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 script contains unprivileged javascript APIs related to chrome | 5 // This script contains unprivileged javascript APIs related to chrome |
6 // extensions. It is loaded by any extension-related context, such as content | 6 // extensions. It is loaded by any extension-related context, such as content |
7 // scripts or background pages. | 7 // scripts or background pages. |
8 // See user_script_slave.cc for script that is loaded by content scripts only. | 8 // See user_script_slave.cc for script that is loaded by content scripts only. |
9 | 9 |
10 var chrome = chrome || {}; | 10 var chrome = chrome || {}; |
11 (function () { | 11 (function () { |
12 native function CloseChannel(portId, notifyBrowser); | 12 native function CloseChannel(portId, notifyBrowser); |
13 native function PortAddRef(portId); | 13 native function PortAddRef(portId); |
14 native function PortRelease(portId); | 14 native function PortRelease(portId); |
15 native function PostMessage(portId, msg); | 15 native function PostMessage(portId, msg); |
16 native function GetChromeHidden(); | 16 native function GetChromeHidden(); |
17 native function Print(); | 17 native function Print(); |
18 native function BindToGC(); | |
18 | 19 |
19 var chromeHidden = GetChromeHidden(); | 20 var chromeHidden = GetChromeHidden(); |
20 var manifestVersion; | 21 var manifestVersion; |
21 var extensionId; | 22 var extensionId; |
22 | 23 |
23 // The reserved channel name for the sendRequest API. | 24 // The reserved channel name for the sendRequest API. |
24 chromeHidden.kRequestChannel = "chrome.extension.sendRequest"; | 25 chromeHidden.kRequestChannel = "chrome.extension.sendRequest"; |
25 | 26 |
26 // Map of port IDs to port object. | 27 // Map of port IDs to port object. |
27 var ports = {}; | 28 var ports = {}; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
116 tab = chromeHidden.JSON.parse(tab); | 117 tab = chromeHidden.JSON.parse(tab); |
117 var sender = {tab: tab, id: sourceExtensionId}; | 118 var sender = {tab: tab, id: sourceExtensionId}; |
118 | 119 |
119 // Special case for sendRequest/onRequest. | 120 // Special case for sendRequest/onRequest. |
120 if (channelName == chromeHidden.kRequestChannel) { | 121 if (channelName == chromeHidden.kRequestChannel) { |
121 var requestEvent = (isExternal ? | 122 var requestEvent = (isExternal ? |
122 chrome.extension.onRequestExternal : chrome.extension.onRequest); | 123 chrome.extension.onRequestExternal : chrome.extension.onRequest); |
123 if (requestEvent.hasListeners()) { | 124 if (requestEvent.hasListeners()) { |
124 var port = chromeHidden.Port.createPort(portId, channelName); | 125 var port = chromeHidden.Port.createPort(portId, channelName); |
125 port.onMessage.addListener(function(request) { | 126 port.onMessage.addListener(function(request) { |
126 requestEvent.dispatch(request, sender, function(response) { | 127 var responseCallback = function(response) { |
127 if (port) { | 128 if (port) { |
128 port.postMessage(response); | 129 port.postMessage(response); |
129 port = null; | 130 port = null; |
130 } else { | 131 } else { |
131 // We nulled out port when sending the response, and now the page | 132 // We nulled out port when sending the response, and now the page |
132 // is trying to send another response for the same request. | 133 // is trying to send another response for the same request. |
133 var errorMsg = | 134 var errorMsg = |
134 "Cannot send a response more than once per " + | 135 "Cannot send a response more than once per " + |
135 "chrome.extension.onRequest listener per document (message " + | 136 "chrome.extension.onRequest listener per document (message " + |
136 "was sent by extension " + sourceExtensionId; | 137 "was sent by extension " + sourceExtensionId; |
137 if (sourceExtensionId != targetExtensionId) { | 138 if (sourceExtensionId != targetExtensionId) { |
138 errorMsg += " for extension " + targetExtensionId; | 139 errorMsg += " for extension " + targetExtensionId; |
139 } | 140 } |
140 errorMsg += ")."; | 141 errorMsg += ")."; |
141 chrome.extension.lastError = {"message": errorMsg}; | 142 chrome.extension.lastError = {"message": errorMsg}; |
142 console.error("Could not send response: " + errorMsg); | 143 console.error("Could not send response: " + errorMsg); |
143 } | 144 } |
145 }; | |
146 // In case the extension never invokes the responseCallback, and also | |
147 // doesn't keep a reference to it, we need to clean up the port. Do | |
148 // so by attaching to the garbage collection of the responseCallback | |
149 // using some native hackery. | |
150 BindToGC(responseCallback, function() { | |
151 if (port) { | |
152 port.postMessage(null); | |
Matt Perry
2012/03/13 19:54:39
Change this to port.disconnect(); We shouldn't sen
| |
153 port = null; | |
154 } | |
144 }); | 155 }); |
156 requestEvent.dispatch(request, sender, responseCallback); | |
145 }); | 157 }); |
146 } | 158 } |
147 return; | 159 return; |
148 } | 160 } |
149 | 161 |
150 var connectEvent = (isExternal ? | 162 var connectEvent = (isExternal ? |
151 chrome.extension.onConnectExternal : chrome.extension.onConnect); | 163 chrome.extension.onConnectExternal : chrome.extension.onConnect); |
152 if (connectEvent.hasListeners()) { | 164 if (connectEvent.hasListeners()) { |
153 var port = chromeHidden.Port.createPort(portId, channelName); | 165 var port = chromeHidden.Port.createPort(portId, channelName); |
154 port.sender = sender; | 166 port.sender = sender; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
204 chrome.extension = chrome.extension || {}; | 216 chrome.extension = chrome.extension || {}; |
205 | 217 |
206 if (manifestVersion < 2) { | 218 if (manifestVersion < 2) { |
207 chrome.self = chrome.extension; | 219 chrome.self = chrome.extension; |
208 chrome.extension.inIncognitoTab = inIncognitoContext; | 220 chrome.extension.inIncognitoTab = inIncognitoContext; |
209 } | 221 } |
210 | 222 |
211 chrome.extension.inIncognitoContext = inIncognitoContext; | 223 chrome.extension.inIncognitoContext = inIncognitoContext; |
212 }); | 224 }); |
213 })(); | 225 })(); |
OLD | NEW |