rocket-js 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -11
- data/Rakefile +33 -47
- data/lib/rocket/js.rb +0 -2
- data/lib/rocket/js/builder.rb +2 -2
- data/lib/rocket/js/cli.rb +1 -1
- data/rocket-js.gemspec +23 -80
- data/src/vendor/web-socket-js/FABridge.js +604 -0
- data/src/vendor/web-socket-js/README.txt +109 -0
- data/src/vendor/web-socket-js/WebSocketMain.swf +0 -0
- data/src/vendor/web-socket-js/WebSocketMainInsecure.zip +0 -0
- data/src/vendor/web-socket-js/flash-src/WebSocket.as +473 -0
- data/src/vendor/web-socket-js/flash-src/WebSocketMain.as +88 -0
- data/src/vendor/web-socket-js/flash-src/WebSocketMainInsecure.as +19 -0
- data/src/vendor/web-socket-js/flash-src/WebSocketStateEvent.as +32 -0
- data/src/vendor/web-socket-js/flash-src/bridge/FABridge.as +943 -0
- data/src/vendor/web-socket-js/flash-src/build.sh +10 -0
- data/src/vendor/web-socket-js/flash-src/com/adobe/net/proxies/RFC2817Socket.as +204 -0
- data/src/vendor/web-socket-js/flash-src/com/gsolo/encryption/MD5.as +375 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/Crypto.as +287 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/cert/MozillaRootCertificates.as +3235 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/cert/X509Certificate.as +218 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/cert/X509CertificateCollection.as +57 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/HMAC.as +82 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/IHMAC.as +27 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/IHash.as +21 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/MAC.as +137 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/MD2.as +124 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/MD5.as +204 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/SHA1.as +106 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/SHA224.as +28 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/SHA256.as +115 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/SHABase.as +71 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/prng/ARC4.as +90 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/prng/IPRNG.as +20 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/prng/Random.as +119 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/prng/TLSPRF.as +142 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/rsa/RSAKey.as +339 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/AESKey.as +2797 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/BlowFishKey.as +375 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/CBCMode.as +55 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/CFB8Mode.as +61 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/CFBMode.as +64 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/CTRMode.as +58 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/DESKey.as +365 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/ECBMode.as +86 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/ICipher.as +21 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/IMode.as +15 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/IPad.as +32 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/IStreamCipher.as +21 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/ISymmetricKey.as +35 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/IVMode.as +110 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/NullPad.as +34 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/OFBMode.as +52 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/PKCS5.as +44 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/SSLPad.as +44 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/SimpleIVMode.as +60 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/TLSPad.as +42 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/TripleDESKey.as +88 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/XTeaKey.as +94 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/aeskey.pl +29 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/dump.txt +2304 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/AESKeyTest.as +1220 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/ARC4Test.as +58 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/BigIntegerTest.as +39 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/BlowFishKeyTest.as +148 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/CBCModeTest.as +160 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/CFB8ModeTest.as +71 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/CFBModeTest.as +98 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/CTRModeTest.as +109 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/DESKeyTest.as +112 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/ECBModeTest.as +151 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/HMACTest.as +184 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/ITestHarness.as +20 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/MD2Test.as +56 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/MD5Test.as +58 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/OFBModeTest.as +101 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/RSAKeyTest.as +92 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/SHA1Test.as +198 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/SHA224Test.as +58 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/SHA256Test.as +60 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/TLSPRFTest.as +51 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/TestCase.as +42 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/TripleDESKeyTest.as +59 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/XTeaKeyTest.as +66 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/BulkCiphers.as +102 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/CipherSuites.as +117 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/IConnectionState.as +14 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/ISecurityParameters.as +29 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/KeyExchanges.as +24 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/MACs.as +38 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLConnectionState.as +171 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLEvent.as +26 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLSecurityParameters.as +340 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSConfig.as +70 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSConnectionState.as +151 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSEngine.as +895 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSError.as +39 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSEvent.as +27 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSSecurityParameters.as +197 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSSocket.as +370 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSSocketEvent.as +26 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSTest.as +180 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/math/BarrettReduction.as +90 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/math/BigInteger.as +1543 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/math/ClassicReduction.as +35 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/math/IReduction.as +11 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/math/MontgomeryReduction.as +85 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/math/NullReduction.as +34 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/math/bi_internal.as +11 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/ArrayUtil.as +25 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/Base64.as +189 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/Hex.as +66 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/Memory.as +28 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/ByteString.as +43 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/DER.as +210 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/IAsn1Type.as +21 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/Integer.as +44 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/OID.as +35 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/ObjectIdentifier.as +112 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/PEM.as +118 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/PrintableString.as +49 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/Sequence.as +90 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/Set.as +27 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/Type.as +94 -0
- data/src/vendor/web-socket-js/flash-src/com/hurlant/util/der/UTCTime.as +60 -0
- data/src/vendor/web-socket-js/sample.html +76 -0
- data/src/vendor/web-socket-js/swfobject.js +4 -0
- data/src/vendor/web-socket-js/web_socket.js +388 -0
- metadata +163 -30
- data/lib/rocket/js/version.rb +0 -14
- data/rocket-0.0.1.min.js +0 -45
@@ -0,0 +1,88 @@
|
|
1
|
+
// Copyright: Hiroshi Ichikawa <http://gimite.net/en/>
|
2
|
+
// License: New BSD License
|
3
|
+
// Reference: http://dev.w3.org/html5/websockets/
|
4
|
+
// Reference: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76
|
5
|
+
|
6
|
+
package {
|
7
|
+
|
8
|
+
import flash.display.*;
|
9
|
+
import flash.events.*;
|
10
|
+
import flash.external.*;
|
11
|
+
import flash.net.*;
|
12
|
+
import flash.system.*;
|
13
|
+
import flash.utils.*;
|
14
|
+
import mx.core.*;
|
15
|
+
import mx.controls.*;
|
16
|
+
import mx.events.*;
|
17
|
+
import mx.utils.*;
|
18
|
+
import bridge.FABridge;
|
19
|
+
|
20
|
+
public class WebSocketMain extends Sprite {
|
21
|
+
|
22
|
+
private var callerUrl:String;
|
23
|
+
private var debug:Boolean = false;
|
24
|
+
|
25
|
+
public function WebSocketMain() {
|
26
|
+
|
27
|
+
// This is to avoid "You are trying to call recursively into the Flash Player ..."
|
28
|
+
// error which (I heard) happens when you pass bunch of messages.
|
29
|
+
// This workaround was written here:
|
30
|
+
// http://www.themorphicgroup.com/blog/2009/02/14/fabridge-error-you-are-trying-to-call-recursively-into-the-flash-player-which-is-not-allowed/
|
31
|
+
FABridge.EventsToCallLater["flash.events::Event"] = "true";
|
32
|
+
FABridge.EventsToCallLater["WebSocketMessageEvent"] = "true";
|
33
|
+
FABridge.EventsToCallLater["WebSocketStateEvent"] = "true";
|
34
|
+
|
35
|
+
var fab:FABridge = new FABridge();
|
36
|
+
fab.rootObject = this;
|
37
|
+
//log("Flash initialized");
|
38
|
+
|
39
|
+
}
|
40
|
+
|
41
|
+
public function setCallerUrl(url:String):void {
|
42
|
+
callerUrl = url;
|
43
|
+
}
|
44
|
+
|
45
|
+
public function setDebug(val:Boolean):void {
|
46
|
+
debug = val;
|
47
|
+
}
|
48
|
+
|
49
|
+
public function create(
|
50
|
+
url:String, protocol:String,
|
51
|
+
proxyHost:String = null, proxyPort:int = 0,
|
52
|
+
headers:String = null):WebSocket {
|
53
|
+
loadPolicyFile("xmlsocket://" + URLUtil.getServerName(url) + ":843");
|
54
|
+
return new WebSocket(this, url, protocol, proxyHost, proxyPort, headers);
|
55
|
+
}
|
56
|
+
|
57
|
+
public function getOrigin():String {
|
58
|
+
return (URLUtil.getProtocol(this.callerUrl) + "://" +
|
59
|
+
URLUtil.getServerNameWithPort(this.callerUrl)).toLowerCase();
|
60
|
+
}
|
61
|
+
|
62
|
+
public function getCallerHost():String {
|
63
|
+
return URLUtil.getServerName(this.callerUrl);
|
64
|
+
}
|
65
|
+
|
66
|
+
public function loadPolicyFile(url:String):void {
|
67
|
+
log("policy file: " + url);
|
68
|
+
Security.loadPolicyFile(url);
|
69
|
+
}
|
70
|
+
|
71
|
+
public function log(message:String):void {
|
72
|
+
if (debug) {
|
73
|
+
ExternalInterface.call("webSocketLog", encodeURIComponent("[WebSocket] " + message));
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
public function error(message:String):void {
|
78
|
+
ExternalInterface.call("webSocketError", encodeURIComponent("[WebSocket] " + message));
|
79
|
+
}
|
80
|
+
|
81
|
+
public function fatal(message:String):void {
|
82
|
+
ExternalInterface.call("webSocketError", encodeURIComponent("[WebSocket] " + message));
|
83
|
+
throw message;
|
84
|
+
}
|
85
|
+
|
86
|
+
}
|
87
|
+
|
88
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
// Copyright: Hiroshi Ichikawa <http://gimite.net/en/>
|
2
|
+
// License: New BSD License
|
3
|
+
// Reference: http://dev.w3.org/html5/websockets/
|
4
|
+
// Reference: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76
|
5
|
+
|
6
|
+
package {
|
7
|
+
|
8
|
+
import flash.system.*;
|
9
|
+
|
10
|
+
public class WebSocketMainInsecure extends WebSocketMain {
|
11
|
+
|
12
|
+
public function WebSocketMainInsecure() {
|
13
|
+
Security.allowDomain("*");
|
14
|
+
super();
|
15
|
+
}
|
16
|
+
|
17
|
+
}
|
18
|
+
|
19
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
// Copyright: Hiroshi Ichikawa <http://gimite.net/en/>
|
2
|
+
// License: New BSD License
|
3
|
+
// Reference: http://dev.w3.org/html5/websockets/
|
4
|
+
// Reference: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-31
|
5
|
+
|
6
|
+
package {
|
7
|
+
|
8
|
+
import flash.display.*;
|
9
|
+
import flash.events.*;
|
10
|
+
import flash.external.*;
|
11
|
+
import flash.net.*;
|
12
|
+
import flash.system.*;
|
13
|
+
import flash.utils.*;
|
14
|
+
import mx.core.*;
|
15
|
+
import mx.controls.*;
|
16
|
+
import mx.events.*;
|
17
|
+
import mx.utils.*;
|
18
|
+
|
19
|
+
public class WebSocketStateEvent extends Event {
|
20
|
+
|
21
|
+
public var readyState:int;
|
22
|
+
public var bufferedAmount:int;
|
23
|
+
|
24
|
+
public function WebSocketStateEvent(type:String, readyState:int, bufferedAmount:int) {
|
25
|
+
super(type);
|
26
|
+
this.readyState = readyState;
|
27
|
+
this.bufferedAmount = bufferedAmount;
|
28
|
+
}
|
29
|
+
|
30
|
+
}
|
31
|
+
|
32
|
+
}
|
@@ -0,0 +1,943 @@
|
|
1
|
+
/*
|
2
|
+
Copyright � 2006 Adobe Systems Incorporated
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
5
|
+
to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
6
|
+
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:
|
7
|
+
|
8
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
9
|
+
|
10
|
+
|
11
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
12
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
13
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
14
|
+
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
15
|
+
|
16
|
+
*/
|
17
|
+
|
18
|
+
|
19
|
+
/*
|
20
|
+
* The Bridge class, responsible for navigating JS instances
|
21
|
+
*/
|
22
|
+
package bridge
|
23
|
+
{
|
24
|
+
|
25
|
+
/*
|
26
|
+
* imports
|
27
|
+
*/
|
28
|
+
import flash.external.ExternalInterface;
|
29
|
+
import flash.utils.Timer;
|
30
|
+
import flash.events.*;
|
31
|
+
import flash.display.DisplayObject;
|
32
|
+
import flash.system.ApplicationDomain;
|
33
|
+
import flash.utils.Dictionary;
|
34
|
+
import flash.utils.setTimeout;
|
35
|
+
|
36
|
+
import mx.collections.errors.ItemPendingError;
|
37
|
+
import mx.core.IMXMLObject;
|
38
|
+
|
39
|
+
import flash.utils.getQualifiedClassName;
|
40
|
+
import flash.utils.describeType;
|
41
|
+
import flash.events.TimerEvent;
|
42
|
+
|
43
|
+
/**
|
44
|
+
* The FABridge class, responsible for proxying AS objects into javascript
|
45
|
+
*/
|
46
|
+
public class FABridge extends EventDispatcher implements IMXMLObject
|
47
|
+
{
|
48
|
+
|
49
|
+
//holds a list of stuff to call later, to break the recurrence of the js <> as calls
|
50
|
+
//you must use the full class name, as returned by the getQualifiedClassName() function
|
51
|
+
public static const MethodsToCallLater:Object = new Object();
|
52
|
+
MethodsToCallLater["mx.collections::ArrayCollection"]="refresh,removeItemAt";
|
53
|
+
|
54
|
+
public static const EventsToCallLater:Object = new Object();
|
55
|
+
EventsToCallLater["mx.data.events::UnresolvedConflictsEvent"]="true";
|
56
|
+
EventsToCallLater["mx.events::PropertyChangeEvent"]="true";
|
57
|
+
|
58
|
+
public static const INITIALIZED:String = "bridgeInitialized";
|
59
|
+
|
60
|
+
// constructor
|
61
|
+
public function FABridge()
|
62
|
+
{
|
63
|
+
super();
|
64
|
+
initializeCallbacks();
|
65
|
+
}
|
66
|
+
|
67
|
+
// private vars
|
68
|
+
|
69
|
+
/**
|
70
|
+
* stores a cache of descriptions of AS types suitable for sending to JS
|
71
|
+
*/
|
72
|
+
private var localTypeMap:Dictionary = new Dictionary();
|
73
|
+
|
74
|
+
/**
|
75
|
+
* stores an id-referenced dictionary of objects exported to JS
|
76
|
+
*/
|
77
|
+
private var localInstanceMap:Dictionary = new Dictionary();
|
78
|
+
|
79
|
+
/**
|
80
|
+
* stores an id-referenced dictionary of functions exported to JS
|
81
|
+
*/
|
82
|
+
private var localFunctionMap:Dictionary = new Dictionary();
|
83
|
+
|
84
|
+
/**
|
85
|
+
* stores an id-referenced dictionary of proxy functions imported from JS
|
86
|
+
*/
|
87
|
+
private var remoteFunctionCache:Dictionary = new Dictionary();
|
88
|
+
|
89
|
+
/**
|
90
|
+
* stores a list of custom serialization functions
|
91
|
+
*/
|
92
|
+
private var customSerializersMap:Dictionary = new Dictionary();
|
93
|
+
|
94
|
+
/**
|
95
|
+
* stores a map of object ID's and their reference count
|
96
|
+
*/
|
97
|
+
private var refMap:Dictionary = new Dictionary();
|
98
|
+
/**
|
99
|
+
* a local counter for generating unique IDs
|
100
|
+
*/
|
101
|
+
private var nextID:Number = 0;
|
102
|
+
|
103
|
+
private var lastRef:int;
|
104
|
+
|
105
|
+
/* values that can't be serialized natively across the bridge are packed and identified by type.
|
106
|
+
These constants represent different serialization types */
|
107
|
+
public static const TYPE_ASINSTANCE:uint = 1;
|
108
|
+
public static const TYPE_ASFUNCTION:uint = 2;
|
109
|
+
public static const TYPE_JSFUNCTION:uint = 3;
|
110
|
+
public static const TYPE_ANONYMOUS:uint = 4;
|
111
|
+
|
112
|
+
private var _initChecked:Boolean = false;
|
113
|
+
|
114
|
+
// properties
|
115
|
+
|
116
|
+
//getters and setters for the main component in the swf - the root
|
117
|
+
public function get rootObject():DisplayObject {return _rootObject;}
|
118
|
+
public function set rootObject(value:DisplayObject):void
|
119
|
+
{
|
120
|
+
_rootObject = value;
|
121
|
+
checkInitialized();
|
122
|
+
}
|
123
|
+
|
124
|
+
/**
|
125
|
+
* the bridge name
|
126
|
+
*/
|
127
|
+
public var bridgeName:String;
|
128
|
+
private var _registerComplete:Boolean = false;
|
129
|
+
|
130
|
+
/**
|
131
|
+
* increment the reference count for an object being passed over the bridge
|
132
|
+
*/
|
133
|
+
public function incRef(objId:int):void
|
134
|
+
{
|
135
|
+
if(refMap[objId] == null) {
|
136
|
+
//the object is being created; we now add it to the map and set its refCount = 1
|
137
|
+
refMap[objId] = 1;
|
138
|
+
} else {
|
139
|
+
refMap[objId] = refMap[objId] +1;
|
140
|
+
}
|
141
|
+
}
|
142
|
+
|
143
|
+
/**
|
144
|
+
* when an object has been completely passed to JS its reference count is decreased with 1
|
145
|
+
*/
|
146
|
+
public function releaseRef(objId:int):void
|
147
|
+
{
|
148
|
+
if(refMap[objId] != null)
|
149
|
+
{
|
150
|
+
var newRefVal:int = refMap[objId] - 1;
|
151
|
+
// if the object exists in the referenceMap and its count equals or has dropped under 0 we clean it up
|
152
|
+
if(refMap[objId] != null && newRefVal <= 0)
|
153
|
+
{
|
154
|
+
delete refMap[objId];
|
155
|
+
delete localInstanceMap[objId];
|
156
|
+
}
|
157
|
+
else
|
158
|
+
{
|
159
|
+
refMap[objId] = newRefVal;
|
160
|
+
}
|
161
|
+
}
|
162
|
+
}
|
163
|
+
|
164
|
+
/**
|
165
|
+
* attaches the callbacks to external interface
|
166
|
+
*/
|
167
|
+
public function initializeCallbacks():void
|
168
|
+
{
|
169
|
+
if (ExternalInterface.available == false)
|
170
|
+
{
|
171
|
+
return;
|
172
|
+
}
|
173
|
+
|
174
|
+
ExternalInterface.addCallback("getRoot", js_getRoot);
|
175
|
+
ExternalInterface.addCallback("getPropFromAS", js_getPropFromAS);
|
176
|
+
ExternalInterface.addCallback("setPropInAS", js_setPropertyInAS);
|
177
|
+
ExternalInterface.addCallback("invokeASMethod", js_invokeMethod);
|
178
|
+
ExternalInterface.addCallback("invokeASFunction", js_invokeFunction);
|
179
|
+
ExternalInterface.addCallback("releaseASObjects", js_releaseASObjects);
|
180
|
+
ExternalInterface.addCallback("create", js_create);
|
181
|
+
ExternalInterface.addCallback("releaseNamedASObject",js_releaseNamedASObject);
|
182
|
+
ExternalInterface.addCallback("incRef", incRef);
|
183
|
+
ExternalInterface.addCallback("releaseRef", releaseRef);
|
184
|
+
}
|
185
|
+
|
186
|
+
private var _rootObject:DisplayObject;
|
187
|
+
|
188
|
+
private var _document:DisplayObject;
|
189
|
+
|
190
|
+
/**
|
191
|
+
* called to check whether the bridge has been initialized for the specified document/id pairs
|
192
|
+
*/
|
193
|
+
public function initialized(document:Object, id:String):void
|
194
|
+
{
|
195
|
+
_document = (document as DisplayObject);
|
196
|
+
|
197
|
+
if (_document != null)
|
198
|
+
{
|
199
|
+
checkInitialized();
|
200
|
+
}
|
201
|
+
}
|
202
|
+
|
203
|
+
private function get baseObject():DisplayObject
|
204
|
+
{
|
205
|
+
return (rootObject == null)? _document:rootObject;
|
206
|
+
}
|
207
|
+
|
208
|
+
|
209
|
+
private function checkInitialized():void
|
210
|
+
{
|
211
|
+
if(_initChecked== true)
|
212
|
+
{
|
213
|
+
return;
|
214
|
+
}
|
215
|
+
_initChecked = true;
|
216
|
+
|
217
|
+
// oops! timing error. Player team is working on it.
|
218
|
+
var t:Timer = new Timer(200,1);
|
219
|
+
t.addEventListener(TimerEvent.TIMER,auxCheckInitialized);
|
220
|
+
t.start();
|
221
|
+
}
|
222
|
+
|
223
|
+
/**
|
224
|
+
* auxiliary initialization check that is called after the timing has occurred
|
225
|
+
*/
|
226
|
+
private function auxCheckInitialized(e:Event):void
|
227
|
+
{
|
228
|
+
|
229
|
+
var bCanGetParams:Boolean = true;
|
230
|
+
|
231
|
+
try
|
232
|
+
{
|
233
|
+
var params:Object = baseObject.root.loaderInfo.parameters;
|
234
|
+
}
|
235
|
+
catch (e:Error)
|
236
|
+
{
|
237
|
+
bCanGetParams = false;
|
238
|
+
}
|
239
|
+
|
240
|
+
if (bCanGetParams == false)
|
241
|
+
{
|
242
|
+
var t:Timer = new Timer(100);
|
243
|
+
var timerFunc:Function = function(e:TimerEvent):void
|
244
|
+
{
|
245
|
+
if(baseObject.root != null)
|
246
|
+
{
|
247
|
+
try
|
248
|
+
{
|
249
|
+
bCanGetParams = true;
|
250
|
+
var params:Object = baseObject.root.loaderInfo.parameters;
|
251
|
+
}
|
252
|
+
catch (err:Error)
|
253
|
+
{
|
254
|
+
bCanGetParams = false;
|
255
|
+
}
|
256
|
+
if (bCanGetParams)
|
257
|
+
{
|
258
|
+
t.removeEventListener(TimerEvent.TIMER, timerFunc);
|
259
|
+
t.stop();
|
260
|
+
dispatchInit();
|
261
|
+
}
|
262
|
+
}
|
263
|
+
}
|
264
|
+
t.addEventListener(TimerEvent.TIMER, timerFunc);
|
265
|
+
t.start();
|
266
|
+
}
|
267
|
+
else
|
268
|
+
{
|
269
|
+
dispatchInit();
|
270
|
+
}
|
271
|
+
}
|
272
|
+
|
273
|
+
/**
|
274
|
+
* call into JS to annunce that the bridge is ready to be used
|
275
|
+
*/
|
276
|
+
private function dispatchInit(e:Event = null):void
|
277
|
+
{
|
278
|
+
if(_registerComplete == true)
|
279
|
+
{
|
280
|
+
return;
|
281
|
+
}
|
282
|
+
|
283
|
+
if (ExternalInterface.available == false)
|
284
|
+
{
|
285
|
+
return;
|
286
|
+
}
|
287
|
+
|
288
|
+
if (bridgeName == null)
|
289
|
+
{
|
290
|
+
bridgeName = baseObject.root.loaderInfo.parameters["bridgeName"];
|
291
|
+
|
292
|
+
if(bridgeName == null)
|
293
|
+
{
|
294
|
+
bridgeName = "flash";
|
295
|
+
}
|
296
|
+
}
|
297
|
+
|
298
|
+
_registerComplete = ExternalInterface.call("FABridge__bridgeInitialized", [bridgeName]);
|
299
|
+
dispatchEvent(new Event(FABridge.INITIALIZED));
|
300
|
+
}
|
301
|
+
|
302
|
+
// serialization/deserialization
|
303
|
+
|
304
|
+
/** serializes a value for transfer across the bridge. primitive types are left as is. Arrays are left as arrays, but individual
|
305
|
+
* values in the array are serialized according to their type. Functions and class instances are inserted into a hash table and sent
|
306
|
+
* across as keys into the table.
|
307
|
+
*
|
308
|
+
* 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,
|
309
|
+
* 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
|
310
|
+
* across, a descriptor indicating methods, properties, and variables of the type is also sent across
|
311
|
+
*/
|
312
|
+
public function serialize(value:*, keep_refs:Boolean=false):*
|
313
|
+
{
|
314
|
+
var result:* = {};
|
315
|
+
result.newTypes = [];
|
316
|
+
result.newRefs = {};
|
317
|
+
|
318
|
+
if (value is Number || value is Boolean || value is String || value == null || value == undefined || value is int || value is uint)
|
319
|
+
{
|
320
|
+
result = value;
|
321
|
+
}
|
322
|
+
else if (value is Array)
|
323
|
+
{
|
324
|
+
result = [];
|
325
|
+
for(var i:int = 0; i < value.length; i++)
|
326
|
+
{
|
327
|
+
result[i] = serialize(value[i], keep_refs);
|
328
|
+
}
|
329
|
+
}
|
330
|
+
else if (value is Function)
|
331
|
+
{
|
332
|
+
// serialize a class
|
333
|
+
result.type = TYPE_ASFUNCTION;
|
334
|
+
result.value = getFunctionID(value, true);
|
335
|
+
}
|
336
|
+
else if (getQualifiedClassName(value) == "Object")
|
337
|
+
{
|
338
|
+
result.type = TYPE_ANONYMOUS;
|
339
|
+
result.value = value;
|
340
|
+
}
|
341
|
+
else
|
342
|
+
{
|
343
|
+
// serialize a class
|
344
|
+
result.type = TYPE_ASINSTANCE;
|
345
|
+
// make sure the type info is available
|
346
|
+
var className:String = getQualifiedClassName(value);
|
347
|
+
|
348
|
+
var serializer:Function = customSerializersMap[className];
|
349
|
+
|
350
|
+
// try looking up the serializer under an alternate name
|
351
|
+
if (serializer == null)
|
352
|
+
{
|
353
|
+
if (className.indexOf('$') > 0)
|
354
|
+
{
|
355
|
+
var split:int = className.lastIndexOf(':');
|
356
|
+
if (split > 0)
|
357
|
+
{
|
358
|
+
var alternate:String = className.substring(split+1);
|
359
|
+
serializer = customSerializersMap[alternate];
|
360
|
+
}
|
361
|
+
}
|
362
|
+
}
|
363
|
+
|
364
|
+
if (serializer != null)
|
365
|
+
{
|
366
|
+
return serializer.apply(null, [value, keep_refs]);
|
367
|
+
}
|
368
|
+
else
|
369
|
+
{
|
370
|
+
if (retrieveCachedTypeDescription(className, false) == null)
|
371
|
+
{
|
372
|
+
try
|
373
|
+
{
|
374
|
+
result.newTypes.push(retrieveCachedTypeDescription(className, true));
|
375
|
+
}
|
376
|
+
catch(err:Error)
|
377
|
+
{
|
378
|
+
var interfaceInfo:XMLList = describeType(value).implementsInterface;
|
379
|
+
for each (var interf:XML in interfaceInfo)
|
380
|
+
{
|
381
|
+
className = interf.@type.toString();
|
382
|
+
if (retrieveCachedTypeDescription(className, false) == null){
|
383
|
+
result.newTypes.push(retrieveCachedTypeDescription(className, true));
|
384
|
+
} //end if push new data type
|
385
|
+
|
386
|
+
} //end for going through interfaces
|
387
|
+
var baseClass:String = describeType(value).@base.toString();
|
388
|
+
if (retrieveCachedTypeDescription(baseClass, false) == null){
|
389
|
+
result.newTypes.push(retrieveCachedTypeDescription(baseClass, true));
|
390
|
+
} //end if push new data type
|
391
|
+
}
|
392
|
+
}
|
393
|
+
|
394
|
+
// make sure the reference is known
|
395
|
+
var objRef:Number = getRef(value, false);
|
396
|
+
var should_keep_ref:Boolean = false;
|
397
|
+
if (isNaN(objRef))
|
398
|
+
{
|
399
|
+
//create the reference if necessary
|
400
|
+
objRef = getRef(value, true);
|
401
|
+
should_keep_ref = true;
|
402
|
+
}
|
403
|
+
|
404
|
+
result.newRefs[objRef] = className;
|
405
|
+
//trace("serializing new reference: " + className + " with value" + value);
|
406
|
+
|
407
|
+
//the result is a getProperty / invokeMethod call. How can we know how much you will need the object ?
|
408
|
+
if (keep_refs && should_keep_ref) {
|
409
|
+
incRef(objRef);
|
410
|
+
}
|
411
|
+
result.value = objRef;
|
412
|
+
}
|
413
|
+
}
|
414
|
+
return result;
|
415
|
+
}
|
416
|
+
|
417
|
+
/**
|
418
|
+
* deserializes a value passed in from javascript. See serialize for details on how values are packed and
|
419
|
+
* unpacked for transfer across the bridge.
|
420
|
+
*/
|
421
|
+
public function deserialize(valuePackage:*):*
|
422
|
+
{
|
423
|
+
var result:*;
|
424
|
+
if (valuePackage is Number || valuePackage is Boolean || valuePackage is String || valuePackage === null || valuePackage === undefined || valuePackage is int || valuePackage is uint)
|
425
|
+
{
|
426
|
+
result = valuePackage;
|
427
|
+
}
|
428
|
+
else if(valuePackage is Array)
|
429
|
+
{
|
430
|
+
result = [];
|
431
|
+
for (var i:int = 0; i < valuePackage.length; i++)
|
432
|
+
{
|
433
|
+
result[i] = deserialize(valuePackage[i]);
|
434
|
+
}
|
435
|
+
}
|
436
|
+
else if (valuePackage.type == FABridge.TYPE_JSFUNCTION)
|
437
|
+
{
|
438
|
+
result = getRemoteFunctionProxy(valuePackage.value, true);
|
439
|
+
}
|
440
|
+
else if (valuePackage.type == FABridge.TYPE_ASFUNCTION)
|
441
|
+
{
|
442
|
+
throw new Error("as functions can't be passed back to as yet");
|
443
|
+
}
|
444
|
+
else if (valuePackage.type == FABridge.TYPE_ASINSTANCE)
|
445
|
+
{
|
446
|
+
result = resolveRef(valuePackage.value);
|
447
|
+
}
|
448
|
+
else if (valuePackage.type == FABridge.TYPE_ANONYMOUS)
|
449
|
+
{
|
450
|
+
result = valuePackage.value;
|
451
|
+
}
|
452
|
+
return result;
|
453
|
+
}
|
454
|
+
|
455
|
+
public function addCustomSerialization(className:String, serializationFunction:Function):void
|
456
|
+
{
|
457
|
+
customSerializersMap[className] = serializationFunction;
|
458
|
+
}
|
459
|
+
|
460
|
+
|
461
|
+
// type management
|
462
|
+
|
463
|
+
/**
|
464
|
+
* retrieves a type description for the type indicated by className, building one and caching it if necessary
|
465
|
+
*/
|
466
|
+
public function retrieveCachedTypeDescription(className:String, createifNecessary:Boolean):Object
|
467
|
+
{
|
468
|
+
if(localTypeMap[className] == null && createifNecessary == true)
|
469
|
+
{
|
470
|
+
localTypeMap[className] = buildTypeDescription(className);
|
471
|
+
}
|
472
|
+
return localTypeMap[className];
|
473
|
+
}
|
474
|
+
|
475
|
+
public function addCachedTypeDescription(className:String, desc:Object):Object
|
476
|
+
{
|
477
|
+
if (localTypeMap[className] == null)
|
478
|
+
{
|
479
|
+
localTypeMap[className] = desc;
|
480
|
+
}
|
481
|
+
return localTypeMap[className];
|
482
|
+
}
|
483
|
+
|
484
|
+
/**
|
485
|
+
* builds a type description for the type indiciated by className
|
486
|
+
*/
|
487
|
+
public function buildTypeDescription(className:String):Object
|
488
|
+
{
|
489
|
+
var desc:Object = {};
|
490
|
+
|
491
|
+
className = className.replace(/::/,".");
|
492
|
+
|
493
|
+
var objClass:Class = Class(ApplicationDomain.currentDomain.getDefinition(className));
|
494
|
+
|
495
|
+
var xData:XML = describeType(objClass);
|
496
|
+
|
497
|
+
desc.name = xData.@name.toString();
|
498
|
+
|
499
|
+
var methods:Array = [];
|
500
|
+
var xMethods:XMLList = xData.factory.method;
|
501
|
+
for (var i:int = 0; i < xMethods.length(); i++)
|
502
|
+
{
|
503
|
+
methods.push(xMethods[i].@name.toString());
|
504
|
+
}
|
505
|
+
desc.methods = methods;
|
506
|
+
|
507
|
+
var accessors:Array = [];
|
508
|
+
var xAcc:XMLList = xData.factory.accessor;
|
509
|
+
for (i = 0; i < xAcc.length(); i++)
|
510
|
+
{
|
511
|
+
accessors.push(xAcc[i].@name.toString());
|
512
|
+
}
|
513
|
+
xAcc = xData.factory.variable;
|
514
|
+
for (i = 0; i < xAcc.length(); i++)
|
515
|
+
{
|
516
|
+
accessors.push(xAcc[i].@name.toString());
|
517
|
+
}
|
518
|
+
desc.accessors = accessors;
|
519
|
+
|
520
|
+
return desc;
|
521
|
+
}
|
522
|
+
|
523
|
+
// instance mgmt
|
524
|
+
|
525
|
+
/**
|
526
|
+
* resolves an instance id passed from JS to an instance previously cached for representing in JS
|
527
|
+
*/
|
528
|
+
private function resolveRef(objRef:Number):Object
|
529
|
+
{
|
530
|
+
try
|
531
|
+
{
|
532
|
+
return (objRef == -1)? baseObject : localInstanceMap[objRef];
|
533
|
+
}
|
534
|
+
catch(e:Error)
|
535
|
+
{
|
536
|
+
return serialize("__FLASHERROR__"+"||"+e.message);
|
537
|
+
}
|
538
|
+
|
539
|
+
return (objRef == -1)? baseObject : localInstanceMap[objRef];
|
540
|
+
}
|
541
|
+
|
542
|
+
/**
|
543
|
+
* returns an id associated with the object provided for passing across the bridge to JS
|
544
|
+
*/
|
545
|
+
public function getRef(obj:Object, createIfNecessary:Boolean):Number
|
546
|
+
{
|
547
|
+
try
|
548
|
+
{
|
549
|
+
var ref:Number;
|
550
|
+
|
551
|
+
if (createIfNecessary)
|
552
|
+
{
|
553
|
+
var newRef:Number = nextID++;
|
554
|
+
localInstanceMap[newRef] = obj;
|
555
|
+
ref = newRef;
|
556
|
+
}
|
557
|
+
else
|
558
|
+
{
|
559
|
+
for (var key:* in localInstanceMap)
|
560
|
+
{
|
561
|
+
if (localInstanceMap[key] === obj)
|
562
|
+
{
|
563
|
+
ref = key;
|
564
|
+
break;
|
565
|
+
}
|
566
|
+
}
|
567
|
+
}
|
568
|
+
}
|
569
|
+
catch(e:Error)
|
570
|
+
{
|
571
|
+
return serialize("__FLASHERROR__"+"||"+e.message)
|
572
|
+
}
|
573
|
+
|
574
|
+
return ref;
|
575
|
+
}
|
576
|
+
|
577
|
+
|
578
|
+
// function management
|
579
|
+
|
580
|
+
/**
|
581
|
+
* resolves a function ID passed from JS to a local function previously cached for representation in JS
|
582
|
+
*/
|
583
|
+
private function resolveFunctionID(funcID:Number):Function
|
584
|
+
{
|
585
|
+
return localFunctionMap[funcID];
|
586
|
+
}
|
587
|
+
|
588
|
+
/**
|
589
|
+
* associates a unique ID with a local function suitable for passing across the bridge to proxy in Javascript
|
590
|
+
*/
|
591
|
+
public function getFunctionID(f:Function, createIfNecessary:Boolean):Number
|
592
|
+
{
|
593
|
+
var ref:Number;
|
594
|
+
|
595
|
+
if (createIfNecessary)
|
596
|
+
{
|
597
|
+
var newID:Number = nextID++;
|
598
|
+
localFunctionMap[newID] = f;
|
599
|
+
ref = newID;
|
600
|
+
}
|
601
|
+
else
|
602
|
+
{
|
603
|
+
for (var key:* in localFunctionMap)
|
604
|
+
{
|
605
|
+
if (localFunctionMap[key] === f) {
|
606
|
+
ref = key;
|
607
|
+
}
|
608
|
+
break;
|
609
|
+
}
|
610
|
+
}
|
611
|
+
|
612
|
+
return ref;
|
613
|
+
}
|
614
|
+
|
615
|
+
/**
|
616
|
+
* returns a proxy function that represents a function defined in javascript. This function can be called syncrhonously, and will
|
617
|
+
* return any values returned by the JS function
|
618
|
+
*/
|
619
|
+
public function getRemoteFunctionProxy(functionID:Number, createIfNecessary:Boolean):Function
|
620
|
+
{
|
621
|
+
try
|
622
|
+
{
|
623
|
+
if (remoteFunctionCache[functionID] == null)
|
624
|
+
{
|
625
|
+
remoteFunctionCache[functionID] = function(...args):*
|
626
|
+
{
|
627
|
+
var externalArgs:Array = args.concat();
|
628
|
+
externalArgs.unshift(functionID);
|
629
|
+
var serializedArgs:* = serialize(externalArgs, true);
|
630
|
+
|
631
|
+
if(checkToThrowLater(serializedArgs[1]))
|
632
|
+
{
|
633
|
+
setTimeout(function a():* {
|
634
|
+
try {
|
635
|
+
var retVal:* = ExternalInterface.call("FABridge__invokeJSFunction", serializedArgs);
|
636
|
+
for(var i:int = 0; i<serializedArgs.length; i++)
|
637
|
+
{
|
638
|
+
if(typeof(serializedArgs[i]) == "object" && serializedArgs[i]!=null)
|
639
|
+
{
|
640
|
+
releaseRef(serializedArgs[i].value);
|
641
|
+
}
|
642
|
+
}
|
643
|
+
return retVal;
|
644
|
+
}
|
645
|
+
catch(e:Error)
|
646
|
+
{
|
647
|
+
return serialize("__FLASHERROR__"+"||"+e.message);
|
648
|
+
}
|
649
|
+
},1);
|
650
|
+
}
|
651
|
+
else
|
652
|
+
{
|
653
|
+
var retVal:* = ExternalInterface.call("FABridge__invokeJSFunction", serializedArgs);
|
654
|
+
for(var i:int = 0; i<serializedArgs.length; i++)
|
655
|
+
{
|
656
|
+
if(typeof(serializedArgs[i]) == "object" && serializedArgs[i]!=null)
|
657
|
+
{
|
658
|
+
releaseRef(serializedArgs[i].value);
|
659
|
+
}
|
660
|
+
}
|
661
|
+
return retVal;
|
662
|
+
}
|
663
|
+
}
|
664
|
+
}
|
665
|
+
}
|
666
|
+
catch(e:Error)
|
667
|
+
{
|
668
|
+
return serialize("__FLASHERROR__"+"||"+e.message);
|
669
|
+
}
|
670
|
+
|
671
|
+
return remoteFunctionCache[functionID];
|
672
|
+
}
|
673
|
+
|
674
|
+
/**
|
675
|
+
* function that checks if the object on which we are working demands that it should be called at a later time, breaking the call chain
|
676
|
+
* we check the actual object, as well as the bsae class and interfaces
|
677
|
+
*/
|
678
|
+
private function checkToThrowLater(obj:Object):Boolean
|
679
|
+
{
|
680
|
+
obj = resolveRef(obj.value);
|
681
|
+
var className:String = getQualifiedClassName(obj);
|
682
|
+
var classInfo:XML = describeType(obj);
|
683
|
+
|
684
|
+
if (FABridge.EventsToCallLater[className] != null) {
|
685
|
+
return true;
|
686
|
+
}
|
687
|
+
|
688
|
+
//check if this class doesn't inherit from one of the entries in the table
|
689
|
+
var inheritanceInfo:XMLList = describeType(obj).extendsClass;
|
690
|
+
for each (var inherit:XML in inheritanceInfo)
|
691
|
+
{
|
692
|
+
className = inherit.@type.toString();
|
693
|
+
if (FABridge.EventsToCallLater[className] != null) {
|
694
|
+
return true;
|
695
|
+
}
|
696
|
+
} //end for going through inheritance tree
|
697
|
+
|
698
|
+
//if we're still here, check the interfaces as well
|
699
|
+
|
700
|
+
var interfaceInfo:XMLList = describeType(obj).implementsInterface;
|
701
|
+
for each (var interf:XML in interfaceInfo)
|
702
|
+
{
|
703
|
+
className = interf.@type.toString();
|
704
|
+
if (FABridge.EventsToCallLater[className] != null) {
|
705
|
+
return true;
|
706
|
+
}
|
707
|
+
} //end for going through inheritance tree
|
708
|
+
|
709
|
+
//if nothing was found, return false, so the function gets executed
|
710
|
+
return false;
|
711
|
+
}
|
712
|
+
|
713
|
+
// callbacks exposed to JS
|
714
|
+
|
715
|
+
/**
|
716
|
+
* called to fetch a named property off the instanced associated with objID
|
717
|
+
*/
|
718
|
+
public function js_getPropFromAS(objID:Number, propName:String):*
|
719
|
+
{
|
720
|
+
incRef(objID);
|
721
|
+
try
|
722
|
+
{
|
723
|
+
var obj:Object = resolveRef(objID);
|
724
|
+
var ret:* = serialize(obj[propName], true);
|
725
|
+
releaseRef(objID);
|
726
|
+
return ret;
|
727
|
+
}
|
728
|
+
catch (e:ItemPendingError)
|
729
|
+
{
|
730
|
+
releaseRef(objID);
|
731
|
+
//ItemPendingError
|
732
|
+
//return serialize("an error occcured with" + obj[propName]);
|
733
|
+
}
|
734
|
+
catch(e:Error)
|
735
|
+
{
|
736
|
+
releaseRef(objID);
|
737
|
+
return serialize("__FLASHERROR__" + "||" + e.message);
|
738
|
+
}
|
739
|
+
}
|
740
|
+
|
741
|
+
/**
|
742
|
+
* called to set a named property on the instance associated with objID
|
743
|
+
*/
|
744
|
+
private function js_setPropertyInAS(objID:Number, propRef:String, value:*):*
|
745
|
+
{
|
746
|
+
incRef(objID);
|
747
|
+
try {
|
748
|
+
var obj:Object = resolveRef(objID);
|
749
|
+
obj[propRef] = deserialize(value);
|
750
|
+
releaseRef(objID);
|
751
|
+
}
|
752
|
+
catch(e:Error)
|
753
|
+
{
|
754
|
+
releaseRef(objID);
|
755
|
+
return serialize("__FLASHERROR__" + "||" + e.message);
|
756
|
+
}
|
757
|
+
}
|
758
|
+
|
759
|
+
/**
|
760
|
+
* accessor for retrieveing a proxy to the root object from JS
|
761
|
+
*/
|
762
|
+
private function js_getRoot():*
|
763
|
+
{
|
764
|
+
try
|
765
|
+
{
|
766
|
+
//always get the root; this is the same as the get property, only it is the root object
|
767
|
+
var objRef:Number = getRef(baseObject, false);
|
768
|
+
if (isNaN(objRef))
|
769
|
+
{
|
770
|
+
//create the reference if necessary
|
771
|
+
objRef = getRef(baseObject, true);
|
772
|
+
incRef(objRef);
|
773
|
+
}
|
774
|
+
return serialize(baseObject);
|
775
|
+
}
|
776
|
+
catch(e:Error)
|
777
|
+
{
|
778
|
+
return serialize("__FLASHERROR__"+"||"+e.message);
|
779
|
+
}
|
780
|
+
}
|
781
|
+
|
782
|
+
/**
|
783
|
+
* called to invoke a function or closure associated with funcID
|
784
|
+
*/
|
785
|
+
private function js_invokeFunction(funcID:Number, args:Object):*
|
786
|
+
{
|
787
|
+
var result:*;
|
788
|
+
try
|
789
|
+
{
|
790
|
+
var func:Function = resolveFunctionID(funcID);
|
791
|
+
if(func != null)
|
792
|
+
result = func.apply(null, deserialize(args));
|
793
|
+
|
794
|
+
return serialize(result, true);
|
795
|
+
}
|
796
|
+
catch(e:Error)
|
797
|
+
{
|
798
|
+
return serialize("__FLASHERROR__"+"||"+e.message);
|
799
|
+
}
|
800
|
+
}
|
801
|
+
|
802
|
+
/**
|
803
|
+
* called to invoke a named method on the object associated with objID
|
804
|
+
*/
|
805
|
+
private function js_invokeMethod(objID:Number, methodName:String, args:Object):*
|
806
|
+
{
|
807
|
+
incRef(objID);
|
808
|
+
try
|
809
|
+
{
|
810
|
+
var obj:Object = resolveRef(objID);
|
811
|
+
var result:*;
|
812
|
+
|
813
|
+
//check if the method is callable right now, or later
|
814
|
+
var callLater:Boolean = checkToExecuteLater(obj, methodName);
|
815
|
+
|
816
|
+
if (callLater) {
|
817
|
+
var t:Timer = new Timer(200, 1);
|
818
|
+
t.addEventListener(TimerEvent.TIMER, function():void {
|
819
|
+
var ret_inner:* = serialize(obj[methodName].apply(null, deserialize(args)), true);
|
820
|
+
releaseRef(objID);
|
821
|
+
});
|
822
|
+
t.start();
|
823
|
+
} else {
|
824
|
+
var ret:* = serialize(obj[methodName].apply(null, deserialize(args)), true);
|
825
|
+
releaseRef(objID);
|
826
|
+
return ret;
|
827
|
+
}
|
828
|
+
}
|
829
|
+
catch (e:ItemPendingError)
|
830
|
+
{
|
831
|
+
releaseRef(objID);
|
832
|
+
// ignore ItemPendingError
|
833
|
+
}
|
834
|
+
catch(e:Error)
|
835
|
+
{
|
836
|
+
releaseRef(objID);
|
837
|
+
return serialize("__FLASHERROR__" + "||" + e.message);
|
838
|
+
}
|
839
|
+
}
|
840
|
+
|
841
|
+
/**
|
842
|
+
* method that performs a check on the specified object and method to see if their execution should be delayed or not
|
843
|
+
* it checks the object, its base class and implemented interfaces
|
844
|
+
*/
|
845
|
+
private function checkToExecuteLater(obj:Object, methodName:String):Boolean
|
846
|
+
{
|
847
|
+
var methods:String;
|
848
|
+
var className:String = getQualifiedClassName(obj);
|
849
|
+
var classInfo:XML = describeType(obj);
|
850
|
+
|
851
|
+
if (FABridge.MethodsToCallLater[className] != null) {
|
852
|
+
methods = FABridge.MethodsToCallLater[className];
|
853
|
+
//must call later
|
854
|
+
if(methods.match(methodName))
|
855
|
+
{
|
856
|
+
return true;
|
857
|
+
}
|
858
|
+
}
|
859
|
+
|
860
|
+
//check if this class doesn't inherit from one of the entries in the table
|
861
|
+
var inheritanceInfo:XMLList = describeType(obj).extendsClass;
|
862
|
+
for each (var inherit:XML in inheritanceInfo)
|
863
|
+
{
|
864
|
+
className = inherit.@type.toString();
|
865
|
+
if (FABridge.MethodsToCallLater[className] != null) {
|
866
|
+
methods = FABridge.MethodsToCallLater[className];
|
867
|
+
//must call later
|
868
|
+
if(methods.match(methodName))
|
869
|
+
{
|
870
|
+
return true;
|
871
|
+
}
|
872
|
+
}
|
873
|
+
} //end for going through inheritance tree
|
874
|
+
|
875
|
+
//if we're still here, check the interfaces as well
|
876
|
+
|
877
|
+
var interfaceInfo:XMLList = describeType(obj).implementsInterface;
|
878
|
+
for each (var interf:XML in interfaceInfo)
|
879
|
+
{
|
880
|
+
className = interf.@type.toString();
|
881
|
+
if (FABridge.MethodsToCallLater[className] != null) {
|
882
|
+
methods = FABridge.MethodsToCallLater[className];
|
883
|
+
//must call later
|
884
|
+
if(methods.match(methodName))
|
885
|
+
{
|
886
|
+
return true;
|
887
|
+
}
|
888
|
+
}
|
889
|
+
} //end for going through inheritance tree
|
890
|
+
|
891
|
+
//if nothing was found, return false, so the function gets executed
|
892
|
+
return false;
|
893
|
+
}
|
894
|
+
|
895
|
+
/**
|
896
|
+
* callback from JS to release all AS Objects from the local cache maps
|
897
|
+
*/
|
898
|
+
private function js_releaseASObjects():void
|
899
|
+
{
|
900
|
+
localTypeMap = new Dictionary();
|
901
|
+
localInstanceMap = new Dictionary();
|
902
|
+
localFunctionMap = new Dictionary();
|
903
|
+
}
|
904
|
+
|
905
|
+
/**
|
906
|
+
* callback from JS to release a specific object, identified by its ID
|
907
|
+
*/
|
908
|
+
private function js_releaseNamedASObject(objId:int):Boolean
|
909
|
+
{
|
910
|
+
var retVal:Boolean = false;
|
911
|
+
if (localInstanceMap[objId] != null)
|
912
|
+
{
|
913
|
+
delete refMap[objId];
|
914
|
+
delete localInstanceMap[objId];
|
915
|
+
retVal = true;
|
916
|
+
}
|
917
|
+
return retVal;
|
918
|
+
}
|
919
|
+
|
920
|
+
/**
|
921
|
+
* callback for js to create a new class instance.
|
922
|
+
*/
|
923
|
+
|
924
|
+
private function js_create(className:String):*
|
925
|
+
{
|
926
|
+
try
|
927
|
+
{
|
928
|
+
var c:Class = Class(ApplicationDomain.currentDomain.getDefinition(className));
|
929
|
+
var instance:Object = new c();
|
930
|
+
}
|
931
|
+
catch(e:Error)
|
932
|
+
{
|
933
|
+
return serialize("__FLASHERROR__" + "||" + e.message);
|
934
|
+
}
|
935
|
+
|
936
|
+
// make sure the reference is known
|
937
|
+
var objRef:Number = getRef(instance, true);
|
938
|
+
incRef(objRef);
|
939
|
+
return serialize(instance);
|
940
|
+
}
|
941
|
+
|
942
|
+
}
|
943
|
+
}
|