Index: chrome/renderer/resources/extensions/last_error.js |
diff --git a/chrome/renderer/resources/extensions/last_error.js b/chrome/renderer/resources/extensions/last_error.js |
index 2b38a2910e4a5dfa9b0acef1a246ed6c042ffd73..25c48c67d8e226fe75c259cdd12936625b00d42c 100644 |
--- a/chrome/renderer/resources/extensions/last_error.js |
+++ b/chrome/renderer/resources/extensions/last_error.js |
@@ -2,20 +2,57 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-requireNative('runtime'); |
+var DCHECK = requireNative('logging').DCHECK; |
+var GetAvailability = requireNative('v8_context').GetAvailability; |
+var GetGlobal = requireNative('sendRequest').GetGlobal; |
-function set(message) { |
+// Utility for setting chrome.*.lastError. |
+// |
+// A utility here is useful for two reasons: |
+// 1. For backwards compatibility we need to set chrome.extension.lastError, |
+// but not all contexts actually have access to the extension namespace. |
+// 2. When calling across contexts, the global object that gets lastError set |
+// needs to be that of the caller. We force callers to explicitly specify |
+// the chrome object to try to prevent bugs here. |
+ |
+/** |
+ * Sets the last error on |targetChrome| to |message|. |
+ */ |
+function set(message, targetChrome) { |
+ DCHECK(targetChrome != undefined); |
+ clear(targetChrome); // in case somebody has set a sneaky getter/setter |
var errorObject = { 'message': message }; |
- if (chrome.extension) |
- chrome.extension.lastError = errorObject; |
- chrome.runtime.lastError = errorObject; |
+ if (GetAvailability('extension').is_available) |
+ targetChrome.extension.lastError = errorObject; |
+ targetChrome.runtime.lastError = errorObject; |
}; |
-function clear() { |
- if (chrome.extension) |
- delete chrome.extension.lastError; |
- delete chrome.runtime.lastError; |
+/** |
+ * Clears the last error on |targetChrome|. |
+ */ |
+function clear(targetChrome) { |
+ DCHECK(targetChrome != undefined); |
+ if (GetAvailability('extension').is_available) |
+ delete targetChrome.extension.lastError; |
+ delete targetChrome.runtime.lastError; |
}; |
+/** |
+ * Runs |callback(args)| with last error set to |message|. |
+ * |
+ * The target chrome object is the global object's of the callback, so this |
+ * method won't work if the real callback has been wrapped (etc). |
+ */ |
+function run(message, callback, args) { |
+ var targetChrome = GetGlobal(callback).chrome; |
+ set(message, targetChrome); |
+ try { |
+ callback.apply(undefined, args); |
+ } finally { |
+ clear(targetChrome); |
+ } |
+} |
+ |
exports.clear = clear; |
exports.set = set; |
+exports.run = run; |