Upgrade to ExtJS 3.0.0 - Released 07/06/2009
[extjs.git] / docs / source / swfobject.html
1 <html>\r
2 <head>\r
3   <title>The source code</title>\r
4     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />\r
5     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>\r
6 </head>\r
7 <body  onload="prettyPrint();">\r
8     <pre class="prettyprint lang-js">/*! SWFObject v2.2 <http://code.google.com/p/swfobject/> \r
9     is released under the MIT License <http://www.opensource.org/licenses/mit-license.php> \r
10 */\r
11 \r
12 var swfobject = function() {\r
13     \r
14     var UNDEF = "undefined",\r
15         OBJECT = "object",\r
16         SHOCKWAVE_FLASH = "Shockwave Flash",\r
17         SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",\r
18         FLASH_MIME_TYPE = "application/x-shockwave-flash",\r
19         EXPRESS_INSTALL_ID = "SWFObjectExprInst",\r
20         ON_READY_STATE_CHANGE = "onreadystatechange",\r
21         \r
22         win = window,\r
23         doc = document,\r
24         nav = navigator,\r
25         \r
26         plugin = false,\r
27         domLoadFnArr = [main],\r
28         regObjArr = [],\r
29         objIdArr = [],\r
30         listenersArr = [],\r
31         storedAltContent,\r
32         storedAltContentId,\r
33         storedCallbackFn,\r
34         storedCallbackObj,\r
35         isDomLoaded = false,\r
36         isExpressInstallActive = false,\r
37         dynamicStylesheet,\r
38         dynamicStylesheetMedia,\r
39         autoHideShow = true,\r
40     \r
41     /* Centralized function for browser feature detection\r
42         - User agent string detection is only used when no good alternative is possible\r
43         - Is executed directly for optimal performance\r
44     */  \r
45     ua = function() {\r
46         var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,\r
47             u = nav.userAgent.toLowerCase(),\r
48             p = nav.platform.toLowerCase(),\r
49             windows = p ? /win/.test(p) : /win/.test(u),\r
50             mac = p ? /mac/.test(p) : /mac/.test(u),\r
51             webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, // returns either the webkit version or false if not webkit\r
52             ie = !+"\v1", // feature detection based on Andrea Giammarchi's solution: http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html\r
53             playerVersion = [0,0,0],\r
54             d = null;\r
55         if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) {\r
56             d = nav.plugins[SHOCKWAVE_FLASH].description;\r
57             if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { // navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin indicates whether plug-ins are enabled or disabled in Safari 3+\r
58                 plugin = true;\r
59                 ie = false; // cascaded feature detection for Internet Explorer\r
60                 d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");\r
61                 playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10);\r
62                 playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10);\r
63                 playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0;\r
64             }\r
65         }\r
66         else if (typeof win.ActiveXObject != UNDEF) {\r
67             try {\r
68                 var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);\r
69                 if (a) { // a will return null when ActiveX is disabled\r
70                     d = a.GetVariable("$version");\r
71                     if (d) {\r
72                         ie = true; // cascaded feature detection for Internet Explorer\r
73                         d = d.split(" ")[1].split(",");\r
74                         playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];\r
75                     }\r
76                 }\r
77             }\r
78             catch(e) {}\r
79         }\r
80         return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac };\r
81     }(),\r
82     \r
83     /* Cross-browser onDomLoad\r
84         - Will fire an event as soon as the DOM of a web page is loaded\r
85         - Internet Explorer workaround based on Diego Perini's solution: http://javascript.nwbox.com/IEContentLoaded/\r
86         - Regular onload serves as fallback\r
87     */ \r
88     onDomLoad = function() {\r
89         if (!ua.w3) { return; }\r
90         if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") || (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) { // function is fired after onload, e.g. when script is inserted dynamically \r
91             callDomLoadFunctions();\r
92         }\r
93         if (!isDomLoaded) {\r
94             if (typeof doc.addEventListener != UNDEF) {\r
95                 doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false);\r
96             }       \r
97             if (ua.ie && ua.win) {\r
98                 doc.attachEvent(ON_READY_STATE_CHANGE, function() {\r
99                     if (doc.readyState == "complete") {\r
100                         doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee);\r
101                         callDomLoadFunctions();\r
102                     }\r
103                 });\r
104                 if (win == top) { // if not inside an iframe\r
105                     (function(){\r
106                         if (isDomLoaded) { return; }\r
107                         try {\r
108                             doc.documentElement.doScroll("left");\r
109                         }\r
110                         catch(e) {\r
111                             setTimeout(arguments.callee, 0);\r
112                             return;\r
113                         }\r
114                         callDomLoadFunctions();\r
115                     })();\r
116                 }\r
117             }\r
118             if (ua.wk) {\r
119                 (function(){\r
120                     if (isDomLoaded) { return; }\r
121                     if (!/loaded|complete/.test(doc.readyState)) {\r
122                         setTimeout(arguments.callee, 0);\r
123                         return;\r
124                     }\r
125                     callDomLoadFunctions();\r
126                 })();\r
127             }\r
128             addLoadEvent(callDomLoadFunctions);\r
129         }\r
130     }();\r
131     \r
132     function callDomLoadFunctions() {\r
133         if (isDomLoaded) { return; }\r
134         try { // test if we can really add/remove elements to/from the DOM; we don't want to fire it too early\r
135             var t = doc.getElementsByTagName("body")[0].appendChild(createElement("span"));\r
136             t.parentNode.removeChild(t);\r
137         }\r
138         catch (e) { return; }\r
139         isDomLoaded = true;\r
140         var dl = domLoadFnArr.length;\r
141         for (var i = 0; i < dl; i++) {\r
142             domLoadFnArr[i]();\r
143         }\r
144     }\r
145     \r
146     function addDomLoadEvent(fn) {\r
147         if (isDomLoaded) {\r
148             fn();\r
149         }\r
150         else { \r
151             domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only available in IE5.5+\r
152         }\r
153     }\r
154     \r
155     /* Cross-browser onload\r
156         - Based on James Edwards' solution: http://brothercake.com/site/resources/scripts/onload/\r
157         - Will fire an event as soon as a web page including all of its assets are loaded \r
158      */\r
159     function addLoadEvent(fn) {\r
160         if (typeof win.addEventListener != UNDEF) {\r
161             win.addEventListener("load", fn, false);\r
162         }\r
163         else if (typeof doc.addEventListener != UNDEF) {\r
164             doc.addEventListener("load", fn, false);\r
165         }\r
166         else if (typeof win.attachEvent != UNDEF) {\r
167             addListener(win, "onload", fn);\r
168         }\r
169         else if (typeof win.onload == "function") {\r
170             var fnOld = win.onload;\r
171             win.onload = function() {\r
172                 fnOld();\r
173                 fn();\r
174             };\r
175         }\r
176         else {\r
177             win.onload = fn;\r
178         }\r
179     }\r
180     \r
181     /* Main function\r
182         - Will preferably execute onDomLoad, otherwise onload (as a fallback)\r
183     */\r
184     function main() { \r
185         if (plugin) {\r
186             testPlayerVersion();\r
187         }\r
188         else {\r
189             matchVersions();\r
190         }\r
191     }\r
192     \r
193     /* Detect the Flash Player version for non-Internet Explorer browsers\r
194         - Detecting the plug-in version via the object element is more precise than using the plugins collection item's description:\r
195           a. Both release and build numbers can be detected\r
196           b. Avoid wrong descriptions by corrupt installers provided by Adobe\r
197           c. Avoid wrong descriptions by multiple Flash Player entries in the plugin Array, caused by incorrect browser imports\r
198         - Disadvantage of this method is that it depends on the availability of the DOM, while the plugins collection is immediately available\r
199     */\r
200     function testPlayerVersion() {\r
201         var b = doc.getElementsByTagName("body")[0];\r
202         var o = createElement(OBJECT);\r
203         o.setAttribute("type", FLASH_MIME_TYPE);\r
204         var t = b.appendChild(o);\r
205         if (t) {\r
206             var counter = 0;\r
207             (function(){\r
208                 if (typeof t.GetVariable != UNDEF) {\r
209                     var d = t.GetVariable("$version");\r
210                     if (d) {\r
211                         d = d.split(" ")[1].split(",");\r
212                         ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];\r
213                     }\r
214                 }\r
215                 else if (counter < 10) {\r
216                     counter++;\r
217                     setTimeout(arguments.callee, 10);\r
218                     return;\r
219                 }\r
220                 b.removeChild(o);\r
221                 t = null;\r
222                 matchVersions();\r
223             })();\r
224         }\r
225         else {\r
226             matchVersions();\r
227         }\r
228     }\r
229     \r
230     /* Perform Flash Player and SWF version matching; static publishing only\r
231     */\r
232     function matchVersions() {\r
233         var rl = regObjArr.length;\r
234         if (rl > 0) {\r
235             for (var i = 0; i < rl; i++) { // for each registered object element\r
236                 var id = regObjArr[i].id;\r
237                 var cb = regObjArr[i].callbackFn;\r
238                 var cbObj = {success:false, id:id};\r
239                 if (ua.pv[0] > 0) {\r
240                     var obj = getElementById(id);\r
241                     if (obj) {\r
242                         if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { // Flash Player version >= published SWF version: Houston, we have a match!\r
243                             setVisibility(id, true);\r
244                             if (cb) {\r
245                                 cbObj.success = true;\r
246                                 cbObj.ref = getObjectById(id);\r
247                                 cb(cbObj);\r
248                             }\r
249                         }\r
250                         else if (regObjArr[i].expressInstall && canExpressInstall()) { // show the Adobe Express Install dialog if set by the web page author and if supported\r
251                             var att = {};\r
252                             att.data = regObjArr[i].expressInstall;\r
253                             att.width = obj.getAttribute("width") || "0";\r
254                             att.height = obj.getAttribute("height") || "0";\r
255                             if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); }\r
256                             if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); }\r
257                             // parse HTML object param element's name-value pairs\r
258                             var par = {};\r
259                             var p = obj.getElementsByTagName("param");\r
260                             var pl = p.length;\r
261                             for (var j = 0; j < pl; j++) {\r
262                                 if (p[j].getAttribute("name").toLowerCase() != "movie") {\r
263                                     par[p[j].getAttribute("name")] = p[j].getAttribute("value");\r
264                                 }\r
265                             }\r
266                             showExpressInstall(att, par, id, cb);\r
267                         }\r
268                         else { // Flash Player and SWF version mismatch or an older Webkit engine that ignores the HTML object element's nested param elements: display alternative content instead of SWF\r
269                             displayAltContent(obj);\r
270                             if (cb) { cb(cbObj); }\r
271                         }\r
272                     }\r
273                 }\r
274                 else {  // if no Flash Player is installed or the fp version cannot be detected we let the HTML object element do its job (either show a SWF or alternative content)\r
275                     setVisibility(id, true);\r
276                     if (cb) {\r
277                         var o = getObjectById(id); // test whether there is an HTML object element or not\r
278                         if (o && typeof o.SetVariable != UNDEF) { \r
279                             cbObj.success = true;\r
280                             cbObj.ref = o;\r
281                         }\r
282                         cb(cbObj);\r
283                     }\r
284                 }\r
285             }\r
286         }\r
287     }\r
288     \r
289     function getObjectById(objectIdStr) {\r
290         var r = null;\r
291         var o = getElementById(objectIdStr);\r
292         if (o && o.nodeName == "OBJECT") {\r
293             if (typeof o.SetVariable != UNDEF) {\r
294                 r = o;\r
295             }\r
296             else {\r
297                 var n = o.getElementsByTagName(OBJECT)[0];\r
298                 if (n) {\r
299                     r = n;\r
300                 }\r
301             }\r
302         }\r
303         return r;\r
304     }\r
305     \r
306     /* Requirements for Adobe Express Install\r
307         - only one instance can be active at a time\r
308         - fp 6.0.65 or higher\r
309         - Win/Mac OS only\r
310         - no Webkit engines older than version 312\r
311     */\r
312     function canExpressInstall() {\r
313         return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312);\r
314     }\r
315     \r
316     /* Show the Adobe Express Install dialog\r
317         - Reference: http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75\r
318     */\r
319     function showExpressInstall(att, par, replaceElemIdStr, callbackFn) {\r
320         isExpressInstallActive = true;\r
321         storedCallbackFn = callbackFn || null;\r
322         storedCallbackObj = {success:false, id:replaceElemIdStr};\r
323         var obj = getElementById(replaceElemIdStr);\r
324         if (obj) {\r
325             if (obj.nodeName == "OBJECT") { // static publishing\r
326                 storedAltContent = abstractAltContent(obj);\r
327                 storedAltContentId = null;\r
328             }\r
329             else { // dynamic publishing\r
330                 storedAltContent = obj;\r
331                 storedAltContentId = replaceElemIdStr;\r
332             }\r
333             att.id = EXPRESS_INSTALL_ID;\r
334             if (typeof att.width == UNDEF || (!/%$/.test(att.width) && parseInt(att.width, 10) < 310)) { att.width = "310"; }\r
335             if (typeof att.height == UNDEF || (!/%$/.test(att.height) && parseInt(att.height, 10) < 137)) { att.height = "137"; }\r
336             doc.title = doc.title.slice(0, 47) + " - Flash Player Installation";\r
337             var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn",\r
338                 fv = "MMredirectURL=" + win.location.toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title;\r
339             if (typeof par.flashvars != UNDEF) {\r
340                 par.flashvars += "&" + fv;\r
341             }\r
342             else {\r
343                 par.flashvars = fv;\r
344             }\r
345             // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it,\r
346             // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work\r
347             if (ua.ie && ua.win && obj.readyState != 4) {\r
348                 var newObj = createElement("div");\r
349                 replaceElemIdStr += "SWFObjectNew";\r
350                 newObj.setAttribute("id", replaceElemIdStr);\r
351                 obj.parentNode.insertBefore(newObj, obj); // insert placeholder div that will be replaced by the object element that loads expressinstall.swf\r
352                 obj.style.display = "none";\r
353                 (function(){\r
354                     if (obj.readyState == 4) {\r
355                         obj.parentNode.removeChild(obj);\r
356                     }\r
357                     else {\r
358                         setTimeout(arguments.callee, 10);\r
359                     }\r
360                 })();\r
361             }\r
362             createSWF(att, par, replaceElemIdStr);\r
363         }\r
364     }\r
365     \r
366     /* Functions to abstract and display alternative content\r
367     */\r
368     function displayAltContent(obj) {\r
369         if (ua.ie && ua.win && obj.readyState != 4) {\r
370             // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it,\r
371             // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work\r
372             var el = createElement("div");\r
373             obj.parentNode.insertBefore(el, obj); // insert placeholder div that will be replaced by the alternative content\r
374             el.parentNode.replaceChild(abstractAltContent(obj), el);\r
375             obj.style.display = "none";\r
376             (function(){\r
377                 if (obj.readyState == 4) {\r
378                     obj.parentNode.removeChild(obj);\r
379                 }\r
380                 else {\r
381                     setTimeout(arguments.callee, 10);\r
382                 }\r
383             })();\r
384         }\r
385         else {\r
386             obj.parentNode.replaceChild(abstractAltContent(obj), obj);\r
387         }\r
388     } \r
389 \r
390     function abstractAltContent(obj) {\r
391         var ac = createElement("div");\r
392         if (ua.win && ua.ie) {\r
393             ac.innerHTML = obj.innerHTML;\r
394         }\r
395         else {\r
396             var nestedObj = obj.getElementsByTagName(OBJECT)[0];\r
397             if (nestedObj) {\r
398                 var c = nestedObj.childNodes;\r
399                 if (c) {\r
400                     var cl = c.length;\r
401                     for (var i = 0; i < cl; i++) {\r
402                         if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) {\r
403                             ac.appendChild(c[i].cloneNode(true));\r
404                         }\r
405                     }\r
406                 }\r
407             }\r
408         }\r
409         return ac;\r
410     }\r
411     \r
412     /* Cross-browser dynamic SWF creation\r
413     */\r
414     function createSWF(attObj, parObj, id) {\r
415         var r, el = getElementById(id);\r
416         if (ua.wk && ua.wk < 312) { return r; }\r
417         if (el) {\r
418             if (typeof attObj.id == UNDEF) { // if no 'id' is defined for the object element, it will inherit the 'id' from the alternative content\r
419                 attObj.id = id;\r
420             }\r
421             if (ua.ie && ua.win) { // Internet Explorer + the HTML object element + W3C DOM methods do not combine: fall back to outerHTML\r
422                 var att = "";\r
423                 for (var i in attObj) {\r
424                     if (attObj[i] != Object.prototype[i]) { // filter out prototype additions from other potential libraries\r
425                         if (i.toLowerCase() == "data") {\r
426                             parObj.movie = attObj[i];\r
427                         }\r
428                         else if (i.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword\r
429                             att += ' class="' + attObj[i] + '"';\r
430                         }\r
431                         else if (i.toLowerCase() != "classid") {\r
432                             att += ' ' + i + '="' + attObj[i] + '"';\r
433                         }\r
434                     }\r
435                 }\r
436                 var par = "";\r
437                 for (var j in parObj) {\r
438                     if (parObj[j] != Object.prototype[j]) { // filter out prototype additions from other potential libraries\r
439                         par += '<param name="' + j + '" value="' + parObj[j] + '" />';\r
440                     }\r
441                 }\r
442                 el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + '>' + par + '</object>';\r
443                 objIdArr[objIdArr.length] = attObj.id; // stored to fix object 'leaks' on unload (dynamic publishing only)\r
444                 r = getElementById(attObj.id);  \r
445             }\r
446             else { // well-behaving browsers\r
447                 var o = createElement(OBJECT);\r
448                 o.setAttribute("type", FLASH_MIME_TYPE);\r
449                 for (var m in attObj) {\r
450                     if (attObj[m] != Object.prototype[m]) { // filter out prototype additions from other potential libraries\r
451                         if (m.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword\r
452                             o.setAttribute("class", attObj[m]);\r
453                         }\r
454                         else if (m.toLowerCase() != "classid") { // filter out IE specific attribute\r
455                             o.setAttribute(m, attObj[m]);\r
456                         }\r
457                     }\r
458                 }\r
459                 for (var n in parObj) {\r
460                     if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") { // filter out prototype additions from other potential libraries and IE specific param element\r
461                         createObjParam(o, n, parObj[n]);\r
462                     }\r
463                 }\r
464                 el.parentNode.replaceChild(o, el);\r
465                 r = o;\r
466             }\r
467         }\r
468         return r;\r
469     }\r
470     \r
471     function createObjParam(el, pName, pValue) {\r
472         var p = createElement("param");\r
473         p.setAttribute("name", pName);  \r
474         p.setAttribute("value", pValue);\r
475         el.appendChild(p);\r
476     }\r
477     \r
478     /* Cross-browser SWF removal\r
479         - Especially needed to safely and completely remove a SWF in Internet Explorer\r
480     */\r
481     function removeSWF(id) {\r
482         var obj = getElementById(id);\r
483         if (obj && obj.nodeName == "OBJECT") {\r
484             if (ua.ie && ua.win) {\r
485                 obj.style.display = "none";\r
486                 (function(){\r
487                     if (obj.readyState == 4) {\r
488                         removeObjectInIE(id);\r
489                     }\r
490                     else {\r
491                         setTimeout(arguments.callee, 10);\r
492                     }\r
493                 })();\r
494             }\r
495             else {\r
496                 obj.parentNode.removeChild(obj);\r
497             }\r
498         }\r
499     }\r
500     \r
501     function removeObjectInIE(id) {\r
502         var obj = getElementById(id);\r
503         if (obj) {\r
504             for (var i in obj) {\r
505                 if (typeof obj[i] == "function") {\r
506                     obj[i] = null;\r
507                 }\r
508             }\r
509             obj.parentNode.removeChild(obj);\r
510         }\r
511     }\r
512     \r
513     /* Functions to optimize JavaScript compression\r
514     */\r
515     function getElementById(id) {\r
516         var el = null;\r
517         try {\r
518             el = doc.getElementById(id);\r
519         }\r
520         catch (e) {}\r
521         return el;\r
522     }\r
523     \r
524     function createElement(el) {\r
525         return doc.createElement(el);\r
526     }\r
527     \r
528     /* Updated attachEvent function for Internet Explorer\r
529         - Stores attachEvent information in an Array, so on unload the detachEvent functions can be called to avoid memory leaks\r
530     */  \r
531     function addListener(target, eventType, fn) {\r
532         target.attachEvent(eventType, fn);\r
533         listenersArr[listenersArr.length] = [target, eventType, fn];\r
534     }\r
535     \r
536     /* Flash Player and SWF content version matching\r
537     */\r
538     function hasPlayerVersion(rv) {\r
539         var pv = ua.pv, v = rv.split(".");\r
540         v[0] = parseInt(v[0], 10);\r
541         v[1] = parseInt(v[1], 10) || 0; // supports short notation, e.g. "9" instead of "9.0.0"\r
542         v[2] = parseInt(v[2], 10) || 0;\r
543         return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;\r
544     }\r
545     \r
546     /* Cross-browser dynamic CSS creation\r
547         - Based on Bobby van der Sluis' solution: http://www.bobbyvandersluis.com/articles/dynamicCSS.php\r
548     */  \r
549     function createCSS(sel, decl, media, newStyle) {\r
550         if (ua.ie && ua.mac) { return; }\r
551         var h = doc.getElementsByTagName("head")[0];\r
552         if (!h) { return; } // to also support badly authored HTML pages that lack a head element\r
553         var m = (media && typeof media == "string") ? media : "screen";\r
554         if (newStyle) {\r
555             dynamicStylesheet = null;\r
556             dynamicStylesheetMedia = null;\r
557         }\r
558         if (!dynamicStylesheet || dynamicStylesheetMedia != m) { \r
559             // create dynamic stylesheet + get a global reference to it\r
560             var s = createElement("style");\r
561             s.setAttribute("type", "text/css");\r
562             s.setAttribute("media", m);\r
563             dynamicStylesheet = h.appendChild(s);\r
564             if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) {\r
565                 dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];\r
566             }\r
567             dynamicStylesheetMedia = m;\r
568         }\r
569         // add style rule\r
570         if (ua.ie && ua.win) {\r
571             if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) {\r
572                 dynamicStylesheet.addRule(sel, decl);\r
573             }\r
574         }\r
575         else {\r
576             if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) {\r
577                 dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}"));\r
578             }\r
579         }\r
580     }\r
581     \r
582     function setVisibility(id, isVisible) {\r
583         if (!autoHideShow) { return; }\r
584         var v = isVisible ? "visible" : "hidden";\r
585         if (isDomLoaded && getElementById(id)) {\r
586             getElementById(id).style.visibility = v;\r
587         }\r
588         else {\r
589             createCSS("#" + id, "visibility:" + v);\r
590         }\r
591     }\r
592 \r
593     /* Filter to avoid XSS attacks\r
594     */\r
595     function urlEncodeIfNecessary(s) {\r
596         var regex = /[\\\"<>\.;]/;\r
597         var hasBadChars = regex.exec(s) != null;\r
598         return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s;\r
599     }\r
600     \r
601     /* Release memory to avoid memory leaks caused by closures, fix hanging audio/video threads and force open sockets/NetConnections to disconnect (Internet Explorer only)\r
602     */\r
603     var cleanup = function() {\r
604         if (ua.ie && ua.win) {\r
605             window.attachEvent("onunload", function() {\r
606                 // remove listeners to avoid memory leaks\r
607                 var ll = listenersArr.length;\r
608                 for (var i = 0; i < ll; i++) {\r
609                     listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);\r
610                 }\r
611                 // cleanup dynamically embedded objects to fix audio/video threads and force open sockets and NetConnections to disconnect\r
612                 var il = objIdArr.length;\r
613                 for (var j = 0; j < il; j++) {\r
614                     removeSWF(objIdArr[j]);\r
615                 }\r
616                 // cleanup library's main closures to avoid memory leaks\r
617                 for (var k in ua) {\r
618                     ua[k] = null;\r
619                 }\r
620                 ua = null;\r
621                 for (var l in swfobject) {\r
622                     swfobject[l] = null;\r
623                 }\r
624                 swfobject = null;\r
625             });\r
626         }\r
627     }();\r
628     \r
629     return {\r
630         /* Public API\r
631             - Reference: http://code.google.com/p/swfobject/wiki/documentation\r
632         */ \r
633         registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {\r
634             if (ua.w3 && objectIdStr && swfVersionStr) {\r
635                 var regObj = {};\r
636                 regObj.id = objectIdStr;\r
637                 regObj.swfVersion = swfVersionStr;\r
638                 regObj.expressInstall = xiSwfUrlStr;\r
639                 regObj.callbackFn = callbackFn;\r
640                 regObjArr[regObjArr.length] = regObj;\r
641                 setVisibility(objectIdStr, false);\r
642             }\r
643             else if (callbackFn) {\r
644                 callbackFn({success:false, id:objectIdStr});\r
645             }\r
646         },\r
647         \r
648         getObjectById: function(objectIdStr) {\r
649             if (ua.w3) {\r
650                 return getObjectById(objectIdStr);\r
651             }\r
652         },\r
653         \r
654         embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {\r
655             var callbackObj = {success:false, id:replaceElemIdStr};\r
656             if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {\r
657                 setVisibility(replaceElemIdStr, false);\r
658                 addDomLoadEvent(function() {\r
659                     widthStr += ""; // auto-convert to string\r
660                     heightStr += "";\r
661                     var att = {};\r
662                     if (attObj && typeof attObj === OBJECT) {\r
663                         for (var i in attObj) { // copy object to avoid the use of references, because web authors often reuse attObj for multiple SWFs\r
664                             att[i] = attObj[i];\r
665                         }\r
666                     }\r
667                     att.data = swfUrlStr;\r
668                     att.width = widthStr;\r
669                     att.height = heightStr;\r
670                     var par = {}; \r
671                     if (parObj && typeof parObj === OBJECT) {\r
672                         for (var j in parObj) { // copy object to avoid the use of references, because web authors often reuse parObj for multiple SWFs\r
673                             par[j] = parObj[j];\r
674                         }\r
675                     }\r
676                     if (flashvarsObj && typeof flashvarsObj === OBJECT) {\r
677                         for (var k in flashvarsObj) { // copy object to avoid the use of references, because web authors often reuse flashvarsObj for multiple SWFs\r
678                             if (typeof par.flashvars != UNDEF) {\r
679                                 par.flashvars += "&" + k + "=" + flashvarsObj[k];\r
680                             }\r
681                             else {\r
682                                 par.flashvars = k + "=" + flashvarsObj[k];\r
683                             }\r
684                         }\r
685                     }\r
686                     if (hasPlayerVersion(swfVersionStr)) { // create SWF\r
687                         var obj = createSWF(att, par, replaceElemIdStr);\r
688                         if (att.id == replaceElemIdStr) {\r
689                             setVisibility(replaceElemIdStr, true);\r
690                         }\r
691                         callbackObj.success = true;\r
692                         callbackObj.ref = obj;\r
693                     }\r
694                     else if (xiSwfUrlStr && canExpressInstall()) { // show Adobe Express Install\r
695                         att.data = xiSwfUrlStr;\r
696                         showExpressInstall(att, par, replaceElemIdStr, callbackFn);\r
697                         return;\r
698                     }\r
699                     else { // show alternative content\r
700                         setVisibility(replaceElemIdStr, true);\r
701                     }\r
702                     if (callbackFn) { callbackFn(callbackObj); }\r
703                 });\r
704             }\r
705             else if (callbackFn) { callbackFn(callbackObj); }\r
706         },\r
707         \r
708         switchOffAutoHideShow: function() {\r
709             autoHideShow = false;\r
710         },\r
711         \r
712         ua: ua,\r
713         \r
714         getFlashPlayerVersion: function() {\r
715             return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] };\r
716         },\r
717         \r
718         hasFlashPlayerVersion: hasPlayerVersion,\r
719         \r
720         createSWF: function(attObj, parObj, replaceElemIdStr) {\r
721             if (ua.w3) {\r
722                 return createSWF(attObj, parObj, replaceElemIdStr);\r
723             }\r
724             else {\r
725                 return undefined;\r
726             }\r
727         },\r
728         \r
729         showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) {\r
730             if (ua.w3 && canExpressInstall()) {\r
731                 showExpressInstall(att, par, replaceElemIdStr, callbackFn);\r
732             }\r
733         },\r
734         \r
735         removeSWF: function(objElemIdStr) {\r
736             if (ua.w3) {\r
737                 removeSWF(objElemIdStr);\r
738             }\r
739         },\r
740         \r
741         createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) {\r
742             if (ua.w3) {\r
743                 createCSS(selStr, declStr, mediaStr, newStyleBoolean);\r
744             }\r
745         },\r
746         \r
747         addDomLoadEvent: addDomLoadEvent,\r
748         \r
749         addLoadEvent: addLoadEvent,\r
750         \r
751         getQueryParamValue: function(param) {\r
752             var q = doc.location.search || doc.location.hash;\r
753             if (q) {\r
754                 if (/\?/.test(q)) { q = q.split("?")[1]; } // strip question mark\r
755                 if (param == null) {\r
756                     return urlEncodeIfNecessary(q);\r
757                 }\r
758                 var pairs = q.split("&");\r
759                 for (var i = 0; i < pairs.length; i++) {\r
760                     if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {\r
761                         return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1)));\r
762                     }\r
763                 }\r
764             }\r
765             return "";\r
766         },\r
767         \r
768         // For internal usage only\r
769         expressInstallCallback: function() {\r
770             if (isExpressInstallActive) {\r
771                 var obj = getElementById(EXPRESS_INSTALL_ID);\r
772                 if (obj && storedAltContent) {\r
773                     obj.parentNode.replaceChild(storedAltContent, obj);\r
774                     if (storedAltContentId) {\r
775                         setVisibility(storedAltContentId, true);\r
776                         if (ua.ie && ua.win) { storedAltContent.style.display = "block"; }\r
777                     }\r
778                     if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); }\r
779                 }\r
780                 isExpressInstallActive = false;\r
781             } \r
782         }\r
783     };\r
784 }();\r
785 </pre>    \r
786 </body>\r
787 </html>