Index: third_party/WebKit/Source/devtools/front_end/bindings/CompilerScriptMapping.js |
diff --git a/third_party/WebKit/Source/devtools/front_end/bindings/CompilerScriptMapping.js b/third_party/WebKit/Source/devtools/front_end/bindings/CompilerScriptMapping.js |
index 56daf344f37334963ce8e3c3956f6cbeaba2d7c3..4396ba2a8a0427cfdcf924f41a1e726b386c12de 100644 |
--- a/third_party/WebKit/Source/devtools/front_end/bindings/CompilerScriptMapping.js |
+++ b/third_party/WebKit/Source/devtools/front_end/bindings/CompilerScriptMapping.js |
@@ -40,38 +40,59 @@ Bindings.CompilerScriptMapping = class { |
*/ |
constructor(debuggerModel, workspace, networkProject, debuggerWorkspaceBinding) { |
this._debuggerModel = debuggerModel; |
+ this._sourceMapManager = this._debuggerModel.sourceMapManager(); |
this._workspace = workspace; |
this._networkProject = networkProject; |
this._debuggerWorkspaceBinding = debuggerWorkspaceBinding; |
- /** @type {!Map<string, !Promise<?SDK.TextSourceMap>>} */ |
- this._sourceMapLoadingPromises = new Map(); |
- /** @type {!Map<string, !SDK.TextSourceMap>} */ |
- this._sourceMapForScriptId = new Map(); |
- /** @type {!Map.<!SDK.TextSourceMap, !SDK.Script>} */ |
- this._scriptForSourceMap = new Map(); |
- /** @type {!Map.<string, !SDK.TextSourceMap>} */ |
- this._sourceMapForURL = new Map(); |
- /** @type {!Map.<string, !Workspace.UISourceCode>} */ |
+ /** @type {!Map.<!SDK.Script, !Workspace.UISourceCode>} */ |
+ this._scriptSources = new Multimap(); |
+ /** @type {!Map.<!SDK.Script, !Workspace.UISourceCode>} */ |
this._stubUISourceCodes = new Map(); |
var projectId = Bindings.CompilerScriptMapping.projectIdForTarget(this._debuggerModel.target()); |
this._stubProject = new Bindings.ContentProviderBasedProject( |
workspace, projectId, Workspace.projectTypes.Service, '', true /* isServiceProject */); |
this._eventListeners = [ |
- workspace.addEventListener( |
- Workspace.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAddedToWorkspace, this), |
- debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this), |
- debuggerModel.addEventListener(SDK.DebuggerModel.Events.SourceMapURLAdded, this._sourceMapURLAdded.bind(this)) |
+ this._sourceMapManager.addEventListener( |
+ SDK.SourceMapManager.Events.SourceMapWillAttach, this._sourceMapWillAttach, this), |
+ this._sourceMapManager.addEventListener( |
+ SDK.SourceMapManager.Events.SourceMapFailedToAttach, this._sourceMapFailedToAttach, this), |
+ this._sourceMapManager.addEventListener( |
+ SDK.SourceMapManager.Events.SourceMapAttached, this._sourceMapAttached, this), |
+ this._sourceMapManager.addEventListener( |
+ SDK.SourceMapManager.Events.SourceMapDetached, this._sourceMapDetached, this), |
]; |
} |
/** |
+ * @param {!SDK.Script} script |
+ */ |
+ _addStubUISourceCode(script) { |
+ var stubUISourceCode = this._stubProject.addContentProvider( |
+ script.sourceURL + ':sourcemap', |
+ Common.StaticContentProvider.fromString( |
+ script.sourceURL, Common.resourceTypes.Script, |
+ '\n\n\n\n\n// Please wait a bit.\n// Compiled script is not shown while source map is being loaded!')); |
+ this._stubUISourceCodes.set(script, stubUISourceCode); |
+ } |
+ |
+ /** |
+ * @param {!SDK.Script} script |
+ */ |
+ _removeStubUISourceCode(script) { |
+ var uiSourceCode = this._stubUISourceCodes.get(script); |
+ this._stubUISourceCodes.delete(script); |
+ this._stubProject.removeFile(uiSourceCode.url()); |
+ } |
+ |
+ /** |
* @param {!Workspace.UISourceCode} uiSourceCode |
* @return {?string} |
*/ |
static uiSourceCodeOrigin(uiSourceCode) { |
- return uiSourceCode[Bindings.CompilerScriptMapping._originSymbol] || null; |
+ var script = uiSourceCode[Bindings.CompilerScriptMapping._scriptSymbol]; |
+ return script ? script.sourceURL : null; |
} |
/** |
@@ -87,10 +108,12 @@ Bindings.CompilerScriptMapping = class { |
* @return {boolean} |
*/ |
mapsToSourceCode(rawLocation) { |
- var sourceMap = this._sourceMapForScriptId.get(rawLocation.scriptId); |
+ var script = rawLocation.script(); |
+ if (!script) |
+ return true; |
+ var sourceMap = this._sourceMapManager.sourceMapForClient(script); |
if (!sourceMap) |
return true; |
- |
return !!sourceMap.findEntry(rawLocation.lineNumber, rawLocation.columnNumber); |
} |
@@ -100,23 +123,22 @@ Bindings.CompilerScriptMapping = class { |
* @return {?Workspace.UILocation} |
*/ |
rawLocationToUILocation(rawLocation) { |
- var debuggerModelLocation = /** @type {!SDK.DebuggerModel.Location} */ (rawLocation); |
+ var script = rawLocation.script(); |
+ if (!script) |
+ return null; |
- var stubUISourceCode = this._stubUISourceCodes.get(debuggerModelLocation.scriptId); |
+ var lineNumber = rawLocation.lineNumber; |
+ var columnNumber = rawLocation.columnNumber || 0; |
+ var stubUISourceCode = this._stubUISourceCodes.get(script); |
if (stubUISourceCode) |
- return new Workspace.UILocation(stubUISourceCode, rawLocation.lineNumber, rawLocation.columnNumber); |
+ return new Workspace.UILocation(stubUISourceCode, lineNumber, columnNumber); |
- var sourceMap = this._sourceMapForScriptId.get(debuggerModelLocation.scriptId); |
+ var sourceMap = this._sourceMapManager.sourceMapForClient(script); |
if (!sourceMap) |
return null; |
- var lineNumber = debuggerModelLocation.lineNumber; |
- var columnNumber = debuggerModelLocation.columnNumber || 0; |
var entry = sourceMap.findEntry(lineNumber, columnNumber); |
if (!entry || !entry.sourceURL) |
return null; |
- var script = rawLocation.script(); |
- if (!script) |
- return null; |
var uiSourceCode = Bindings.NetworkProject.uiSourceCodeForScriptURL( |
this._workspace, /** @type {string} */ (entry.sourceURL), script); |
if (!uiSourceCode) |
@@ -133,13 +155,12 @@ Bindings.CompilerScriptMapping = class { |
* @return {?SDK.DebuggerModel.Location} |
*/ |
uiLocationToRawLocation(uiSourceCode, lineNumber, columnNumber) { |
- if (uiSourceCode.project().type() === Workspace.projectTypes.Service) |
+ var script = uiSourceCode[Bindings.CompilerScriptMapping._scriptSymbol]; |
+ if (!script) |
return null; |
- var sourceMap = this._sourceMapForURL.get(uiSourceCode.url()); |
+ var sourceMap = this._sourceMapManager.sourceMapForClient(script); |
if (!sourceMap) |
return null; |
- var script = /** @type {!SDK.Script} */ (this._scriptForSourceMap.get(sourceMap)); |
- console.assert(script); |
var entry = sourceMap.firstSourceLineMapping(uiSourceCode.url(), lineNumber); |
if (!entry) |
return null; |
@@ -147,63 +168,72 @@ Bindings.CompilerScriptMapping = class { |
} |
/** |
- * @param {!SDK.Script} script |
+ * @param {!Common.Event} event |
*/ |
- addScript(script) { |
- if (script.sourceMapURL) |
- this._processScript(script); |
+ _sourceMapWillAttach(event) { |
+ var script = /** @type {!SDK.Script} */ (event.data.client); |
+ // Create stub UISourceCode for the time source mapping is being loaded. |
+ this._addStubUISourceCode(script); |
+ this._debuggerWorkspaceBinding.pushSourceMapping(script, this); |
} |
/** |
- * @param {!SDK.Script} script |
- * @return {?SDK.TextSourceMap} |
+ * @param {!Common.Event} event |
*/ |
- sourceMapForScript(script) { |
- return this._sourceMapForScriptId.get(script.scriptId) || null; |
+ _sourceMapFailedToAttach(event) { |
+ var script = /** @type {!SDK.Script} */ (event.data.client); |
+ this._removeStubUISourceCode(script); |
} |
/** |
- * @param {!SDK.Script} script |
+ * @param {!Common.Event} event |
*/ |
- maybeLoadSourceMap(script) { |
- if (!script.sourceMapURL) |
- return; |
- if (this._sourceMapLoadingPromises.has(script.sourceMapURL)) |
- return; |
- if (this._sourceMapForScriptId.has(script.scriptId)) |
+ _sourceMapAttached(event) { |
+ var script = /** @type {!SDK.Script} */ (event.data.client); |
+ var sourceMap = /** @type {!SDK.SourceMap} */ (event.data.sourceMap); |
+ this._removeStubUISourceCode(script); |
+ |
+ if (Bindings.blackboxManager.isBlackboxedURL(script.sourceURL, script.isContentScript())) |
return; |
- this._processScript(script); |
+ Bindings.blackboxManager.sourceMapLoaded(script, sourceMap); |
+ |
+ this._populateSourceMapSources(script, sourceMap); |
+ this._sourceMapAttachedForTest(sourceMap); |
} |
/** |
* @param {!Common.Event} event |
*/ |
- _sourceMapURLAdded(event) { |
- var script = /** @type {!SDK.Script} */ (event.data); |
- if (!script.sourceMapURL) |
+ _sourceMapDetached(event) { |
+ var script = /** @type {!SDK.Script} */ (event.data.client); |
+ var sources = this._scriptSources.get(script); |
+ if (!sources.size) |
return; |
- this._processScript(script); |
+ var frameId = script[Bindings.CompilerScriptMapping._frameIdSymbol]; |
+ for (var uiSourceCode of sources) { |
+ this._debuggerWorkspaceBinding.setSourceMapping(this._debuggerModel, uiSourceCode, null); |
+ this._networkProject.removeSourceMapFile(uiSourceCode.url(), frameId, script.isContentScript()); |
+ } |
+ this._debuggerWorkspaceBinding.updateLocations(script); |
} |
/** |
* @param {!SDK.Script} script |
+ * @return {?SDK.SourceMap} |
*/ |
- _processScript(script) { |
- if (Bindings.blackboxManager.isBlackboxedURL(script.sourceURL, script.isContentScript())) |
- return; |
- // Create stub UISourceCode for the time source mapping is being loaded. |
- var stubUISourceCode = this._stubProject.addContentProvider( |
- script.sourceURL + ':sourcemap', |
- Common.StaticContentProvider.fromString( |
- script.sourceURL, Common.resourceTypes.Script, |
- '\n\n\n\n\n// Please wait a bit.\n// Compiled script is not shown while source map is being loaded!')); |
- this._stubUISourceCodes.set(script.scriptId, stubUISourceCode); |
+ sourceMapForScript(script) { |
+ return this._sourceMapManager.sourceMapForClient(script); |
+ } |
- this._debuggerWorkspaceBinding.pushSourceMapping(script, this); |
- this._loadSourceMapForScript(script).then(sourceMap => { |
- this._sourceMapLoaded(script, stubUISourceCode.url(), sourceMap); |
- this._sourceMapAttachedForTest(sourceMap); |
- }); |
+ /** |
+ * @param {!SDK.Script} script |
+ */ |
+ maybeLoadSourceMap(script) { |
+ //TODO: populate source map sources |
+ var sourceMap = this._sourceMapManager.sourceMapForClient(script); |
+ if (!sourceMap) |
+ return; |
+ this._populateSourceMapSources(script, sourceMap); |
} |
/** |
@@ -214,61 +244,22 @@ Bindings.CompilerScriptMapping = class { |
/** |
* @param {!SDK.Script} script |
- * @param {string} uiSourceCodePath |
- * @param {?SDK.TextSourceMap} sourceMap |
+ * @param {!SDK.TextSourceMap} sourceMap |
*/ |
- _sourceMapLoaded(script, uiSourceCodePath, sourceMap) { |
- Bindings.blackboxManager.sourceMapLoaded(script, sourceMap); |
- |
- this._stubUISourceCodes.delete(script.scriptId); |
- this._stubProject.removeFile(uiSourceCodePath); |
- |
- if (!sourceMap) { |
- this._debuggerWorkspaceBinding.updateLocations(script); |
- return; |
- } |
- |
- if (this._scriptForSourceMap.get(sourceMap)) { |
- this._sourceMapForScriptId.set(script.scriptId, sourceMap); |
- this._debuggerWorkspaceBinding.updateLocations(script); |
- return; |
- } |
- |
- this._sourceMapForScriptId.set(script.scriptId, sourceMap); |
- this._scriptForSourceMap.set(sourceMap, script); |
- |
- // Report sources. |
- var missingSources = []; |
+ _populateSourceMapSources(script, sourceMap) { |
var executionContext = script.executionContext(); |
var frameId = executionContext ? executionContext.frameId || '' : ''; |
+ script[Bindings.CompilerScriptMapping._frameIdSymbol] = frameId; |
for (var sourceURL of sourceMap.sourceURLs()) { |
- if (this._sourceMapForURL.get(sourceURL)) |
- continue; |
- this._sourceMapForURL.set(sourceURL, sourceMap); |
- var uiSourceCode = Bindings.NetworkProject.uiSourceCodeForScriptURL(this._workspace, sourceURL, script); |
- if (!uiSourceCode) { |
- var contentProvider = sourceMap.sourceContentProvider(sourceURL, Common.resourceTypes.SourceMapScript); |
- var embeddedContent = sourceMap.embeddedContentByURL(sourceURL); |
- var embeddedContentLength = typeof embeddedContent === 'string' ? embeddedContent.length : null; |
- uiSourceCode = this._networkProject.addSourceMapFile( |
- contentProvider, frameId, script.isContentScript(), embeddedContentLength); |
- uiSourceCode[Bindings.CompilerScriptMapping._originSymbol] = script.sourceURL; |
- } |
- if (uiSourceCode) { |
- this._bindUISourceCode(uiSourceCode); |
- } else { |
- if (missingSources.length < 3) |
- missingSources.push(sourceURL); |
- else if (missingSources.peekLast() !== '\u2026') |
- missingSources.push('\u2026'); |
- } |
+ var contentProvider = sourceMap.sourceContentProvider(sourceURL, Common.resourceTypes.SourceMapScript); |
+ var embeddedContent = sourceMap.embeddedContentByURL(sourceURL); |
+ var embeddedContentLength = typeof embeddedContent === 'string' ? embeddedContent.length : null; |
+ var uiSourceCode = this._networkProject.addSourceMapFile( |
+ contentProvider, frameId, script.isContentScript(), embeddedContentLength); |
+ uiSourceCode[Bindings.CompilerScriptMapping._scriptSymbol] = script; |
+ this._scriptSources.set(script, uiSourceCode); |
+ this._debuggerWorkspaceBinding.setSourceMapping(this._debuggerModel, uiSourceCode, this); |
} |
- if (missingSources.length) { |
- Common.console.warn(Common.UIString( |
- 'Source map %s points to the files missing from the workspace: [%s]', sourceMap.url(), |
- missingSources.join(', '))); |
- } |
- |
this._debuggerWorkspaceBinding.updateLocations(script); |
} |
@@ -287,105 +278,18 @@ Bindings.CompilerScriptMapping = class { |
* @return {boolean} |
*/ |
uiLineHasMapping(uiSourceCode, lineNumber) { |
- var sourceMap = this._sourceMapForURL.get(uiSourceCode.url()); |
+ var script = uiSourceCode[Bindings.CompilerScriptMapping._scriptSymbol]; |
+ var sourceMap = this._sourceMapManager.sourceMapForClient(script); |
if (!sourceMap) |
return true; |
return !!sourceMap.firstSourceLineMapping(uiSourceCode.url(), lineNumber); |
} |
- /** |
- * @param {!Workspace.UISourceCode} uiSourceCode |
- */ |
- _bindUISourceCode(uiSourceCode) { |
- this._debuggerWorkspaceBinding.setSourceMapping(this._debuggerModel, uiSourceCode, this); |
- } |
- |
- /** |
- * @param {!Workspace.UISourceCode} uiSourceCode |
- */ |
- _unbindUISourceCode(uiSourceCode) { |
- this._debuggerWorkspaceBinding.setSourceMapping(this._debuggerModel, uiSourceCode, null); |
- } |
- |
- /** |
- * @param {!Common.Event} event |
- */ |
- _uiSourceCodeAddedToWorkspace(event) { |
- var uiSourceCode = /** @type {!Workspace.UISourceCode} */ (event.data); |
- if (!this._sourceMapForURL.get(uiSourceCode.url())) |
- return; |
- this._bindUISourceCode(uiSourceCode); |
- } |
- |
- /** |
- * @param {!SDK.Script} script |
- * @return {!Promise<?SDK.TextSourceMap>} |
- */ |
- _loadSourceMapForScript(script) { |
- // script.sourceURL can be a random string, but is generally an absolute path -> complete it to inspected page url for |
- // relative links. |
- var scriptURL = Common.ParsedURL.completeURL(this._debuggerModel.target().inspectedURL(), script.sourceURL); |
- if (!scriptURL) |
- return Promise.resolve(/** @type {?SDK.TextSourceMap} */ (null)); |
- |
- console.assert(script.sourceMapURL); |
- var scriptSourceMapURL = /** @type {string} */ (script.sourceMapURL); |
- |
- var sourceMapURL = Common.ParsedURL.completeURL(scriptURL, scriptSourceMapURL); |
- if (!sourceMapURL) |
- return Promise.resolve(/** @type {?SDK.TextSourceMap} */ (null)); |
- |
- var loadingPromise = this._sourceMapLoadingPromises.get(sourceMapURL); |
- if (!loadingPromise) { |
- loadingPromise = SDK.TextSourceMap.load(sourceMapURL, scriptURL).then(sourceMapLoaded.bind(this, sourceMapURL)); |
- this._sourceMapLoadingPromises.set(sourceMapURL, loadingPromise); |
- } |
- return loadingPromise; |
- |
- /** |
- * @param {string} url |
- * @param {?SDK.TextSourceMap} sourceMap |
- * @this {Bindings.CompilerScriptMapping} |
- */ |
- function sourceMapLoaded(url, sourceMap) { |
- if (!sourceMap) { |
- this._sourceMapLoadingPromises.delete(url); |
- return null; |
- } |
- |
- return sourceMap; |
- } |
- } |
- |
- _debuggerReset() { |
- /** |
- * @param {!SDK.TextSourceMap} sourceMap |
- * @this {Bindings.CompilerScriptMapping} |
- */ |
- function unbindSourceMapSources(sourceMap) { |
- var script = this._scriptForSourceMap.get(sourceMap); |
- if (!script) |
- return; |
- for (var sourceURL of sourceMap.sourceURLs()) { |
- var uiSourceCode = Bindings.NetworkProject.uiSourceCodeForScriptURL(this._workspace, sourceURL, script); |
- if (uiSourceCode) |
- this._unbindUISourceCode(uiSourceCode); |
- } |
- } |
- |
- Array.from(new Set(this._sourceMapForURL.values())).forEach(unbindSourceMapSources.bind(this)); |
- |
- this._sourceMapLoadingPromises.clear(); |
- this._sourceMapForScriptId.clear(); |
- this._scriptForSourceMap.clear(); |
- this._sourceMapForURL.clear(); |
- } |
- |
dispose() { |
Common.EventTarget.removeEventListeners(this._eventListeners); |
- this._debuggerReset(); |
this._stubProject.dispose(); |
} |
}; |
-Bindings.CompilerScriptMapping._originSymbol = Symbol('origin'); |
+Bindings.CompilerScriptMapping._scriptSymbol = Symbol('Bindings.CompilerScriptMapping._scriptSymbol'); |
+Bindings.CompilerScriptMapping._frameIdSymbol = Symbol('Bindings.CompilerScriptMapping._frameIdSymbol'); |