1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/social/MessagePortBase.jsm Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,108 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +// Code that is shared between clients and workers. 1.9 +this.EXPORTED_SYMBOLS = ["AbstractPort"]; 1.10 + 1.11 +this.AbstractPort = function AbstractPort(portid) { 1.12 + this._portid = portid; 1.13 + this._handler = undefined; 1.14 + this._closed = false; 1.15 + // pending messages sent to this port before it has a message handler. 1.16 + this._pendingMessagesIncoming = []; 1.17 +}; 1.18 + 1.19 +AbstractPort.prototype = { 1.20 + _portType: null, // set by a subclass. 1.21 + // abstract methods to be overridden. 1.22 + _dopost: function fw_AbstractPort_dopost(data) { 1.23 + throw new Error("not implemented"); 1.24 + }, 1.25 + _onerror: function fw_AbstractPort_onerror(err) { 1.26 + throw new Error("not implemented"); 1.27 + }, 1.28 + 1.29 + // and concrete methods shared by client and workers. 1.30 + toString: function fw_AbstractPort_toString() { 1.31 + return "MessagePort(portType='" + this._portType + "', portId=" 1.32 + + this._portid + (this._closed ? ", closed=true" : "") + ")"; 1.33 + }, 1.34 + _JSONParse: function fw_AbstractPort_JSONParse(data) JSON.parse(data), 1.35 + 1.36 + _postControlMessage: function fw_AbstractPort_postControlMessage(topic, data) { 1.37 + let postData = { 1.38 + portTopic: topic, 1.39 + portId: this._portid, 1.40 + portFromType: this._portType, 1.41 + data: data 1.42 + }; 1.43 + this._dopost(postData); 1.44 + }, 1.45 + 1.46 + _onmessage: function fw_AbstractPort_onmessage(data) { 1.47 + // See comments in postMessage below - we work around a cloning 1.48 + // issue by using JSON for these messages. 1.49 + // Further, we allow the workers to override exactly how the JSON parsing 1.50 + // is done - we try and do such parsing in the client window so things 1.51 + // like prototype overrides on Array work as expected. 1.52 + if (!this._handler) { 1.53 + this._pendingMessagesIncoming.push(data); 1.54 + } else { 1.55 + data = this._JSONParse(data); 1.56 + try { 1.57 + this._handler({ 1.58 + data: data, 1.59 + __exposedProps__: { 1.60 + data: 'r' 1.61 + } 1.62 + }); 1.63 + } catch (ex) { 1.64 + this._onerror(ex); 1.65 + } 1.66 + } 1.67 + }, 1.68 + 1.69 + set onmessage(handler) { // property setter for onmessage 1.70 + this._handler = handler; 1.71 + while (this._pendingMessagesIncoming.length) { 1.72 + this._onmessage(this._pendingMessagesIncoming.shift()); 1.73 + } 1.74 + }, 1.75 + get onmessage() { 1.76 + return this._handler; 1.77 + }, 1.78 + 1.79 + /** 1.80 + * postMessage 1.81 + * 1.82 + * Send data to the onmessage handler on the other end of the port. The 1.83 + * data object should have a topic property. 1.84 + * 1.85 + * @param {jsobj} data 1.86 + */ 1.87 + postMessage: function fw_AbstractPort_postMessage(data) { 1.88 + if (this._closed) { 1.89 + throw new Error("port is closed"); 1.90 + } 1.91 + // There seems to be an issue with passing objects directly and letting 1.92 + // the structured clone thing work - we sometimes get: 1.93 + // [Exception... "The object could not be cloned." code: "25" nsresult: "0x80530019 (DataCloneError)"] 1.94 + // The best guess is that this happens when funky things have been added to the prototypes. 1.95 + // It doesn't happen for our "control" messages, only in messages from 1.96 + // content - so we explicitly use JSON on these messages as that avoids 1.97 + // the problem. 1.98 + this._postControlMessage("port-message", JSON.stringify(data)); 1.99 + }, 1.100 + 1.101 + close: function fw_AbstractPort_close() { 1.102 + if (this._closed) { 1.103 + return; // already closed. 1.104 + } 1.105 + this._postControlMessage("port-close"); 1.106 + // and clean myself up. 1.107 + this._handler = null; 1.108 + this._pendingMessagesIncoming = []; 1.109 + this._closed = true; 1.110 + } 1.111 +};