From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- devtools/server/actors/utils/TabSources.js | 833 +++++++++++++++ .../server/actors/utils/actor-registry-utils.js | 78 ++ devtools/server/actors/utils/audionodes.json | 113 +++ .../server/actors/utils/automation-timeline.js | 373 +++++++ devtools/server/actors/utils/css-grid-utils.js | 61 ++ devtools/server/actors/utils/make-debugger.js | 101 ++ .../server/actors/utils/map-uri-to-addon-id.js | 44 + devtools/server/actors/utils/moz.build | 19 + devtools/server/actors/utils/stack.js | 185 ++++ devtools/server/actors/utils/walker-search.js | 278 +++++ devtools/server/actors/utils/webconsole-utils.js | 1063 ++++++++++++++++++++ .../server/actors/utils/webconsole-worker-utils.js | 20 + 12 files changed, 3168 insertions(+) create mode 100644 devtools/server/actors/utils/TabSources.js create mode 100644 devtools/server/actors/utils/actor-registry-utils.js create mode 100644 devtools/server/actors/utils/audionodes.json create mode 100644 devtools/server/actors/utils/automation-timeline.js create mode 100644 devtools/server/actors/utils/css-grid-utils.js create mode 100644 devtools/server/actors/utils/make-debugger.js create mode 100644 devtools/server/actors/utils/map-uri-to-addon-id.js create mode 100644 devtools/server/actors/utils/moz.build create mode 100644 devtools/server/actors/utils/stack.js create mode 100644 devtools/server/actors/utils/walker-search.js create mode 100644 devtools/server/actors/utils/webconsole-utils.js create mode 100644 devtools/server/actors/utils/webconsole-worker-utils.js (limited to 'devtools/server/actors/utils') diff --git a/devtools/server/actors/utils/TabSources.js b/devtools/server/actors/utils/TabSources.js new file mode 100644 index 000000000..56e862939 --- /dev/null +++ b/devtools/server/actors/utils/TabSources.js @@ -0,0 +1,833 @@ +/* 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"; + +const { Ci, Cu } = require("chrome"); +const DevToolsUtils = require("devtools/shared/DevToolsUtils"); +const { assert, fetch } = DevToolsUtils; +const EventEmitter = require("devtools/shared/event-emitter"); +const { OriginalLocation, GeneratedLocation } = require("devtools/server/actors/common"); +const { resolve } = require("promise"); +const { joinURI } = require("devtools/shared/path"); + +loader.lazyRequireGetter(this, "SourceActor", "devtools/server/actors/source", true); +loader.lazyRequireGetter(this, "isEvalSource", "devtools/server/actors/source", true); +loader.lazyRequireGetter(this, "SourceMapConsumer", "source-map", true); +loader.lazyRequireGetter(this, "SourceMapGenerator", "source-map", true); + +/** + * Manages the sources for a thread. Handles source maps, locations in the + * sources, etc for ThreadActors. + */ +function TabSources(threadActor, allowSourceFn = () => true) { + EventEmitter.decorate(this); + + this._thread = threadActor; + this._useSourceMaps = true; + this._autoBlackBox = true; + this._anonSourceMapId = 1; + this.allowSource = source => { + return !isHiddenSource(source) && allowSourceFn(source); + }; + + this.blackBoxedSources = new Set(); + this.prettyPrintedSources = new Map(); + this.neverAutoBlackBoxSources = new Set(); + + // generated Debugger.Source -> promise of SourceMapConsumer + this._sourceMaps = new Map(); + // sourceMapURL -> promise of SourceMapConsumer + this._sourceMapCache = Object.create(null); + // Debugger.Source -> SourceActor + this._sourceActors = new Map(); + // url -> SourceActor + this._sourceMappedSourceActors = Object.create(null); +} + +/** + * Matches strings of the form "foo.min.js" or "foo-min.js", etc. If the regular + * expression matches, we can be fairly sure that the source is minified, and + * treat it as such. + */ +const MINIFIED_SOURCE_REGEXP = /\bmin\.js$/; + +TabSources.prototype = { + /** + * Update preferences and clear out existing sources + */ + setOptions: function (options) { + let shouldReset = false; + + if ("useSourceMaps" in options) { + shouldReset = true; + this._useSourceMaps = options.useSourceMaps; + } + + if ("autoBlackBox" in options) { + shouldReset = true; + this._autoBlackBox = options.autoBlackBox; + } + + if (shouldReset) { + this.reset(); + } + }, + + /** + * Clear existing sources so they are recreated on the next access. + * + * @param Object opts + * Specify { sourceMaps: true } if you also want to clear + * the source map cache (usually done on reload). + */ + reset: function (opts = {}) { + this._sourceActors = new Map(); + this._sourceMaps = new Map(); + this._sourceMappedSourceActors = Object.create(null); + + if (opts.sourceMaps) { + this._sourceMapCache = Object.create(null); + } + }, + + /** + * Return the source actor representing the `source` (or + * `originalUrl`), creating one if none exists already. May return + * null if the source is disallowed. + * + * @param Debugger.Source source + * The source to make an actor for + * @param String originalUrl + * The original source URL of a sourcemapped source + * @param optional Debguger.Source generatedSource + * The generated source that introduced this source via source map, + * if any. + * @param optional String contentType + * The content type of the source, if immediately available. + * @returns a SourceActor representing the source or null. + */ + source: function ({ source, originalUrl, generatedSource, + isInlineSource, contentType }) { + assert(source || (originalUrl && generatedSource), + "TabSources.prototype.source needs an originalUrl or a source"); + + if (source) { + // If a source is passed, we are creating an actor for a real + // source, which may or may not be sourcemapped. + + if (!this.allowSource(source)) { + return null; + } + + // It's a hack, but inline HTML scripts each have real sources, + // but we want to represent all of them as one source as the + // HTML page. The actor representing this fake HTML source is + // stored in this array, which always has a URL, so check it + // first. + if (source.url in this._sourceMappedSourceActors) { + return this._sourceMappedSourceActors[source.url]; + } + + if (isInlineSource) { + // If it's an inline source, the fake HTML source hasn't been + // created yet (would have returned above), so flip this source + // into a sourcemapped state by giving it an `originalUrl` which + // is the HTML url. + originalUrl = source.url; + source = null; + } + else if (this._sourceActors.has(source)) { + return this._sourceActors.get(source); + } + } + else if (originalUrl) { + // Not all "original" scripts are distinctly separate from the + // generated script. Pretty-printed sources have a sourcemap for + // themselves, so we need to make sure there a real source + // doesn't already exist with this URL. + for (let [source, actor] of this._sourceActors) { + if (source.url === originalUrl) { + return actor; + } + } + + if (originalUrl in this._sourceMappedSourceActors) { + return this._sourceMappedSourceActors[originalUrl]; + } + } + + let actor = new SourceActor({ + thread: this._thread, + source: source, + originalUrl: originalUrl, + generatedSource: generatedSource, + isInlineSource: isInlineSource, + contentType: contentType + }); + + let sourceActorStore = this._thread.sourceActorStore; + var id = sourceActorStore.getReusableActorId(source, originalUrl); + if (id) { + actor.actorID = id; + } + + this._thread.threadLifetimePool.addActor(actor); + sourceActorStore.setReusableActorId(source, originalUrl, actor.actorID); + + if (this._autoBlackBox && + !this.neverAutoBlackBoxSources.has(actor.url) && + this._isMinifiedURL(actor.url)) { + + this.blackBox(actor.url); + this.neverAutoBlackBoxSources.add(actor.url); + } + + if (source) { + this._sourceActors.set(source, actor); + } + else { + this._sourceMappedSourceActors[originalUrl] = actor; + } + + this._emitNewSource(actor); + return actor; + }, + + _emitNewSource: function (actor) { + if (!actor.source) { + // Always notify if we don't have a source because that means + // it's something that has been sourcemapped, or it represents + // the HTML file that contains inline sources. + this.emit("newSource", actor); + } + else { + // If sourcemapping is enabled and a source has sourcemaps, we + // create `SourceActor` instances for both the original and + // generated sources. The source actors for the generated + // sources are only for internal use, however; breakpoints are + // managed by these internal actors. We only want to notify the + // user of the original sources though, so if the actor has a + // `Debugger.Source` instance and a valid source map (meaning + // it's a generated source), don't send the notification. + this.fetchSourceMap(actor.source).then(map => { + if (!map) { + this.emit("newSource", actor); + } + }); + } + }, + + getSourceActor: function (source) { + if (source.url in this._sourceMappedSourceActors) { + return this._sourceMappedSourceActors[source.url]; + } + + if (this._sourceActors.has(source)) { + return this._sourceActors.get(source); + } + + throw new Error("getSource: could not find source actor for " + + (source.url || "source")); + }, + + getSourceActorByURL: function (url) { + if (url) { + for (let [source, actor] of this._sourceActors) { + if (source.url === url) { + return actor; + } + } + + if (url in this._sourceMappedSourceActors) { + return this._sourceMappedSourceActors[url]; + } + } + + throw new Error("getSourceActorByURL: could not find source for " + url); + return null; + }, + + /** + * Returns true if the URL likely points to a minified resource, false + * otherwise. + * + * @param String aURL + * The URL to test. + * @returns Boolean + */ + _isMinifiedURL: function (aURL) { + if (!aURL) { + return false; + } + + try { + let url = new URL(aURL); + let pathname = url.pathname; + return MINIFIED_SOURCE_REGEXP.test(pathname.slice(pathname.lastIndexOf("/") + 1)); + } catch (e) { + // Not a valid URL so don't try to parse out the filename, just test the + // whole thing with the minified source regexp. + return MINIFIED_SOURCE_REGEXP.test(aURL); + } + }, + + /** + * Create a source actor representing this source. This ignores + * source mapping and always returns an actor representing this real + * source. Use `createSourceActors` if you want to respect source maps. + * + * @param Debugger.Source aSource + * The source instance to create an actor for. + * @returns SourceActor + */ + createNonSourceMappedActor: function (aSource) { + // Don't use getSourceURL because we don't want to consider the + // displayURL property if it's an eval source. We only want to + // consider real URLs, otherwise if there is a URL but it's + // invalid the code below will not set the content type, and we + // will later try to fetch the contents of the URL to figure out + // the content type, but it's a made up URL for eval sources. + let url = isEvalSource(aSource) ? null : aSource.url; + let spec = { source: aSource }; + + // XXX bug 915433: We can't rely on Debugger.Source.prototype.text + // if the source is an HTML-embedded