diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /devtools/client/shared/view-source.js | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/client/shared/view-source.js')
-rw-r--r-- | devtools/client/shared/view-source.js | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/devtools/client/shared/view-source.js b/devtools/client/shared/view-source.js new file mode 100644 index 0000000000..731c4b0cd5 --- /dev/null +++ b/devtools/client/shared/view-source.js @@ -0,0 +1,227 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +/** + * Tries to open a Stylesheet file in the Style Editor. If the file is not + * found, it is opened in source view instead. + * Returns a promise resolving to a boolean indicating whether or not + * the source was able to be displayed in the StyleEditor, as the built-in + * Firefox View Source is the fallback. + * + * @param {Toolbox} toolbox + * @param {string} sourceURL + * @param {number} sourceLine + * + * @return {Promise<boolean>} + */ +exports.viewSourceInStyleEditor = async function( + toolbox, + stylesheetFrontOrGeneratedURL, + generatedLine, + generatedColumn +) { + const panel = await toolbox.loadTool("styleeditor"); + + let stylesheetFront; + if (typeof stylesheetFrontOrGeneratedURL === "string") { + stylesheetFront = panel.getStylesheetFrontForGeneratedURL( + stylesheetFrontOrGeneratedURL + ); + } else { + stylesheetFront = stylesheetFrontOrGeneratedURL; + } + + const originalLocation = stylesheetFront + ? await getOriginalLocation( + toolbox, + stylesheetFront.resourceId, + generatedLine, + generatedColumn + ) + : null; + + try { + if (originalLocation) { + await panel.selectOriginalSheet( + originalLocation.sourceId, + originalLocation.line, + originalLocation.column + ); + await toolbox.selectTool("styleeditor"); + return true; + } else if (stylesheetFront) { + await panel.selectStyleSheet( + stylesheetFront, + generatedLine, + generatedColumn + ); + await toolbox.selectTool("styleeditor"); + return true; + } + } catch (e) { + console.error("Failed to view source in style editor", e); + } + + exports.viewSource( + toolbox, + typeof stylesheetFrontOrGeneratedURL === "string" + ? stylesheetFrontOrGeneratedURL + : stylesheetFrontOrGeneratedURL.href || + stylesheetFrontOrGeneratedURL.nodeHref, + generatedLine + ); + return false; +}; + +/** + * Tries to open a JavaScript file in the Debugger. If the file is not found, + * it is opened in source view instead. Either the source URL or source actor ID + * can be specified. If both are specified, the source actor ID is used. + * + * Returns a promise resolving to a boolean indicating whether or not + * the source was able to be displayed in the Debugger, as the built-in Firefox + * View Source is the fallback. + * + * @param {Toolbox} toolbox + * @param {string} sourceURL + * @param {number} sourceLine + * @param {number} sourceColumn + * @param {string} sourceID + * @param {(string|object)} [reason=unknown] + * + * @return {Promise<boolean>} + */ +exports.viewSourceInDebugger = async function( + toolbox, + generatedURL, + generatedLine, + generatedColumn, + sourceActorId, + reason = "unknown" +) { + const location = await getViewSourceInDebuggerLocation( + toolbox, + generatedURL, + generatedLine, + generatedColumn, + sourceActorId + ); + + if (location) { + const { id, line, column } = location; + + const dbg = await toolbox.selectTool("jsdebugger", reason); + try { + await dbg.selectSource(id, line, column); + return true; + } catch (err) { + console.error("Failed to view source in debugger", err); + } + } + + exports.viewSource(toolbox, generatedURL, generatedLine); + return false; +}; + +async function getViewSourceInDebuggerLocation( + toolbox, + generatedURL, + generatedLine, + generatedColumn, + sourceActorId +) { + const dbg = await toolbox.loadTool("jsdebugger"); + + const generatedSource = sourceActorId + ? dbg.getSourceByActorId(sourceActorId) + : dbg.getSourceByURL(generatedURL); + if ( + !generatedSource || + // Note: We're not entirely sure when this can happen, so we may want + // to revisit that at some point. + dbg.getSourceActorsForSource(generatedSource.id).length === 0 + ) { + return null; + } + + const generatedLocation = { + id: generatedSource.id, + line: generatedLine, + column: generatedColumn, + }; + + const originalLocation = await getOriginalLocation( + toolbox, + generatedLocation.id, + generatedLocation.line, + generatedLocation.column + ); + + if (!originalLocation) { + return generatedLocation; + } + + const originalSource = dbg.getSource(originalLocation.sourceId); + + if (!originalSource) { + return generatedLocation; + } + + return { + id: originalSource.id, + line: originalLocation.line, + column: originalLocation.column, + }; +} + +async function getOriginalLocation( + toolbox, + generatedID, + generatedLine, + generatedColumn +) { + // If there is no line number, then there's no chance that we'll get back + // a useful original location. + if (typeof generatedLine !== "number") { + return null; + } + + let originalLocation = null; + try { + originalLocation = await toolbox.sourceMapService.getOriginalLocation({ + sourceId: generatedID, + line: generatedLine, + column: generatedColumn, + }); + if (originalLocation && originalLocation.sourceId === generatedID) { + originalLocation = null; + } + } catch (err) { + console.error( + "Failed to resolve sourcemapped location for the given source location", + { generatedID, generatedLine, generatedColumn }, + err + ); + } + return originalLocation; +} + +/** + * Open a link in Firefox's View Source. + * + * @param {Toolbox} toolbox + * @param {string} sourceURL + * @param {number} sourceLine + * + * @return {Promise} + */ +exports.viewSource = async function(toolbox, sourceURL, sourceLine) { + const utils = toolbox.gViewSourceUtils; + utils.viewSource({ + URL: sourceURL, + lineNumber: sourceLine || 0, + }); +}; |