utils.js (3144B)
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 CONSOLE_WORKER_IDS = (exports.CONSOLE_WORKER_IDS = new Set([ 8 "SharedWorker", 9 "ServiceWorker", 10 "Worker", 11 ])); 12 13 var WebConsoleUtils = { 14 /** 15 * Given a message, return one of CONSOLE_WORKER_IDS if it matches 16 * one of those. 17 * 18 * @return string 19 */ 20 getWorkerType(message) { 21 const innerID = message?.innerID; 22 return CONSOLE_WORKER_IDS.has(innerID) ? innerID : null; 23 }, 24 25 /** 26 * Gets the ID of the inner window of this DOM window. 27 * 28 * @param nsIDOMWindow window 29 * @return integer|null 30 * Inner ID for the given window, null if we can't access it. 31 */ 32 getInnerWindowId(window) { 33 // Might throw with SecurityError: Permission denied to access property 34 // "windowGlobalChild" on cross-origin object. 35 try { 36 return window.windowGlobalChild.innerWindowId; 37 } catch (e) { 38 return null; 39 } 40 }, 41 42 /** 43 * Recursively gather a list of inner window ids given a 44 * top level window. 45 * 46 * @param nsIDOMWindow window 47 * @return Array 48 * list of inner window ids. 49 */ 50 getInnerWindowIDsForFrames(window) { 51 const innerWindowID = this.getInnerWindowId(window); 52 if (innerWindowID === null) { 53 return []; 54 } 55 56 let ids = [innerWindowID]; 57 58 if (window.frames) { 59 for (let i = 0; i < window.frames.length; i++) { 60 const frame = window.frames[i]; 61 ids = ids.concat(this.getInnerWindowIDsForFrames(frame)); 62 } 63 } 64 65 return ids; 66 }, 67 68 /** 69 * Remove any frames in a stack that are above a debugger-triggered evaluation 70 * and will correspond with devtools server code, which we never want to show 71 * to the user. 72 * 73 * @param array stack 74 * An array of frames, with the topmost first, and each of which has a 75 * 'filename' property. 76 * @return array 77 * An array of stack frames with any devtools server frames removed. 78 * The original array is not modified. 79 */ 80 removeFramesAboveDebuggerEval(stack) { 81 const debuggerEvalFilename = "debugger eval code"; 82 83 // Remove any frames for server code above the last debugger eval frame. 84 const evalIndex = stack.findIndex(({ filename }, idx, arr) => { 85 const nextFrame = arr[idx + 1]; 86 return ( 87 filename == debuggerEvalFilename && 88 (!nextFrame || nextFrame.filename !== debuggerEvalFilename) 89 ); 90 }); 91 if (evalIndex != -1) { 92 return stack.slice(0, evalIndex + 1); 93 } 94 95 // In some cases (e.g. evaluated expression with SyntaxError), we might not have a 96 // "debugger eval code" frame but still have internal ones. If that's the case, we 97 // return null as the end user shouldn't see those frames. 98 if ( 99 stack.some( 100 ({ filename }) => 101 filename && filename.startsWith("resource://devtools/") 102 ) 103 ) { 104 return null; 105 } 106 107 return stack; 108 }, 109 }; 110 111 exports.WebConsoleUtils = WebConsoleUtils;