inspected-window-command.js (5167B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 const { 8 getAdHocFrontOrPrimitiveGrip, 9 // eslint-disable-next-line mozilla/reject-some-requires 10 } = require("resource://devtools/client/fronts/object.js"); 11 12 /** 13 * For now, this class is mostly a wrapper around webExtInspectedWindow actor. 14 */ 15 class InspectedWindowCommand { 16 constructor({ commands }) { 17 this.commands = commands; 18 } 19 20 /** 21 * Return a promise that resolves to the related target actor's front. 22 * The Web Extension inspected window actor. 23 * 24 * @return {Promise<WebExtensionInspectedWindowFront>} 25 */ 26 getFront() { 27 return this.commands.targetCommand.targetFront.getFront( 28 "webExtensionInspectedWindow" 29 ); 30 } 31 32 /** 33 * Evaluate the provided javascript code in a target window. 34 * 35 * @param {object} webExtensionCallerInfo - The addonId and the url (the addon base url 36 * or the url of the actual caller filename and lineNumber) used to log useful 37 * debugging information in the produced error logs and eval stack trace. 38 * @param {string} expression - The expression to evaluate. 39 * @param {object} options - An option object. Check the actor method definition to see 40 * what properties it can hold (minus the `consoleFront` property which is defined 41 * below). 42 * @param {WebConsoleFront} options.consoleFront - An optional webconsole front. When 43 * set, the result will be either a primitive, a LongStringFront or an 44 * ObjectFront, and the WebConsoleActor corresponding to the console front will 45 * be used to generate those, which is needed if we want to handle ObjectFronts 46 * on the client. 47 */ 48 async eval(webExtensionCallerInfo, expression, options = {}) { 49 const { consoleFront } = options; 50 51 if (consoleFront) { 52 options.evalResultAsGrip = true; 53 options.toolboxConsoleActorID = consoleFront.actor; 54 delete options.consoleFront; 55 } 56 57 const front = await this.getFront(); 58 const response = await front.eval( 59 webExtensionCallerInfo, 60 expression, 61 options 62 ); 63 64 // If no consoleFront was provided, we can directly return the response. 65 if (!consoleFront) { 66 return response; 67 } 68 69 if ( 70 !response.hasOwnProperty("exceptionInfo") && 71 !response.hasOwnProperty("valueGrip") 72 ) { 73 throw new Error( 74 "Response does not have `exceptionInfo` or `valueGrip` property" 75 ); 76 } 77 78 if (response.exceptionInfo) { 79 console.error( 80 response.exceptionInfo.description, 81 ...(response.exceptionInfo.details || []) 82 ); 83 return response; 84 } 85 86 // On the server, the valueGrip is created from the toolbox webconsole actor. 87 // If we want since the ObjectFront connection is inherited from the parent front, we 88 // need to set the console front as the parent front. 89 return getAdHocFrontOrPrimitiveGrip( 90 response.valueGrip, 91 consoleFront || this 92 ); 93 } 94 95 /** 96 * Reload the target tab, optionally bypass cache, customize the userAgent and/or 97 * inject a script in targeted document or any of its sub-frame. 98 * 99 * @param {WebExtensionCallerInfo} callerInfo 100 * the addonId and the url (the addon base url or the url of the actual caller 101 * filename and lineNumber) used to log useful debugging information in the 102 * produced error logs and eval stack trace. 103 * @param {object} options 104 * @param {boolean|undefined} options.ignoreCache 105 * Enable/disable the cache bypass headers. 106 * @param {string|undefined} options.injectedScript 107 * Evaluate the provided javascript code in the top level and every sub-frame 108 * created during the page reload, before any other script in the page has been 109 * executed. 110 * @param {string|undefined} options.userAgent 111 * Customize the userAgent during the page reload. 112 * @returns {Promise} A promise that resolves once the page is done loading when userAgent 113 * or injectedScript option are passed. If those options are not provided, the 114 * Promise will resolve after the reload was initiated. 115 */ 116 async reload(callerInfo, options = {}) { 117 if (this._reloadPending) { 118 return null; 119 } 120 121 this._reloadPending = true; 122 123 try { 124 // We always want to update the target configuration to set the user agent if one is 125 // passed, or to reset a potential existing override if userAgent isn't defined. 126 await this.commands.targetConfigurationCommand.updateConfiguration({ 127 customUserAgent: options.userAgent, 128 }); 129 130 const front = await this.getFront(); 131 const result = await front.reload(callerInfo, options); 132 this._reloadPending = false; 133 134 return result; 135 } catch (e) { 136 this._reloadPending = false; 137 console.error(e); 138 return Promise.reject({ 139 message: "An unexpected error occurred", 140 }); 141 } 142 } 143 } 144 145 module.exports = InspectedWindowCommand;