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 = _call(_id, serialized); | 112 var result = _call(_id, serialized); |
79 return _deserialize(result); | 113 return _deserialize(result); |
80 } | 114 } |
81 | 115 |
82 static _call(num id, var message) native @""" | 116 static _call(num id, var message) native @""" |
83 return ReceivePortSync.dispatchCall(id, message); | 117 return ReceivePortSync.dispatchCall(id, message); |
84 """; | 118 """; |
85 | 119 |
86 } | 120 } |
| 121 |
| 122 // TODO(vsm): Handle Dartium isolates. |
| 123 // The receiver is a different Dart isolate, compiled to JS. |
| 124 class _RemoteSendPortSync implements SendPortSync { |
| 125 |
| 126 int _isolateId; |
| 127 int _portId; |
| 128 _RemoteSendPortSync(this._isolateId, this._portId); |
| 129 |
| 130 callSync(var message) { |
| 131 var serialized = _serialize(message); |
| 132 var result = _call(_isolateId, _portId, serialized); |
| 133 return _deserialize(result); |
| 134 } |
| 135 |
| 136 static _call(int isolateId, int portId, var message) { |
| 137 var target = 'dart-port-$isolateId-$portId'; |
| 138 // TODO(vsm): Make this re-entrant. |
| 139 // TODO(vsm): Set this up set once, on the first call. |
| 140 var source = '$target-result'; |
| 141 var result = null; |
| 142 var listener = (TextEvent e) { |
| 143 result = JSON.parse(e.data); |
| 144 }; |
| 145 window.on[source].add(listener); |
| 146 _dispatchEvent(target, [source, message]); |
| 147 window.on[source].remove(listener); |
| 148 return result; |
| 149 } |
| 150 } |
| 151 |
| 152 // The receiver is in the same Dart isolate, compiled to JS. |
| 153 class _LocalSendPortSync implements SendPortSync { |
| 154 |
| 155 ReceivePortSync _receivePort; |
| 156 |
| 157 _LocalSendPortSync._internal(this._receivePort); |
| 158 |
| 159 callSync(var message) { |
| 160 // TODO(vsm): Do a more efficient deep copy. |
| 161 var copy = _deserialize(_serialize(message)); |
| 162 var result = _receivePort._callback(copy); |
| 163 return _deserialize(_serialize(result)); |
| 164 } |
| 165 } |
| 166 |
| 167 // TODO(vsm): Move this to dart:isolate. This will take some |
| 168 // refactoring as there are dependences here on the DOM. Users |
| 169 // interact with this class (or interface if we change it) directly - |
| 170 // new ReceivePortSync. I think most of the DOM logic could be |
| 171 // delayed until the corresponding SendPort is registered on the |
| 172 // window. |
| 173 |
| 174 // A Dart2JS ReceivePortSync (tagged 'dart2js' when serialized) is |
| 175 // identifiable / resolvable by the combination of its isolateid and |
| 176 // portid. When a corresponding SendPort is used within the same |
| 177 // isolate, the _portMap below can be used to obtain the |
| 178 // ReceivePortSync directly. Across isolates (or from JS), an |
| 179 // EventListener can be used to communicate with the port indirectly. |
| 180 class ReceivePortSync { |
| 181 |
| 182 static Map<int, ReceivePortSync> _portMap; |
| 183 static int _portIdCount; |
| 184 static int _cachedIsolateId; |
| 185 |
| 186 num _portId; |
| 187 Function _callback; |
| 188 EventListener _listener; |
| 189 |
| 190 ReceivePortSync() { |
| 191 if (_portIdCount == null) { |
| 192 _portIdCount = 0; |
| 193 _portMap = new Map<int, ReceivePortSync>(); |
| 194 } |
| 195 _portId = _portIdCount++; |
| 196 _portMap[_portId] = this; |
| 197 } |
| 198 |
| 199 static int get _isolateId() { |
| 200 // TODO(vsm): Make this coherent with existing isolate code. |
| 201 if (_cachedIsolateId == null) { |
| 202 _cachedIsolateId = _getNewIsolateId(); |
| 203 } |
| 204 return _cachedIsolateId; |
| 205 } |
| 206 |
| 207 static int _getNewIsolateId() native @''' |
| 208 if (!window.$dart$isolate$counter) { |
| 209 window.$dart$isolate$counter = 1; |
| 210 } |
| 211 return window.$dart$isolate$counter++; |
| 212 '''; |
| 213 |
| 214 static String _getListenerName(isolateId, portId) => |
| 215 'dart-port-$isolateId-$portId'; |
| 216 String get _listenerName() => _getListenerName(_isolateId, _portId); |
| 217 |
| 218 void receive(callback(var message)) { |
| 219 // Clear old listener. |
| 220 if (_callback != null) { |
| 221 window.on[_listenerName].remove(_listener); |
| 222 } |
| 223 |
| 224 _callback = callback; |
| 225 |
| 226 // Install new listener. |
| 227 var sendport = toSendPort(); |
| 228 _listener = (TextEvent e) { |
| 229 var data = JSON.parse(e.data); |
| 230 var replyTo = data[0]; |
| 231 var message = _deserialize(data[1]); |
| 232 var result = sendport.callSync(message); |
| 233 _dispatchEvent(replyTo, _serialize(result)); |
| 234 }; |
| 235 window.on[_listenerName].add(_listener); |
| 236 } |
| 237 |
| 238 void close() { |
| 239 _portMap.remove(_portId); |
| 240 window.on[_listenerName].remove(_listener); |
| 241 } |
| 242 |
| 243 SendPortSync toSendPort() { |
| 244 return new _LocalSendPortSync._internal(this); |
| 245 } |
| 246 |
| 247 static SendPortSync _lookup(int isolateId, int portId) { |
| 248 if (isolateId == _isolateId) { |
| 249 return _portMap[portId].toSendPort(); |
| 250 } else { |
| 251 return new _RemoteSendPortSync(isolateId, portId); |
| 252 } |
| 253 } |
| 254 } |
| 255 |
| 256 void _dispatchEvent(String receiver, var message) { |
| 257 var event = document.$dom_createEvent('TextEvent'); |
| 258 event.initTextEvent(receiver, false, false, window, JSON.stringify(message)); |
| 259 window.$dom_dispatchEvent(event); |
| 260 } |
OLD | NEW |