| OLD | NEW | 
|---|
|  | (Empty) | 
| 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 |  | 
| 3 // found in the LICENSE file. |  | 
| 4 |  | 
| 5 var GetAvailability = requireNative('v8_context').GetAvailability; |  | 
| 6 var GetGlobal = requireNative('sendRequest').GetGlobal; |  | 
| 7 |  | 
| 8 // Utility for setting chrome.*.lastError. |  | 
| 9 // |  | 
| 10 // A utility here is useful for two reasons: |  | 
| 11 //  1. For backwards compatibility we need to set chrome.extension.lastError, |  | 
| 12 //     but not all contexts actually have access to the extension namespace. |  | 
| 13 //  2. When calling across contexts, the global object that gets lastError set |  | 
| 14 //     needs to be that of the caller. We force callers to explicitly specify |  | 
| 15 //     the chrome object to try to prevent bugs here. |  | 
| 16 |  | 
| 17 /** |  | 
| 18  * Sets the last error for |name| on |targetChrome| to |message| with an |  | 
| 19  * optional |stack|. |  | 
| 20  */ |  | 
| 21 function set(name, message, stack, targetChrome) { |  | 
| 22   var errorMessage = name + ': ' + message; |  | 
| 23   if (stack != null && stack != '') |  | 
| 24     errorMessage += '\n' + stack; |  | 
| 25 |  | 
| 26   if (!targetChrome) |  | 
| 27     throw new Error('No chrome object to set error: ' + errorMessage); |  | 
| 28   clear(targetChrome);  // in case somebody has set a sneaky getter/setter |  | 
| 29 |  | 
| 30   var errorObject = { message: message }; |  | 
| 31   if (GetAvailability('extension.lastError').is_available) |  | 
| 32     targetChrome.extension.lastError = errorObject; |  | 
| 33 |  | 
| 34   assertRuntimeIsAvailable(); |  | 
| 35 |  | 
| 36   // We check to see if developers access runtime.lastError in order to decide |  | 
| 37   // whether or not to log it in the (error) console. |  | 
| 38   privates(targetChrome.runtime).accessedLastError = false; |  | 
| 39   $Object.defineProperty(targetChrome.runtime, 'lastError', { |  | 
| 40       configurable: true, |  | 
| 41       get: function() { |  | 
| 42         privates(targetChrome.runtime).accessedLastError = true; |  | 
| 43         return errorObject; |  | 
| 44       }, |  | 
| 45       set: function(error) { |  | 
| 46         errorObject = errorObject; |  | 
| 47       }}); |  | 
| 48 }; |  | 
| 49 |  | 
| 50 /** |  | 
| 51  * Check if anyone has checked chrome.runtime.lastError since it was set. |  | 
| 52  * @param {Object} targetChrome the Chrome object to check. |  | 
| 53  * @return boolean True if the lastError property was set. |  | 
| 54  */ |  | 
| 55 function hasAccessed(targetChrome) { |  | 
| 56   assertRuntimeIsAvailable(); |  | 
| 57   return privates(targetChrome.runtime).accessedLastError === true; |  | 
| 58 } |  | 
| 59 |  | 
| 60 /** |  | 
| 61  * Check whether there is an error set on |targetChrome| without setting |  | 
| 62  * |accessedLastError|. |  | 
| 63  * @param {Object} targetChrome the Chrome object to check. |  | 
| 64  * @return boolean Whether lastError has been set. |  | 
| 65  */ |  | 
| 66 function hasError(targetChrome) { |  | 
| 67   if (!targetChrome) |  | 
| 68     throw new Error('No target chrome to check'); |  | 
| 69 |  | 
| 70   assertRuntimeIsAvailable(); |  | 
| 71   if ('lastError' in targetChrome.runtime) |  | 
| 72     return true; |  | 
| 73 |  | 
| 74   return false; |  | 
| 75 }; |  | 
| 76 |  | 
| 77 /** |  | 
| 78  * Clears the last error on |targetChrome|. |  | 
| 79  */ |  | 
| 80 function clear(targetChrome) { |  | 
| 81   if (!targetChrome) |  | 
| 82     throw new Error('No target chrome to clear error'); |  | 
| 83 |  | 
| 84   if (GetAvailability('extension.lastError').is_available) |  | 
| 85    delete targetChrome.extension.lastError; |  | 
| 86 |  | 
| 87   assertRuntimeIsAvailable(); |  | 
| 88   delete targetChrome.runtime.lastError; |  | 
| 89   delete privates(targetChrome.runtime).accessedLastError; |  | 
| 90 }; |  | 
| 91 |  | 
| 92 function assertRuntimeIsAvailable() { |  | 
| 93   // chrome.runtime should always be available, but maybe it's disappeared for |  | 
| 94   // some reason? Add debugging for http://crbug.com/258526. |  | 
| 95   var runtimeAvailability = GetAvailability('runtime.lastError'); |  | 
| 96   if (!runtimeAvailability.is_available) { |  | 
| 97     throw new Error('runtime.lastError is not available: ' + |  | 
| 98                     runtimeAvailability.message); |  | 
| 99   } |  | 
| 100   if (!chrome.runtime) |  | 
| 101     throw new Error('runtime namespace is null or undefined'); |  | 
| 102 } |  | 
| 103 |  | 
| 104 /** |  | 
| 105  * Runs |callback(args)| with last error args as in set(). |  | 
| 106  * |  | 
| 107  * The target chrome object is the global object's of the callback, so this |  | 
| 108  * method won't work if the real callback has been wrapped (etc). |  | 
| 109  */ |  | 
| 110 function run(name, message, stack, callback, args) { |  | 
| 111   var targetChrome = GetGlobal(callback).chrome; |  | 
| 112   set(name, message, stack, targetChrome); |  | 
| 113   try { |  | 
| 114     $Function.apply(callback, undefined, args); |  | 
| 115   } finally { |  | 
| 116     clear(targetChrome); |  | 
| 117   } |  | 
| 118 } |  | 
| 119 |  | 
| 120 exports.clear = clear; |  | 
| 121 exports.hasAccessed = hasAccessed; |  | 
| 122 exports.hasError = hasError; |  | 
| 123 exports.set = set; |  | 
| 124 exports.run = run; |  | 
| OLD | NEW | 
|---|