From 53c9685043418b679b2c9083400435c8e27cf216 Mon Sep 17 00:00:00 2001 From: adufilie Date: Sat, 10 May 2014 00:09:30 -0400 Subject: [PATCH] Cleaned up code related to JavaScript. Weave now reports JavaScript syntax errors. Removed broken pageTitle feature and no longer including that text when exporting screenshots. Change-Id: I0ecf1a520a8c2cc6cb11e956f240d33310697146 --- WeaveAPI/src/JavaScript.as | 119 ++++++++++---- WeaveAPI/src/weave/api/WeaveAPI.as | 153 +++++++++--------- WeaveAdmin/src/AdminConsole.mxml | 4 +- WeaveAdmin/src/weave/services/Admin.as | 3 +- WeaveAdmin/src/weave/ui/admin/LoginPopup.mxml | 3 +- .../src/weave/services/ExternalDownloader.as | 15 +- .../src/weave/services/URLRequestUtils.as | 3 +- WeaveMobileClient/src/MobileConsole.mxml | 8 +- .../src/weave/application/VisApplication.as | 38 ++--- .../weave/editors/WeavePropertiesEditor.mxml | 4 +- WeaveUI/src/weave/ui/Console.mxml | 7 +- WeaveUI/src/weave/ui/PrintPanel.mxml | 9 +- .../weave/visualization/tools/ExternalTool.as | 10 +- WeaveUISpark/src/weave/Weave.as | 26 +-- WeaveUISpark/src/weave/WeaveProperties.as | 21 +-- .../src/weave/utils/CustomCursorManager.as | 9 +- 16 files changed, 228 insertions(+), 204 deletions(-) diff --git a/WeaveAPI/src/JavaScript.as b/WeaveAPI/src/JavaScript.as index aaa454e00f..639e5a9eec 100644 --- a/WeaveAPI/src/JavaScript.as +++ b/WeaveAPI/src/JavaScript.as @@ -23,10 +23,12 @@ package * Requires Flash Player 11 or later to get the full benefit (uses native JSON support), * but has backwards compatibility to Flash Player 10, or possibly earlier versions (untested). * + * If there is a syntax error, JavaScript.exec() will throw the Error while ExternalInterface.call() would return null. + * * When parameters are passed to ExternalInterface.call() it attempts to stringify the parameters * to JavaScript object literals, but it does not quote keys and it does not escape backslashes * in String values. For example, if you give {"Content-Type": "foo\\"} as a parameter, - * ExternalInterface generates the following invalid object literal: {Content-Type: "foo\"}. + * ExternalInterface generates the following invalid code: {Content-Type: "foo\"}. * The same problem occurs when returning an Object from an ActionScript function that was invoked * from JavaScript. This class works around the limitation by using JSON.stringify() and JSON.parse() * and escaping backslashes in resulting JSON strings. The values undefined, NaN, Infinity, -Infinity @@ -85,7 +87,7 @@ package /** * A random String which is highly unlikely to appear in any String value. */ - private static const JSON_SUFFIX:String = ';' + new Date() + ';' + Math.random(); + private static const JSON_SUFFIX:String = ';' + Math.random() + ';' + new Date(); private static const NOT_A_NUMBER:String = NaN + JSON_SUFFIX; private static const UNDEFINED:String = undefined + JSON_SUFFIX; @@ -161,7 +163,7 @@ package var resultJson:String = json.stringify(result, _jsonReplacer); // work around unescaped backslash bug - if (backslashNeedsEscaping) + if (backslashNeedsEscaping && resultJson.indexOf('\\') >= 0) resultJson = resultJson.split('\\').join('\\\\'); return resultJson; @@ -247,13 +249,29 @@ package * Generates a line of JavaScript which intializes a variable equal to this Flash object using document.getElementById(). * @param variableName The variable name, which must be a valid JavaScript identifier. */ - public static function JS_var_this(variableName:String):String + private static function JS_var_this(variableName:String):String { if (!_objectID) _objectID = getExternalObjectID(variableName); - return 'var ' + variableName + ' = document.getElementById("' + _objectID + '");'; + return 'var ' + variableName + ' = ' + JS_this + ';'; } + /** + * A JavaScript expression which gets a pointer to this Flash object. + */ + private static function get JS_this():String + { + if (!_objectID) + _objectID = getExternalObjectID(); + return 'document.getElementById("' + _objectID + '")'; + } + + /** + * Alias for ExternalInterface.available + * @see flash.external.ExternalInterface#available + */ + public static const available:Boolean = ExternalInterface.available; + /** * The "id" property of this Flash object. * Use this as a reliable alternative to ExternalInterface.objectID, which may be null in some cases even if the Flash object has an "id" property. @@ -299,9 +317,14 @@ package * This will execute JavaScript code inside a function(){} wrapper. * @param paramsAndCode A list of lines of code, optionally including an * Object containing named parameters to be passed from ActionScript to JavaScript. + * * Inside the code, you can use the "this" variable to access this flash object. * If instead you prefer to use a variable name other than "this", supply an Object - * containing a "this" property equal to the desired variable name. + * like {"this": "yourDesiredVariableName"}. + * + * By default, a JavaScript Error will be marshalled to an ActionScript Error. + * To disable this behavior, supply an Object like {"catch": false}. + * You can also provide an ActionScript function to handle errors: {"catch": myErrorHandler}. * @return The result of executing the JavaScript code. * * @example Example 1 @@ -329,10 +352,10 @@ package if (paramsAndCode.length == 1 && paramsAndCode[0] is Array) paramsAndCode = paramsAndCode[0]; - var pNames:Array = []; - var pValues:Array = []; - var code:String = ''; - var thisVar:String = 'this'; + var pNames:Array = json ? null : []; + var pValues:Array = json ? null : []; + var code:Array = []; + var marshallExceptions:Object = true; // separate function parameters from code for each (var value:Object in paramsAndCode) @@ -343,50 +366,88 @@ package // since they are to be used in the code as variables. for (var key:String in value) { - var param:Object = value[key]; + var param:* = value[key]; if (json) { if (key == 'this') { - thisVar = String(param); + // put a variable declaration at the beginning of the code + var thisVar:String = String(param); if (thisVar) - code = JS_var_this(thisVar) + '\n' + code; + code.unshift(JS_var_this(thisVar)); + } + else if (key == 'catch') + { + // save error handler + marshallExceptions = param; } else { // put a variable declaration at the beginning of the code - code = "var " + key + " = " + json.stringify(param) + ";\n" + code; + code.unshift("var " + key + " = " + json.stringify(param) + ";"); } } else { // JSON unavailable + + // work around unescaped backslash bug + // this backwards compatibility code doesn't handle Strings inside Objects. + if (param is String && backslashNeedsEscaping) + param = (param as String).split('\\').join('\\\\'); + pNames.push(key); pValues.push(param); } } } else - code += value + '\n'; + { + code.push(String(value)); + } } - if (thisVar == 'this') + // if the code references "this", we need to use Function.apply() to make the symbol work as expected + var appliedCode:String = '(function(){\n' + code.join('\n') + '\n}).apply(' + JS_this + ')'; + + var result:*; + var prevMarshallExceptions:Boolean = ExternalInterface.marshallExceptions; + ExternalInterface.marshallExceptions = !!marshallExceptions; + try { - // to make the "this" symbol work as expected we need to use Function.apply(). - thisVar = '__JavaScript_dot_as__'; - code = JS_var_this(thisVar) + '\nreturn (function(){\n' + code + '}).apply(' + thisVar + ');'; + if (json) + { + // work around unescaped backslash bug + if (backslashNeedsEscaping && appliedCode.indexOf('\\') >= 0) + appliedCode = appliedCode.split('\\').join('\\\\'); + + // we need to use "eval" in order to receive syntax errors + result = ExternalInterface.call('eval', appliedCode); + } + else + { + // JSON is unavailable, so we settle with the flawed ExternalInterface.call() parameters feature. + var wrappedCode:String = 'function(' + pNames.join(',') + '){ return ' + appliedCode + '; }'; + pValues.unshift(wrappedCode); + result = ExternalInterface.call.apply(null, pValues); + } } + catch (e:*) + { + if (marshallExceptions is Function) + { + marshallExceptions(e); + } + else + { + ExternalInterface.marshallExceptions = prevMarshallExceptions; + throw e; + } + } + // we can't put this in a finally{} block because it prevents catch() from happening if set to false. + ExternalInterface.marshallExceptions = prevMarshallExceptions; - // Concatenate all code inside a function wrapper. - // The pNames Array will be empty if JSON is available. - code = 'function(' + pNames.join(',') + '){\n' + code + '}'; - - if (json) - return ExternalInterface.call(code); - - // JSON is unavailable, so we settle with the flawed ExternalInterface.call() parameters feature. - pValues.unshift(code); - return ExternalInterface.call.apply(null, pValues); + return result; } } } diff --git a/WeaveAPI/src/weave/api/WeaveAPI.as b/WeaveAPI/src/weave/api/WeaveAPI.as index eb1e7e36e2..5424317f85 100644 --- a/WeaveAPI/src/weave/api/WeaveAPI.as +++ b/WeaveAPI/src/weave/api/WeaveAPI.as @@ -17,11 +17,11 @@ package weave.api { import avmplus.DescribeType; - import flash.external.ExternalInterface; import flash.utils.Dictionary; import flash.utils.getDefinitionByName; import flash.utils.getQualifiedClassName; + import mx.core.ByteArrayAsset; import mx.core.FlexGlobals; import mx.core.Singleton; @@ -167,80 +167,116 @@ package weave.api return FlexGlobals.topLevelApplication; } - private static var _externalInterfaceInitialized:Boolean = false; + private static const _javaScriptInitialized:Dictionary = new Dictionary(); /** - * This will be true after initializeExternalInterface() completes successfully. + * This will be true after initializeJavaScript() completes successfully. */ - public static function get externalInterfaceInitialized():Boolean + public static function get javaScriptInitialized():Boolean { - return _externalInterfaceInitialized; + return !!_javaScriptInitialized[WeavePath]; } /** * This function will initialize the external API so calls can be made from JavaScript to Weave. * After initializing, this will call an external function weave.apiReady(weave) if it exists, where * 'weave' is a pointer to the instance of Weave that was initialized. + * @param scripts A list of JavaScript files containing initialization code, each given as a Class (for an embedded file) or a String. + * Within the script, the "weave" variable can be used as a pointer to the Weave instance. + * + * @example Example + * + * [Embed(source="MyScript.js", mimeType="application/octet-stream")] + * private static const MyScript:Class; + * + * WeaveAPI.initializeJavaScript(MyScript); + * */ - public static function initializeExternalInterface():void + public static function initializeJavaScript(...scripts):void { - if (!ExternalInterface.available || _externalInterfaceInitialized) + if (!JavaScript.available) return; - try + // we want WeavePath to be initialized first + var firstTime:Boolean = !javaScriptInitialized; + if (firstTime) { - // initialize Direct API - var interfaces:Array = [IExternalSessionStateInterface]; // add more interfaces here if necessary - for each (var theInterface:Class in interfaces) - registerJavaScriptInterface(getSingletonInstance(theInterface), theInterface); - - var prev:Boolean = ExternalInterface.marshallExceptions; - ExternalInterface.marshallExceptions = false; - - // initialize WeavePath API - executeJavaScript(new WeavePath()); + // always include WeavePath + if (scripts.indexOf(WeavePath) < 0) + scripts.unshift(WeavePath); - // set flag before calling external apiReady() - _externalInterfaceInitialized = true; - - // call external weaveApiReady(weave) - executeJavaScript( - 'if (weave.hasOwnProperty("weaveApiReady")) { weave.weaveApiReady(weave); }', - 'if (window && window.weaveApiReady) { window.weaveApiReady(weave); }', - 'else if (weaveApiReady) { weaveApiReady(weave); }' - ); + // initialize Direct API before anything else + scripts.unshift(IExternalSessionStateInterface); + } + + try + { + for each (var script:Object in scripts) + { + // skip scripts we've already initialized + if (_javaScriptInitialized[script]) + continue; + + if (script is Class) + { + var instanceInfo:Object = DescribeType.getInfo(script, DescribeType.INCLUDE_TRAITS | DescribeType.INCLUDE_METHODS | DescribeType.HIDE_NSURI_METHODS | DescribeType.USE_ITRAITS | DescribeType.INCLUDE_BASES); + if (instanceInfo.traits.bases.indexOf(getQualifiedClassName(ByteArrayAsset)) >= 0) + { + // run embedded script file + JavaScript.exec({"this": "weave"}, new script()); + } + else + { + // initialize interface + registerJavaScriptInterface(getSingletonInstance(script as Class), instanceInfo); + } + } + else + { + // run the script + JavaScript.exec({"this": "weave"}, script); + } + + // remember that we initialized the script + _javaScriptInitialized[script] = true; + } - ExternalInterface.marshallExceptions = prev; + if (firstTime) + { + // call external weaveApiReady(weave) + JavaScript.exec( + {method: "weaveApiReady"}, + 'if (this.hasOwnProperty(method)) this[method](this);', + 'if (window.hasOwnProperty(method)) window[method](this);' + ); + } } - catch (e:Error) + catch (e:*) { handleExternalError(e); } } [Embed(source="WeavePath.js", mimeType="application/octet-stream")] - private static const WeavePath:Class; + public static const WeavePath:Class; /** * Calls external function(s) weave.weaveReady(weave) and/or window.weaveReady(weave). */ public static function callExternalWeaveReady():void { - initializeExternalInterface(); + initializeJavaScript(); - if (!ExternalInterface.available) + if (!JavaScript.available) return; try { - var prev:Boolean = ExternalInterface.marshallExceptions; - ExternalInterface.marshallExceptions = false; - executeJavaScript( - 'if (weave.hasOwnProperty("weaveReady")) { weave.weaveReady(weave); }', - 'if (window && window.weaveReady) { window.weaveReady(weave); }', - 'else if (weaveReady) { weaveReady(weave); }' + JavaScript.exec( + {method: "weaveReady"}, + 'if (this.hasOwnProperty(method)) this[method](this);', + 'if (window.hasOwnProperty(method)) window[method](this);' ); - ExternalInterface.marshallExceptions = prev; } catch (e:Error) { @@ -251,11 +287,10 @@ package weave.api /** * Exposes an interface to JavaScript. * @param host The host object containing methods to expose to JavaScript. - * @param theInterface An interface listing methods on the host to be exposed. + * @param typeInfo Type information from describeTypeJSON() listing methods to expose. */ - public static function registerJavaScriptInterface(host:Object, theInterface:Class = null):void + public static function registerJavaScriptInterface(host:Object, classInfo:Object):void { - var classInfo:Object = DescribeType.getInfo(theInterface || host, DescribeType.INCLUDE_TRAITS | DescribeType.INCLUDE_METHODS | DescribeType.HIDE_NSURI_METHODS | DescribeType.USE_ITRAITS); // register each external interface function for each (var methodInfo:Object in classInfo.traits.methods) { @@ -269,38 +304,6 @@ package weave.api JavaScript.registerMethod(methodName, method, paramCount); } } - - /** - * This will execute JavaScript code that uses a 'weave' variable. - * @param paramsAndCode A list of lines of code, optionally including an - * Object containing named parameters to be passed from ActionScript to JavaScript. - * Inside the code, you can use a variable named "weave" which will be a pointer - * to the Weave instance. - * @return The result of executing the JavaScript code. - * - * @example Example 1 - * - * var sum = WeaveAPI.executeJavaScript({x: 2, y: 3}, "return x + y"); - * trace("sum:", sum); - * - * - * @example Example 2 - * - * var sum = WeaveAPI.executeJavaScript( - * {x: 2, y: 3}, - * 'return weave.path().vars({x: x, y: y}).getValue("x + y");' - * ); - * trace("sum:", sum); - * - * - * @see JavaScript#exec() - */ - public static function executeJavaScript(...paramsAndCode):* - { - // insert weave variable declaration - paramsAndCode.unshift({"this": "weave"}); - return JavaScript.exec(paramsAndCode); - } private static function handleExternalError(e:Error):void { @@ -482,7 +485,7 @@ package weave.api */ public static function externalTrace(...params):void { - executeJavaScript( + JavaScript.exec( {"params": params}, "console.log.apply(console, params)" ); diff --git a/WeaveAdmin/src/AdminConsole.mxml b/WeaveAdmin/src/AdminConsole.mxml index c43b68f1ce..1f6e5adb7d 100644 --- a/WeaveAdmin/src/AdminConsole.mxml +++ b/WeaveAdmin/src/AdminConsole.mxml @@ -175,7 +175,7 @@ private function handleApplicationComplete():void { - WeaveAPI.initializeExternalInterface(); + WeaveAPI.initializeJavaScript(); getCallbackCollection(WeaveAPI.ErrorManager).addGroupedCallback(this, ErrorLogPanel.openErrorLog, WeaveAPI.ErrorManager.errors.length > 0); } @@ -187,7 +187,7 @@ private function openAcsHeaderTool():void { - ExternalInterface.call('window.open("http://demo.oicweave.org/HeaderTool.swf", "_blank")'); + JavaScript.exec('window.open("http://demo.oicweave.org/HeaderTool.swf", "_blank")'); } ]]> diff --git a/WeaveAdmin/src/weave/services/Admin.as b/WeaveAdmin/src/weave/services/Admin.as index 1f02561312..68e44687a5 100644 --- a/WeaveAdmin/src/weave/services/Admin.as +++ b/WeaveAdmin/src/weave/services/Admin.as @@ -24,7 +24,6 @@ package weave.services import mx.utils.UIDUtil; import mx.utils.URLUtil; - import weave.api.WeaveAPI; import weave.api.data.ColumnMetadata; import weave.api.data.DataTypes; import weave.api.data.EntityType; @@ -413,7 +412,7 @@ package weave.services params['file'] = fileName; if (recover) params['recover'] = true; - WeaveAPI.executeJavaScript( + JavaScript.exec( { url: 'weave.html?' + URLUtil.objectToString(params, '&'), target: ADMIN_SESSION_WINDOW_NAME_PREFIX + createWeaveSession(), diff --git a/WeaveAdmin/src/weave/ui/admin/LoginPopup.mxml b/WeaveAdmin/src/weave/ui/admin/LoginPopup.mxml index 950a73205e..8da399d8b5 100644 --- a/WeaveAdmin/src/weave/ui/admin/LoginPopup.mxml +++ b/WeaveAdmin/src/weave/ui/admin/LoginPopup.mxml @@ -41,7 +41,6 @@ Author: skolman - - + + + + + diff --git a/WeaveUI/src/weave/visualization/tools/ExternalTool.as b/WeaveUI/src/weave/visualization/tools/ExternalTool.as index 7be66dae80..04132fbfc6 100644 --- a/WeaveUI/src/weave/visualization/tools/ExternalTool.as +++ b/WeaveUI/src/weave/visualization/tools/ExternalTool.as @@ -52,23 +52,23 @@ package weave.visualization.tools toolPath.unshift(JavaScript.objectID); windowName = Compiler.stringify(toolPath); } - WeaveAPI.executeJavaScript( + JavaScript.exec( { windowName: windowName, toolPath: toolPath, url: toolUrl.value, features: "menubar=no,status=no,toolbar=no" }, - "if (!weave.external_tools) weave.external_tools = {};", - "weave.external_tools[windowName] = window.open(url, windowName, features);" + "if (!this.external_tools) this.external_tools = {};", + "this.external_tools[windowName] = window.open(url, windowName, features);" ); } override public function dispose():void { super.dispose(); - WeaveAPI.executeJavaScript( + JavaScript.exec( {windowName: windowName}, - "if (weave.external_tools && weave.external_tools[windowName]) weave.external_tools[windowName].close();" + "if (this.external_tools && this.external_tools[windowName]) this.external_tools[windowName].close();" ); } /** diff --git a/WeaveUISpark/src/weave/Weave.as b/WeaveUISpark/src/weave/Weave.as index c16833a3b9..641ae0a249 100644 --- a/WeaveUISpark/src/weave/Weave.as +++ b/WeaveUISpark/src/weave/Weave.as @@ -423,7 +423,7 @@ package weave // hack for forcing VisApplication menu to refresh getCallbackCollection(Weave.properties).triggerCallbacks(); - if (WeaveAPI.externalInterfaceInitialized) + if (WeaveAPI.javaScriptInitialized) { Weave.initExternalDragDrop(); properties.runStartupJavaScript(); @@ -450,10 +450,10 @@ package weave */ public static function externalReload(weaveContent:Object = null):void { - if (!ExternalInterface.available) + if (!JavaScript.available) { //TODO: is it possible to restart an Adobe AIR application from within? - reportError("Unable to restart Weave when ExternalInterface is not available."); + reportError("Unable to restart Weave when JavaScript is not available."); return; } @@ -462,7 +462,7 @@ package weave var obj:SharedObject = SharedObject.getLocal(WEAVE_RELOAD_SHARED_OBJECT); var uid:String = WEAVE_RELOAD_SHARED_OBJECT; - if (ExternalInterface.available && ExternalInterface.objectID) + if (JavaScript.available && ExternalInterface.objectID) { // generate uid to be saved in parent node uid = UIDUtil.createUID(); @@ -491,13 +491,13 @@ package weave // reload the application if (ExternalInterface.objectID) - WeaveAPI.executeJavaScript( + JavaScript.exec( {reloadID: uid}, - "weave.parentNode.weaveReloadID = reloadID;", - "weave.outerHTML = weave.outerHTML;" + "this.parentNode.weaveReloadID = reloadID;", + "this.outerHTML = this.outerHTML;" ); else - ExternalInterface.call("function(){ location.reload(false); }"); + JavaScript.exec("location.reload(false);"); } } @@ -511,13 +511,13 @@ package weave { var obj:SharedObject = SharedObject.getLocal(WEAVE_RELOAD_SHARED_OBJECT); var uid:String = WEAVE_RELOAD_SHARED_OBJECT; - if (ExternalInterface.available && ExternalInterface.objectID) + if (JavaScript.available && ExternalInterface.objectID) { try { // get uid that was previously saved in parent node - uid = WeaveAPI.executeJavaScript( - 'var p = weave.parentNode;', + uid = JavaScript.exec( + 'var p = this.parentNode;', 'var reloadID = p.weaveReloadID;', 'p.weaveReloadID = undefined;', 'return reloadID;' @@ -574,11 +574,11 @@ package weave private static var _startupComplete:Boolean = false; public static function initExternalDragDrop():void { - if (_startupComplete || !ExternalInterface.available) + if (_startupComplete || !JavaScript.available) return; try { - WeaveAPI.executeJavaScript(new WeaveStartup()); + JavaScript.exec({"this": "weave"}, new WeaveStartup()); _startupComplete = true; } catch (e:Error) diff --git a/WeaveUISpark/src/weave/WeaveProperties.as b/WeaveUISpark/src/weave/WeaveProperties.as index d10d8d4a0e..6c4a99fc05 100644 --- a/WeaveUISpark/src/weave/WeaveProperties.as +++ b/WeaveUISpark/src/weave/WeaveProperties.as @@ -21,7 +21,6 @@ package weave { import flash.display.Stage; import flash.events.Event; - import flash.external.ExternalInterface; import flash.filters.BlurFilter; import flash.filters.DropShadowFilter; import flash.filters.GlowFilter; @@ -330,7 +329,6 @@ package weave public const showKeyTypeInColumnTitle:LinkableBoolean = new LinkableBoolean(false); // cosmetic options - public const pageTitle:LinkableString = new LinkableString("Open Indicators Weave"); // title to show in browser window public const showCopyright:LinkableBoolean = new LinkableBoolean(true); // copyright at bottom of page // probing and selection @@ -463,23 +461,8 @@ package weave */ public function runStartupJavaScript():void { - if (!startupJavaScript.value) - return; - - var prev:Boolean = ExternalInterface.marshallExceptions; - try - { - ExternalInterface.marshallExceptions = true; - WeaveAPI.executeJavaScript(startupJavaScript.value); - } - catch (e:Error) - { - reportError(e); - } - finally - { - ExternalInterface.marshallExceptions = prev; - } + if (startupJavaScript.value) + JavaScript.exec({"this": "weave", "catch": reportError}, startupJavaScript.value); } /** diff --git a/WeaveUISpark/src/weave/utils/CustomCursorManager.as b/WeaveUISpark/src/weave/utils/CustomCursorManager.as index 059d82d5f4..f85c81f959 100644 --- a/WeaveUISpark/src/weave/utils/CustomCursorManager.as +++ b/WeaveUISpark/src/weave/utils/CustomCursorManager.as @@ -19,7 +19,6 @@ package weave.utils { import flash.display.BitmapData; - import flash.external.ExternalInterface; import flash.geom.Point; import flash.system.Capabilities; import flash.ui.Mouse; @@ -27,8 +26,6 @@ package weave.utils import flash.ui.MouseCursorData; import mx.core.BitmapAsset; - - import weave.api.WeaveAPI; /** * Easy interface for using native cursors. @@ -46,11 +43,11 @@ package weave.utils { if (!_initialized) { - if (Capabilities.manufacturer == "Adobe Linux" && ExternalInterface.available) + if (Capabilities.manufacturer == "Adobe Linux" && JavaScript.available) { - _customCursorsSupported = WeaveAPI.executeJavaScript( + _customCursorsSupported = JavaScript.exec( 'try {', - ' return weave.children.wmode.value != "transparent";', + ' return this.children.wmode.value != "transparent";', '} catch (e) { return true; }' ); }