Improve output: distinguish between failed assertions (failures) and unexpected exceptions (errors), and print a filtered stack trace for any exception.
This commit is contained in:
commit
4f2e303079
1839 changed files with 235630 additions and 0 deletions
214
webapp/web/src/flash/flash6/DojoExternalInterface.as
Normal file
214
webapp/web/src/flash/flash6/DojoExternalInterface.as
Normal file
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
/**
|
||||
An implementation of Flash 8's ExternalInterface that works with Flash 6
|
||||
and which is source-compatible with Flash 8.
|
||||
|
||||
@author Brad Neuberg, bkn3@columbia.edu
|
||||
*/
|
||||
|
||||
class DojoExternalInterface{
|
||||
public static var available:Boolean;
|
||||
public static var dojoPath = "";
|
||||
|
||||
public static var _fscommandReady = false;
|
||||
public static var _callbacks = new Array();
|
||||
|
||||
public static function initialize(){
|
||||
//getURL("javascript:dojo.debug('FLASH:DojoExternalInterface initialize')");
|
||||
// FIXME: Set available variable by testing for capabilities
|
||||
DojoExternalInterface.available = true;
|
||||
|
||||
// extract the dojo base path
|
||||
DojoExternalInterface.dojoPath = DojoExternalInterface.getDojoPath();
|
||||
//getURL("javascript:dojo.debug('FLASH:dojoPath="+DojoExternalInterface.dojoPath+"')");
|
||||
|
||||
// Sometimes, on IE, the fscommand infrastructure can take a few hundred
|
||||
// milliseconds the first time a page loads. Set a timer to keep checking
|
||||
// to make sure we can issue fscommands; otherwise, our calls to fscommand
|
||||
// for setCallback() and loaded() will just "disappear"
|
||||
_root.fscommandReady = false;
|
||||
var fsChecker = function(){
|
||||
// issue a test fscommand
|
||||
fscommand("fscommandReady");
|
||||
|
||||
// JavaScript should set _root.fscommandReady if it got the call
|
||||
if(_root.fscommandReady == "true"){
|
||||
DojoExternalInterface._fscommandReady = true;
|
||||
clearInterval(_root.fsTimer);
|
||||
}
|
||||
};
|
||||
_root.fsTimer = setInterval(fsChecker, 100);
|
||||
}
|
||||
|
||||
public static function addCallback(methodName:String, instance:Object,
|
||||
method:Function) : Boolean{
|
||||
// A variable that indicates whether the call below succeeded
|
||||
_root._succeeded = null;
|
||||
|
||||
// Callbacks are registered with the JavaScript side as follows.
|
||||
// On the Flash side, we maintain a lookup table that associates
|
||||
// the methodName with the actual instance and method that are
|
||||
// associated with this method.
|
||||
// Using fscommand, we send over the action "addCallback", with the
|
||||
// argument being the methodName to add, such as "foobar".
|
||||
// The JavaScript takes these values and registers the existence of
|
||||
// this callback point.
|
||||
|
||||
// precede the method name with a _ character in case it starts
|
||||
// with a number
|
||||
_callbacks["_" + methodName] = {_instance: instance, _method: method};
|
||||
_callbacks[_callbacks.length] = methodName;
|
||||
|
||||
// The API for ExternalInterface says we have to make sure the call
|
||||
// succeeded; check to see if there is a value
|
||||
// for _succeeded, which is set by the JavaScript side
|
||||
if(_root._succeeded == null){
|
||||
return false;
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static function call(methodName:String,
|
||||
resultsCallback:Function) : Void{
|
||||
// FIXME: support full JSON serialization
|
||||
|
||||
// First, we pack up all of the arguments to this call and set them
|
||||
// as Flash variables, which the JavaScript side will unpack using
|
||||
// plugin.GetVariable(). We set the number of arguments as "_numArgs",
|
||||
// and add each argument as a variable, such as "_1", "_2", etc., starting
|
||||
// from 0.
|
||||
// We then execute an fscommand with the action "call" and the
|
||||
// argument being the method name. JavaScript takes the method name,
|
||||
// retrieves the arguments using GetVariable, executes the method,
|
||||
// and then places the return result in a Flash variable
|
||||
// named "_returnResult".
|
||||
_root._numArgs = arguments.length - 2;
|
||||
for(var i = 2; i < arguments.length; i++){
|
||||
var argIndex = i - 2;
|
||||
_root["_" + argIndex] = arguments[i];
|
||||
}
|
||||
|
||||
_root._returnResult = undefined;
|
||||
fscommand("call", methodName);
|
||||
|
||||
// immediately return if the caller is not waiting for return results
|
||||
if(resultsCallback == undefined || resultsCallback == null){
|
||||
return;
|
||||
}
|
||||
|
||||
// check at regular intervals for return results
|
||||
var resultsChecker = function(){
|
||||
if(_root._returnResult != undefined){
|
||||
clearInterval(_root._callbackID);
|
||||
resultsCallback.call(null, _root._returnResult);
|
||||
}
|
||||
};
|
||||
_root._callbackID = setInterval(resultsChecker, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
Called by Flash to indicate to JavaScript that we are ready to have
|
||||
our Flash functions called. Calling loaded()
|
||||
will fire the dojo.flash.loaded() event, so that JavaScript can know that
|
||||
Flash has finished loading and adding its callbacks, and can begin to
|
||||
interact with the Flash file.
|
||||
*/
|
||||
public static function loaded(){
|
||||
//getURL("javascript:dojo.debug('FLASH:loaded')");
|
||||
|
||||
// one more step: see if fscommands are ready to be executed; if not,
|
||||
// set an interval that will keep running until fscommands are ready;
|
||||
// make sure the gateway is loaded as well
|
||||
var execLoaded = function(){
|
||||
if(DojoExternalInterface._fscommandReady == true){
|
||||
clearInterval(_root.loadedInterval);
|
||||
|
||||
// initialize the small Flash file that helps gateway JS to Flash
|
||||
// calls
|
||||
DojoExternalInterface._initializeFlashRunner();
|
||||
}
|
||||
};
|
||||
|
||||
if(_fscommandReady == true){
|
||||
execLoaded();
|
||||
}else{
|
||||
_root.loadedInterval = setInterval(execLoaded, 50);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Handles and executes a JavaScript to Flash method call. Used by
|
||||
initializeFlashRunner.
|
||||
*/
|
||||
public static function _handleJSCall(){
|
||||
// get our parameters
|
||||
var numArgs = parseInt(_root._numArgs);
|
||||
var jsArgs = new Array();
|
||||
for(var i = 0; i < numArgs; i++){
|
||||
var currentValue = _root["_" + i];
|
||||
jsArgs.push(currentValue);
|
||||
}
|
||||
|
||||
// get our function name
|
||||
var functionName = _root._functionName;
|
||||
|
||||
// now get the actual instance and method object to execute on,
|
||||
// using our lookup table that was constructed by calls to
|
||||
// addCallback on initialization
|
||||
var instance = _callbacks["_" + functionName]._instance;
|
||||
var method = _callbacks["_" + functionName]._method;
|
||||
|
||||
// execute it
|
||||
var results = method.apply(instance, jsArgs);
|
||||
|
||||
// return the results
|
||||
_root._returnResult = results;
|
||||
}
|
||||
|
||||
/** Called by the flash6_gateway.swf to indicate that it is loaded. */
|
||||
public static function _gatewayReady(){
|
||||
for(var i = 0; i < _callbacks.length; i++){
|
||||
fscommand("addCallback", _callbacks[i]);
|
||||
}
|
||||
call("dojo.flash.loaded");
|
||||
}
|
||||
|
||||
/**
|
||||
When JavaScript wants to communicate with Flash it simply sets
|
||||
the Flash variable "_execute" to true; this method creates the
|
||||
internal Movie Clip, called the Flash Runner, that makes this
|
||||
magic happen.
|
||||
*/
|
||||
public static function _initializeFlashRunner(){
|
||||
// figure out where our Flash movie is
|
||||
var swfLoc = DojoExternalInterface.dojoPath + "flash6_gateway.swf";
|
||||
|
||||
// load our gateway helper file
|
||||
_root.createEmptyMovieClip("_flashRunner", 5000);
|
||||
_root._flashRunner._lockroot = true;
|
||||
_root._flashRunner.loadMovie(swfLoc);
|
||||
}
|
||||
|
||||
private static function getDojoPath(){
|
||||
var url = _root._url;
|
||||
var start = url.indexOf("baseRelativePath=") + "baseRelativePath=".length;
|
||||
var path = url.substring(start);
|
||||
var end = path.indexOf("&");
|
||||
if(end != -1){
|
||||
path = path.substring(0, end);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
// vim:ts=4:noet:tw=0:
|
BIN
webapp/web/src/flash/flash6/flash6_gateway.fla
Normal file
BIN
webapp/web/src/flash/flash6/flash6_gateway.fla
Normal file
Binary file not shown.
234
webapp/web/src/flash/flash8/DojoExternalInterface.as
Normal file
234
webapp/web/src/flash/flash8/DojoExternalInterface.as
Normal file
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
/**
|
||||
A wrapper around Flash 8's ExternalInterface; DojoExternalInterface is needed so that we
|
||||
can do a Flash 6 implementation of ExternalInterface, and be able
|
||||
to support having a single codebase that uses DojoExternalInterface
|
||||
across Flash versions rather than having two seperate source bases,
|
||||
where one uses ExternalInterface and the other uses DojoExternalInterface.
|
||||
|
||||
DojoExternalInterface class does a variety of optimizations to bypass ExternalInterface's
|
||||
unbelievably bad performance so that we can have good performance
|
||||
on Safari; see the blog post
|
||||
http://codinginparadise.org/weblog/2006/02/how-to-speed-up-flash-8s.html
|
||||
for details.
|
||||
|
||||
@author Brad Neuberg, bkn3@columbia.edu
|
||||
*/
|
||||
import flash.external.ExternalInterface;
|
||||
|
||||
class DojoExternalInterface{
|
||||
public static var available:Boolean;
|
||||
public static var dojoPath = "";
|
||||
|
||||
private static var flashMethods:Array = new Array();
|
||||
private static var numArgs:Number;
|
||||
private static var argData:Array;
|
||||
private static var resultData = null;
|
||||
|
||||
public static function initialize(){
|
||||
// extract the dojo base path
|
||||
DojoExternalInterface.dojoPath = DojoExternalInterface.getDojoPath();
|
||||
|
||||
// see if we need to do an express install
|
||||
var install:ExpressInstall = new ExpressInstall();
|
||||
if(install.needsUpdate){
|
||||
install.init();
|
||||
}
|
||||
|
||||
// register our callback functions
|
||||
ExternalInterface.addCallback("startExec", DojoExternalInterface, startExec);
|
||||
ExternalInterface.addCallback("setNumberArguments", DojoExternalInterface,
|
||||
setNumberArguments);
|
||||
ExternalInterface.addCallback("chunkArgumentData", DojoExternalInterface,
|
||||
chunkArgumentData);
|
||||
ExternalInterface.addCallback("exec", DojoExternalInterface, exec);
|
||||
ExternalInterface.addCallback("getReturnLength", DojoExternalInterface,
|
||||
getReturnLength);
|
||||
ExternalInterface.addCallback("chunkReturnData", DojoExternalInterface,
|
||||
chunkReturnData);
|
||||
ExternalInterface.addCallback("endExec", DojoExternalInterface, endExec);
|
||||
|
||||
// set whether communication is available
|
||||
DojoExternalInterface.available = ExternalInterface.available;
|
||||
DojoExternalInterface.call("loaded");
|
||||
}
|
||||
|
||||
public static function addCallback(methodName:String, instance:Object,
|
||||
method:Function) : Boolean{
|
||||
// register DojoExternalInterface methodName with it's instance
|
||||
DojoExternalInterface.flashMethods[methodName] = instance;
|
||||
|
||||
// tell JavaScript about DojoExternalInterface new method so we can create a proxy
|
||||
ExternalInterface.call("dojo.flash.comm._addExternalInterfaceCallback",
|
||||
methodName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function call(methodName:String,
|
||||
resultsCallback:Function) : Void{
|
||||
// we might have any number of optional arguments, so we have to
|
||||
// pass them in dynamically; strip out the results callback
|
||||
var parameters = new Array();
|
||||
for(var i = 0; i < arguments.length; i++){
|
||||
if(i != 1){ // skip the callback
|
||||
parameters.push(arguments[i]);
|
||||
}
|
||||
}
|
||||
|
||||
var results = ExternalInterface.call.apply(ExternalInterface, parameters);
|
||||
|
||||
// immediately give the results back, since ExternalInterface is
|
||||
// synchronous
|
||||
if(resultsCallback != null && typeof resultsCallback != "undefined"){
|
||||
resultsCallback.call(null, results);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Called by Flash to indicate to JavaScript that we are ready to have
|
||||
our Flash functions called. Calling loaded()
|
||||
will fire the dojo.flash.loaded() event, so that JavaScript can know that
|
||||
Flash has finished loading and adding its callbacks, and can begin to
|
||||
interact with the Flash file.
|
||||
*/
|
||||
public static function loaded(){
|
||||
DojoExternalInterface.call("dojo.flash.loaded");
|
||||
}
|
||||
|
||||
public static function startExec():Void{
|
||||
DojoExternalInterface.numArgs = null;
|
||||
DojoExternalInterface.argData = null;
|
||||
DojoExternalInterface.resultData = null;
|
||||
}
|
||||
|
||||
public static function setNumberArguments(numArgs):Void{
|
||||
DojoExternalInterface.numArgs = numArgs;
|
||||
DojoExternalInterface.argData = new Array(DojoExternalInterface.numArgs);
|
||||
}
|
||||
|
||||
public static function chunkArgumentData(value, argIndex:Number):Void{
|
||||
//getURL("javascript:dojo.debug('FLASH: chunkArgumentData, value="+value+", argIndex="+argIndex+"')");
|
||||
var currentValue = DojoExternalInterface.argData[argIndex];
|
||||
if(currentValue == null || typeof currentValue == "undefined"){
|
||||
DojoExternalInterface.argData[argIndex] = value;
|
||||
}else{
|
||||
DojoExternalInterface.argData[argIndex] += value;
|
||||
}
|
||||
}
|
||||
|
||||
public static function exec(methodName):Void{
|
||||
// decode all of the arguments that were passed in
|
||||
for(var i = 0; i < DojoExternalInterface.argData.length; i++){
|
||||
DojoExternalInterface.argData[i] =
|
||||
DojoExternalInterface.decodeData(DojoExternalInterface.argData[i]);
|
||||
}
|
||||
|
||||
var instance = DojoExternalInterface.flashMethods[methodName];
|
||||
DojoExternalInterface.resultData = instance[methodName].apply(
|
||||
instance, DojoExternalInterface.argData);
|
||||
// encode the result data
|
||||
DojoExternalInterface.resultData =
|
||||
DojoExternalInterface.encodeData(DojoExternalInterface.resultData);
|
||||
|
||||
//getURL("javascript:dojo.debug('FLASH: encoded result data="+DojoExternalInterface.resultData+"')");
|
||||
}
|
||||
|
||||
public static function getReturnLength():Number{
|
||||
if(DojoExternalInterface.resultData == null ||
|
||||
typeof DojoExternalInterface.resultData == "undefined"){
|
||||
return 0;
|
||||
}
|
||||
var segments = Math.ceil(DojoExternalInterface.resultData.length / 1024);
|
||||
return segments;
|
||||
}
|
||||
|
||||
public static function chunkReturnData(segment:Number):String{
|
||||
var numSegments = DojoExternalInterface.getReturnLength();
|
||||
var startCut = segment * 1024;
|
||||
var endCut = segment * 1024 + 1024;
|
||||
if(segment == (numSegments - 1)){
|
||||
endCut = segment * 1024 + DojoExternalInterface.resultData.length;
|
||||
}
|
||||
|
||||
var piece = DojoExternalInterface.resultData.substring(startCut, endCut);
|
||||
|
||||
//getURL("javascript:dojo.debug('FLASH: chunking return piece="+piece+"')");
|
||||
|
||||
return piece;
|
||||
}
|
||||
|
||||
public static function endExec():Void{
|
||||
}
|
||||
|
||||
private static function decodeData(data):String{
|
||||
// we have to use custom encodings for certain characters when passing
|
||||
// them over; for example, passing a backslash over as //// from JavaScript
|
||||
// to Flash doesn't work
|
||||
data = DojoExternalInterface.replaceStr(data, "&custom_backslash;", "\\");
|
||||
|
||||
data = DojoExternalInterface.replaceStr(data, "\\\'", "\'");
|
||||
data = DojoExternalInterface.replaceStr(data, "\\\"", "\"");
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private static function encodeData(data){
|
||||
//getURL("javascript:dojo.debug('inside flash, data before="+data+"')");
|
||||
|
||||
// double encode all entity values, or they will be mis-decoded
|
||||
// by Flash when returned
|
||||
data = DojoExternalInterface.replaceStr(data, "&", "&");
|
||||
|
||||
// certain XMLish characters break Flash's wire serialization for
|
||||
// ExternalInterface; encode these into a custom encoding, rather than
|
||||
// the standard entity encoding, because otherwise we won't be able to
|
||||
// differentiate between our own encoding and any entity characters
|
||||
// that are being used in the string itself
|
||||
data = DojoExternalInterface.replaceStr(data, '<', '&custom_lt;');
|
||||
data = DojoExternalInterface.replaceStr(data, '>', '&custom_gt;');
|
||||
|
||||
// encode control characters and JavaScript delimiters
|
||||
data = DojoExternalInterface.replaceStr(data, "\n", "\\n");
|
||||
data = DojoExternalInterface.replaceStr(data, "\r", "\\r");
|
||||
data = DojoExternalInterface.replaceStr(data, "\f", "\\f");
|
||||
data = DojoExternalInterface.replaceStr(data, "'", "\\'");
|
||||
data = DojoExternalInterface.replaceStr(data, '"', '\"');
|
||||
|
||||
//getURL("javascript:dojo.debug('inside flash, data after="+data+"')");
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
Flash ActionScript has no String.replace method or support for
|
||||
Regular Expressions! We roll our own very simple one.
|
||||
*/
|
||||
private static function replaceStr(inputStr:String, replaceThis:String,
|
||||
withThis:String):String {
|
||||
var splitStr = inputStr.split(replaceThis)
|
||||
inputStr = splitStr.join(withThis)
|
||||
return inputStr;
|
||||
}
|
||||
|
||||
private static function getDojoPath(){
|
||||
var url = _root._url;
|
||||
var start = url.indexOf("baseRelativePath=") + "baseRelativePath=".length;
|
||||
var path = url.substring(start);
|
||||
var end = path.indexOf("&");
|
||||
if(end != -1){
|
||||
path = path.substring(0, end);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
// vim:ts=4:noet:tw=0:
|
81
webapp/web/src/flash/flash8/ExpressInstall.as
Normal file
81
webapp/web/src/flash/flash8/ExpressInstall.as
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
Copyright (c) 2004-2006, The Dojo Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
Licensed under the Academic Free License version 2.1 or above OR the
|
||||
modified BSD license. For more information on Dojo licensing, see:
|
||||
|
||||
http://dojotoolkit.org/community/licensing.shtml
|
||||
*/
|
||||
|
||||
/**
|
||||
* Based on the expressinstall.as class created by Geoff Stearns as part
|
||||
* of the FlashObject library.
|
||||
*
|
||||
* Use this file to invoke the Macromedia Flash Player Express Install functionality
|
||||
* This file is intended for use with the FlashObject embed script. You can download FlashObject
|
||||
* and this file at the following URL: http://blog.deconcept.com/flashobject/
|
||||
*
|
||||
* Usage:
|
||||
* var ExpressInstall = new ExpressInstall();
|
||||
*
|
||||
* // test to see if install is needed:
|
||||
* if (ExpressInstall.needsUpdate) { // returns true if update is needed
|
||||
* ExpressInstall.init(); // starts the update
|
||||
* }
|
||||
*
|
||||
* NOTE: Your Flash movie must be at least 214px by 137px in order to use ExpressInstall.
|
||||
*
|
||||
*/
|
||||
|
||||
class ExpressInstall {
|
||||
public var needsUpdate:Boolean;
|
||||
private var updater:MovieClip;
|
||||
private var hold:MovieClip;
|
||||
|
||||
public function ExpressInstall(){
|
||||
// does the user need to update?
|
||||
this.needsUpdate = (_root.MMplayerType == undefined) ? false : true;
|
||||
}
|
||||
|
||||
public function init():Void{
|
||||
this.loadUpdater();
|
||||
}
|
||||
|
||||
public function loadUpdater():Void {
|
||||
System.security.allowDomain("fpdownload.macromedia.com");
|
||||
|
||||
// hope that nothing is at a depth of 10000000, you can change this depth if needed, but you want
|
||||
// it to be on top of your content if you have any stuff on the first frame
|
||||
this.updater = _root.createEmptyMovieClip("expressInstallHolder", 10000000);
|
||||
|
||||
// register the callback so we know if they cancel or there is an error
|
||||
var _self = this;
|
||||
this.updater.installStatus = _self.onInstallStatus;
|
||||
this.hold = this.updater.createEmptyMovieClip("hold", 1);
|
||||
|
||||
// can't use movieClipLoader because it has to work in 6.0.65
|
||||
this.updater.onEnterFrame = function():Void {
|
||||
if(typeof this.hold.startUpdate == 'function'){
|
||||
_self.initUpdater();
|
||||
this.onEnterFrame = null;
|
||||
}
|
||||
}
|
||||
|
||||
var cacheBuster:Number = Math.random();
|
||||
|
||||
this.hold.loadMovie("http://fpdownload.macromedia.com/pub/flashplayer/"
|
||||
+"update/current/swf/autoUpdater.swf?"+ cacheBuster);
|
||||
}
|
||||
|
||||
private function initUpdater():Void{
|
||||
this.hold.redirectURL = _root.MMredirectURL;
|
||||
this.hold.MMplayerType = _root.MMplayerType;
|
||||
this.hold.MMdoctitle = _root.MMdoctitle;
|
||||
this.hold.startUpdate();
|
||||
}
|
||||
|
||||
public function onInstallStatus(msg):Void{
|
||||
getURL("javascript:dojo.flash.install._onInstallStatus('"+msg+"')");
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue