OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 // DO NOT EDIT | 5 // DO NOT EDIT |
6 // Auto-generated dart:html library. | 6 // Auto-generated dart:html library. |
7 | 7 |
8 #library('html'); | 8 #library('html'); |
9 | 9 |
10 #import('dart:isolate'); | 10 #import('dart:isolate'); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 Element query(String selector) => _document.query(selector); | 44 Element query(String selector) => _document.query(selector); |
45 ElementList queryAll(String selector) => _document.queryAll(selector); | 45 ElementList queryAll(String selector) => _document.queryAll(selector); |
46 | 46 |
47 // Workaround for tags like <cite> that lack their own Element subclass -- | 47 // Workaround for tags like <cite> that lack their own Element subclass -- |
48 // Dart issue 1990. | 48 // Dart issue 1990. |
49 class _HTMLElementImpl extends _ElementImpl native "*HTMLElement" { | 49 class _HTMLElementImpl extends _ElementImpl native "*HTMLElement" { |
50 } | 50 } |
51 | 51 |
52 // TODO(vsm): Move this to a separate Isolates.dart file. | 52 // TODO(vsm): Move this to a separate Isolates.dart file. |
53 _serialize(var message) { | 53 _serialize(var message) { |
54 // TODO(kasperl): Specialize the serializer. | 54 return new _JsSerializer().traverse(message); |
55 return new _Serializer().traverse(message); | 55 } |
| 56 |
| 57 class _JsSerializer extends _Serializer { |
| 58 |
| 59 visitSendPortSync(SendPortSync x) { |
| 60 if (x is _JsSendPortSync) return visitJsSendPortSync(x); |
| 61 if (x is _LocalSendPortSync) return visitLocalSendPortSync(x); |
| 62 if (x is _RemoteSendPortSync) return visitRemoteSendPortSync(x); |
| 63 throw "Illegal underlying port $x"; |
| 64 } |
| 65 |
| 66 visitJsSendPortSync(_JsSendPortSync x) { |
| 67 return [ 'sendport', 'nativejs', x._id ]; |
| 68 } |
| 69 |
| 70 visitLocalSendPortSync(_LocalSendPortSync x) { |
| 71 return [ 'sendport', 'dart2js', |
| 72 ReceivePortSync._isolateId, x._receivePort._portId ]; |
| 73 } |
| 74 |
| 75 visitRemoteSendPortSync(_RemoteSendPortSync x) { |
| 76 return [ 'sendport', 'dart2js', |
| 77 x._receivePort._isolateId, x._receivePort._portId ]; |
| 78 } |
56 } | 79 } |
57 | 80 |
58 _deserialize(var message) { | 81 _deserialize(var message) { |
59 return new _JsDeserializer().deserialize(message); | 82 return new _JsDeserializer().deserialize(message); |
60 } | 83 } |
61 | 84 |
62 class _JsDeserializer extends _Deserializer { | 85 class _JsDeserializer extends _Deserializer { |
63 | 86 |
64 deserializeSendPort(List x) { | 87 deserializeSendPort(List x) { |
65 num id = x[1]; | 88 String tag = x[1]; |
66 return new _JsSendPortSync(id); | 89 switch (tag) { |
| 90 case 'nativejs': |
| 91 num id = x[2]; |
| 92 return new _JsSendPortSync(id); |
| 93 case 'dart2js': |
| 94 num isolateId = x[2]; |
| 95 num portId = x[3]; |
| 96 return ReceivePortSync._lookup(isolateId, portId); |
| 97 default: |
| 98 throw 'Illegal SendPortSync type: $tag'; |
| 99 } |
67 } | 100 } |
68 | 101 |
69 } | 102 } |
70 | 103 |
| 104 // The receiver is JS. |
71 class _JsSendPortSync implements SendPortSync { | 105 class _JsSendPortSync implements SendPortSync { |
72 | 106 |
73 num _id; | 107 num _id; |
74 _JsSendPortSync(this._id); | 108 _JsSendPortSync(this._id); |
75 | 109 |
76 callSync(var message) { | 110 callSync(var message) { |
77 var serialized = _serialize(message); | 111 var serialized = _serialize(message); |
78 var result = | 112 var result = |
79 JS('var', @'ReceivePortSync.dispatchCall(#, #)', _id, serialized); | 113 JS('var', @'ReceivePortSync.dispatchCall(#, #)', _id, serialized); |
80 return _deserialize(result); | 114 return _deserialize(result); |
81 } | 115 } |
82 | 116 |
83 } | 117 } |
| 118 |
| 119 // TODO(vsm): Handle Dartium isolates. |
| 120 // The receiver is a different Dart isolate, compiled to JS. |
| 121 class _RemoteSendPortSync implements SendPortSync { |
| 122 |
| 123 int _isolateId; |
| 124 int _portId; |
| 125 _RemoteSendPortSync(this._isolateId, this._portId); |
| 126 |
| 127 callSync(var message) { |
| 128 var serialized = _serialize(message); |
| 129 var result = _call(_isolateId, _portId, serialized); |
| 130 return _deserialize(result); |
| 131 } |
| 132 |
| 133 static _call(int isolateId, int portId, var message) { |
| 134 var target = 'dart-port-$isolateId-$portId'; |
| 135 // TODO(vsm): Make this re-entrant. |
| 136 // TODO(vsm): Set this up set once, on the first call. |
| 137 var source = '$target-result'; |
| 138 var result = null; |
| 139 var listener = (TextEvent e) { |
| 140 result = JSON.parse(e.data); |
| 141 }; |
| 142 window.on[source].add(listener); |
| 143 _dispatchEvent(target, [source, message]); |
| 144 window.on[source].remove(listener); |
| 145 return result; |
| 146 } |
| 147 } |
| 148 |
| 149 // The receiver is in the same Dart isolate, compiled to JS. |
| 150 class _LocalSendPortSync implements SendPortSync { |
| 151 |
| 152 ReceivePortSync _receivePort; |
| 153 |
| 154 _LocalSendPortSync._internal(this._receivePort); |
| 155 |
| 156 callSync(var message) { |
| 157 // TODO(vsm): Do a more efficient deep copy. |
| 158 var copy = _deserialize(_serialize(message)); |
| 159 var result = _receivePort._callback(copy); |
| 160 return _deserialize(_serialize(result)); |
| 161 } |
| 162 } |
| 163 |
| 164 // TODO(vsm): Move this to dart:isolate. This will take some |
| 165 // refactoring as there are dependences here on the DOM. Users |
| 166 // interact with this class (or interface if we change it) directly - |
| 167 // new ReceivePortSync. I think most of the DOM logic could be |
| 168 // delayed until the corresponding SendPort is registered on the |
| 169 // window. |
| 170 |
| 171 // A Dart2JS ReceivePortSync (tagged 'dart2js' when serialized) is |
| 172 // identifiable / resolvable by the combination of its isolateid and |
| 173 // portid. When a corresponding SendPort is used within the same |
| 174 // isolate, the _portMap below can be used to obtain the |
| 175 // ReceivePortSync directly. Across isolates (or from JS), an |
| 176 // EventListener can be used to communicate with the port indirectly. |
| 177 class ReceivePortSync { |
| 178 |
| 179 static Map<int, ReceivePortSync> _portMap; |
| 180 static int _portIdCount; |
| 181 static int _cachedIsolateId; |
| 182 |
| 183 num _portId; |
| 184 Function _callback; |
| 185 EventListener _listener; |
| 186 |
| 187 ReceivePortSync() { |
| 188 if (_portIdCount == null) { |
| 189 _portIdCount = 0; |
| 190 _portMap = new Map<int, ReceivePortSync>(); |
| 191 } |
| 192 _portId = _portIdCount++; |
| 193 _portMap[_portId] = this; |
| 194 } |
| 195 |
| 196 static int get _isolateId() { |
| 197 // TODO(vsm): Make this coherent with existing isolate code. |
| 198 if (_cachedIsolateId == null) { |
| 199 _cachedIsolateId = _getNewIsolateId(); |
| 200 } |
| 201 return _cachedIsolateId; |
| 202 } |
| 203 |
| 204 static int _getNewIsolateId() native @''' |
| 205 if (!window.$dart$isolate$counter) { |
| 206 window.$dart$isolate$counter = 1; |
| 207 } |
| 208 return window.$dart$isolate$counter++; |
| 209 '''; |
| 210 |
| 211 static String _getListenerName(isolateId, portId) => |
| 212 'dart-port-$isolateId-$portId'; |
| 213 String get _listenerName() => _getListenerName(_isolateId, _portId); |
| 214 |
| 215 void receive(callback(var message)) { |
| 216 // Clear old listener. |
| 217 if (_callback != null) { |
| 218 window.on[_listenerName].remove(_listener); |
| 219 } |
| 220 |
| 221 _callback = callback; |
| 222 |
| 223 // Install new listener. |
| 224 var sendport = toSendPort(); |
| 225 _listener = (TextEvent e) { |
| 226 var data = JSON.parse(e.data); |
| 227 var replyTo = data[0]; |
| 228 var message = _deserialize(data[1]); |
| 229 var result = sendport.callSync(message); |
| 230 _dispatchEvent(replyTo, _serialize(result)); |
| 231 }; |
| 232 window.on[_listenerName].add(_listener); |
| 233 } |
| 234 |
| 235 void close() { |
| 236 _portMap.remove(_portId); |
| 237 window.on[_listenerName].remove(_listener); |
| 238 } |
| 239 |
| 240 SendPortSync toSendPort() { |
| 241 return new _LocalSendPortSync._internal(this); |
| 242 } |
| 243 |
| 244 static SendPortSync _lookup(int isolateId, int portId) { |
| 245 if (isolateId == _isolateId) { |
| 246 return _portMap[portId].toSendPort(); |
| 247 } else { |
| 248 return new _RemoteSendPortSync(isolateId, portId); |
| 249 } |
| 250 } |
| 251 } |
| 252 |
| 253 void _dispatchEvent(String receiver, var message) { |
| 254 var event = document.$dom_createEvent('TextEvent'); |
| 255 event.initTextEvent(receiver, false, false, window, JSON.stringify(message)); |
| 256 window.$dom_dispatchEvent(event); |
| 257 } |
OLD | NEW |