index.js (4425B)
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 WorkerDispatcher, 9 } = require("resource://devtools/client/shared/worker-utils.js"); 10 const EventEmitter = require("resource://devtools/shared/event-emitter.js"); 11 const { LocalizationHelper } = require("resource://devtools/shared/l10n.js"); 12 13 const L10N = new LocalizationHelper( 14 "devtools/client/locales/toolbox.properties" 15 ); 16 17 const SOURCE_MAP_WORKER_URL = 18 "resource://devtools/client/shared/source-map-loader/worker.js"; 19 20 const { 21 originalToGeneratedId, 22 generatedToOriginalId, 23 isGeneratedId, 24 isOriginalId, 25 } = require("resource://devtools/client/shared/source-map-loader/utils/index.js"); 26 27 class SourceMapLoader extends WorkerDispatcher { 28 constructor(targetCommand) { 29 super(SOURCE_MAP_WORKER_URL); 30 this.#targetCommand = targetCommand; 31 } 32 33 #setSourceMapForGeneratedSources = this.task( 34 "setSourceMapForGeneratedSources" 35 ); 36 #getOriginalURLs = this.task("getOriginalURLs"); 37 #getOriginalSourceText = this.task("getOriginalSourceText"); 38 #targetCommand = null; 39 40 async getOriginalURLs(urlInfo) { 41 try { 42 return await this.#getOriginalURLs(urlInfo); 43 } catch (error) { 44 // Note that tests may not pass the targetCommand 45 if (this.#targetCommand) { 46 // Catch all errors and log them to the Web Console for users to see. 47 const message = L10N.getFormatStr( 48 "toolbox.sourceMapFailure", 49 error, 50 urlInfo.url, 51 urlInfo.sourceMapURL 52 ); 53 this.#targetCommand.targetFront.logWarningInPage(message, "source map"); 54 } 55 56 // And re-throw the error so that the debugger can also interpret the error 57 throw error; 58 } 59 } 60 61 hasOriginalURL = this.task("hasOriginalURL"); 62 getOriginalRanges = this.task("getOriginalRanges"); 63 64 getGeneratedRanges = this.task("getGeneratedRanges", { 65 queue: true, 66 }); 67 getGeneratedLocation = this.task("getGeneratedLocation", { 68 queue: true, 69 }); 70 getOriginalLocation = this.task("getOriginalLocation", { 71 queue: true, 72 }); 73 74 getOriginalLocations = this.task("getOriginalLocations"); 75 getGeneratedRangesForOriginal = this.task("getGeneratedRangesForOriginal"); 76 getFileGeneratedRange = this.task("getFileGeneratedRange"); 77 loadSourceMap = this.task("loadSourceMap"); 78 79 async getOriginalSourceText(originalSourceId) { 80 try { 81 return await this.#getOriginalSourceText(originalSourceId); 82 } catch (error) { 83 const message = L10N.getFormatStr( 84 "toolbox.sourceMapSourceFailure", 85 error.message, 86 error.metadata ? error.metadata.url : "<unknown>" 87 ); 88 89 // Note that tests may not pass the targetCommand 90 if (this.#targetCommand) { 91 // Catch all errors and log them to the Web Console for users to see. 92 this.#targetCommand.targetFront.logWarningInPage(message, "source map"); 93 } 94 95 // Also replace the result with the error text. 96 // Note that this result has to have the same form 97 // as whatever the upstream getOriginalSourceText 98 // returns. 99 return { 100 text: message, 101 contentType: "text/plain", 102 }; 103 } 104 } 105 106 clearSourceMaps = this.task("clearSourceMaps"); 107 getOriginalStackFrames = this.task("getOriginalStackFrames"); 108 109 async setSourceMapForGeneratedSources(generatedIds, sourceMap) { 110 const rv = await this.#setSourceMapForGeneratedSources( 111 generatedIds, 112 sourceMap 113 ); 114 115 // Notify and ensure waiting for the SourceMapURLService to process the source map before resolving. 116 // Otherwise tests start failing because of pending request made by this component. 117 await this.emitAsync("source-map-created", generatedIds); 118 119 return rv; 120 } 121 clearSourceMapForGeneratedSources = this.task( 122 "clearSourceMapForGeneratedSources" 123 ); 124 125 destroy() { 126 // Request to stop the underlying DOM Worker 127 this.stop(); 128 // Unregister all listeners 129 this.clearEvents(); 130 // SourceMapLoader may be leaked and so it is important to clear most outer references 131 this.#targetCommand = null; 132 } 133 } 134 EventEmitter.decorate(SourceMapLoader.prototype); 135 136 module.exports = { 137 SourceMapLoader, 138 originalToGeneratedId, 139 generatedToOriginalId, 140 isGeneratedId, 141 isOriginalId, 142 };