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