~dongpo-deng/sahana-eden/test

« back to all changes in this revision

Viewing changes to static/scripts/ext/src/widgets/chart/swfobject.js

  • Committer: Deng Dongpo
  • Date: 2010-08-01 09:29:44 UTC
  • Revision ID: dongpo@dhcp-21193.iis.sinica.edu.tw-20100801092944-8t9obt4xtl7otesb
initial

Show diffs side-by-side

added added

removed removed

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