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