1/* 2 * jQuery Media Plugin for converting elements into rich media content. 3 * 4 * Examples and documentation at: http://malsup.com/jquery/media/ 5 * Copyright (c) 2007-2010 M. Alsup 6 * Dual licensed under the MIT and GPL licenses: 7 * http://www.opensource.org/licenses/mit-license.php 8 * http://www.gnu.org/licenses/gpl.html 9 * 10 * @author: M. Alsup 11 * @version: 0.99 (05-JUN-2013) 12 * @requires jQuery v1.1.2 or later 13 * $Id: jquery.media.js 2460 2007-07-23 02:53:15Z malsup $ 14 * 15 * Supported Media Players: 16 * - Flash 17 * - Quicktime 18 * - Real Player 19 * - Silverlight 20 * - Windows Media Player 21 * - iframe 22 * 23 * Supported Media Formats: 24 * Any types supported by the above players, such as: 25 * Video: asf, avi, flv, mov, mpg, mpeg, mp4, qt, smil, swf, wmv, 3g2, 3gp 26 * Audio: aif, aac, au, gsm, mid, midi, mov, mp3, m4a, snd, rm, wav, wma 27 * Other: bmp, html, pdf, psd, qif, qtif, qti, tif, tiff, xaml 28 * 29 * Thanks to Mark Hicken and Brent Pedersen for helping me debug this on the Mac! 30 * Thanks to Dan Rossi for numerous bug reports and code bits! 31 * Thanks to Skye Giordano for several great suggestions! 32 * Thanks to Richard Connamacher for excellent improvements to the non-IE behavior! 33 */ 34/*global SWFObject alert Sys */ 35/*jshint forin:false */ 36;(function($) { 37"use strict"; 38 39var mode = document.documentMode || 0; 40var msie = /MSIE/.test(navigator.userAgent); 41var lameIE = msie && (/MSIE (6|7|8)\.0/.test(navigator.userAgent) || mode < 9); 42 43/** 44 * Chainable method for converting elements into rich media. 45 * 46 * @param options 47 * @param callback fn invoked for each matched element before conversion 48 * @param callback fn invoked for each matched element after conversion 49 */ 50$.fn.media = function(options, f1, f2) { 51 if (options == 'undo') { 52 return this.each(function() { 53 var $this = $(this); 54 var html = $this.data('media.origHTML'); 55 if (html) 56 $this.replaceWith(html); 57 }); 58 } 59 60 return this.each(function() { 61 if (typeof options == 'function') { 62 f2 = f1; 63 f1 = options; 64 options = {}; 65 } 66 var o = getSettings(this, options); 67 // pre-conversion callback, passes original element and fully populated options 68 if (typeof f1 == 'function') f1(this, o); 69 70 var r = getTypesRegExp(); 71 var m = r.exec(o.src.toLowerCase()) || ['']; 72 var fn; 73 74 if (o.type) 75 m[0] = o.type; 76 else 77 m.shift(); 78 79 for (var i=0; i < m.length; i++) { 80 fn = m[i].toLowerCase(); 81 if (isDigit(fn[0])) fn = 'fn' + fn; // fns can't begin with numbers 82 if (!$.fn.media[fn]) 83 continue; // unrecognized media type 84 // normalize autoplay settings 85 var player = $.fn.media[fn+'_player']; 86 if (!o.params) o.params = {}; 87 if (player) { 88 var num = player.autoplayAttr == 'autostart'; 89 o.params[player.autoplayAttr || 'autoplay'] = num ? (o.autoplay ? 1 : 0) : o.autoplay ? true : false; 90 } 91 var $div = $.fn.media[fn](this, o); 92 93 $div.css('backgroundColor', o.bgColor).width(o.width); 94 95 if (o.canUndo) { 96 var $temp = $('<div></div>').append(this); 97 $div.data('media.origHTML', $temp.html()); // store original markup 98 } 99 100 // post-conversion callback, passes original element, new div element and fully populated options 101 if (typeof f2 == 'function') f2(this, $div[0], o, player.name); 102 break; 103 } 104 }); 105}; 106 107/** 108 * Non-chainable method for adding or changing file format / player mapping 109 * @name mapFormat 110 * @param String format File format extension (ie: mov, wav, mp3) 111 * @param String player Player name to use for the format (one of: flash, quicktime, realplayer, winmedia, silverlight or iframe 112 */ 113$.fn.media.mapFormat = function(format, player) { 114 if (!format || !player || !$.fn.media.defaults.players[player]) return; // invalid 115 format = format.toLowerCase(); 116 if (isDigit(format[0])) format = 'fn' + format; 117 $.fn.media[format] = $.fn.media[player]; 118 $.fn.media[format+'_player'] = $.fn.media.defaults.players[player]; 119}; 120 121// global defautls; override as needed 122$.fn.media.defaults = { 123 standards: true, // use object tags only (no embeds for non-IE browsers) 124 canUndo: true, // tells plugin to store the original markup so it can be reverted via: $(sel).mediaUndo() 125 width: 400, 126 height: 400, 127 autoplay: 0, // normalized cross-player setting 128 bgColor: '#ffffff', // background color 129 params: { wmode: 'transparent'}, // added to object element as param elements; added to embed element as attrs 130 attrs: {}, // added to object and embed elements as attrs 131 flvKeyName: 'file', // key used for object src param (thanks to Andrea Ercolino) 132 flashvars: {}, // added to flash content as flashvars param/attr 133 flashVersion: '7', // required flash version 134 expressInstaller: null, // src for express installer 135 136 // default flash video and mp3 player (@see: http://jeroenwijering.com/?item=Flash_Media_Player) 137 flvPlayer: 'mediaplayer.swf', 138 mp3Player: 'mediaplayer.swf', 139
140 // @see http://msdn2.microsoft.com/en-us/library/bb412401.aspx 141 silverlight: { 142 inplaceInstallPrompt: 'true', // display in-place install prompt? 143 isWindowless: 'true', // windowless mode (false for wrapping markup) 144 framerate: '24', // maximum framerate 145 version: '0.9', // Silverlight version 146 onError: null, // onError callback 147 onLoad: null, // onLoad callback 148 initParams: null, // object init params 149 userContext: null // callback arg passed to the load callback 150 } 151}; 152 153// Media Players; think twice before overriding 154$.fn.media.defaults.players = { 155 flash: { 156 name: 'flash', 157 title: 'Flash', 158 types: 'flv,mp3,swf', 159 mimetype: 'application/x-shockwave-flash', 160 pluginspage: 'http://www.adobe.com/go/getflashplayer', 161 ieAttrs: { 162 classid: 'clsid:d27cdb6e-ae6d-11cf-96b8-444553540000', 163 type: 'application/x-oleobject', 164 codebase: 'http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=' + $.fn.media.defaults.flashVersion 165 } 166 }, 167 quicktime: { 168 name: 'quicktime', 169 title: 'QuickTime', 170 mimetype: 'video/quicktime', 171 pluginspage: 'http://www.apple.com/quicktime/download/', 172 types: 'aif,aiff,aac,au,bmp,gsm,mov,mid,midi,mpg,mpeg,mp4,m4a,psd,qt,qtif,qif,qti,snd,tif,tiff,wav,3g2,3gp', 173 ieAttrs: { 174 classid: 'clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B', 175 codebase: 'http://www.apple.com/qtactivex/qtplugin.cab' 176 } 177 }, 178 realplayer: { 179 name: 'real', 180 title: 'RealPlayer', 181 types: 'ra,ram,rm,rpm,rv,smi,smil', 182 mimetype: 'audio/x-pn-realaudio-plugin', 183 pluginspage: 'http://www.real.com/player/', 184 autoplayAttr: 'autostart', 185 ieAttrs: { 186 classid: 'clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA' 187 } 188 }, 189 winmedia: { 190 name: 'winmedia', 191 title: 'Windows Media', 192 types: 'asx,asf,avi,wma,wmv', 193 mimetype: isFirefoxWMPPluginInstalled() ? 'application/x-ms-wmp' : 'application/x-mplayer2', 194 pluginspage: 'http://www.microsoft.com/Windows/MediaPlayer/', 195 autoplayAttr: 'autostart', 196 oUrl: 'url', 197 ieAttrs: { 198 classid: 'clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6', 199 type: 'application/x-oleobject' 200 } 201 }, 202 // special cases 203 img: { 204 name: 'img', 205 title: 'Image', 206 types: 'gif,png,jpg' 207 }, 208 iframe: { 209 name: 'iframe', 210 types: 'html,pdf' 211 }, 212 silverlight: { 213 name: 'silverlight', 214 types: 'xaml' 215 } 216}; 217 218// 219// everything below here is private 220// 221 222 223// detection script for FF WMP plugin (http://www.therossman.org/experiments/wmp_play.html) 224// (hat tip to Mark Ross for this script) 225function isFirefoxWMPPluginInstalled() { 226 var plugs = navigator.plugins || []; 227 for (var i = 0; i < plugs.length; i++) { 228 var plugin = plugs[i]; 229 if (plugin['filename'] == 'np-mswmp.dll') 230 return true; 231 } 232 return false; 233} 234 235var counter = 1; 236 237for (var player in $.fn.media.defaults.players) { 238 var types = $.fn.media.defaults.players[player].types; 239 $.each(types.split(','), function(i,o) { 240 if (isDigit(o[0])) o = 'fn' + o; 241 $.fn.media[o] = $.fn.media[player] = getGenerator(player); 242 $.fn.media[o+'_player'] = $.fn.media.defaults.players[player]; 243 }); 244} 245 246function getTypesRegExp() { 247 var types = ''; 248 for (var player in $.fn.media.defaults.players) { 249 if (types.length) types += ','; 250 types += $.fn.media.defaults.players[player].types; 251 } 252 return new RegExp('\\.(' + types.replace(/,/ig,'|') + ')\\b'); 253} 254 255function getGenerator(player) { 256 return function(el, options) { 257 return generate(el, options, player); 258 }; 259} 260 261function isDigit(c) { 262 return '0123456789'.indexOf(c) > -1; 263} 264 265// flatten all possible options: global defaults, meta, option obj 266function getSettings(el, options) { 267 options = options || {}; 268 var a, n; 269 var $el = $(el); 270 var cls = el.className || ''; 271 // support metadata plugin (v1.0 and v2.0) 272 var meta = $.metadata ? $el.metadata() : $.meta ? $el.data() : {}; 273 meta = meta || {}; 274 var w = meta.width || parseInt(((cls.match(/\bw:(\d+)/)||[])[1]||0),10) || parseInt(((cls.match(/\bwidth:(\d+)/)||[])[1]||0),10); 275 var h = meta.height || parseInt(((cls.match(/\bh:(\d+)/)||[])[1]||0),10) || parseInt(((cls.match(/\bheight:(\d+)/)||[])[1]||0),10); 276 277 if (w) meta.width = w; 278 if (h) meta.height = h; 279 if (cls) meta.cls = cls; 280 281 // crank html5 style data attributes 282 var dataName = 'data-'; 283 for (var i=0; i < el.attributes.length; i++) { 284 a = el.attributes[i], n = $.trim(a.name); 285 var index = n.indexOf(dataName); 286 if (index === 0) { 287 n = n.substring(dataName.length); 288 meta[n] = a.value; 289 } 290 } 291 292 a = $.fn.media.defaults; 293 var b = options; 294 var c = meta; 295 296 var p = { params: { bgColor: options.bgColor || $.fn.media.defaults.bgColor } }; 297 var opts = $.extend({}, a, b, c); 298 $.each(['attrs','params','flashvars','silverlight'], function(i,o) { 299 opts[o] = $.extend({}, p[o] || {}, a[o] || {}, b[o] || {}, c[o] || {}); 300 }); 301 302 if (typeof opts.caption == 'undefined') opts.caption = $el.text(); 303 304 // make sure we have a source! 305 opts.src = opts.src || $el.attr('href') || $el.attr('src') || 'unknown'; 306 return opts; 307} 308 309// 310// Flash Player 311// 312 313// generate flash using SWFObject library if possible 314$.fn.media.swf = function(el, opts) { 315 var f, p; 316 if (!window.SWFObject && !window.swfobject) { 317 // roll our own 318 if (opts.flashvars) { 319 var a = [];
320 for (f in opts.flashvars) 321 a.push(f + '=' + opts.flashvars[f]); 322 if (!opts.params) opts.params = {}; 323 opts.params.flashvars = a.join('&'); 324 } 325 return generate(el, opts, 'flash'); 326 } 327 328 var id = el.id ? (' id="'+el.id+'"') : ''; 329 var cls = opts.cls ? (' class="' + opts.cls + '"') : ''; 330 var $div = $('<div' + id + cls + '>'); 331 332 // swfobject v2+ 333 if (window.swfobject) { 334 $(el).after($div).appendTo($div); 335 if (!el.id) el.id = 'movie_player_' + counter++; 336 337 // replace el with swfobject content 338 window.swfobject.embedSWF(opts.src, el.id, opts.width, opts.height, opts.flashVersion, 339 opts.expressInstaller, opts.flashvars, opts.params, opts.attrs); 340 } 341 // swfobject < v2 342 else { 343 $(el).after($div).remove(); 344 var so = new SWFObject(opts.src, 'movie_player_' + counter++, opts.width, opts.height, opts.flashVersion, opts.bgColor); 345 if (opts.expressInstaller) so.useExpressInstall(opts.expressInstaller); 346 347 for (p in opts.params) 348 if (p != 'bgColor') so.addParam(p, opts.params[p]); 349 for (f in opts.flashvars) 350 so.addVariable(f, opts.flashvars[f]); 351 so.write($div[0]); 352 } 353 354 if (opts.caption) $('<div>').appendTo($div).html(opts.caption); 355 return $div; 356}; 357 358// map flv and mp3 files to the swf player by default 359$.fn.media.flv = $.fn.media.mp3 = function(el, opts) { 360 var src = opts.src; 361 var player = /\.mp3\b/i.test(src) ? opts.mp3Player : opts.flvPlayer; 362 var key = opts.flvKeyName; 363 src = encodeURIComponent(src); 364 opts.src = player; 365 opts.src = opts.src + '?'+key+'=' + (src); 366 var srcObj = {}; 367 srcObj[key] = src; 368 opts.flashvars = $.extend({}, srcObj, opts.flashvars ); 369 return $.fn.media.swf(el, opts); 370}; 371 372// 373// Silverlight 374// 375$.fn.media.xaml = function(el, opts) { 376 if (!window.Sys || !window.Sys.Silverlight) { 377 if ($.fn.media.xaml.warning) return; 378 $.fn.media.xaml.warning = 1; 379 alert('You must include the Silverlight.js script.'); 380 return; 381 } 382 383 var props = { 384 width: opts.width, 385 height: opts.height, 386 background: opts.bgColor, 387 inplaceInstallPrompt: opts.silverlight.inplaceInstallPrompt, 388 isWindowless: opts.silverlight.isWindowless, 389 framerate: opts.silverlight.framerate, 390 version: opts.silverlight.version 391 }; 392 var events = { 393 onError: opts.silverlight.onError, 394 onLoad: opts.silverlight.onLoad 395 }; 396 397 var id1 = el.id ? (' id="'+el.id+'"') : ''; 398 var id2 = opts.id || 'AG' + counter++; 399 // convert element to div 400 var cls = opts.cls ? (' class="' + opts.cls + '"') : ''; 401 var $div = $('<div' + id1 + cls + '>'); 402 $(el).after($div).remove(); 403 404 Sys.Silverlight.createObjectEx({ 405 source: opts.src, 406 initParams: opts.silverlight.initParams, 407 userContext: opts.silverlight.userContext, 408 id: id2, 409 parentElement: $div[0], 410 properties: props, 411 events: events 412 }); 413 414 if (opts.caption) $('<div>').appendTo($div).html(opts.caption); 415 return $div; 416}; 417 418// 419// generate object/embed markup 420// 421function generate(el, opts, player) { 422 var $el = $(el); 423 var o = $.fn.media.defaults.players[player]; 424 var a, key, v; 425 426 if (player == 'iframe') { 427 o = $('<iframe' + ' width="' + opts.width + '" height="' + opts.height + '" >'); 428 o.attr('src', opts.src); 429 o.css('backgroundColor', o.bgColor); 430 } 431 else if (player == 'img') { 432 o = $('<img>'); 433 o.attr('src', opts.src); 434 if (opts.width) 435 o.attr('width', opts.width); 436 if (opts.height) 437 o.attr('height', opts.height); 438 o.css('backgroundColor', o.bgColor); 439 } 440 else if (lameIE) { 441 a = ['<object width="' + opts.width + '" height="' + opts.height + '" ']; 442 for (key in opts.attrs) 443 a.push(key + '="'+opts.attrs[key]+'" '); 444 for (key in o.ieAttrs || {}) { 445 v = o.ieAttrs[key]; 446 if (key == 'codebase' && window.location.protocol == 'https:') 447 v = v.replace('http','https'); 448 a.push(key + '="'+v+'" '); 449 } 450 a.push('></ob'+'ject'+'>'); 451 var p = ['<param name="' + (o.oUrl || 'src') +'" value="' + opts.src + '">']; 452 for (key in opts.params) 453 p.push('<param name="'+ key +'" value="' + opts.params[key] + '">'); 454 o = document.createElement(a.join(''));
455 for (var i=0; i < p.length; i++) 456 o.appendChild(document.createElement(p[i])); 457 } 458 else if (opts.standards) { 459 // Rewritten to be standards compliant by Richard Connamacher 460 a = ['<object type="' + o.mimetype +'" width="' + opts.width + '" height="' + opts.height +'"']; 461 if (opts.src) a.push(' data="' + opts.src + '" '); 462 if (msie) { 463 for (key in o.ieAttrs || {}) { 464 v = o.ieAttrs[key]; 465 if (key == 'codebase' && window.location.protocol == 'https:') 466 v = v.replace('http','https'); 467 a.push(key + '="'+v+'" '); 468 } 469 } 470 a.push('>'); 471 a.push('<param name="' + (o.oUrl || 'src') +'" value="' + opts.src + '">'); 472 for (key in opts.params) { 473 if (key == 'wmode' && player != 'flash') // FF3/Quicktime borks on wmode 474 continue; 475 a.push('<param name="'+ key +'" value="' + opts.params[key] + '">'); 476 } 477 // Alternate HTML 478 a.push('<div><p><strong>'+o.title+' Required</strong></p><p>'+o.title+' is required to view this media. <a href="'+o.pluginspage+'">Download Here</a>.</p></div>'); 479 a.push('</ob'+'ject'+'>'); 480 } 481 else { 482 a = ['<embed width="' + opts.width + '" height="' + opts.height + '" style="display:block"']; 483 if (opts.src) a.push(' src="' + opts.src + '" '); 484 for (key in opts.attrs) 485 a.push(key + '="'+opts.attrs[key]+'" '); 486 for (key in o.eAttrs || {}) 487 a.push(key + '="'+o.eAttrs[key]+'" '); 488 for (key in opts.params) { 489 if (key == 'wmode' && player != 'flash') // FF3/Quicktime borks on wmode 490 continue; 491 a.push(key + '="'+opts.params[key]+'" '); 492 } 493 a.push('></em'+'bed'+'>'); 494 } 495 // convert element to div 496 var id = el.id ? (' id="'+el.id+'"') : ''; 497 var cls = opts.cls ? (' class="' + opts.cls + '"') : ''; 498 var $div = $('<div' + id + cls + '>'); 499 $el.after($div).remove(); 500 if (lameIE || player == 'iframe' || player == 'img') 501 $div.append(o); 502 else 503 $div.html(a.join('')); 504 505 if (opts.caption) 506 $('<div>').appendTo($div).html(opts.caption); 507 return $div; 508} 509 510 511})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.