OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // This contains unprivileged javascript APIs for extensions and apps. It | 5 // This contains unprivileged javascript APIs for extensions and apps. It |
6 // can be loaded by any extension-related context, such as content scripts or | 6 // can be loaded by any extension-related context, such as content scripts or |
7 // background pages. See user_script_slave.cc for script that is loaded by | 7 // background pages. See user_script_slave.cc for script that is loaded by |
8 // content scripts only. | 8 // content scripts only. |
9 | 9 |
10 require('json_schema'); | 10 require('json_schema'); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 var port = new PortImpl(portId, opt_name); | 98 var port = new PortImpl(portId, opt_name); |
99 ports[portId] = port; | 99 ports[portId] = port; |
100 portReleasers[portId] = PortRelease.bind(this, portId); | 100 portReleasers[portId] = PortRelease.bind(this, portId); |
101 chromeHidden.onUnload.addListener(portReleasers[portId]); | 101 chromeHidden.onUnload.addListener(portReleasers[portId]); |
102 | 102 |
103 PortAddRef(portId); | 103 PortAddRef(portId); |
104 return port; | 104 return port; |
105 }; | 105 }; |
106 | 106 |
107 // Helper function for dispatchOnRequest. | 107 // Helper function for dispatchOnRequest. |
108 function handleSendRequestError(isSendMessage, responseCallbackPreserved, | 108 function handleSendRequestError(isSendMessage, |
109 sourceExtensionId, targetExtensionId) { | 109 responseCallbackPreserved, |
110 var errorMsg; | 110 sourceExtensionId, |
| 111 targetExtensionId, |
| 112 sourceUrl) { |
| 113 var errorMsg = []; |
111 var eventName = isSendMessage ? "runtime.onMessage" : "extension.onRequest"; | 114 var eventName = isSendMessage ? "runtime.onMessage" : "extension.onRequest"; |
112 if (isSendMessage && !responseCallbackPreserved) { | 115 if (isSendMessage && !responseCallbackPreserved) { |
113 errorMsg = | 116 errorMsg.push( |
114 "The chrome." + eventName + " listener must return true if you " + | 117 "The chrome." + eventName + " listener must return true if you " + |
115 "want to send a response after the listener returns "; | 118 "want to send a response after the listener returns"); |
116 } else { | 119 } else { |
117 errorMsg = | 120 errorMsg.push( |
118 "Cannot send a response more than once per chrome." + eventName + | 121 "Cannot send a response more than once per chrome." + eventName + |
119 " listener per document"; | 122 " listener per document"); |
120 } | 123 } |
121 errorMsg += "(message was sent by extension " + sourceExtensionId; | 124 errorMsg.push("(message was sent by extension" + sourceExtensionId); |
122 if (sourceExtensionId != targetExtensionId) | 125 if (sourceExtensionId != "" && sourceExtensionId != targetExtensionId) |
123 errorMsg += " for extension " + targetExtensionId; | 126 errorMsg.push("for extension " + targetExtensionId); |
124 errorMsg += ")."; | 127 if (sourceUrl != "") |
125 lastError.set(eventName, errorMsg, null, chrome); | 128 errorMsg.push("for URL " + sourceUrl); |
| 129 lastError.set(eventName, errorMsg.join(" ") + ").", null, chrome); |
126 } | 130 } |
127 | 131 |
128 // Helper function for dispatchOnConnect | 132 // Helper function for dispatchOnConnect |
129 function dispatchOnRequest(portId, channelName, sender, | 133 function dispatchOnRequest(portId, channelName, sender, |
130 sourceExtensionId, targetExtensionId, | 134 sourceExtensionId, targetExtensionId, sourceUrl, |
131 isExternal) { | 135 isExternal) { |
132 var isSendMessage = channelName == chromeHidden.kMessageChannel; | 136 var isSendMessage = channelName == chromeHidden.kMessageChannel; |
133 var requestEvent = (isSendMessage ? | 137 var requestEvent = (isSendMessage ? |
134 (isExternal ? | 138 (isExternal ? |
135 chrome.runtime.onMessageExternal : chrome.runtime.onMessage) : | 139 chrome.runtime.onMessageExternal : chrome.runtime.onMessage) : |
136 (isExternal ? | 140 (isExternal ? |
137 chrome.extension.onRequestExternal : chrome.extension.onRequest)); | 141 chrome.extension.onRequestExternal : chrome.extension.onRequest)); |
138 if (requestEvent.hasListeners()) { | 142 if (requestEvent.hasListeners()) { |
139 var port = chromeHidden.Port.createPort(portId, channelName); | 143 var port = chromeHidden.Port.createPort(portId, channelName); |
140 port.onMessage.addListener(function(request) { | 144 port.onMessage.addListener(function(request) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 } | 179 } |
176 } | 180 } |
177 }); | 181 }); |
178 var eventName = (isSendMessage ? | 182 var eventName = (isSendMessage ? |
179 (isExternal ? | 183 (isExternal ? |
180 "runtime.onMessageExternal" : "runtime.onMessage") : | 184 "runtime.onMessageExternal" : "runtime.onMessage") : |
181 (isExternal ? | 185 (isExternal ? |
182 "extension.onRequestExternal" : "extension.onRequest")); | 186 "extension.onRequestExternal" : "extension.onRequest")); |
183 logActivity.LogEvent(targetExtensionId, | 187 logActivity.LogEvent(targetExtensionId, |
184 eventName, | 188 eventName, |
185 [sourceExtensionId]); | 189 [sourceExtensionId, sourceUrl]); |
186 return true; | 190 return true; |
187 } | 191 } |
188 return false; | 192 return false; |
189 } | 193 } |
190 | 194 |
191 // Called by native code when a channel has been opened to this context. | 195 // Called by native code when a channel has been opened to this context. |
192 chromeHidden.Port.dispatchOnConnect = function(portId, channelName, tab, | 196 chromeHidden.Port.dispatchOnConnect = function(portId, |
| 197 channelName, |
| 198 sourceTab, |
193 sourceExtensionId, | 199 sourceExtensionId, |
194 targetExtensionId) { | 200 targetExtensionId, |
| 201 sourceUrl) { |
195 // Only create a new Port if someone is actually listening for a connection. | 202 // Only create a new Port if someone is actually listening for a connection. |
196 // In addition to being an optimization, this also fixes a bug where if 2 | 203 // In addition to being an optimization, this also fixes a bug where if 2 |
197 // channels were opened to and from the same process, closing one would | 204 // channels were opened to and from the same process, closing one would |
198 // close both. | 205 // close both. |
199 if (targetExtensionId != extensionId) | 206 if (targetExtensionId != extensionId) |
200 return false; // not for us | 207 return false; // not for us |
201 if (ports[getOppositePortId(portId)]) | 208 if (ports[getOppositePortId(portId)]) |
202 return false; // this channel was opened by us, so ignore it | 209 return false; // this channel was opened by us, so ignore it |
203 | 210 |
204 // Determine whether this is coming from another extension, so we can use | 211 // Determine whether this is coming from another extension, so we can use |
205 // the right event. | 212 // the right event. |
206 var isExternal = sourceExtensionId != extensionId; | 213 var isExternal = sourceExtensionId != extensionId; |
207 | 214 |
208 if (tab) | 215 var sender = {id: sourceExtensionId}; |
209 tab = json.parse(tab); | 216 if (sourceUrl) |
210 var sender = {tab: tab, id: sourceExtensionId}; | 217 sender.url = sourceUrl; |
| 218 if (sourceTab) |
| 219 sender.tab = sourceTab; |
211 | 220 |
212 // Special case for sendRequest/onRequest and sendMessage/onMessage. | 221 // Special case for sendRequest/onRequest and sendMessage/onMessage. |
213 if (channelName == chromeHidden.kRequestChannel || | 222 if (channelName == chromeHidden.kRequestChannel || |
214 channelName == chromeHidden.kMessageChannel) { | 223 channelName == chromeHidden.kMessageChannel) { |
215 return dispatchOnRequest(portId, channelName, sender, | 224 return dispatchOnRequest(portId, channelName, sender, |
216 sourceExtensionId, targetExtensionId, | 225 sourceExtensionId, targetExtensionId, sourceUrl, |
217 isExternal); | 226 isExternal); |
218 } | 227 } |
219 | 228 |
220 var connectEvent = (isExternal ? | 229 var connectEvent = (isExternal ? |
221 chrome.runtime.onConnectExternal : chrome.runtime.onConnect); | 230 chrome.runtime.onConnectExternal : chrome.runtime.onConnect); |
222 if (connectEvent.hasListeners()) { | 231 if (connectEvent.hasListeners()) { |
223 var port = chromeHidden.Port.createPort(portId, channelName); | 232 var port = chromeHidden.Port.createPort(portId, channelName); |
224 port.sender = sender; | 233 port.sender = sender; |
225 if (manifestVersion < 2) | 234 if (manifestVersion < 2) |
226 port.tab = port.sender.tab; | 235 port.tab = port.sender.tab; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 var targetId = null; | 332 var targetId = null; |
324 if (lastArg >= 0) | 333 if (lastArg >= 0) |
325 targetId = args[lastArg--]; | 334 targetId = args[lastArg--]; |
326 | 335 |
327 if (lastArg != -1) | 336 if (lastArg != -1) |
328 throw new Error('Invalid arguments to ' + functionName + '.'); | 337 throw new Error('Invalid arguments to ' + functionName + '.'); |
329 return [targetId, request, responseCallback]; | 338 return [targetId, request, responseCallback]; |
330 } | 339 } |
331 | 340 |
332 exports.sendMessageUpdateArguments = sendMessageUpdateArguments; | 341 exports.sendMessageUpdateArguments = sendMessageUpdateArguments; |
OLD | NEW |