OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // chrome.runtime.messaging API implementation. | 5 // chrome.runtime.messaging API implementation. |
6 // TODO(robwu): Fix this indentation. | |
6 | 7 |
7 // TODO(kalman): factor requiring chrome out of here. | 8 // TODO(kalman): factor requiring chrome out of here. |
8 var chrome = requireNative('chrome').GetChrome(); | 9 var chrome = requireNative('chrome').GetChrome(); |
9 var Event = require('event_bindings').Event; | 10 var Event = require('event_bindings').Event; |
10 var lastError = require('lastError'); | 11 var lastError = require('lastError'); |
11 var logActivity = requireNative('activityLogger'); | 12 var logActivity = requireNative('activityLogger'); |
12 var logging = requireNative('logging'); | 13 var logging = requireNative('logging'); |
13 var messagingNatives = requireNative('messaging_natives'); | 14 var messagingNatives = requireNative('messaging_natives'); |
14 var processNatives = requireNative('process'); | 15 var processNatives = requireNative('process'); |
15 var utils = require('utils'); | 16 var utils = require('utils'); |
16 var messagingUtils = require('messaging_utils'); | 17 var messagingUtils = require('messaging_utils'); |
17 | 18 |
18 // The reserved channel name for the sendRequest/send(Native)Message APIs. | 19 // The reserved channel name for the sendRequest/send(Native)Message APIs. |
19 // Note: sendRequest is deprecated. | 20 // Note: sendRequest is deprecated. |
20 var kRequestChannel = "chrome.extension.sendRequest"; | 21 var kRequestChannel = "chrome.extension.sendRequest"; |
21 var kMessageChannel = "chrome.runtime.sendMessage"; | 22 var kMessageChannel = "chrome.runtime.sendMessage"; |
22 var kNativeMessageChannel = "chrome.runtime.sendNativeMessage"; | 23 var kNativeMessageChannel = "chrome.runtime.sendNativeMessage"; |
23 | 24 |
24 // Map of port IDs to port object. | 25 // Map of port IDs to port object. |
25 var ports = {}; | 26 var ports = {__proto__:null}; |
Devlin
2016/04/28 21:21:21
nit: space after ':'
| |
26 | 27 |
27 // Change even to odd and vice versa, to get the other side of a given | 28 // Change even to odd and vice versa, to get the other side of a given |
28 // channel. | 29 // channel. |
29 function getOppositePortId(portId) { return portId ^ 1; } | 30 function getOppositePortId(portId) { return portId ^ 1; } |
30 | 31 |
31 // Port object. Represents a connection to another script context through | 32 // Port object. Represents a connection to another script context through |
32 // which messages can be passed. | 33 // which messages can be passed. |
33 function PortImpl(portId, opt_name) { | 34 function PortImpl(portId, opt_name) { |
34 this.portId_ = portId; | 35 this.portId_ = portId; |
35 this.name = opt_name; | 36 this.name = opt_name; |
36 | 37 |
37 var portSchema = {name: 'port', $ref: 'runtime.Port'}; | 38 // Note: Keep these schemas in sync with the documentation in runtime.json |
38 var options = {unmanaged: true}; | 39 var portSchema = { |
40 __proto__: null, | |
41 name: 'port', | |
42 $ref: 'runtime.Port', | |
43 }; | |
44 var messageSchema = { | |
45 __proto__: null, | |
46 name: 'message', | |
47 type: 'any', | |
48 optional: true, | |
49 }; | |
50 var options = { | |
51 __proto__: null, | |
52 unmanaged: true, | |
53 }; | |
39 this.onDisconnect = new Event(null, [portSchema], options); | 54 this.onDisconnect = new Event(null, [portSchema], options); |
40 this.onMessage = new Event( | 55 this.onMessage = new Event(null, [messageSchema, portSchema], options); |
41 null, | |
42 [{name: 'message', type: 'any', optional: true}, portSchema], | |
43 options); | |
44 this.onDestroy_ = null; | 56 this.onDestroy_ = null; |
45 } | 57 } |
58 $Object.setPrototypeOf(PortImpl.prototype, null); | |
46 | 59 |
47 // Sends a message asynchronously to the context on the other end of this | 60 // Sends a message asynchronously to the context on the other end of this |
48 // port. | 61 // port. |
49 PortImpl.prototype.postMessage = function(msg) { | 62 PortImpl.prototype.postMessage = function(msg) { |
50 // JSON.stringify doesn't support a root object which is undefined. | 63 // JSON.stringify doesn't support a root object which is undefined. |
51 if (msg === undefined) | 64 if (msg === undefined) |
52 msg = null; | 65 msg = null; |
53 msg = $JSON.stringify(msg); | 66 msg = $JSON.stringify(msg); |
54 if (msg === undefined) { | 67 if (msg === undefined) { |
55 // JSON.stringify can fail with unserializable objects. Log an error and | 68 // JSON.stringify can fail with unserializable objects. Log an error and |
56 // drop the message. | 69 // drop the message. |
57 // | 70 // |
58 // TODO(kalman/mpcomplete): it would be better to do the same validation | 71 // TODO(kalman/mpcomplete): it would be better to do the same validation |
59 // here that we do for runtime.sendMessage (and variants), i.e. throw an | 72 // here that we do for runtime.sendMessage (and variants), i.e. throw an |
60 // schema validation Error, but just maintain the old behaviour until | 73 // schema validation Error, but just maintain the old behaviour until |
61 // there's a good reason not to (http://crbug.com/263077). | 74 // there's a good reason not to (http://crbug.com/263077). |
62 console.error('Illegal argument to Port.postMessage'); | 75 console.error('Illegal argument to Port.postMessage'); |
63 return; | 76 return; |
64 } | 77 } |
65 messagingNatives.PostMessage(this.portId_, msg); | 78 messagingNatives.PostMessage(this.portId_, msg); |
66 }; | 79 }; |
67 | 80 |
68 // Disconnects the port from the other end. | 81 // Disconnects the port from the other end. |
69 PortImpl.prototype.disconnect = function() { | 82 PortImpl.prototype.disconnect = function() { |
70 messagingNatives.CloseChannel(this.portId_, true); | 83 messagingNatives.CloseChannel(this.portId_, true); |
71 this.destroy_(); | 84 this.destroy_(); |
72 }; | 85 }; |
73 | 86 |
74 PortImpl.prototype.destroy_ = function() { | 87 PortImpl.prototype.destroy_ = function() { |
75 if (this.onDestroy_) | 88 if (this.onDestroy_) { |
76 this.onDestroy_(); | 89 this.onDestroy_(); |
90 this.onDestroy_ = null; | |
91 } | |
77 privates(this.onDisconnect).impl.destroy_(); | 92 privates(this.onDisconnect).impl.destroy_(); |
78 privates(this.onMessage).impl.destroy_(); | 93 privates(this.onMessage).impl.destroy_(); |
79 // TODO(robwu): Remove port lifetime management because it is completely | 94 // TODO(robwu): Remove port lifetime management because it is completely |
80 // handled in the browser. The renderer's only roles are | 95 // handled in the browser. The renderer's only roles are |
81 // 1) rejecting ports so that the browser knows that the renderer is not | 96 // 1) rejecting ports so that the browser knows that the renderer is not |
82 // interested in the port (this is merely an optimization) | 97 // interested in the port (this is merely an optimization) |
83 // 2) acknowledging port creations, so that the browser knows that the port | 98 // 2) acknowledging port creations, so that the browser knows that the port |
84 // was successfully created (from the perspective of the extension), but | 99 // was successfully created (from the perspective of the extension), but |
85 // then closed for some non-fatal reason. | 100 // then closed for some non-fatal reason. |
86 // 3) notifying the browser of explicit port closure via .disconnect(). | 101 // 3) notifying the browser of explicit port closure via .disconnect(). |
(...skipping 20 matching lines...) Expand all Loading... | |
107 messagingNatives.PortAddRef(portId); | 122 messagingNatives.PortAddRef(portId); |
108 return port; | 123 return port; |
109 }; | 124 }; |
110 | 125 |
111 // Helper function for dispatchOnRequest. | 126 // Helper function for dispatchOnRequest. |
112 function handleSendRequestError(isSendMessage, | 127 function handleSendRequestError(isSendMessage, |
113 responseCallbackPreserved, | 128 responseCallbackPreserved, |
114 sourceExtensionId, | 129 sourceExtensionId, |
115 targetExtensionId, | 130 targetExtensionId, |
116 sourceUrl) { | 131 sourceUrl) { |
117 var errorMsg = []; | 132 var errorMsg; |
118 var eventName = isSendMessage ? "runtime.onMessage" : "extension.onRequest"; | 133 var eventName = isSendMessage ? 'runtime.onMessage' : 'extension.onRequest'; |
119 if (isSendMessage && !responseCallbackPreserved) { | 134 if (isSendMessage && !responseCallbackPreserved) { |
120 $Array.push(errorMsg, | 135 errorMsg = |
121 "The chrome." + eventName + " listener must return true if you " + | 136 'The chrome.' + eventName + ' listener must return true if you ' + |
122 "want to send a response after the listener returns"); | 137 'want to send a response after the listener returns'; |
123 } else { | 138 } else { |
124 $Array.push(errorMsg, | 139 errorMsg = |
125 "Cannot send a response more than once per chrome." + eventName + | 140 'Cannot send a response more than once per chrome.' + eventName + |
126 " listener per document"); | 141 ' listener per document'; |
127 } | 142 } |
128 $Array.push(errorMsg, "(message was sent by extension" + sourceExtensionId); | 143 errorMsg += ' (message was sent by extension' + sourceExtensionId; |
129 if (sourceExtensionId != "" && sourceExtensionId != targetExtensionId) | 144 if (sourceExtensionId && sourceExtensionId !== targetExtensionId) |
130 $Array.push(errorMsg, "for extension " + targetExtensionId); | 145 errorMsg += ' for extension ' + targetExtensionId; |
131 if (sourceUrl != "") | 146 if (sourceUrl) |
132 $Array.push(errorMsg, "for URL " + sourceUrl); | 147 errorMsg += ' for URL ' + sourceUrl; |
133 lastError.set(eventName, errorMsg.join(" ") + ").", null, chrome); | 148 errorMsg += ').'; |
149 lastError.set(eventName, errorMsg, null, chrome); | |
134 } | 150 } |
135 | 151 |
136 // Helper function for dispatchOnConnect | 152 // Helper function for dispatchOnConnect |
137 function dispatchOnRequest(portId, channelName, sender, | 153 function dispatchOnRequest(portId, channelName, sender, |
138 sourceExtensionId, targetExtensionId, sourceUrl, | 154 sourceExtensionId, targetExtensionId, sourceUrl, |
139 isExternal) { | 155 isExternal) { |
140 var isSendMessage = channelName == kMessageChannel; | 156 var isSendMessage = channelName == kMessageChannel; |
141 var requestEvent = null; | 157 var requestEvent = null; |
142 if (isSendMessage) { | 158 if (isSendMessage) { |
143 if (chrome.runtime) { | 159 if (chrome.runtime) { |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
421 exports.$set('Port', Port); | 437 exports.$set('Port', Port); |
422 exports.$set('createPort', createPort); | 438 exports.$set('createPort', createPort); |
423 exports.$set('sendMessageImpl', sendMessageImpl); | 439 exports.$set('sendMessageImpl', sendMessageImpl); |
424 exports.$set('sendMessageUpdateArguments', sendMessageUpdateArguments); | 440 exports.$set('sendMessageUpdateArguments', sendMessageUpdateArguments); |
425 | 441 |
426 // For C++ code to call. | 442 // For C++ code to call. |
427 exports.$set('hasPort', hasPort); | 443 exports.$set('hasPort', hasPort); |
428 exports.$set('dispatchOnConnect', dispatchOnConnect); | 444 exports.$set('dispatchOnConnect', dispatchOnConnect); |
429 exports.$set('dispatchOnDisconnect', dispatchOnDisconnect); | 445 exports.$set('dispatchOnDisconnect', dispatchOnDisconnect); |
430 exports.$set('dispatchOnMessage', dispatchOnMessage); | 446 exports.$set('dispatchOnMessage', dispatchOnMessage); |
OLD | NEW |