mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-10 05:35:05 +08:00
Move and rename files. NOAUTOREVERT=true NOPRESUBMIT=true NOTREECHECKS=true Bug: 768828 TBR=darin@chromium.org NOTRY=true Change-Id: I66d3b155808bc5bdbf237b80208e1e552bcf7f28 Reviewed-on: https://chromium-review.googlesource.com/1001153 Reviewed-by: Blink Reformat <blink-reformat@chromium.org> Commit-Queue: Blink Reformat <blink-reformat@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#549061} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: 0aee4434a4dba42a42abaea9bfbc0cd196a63bc1
257 lines
8.9 KiB
JavaScript
257 lines
8.9 KiB
JavaScript
// Copyright 2017 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
/**
|
|
* @template T
|
|
*/
|
|
SDK.SourceMapManager = class extends Common.Object {
|
|
/**
|
|
* @param {!SDK.Target} target
|
|
*/
|
|
constructor(target) {
|
|
super();
|
|
|
|
this._target = target;
|
|
this._isEnabled = true;
|
|
|
|
/** @type {!Map<!T, string>} */
|
|
this._relativeSourceURL = new Map();
|
|
/** @type {!Map<!T, string>} */
|
|
this._relativeSourceMapURL = new Map();
|
|
/** @type {!Map<!T, string>} */
|
|
this._resolvedSourceMapURL = new Map();
|
|
|
|
/** @type {!Map<string, !SDK.SourceMap>} */
|
|
this._sourceMapByURL = new Map();
|
|
/** @type {!Multimap<string, !T>} */
|
|
this._sourceMapURLToLoadingClients = new Multimap();
|
|
/** @type {!Multimap<string, !T>} */
|
|
this._sourceMapURLToClients = new Multimap();
|
|
|
|
SDK.targetManager.addEventListener(SDK.TargetManager.Events.InspectedURLChanged, this._inspectedURLChanged, this);
|
|
}
|
|
|
|
/**
|
|
* @param {boolean} isEnabled
|
|
*/
|
|
setEnabled(isEnabled) {
|
|
if (isEnabled === this._isEnabled)
|
|
return;
|
|
this._isEnabled = isEnabled;
|
|
const clients = Array.from(this._resolvedSourceMapURL.keys());
|
|
for (const client of clients) {
|
|
const relativeSourceURL = this._relativeSourceURL.get(client);
|
|
const relativeSourceMapURL = this._relativeSourceMapURL.get(client);
|
|
this.detachSourceMap(client);
|
|
this.attachSourceMap(client, relativeSourceURL, relativeSourceMapURL);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {!Common.Event} event
|
|
*/
|
|
_inspectedURLChanged(event) {
|
|
if (event.data !== this._target)
|
|
return;
|
|
|
|
const clients = Array.from(this._resolvedSourceMapURL.keys());
|
|
for (const client of clients) {
|
|
const relativeSourceURL = this._relativeSourceURL.get(client);
|
|
const relativeSourceMapURL = this._relativeSourceMapURL.get(client);
|
|
const resolvedSourceMapURL = this._resolvedSourceMapURL.get(client);
|
|
const sourceMapURL = this._resolveRelativeURLs(relativeSourceURL, relativeSourceMapURL).sourceMapURL;
|
|
if (sourceMapURL !== resolvedSourceMapURL) {
|
|
this.detachSourceMap(client);
|
|
this.attachSourceMap(client, relativeSourceURL, relativeSourceMapURL);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {!T} client
|
|
* @return {?SDK.SourceMap}
|
|
*/
|
|
sourceMapForClient(client) {
|
|
const sourceMapURL = this._resolvedSourceMapURL.get(client);
|
|
return sourceMapURL ? this._sourceMapByURL.get(sourceMapURL) || null : null;
|
|
}
|
|
|
|
/**
|
|
* @param {!SDK.SourceMap} sourceMap
|
|
* @return {!Array<!T>}
|
|
*/
|
|
clientsForSourceMap(sourceMap) {
|
|
if (this._sourceMapURLToClients.has(sourceMap.url()))
|
|
return this._sourceMapURLToClients.get(sourceMap.url()).valuesArray();
|
|
return this._sourceMapURLToLoadingClients.get(sourceMap.url()).valuesArray();
|
|
}
|
|
|
|
/**
|
|
* @param {!SDK.SourceMap.EditResult} editResult
|
|
*/
|
|
applySourceMapEdit(editResult) {
|
|
console.assert(
|
|
this._sourceMapByURL.has(editResult.map.url()), 'Cannot apply edit result for non-existing source map');
|
|
this._sourceMapByURL.set(editResult.map.url(), editResult.map);
|
|
this.dispatchEventToListeners(
|
|
SDK.SourceMapManager.Events.SourceMapChanged, {sourceMap: editResult.map, newSources: editResult.newSources});
|
|
}
|
|
|
|
/**
|
|
* @param {string} sourceURL
|
|
* @param {string} sourceMapURL
|
|
* @return {!{sourceURL: ?string, sourceMapURL: ?string}}
|
|
*/
|
|
_resolveRelativeURLs(sourceURL, sourceMapURL) {
|
|
// |sourceURL| can be a random string, but is generally an absolute path.
|
|
// Complete it to inspected page url for relative links.
|
|
const resolvedSourceURL = Common.ParsedURL.completeURL(this._target.inspectedURL(), sourceURL);
|
|
const resolvedSourceMapURL =
|
|
resolvedSourceURL ? Common.ParsedURL.completeURL(resolvedSourceURL, sourceMapURL) : null;
|
|
return {sourceURL: resolvedSourceURL, sourceMapURL: resolvedSourceMapURL};
|
|
}
|
|
|
|
/**
|
|
* @param {!T} client
|
|
* @param {string} sourceURL
|
|
* @param {?string} sourceMapURL
|
|
*/
|
|
attachSourceMap(client, sourceURL, sourceMapURL) {
|
|
if (!sourceMapURL)
|
|
return;
|
|
console.assert(!this._resolvedSourceMapURL.has(client), 'SourceMap is already attached to client');
|
|
const resolvedURLs = this._resolveRelativeURLs(sourceURL, sourceMapURL);
|
|
if (!resolvedURLs.sourceURL || !resolvedURLs.sourceMapURL)
|
|
return;
|
|
this._relativeSourceURL.set(client, sourceURL);
|
|
this._relativeSourceMapURL.set(client, sourceMapURL);
|
|
this._resolvedSourceMapURL.set(client, resolvedURLs.sourceMapURL);
|
|
|
|
sourceURL = resolvedURLs.sourceURL;
|
|
sourceMapURL = resolvedURLs.sourceMapURL;
|
|
if (!this._isEnabled)
|
|
return;
|
|
|
|
this.dispatchEventToListeners(SDK.SourceMapManager.Events.SourceMapWillAttach, client);
|
|
|
|
if (this._sourceMapByURL.has(sourceMapURL)) {
|
|
attach.call(this, sourceMapURL, client);
|
|
return;
|
|
}
|
|
if (!this._sourceMapURLToLoadingClients.has(sourceMapURL)) {
|
|
SDK.TextSourceMap.load(sourceMapURL, sourceURL)
|
|
.then(onTextSourceMapLoaded.bind(this, sourceMapURL))
|
|
.then(onSourceMap.bind(this, sourceMapURL));
|
|
}
|
|
this._sourceMapURLToLoadingClients.set(sourceMapURL, client);
|
|
|
|
/**
|
|
* @param {string} sourceMapURL
|
|
* @param {?SDK.TextSourceMap} sourceMap
|
|
* @return {!Promise<?SDK.SourceMap>}
|
|
* @this {SDK.SourceMapManager}
|
|
*/
|
|
function onTextSourceMapLoaded(sourceMapURL, sourceMap) {
|
|
if (!sourceMap)
|
|
return Promise.resolve(/** @type {?SDK.SourceMap} */ (null));
|
|
const factoryExtension = this._factoryForSourceMap(sourceMap);
|
|
if (!factoryExtension)
|
|
return Promise.resolve(/** @type {?SDK.SourceMap} */ (sourceMap));
|
|
return factoryExtension.instance()
|
|
.then(factory => factory.editableSourceMap(this._target, sourceMap))
|
|
.then(map => map || sourceMap)
|
|
.catchException(/** @type {?SDK.SourceMap} */ (null));
|
|
}
|
|
|
|
/**
|
|
* @param {string} sourceMapURL
|
|
* @param {?SDK.SourceMap} sourceMap
|
|
* @this {SDK.SourceMapManager}
|
|
*/
|
|
function onSourceMap(sourceMapURL, sourceMap) {
|
|
this._sourceMapLoadedForTest();
|
|
const clients = this._sourceMapURLToLoadingClients.get(sourceMapURL);
|
|
this._sourceMapURLToLoadingClients.deleteAll(sourceMapURL);
|
|
if (!clients.size)
|
|
return;
|
|
if (!sourceMap) {
|
|
for (const client of clients)
|
|
this.dispatchEventToListeners(SDK.SourceMapManager.Events.SourceMapFailedToAttach, client);
|
|
return;
|
|
}
|
|
this._sourceMapByURL.set(sourceMapURL, sourceMap);
|
|
for (const client of clients)
|
|
attach.call(this, sourceMapURL, client);
|
|
}
|
|
|
|
/**
|
|
* @param {string} sourceMapURL
|
|
* @param {!T} client
|
|
* @this {SDK.SourceMapManager}
|
|
*/
|
|
function attach(sourceMapURL, client) {
|
|
this._sourceMapURLToClients.set(sourceMapURL, client);
|
|
const sourceMap = this._sourceMapByURL.get(sourceMapURL);
|
|
this.dispatchEventToListeners(
|
|
SDK.SourceMapManager.Events.SourceMapAttached, {client: client, sourceMap: sourceMap});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {!SDK.SourceMap} sourceMap
|
|
* @return {?Runtime.Extension}
|
|
*/
|
|
_factoryForSourceMap(sourceMap) {
|
|
const sourceExtensions = new Set();
|
|
for (const url of sourceMap.sourceURLs())
|
|
sourceExtensions.add(Common.ParsedURL.extractExtension(url));
|
|
for (const runtimeExtension of self.runtime.extensions(SDK.SourceMapFactory)) {
|
|
const supportedExtensions = new Set(runtimeExtension.descriptor()['extensions']);
|
|
if (supportedExtensions.containsAll(sourceExtensions))
|
|
return runtimeExtension;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @param {!T} client
|
|
*/
|
|
detachSourceMap(client) {
|
|
const sourceMapURL = this._resolvedSourceMapURL.get(client);
|
|
this._relativeSourceURL.delete(client);
|
|
this._relativeSourceMapURL.delete(client);
|
|
this._resolvedSourceMapURL.delete(client);
|
|
|
|
if (!sourceMapURL)
|
|
return;
|
|
if (!this._sourceMapURLToClients.hasValue(sourceMapURL, client)) {
|
|
if (this._sourceMapURLToLoadingClients.delete(sourceMapURL, client))
|
|
this.dispatchEventToListeners(SDK.SourceMapManager.Events.SourceMapFailedToAttach, client);
|
|
return;
|
|
}
|
|
this._sourceMapURLToClients.delete(sourceMapURL, client);
|
|
const sourceMap = this._sourceMapByURL.get(sourceMapURL);
|
|
if (!this._sourceMapURLToClients.has(sourceMapURL))
|
|
this._sourceMapByURL.delete(sourceMapURL);
|
|
this.dispatchEventToListeners(
|
|
SDK.SourceMapManager.Events.SourceMapDetached, {client: client, sourceMap: sourceMap});
|
|
}
|
|
|
|
_sourceMapLoadedForTest() {
|
|
}
|
|
|
|
dispose() {
|
|
SDK.targetManager.removeEventListener(
|
|
SDK.TargetManager.Events.InspectedURLChanged, this._inspectedURLChanged, this);
|
|
}
|
|
};
|
|
|
|
SDK.SourceMapManager.Events = {
|
|
SourceMapWillAttach: Symbol('SourceMapWillAttach'),
|
|
SourceMapFailedToAttach: Symbol('SourceMapFailedToAttach'),
|
|
SourceMapAttached: Symbol('SourceMapAttached'),
|
|
SourceMapDetached: Symbol('SourceMapDetached'),
|
|
SourceMapChanged: Symbol('SourceMapChanged')
|
|
};
|