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 // Bootstrap support for Dart scripts on the page as this script. | 5 // Bootstrap support for Dart scripts on the page as this script. |
6 if (navigator.webkitStartDart) { | 6 if (navigator.webkitStartDart) { |
7 if (!navigator.webkitStartDart()) { | 7 if (!navigator.webkitStartDart()) { |
8 document.body.innerHTML = 'This build has expired. Please download a new Da
rtium at http://www.dartlang.org/dartium/index.html'; | 8 document.body.innerHTML = 'This build has expired. Please download a new Da
rtium at http://www.dartlang.org/dartium/index.html'; |
9 } | 9 } |
10 } else { | 10 } else { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 for (var i = 0; i < message.length; i++) { | 79 for (var i = 0; i < message.length; i++) { |
80 values[i] = doSerialize(message[i]); | 80 values[i] = doSerialize(message[i]); |
81 } | 81 } |
82 return [ 'list', id, values ]; | 82 return [ 'list', id, values ]; |
83 }); | 83 }); |
84 } else if (message instanceof LocalSendPortSync) { | 84 } else if (message instanceof LocalSendPortSync) { |
85 return [ 'sendport', 'nativejs', message.receivePort.id ]; | 85 return [ 'sendport', 'nativejs', message.receivePort.id ]; |
86 } else if (message instanceof DartSendPortSync) { | 86 } else if (message instanceof DartSendPortSync) { |
87 return [ 'sendport', 'dart', message.isolateId, message.portId ]; | 87 return [ 'sendport', 'dart', message.isolateId, message.portId ]; |
88 } else if (message instanceof Function) { | 88 } else if (message instanceof Function) { |
89 return [ 'funcref', functionRefTable.makeRef(message), | 89 // In case we are reserializing a previously serialized |
90 doSerialize(functionRefTable.sendPort) ]; | 90 // function, use a cached value. |
| 91 if (message._dart_serialized) return message._dart_serialized; |
| 92 message._dart_serialized = [ 'funcref', |
| 93 functionRefTable.makeRef(message), |
| 94 doSerialize(functionRefTable.sendPort) ]; |
| 95 return message._dart_serialized; |
91 } else if (message instanceof HTMLElement) { | 96 } else if (message instanceof HTMLElement) { |
92 var id = elementId(message); | 97 var id = elementId(message); |
93 // Verify that the element is connected to the document. | 98 // Verify that the element is connected to the document. |
94 // Otherwise, we will not be able to find it on the other side. | 99 // Otherwise, we will not be able to find it on the other side. |
95 getElement(id); | 100 getElement(id); |
96 return [ 'element', id ]; | 101 return [ 'element', id ]; |
97 } else if (message instanceof DartProxy) { | 102 } else if (message instanceof DartProxy) { |
98 return [ 'objref', message._id, doSerialize(message._port) ]; | 103 return [ 'objref', message._id, doSerialize(message._port) ]; |
99 } else if (message.__proto__ != {}.__proto__) { | 104 } else if (message.__proto__ != {}.__proto__) { |
100 // TODO(vsm): Is the above portable and what we want? | 105 // TODO(vsm): Is the above portable and what we want? |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 result[i] = deserializeHelper(values[i]); | 178 result[i] = deserializeHelper(values[i]); |
174 } | 179 } |
175 return result; | 180 return result; |
176 } | 181 } |
177 | 182 |
178 function deserializeFunction(message) { | 183 function deserializeFunction(message) { |
179 var ref = message[1]; | 184 var ref = message[1]; |
180 var sendPort = deserializeSendPort(message[2]); | 185 var sendPort = deserializeSendPort(message[2]); |
181 // Number of arguments is not used as of now | 186 // Number of arguments is not used as of now |
182 // we cannot find it out for Dart function in pure Dart. | 187 // we cannot find it out for Dart function in pure Dart. |
183 return _makeFunctionFromRef(ref, sendPort); | 188 var result = _makeFunctionFromRef(ref, sendPort); |
| 189 // Cache the serialized form in case we resend this. |
| 190 result._dart_serialized = message; |
| 191 return result; |
184 } | 192 } |
185 | 193 |
186 function deserializeProxy(message) { | 194 function deserializeProxy(message) { |
187 var id = message[1]; | 195 var id = message[1]; |
188 var port = deserializeSendPort(message[2]); | 196 var port = deserializeSendPort(message[2]); |
189 if (port instanceof LocalSendPortSync) { | 197 if (port instanceof LocalSendPortSync) { |
190 return jsRefTable.map[id]; | 198 return jsRefTable.map[id]; |
191 } else if (port instanceof DartSendPortSync) { | 199 } else if (port instanceof DartSendPortSync) { |
192 return new DartProxy(port, id); | 200 return new DartProxy(port, id); |
193 } | 201 } |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 | 325 |
318 RefTable.prototype.get = function (ref) { | 326 RefTable.prototype.get = function (ref) { |
319 return this.map[ref]; | 327 return this.map[ref]; |
320 } | 328 } |
321 | 329 |
322 function FunctionRefTable() {} | 330 function FunctionRefTable() {} |
323 | 331 |
324 FunctionRefTable.prototype = new RefTable('func-ref'); | 332 FunctionRefTable.prototype = new RefTable('func-ref'); |
325 | 333 |
326 FunctionRefTable.prototype.initialize = function () { | 334 FunctionRefTable.prototype.initialize = function () { |
327 map = this.map; | 335 var map = this.map; |
328 this.port.receive(function (message) { | 336 this.port.receive(function (message) { |
329 var id = message[0]; | 337 var id = message[0]; |
330 var args = message[1]; | 338 var args = message[1]; |
331 var f = map[id]; | 339 var f = map[id]; |
332 // TODO(vsm): Should we capture this automatically? | 340 // TODO(vsm): Should we capture this automatically? |
333 return f.apply(null, args); | 341 return f.apply(null, args); |
334 }); | 342 }); |
335 } | 343 } |
336 | 344 |
337 var functionRefTable = new FunctionRefTable(); | 345 var functionRefTable = new FunctionRefTable(); |
338 | 346 |
339 function JSRefTable() {} | 347 function JSRefTable() {} |
340 | 348 |
341 JSRefTable.prototype = new RefTable('js-ref'); | 349 JSRefTable.prototype = new RefTable('js-ref'); |
342 | 350 |
343 JSRefTable.prototype.initialize = function () { | 351 JSRefTable.prototype.initialize = function () { |
344 map = this.map; | 352 var map = this.map; |
345 this.port.receive(function (message) { | 353 this.port.receive(function (message) { |
346 // TODO(vsm): Support a mechanism to register a handler here. | 354 // TODO(vsm): Support a mechanism to register a handler here. |
347 var receiver = map[message[0]]; | 355 var receiver = map[message[0]]; |
348 var method = message[1]; | 356 var method = message[1]; |
349 var args = message[2]; | 357 var args = message[2]; |
350 if (method.indexOf("get:") == 0) { | 358 if (method.indexOf("get:") == 0) { |
351 // Getter. | 359 // Getter. |
352 var field = method.substring(4); | 360 var field = method.substring(4); |
353 if (field in receiver && args.length == 0) { | 361 if (field in receiver && args.length == 0) { |
354 return [ 'return', receiver[field] ]; | 362 return [ 'return', receiver[field] ]; |
(...skipping 22 matching lines...) Expand all Loading... |
377 var jsRefTable = new JSRefTable(); | 385 var jsRefTable = new JSRefTable(); |
378 | 386 |
379 function DartProxy(port, id) { | 387 function DartProxy(port, id) { |
380 this._port = port; | 388 this._port = port; |
381 this._id = id; | 389 this._id = id; |
382 } | 390 } |
383 | 391 |
384 // Leaking implementation. | 392 // Leaking implementation. |
385 // TODO(vsm): provide proper, backend-specific implementation. | 393 // TODO(vsm): provide proper, backend-specific implementation. |
386 function _makeFunctionFromRef(ref, sendPort) { | 394 function _makeFunctionFromRef(ref, sendPort) { |
| 395 // If the sendPort is local, just return the underlying function. |
| 396 // Otherwise, create a new function that forwards to the remote |
| 397 // port. |
| 398 if (sendPort instanceof LocalSendPortSync) { |
| 399 return functionRefTable.map[ref]; |
| 400 } |
387 return function() { | 401 return function() { |
388 return sendPort.callSync([ref, Array.prototype.slice.call(arguments)]); | 402 return sendPort.callSync([ref, Array.prototype.slice.call(arguments)]); |
389 } | 403 }; |
390 } | 404 } |
391 | 405 |
392 var localNextElementId = 0; | 406 var localNextElementId = 0; |
393 var _DART_ID = 'data-dart_id'; | 407 var _DART_ID = 'data-dart_id'; |
394 | 408 |
395 function elementId(e) { | 409 function elementId(e) { |
396 if (e.hasAttribute(_DART_ID)) return e.getAttribute(_DART_ID); | 410 if (e.hasAttribute(_DART_ID)) return e.getAttribute(_DART_ID); |
397 var id = (localNextElementId++).toString(); | 411 var id = (localNextElementId++).toString(); |
398 e.setAttribute(_DART_ID, id); | 412 e.setAttribute(_DART_ID, id); |
399 return id; | 413 return id; |
400 } | 414 } |
401 | 415 |
402 function getElement(id) { | 416 function getElement(id) { |
403 var list = document.querySelectorAll('[' + _DART_ID + '="' + id + '"]'); | 417 var list = document.querySelectorAll('[' + _DART_ID + '="' + id + '"]'); |
404 | 418 |
405 if (list.length > 1) throw 'Non unique ID: ' + id; | 419 if (list.length > 1) throw 'Non unique ID: ' + id; |
406 if (list.length == 0) { | 420 if (list.length == 0) { |
407 throw 'Element must be attached to the document: ' + id; | 421 throw 'Element must be attached to the document: ' + id; |
408 } | 422 } |
409 return list[0]; | 423 return list[0]; |
410 } | 424 } |
411 })(); | 425 })(); |
OLD | NEW |