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

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: better docs 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 84556f3b14cc07c26058beae8140586bacdf948f..b20d34d14276eb1c20c03e7dcb3163c44a5acaf3 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,6 +97,30 @@
return port;
};
+ // Helper function for dispatchOnConnect.
+ function handleSendRequestError(isSendMessage, responseCallbackAccessed,
+ sourceExtensionId, targetExtensionId) {
+ var errorMsg;
+ var eventName = (isSendMessage ?
+ "chrome.extension.onMessage" : "chrome.extension.onRequest");
+ if (isSendMessage && !responseCallbackAccessed) {
+ 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);
+ }
+
// Called by native code when a channel has been opened to this context.
chromeHidden.Port.dispatchOnConnect = function(portId, channelName, tab,
sourceExtensionId,
@@ -116,13 +142,19 @@
tab = chromeHidden.JSON.parse(tab);
var sender = {tab: tab, id: sourceExtensionId};
- // Special case for sendRequest/onRequest.
- if (channelName == chromeHidden.kRequestChannel) {
- var requestEvent = (isExternal ?
- chrome.extension.onRequestExternal : chrome.extension.onRequest);
+ // Special case for sendRequest/onRequest and sendMessage/onMessage.
+ var isSendMessage = channelName == chromeHidden.kMessageChannel;
+ if (channelName == chromeHidden.kRequestChannel ||
+ channelName == chromeHidden.kMessageChannel) {
+ var requestEvent = (isSendMessage ?
Aaron Boodman 2012/03/30 21:28:00 O_o
Matt Perry 2012/03/30 23:02:48 Yeah I went there.
+ (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 responseCallbackAccessed = false;
var responseCallback = function(response) {
if (port) {
port.postMessage(response);
@@ -130,16 +162,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, responseCallbackAccessed,
+ sourceExtensionId, targetExtensionId);
}
};
// In case the extension never invokes the responseCallback, and also
@@ -152,10 +176,26 @@
port = null;
}
});
- requestEvent.dispatch(request, sender, responseCallback);
+ if (!isSendMessage) {
+ requestEvent.dispatch(request, sender, responseCallback);
+ } else {
+ var retvals = requestEvent.dispatch(request, sender,
+ responseCallback);
+ for (var i in retvals) {
+ if (retvals[i] === true) {
+ responseCallbackAccessed = true;
Aaron Boodman 2012/03/30 21:28:00 Were you originally trying to do some craziness wh
Aaron Boodman 2012/03/30 21:28:00 responseCallback = retvals.indexOf(true) > -1;
Matt Perry 2012/03/30 23:02:48 Yep. New name.
Matt Perry 2012/03/30 23:02:48 Sweet, done.
+ break;
+ }
+ }
+ if (!responseCallbackAccessed) {
+ // 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;
}
var connectEvent = (isExternal ?
@@ -203,6 +243,40 @@
}
};
+ // 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) {
+ // Go ahead and disconnect immediately if the sender is not expecting
+ // a response.
+ port.disconnect();
+ return;
+ }
+
+ if (!responseCallback)
Aaron Boodman 2012/03/30 21:28:00 Maybe add a comment that this is used by the older
Matt Perry 2012/03/30 23:02:48 Done.
+ 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