Index: third_party/pkg/js/lib/dart_interop.js |
diff --git a/third_party/pkg/js/lib/dart_interop.js b/third_party/pkg/js/lib/dart_interop.js |
deleted file mode 100644 |
index bf8f25d46023839748a9e6cf7577625d4f23a539..0000000000000000000000000000000000000000 |
--- a/third_party/pkg/js/lib/dart_interop.js |
+++ /dev/null |
@@ -1,576 +0,0 @@ |
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
-// for details. All rights reserved. Use of this source code is governed by a |
-// BSD-style license that can be found in the LICENSE file. |
- |
-// THIS FILE IS AUTO GENERATED. PLEASE DO NOT EDIT. |
- |
-// TODO(vsm): Move this file once we determine where assets should go. See |
-// http://dartbug.com/6101. |
- |
-(function() { |
- // Proxy support for js.dart. |
- |
- var globalContext = window; |
- |
- // Support for binding the receiver (this) in proxied functions. |
- function bindIfFunction(f, _this) { |
- if (typeof(f) != "function") { |
- return f; |
- } else { |
- return new BoundFunction(_this, f); |
- } |
- } |
- |
- function unbind(obj) { |
- if (obj instanceof BoundFunction) { |
- return obj.object; |
- } else { |
- return obj; |
- } |
- } |
- |
- function getBoundThis(obj) { |
- if (obj instanceof BoundFunction) { |
- return obj._this; |
- } else { |
- return globalContext; |
- } |
- } |
- |
- function BoundFunction(_this, object) { |
- this._this = _this; |
- this.object = object; |
- } |
- |
- // Table for local objects and functions that are proxied. |
- function ProxiedObjectTable() { |
- // Name for debugging. |
- this.name = 'js-ref'; |
- |
- // Table from IDs to JS objects. |
- this.map = {}; |
- |
- // Generator for new IDs. |
- this._nextId = 0; |
- |
- // Counter for deleted proxies. |
- this._deletedCount = 0; |
- |
- // Flag for one-time initialization. |
- this._initialized = false; |
- |
- // Ports for managing communication to proxies. |
- this.port = new ReceivePortSync(); |
- this.sendPort = this.port.toSendPort(); |
- |
- // Set of IDs that are global. |
- // These will not be freed on an exitScope(). |
- this.globalIds = {}; |
- |
- // Stack of scoped handles. |
- this.handleStack = []; |
- |
- // Stack of active scopes where each value is represented by the size of |
- // the handleStack at the beginning of the scope. When an active scope |
- // is popped, the handleStack is restored to where it was when the |
- // scope was entered. |
- this.scopeIndices = []; |
- } |
- |
- // Number of valid IDs. This is the number of objects (global and local) |
- // kept alive by this table. |
- ProxiedObjectTable.prototype.count = function () { |
- return Object.keys(this.map).length; |
- } |
- |
- // Number of total IDs ever allocated. |
- ProxiedObjectTable.prototype.total = function () { |
- return this.count() + this._deletedCount; |
- } |
- |
- // Adds an object to the table and return an ID for serialization. |
- ProxiedObjectTable.prototype.add = function (obj) { |
- if (this.scopeIndices.length == 0) { |
- throw "Cannot allocate a proxy outside of a scope."; |
- } |
- // TODO(vsm): Cache refs for each obj? |
- var ref = this.name + '-' + this._nextId++; |
- this.handleStack.push(ref); |
- this.map[ref] = obj; |
- return ref; |
- } |
- |
- ProxiedObjectTable.prototype._initializeOnce = function () { |
- if (!this._initialized) { |
- this._initialize(); |
- this._initialized = true; |
- } |
- } |
- |
- // Enters a new scope for this table. |
- ProxiedObjectTable.prototype.enterScope = function() { |
- this._initializeOnce(); |
- this.scopeIndices.push(this.handleStack.length); |
- } |
- |
- // Invalidates all non-global IDs in the current scope and |
- // exit the current scope. |
- ProxiedObjectTable.prototype.exitScope = function() { |
- var start = this.scopeIndices.pop(); |
- for (var i = start; i < this.handleStack.length; ++i) { |
- var key = this.handleStack[i]; |
- if (!this.globalIds.hasOwnProperty(key)) { |
- delete this.map[this.handleStack[i]]; |
- this._deletedCount++; |
- } |
- } |
- this.handleStack = this.handleStack.splice(0, start); |
- } |
- |
- // Makes this ID globally scope. It must be explicitly invalidated. |
- ProxiedObjectTable.prototype.globalize = function(id) { |
- this.globalIds[id] = true; |
- } |
- |
- // Invalidates this ID, potentially freeing its corresponding object. |
- ProxiedObjectTable.prototype.invalidate = function(id) { |
- var old = this.get(id); |
- delete this.globalIds[id]; |
- delete this.map[id]; |
- this._deletedCount++; |
- } |
- |
- // Gets the object or function corresponding to this ID. |
- ProxiedObjectTable.prototype.get = function (id) { |
- if (!this.map.hasOwnProperty(id)) { |
- throw 'Proxy ' + id + ' has been invalidated.' |
- } |
- return this.map[id]; |
- } |
- |
- ProxiedObjectTable.prototype._initialize = function () { |
- // Configure this table's port to forward methods, getters, and setters |
- // from the remote proxy to the local object. |
- var table = this; |
- |
- this.port.receive(function (message) { |
- // TODO(vsm): Support a mechanism to register a handler here. |
- try { |
- var object = table.get(message[0]); |
- var receiver = unbind(object); |
- var member = message[1]; |
- var kind = message[2]; |
- var args = message[3].map(deserialize); |
- if (kind == 'get') { |
- // Getter. |
- var field = member; |
- if (field in receiver && args.length == 0) { |
- var result = bindIfFunction(receiver[field], receiver); |
- return [ 'return', serialize(result) ]; |
- } |
- } else if (kind == 'set') { |
- // Setter. |
- var field = member; |
- if (args.length == 1) { |
- return [ 'return', serialize(receiver[field] = args[0]) ]; |
- } |
- } else if (kind == 'apply') { |
- // Direct function invocation. |
- var _this = getBoundThis(object); |
- return [ 'return', serialize(receiver.apply(_this, args)) ]; |
- } else if (member == '[]' && args.length == 1) { |
- // Index getter. |
- var result = bindIfFunction(receiver[args[0]], receiver); |
- return [ 'return', serialize(result) ]; |
- } else if (member == '[]=' && args.length == 2) { |
- // Index setter. |
- return [ 'return', serialize(receiver[args[0]] = args[1]) ]; |
- } else { |
- // Member function invocation. |
- var f = receiver[member]; |
- if (f) { |
- var result = f.apply(receiver, args); |
- return [ 'return', serialize(result) ]; |
- } |
- } |
- return [ 'none' ]; |
- } catch (e) { |
- return [ 'throws', e.toString() ]; |
- } |
- }); |
- } |
- |
- // Singleton for local proxied objects. |
- var proxiedObjectTable = new ProxiedObjectTable(); |
- |
- // DOM element serialization code. |
- var _localNextElementId = 0; |
- var _DART_ID = 'data-dart_id'; |
- var _DART_TEMPORARY_ATTACHED = 'data-dart_temporary_attached'; |
- |
- function serializeElement(e) { |
- // TODO(vsm): Use an isolate-specific id. |
- var id; |
- if (e.hasAttribute(_DART_ID)) { |
- id = e.getAttribute(_DART_ID); |
- } else { |
- id = (_localNextElementId++).toString(); |
- e.setAttribute(_DART_ID, id); |
- } |
- if (e !== document.documentElement) { |
- // Element must be attached to DOM to be retrieve in js part. |
- // Attach top unattached parent to avoid detaching parent of "e" when |
- // appending "e" directly to document. We keep count of elements |
- // temporarily attached to prevent detaching top unattached parent to |
- // early. This count is equals to the length of _DART_TEMPORARY_ATTACHED |
- // attribute. There could be other elements to serialize having the same |
- // top unattached parent. |
- var top = e; |
- while (true) { |
- if (top.hasAttribute(_DART_TEMPORARY_ATTACHED)) { |
- var oldValue = top.getAttribute(_DART_TEMPORARY_ATTACHED); |
- var newValue = oldValue + "a"; |
- top.setAttribute(_DART_TEMPORARY_ATTACHED, newValue); |
- break; |
- } |
- if (top.parentNode == null) { |
- top.setAttribute(_DART_TEMPORARY_ATTACHED, "a"); |
- document.documentElement.appendChild(top); |
- break; |
- } |
- if (top.parentNode === document.documentElement) { |
- // e was already attached to dom |
- break; |
- } |
- top = top.parentNode; |
- } |
- } |
- return id; |
- } |
- |
- function deserializeElement(id) { |
- // TODO(vsm): Clear the attribute. |
- var list = document.querySelectorAll('[' + _DART_ID + '="' + id + '"]'); |
- |
- if (list.length > 1) throw 'Non unique ID: ' + id; |
- if (list.length == 0) { |
- throw 'Element must be attached to the document: ' + id; |
- } |
- var e = list[0]; |
- if (e !== document.documentElement) { |
- // detach temporary attached element |
- var top = e; |
- while (true) { |
- if (top.hasAttribute(_DART_TEMPORARY_ATTACHED)) { |
- var oldValue = top.getAttribute(_DART_TEMPORARY_ATTACHED); |
- var newValue = oldValue.substring(1); |
- top.setAttribute(_DART_TEMPORARY_ATTACHED, newValue); |
- // detach top only if no more elements have to be unserialized |
- if (top.getAttribute(_DART_TEMPORARY_ATTACHED).length === 0) { |
- top.removeAttribute(_DART_TEMPORARY_ATTACHED); |
- document.documentElement.removeChild(top); |
- } |
- break; |
- } |
- if (top.parentNode === document.documentElement) { |
- // e was already attached to dom |
- break; |
- } |
- top = top.parentNode; |
- } |
- } |
- return e; |
- } |
- |
- |
- // Type for remote proxies to Dart objects. |
- function DartProxy(id, sendPort) { |
- this.id = id; |
- this.port = sendPort; |
- } |
- |
- // Serializes JS types to SendPortSync format: |
- // - primitives -> primitives |
- // - sendport -> sendport |
- // - DOM element -> [ 'domref', element-id ] |
- // - Function -> [ 'funcref', function-id, sendport ] |
- // - Object -> [ 'objref', object-id, sendport ] |
- function serialize(message) { |
- if (message == null) { |
- return null; // Convert undefined to null. |
- } else if (typeof(message) == 'string' || |
- typeof(message) == 'number' || |
- typeof(message) == 'boolean') { |
- // Primitives are passed directly through. |
- return message; |
- } else if (message instanceof SendPortSync) { |
- // Non-proxied objects are serialized. |
- return message; |
- } else if (message instanceof Element && |
- (message.ownerDocument == null || message.ownerDocument == document)) { |
- return [ 'domref', serializeElement(message) ]; |
- } else if (message instanceof BoundFunction && |
- typeof(message.object) == 'function') { |
- // Local function proxy. |
- return [ 'funcref', |
- proxiedObjectTable.add(message), |
- proxiedObjectTable.sendPort ]; |
- } else if (typeof(message) == 'function') { |
- if ('_dart_id' in message) { |
- // Remote function proxy. |
- var remoteId = message._dart_id; |
- var remoteSendPort = message._dart_port; |
- return [ 'funcref', remoteId, remoteSendPort ]; |
- } else { |
- // Local function proxy. |
- return [ 'funcref', |
- proxiedObjectTable.add(message), |
- proxiedObjectTable.sendPort ]; |
- } |
- } else if (message instanceof DartProxy) { |
- // Remote object proxy. |
- return [ 'objref', message.id, message.port ]; |
- } else { |
- // Local object proxy. |
- return [ 'objref', |
- proxiedObjectTable.add(message), |
- proxiedObjectTable.sendPort ]; |
- } |
- } |
- |
- function deserialize(message) { |
- if (message == null) { |
- return null; // Convert undefined to null. |
- } else if (typeof(message) == 'string' || |
- typeof(message) == 'number' || |
- typeof(message) == 'boolean') { |
- // Primitives are passed directly through. |
- return message; |
- } else if (message instanceof SendPortSync) { |
- // Serialized type. |
- return message; |
- } |
- var tag = message[0]; |
- switch (tag) { |
- case 'funcref': return deserializeFunction(message); |
- case 'objref': return deserializeObject(message); |
- case 'domref': return deserializeElement(message[1]); |
- } |
- throw 'Unsupported serialized data: ' + message; |
- } |
- |
- // Create a local function that forwards to the remote function. |
- function deserializeFunction(message) { |
- var id = message[1]; |
- var port = message[2]; |
- // TODO(vsm): Add a more robust check for a local SendPortSync. |
- if ("receivePort" in port) { |
- // Local function. |
- return unbind(proxiedObjectTable.get(id)); |
- } else { |
- // Remote function. Forward to its port. |
- var f = function () { |
- var depth = enterScope(); |
- try { |
- var args = Array.prototype.slice.apply(arguments); |
- args.splice(0, 0, this); |
- args = args.map(serialize); |
- var result = port.callSync([id, '#call', args]); |
- if (result[0] == 'throws') throw deserialize(result[1]); |
- return deserialize(result[1]); |
- } finally { |
- exitScope(depth); |
- } |
- }; |
- // Cache the remote id and port. |
- f._dart_id = id; |
- f._dart_port = port; |
- return f; |
- } |
- } |
- |
- // Creates a DartProxy to forwards to the remote object. |
- function deserializeObject(message) { |
- var id = message[1]; |
- var port = message[2]; |
- // TODO(vsm): Add a more robust check for a local SendPortSync. |
- if ("receivePort" in port) { |
- // Local object. |
- return proxiedObjectTable.get(id); |
- } else { |
- // Remote object. |
- return new DartProxy(id, port); |
- } |
- } |
- |
- // Remote handler to construct a new JavaScript object given its |
- // serialized constructor and arguments. |
- function construct(args) { |
- args = args.map(deserialize); |
- var constructor = unbind(args[0]); |
- args = Array.prototype.slice.call(args, 1); |
- |
- // Until 10 args, the 'new' operator is used. With more arguments we use a |
- // generic way that may not work, particulary when the constructor does not |
- // have an "apply" method. |
- var ret = null; |
- if (args.length === 0) { |
- ret = new constructor(); |
- } else if (args.length === 1) { |
- ret = new constructor(args[0]); |
- } else if (args.length === 2) { |
- ret = new constructor(args[0], args[1]); |
- } else if (args.length === 3) { |
- ret = new constructor(args[0], args[1], args[2]); |
- } else if (args.length === 4) { |
- ret = new constructor(args[0], args[1], args[2], args[3]); |
- } else if (args.length === 5) { |
- ret = new constructor(args[0], args[1], args[2], args[3], args[4]); |
- } else if (args.length === 6) { |
- ret = new constructor(args[0], args[1], args[2], args[3], args[4], |
- args[5]); |
- } else if (args.length === 7) { |
- ret = new constructor(args[0], args[1], args[2], args[3], args[4], |
- args[5], args[6]); |
- } else if (args.length === 8) { |
- ret = new constructor(args[0], args[1], args[2], args[3], args[4], |
- args[5], args[6], args[7]); |
- } else if (args.length === 9) { |
- ret = new constructor(args[0], args[1], args[2], args[3], args[4], |
- args[5], args[6], args[7], args[8]); |
- } else if (args.length === 10) { |
- ret = new constructor(args[0], args[1], args[2], args[3], args[4], |
- args[5], args[6], args[7], args[8], args[9]); |
- } else { |
- // Dummy Type with correct constructor. |
- var Type = function(){}; |
- Type.prototype = constructor.prototype; |
- |
- // Create a new instance |
- var instance = new Type(); |
- |
- // Call the original constructor. |
- ret = constructor.apply(instance, args); |
- ret = Object(ret) === ret ? ret : instance; |
- } |
- return serialize(ret); |
- } |
- |
- // Remote handler to return the top-level JavaScript context. |
- function context(data) { |
- return serialize(globalContext); |
- } |
- |
- // Remote handler to track number of live / allocated proxies. |
- function proxyCount() { |
- var live = proxiedObjectTable.count(); |
- var total = proxiedObjectTable.total(); |
- return [live, total]; |
- } |
- |
- // Return true if two JavaScript proxies are equal (==). |
- function proxyEquals(args) { |
- return deserialize(args[0]) == deserialize(args[1]); |
- } |
- |
- // Return true if a JavaScript proxy is instance of a given type (instanceof). |
- function proxyInstanceof(args) { |
- var obj = unbind(deserialize(args[0])); |
- var type = unbind(deserialize(args[1])); |
- return obj instanceof type; |
- } |
- |
- // Return true if a JavaScript proxy has a given property. |
- function proxyHasProperty(args) { |
- var obj = unbind(deserialize(args[0])); |
- var member = unbind(deserialize(args[1])); |
- return member in obj; |
- } |
- |
- // Delete a given property of object. |
- function proxyDeleteProperty(args) { |
- var obj = unbind(deserialize(args[0])); |
- var member = unbind(deserialize(args[1])); |
- delete obj[member]; |
- } |
- |
- function proxyConvert(args) { |
- return serialize(deserializeDataTree(args)); |
- } |
- |
- function deserializeDataTree(data) { |
- var type = data[0]; |
- var value = data[1]; |
- if (type === 'map') { |
- var obj = {}; |
- for (var i = 0; i < value.length; i++) { |
- obj[value[i][0]] = deserializeDataTree(value[i][1]); |
- } |
- return obj; |
- } else if (type === 'list') { |
- var list = []; |
- for (var i = 0; i < value.length; i++) { |
- list.push(deserializeDataTree(value[i])); |
- } |
- return list; |
- } else /* 'simple' */ { |
- return deserialize(value); |
- } |
- } |
- |
- function makeGlobalPort(name, f) { |
- var port = new ReceivePortSync(); |
- port.receive(f); |
- window.registerPort(name, port.toSendPort()); |
- } |
- |
- // Enters a new scope in the JavaScript context. |
- function enterJavaScriptScope() { |
- proxiedObjectTable.enterScope(); |
- } |
- |
- // Enters a new scope in both the JavaScript and Dart context. |
- var _dartEnterScopePort = null; |
- function enterScope() { |
- enterJavaScriptScope(); |
- if (!_dartEnterScopePort) { |
- _dartEnterScopePort = window.lookupPort('js-dart-interop-enter-scope'); |
- } |
- return _dartEnterScopePort.callSync([]); |
- } |
- |
- // Exits the current scope (and invalidate local IDs) in the JavaScript |
- // context. |
- function exitJavaScriptScope() { |
- proxiedObjectTable.exitScope(); |
- } |
- |
- // Exits the current scope in both the JavaScript and Dart context. |
- var _dartExitScopePort = null; |
- function exitScope(depth) { |
- exitJavaScriptScope(); |
- if (!_dartExitScopePort) { |
- _dartExitScopePort = window.lookupPort('js-dart-interop-exit-scope'); |
- } |
- return _dartExitScopePort.callSync([ depth ]); |
- } |
- |
- makeGlobalPort('dart-js-interop-context', context); |
- makeGlobalPort('dart-js-interop-create', construct); |
- makeGlobalPort('dart-js-interop-proxy-count', proxyCount); |
- makeGlobalPort('dart-js-interop-equals', proxyEquals); |
- makeGlobalPort('dart-js-interop-instanceof', proxyInstanceof); |
- makeGlobalPort('dart-js-interop-has-property', proxyHasProperty); |
- makeGlobalPort('dart-js-interop-delete-property', proxyDeleteProperty); |
- makeGlobalPort('dart-js-interop-convert', proxyConvert); |
- makeGlobalPort('dart-js-interop-enter-scope', enterJavaScriptScope); |
- makeGlobalPort('dart-js-interop-exit-scope', exitJavaScriptScope); |
- makeGlobalPort('dart-js-interop-globalize', function(data) { |
- if (data[0] == "objref" || data[0] == "funcref") return proxiedObjectTable.globalize(data[1]); |
- throw 'Illegal type: ' + data[0]; |
- }); |
- makeGlobalPort('dart-js-interop-invalidate', function(data) { |
- if (data[0] == "objref" || data[0] == "funcref") return proxiedObjectTable.invalidate(data[1]); |
- throw 'Illegal type: ' + data[0]; |
- }); |
-})(); |