diff options
Diffstat (limited to 'devtools/client/debugger/src/utils')
15 files changed, 55 insertions, 321 deletions
diff --git a/devtools/client/debugger/src/utils/bootstrap.js b/devtools/client/debugger/src/utils/bootstrap.js index e8d6de2cf0..e0ee6c35be 100644 --- a/devtools/client/debugger/src/utils/bootstrap.js +++ b/devtools/client/debugger/src/utils/bootstrap.js @@ -42,7 +42,7 @@ export function bootstrapStore(client, workers, panel, initialState) { const createStore = configureStore({ log: prefs.logging || flags.testing, timing: debugJsModules, - makeThunkArgs: (args, state) => { + makeThunkArgs: args => { return { ...args, client, ...workers, panel }; }, }); diff --git a/devtools/client/debugger/src/utils/editor/create-editor.js b/devtools/client/debugger/src/utils/editor/create-editor.js index 6bb280fc4d..74b41ff78b 100644 --- a/devtools/client/debugger/src/utils/editor/create-editor.js +++ b/devtools/client/debugger/src/utils/editor/create-editor.js @@ -5,7 +5,7 @@ import SourceEditor from "devtools/client/shared/sourceeditor/editor"; import { features, prefs } from "../prefs"; -export function createEditor() { +export function createEditor(useCm6 = false) { const gutters = ["breakpoints", "hit-markers", "CodeMirror-linenumbers"]; if (features.codeFolding) { @@ -13,7 +13,8 @@ export function createEditor() { } return new SourceEditor({ - mode: "javascript", + mode: SourceEditor.modes.js, + cm6: useCm6, foldGutter: features.codeFolding, enableCodeFolding: features.codeFolding, readOnly: true, diff --git a/devtools/client/debugger/src/utils/editor/index.js b/devtools/client/debugger/src/utils/editor/index.js index 1adc73b4f8..d12e2f29f1 100644 --- a/devtools/client/debugger/src/utils/editor/index.js +++ b/devtools/client/debugger/src/utils/editor/index.js @@ -14,12 +14,12 @@ import { createLocation } from "../location"; let editor; -export function getEditor() { +export function getEditor(useCm6) { if (editor) { return editor; } - editor = createEditor(); + editor = createEditor(useCm6); return editor; } @@ -27,6 +27,16 @@ export function removeEditor() { editor = null; } +/** + * Update line wrapping for the codemirror editor. + */ +export function updateEditorLineWrapping(value) { + if (!editor) { + return; + } + editor.setLineWrapping(value); +} + function getCodeMirror() { return editor && editor.hasCodeMirror ? editor.codeMirror : null; } diff --git a/devtools/client/debugger/src/utils/editor/source-documents.js b/devtools/client/debugger/src/utils/editor/source-documents.js index 2ddb0b1965..53ee4f2f35 100644 --- a/devtools/client/debugger/src/utils/editor/source-documents.js +++ b/devtools/client/debugger/src/utils/editor/source-documents.js @@ -35,7 +35,7 @@ export function clearDocumentsForSources(sources) { } } -function resetLineNumberFormat(editor) { +export function resetLineNumberFormat(editor) { const cm = editor.codeMirror; cm.setOption("lineNumberFormatter", number => number); resizeBreakpointGutter(cm); @@ -54,59 +54,6 @@ function updateLineNumberFormat(editor, sourceId) { resizeToggleButton(cm); } -export function updateDocument(editor, source) { - if (!source) { - return; - } - - const sourceId = source.id; - const doc = getDocument(sourceId) || editor.createDocument(); - editor.replaceDocument(doc); - - updateLineNumberFormat(editor, sourceId); -} - -/* used to apply the context menu wrap line option change to all the docs */ -export function updateDocuments(updater) { - for (const doc of sourceDocs.values()) { - if (doc.cm == null) { - continue; - } else { - updater(doc); - } - } -} - -export function clearEditor(editor) { - const doc = editor.createDocument("", { name: "text" }); - editor.replaceDocument(doc); - resetLineNumberFormat(editor); -} - -export function showLoading(editor) { - // Create the "loading message" document only once - let doc = getDocument("loading"); - if (!doc) { - doc = editor.createDocument(L10N.getStr("loadingText"), { name: "text" }); - setDocument("loading", doc); - } - // `createDocument` won't be used right away in the editor, we still need to - // explicitely update it - editor.replaceDocument(doc); -} - -export function showErrorMessage(editor, msg) { - let error; - if (msg.includes("WebAssembly binary source is not available")) { - error = L10N.getStr("wasmIsNotAvailable"); - } else { - error = L10N.getFormatStr("errorLoadingText3", msg); - } - const doc = editor.createDocument(error, { name: "text" }); - editor.replaceDocument(doc); - resetLineNumberFormat(editor); -} - const contentTypeModeMap = new Map([ ["text/javascript", { name: "javascript" }], ["text/typescript", { name: "javascript", typescript: true }], diff --git a/devtools/client/debugger/src/utils/editor/source-search.js b/devtools/client/debugger/src/utils/editor/source-search.js index 92097377ba..2316cd2ccb 100644 --- a/devtools/client/debugger/src/utils/editor/source-search.js +++ b/devtools/client/debugger/src/utils/editor/source-search.js @@ -27,7 +27,7 @@ function SearchState() { * @memberof utils/source-search * @static */ -function getSearchState(cm, query) { +function getSearchState(cm) { const state = cm.state.search || (cm.state.search = new SearchState()); return state; } @@ -55,7 +55,7 @@ function searchOverlay(query, modifiers) { }); return { - token: function (stream, state) { + token(stream) { // set the last index to be the current stream position // this acts as an offset regexQuery.lastIndex = stream.pos; @@ -141,11 +141,11 @@ function doSearch( return cm.operation(function () { if (!query || isWhitespace(query)) { - clearSearch(cm, query); + clearSearch(cm); return null; } - const state = getSearchState(cm, query); + const state = getSearchState(cm); const isNewQuery = state.query !== query; state.query = query; @@ -179,7 +179,7 @@ export function searchSourceForHighlight( } cm.operation(function () { - const state = getSearchState(cm, query); + const state = getSearchState(cm); const isNewQuery = state.query !== query; state.query = query; @@ -207,7 +207,7 @@ function searchNext(ctx, rev, query, newQuery, modifiers) { const { cm } = ctx; let nextMatch; cm.operation(function () { - const state = getSearchState(cm, query); + const state = getSearchState(cm); const pos = getCursorPos(newQuery, rev, state); if (!state.query) { @@ -261,8 +261,8 @@ function findNextOnLine(ctx, rev, query, newQuery, modifiers, line, ch) { * @memberof utils/source-search * @static */ -export function removeOverlay(ctx, query) { - const state = getSearchState(ctx.cm, query); +export function removeOverlay(ctx) { + const state = getSearchState(ctx.cm); ctx.cm.removeOverlay(state.overlay); const { line, ch } = ctx.cm.getCursor(); ctx.cm.doc.setSelection({ line, ch }, { line, ch }, { scroll: false }); @@ -274,8 +274,8 @@ export function removeOverlay(ctx, query) { * @memberof utils/source-search * @static */ -export function clearSearch(cm, query) { - const state = getSearchState(cm, query); +export function clearSearch(cm) { + const state = getSearchState(cm); state.results = []; @@ -293,7 +293,7 @@ export function clearSearch(cm, query) { * @static */ export function find(ctx, query, keepSelection, modifiers, focusFirstResult) { - clearSearch(ctx.cm, query); + clearSearch(ctx.cm); return doSearch( ctx, false, diff --git a/devtools/client/debugger/src/utils/editor/tests/__snapshots__/create-editor.spec.js.snap b/devtools/client/debugger/src/utils/editor/tests/__snapshots__/create-editor.spec.js.snap Binary files differindex 843647731b..5c47ed94c7 100644 --- a/devtools/client/debugger/src/utils/editor/tests/__snapshots__/create-editor.spec.js.snap +++ b/devtools/client/debugger/src/utils/editor/tests/__snapshots__/create-editor.spec.js.snap diff --git a/devtools/client/debugger/src/utils/moz.build b/devtools/client/debugger/src/utils/moz.build index 8deb8e18db..742f96e060 100644 --- a/devtools/client/debugger/src/utils/moz.build +++ b/devtools/client/debugger/src/utils/moz.build @@ -42,7 +42,6 @@ CompiledModules( "source-queue.js", "source.js", "tabs.js", - "task.js", "telemetry.js", "text.js", "ui.js", diff --git a/devtools/client/debugger/src/utils/quick-open.js b/devtools/client/debugger/src/utils/quick-open.js index e2624559bc..f51d1c6ac7 100644 --- a/devtools/client/debugger/src/utils/quick-open.js +++ b/devtools/client/debugger/src/utils/quick-open.js @@ -3,12 +3,7 @@ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */ import { endTruncateStr } from "./utils"; -import { - getFilename, - getSourceClassnames, - getSourceQueryString, - getRelativeUrl, -} from "./source"; +import { getSourceClassnames, getRelativeUrl } from "./source"; export const MODIFIERS = { "@": "functions", @@ -62,16 +57,15 @@ export function formatSourceForList( isBlackBoxed, projectDirectoryRoot ) { - const title = getFilename(source); const relativeUrlWithQuery = `${getRelativeUrl( source, projectDirectoryRoot - )}${getSourceQueryString(source) || ""}`; + )}${source.displayURL.search || ""}`; const subtitle = endTruncateStr(relativeUrlWithQuery, 100); const value = relativeUrlWithQuery; return { value, - title, + title: source.shortName, subtitle, icon: hasTabOpened ? "tab result-item-icon" diff --git a/devtools/client/debugger/src/utils/source.js b/devtools/client/debugger/src/utils/source.js index 31920453eb..91a02778e2 100644 --- a/devtools/client/debugger/src/utils/source.js +++ b/devtools/client/debugger/src/utils/source.js @@ -17,7 +17,6 @@ const { import { getRelativePath } from "../utils/sources-tree/utils"; import { endTruncateStr } from "./utils"; import { truncateMiddleText } from "../utils/text"; -import { parse as parseURL } from "../utils/url"; import { memoizeLast } from "../utils/memoizeLast"; import { renderWasmText } from "./wasm"; import { toEditorLine } from "./editor/index"; @@ -214,33 +213,10 @@ export function getFormattedSourceId(id) { } /** - * Gets a readable filename from a source URL for display purposes. - * If the source does not have a URL, the source ID will be returned instead. - * - * @memberof utils/source - * @static - */ -export function getFilename( - source, - rawSourceURL = getRawSourceURL(source.url) -) { - const { id } = source; - if (!rawSourceURL) { - return getFormattedSourceId(id); - } - - const { filename } = source.displayURL; - return getRawSourceURL(filename); -} - -/** - * Provides a middle-trunated filename - * - * @memberof utils/source - * @static + * Provides a middle-truncated filename displayed in Tab titles */ -export function getTruncatedFileName(source, querystring = "", length = 30) { - return truncateMiddleText(`${getFilename(source)}${querystring}`, length); +export function getTruncatedFileName(source) { + return truncateMiddleText(source.longName, 30); } /* Gets path for files with same filename for editor tabs, breakpoints, etc. @@ -252,15 +228,13 @@ export function getTruncatedFileName(source, querystring = "", length = 30) { export function getDisplayPath(mySource, sources) { const rawSourceURL = getRawSourceURL(mySource.url); - const filename = getFilename(mySource, rawSourceURL); + const filename = mySource.shortName; // Find sources that have the same filename, but different paths // as the original source const similarSources = sources.filter(source => { const rawSource = getRawSourceURL(source.url); - return ( - rawSourceURL != rawSource && filename == getFilename(source, rawSource) - ); + return rawSourceURL != rawSource && filename == source.shortName; }); if (!similarSources.length) { @@ -314,16 +288,6 @@ export function getFileURL(source, truncate = true) { return resolveFileURL(url, getUnicodeUrl, truncate); } -export function getSourcePath(url) { - if (!url) { - return ""; - } - - const { path, href } = parseURL(url); - // for URLs like "about:home" the path is null so we pass the full href - return path || href; -} - /** * Returns amount of lines in the source. If source is a WebAssembly binary, * the function returns amount of bytes. @@ -345,10 +309,6 @@ export function getSourceLineCount(content) { return count + 1; } -export function isInlineScript(source) { - return source.introductionType === "scriptElement"; -} - function getNthLine(str, lineNum) { let startIndex = -1; @@ -454,51 +414,6 @@ export function getRelativeUrl(source, root) { return url.slice(url.indexOf(root) + root.length + 1); } -/** - * source.url doesn't include thread actor ID, so before calling underRoot(), the thread actor ID - * must be removed from the root, which this function handles. - * @param {string} root The root url to be cleaned - * @param {Set<Thread>} threads The list of threads - * @returns {string} The root url with thread actor IDs removed - */ -export function removeThreadActorId(root, threads) { - threads.forEach(thread => { - if (root.includes(thread.actor)) { - root = root.slice(thread.actor.length + 1); - } - }); - return root; -} - -/** - * Checks if the source is descendant of the root identified by the - * root url specified. The root might likely be projectDirectoryRoot which - * is a defined by a pref that allows users restrict the source tree to - * a subset of sources. - * - * @param {Object} source - * The source object - * @param {String} rootUrlWithoutThreadActor - * The url for the root node, without the thread actor ID. This can be obtained - * by calling removeThreadActorId() - */ -export function isDescendantOfRoot(source, rootUrlWithoutThreadActor) { - if (source.url && source.url.includes("chrome://")) { - const { group, path } = source.displayURL; - return (group + path).includes(rootUrlWithoutThreadActor); - } - - return !!source.url && source.url.includes(rootUrlWithoutThreadActor); -} - -export function getSourceQueryString(source) { - if (!source) { - return ""; - } - - return parseURL(getRawSourceURL(source.url)).search; -} - export function isUrlExtension(url) { return url.includes("moz-extension:") || url.includes("chrome-extension"); } diff --git a/devtools/client/debugger/src/utils/sources-tree/getURL.js b/devtools/client/debugger/src/utils/sources-tree/getURL.js index c01fce5f23..5c9e7db6e5 100644 --- a/devtools/client/debugger/src/utils/sources-tree/getURL.js +++ b/devtools/client/debugger/src/utils/sources-tree/getURL.js @@ -56,6 +56,9 @@ const def = { * This is augmented with custom properties like: * - `group`, which is mostly the host of the source's URL. * This is used to sort sources in the Source tree. + * - `filename` which may not be quite matching the URL. + * When files are loaded from "/", they won't have a real name, + * but instead this will report "(index)". * - `fileExtension`, lowercased file extension of the source * (if any extension is available) * - `path` and `pathname` have some special behavior. @@ -66,8 +69,14 @@ export function getDisplayURL(url, extensionName = null) { return def; } - const { pathname, search, protocol, host } = parse(url); - const filename = getUnicodeUrlPath(getFilenameFromPath(pathname)); + let { pathname, search, protocol, host } = parse(url); + + // Decode encoded characters early so that all other code rely on decoded strings + pathname = getUnicodeUrlPath(pathname); + search = getUnicodeUrlPath(search); + host = getUnicodeHostname(host); + + const filename = getFilenameFromPath(pathname); switch (protocol) { case "javascript:": @@ -121,7 +130,7 @@ export function getDisplayURL(url, extensionName = null) { search, filename, fileExtension: getFileExtension("/"), - group: url, + group: getUnicodeUrlPath(url), }; case "data:": @@ -165,7 +174,7 @@ export function getDisplayURL(url, extensionName = null) { search, filename, fileExtension: getFileExtension(pathname), - group: getUnicodeHostname(host), + group: host, }; } diff --git a/devtools/client/debugger/src/utils/sources-tree/utils.js b/devtools/client/debugger/src/utils/sources-tree/utils.js index 0a2f41752b..45eba2d817 100644 --- a/devtools/client/debugger/src/utils/sources-tree/utils.js +++ b/devtools/client/debugger/src/utils/sources-tree/utils.js @@ -28,17 +28,3 @@ export function getRelativePath(url) { } return ""; } - -/** - * - * @param {String} name: Name (e.g. computed in SourcesTreeItem renderItemName), - * which might include URI search. - * @returns {String} result of `decodedURI(name)`, or name if it `name` is malformed. - */ -export function safeDecodeItemName(name) { - try { - return decodeURI(name); - } catch (e) { - return name; - } -} diff --git a/devtools/client/debugger/src/utils/task.js b/devtools/client/debugger/src/utils/task.js deleted file mode 100644 index 25663fdd16..0000000000 --- a/devtools/client/debugger/src/utils/task.js +++ /dev/null @@ -1,44 +0,0 @@ -/* 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/>. */ - -/** - * This object provides the public module functions. - */ -export const Task = { - // XXX: Not sure if this works in all cases... - async: function (task) { - return function () { - return Task.spawn(task, this, arguments); - }; - }, - - /** - * Creates and starts a new task. - * @param task A generator function - * @return A promise, resolved when the task terminates - */ - spawn: function (task, scope, args) { - return new Promise(function (resolve, reject) { - const iterator = task.apply(scope, args); - - const callNext = lastValue => { - const iteration = iterator.next(lastValue); - Promise.resolve(iteration.value) - .then(value => { - if (iteration.done) { - resolve(value); - } else { - callNext(value); - } - }) - .catch(error => { - reject(error); - iterator.throw(error); - }); - }; - - callNext(undefined); - }); - }, -}; diff --git a/devtools/client/debugger/src/utils/test-head.js b/devtools/client/debugger/src/utils/test-head.js index c21f408b61..1021849d02 100644 --- a/devtools/client/debugger/src/utils/test-head.js +++ b/devtools/client/debugger/src/utils/test-head.js @@ -101,10 +101,11 @@ function makeFrame({ id, sourceId, thread }, opts = {}) { }; } -function createSourceObject(filename, props = {}) { +function createSourceObject(filename) { return { id: filename, url: makeSourceURL(filename), + shortName: filename, isPrettyPrinted: false, isExtension: false, isOriginal: filename.includes("originalSource"), diff --git a/devtools/client/debugger/src/utils/test-mockup.js b/devtools/client/debugger/src/utils/test-mockup.js index 521872b7cb..8224050f6a 100644 --- a/devtools/client/debugger/src/utils/test-mockup.js +++ b/devtools/client/debugger/src/utils/test-mockup.js @@ -20,6 +20,8 @@ function makeMockSource(url = "url", id = "source", thread = "FakeThread") { return { id, url, + shortName: getDisplayURL(url).filename, + longName: getDisplayURL(url).filename + getDisplayURL(url).search, displayURL: getDisplayURL(url), thread, isPrettyPrinted: false, diff --git a/devtools/client/debugger/src/utils/tests/source.spec.js b/devtools/client/debugger/src/utils/tests/source.spec.js index 484c8ce570..6542ee2c0d 100644 --- a/devtools/client/debugger/src/utils/tests/source.spec.js +++ b/devtools/client/debugger/src/utils/tests/source.spec.js @@ -3,14 +3,11 @@ * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */ import { - getFilename, getTruncatedFileName, getFileURL, getDisplayPath, getSourceLineCount, isJavaScript, - isDescendantOfRoot, - removeThreadActorId, isUrlExtension, getLineText, } from "../source.js"; @@ -20,7 +17,6 @@ import { makeMockSourceWithContent, makeMockSourceAndContent, makeMockWasmSourceWithContent, - makeMockThread, makeFullfilledMockSourceContent, } from "../test-mockup"; import { isFulfilled } from "../async-value.js"; @@ -29,66 +25,20 @@ describe("sources", () => { const unicode = "\u6e2c"; const encodedUnicode = encodeURIComponent(unicode); - describe("getFilename", () => { - it("should give us a default of (index)", () => { - expect( - getFilename(makeMockSource("http://localhost.com:7999/increment/")) - ).toBe("(index)"); - }); - it("should give us the filename", () => { - expect( - getFilename( - makeMockSource("http://localhost.com:7999/increment/hello.html") - ) - ).toBe("hello.html"); - }); - it("should give us the readable Unicode filename if encoded", () => { - expect( - getFilename( - makeMockSource( - `http://localhost.com:7999/increment/${encodedUnicode}.html` - ) - ) - ).toBe(`${unicode}.html`); - }); - it("should give us the filename excluding the query strings", () => { - expect( - getFilename( - makeMockSource( - "http://localhost.com:7999/increment/hello.html?query_strings" - ) - ) - ).toBe("hello.html"); - }); - it("should give us the proper filename for pretty files", () => { - expect( - getFilename( - makeMockSource( - "http://localhost.com:7999/increment/hello.html:formatted" - ) - ) - ).toBe("hello.html"); - }); - }); - describe("getTruncatedFileName", () => { it("should truncate the file name when it is more than 30 chars", () => { expect( getTruncatedFileName( makeMockSource( "really-really-really-really-really-really-long-name.html" - ), - "", - 30 + ) ) ).toBe("really-really…long-name.html"); }); it("should first decode the filename and then truncate it", () => { expect( getTruncatedFileName( - makeMockSource(`${encodedUnicode.repeat(30)}.html`), - "", - 30 + makeMockSource(`${encodedUnicode.repeat(30)}.html`) ) ).toBe("測測測測測測測測測測測測測…測測測測測測測測測.html"); }); @@ -274,42 +224,6 @@ describe("sources", () => { }); }); - describe("isDescendantOfRoot", () => { - const threads = [ - makeMockThread({ actor: "server0.conn1.child1/thread19" }), - ]; - - it("should detect normal source urls", () => { - const source = makeMockSource( - "resource://activity-stream/vendor/react.js" - ); - const rootWithoutThreadActor = removeThreadActorId( - "resource://activity-stream", - threads - ); - expect(isDescendantOfRoot(source, rootWithoutThreadActor)).toBe(true); - }); - - it("should detect source urls under chrome:// as root", () => { - const source = makeMockSource( - "chrome://browser/content/contentSearchUI.js" - ); - const rootWithoutThreadActor = removeThreadActorId("chrome://", threads); - expect(isDescendantOfRoot(source, rootWithoutThreadActor)).toBe(true); - }); - - it("should detect source urls if root is a thread actor Id", () => { - const source = makeMockSource( - "resource://activity-stream/vendor/react-dom.js" - ); - const rootWithoutThreadActor = removeThreadActorId( - "server0.conn1.child1/thread19", - threads - ); - expect(isDescendantOfRoot(source, rootWithoutThreadActor)).toBe(true); - }); - }); - describe("isUrlExtension", () => { it("should detect mozilla extension", () => { expect(isUrlExtension("moz-extension://id/js/content.js")).toBe(true); |