Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6131)

Unified Diff: chrome/renderer/resources/extensions/miscellaneous_bindings.js

Issue 9965005: Deprecate chrome.extension.sendRequest in favor of sendMessage, with a safer (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sync Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/renderer/resources/extensions/miscellaneous_bindings.js
diff --git a/chrome/renderer/resources/extensions/miscellaneous_bindings.js b/chrome/renderer/resources/extensions/miscellaneous_bindings.js
index 205bc01b25fb821dc34e2a2261b5df8852efabac..f3b236059136cdd1b47dcfccc2697d017cd16cd3 100644
--- a/chrome/renderer/resources/extensions/miscellaneous_bindings.js
+++ b/chrome/renderer/resources/extensions/miscellaneous_bindings.js
@@ -20,8 +20,10 @@
var manifestVersion;
var extensionId;
- // The reserved channel name for the sendRequest API.
+ // The reserved channel name for the sendRequest/sendMessage APIs.
+ // Note: sendRequest is deprecated.
chromeHidden.kRequestChannel = "chrome.extension.sendRequest";
+ chromeHidden.kMessageChannel = "chrome.extension.sendMessage";
// Map of port IDs to port object.
var ports = {};
@@ -95,14 +97,43 @@
return port;
};
+ // Helper function for dispatchOnRequest.
+ function handleSendRequestError(isSendMessage, responseCallbackPreserved,
+ sourceExtensionId, targetExtensionId) {
+ var errorMsg;
+ var eventName = (isSendMessage ?
+ "chrome.extension.onMessage" : "chrome.extension.onRequest");
+ if (isSendMessage && !responseCallbackPreserved) {
+ errorMsg =
+ "The " + eventName + " listener must return true if you want to" +
+ " send a response after the listener returns ";
+ } else {
+ errorMsg =
+ "Cannot send a response more than once per " + eventName +
+ " listener per document";
+ }
+ errorMsg += " (message was sent by extension " + sourceExtensionId;
+ if (sourceExtensionId != targetExtensionId)
+ errorMsg += " for extension " + targetExtensionId;
+ errorMsg += ").";
+ chrome.extension.lastError = {"message": errorMsg};
+ console.error("Could not send response: " + errorMsg);
+ }
+
+ // Helper function for dispatchOnConnect
function dispatchOnRequest(portId, channelName, sender,
sourceExtensionId, targetExtensionId,
isExternal) {
- var requestEvent = (isExternal ?
- chrome.extension.onRequestExternal : chrome.extension.onRequest);
+ var isSendMessage = channelName == chromeHidden.kMessageChannel;
+ var requestEvent = (isSendMessage ?
+ (isExternal ?
+ chrome.extension.onMessageExternal : chrome.extension.onMessage) :
+ (isExternal ?
+ chrome.extension.onRequestExternal : chrome.extension.onRequest));
if (requestEvent.hasListeners()) {
var port = chromeHidden.Port.createPort(portId, channelName);
port.onMessage.addListener(function(request) {
+ var responseCallbackPreserved = false;
var responseCallback = function(response) {
if (port) {
port.postMessage(response);
@@ -111,16 +142,8 @@
} else {
// We nulled out port when sending the response, and now the page
// is trying to send another response for the same request.
- var errorMsg =
- "Cannot send a response more than once per " +
- "chrome.extension.onRequest listener per document (message " +
- "was sent by extension " + sourceExtensionId;
- if (sourceExtensionId != targetExtensionId) {
- errorMsg += " for extension " + targetExtensionId;
- }
- errorMsg += ").";
- chrome.extension.lastError = {"message": errorMsg};
- console.error("Could not send response: " + errorMsg);
+ handleSendRequestError(isSendMessage, responseCallbackPreserved,
+ sourceExtensionId, targetExtensionId);
}
};
// In case the extension never invokes the responseCallback, and also
@@ -133,7 +156,19 @@
port = null;
}
});
- requestEvent.dispatch(request, sender, responseCallback);
+ if (!isSendMessage) {
+ requestEvent.dispatch(request, sender, responseCallback);
+ } else {
+ var rv = requestEvent.dispatch(request, sender, responseCallback);
+ responseCallbackPreserved =
+ rv && rv.results && rv.results.indexOf(true) > -1;
+ if (!responseCallbackPreserved) {
+ // If they didn't access the response callback, they're not
+ // going to send a response, so clean up the port immediately.
+ port.destroy_();
+ port = null;
+ }
+ }
});
return true;
}
@@ -161,8 +196,9 @@
tab = chromeHidden.JSON.parse(tab);
var sender = {tab: tab, id: sourceExtensionId};
- // Special case for sendRequest/onRequest.
- if (channelName == chromeHidden.kRequestChannel) {
+ // Special case for sendRequest/onRequest and sendMessage/onMessage.
+ if (channelName == chromeHidden.kRequestChannel ||
+ channelName == chromeHidden.kMessageChannel) {
return dispatchOnRequest(portId, channelName, sender,
sourceExtensionId, targetExtensionId,
isExternal);
@@ -215,6 +251,43 @@
}
};
+ // Shared implementation used by tabs.sendMessage and extension.sendMessage.
+ chromeHidden.Port.sendMessageImpl = function(port, request,
+ responseCallback) {
+ port.postMessage(request);
+
+ if (port.name == chromeHidden.kMessageChannel && !responseCallback) {
+ // TODO(mpcomplete): Do this for the old sendRequest API too, after
+ // verifying it doesn't break anything.
+ // Go ahead and disconnect immediately if the sender is not expecting
+ // a response.
+ port.disconnect();
+ return;
+ }
+
+ // Ensure the callback exists for the older sendRequest API.
+ if (!responseCallback)
+ responseCallback = function() {};
+
+ port.onDisconnect.addListener(function() {
+ // For onDisconnects, we only notify the callback if there was an error
+ try {
+ if (chrome.extension.lastError)
+ responseCallback();
+ } finally {
+ port = null;
+ }
+ });
+ port.onMessage.addListener(function(response) {
+ try {
+ responseCallback(response);
+ } finally {
+ port.disconnect();
+ port = null;
+ }
+ });
+ }
+
// This function is called on context initialization for both content scripts
// and extension contexts.
chromeHidden.onLoad.addListener(function(tempExtensionId,

Powered by Google App Engine
This is Rietveld 408576698