From eb21bbdd550e4d1efc9a4c6e506eb64ba2cf9842 Mon Sep 17 00:00:00 2001 From: friendica Date: Mon, 27 Jan 2014 18:37:06 -0800 Subject: Ajaxchat package has way too many incompatible assumptions - after a lot of review, we can't work with it without re-writing huge chunks. Think I'll just start fresh. Ajax chat isn't that hard and we can do stuff with it that you just can't do with other chat clients because - well we've got zot. --- library/ajaxchat/chat/src/FABridge.as | 943 ---------------------------------- 1 file changed, 943 deletions(-) delete mode 100644 library/ajaxchat/chat/src/FABridge.as (limited to 'library/ajaxchat/chat/src/FABridge.as') diff --git a/library/ajaxchat/chat/src/FABridge.as b/library/ajaxchat/chat/src/FABridge.as deleted file mode 100644 index d03dba01a..000000000 --- a/library/ajaxchat/chat/src/FABridge.as +++ /dev/null @@ -1,943 +0,0 @@ -/* -Copyright � 2006 Adobe Systems Incorporated - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE -OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - -/* - * The Bridge class, responsible for navigating JS instances - */ -package bridge -{ - -/* - * imports - */ -import flash.external.ExternalInterface; -import flash.utils.Timer; -import flash.events.*; -import flash.display.DisplayObject; -import flash.system.ApplicationDomain; -import flash.utils.Dictionary; -import flash.utils.setTimeout; - -import mx.collections.errors.ItemPendingError; -import mx.core.IMXMLObject; - -import flash.utils.getQualifiedClassName; -import flash.utils.describeType; -import flash.events.TimerEvent; - -/** - * The FABridge class, responsible for proxying AS objects into javascript - */ -public class FABridge extends EventDispatcher implements IMXMLObject -{ - - //holds a list of stuff to call later, to break the recurrence of the js <> as calls - //you must use the full class name, as returned by the getQualifiedClassName() function - public static const MethodsToCallLater:Object = new Object(); - MethodsToCallLater["mx.collections::ArrayCollection"]="refresh,removeItemAt"; - - public static const EventsToCallLater:Object = new Object(); - EventsToCallLater["mx.data.events::UnresolvedConflictsEvent"]="true"; - EventsToCallLater["mx.events::PropertyChangeEvent"]="true"; - - public static const INITIALIZED:String = "bridgeInitialized"; - - // constructor - public function FABridge() - { - super(); - initializeCallbacks(); - } - - // private vars - - /** - * stores a cache of descriptions of AS types suitable for sending to JS - */ - private var localTypeMap:Dictionary = new Dictionary(); - - /** - * stores an id-referenced dictionary of objects exported to JS - */ - private var localInstanceMap:Dictionary = new Dictionary(); - - /** - * stores an id-referenced dictionary of functions exported to JS - */ - private var localFunctionMap:Dictionary = new Dictionary(); - - /** - * stores an id-referenced dictionary of proxy functions imported from JS - */ - private var remoteFunctionCache:Dictionary = new Dictionary(); - - /** - * stores a list of custom serialization functions - */ - private var customSerializersMap:Dictionary = new Dictionary(); - - /** - * stores a map of object ID's and their reference count - */ - private var refMap:Dictionary = new Dictionary(); - /** - * a local counter for generating unique IDs - */ - private var nextID:Number = 0; - - private var lastRef:int; - - /* values that can't be serialized natively across the bridge are packed and identified by type. - These constants represent different serialization types */ - public static const TYPE_ASINSTANCE:uint = 1; - public static const TYPE_ASFUNCTION:uint = 2; - public static const TYPE_JSFUNCTION:uint = 3; - public static const TYPE_ANONYMOUS:uint = 4; - - private var _initChecked:Boolean = false; - - // properties - - //getters and setters for the main component in the swf - the root - public function get rootObject():DisplayObject {return _rootObject;} - public function set rootObject(value:DisplayObject):void - { - _rootObject = value; - checkInitialized(); - } - - /** - * the bridge name - */ - public var bridgeName:String; - private var _registerComplete:Boolean = false; - - /** - * increment the reference count for an object being passed over the bridge - */ - public function incRef(objId:int):void - { - if(refMap[objId] == null) { - //the object is being created; we now add it to the map and set its refCount = 1 - refMap[objId] = 1; - } else { - refMap[objId] = refMap[objId] +1; - } - } - - /** - * when an object has been completely passed to JS its reference count is decreased with 1 - */ - public function releaseRef(objId:int):void - { - if(refMap[objId] != null) - { - var newRefVal:int = refMap[objId] - 1; - // if the object exists in the referenceMap and its count equals or has dropped under 0 we clean it up - if(refMap[objId] != null && newRefVal <= 0) - { - delete refMap[objId]; - delete localInstanceMap[objId]; - } - else - { - refMap[objId] = newRefVal; - } - } - } - - /** - * attaches the callbacks to external interface - */ - public function initializeCallbacks():void - { - if (ExternalInterface.available == false) - { - return; - } - - ExternalInterface.addCallback("getRoot", js_getRoot); - ExternalInterface.addCallback("getPropFromAS", js_getPropFromAS); - ExternalInterface.addCallback("setPropInAS", js_setPropertyInAS); - ExternalInterface.addCallback("invokeASMethod", js_invokeMethod); - ExternalInterface.addCallback("invokeASFunction", js_invokeFunction); - ExternalInterface.addCallback("releaseASObjects", js_releaseASObjects); - ExternalInterface.addCallback("create", js_create); - ExternalInterface.addCallback("releaseNamedASObject",js_releaseNamedASObject); - ExternalInterface.addCallback("incRef", incRef); - ExternalInterface.addCallback("releaseRef", releaseRef); - } - - private var _rootObject:DisplayObject; - - private var _document:DisplayObject; - - /** - * called to check whether the bridge has been initialized for the specified document/id pairs - */ - public function initialized(document:Object, id:String):void - { - _document = (document as DisplayObject); - - if (_document != null) - { - checkInitialized(); - } - } - - private function get baseObject():DisplayObject - { - return (rootObject == null)? _document:rootObject; - } - - - private function checkInitialized():void - { - if(_initChecked== true) - { - return; - } - _initChecked = true; - - // oops! timing error. Player team is working on it. - var t:Timer = new Timer(200,1); - t.addEventListener(TimerEvent.TIMER,auxCheckInitialized); - t.start(); - } - - /** - * auxiliary initialization check that is called after the timing has occurred - */ - private function auxCheckInitialized(e:Event):void - { - - var bCanGetParams:Boolean = true; - - try - { - var params:Object = baseObject.root.loaderInfo.parameters; - } - catch (e:Error) - { - bCanGetParams = false; - } - - if (bCanGetParams == false) - { - var t:Timer = new Timer(100); - var timerFunc:Function = function(e:TimerEvent):void - { - if(baseObject.root != null) - { - try - { - bCanGetParams = true; - var params:Object = baseObject.root.loaderInfo.parameters; - } - catch (err:Error) - { - bCanGetParams = false; - } - if (bCanGetParams) - { - t.removeEventListener(TimerEvent.TIMER, timerFunc); - t.stop(); - dispatchInit(); - } - } - } - t.addEventListener(TimerEvent.TIMER, timerFunc); - t.start(); - } - else - { - dispatchInit(); - } - } - - /** - * call into JS to annunce that the bridge is ready to be used - */ - private function dispatchInit(e:Event = null):void - { - if(_registerComplete == true) - { - return; - } - - if (ExternalInterface.available == false) - { - return; - } - - if (bridgeName == null) - { - bridgeName = baseObject.root.loaderInfo.parameters["bridgeName"]; - - if(bridgeName == null) - { - bridgeName = "flash"; - } - } - - _registerComplete = ExternalInterface.call("FABridge__bridgeInitialized", [bridgeName]); - dispatchEvent(new Event(FABridge.INITIALIZED)); - } - - // serialization/deserialization - - /** serializes a value for transfer across the bridge. primitive types are left as is. Arrays are left as arrays, but individual - * values in the array are serialized according to their type. Functions and class instances are inserted into a hash table and sent - * across as keys into the table. - * - * For class instances, if the instance has been sent before, only its id is passed. If This is the first time the instance has been sent, - * a ref descriptor is sent associating the id with a type string. If this is the first time any instance of that type has been sent - * across, a descriptor indicating methods, properties, and variables of the type is also sent across - */ - public function serialize(value:*, keep_refs:Boolean=false):* - { - var result:* = {}; - result.newTypes = []; - result.newRefs = {}; - - if (value is Number || value is Boolean || value is String || value == null || value == undefined || value is int || value is uint) - { - result = value; - } - else if (value is Array) - { - result = []; - for(var i:int = 0; i < value.length; i++) - { - result[i] = serialize(value[i], keep_refs); - } - } - else if (value is Function) - { - // serialize a class - result.type = TYPE_ASFUNCTION; - result.value = getFunctionID(value, true); - } - else if (getQualifiedClassName(value) == "Object") - { - result.type = TYPE_ANONYMOUS; - result.value = value; - } - else - { - // serialize a class - result.type = TYPE_ASINSTANCE; - // make sure the type info is available - var className:String = getQualifiedClassName(value); - - var serializer:Function = customSerializersMap[className]; - - // try looking up the serializer under an alternate name - if (serializer == null) - { - if (className.indexOf('$') > 0) - { - var split:int = className.lastIndexOf(':'); - if (split > 0) - { - var alternate:String = className.substring(split+1); - serializer = customSerializersMap[alternate]; - } - } - } - - if (serializer != null) - { - return serializer.apply(null, [value, keep_refs]); - } - else - { - if (retrieveCachedTypeDescription(className, false) == null) - { - try - { - result.newTypes.push(retrieveCachedTypeDescription(className, true)); - } - catch(err:Error) - { - var interfaceInfo:XMLList = describeType(value).implementsInterface; - for each (var interf:XML in interfaceInfo) - { - className = interf.@type.toString(); - if (retrieveCachedTypeDescription(className, false) == null){ - result.newTypes.push(retrieveCachedTypeDescription(className, true)); - } //end if push new data type - - } //end for going through interfaces - var baseClass:String = describeType(value).@base.toString(); - if (retrieveCachedTypeDescription(baseClass, false) == null){ - result.newTypes.push(retrieveCachedTypeDescription(baseClass, true)); - } //end if push new data type - } - } - - // make sure the reference is known - var objRef:Number = getRef(value, false); - var should_keep_ref:Boolean = false; - if (isNaN(objRef)) - { - //create the reference if necessary - objRef = getRef(value, true); - should_keep_ref = true; - } - - result.newRefs[objRef] = className; - //trace("serializing new reference: " + className + " with value" + value); - - //the result is a getProperty / invokeMethod call. How can we know how much you will need the object ? - if (keep_refs && should_keep_ref) { - incRef(objRef); - } - result.value = objRef; - } - } - return result; - } - - /** - * deserializes a value passed in from javascript. See serialize for details on how values are packed and - * unpacked for transfer across the bridge. - */ - public function deserialize(valuePackage:*):* - { - var result:*; - if (valuePackage is Number || valuePackage is Boolean || valuePackage is String || valuePackage === null || valuePackage === undefined || valuePackage is int || valuePackage is uint) - { - result = valuePackage; - } - else if(valuePackage is Array) - { - result = []; - for (var i:int = 0; i < valuePackage.length; i++) - { - result[i] = deserialize(valuePackage[i]); - } - } - else if (valuePackage.type == FABridge.TYPE_JSFUNCTION) - { - result = getRemoteFunctionProxy(valuePackage.value, true); - } - else if (valuePackage.type == FABridge.TYPE_ASFUNCTION) - { - throw new Error("as functions can't be passed back to as yet"); - } - else if (valuePackage.type == FABridge.TYPE_ASINSTANCE) - { - result = resolveRef(valuePackage.value); - } - else if (valuePackage.type == FABridge.TYPE_ANONYMOUS) - { - result = valuePackage.value; - } - return result; - } - - public function addCustomSerialization(className:String, serializationFunction:Function):void - { - customSerializersMap[className] = serializationFunction; - } - - - // type management - - /** - * retrieves a type description for the type indicated by className, building one and caching it if necessary - */ - public function retrieveCachedTypeDescription(className:String, createifNecessary:Boolean):Object - { - if(localTypeMap[className] == null && createifNecessary == true) - { - localTypeMap[className] = buildTypeDescription(className); - } - return localTypeMap[className]; - } - - public function addCachedTypeDescription(className:String, desc:Object):Object - { - if (localTypeMap[className] == null) - { - localTypeMap[className] = desc; - } - return localTypeMap[className]; - } - - /** - * builds a type description for the type indiciated by className - */ - public function buildTypeDescription(className:String):Object - { - var desc:Object = {}; - - className = className.replace(/::/,"."); - - var objClass:Class = Class(ApplicationDomain.currentDomain.getDefinition(className)); - - var xData:XML = describeType(objClass); - - desc.name = xData.@name.toString(); - - var methods:Array = []; - var xMethods:XMLList = xData.factory.method; - for (var i:int = 0; i < xMethods.length(); i++) - { - methods.push(xMethods[i].@name.toString()); - } - desc.methods = methods; - - var accessors:Array = []; - var xAcc:XMLList = xData.factory.accessor; - for (i = 0; i < xAcc.length(); i++) - { - accessors.push(xAcc[i].@name.toString()); - } - xAcc = xData.factory.variable; - for (i = 0; i < xAcc.length(); i++) - { - accessors.push(xAcc[i].@name.toString()); - } - desc.accessors = accessors; - - return desc; - } - -// instance mgmt - - /** - * resolves an instance id passed from JS to an instance previously cached for representing in JS - */ - private function resolveRef(objRef:Number):Object - { - try - { - return (objRef == -1)? baseObject : localInstanceMap[objRef]; - } - catch(e:Error) - { - return serialize("__FLASHERROR__"+"||"+e.message); - } - - return (objRef == -1)? baseObject : localInstanceMap[objRef]; - } - - /** - * returns an id associated with the object provided for passing across the bridge to JS - */ - public function getRef(obj:Object, createIfNecessary:Boolean):Number - { - try - { - var ref:Number; - - if (createIfNecessary) - { - var newRef:Number = nextID++; - localInstanceMap[newRef] = obj; - ref = newRef; - } - else - { - for (var key:* in localInstanceMap) - { - if (localInstanceMap[key] === obj) - { - ref = key; - break; - } - } - } - } - catch(e:Error) - { - return serialize("__FLASHERROR__"+"||"+e.message) - } - - return ref; - } - - - // function management - - /** - * resolves a function ID passed from JS to a local function previously cached for representation in JS - */ - private function resolveFunctionID(funcID:Number):Function - { - return localFunctionMap[funcID]; - } - - /** - * associates a unique ID with a local function suitable for passing across the bridge to proxy in Javascript - */ - public function getFunctionID(f:Function, createIfNecessary:Boolean):Number - { - var ref:Number; - - if (createIfNecessary) - { - var newID:Number = nextID++; - localFunctionMap[newID] = f; - ref = newID; - } - else - { - for (var key:* in localFunctionMap) - { - if (localFunctionMap[key] === f) { - ref = key; - } - break; - } - } - - return ref; - } - - /** - * returns a proxy function that represents a function defined in javascript. This function can be called syncrhonously, and will - * return any values returned by the JS function - */ - public function getRemoteFunctionProxy(functionID:Number, createIfNecessary:Boolean):Function - { - try - { - if (remoteFunctionCache[functionID] == null) - { - remoteFunctionCache[functionID] = function(...args):* - { - var externalArgs:Array = args.concat(); - externalArgs.unshift(functionID); - var serializedArgs:* = serialize(externalArgs, true); - - if(checkToThrowLater(serializedArgs[1])) - { - setTimeout(function a():* { - try { - var retVal:* = ExternalInterface.call("FABridge__invokeJSFunction", serializedArgs); - for(var i:int = 0; i