Subversion Repositories Applications.papyrus

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2150 mathias 1
if(!dojo._hasResource["dojox.flash._common"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2
dojo._hasResource["dojox.flash._common"] = true;
3
dojo.provide("dojox.flash._common");
4
 
5
dojox.flash = function(){
6
	// summary:
7
	//	The goal of dojox.flash is to make it easy to extend Flash's capabilities
8
	//	into an AJAX/DHTML environment.
9
	// description:
10
	//	The goal of dojox.flash is to make it easy to extend Flash's capabilities
11
	//	into an AJAX/DHTML environment. Robust, performant, reliable
12
	//	JavaScript/Flash communication is harder than most realize when they
13
	//	delve into the topic, especially if you want it
14
	//	to work on Internet Explorer, Firefox, and Safari, and to be able to
15
	//	push around hundreds of K of information quickly. dojox.flash makes it
16
	//	possible to support these platforms; you have to jump through a few
17
	//	hoops to get its capabilites, but if you are a library writer
18
	//	who wants to bring Flash's storage or streaming sockets ability into
19
	//	DHTML, for example, then dojox.flash is perfect for you.
20
	//
21
	//	dojox.flash provides an easy object for interacting with the Flash plugin.
22
	//	This object provides methods to determine the current version of the Flash
23
	//	plugin (dojox.flash.info); execute Flash instance methods
24
	//	independent of the Flash version
25
	//	being used (dojox.flash.comm); write out the necessary markup to
26
	//	dynamically insert a Flash object into the page (dojox.flash.Embed; and
27
	//	do dynamic installation and upgrading of the current Flash plugin in
28
	//	use (dojox.flash.Install).
29
	//
30
	//	To use dojox.flash, you must first wait until Flash is finished loading
31
	//	and initializing before you attempt communication or interaction.
32
	//	To know when Flash is finished use dojo.connect:
33
	//
34
	//	dojo.connect(dojox.flash, "loaded", myInstance, "myCallback");
35
	//
36
	//	Then, while the page is still loading provide the file name
37
	//	and the major version of Flash that will be used for Flash/JavaScript
38
	//	communication (see "Flash Communication" below for information on the
39
	//	different kinds of Flash/JavaScript communication supported and how they
40
	//	depend on the version of Flash installed):
41
	//
42
	//	dojox.flash.setSwf({flash6: dojo.moduleUrl("dojox", "_storage/storage_flash6.swf"),
43
	//						flash8: dojo.moduleUrl("dojox", "_storage/storage_flash8.swf")});
44
	//
45
	//	This will cause dojox.flash to pick the best way of communicating
46
	//	between Flash and JavaScript based on the platform.
47
	//
48
	//	If no SWF files are specified, then Flash is not initialized.
49
	//
50
	//	Your Flash must use DojoExternalInterface to expose Flash methods and
51
	//	to call JavaScript; see "Flash Communication" below for details.
52
	//
53
	//	setSwf can take an optional 'visible' attribute to control whether
54
	//	the Flash object is visible or not on the page; the default is visible:
55
	//
56
	//	dojox.flash.setSwf({flash6: dojo.moduleUrl("dojox", "_storage/storage_flash6.swf"),
57
	//						flash8: dojo.moduleUrl("dojox", "_storage/storage_flash8.swf"),
58
	//						visible: false });
59
	//
60
	//	Once finished, you can query Flash version information:
61
	//
62
	//	dojox.flash.info.version
63
	//
64
	//	Or can communicate with Flash methods that were exposed:
65
	//
66
	//	var results = dojox.flash.comm.sayHello("Some Message");
67
	//
68
	//	Only string values are currently supported for both arguments and
69
	//	for return results. Everything will be cast to a string on both
70
	//	the JavaScript and Flash sides.
71
	//
72
	//	-------------------
73
	//	Flash Communication
74
	//	-------------------
75
	//
76
	//	dojox.flash allows Flash/JavaScript communication in
77
	//	a way that can pass large amounts of data back and forth reliably and
78
	//	very fast. The dojox.flash
79
	//	framework encapsulates the specific way in which this communication occurs,
80
	//	presenting a common interface to JavaScript irrespective of the underlying
81
	//	Flash version.
82
	//
83
	//	There are currently three major ways to do Flash/JavaScript communication
84
	//	in the Flash community:
85
	//
86
	//	1) Flash 6+ - Uses Flash methods, such as SetVariable and TCallLabel,
87
	//	and the fscommand handler to do communication. Strengths: Very fast,
88
	//	mature, and can send extremely large amounts of data; can do
89
	//	synchronous method calls. Problems: Does not work on Safari; works on
90
	//	Firefox/Mac OS X only if Flash 8 plugin is installed; cryptic to work with.
91
	//
92
	//	2) Flash 8+ - Uses ExternalInterface, which provides a way for Flash
93
	//	methods to register themselves for callbacks from JavaScript, and a way
94
	//	for Flash to call JavaScript. Strengths: Works on Safari; elegant to
95
	//	work with; can do synchronous method calls. Problems: Extremely buggy
96
	//	(fails if there are new lines in the data, for example); performance
97
	//	degrades drastically in O(n^2) time as data grows; locks up the browser while
98
	//	it is communicating; does not work in Internet Explorer if Flash
99
	//	object is dynamically added to page with document.writeln, DOM methods,
100
	//	or innerHTML.
101
	//
102
	//	3) Flash 6+ - Uses two seperate Flash applets, one that we
103
	//	create over and over, passing input data into it using the PARAM tag,
104
	//	which then uses a Flash LocalConnection to pass the data to the main Flash
105
	//	applet; communication back to Flash is accomplished using a getURL
106
	//	call with a javascript protocol handler, such as "javascript:myMethod()".
107
	//	Strengths: the most cross browser, cross platform pre-Flash 8 method
108
	//	of Flash communication known; works on Safari. Problems: Timing issues;
109
	//	clunky and complicated; slow; can only send very small amounts of
110
	//	data (several K); all method calls are asynchronous.
111
	//
112
	//	dojox.flash.comm uses only the first two methods. This framework
113
	//	was created primarily for dojox.storage, which needs to pass very large
114
	//	amounts of data synchronously and reliably across the Flash/JavaScript
115
	//	boundary. We use the first method, the Flash 6 method, on all platforms
116
	//	that support it, while using the Flash 8 ExternalInterface method
117
	//	only on Safari with some special code to help correct ExternalInterface's
118
	//	bugs.
119
	//
120
	//	Since dojox.flash needs to have two versions of the Flash
121
	//	file it wants to generate, a Flash 6 and a Flash 8 version to gain
122
	//	true cross-browser compatibility, several tools are provided to ease
123
	//	development on the Flash side.
124
	//
125
	//	In your Flash file, if you want to expose Flash methods that can be
126
	//	called, use the DojoExternalInterface class to register methods. This
127
	//	class is an exact API clone of the standard ExternalInterface class, but
128
	//	can work in Flash 6+ browsers. Under the covers it uses the best
129
	//	mechanism to do communication:
130
	//
131
	//	class HelloWorld{
132
	//		function HelloWorld(){
133
	//			// Initialize the DojoExternalInterface class
134
	//			DojoExternalInterface.initialize();
135
	//
136
	//			// Expose your methods
137
	//			DojoExternalInterface.addCallback("sayHello", this, this.sayHello);
138
	//
139
	//			// Tell JavaScript that you are ready to have method calls
140
	//			DojoExternalInterface.loaded();
141
	//
142
	//			// Call some JavaScript
143
	//			var resultsReady = function(results){
144
	//				trace("Received the following results from JavaScript: " + results);
145
	//			}
146
	//			DojoExternalInterface.call("someJavaScriptMethod", resultsReady,
147
	//																	 someParameter);
148
	//		}
149
	//
150
	//		function sayHello(){ ... }
151
	//
152
	//		static main(){ ... }
153
	//	}
154
	//
155
	//	DojoExternalInterface adds two new functions to the ExternalInterface
156
	//	API: initialize() and loaded(). initialize() must be called before
157
	//	any addCallback() or call() methods are run, and loaded() must be
158
	//	called after you are finished adding your callbacks. Calling loaded()
159
	//	will fire the dojox.flash.loaded() event, so that JavaScript can know that
160
	//	Flash has finished loading and adding its callbacks, and can begin to
161
	//	interact with the Flash file.
162
	//
163
	//	To generate your SWF files, use the ant task
164
	//	"buildFlash". You must have the open source Motion Twin ActionScript
165
	//	compiler (mtasc) installed and in your path to use the "buildFlash"
166
	//	ant task; download and install mtasc from http://www.mtasc.org/.
167
	//
168
	//
169
	//
170
	//	buildFlash usage:
171
	//
172
	//	// FIXME: this is not correct in the 0.9 world!
173
	//	ant buildFlash -Ddojox.flash.file=../tests/flash/HelloWorld.as
174
	//
175
	//	where "dojox.flash.file" is the relative path to your Flash
176
	//	ActionScript file.
177
	//
178
	//	This will generate two SWF files, one ending in _flash6.swf and the other
179
	//	ending in _flash8.swf in the same directory as your ActionScript method:
180
	//
181
	//	HelloWorld_flash6.swf
182
	//	HelloWorld_flash8.swf
183
	//
184
	//	Initialize dojox.flash with the filename and Flash communication version to
185
	//	use during page load; see the documentation for dojox.flash for details:
186
	//
187
	//	dojox.flash.setSwf({flash6: dojo.moduleUrl("dojox", "flash/tests/flash/HelloWorld_flash6.swf"),
188
	//					 	flash8: dojo.moduleUrl("dojox", "flash/tests/flash/HelloWorld_flash8.swf")});
189
	//
190
	//	Now, your Flash methods can be called from JavaScript as if they are native
191
	//	Flash methods, mirrored exactly on the JavaScript side:
192
	//
193
	//	dojox.flash.comm.sayHello();
194
	//
195
	//	Only Strings are supported being passed back and forth currently.
196
	//
197
	//	JavaScript to Flash communication is synchronous; i.e., results are returned
198
	//	directly from the method call:
199
	//
200
	//	var results = dojox.flash.comm.sayHello();
201
	//
202
	//	Flash to JavaScript communication is asynchronous due to limitations in
203
	//	the underlying technologies; you must use a results callback to handle
204
	//	results returned by JavaScript in your Flash AS files:
205
	//
206
	//	var resultsReady = function(results){
207
	//		trace("Received the following results from JavaScript: " + results);
208
	//	}
209
	//	DojoExternalInterface.call("someJavaScriptMethod", resultsReady);
210
	//
211
	//
212
	//
213
	//	-------------------
214
	//	Notes
215
	//	-------------------
216
	//
217
	//	If you have both Flash 6 and Flash 8 versions of your file:
218
	//
219
	//	dojox.flash.setSwf({flash6: dojo.moduleUrl("dojox", "flash/tests/flash/HelloWorld_flash6.swf"),
220
	//					 	flash8: dojo.moduleUrl("dojox", "flash/tests/flash/HelloWorld_flash8.swf")});
221
	//
222
	//	but want to force the browser to use a certain version of Flash for
223
	//	all platforms (for testing, for example), use the djConfig
224
	//	variable 'forceFlashComm' with the version number to force:
225
	//
226
	//	var djConfig = { forceFlashComm: 6 };
227
	//
228
	//	Two values are currently supported, 6 and 8, for the two styles of
229
	//	communication described above. Just because you force dojox.flash
230
	//	to use a particular communication style is no guarantee that it will
231
	//	work; for example, Flash 8 communication doesn't work in Internet
232
	//	Explorer due to bugs in Flash, and Flash 6 communication does not work
233
	//	in Safari. It is best to let dojox.flash determine the best communication
234
	//	mechanism, and to use the value above only for debugging the dojox.flash
235
	//	framework itself.
236
	//
237
	//	Also note that dojox.flash can currently only work with one Flash object
238
	//	on the page; it and the API do not yet support multiple Flash objects on
239
	//	the same page.
240
	//
241
	//	We use some special tricks to get decent, linear performance
242
	//	out of Flash 8's ExternalInterface on Safari; see the blog
243
	//	post
244
	//	http://codinginparadise.org/weblog/2006/02/how-to-speed-up-flash-8s.html
245
	//	for details.
246
	//
247
	//	Your code can detect whether the Flash player is installing or having
248
	//	its version revved in two ways. First, if dojox.flash detects that
249
	//	Flash installation needs to occur, it sets dojox.flash.info.installing
250
	//	to true. Second, you can detect if installation is necessary with the
251
	//	following callback:
252
	//
253
	//	dojo.connect(dojox.flash, "installing", myInstance, "myCallback");
254
	//
255
	//	You can use this callback to delay further actions that might need Flash;
256
	//	when installation is finished the full page will be refreshed and the
257
	//	user will be placed back on your page with Flash installed.
258
	//
259
	//	-------------------
260
	//	Todo/Known Issues
261
	//	-------------------
262
	//
263
	//	There are several tasks I was not able to do, or did not need to fix
264
	//	to get dojo.storage out:
265
	//
266
	//	* When using Flash 8 communication, Flash method calls to JavaScript
267
	//	are not working properly; serialization might also be broken for certain
268
	//	invalid characters when it is Flash invoking JavaScript methods.
269
	//	The Flash side needs to have more sophisticated serialization/
270
	//	deserialization mechanisms like JavaScript currently has. The
271
	//	test_flash2.html unit tests should also be updated to have much more
272
	//	sophisticated Flash to JavaScript unit tests, including large
273
	//	amounts of data.
274
	//
275
	//	* On Internet Explorer, after doing a basic install, the page is
276
	//	not refreshed or does not detect that Flash is now available. The way
277
	//	to fix this is to create a custom small Flash file that is pointed to
278
	//	during installation; when it is finished loading, it does a callback
279
	//	that says that Flash installation is complete on IE, and we can proceed
280
	//	to initialize the dojox.flash subsystem.
281
	//
282
	//	Author- Brad Neuberg, bkn3@columbia.edu
283
}
284
 
285
dojox.flash = {
286
	flash6_version: null,
287
	flash8_version: null,
288
	ready: false,
289
	_visible: true,
290
	_loadedListeners: new Array(),
291
	_installingListeners: new Array(),
292
 
293
	setSwf: function(/* Object */ fileInfo){
294
		// summary: Sets the SWF files and versions we are using.
295
		// fileInfo: Object
296
		//		An object that contains two attributes, 'flash6' and 'flash8',
297
		//		each of which contains the path to our Flash 6 and Flash 8
298
		//		versions of the file we want to script.
299
		//	example:
300
		//		var swfloc6 = dojo.moduleUrl("dojox.storage", "Storage_version6.swf").toString();
301
		//		var swfloc8 = dojo.moduleUrl("dojox.storage", "Storage_version8.swf").toString();
302
		//		dojox.flash.setSwf({flash6: swfloc6, flash8: swfloc8, visible: false});
303
 
304
		if(!fileInfo){
305
			return;
306
		}
307
 
308
		if(fileInfo["flash6"]){
309
			this.flash6_version = fileInfo.flash6;
310
		}
311
 
312
		if(fileInfo["flash8"]){
313
			this.flash8_version = fileInfo.flash8;
314
		}
315
 
316
		if(fileInfo["visible"]){
317
			this._visible = fileInfo.visible;
318
		}
319
 
320
		// initialize ourselves
321
		this._initialize();
322
	},
323
 
324
	useFlash6: function(){ /* Boolean */
325
		// summary: Returns whether we are using Flash 6 for communication on this platform.
326
 
327
		if(this.flash6_version == null){
328
			return false;
329
		}else if (this.flash6_version != null && dojox.flash.info.commVersion == 6){
330
			// if we have a flash 6 version of this SWF, and this browser supports
331
			// communicating using Flash 6 features...
332
			return true;
333
		}else{
334
			return false;
335
		}
336
	},
337
 
338
	useFlash8: function(){ /* Boolean */
339
		// summary: Returns whether we are using Flash 8 for communication on this platform.
340
 
341
		if(this.flash8_version == null){
342
			return false;
343
		}else if (this.flash8_version != null && dojox.flash.info.commVersion == 8){
344
			// if we have a flash 8 version of this SWF, and this browser supports
345
			// communicating using Flash 8 features...
346
			return true;
347
		}else{
348
			return false;
349
		}
350
	},
351
 
352
	addLoadedListener: function(/* Function */ listener){
353
		// summary:
354
		//	Adds a listener to know when Flash is finished loading.
355
		//	Useful if you don't want a dependency on dojo.event.
356
		// listener: Function
357
		//	A function that will be called when Flash is done loading.
358
 
359
		this._loadedListeners.push(listener);
360
	},
361
 
362
	addInstallingListener: function(/* Function */ listener){
363
		// summary:
364
		//	Adds a listener to know if Flash is being installed.
365
		//	Useful if you don't want a dependency on dojo.event.
366
		// listener: Function
367
		//	A function that will be called if Flash is being
368
		//	installed
369
 
370
		this._installingListeners.push(listener);
371
	},
372
 
373
	loaded: function(){
374
		// summary: Called back when the Flash subsystem is finished loading.
375
		// description:
376
		//	A callback when the Flash subsystem is finished loading and can be
377
		//	worked with. To be notified when Flash is finished loading, connect
378
		//	your callback to this method using the following:
379
		//
380
		//	dojo.event.connect(dojox.flash, "loaded", myInstance, "myCallback");
381
 
382
		//dojo.debug("dojox.flash.loaded");
383
		dojox.flash.ready = true;
384
		if(dojox.flash._loadedListeners.length > 0){
385
			for(var i = 0;i < dojox.flash._loadedListeners.length; i++){
386
				dojox.flash._loadedListeners[i].call(null);
387
			}
388
		}
389
	},
390
 
391
	installing: function(){
392
		// summary: Called if Flash is being installed.
393
		// description:
394
		//	A callback to know if Flash is currently being installed or
395
		//	having its version revved. To be notified if Flash is installing, connect
396
		//	your callback to this method using the following:
397
		//
398
		//	dojo.event.connect(dojox.flash, "installing", myInstance, "myCallback");
399
 
400
		//dojo.debug("installing");
401
		if(dojox.flash._installingListeners.length > 0){
402
			for(var i = 0; i < dojox.flash._installingListeners.length; i++){
403
				dojox.flash._installingListeners[i].call(null);
404
			}
405
		}
406
	},
407
 
408
	// Initializes dojox.flash.
409
	_initialize: function(){
410
		//dojo.debug("dojox.flash._initialize");
411
		// see if we need to rev or install Flash on this platform
412
		var installer = new dojox.flash.Install();
413
		dojox.flash.installer = installer;
414
 
415
		if(installer.needed() == true){
416
			installer.install();
417
		}else{
418
			//dojo.debug("Writing object out");
419
			// write the flash object into the page
420
			dojox.flash.obj = new dojox.flash.Embed(this._visible);
421
			dojox.flash.obj.write(dojox.flash.info.commVersion);
422
 
423
			// initialize the way we do Flash/JavaScript communication
424
			dojox.flash.comm = new dojox.flash.Communicator();
425
		}
426
	}
427
};
428
 
429
 
430
dojox.flash.Info = function(){
431
	// summary: A class that helps us determine whether Flash is available.
432
	// description:
433
	//	A class that helps us determine whether Flash is available,
434
	//	it's major and minor versions, and what Flash version features should
435
	//	be used for Flash/JavaScript communication. Parts of this code
436
	//	are adapted from the automatic Flash plugin detection code autogenerated
437
	//	by the Macromedia Flash 8 authoring environment.
438
	//
439
	//	An instance of this class can be accessed on dojox.flash.info after
440
	//	the page is finished loading.
441
	//
442
	//	This constructor must be called before the page is finished loading.
443
 
444
	// Visual basic helper required to detect Flash Player ActiveX control
445
	// version information on Internet Explorer
446
	if(dojo.isIE){
447
		document.write([
448
			'<script language="VBScript" type="text/vbscript"\>',
449
			'Function VBGetSwfVer(i)',
450
			'  on error resume next',
451
			'  Dim swControl, swVersion',
452
			'  swVersion = 0',
453
			'  set swControl = CreateObject("ShockwaveFlash.ShockwaveFlash." + CStr(i))',
454
			'  if (IsObject(swControl)) then',
455
			'    swVersion = swControl.GetVariable("$version")',
456
			'  end if',
457
			'  VBGetSwfVer = swVersion',
458
			'End Function',
459
			'</script\>'].join("\r\n"));
460
	}
461
 
462
	this._detectVersion();
463
	this._detectCommunicationVersion();
464
}
465
 
466
dojox.flash.Info.prototype = {
467
	// version: String
468
	//		The full version string, such as "8r22".
469
	version: -1,
470
 
471
	// versionMajor, versionMinor, versionRevision: String
472
	//		The major, minor, and revisions of the plugin. For example, if the
473
	//		plugin is 8r22, then the major version is 8, the minor version is 0,
474
	//		and the revision is 22.
475
	versionMajor: -1,
476
	versionMinor: -1,
477
	versionRevision: -1,
478
 
479
	// capable: Boolean
480
	//		Whether this platform has Flash already installed.
481
	capable: false,
482
 
483
	// commVersion: int
484
	//		The major version number for how our Flash and JavaScript communicate.
485
	//		This can currently be the following values:
486
	//		6 - We use a combination of the Flash plugin methods, such as SetVariable
487
	//		and TCallLabel, along with fscommands, to do communication.
488
	//		8 - We use the ExternalInterface API.
489
	//		-1 - For some reason neither method is supported, and no communication
490
	//		is possible.
491
	commVersion: 6,
492
 
493
	// installing: Boolean
494
	//	Set if we are in the middle of a Flash installation session.
495
	installing: false,
496
 
497
	isVersionOrAbove: function(
498
							/* int */ reqMajorVer,
499
							/* int */ reqMinorVer,
500
							/* int */ reqVer){ /* Boolean */
501
		// summary:
502
		//	Asserts that this environment has the given major, minor, and revision
503
		//	numbers for the Flash player.
504
		// description:
505
		//	Asserts that this environment has the given major, minor, and revision
506
		//	numbers for the Flash player.
507
		//
508
		//	Example- To test for Flash Player 7r14:
509
		//
510
		//	dojox.flash.info.isVersionOrAbove(7, 0, 14)
511
		// returns:
512
		//	Returns true if the player is equal
513
		//	or above the given version, false otherwise.
514
 
515
		// make the revision a decimal (i.e. transform revision 14 into
516
		// 0.14
517
		reqVer = parseFloat("." + reqVer);
518
 
519
		if(this.versionMajor >= reqMajorVer && this.versionMinor >= reqMinorVer
520
			 && this.versionRevision >= reqVer){
521
			return true;
522
		}else{
523
			return false;
524
		}
525
	},
526
 
527
	getResourceList: function(/*string*/ swfloc6, /*String*/ swfloc8){ /*String[]*/
528
		// summary:
529
		//		Returns all resources required for embedding.
530
		// description:
531
		//		This is a convenience method for Dojo Offline, meant to
532
		//		encapsulate us from the specific resources necessary for
533
		//		embedding. Dojo Offline requires that we sync our offline
534
		//		resources for offline availability; this method will return all
535
		//		offline resources, including any possible query parameters that
536
		//		might be used since caches treat resources with query
537
		//		parameters as different than ones that have query parameters.
538
		//		If offline and we request a resource with a query parameter
539
		//		that was not cached with a query parameter, then we will have a
540
		//		cache miss and not be able to work offline
541
		var results = [];
542
 
543
		// flash 6
544
		var swfloc = swfloc6;
545
		results.push(swfloc);
546
		swfloc = swfloc + "?baseRelativePath=" + escape(dojo.baseUrl); // FIXME: should this be encodeURIComponent?
547
		results.push(swfloc);
548
		// Safari has a strange bug where it appends '%20'%20quality=
549
		// to the end of Flash movies taken through XHR while offline;
550
		// append this so we don't get a cache miss
551
		swfloc += "'%20'%20quality=";
552
		results.push(swfloc);
553
 
554
		// flash 8
555
		swfloc = swfloc8;
556
		results.push(swfloc);
557
		swfloc +=  "?baseRelativePath="+escape(dojo.baseUrl); // FIXME: should this be encodeURIComponent?
558
		results.push(swfloc);
559
		// Safari has a strange bug where it appends '%20'%20quality=
560
		// to the end of Flash movies taken through XHR while offline;
561
		// append this so we don't get a cache miss
562
		swfloc += "'%20'%20quality=";
563
		results.push(swfloc);
564
 
565
		// flash 6 gateway
566
		results.push(dojo.moduleUrl("dojox", "flash/flash6/flash6_gateway.swf")+"");
567
 
568
		return results;
569
	},
570
 
571
	_detectVersion: function(){
572
		var versionStr;
573
 
574
		// loop backwards through the versions until we find the newest version
575
		for(var testVersion = 25; testVersion > 0; testVersion--){
576
			if(dojo.isIE){
577
				versionStr = VBGetSwfVer(testVersion);
578
			}else{
579
				versionStr = this._JSFlashInfo(testVersion);
580
			}
581
 
582
			if(versionStr == -1 ){
583
				this.capable = false;
584
				return;
585
			}else if(versionStr != 0){
586
				var versionArray;
587
				if(dojo.isIE){
588
					var tempArray = versionStr.split(" ");
589
					var tempString = tempArray[1];
590
					versionArray = tempString.split(",");
591
				}else{
592
					versionArray = versionStr.split(".");
593
				}
594
 
595
				this.versionMajor = versionArray[0];
596
				this.versionMinor = versionArray[1];
597
				this.versionRevision = versionArray[2];
598
 
599
				// 7.0r24 == 7.24
600
				var versionString = this.versionMajor + "." + this.versionRevision;
601
				this.version = parseFloat(versionString);
602
 
603
				this.capable = true;
604
 
605
				break;
606
			}
607
		}
608
	},
609
 
610
	// JavaScript helper required to detect Flash Player PlugIn version
611
	// information. Internet Explorer uses a corresponding Visual Basic
612
	// version to interact with the Flash ActiveX control.
613
	_JSFlashInfo: function(testVersion){
614
		// NS/Opera version >= 3 check for Flash plugin in plugin array
615
		if(navigator.plugins != null && navigator.plugins.length > 0){
616
			if(navigator.plugins["Shockwave Flash 2.0"] ||
617
				 navigator.plugins["Shockwave Flash"]){
618
				var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
619
				var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
620
				var descArray = flashDescription.split(" ");
621
				var tempArrayMajor = descArray[2].split(".");
622
				var versionMajor = tempArrayMajor[0];
623
				var versionMinor = tempArrayMajor[1];
624
				if(descArray[3] != ""){
625
					var tempArrayMinor = descArray[3].split("r");
626
				}else{
627
					var tempArrayMinor = descArray[4].split("r");
628
				}
629
				var versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0;
630
				var version = versionMajor + "." + versionMinor + "."
631
											+ versionRevision;
632
 
633
				return version;
634
			}
635
		}
636
 
637
		return -1;
638
	},
639
 
640
	// Detects the mechanisms that should be used for Flash/JavaScript
641
	// communication, setting 'commVersion' to either 6 or 8. If the value is
642
	// 6, we use Flash Plugin 6+ features, such as GetVariable, TCallLabel,
643
	// and fscommand, to do Flash/JavaScript communication; if the value is
644
	// 8, we use the ExternalInterface API for communication.
645
	_detectCommunicationVersion: function(){
646
		if(this.capable == false){
647
			this.commVersion = null;
648
			return;
649
		}
650
 
651
		// detect if the user has over-ridden the default flash version
652
		if (typeof djConfig["forceFlashComm"] != "undefined" &&
653
				typeof djConfig["forceFlashComm"] != null){
654
			this.commVersion = djConfig["forceFlashComm"];
655
			return;
656
		}
657
 
658
		// we prefer Flash 6 features over Flash 8, because they are much faster
659
		// and much less buggy
660
 
661
		// at this point, we don't have a flash file to detect features on,
662
		// so we need to instead look at the browser environment we are in
663
		if(dojo.isSafari||dojo.isOpera){
664
			this.commVersion = 8;
665
		}else{
666
			this.commVersion = 6;
667
		}
668
	}
669
};
670
 
671
dojox.flash.Embed = function(visible){
672
	// summary: A class that is used to write out the Flash object into the page.
673
 
674
	this._visible = visible;
675
}
676
 
677
dojox.flash.Embed.prototype = {
678
	// width: int
679
	//	The width of this Flash applet. The default is the minimal width
680
	//	necessary to show the Flash settings dialog. Current value is
681
	//  215 pixels.
682
	width: 215,
683
 
684
	// height: int
685
	//	The height of this Flash applet. The default is the minimal height
686
	//	necessary to show the Flash settings dialog. Current value is
687
	// 138 pixels.
688
	height: 138,
689
 
690
	// id: String
691
	// 	The id of the Flash object. Current value is 'flashObject'.
692
	id: "flashObject",
693
 
694
	// Controls whether this is a visible Flash applet or not.
695
	_visible: true,
696
 
697
	protocol: function(){
698
		switch(window.location.protocol){
699
			case "https:":
700
				return "https";
701
				break;
702
			default:
703
				return "http";
704
				break;
705
		}
706
	},
707
 
708
	write: function(/* String */ flashVer, /* Boolean? */ doExpressInstall){
709
		// summary: Writes the Flash into the page.
710
		// description:
711
		//	This must be called before the page
712
		//	is finished loading.
713
		// flashVer: String
714
		//	The Flash version to write.
715
		// doExpressInstall: Boolean
716
		//	Whether to write out Express Install
717
		//	information. Optional value; defaults to false.
718
 
719
		//dojo.debug("write");
720
		doExpressInstall = !!doExpressInstall;
721
 
722
		// determine our container div's styling
723
		var containerStyle = "";
724
		containerStyle += ("width: " + this.width + "px; ");
725
		containerStyle += ("height: " + this.height + "px; ");
726
		if(this._visible == false){
727
			containerStyle += "position: absolute; z-index: 10000; top: -1000px; left: -1000px; ";
728
		}
729
 
730
		// figure out the SWF file to get and how to write out the correct HTML
731
		// for this Flash version
732
		var objectHTML;
733
		var swfloc;
734
		// Flash 6
735
		if(flashVer == 6){
736
			swfloc = dojox.flash.flash6_version;
737
			var dojoPath = djConfig.baseRelativePath;
738
			swfloc = swfloc + "?baseRelativePath=" + escape(dojoPath);
739
			objectHTML =
740
						  '<embed id="' + this.id + '" src="' + swfloc + '" '
741
						+ '    quality="high" bgcolor="#ffffff" '
742
						+ '    width="' + this.width + '" height="' + this.height + '" '
743
						+ '    name="' + this.id + '" '
744
						+ '    align="middle" allowScriptAccess="sameDomain" '
745
						+ '    type="application/x-shockwave-flash" swLiveConnect="true" '
746
						+ '    pluginspage="'
747
						+ this.protocol()
748
						+ '://www.macromedia.com/go/getflashplayer">';
749
		}else{ // Flash 8
750
			swfloc = dojox.flash.flash8_version;
751
			var swflocObject = swfloc;
752
			var swflocEmbed = swfloc;
753
			var dojoPath = djConfig.baseRelativePath;
754
			if(doExpressInstall){
755
				// the location to redirect to after installing
756
				var redirectURL = escape(window.location);
757
				document.title = document.title.slice(0, 47) + " - Flash Player Installation";
758
				var docTitle = escape(document.title);
759
				swflocObject += "?MMredirectURL=" + redirectURL
760
				                + "&MMplayerType=ActiveX"
761
				                + "&MMdoctitle=" + docTitle
762
								+ "&baseRelativePath=" + escape(dojoPath);
763
				swflocEmbed += "?MMredirectURL=" + redirectURL
764
								+ "&MMplayerType=PlugIn"
765
								+ "&baseRelativePath=" + escape(dojoPath);
766
			}
767
 
768
			if(swflocEmbed.indexOf("?") == -1){
769
				swflocEmbed +=  "?baseRelativePath="+escape(dojoPath)+"' ";
770
			}
771
 
772
			objectHTML =
773
				'<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '
774
				  + 'codebase="'
775
					+ this.protocol()
776
					+ '://fpdownload.macromedia.com/pub/shockwave/cabs/flash/'
777
					+ 'swflash.cab#version=8,0,0,0" '
778
				  + 'width="' + this.width + '" '
779
				  + 'height="' + this.height + '" '
780
				  + 'id="' + this.id + '" '
781
				  + 'align="middle"> '
782
				  + '<param name="allowScriptAccess" value="sameDomain" /> '
783
				  + '<param name="movie" value="' + swflocObject + '" /> '
784
				  + '<param name="quality" value="high" /> '
785
				  + '<param name="bgcolor" value="#ffffff" /> '
786
				  + '<embed src="' + swflocEmbed + "' "
787
				  + 'quality="high" '
788
				  + 'bgcolor="#ffffff" '
789
				  + 'width="' + this.width + '" '
790
				  + 'height="' + this.height + '" '
791
				  + 'id="' + this.id + '" '
792
				  + 'name="' + this.id + '" '
793
				  + 'swLiveConnect="true" '
794
				  + 'align="middle" '
795
				  + 'allowScriptAccess="sameDomain" '
796
				  + 'type="application/x-shockwave-flash" '
797
				  + 'pluginspage="'
798
					+ this.protocol()
799
					+'://www.macromedia.com/go/getflashplayer" />'
800
				+ '</object>';
801
		}
802
 
803
		// now write everything out
804
		objectHTML = '<div id="' + this.id + 'Container" style="' + containerStyle + '"> '
805
						+ objectHTML
806
					 + '</div>';
807
		document.writeln(objectHTML);
808
	},
809
 
810
	get: function(){ /* Object */
811
		// summary: Gets the Flash object DOM node.
812
 
813
		//return (dojo.render.html.ie) ? window[this.id] : document[this.id];
814
 
815
		// more robust way to get Flash object; version above can break
816
		// communication on IE sometimes
817
		return document.getElementById(this.id);
818
	},
819
 
820
	setVisible: function(/* Boolean */ visible){
821
		// summary: Sets the visibility of this Flash object.
822
 
823
		var container = dojo.byId(this.id + "Container");
824
		if(visible == true){
825
			container.style.visibility = "visible";
826
		}else{
827
			container.style.position = "absolute";
828
			container.style.x = "-1000px";
829
			container.style.y = "-1000px";
830
			container.style.visibility = "hidden";
831
		}
832
	},
833
 
834
	center: function(){
835
		// summary: Centers the flash applet on the page.
836
 
837
		/*
838
		var elementWidth = this.width;
839
		var elementHeight = this.height;
840
 
841
		var scroll_offset = dojo._docScroll();
842
		var viewport_size = dojo.html.getViewport();
843
 
844
		// compute the centered position
845
		var x = scroll_offset.x + (viewport_size.width - elementWidth) / 2;
846
		var y = scroll_offset.y + (viewport_size.height - elementHeight) / 2;
847
		*/
848
		var x = 100;
849
		var y = 100;
850
 
851
		// set the centered position
852
		var container = dojo.byId(this.id + "Container");
853
		container.style.top = y + "px";
854
		container.style.left = x + "px";
855
	}
856
};
857
 
858
 
859
dojox.flash.Communicator = function(){
860
	// summary:
861
	//	A class that is used to communicate between Flash and JavaScript in
862
	//	a way that can pass large amounts of data back and forth reliably,
863
	//	very fast, and with synchronous method calls.
864
	// description:
865
	//	A class that is used to communicate between Flash and JavaScript in
866
	//	a way that can pass large amounts of data back and forth reliably,
867
	//	very fast, and with synchronous method calls. This class encapsulates the
868
	//	specific way in which this communication occurs,
869
	//	presenting a common interface to JavaScript irrespective of the underlying
870
	//	Flash version.
871
 
872
	if(dojox.flash.useFlash6()){
873
		this._writeFlash6();
874
	}else if(dojox.flash.useFlash8()){
875
		this._writeFlash8();
876
	}
877
}
878
 
879
dojox.flash.Communicator.prototype = {
880
	_writeFlash6: function(){
881
		var id = dojox.flash.obj.id;
882
 
883
		// global function needed for Flash 6 callback;
884
		// we write it out as a script tag because the VBScript hook for IE
885
		// callbacks does not work properly if this function is evalled() from
886
		// within the Dojo system
887
		document.writeln('<script language="JavaScript">');
888
		document.writeln('  function ' + id + '_DoFSCommand(command, args){ ');
889
		document.writeln('    dojox.flash.comm._handleFSCommand(command, args); ');
890
		document.writeln('}');
891
		document.writeln('</script>');
892
 
893
		// hook for Internet Explorer to receive FSCommands from Flash
894
		if(dojo.isIE){
895
			document.writeln('<SCRIPT LANGUAGE=VBScript\> ');
896
			document.writeln('on error resume next ');
897
			document.writeln('Sub ' + id + '_FSCommand(ByVal command, ByVal args)');
898
			document.writeln(' call ' + id + '_DoFSCommand(command, args)');
899
			document.writeln('end sub');
900
			document.writeln('</SCRIPT\> ');
901
		}
902
	},
903
 
904
	_writeFlash8: function(){
905
		// nothing needs to be written out for Flash 8 communication;
906
		// happens automatically
907
	},
908
 
909
	//Flash 6 communication.
910
 
911
	// Handles fscommand's from Flash to JavaScript. Flash 6 communication.
912
	_handleFSCommand: function(command, args){
913
		//console.debug("fscommand, command="+command+", args="+args);
914
		// Flash 8 on Mac/Firefox precedes all commands with the string "FSCommand:";
915
		// strip it off if it is present
916
		if((command) && dojo.isString(command) && (/^FSCommand:(.*)/.test(command) == true)){
917
			command = command.match(/^FSCommand:(.*)/)[1];
918
		}
919
 
920
		if(command == "addCallback"){ // add Flash method for JavaScript callback
921
			this._fscommandAddCallback(command, args);
922
		}else if(command == "call"){ // Flash to JavaScript method call
923
			this._fscommandCall(command, args);
924
		}else if(command == "fscommandReady"){ // see if fscommands are ready
925
			this._fscommandReady();
926
		}
927
	},
928
 
929
	// Handles registering a callable Flash function. Flash 6 communication.
930
	_fscommandAddCallback: function(command, args){
931
		var functionName = args;
932
 
933
		// do a trick, where we link this function name to our wrapper
934
		// function, _call, that does the actual JavaScript to Flash call
935
		var callFunc = function(){
936
			return dojox.flash.comm._call(functionName, arguments);
937
		};
938
		dojox.flash.comm[functionName] = callFunc;
939
 
940
		// indicate that the call was successful
941
		dojox.flash.obj.get().SetVariable("_succeeded", true);
942
	},
943
 
944
	// Handles Flash calling a JavaScript function. Flash 6 communication.
945
	_fscommandCall: function(command, args){
946
		var plugin = dojox.flash.obj.get();
947
		var functionName = args;
948
 
949
		// get the number of arguments to this method call and build them up
950
		var numArgs = parseInt(plugin.GetVariable("_numArgs"));
951
		var flashArgs = new Array();
952
		for(var i = 0; i < numArgs; i++){
953
			var currentArg = plugin.GetVariable("_" + i);
954
			flashArgs.push(currentArg);
955
		}
956
 
957
		// get the function instance; we technically support more capabilities
958
		// than ExternalInterface, which can only call global functions; if
959
		// the method name has a dot in it, such as "dojox.flash.loaded", we
960
		// eval it so that the method gets run against an instance
961
		var runMe;
962
		if(functionName.indexOf(".") == -1){ // global function
963
			runMe = window[functionName];
964
		}else{
965
			// instance function
966
			runMe = eval(functionName);
967
		}
968
 
969
		// make the call and get the results
970
		var results = null;
971
		if(dojo.isFunction(runMe)){
972
			results = runMe.apply(null, flashArgs);
973
		}
974
 
975
		// return the results to flash
976
		plugin.SetVariable("_returnResult", results);
977
	},
978
 
979
	// Reports that fscommands are ready to run if executed from Flash.
980
	_fscommandReady: function(){
981
		var plugin = dojox.flash.obj.get();
982
		plugin.SetVariable("fscommandReady", "true");
983
	},
984
 
985
	// The actual function that will execute a JavaScript to Flash call; used
986
	// by the Flash 6 communication method.
987
	_call: function(functionName, args){
988
		// we do JavaScript to Flash method calls by setting a Flash variable
989
		// "_functionName" with the function name; "_numArgs" with the number
990
		// of arguments; and "_0", "_1", etc for each numbered argument. Flash
991
		// reads these, executes the function call, and returns the result
992
		// in "_returnResult"
993
		var plugin = dojox.flash.obj.get();
994
		plugin.SetVariable("_functionName", functionName);
995
		plugin.SetVariable("_numArgs", args.length);
996
		for(var i = 0; i < args.length; i++){
997
			// unlike Flash 8's ExternalInterface, Flash 6 has no problem with
998
			// any special characters _except_ for the null character \0; double
999
			// encode this so the Flash side never sees it, but we can get it
1000
			// back if the value comes back to JavaScript
1001
			var value = args[i];
1002
			value = value.replace(/\0/g, "\\0");
1003
 
1004
			plugin.SetVariable("_" + i, value);
1005
		}
1006
 
1007
		// now tell Flash to execute this method using the Flash Runner
1008
		plugin.TCallLabel("/_flashRunner", "execute");
1009
 
1010
		// get the results
1011
		var results = plugin.GetVariable("_returnResult");
1012
 
1013
		// we double encoded all null characters as //0 because Flash breaks
1014
		// if they are present; turn the //0 back into /0
1015
		results = results.replace(/\\0/g, "\0");
1016
 
1017
		return results;
1018
	},
1019
 
1020
	// Flash 8 communication.
1021
 
1022
	// Registers the existence of a Flash method that we can call with
1023
	// JavaScript, using Flash 8's ExternalInterface.
1024
	_addExternalInterfaceCallback: function(methodName){
1025
		var wrapperCall = function(){
1026
			// some browsers don't like us changing values in the 'arguments' array, so
1027
			// make a fresh copy of it
1028
			var methodArgs = new Array(arguments.length);
1029
			for(var i = 0; i < arguments.length; i++){
1030
				methodArgs[i] = arguments[i];
1031
			}
1032
			return dojox.flash.comm._execFlash(methodName, methodArgs);
1033
		};
1034
 
1035
		dojox.flash.comm[methodName] = wrapperCall;
1036
	},
1037
 
1038
	// Encodes our data to get around ExternalInterface bugs.
1039
	// Flash 8 communication.
1040
	_encodeData: function(data){
1041
		// double encode all entity values, or they will be mis-decoded
1042
		// by Flash when returned
1043
		var entityRE = /\&([^;]*)\;/g;
1044
		data = data.replace(entityRE, "&amp;$1;");
1045
 
1046
		// entity encode XML-ish characters, or Flash's broken XML serializer
1047
		// breaks
1048
		data = data.replace(/</g, "&lt;");
1049
		data = data.replace(/>/g, "&gt;");
1050
 
1051
		// transforming \ into \\ doesn't work; just use a custom encoding
1052
		data = data.replace("\\", "&custom_backslash;&custom_backslash;");
1053
 
1054
		data = data.replace(/\n/g, "\\n");
1055
		data = data.replace(/\r/g, "\\r");
1056
		data = data.replace(/\f/g, "\\f");
1057
		data = data.replace(/\0/g, "\\0"); // null character
1058
		data = data.replace(/\'/g, "\\\'");
1059
		data = data.replace(/\"/g, '\\\"');
1060
 
1061
		return data;
1062
	},
1063
 
1064
	// Decodes our data to get around ExternalInterface bugs.
1065
	// Flash 8 communication.
1066
	_decodeData: function(data){
1067
		if(data == null || typeof data == "undefined"){
1068
			return data;
1069
		}
1070
 
1071
		// certain XMLish characters break Flash's wire serialization for
1072
		// ExternalInterface; these are encoded on the
1073
		// DojoExternalInterface side into a custom encoding, rather than
1074
		// the standard entity encoding, because otherwise we won't be able to
1075
		// differentiate between our own encoding and any entity characters
1076
		// that are being used in the string itself
1077
		data = data.replace(/\&custom_lt\;/g, "<");
1078
		data = data.replace(/\&custom_gt\;/g, ">");
1079
 
1080
		// Unfortunately, Flash returns us our String with special characters
1081
		// like newlines broken into seperate characters. So if \n represents
1082
		// a new line, Flash returns it as "\" and "n". This means the character
1083
		// is _not_ a newline. This forces us to eval() the string to cause
1084
		// escaped characters to turn into their real special character values.
1085
		data = eval('"' + data + '"');
1086
 
1087
		return data;
1088
	},
1089
 
1090
	// Sends our method arguments over to Flash in chunks in order to
1091
	// have ExternalInterface's performance not be O(n^2).
1092
	// Flash 8 communication.
1093
	_chunkArgumentData: function(value, argIndex){
1094
		var plugin = dojox.flash.obj.get();
1095
 
1096
		// cut up the string into pieces, and push over each piece one
1097
		// at a time
1098
		var numSegments = Math.ceil(value.length / 1024);
1099
		for(var i = 0; i < numSegments; i++){
1100
			var startCut = i * 1024;
1101
			var endCut = i * 1024 + 1024;
1102
			if(i == (numSegments - 1)){
1103
				endCut = i * 1024 + value.length;
1104
			}
1105
 
1106
			var piece = value.substring(startCut, endCut);
1107
 
1108
			// encode each piece seperately, rather than the entire
1109
			// argument data, because ocassionally a special
1110
			// character, such as an entity like &foobar;, will fall between
1111
			// piece boundaries, and we _don't_ want to encode that value if
1112
			// it falls between boundaries, or else we will end up with incorrect
1113
			// data when we patch the pieces back together on the other side
1114
			piece = this._encodeData(piece);
1115
 
1116
			// directly use the underlying CallFunction method used by
1117
			// ExternalInterface, which is vastly faster for large strings
1118
			// and lets us bypass some Flash serialization bugs
1119
			plugin.CallFunction('<invoke name="chunkArgumentData" '
1120
														+ 'returntype="javascript">'
1121
														+ '<arguments>'
1122
														+ '<string>' + piece + '</string>'
1123
														+ '<number>' + argIndex + '</number>'
1124
														+ '</arguments>'
1125
														+ '</invoke>');
1126
		}
1127
	},
1128
 
1129
	// Gets our method return data in chunks for better performance.
1130
	// Flash 8 communication.
1131
	_chunkReturnData: function(){
1132
		var plugin = dojox.flash.obj.get();
1133
 
1134
		var numSegments = plugin.getReturnLength();
1135
		var resultsArray = new Array();
1136
		for(var i = 0; i < numSegments; i++){
1137
			// directly use the underlying CallFunction method used by
1138
			// ExternalInterface, which is vastly faster for large strings
1139
			var piece =
1140
					plugin.CallFunction('<invoke name="chunkReturnData" '
1141
															+ 'returntype="javascript">'
1142
															+ '<arguments>'
1143
															+ '<number>' + i + '</number>'
1144
															+ '</arguments>'
1145
															+ '</invoke>');
1146
 
1147
			// remove any leading or trailing JavaScript delimiters, which surround
1148
			// our String when it comes back from Flash since we bypass Flash's
1149
			// deserialization routines by directly calling CallFunction on the
1150
			// plugin
1151
			if(piece == '""' || piece == "''"){
1152
				piece = "";
1153
			}else{
1154
				piece = piece.substring(1, piece.length-1);
1155
			}
1156
 
1157
			resultsArray.push(piece);
1158
		}
1159
		var results = resultsArray.join("");
1160
 
1161
		return results;
1162
	},
1163
 
1164
	// Executes a Flash method; called from the JavaScript wrapper proxy we
1165
	// create on dojox.flash.comm.
1166
	// Flash 8 communication.
1167
	_execFlash: function(methodName, methodArgs){
1168
		var plugin = dojox.flash.obj.get();
1169
 
1170
		// begin Flash method execution
1171
		plugin.startExec();
1172
 
1173
		// set the number of arguments
1174
		plugin.setNumberArguments(methodArgs.length);
1175
 
1176
		// chunk and send over each argument
1177
		for(var i = 0; i < methodArgs.length; i++){
1178
			this._chunkArgumentData(methodArgs[i], i);
1179
		}
1180
 
1181
		// execute the method
1182
		plugin.exec(methodName);
1183
 
1184
		// get the return result
1185
		var results = this._chunkReturnData();
1186
 
1187
		// decode the results
1188
		results = this._decodeData(results);
1189
 
1190
		// reset everything
1191
		plugin.endExec();
1192
 
1193
		return results;
1194
	}
1195
}
1196
 
1197
// FIXME: dojo.declare()-ify this
1198
 
1199
dojox.flash.Install = function(){
1200
	// summary: Helps install Flash plugin if needed.
1201
	// description:
1202
	//		Figures out the best way to automatically install the Flash plugin
1203
	//		for this browser and platform. Also determines if installation or
1204
	//		revving of the current plugin is needed on this platform.
1205
}
1206
 
1207
dojox.flash.Install.prototype = {
1208
	needed: function(){ /* Boolean */
1209
		// summary:
1210
		//		Determines if installation or revving of the current plugin is
1211
		//		needed.
1212
 
1213
		// do we even have flash?
1214
		if(dojox.flash.info.capable == false){
1215
			return true;
1216
		}
1217
 
1218
		var isMac = (navigator.appVersion.indexOf("Macintosh") >= 0);
1219
 
1220
		// are we on the Mac? Safari needs Flash version 8 to do Flash 8
1221
		// communication, while Firefox/Mac needs Flash 8 to fix bugs it has
1222
		// with Flash 6 communication
1223
		if(isMac && (!dojox.flash.info.isVersionOrAbove(8, 0, 0))){
1224
			return true;
1225
		}
1226
 
1227
		// other platforms need at least Flash 6 or above
1228
		if(!dojox.flash.info.isVersionOrAbove(6, 0, 0)){
1229
			return true;
1230
		}
1231
 
1232
		// otherwise we don't need installation
1233
		return false;
1234
	},
1235
 
1236
	install: function(){
1237
		// summary: Performs installation or revving of the Flash plugin.
1238
 
1239
		//dojo.debug("install");
1240
		// indicate that we are installing
1241
		dojox.flash.info.installing = true;
1242
		dojox.flash.installing();
1243
 
1244
		if(dojox.flash.info.capable == false){ // we have no Flash at all
1245
			//dojo.debug("Completely new install");
1246
			// write out a simple Flash object to force the browser to prompt
1247
			// the user to install things
1248
			var installObj = new dojox.flash.Embed(false);
1249
			installObj.write(8); // write out HTML for Flash 8 version+
1250
		}else if(dojox.flash.info.isVersionOrAbove(6, 0, 65)){ // Express Install
1251
			//dojo.debug("Express install");
1252
			var installObj = new dojox.flash.Embed(false);
1253
			installObj.write(8, true); // write out HTML for Flash 8 version+
1254
			installObj.setVisible(true);
1255
			installObj.center();
1256
		}else{ // older Flash install than version 6r65
1257
			alert("This content requires a more recent version of the Macromedia "
1258
						+" Flash Player.");
1259
			window.location.href = + dojox.flash.Embed.protocol() +
1260
						"://www.macromedia.com/go/getflashplayer";
1261
		}
1262
	},
1263
 
1264
	// Called when the Express Install is either finished, failed, or was
1265
	// rejected by the user.
1266
	_onInstallStatus: function(msg){
1267
		if (msg == "Download.Complete"){
1268
			// Installation is complete.
1269
			dojox.flash._initialize();
1270
		}else if(msg == "Download.Cancelled"){
1271
			alert("This content requires a more recent version of the Macromedia "
1272
						+" Flash Player.");
1273
			window.location.href = dojox.flash.Embed.protocol() +
1274
						"://www.macromedia.com/go/getflashplayer";
1275
		}else if (msg == "Download.Failed"){
1276
			// The end user failed to download the installer due to a network failure
1277
			alert("There was an error downloading the Flash Player update. "
1278
						+ "Please try again later, or visit macromedia.com to download "
1279
						+ "the latest version of the Flash plugin.");
1280
		}
1281
	}
1282
}
1283
 
1284
// find out if Flash is installed
1285
dojox.flash.info = new dojox.flash.Info();
1286
 
1287
// vim:ts=4:noet:tw=0:
1288
 
1289
}