Commit 2277d587 authored by caseq's avatar caseq Committed by Commit bot

DevTools: support uiLocationToRawLocations for CSS

BUG=717694

Review-Url: https://codereview.chromium.org/2856233002
Cr-Commit-Position: refs/heads/master@{#469426}
parent b14926c9
...@@ -2,5 +2,16 @@ Tests SourceMap and StyleSheetMapping. ...@@ -2,5 +2,16 @@ Tests SourceMap and StyleSheetMapping.
Added CSS uiSourceCode: http://127.0.0.1:8000/inspector/resources/example.css Added CSS uiSourceCode: http://127.0.0.1:8000/inspector/resources/example.css
Added SCSS uiSourceCode: http://127.0.0.1:8000/inspector/resources/example.scss Added SCSS uiSourceCode: http://127.0.0.1:8000/inspector/resources/example.scss
0:3 0:3(expected: 0:3) -> 0:3
1:0 1:0(expected: 1:0) -> 1:0
2:4 2:2(expected: 2:2) -> 2:2
2:6 2:5(expected: 2:5) -> 2:5
2:9 2:7(expected: 2:7) -> 2:7
3:7 2:10(expected: 2:10) -> 2:10
4:8 4:2(expected: 4:2) -> 4:2
4:10 4:2(expected: 4:2) -> 4:2
4:11 4:11(expected: 4:11) -> 4:11
4:15 4:13(expected: 4:13) -> 4:13
4:20 4:17(expected: 4:17) -> 4:17
UILocation upon LiveLocation update: http://127.0.0.1:8000/inspector/resources/example.scss:2:2 UILocation upon LiveLocation update: http://127.0.0.1:8000/inspector/resources/example.scss:2:2
...@@ -45,10 +45,14 @@ function test() ...@@ -45,10 +45,14 @@ function test()
InspectorTest.waitForUISourceCode(sourceURL).then(scssUISourceCodeAdded); InspectorTest.waitForUISourceCode(sourceURL).then(scssUISourceCodeAdded);
} }
function rawLocationToUILocation(line, column) function testAndDumpLocation(uiSourceCode, expectedLine, expectedColumn, line, column) {
{
var header = cssModel.styleSheetHeaderForId(styleSheetId); var header = cssModel.styleSheetHeaderForId(styleSheetId);
return Bindings.cssWorkspaceBinding.rawLocationToUILocation(new SDK.CSSLocation(header, line, column)); var uiLocation = Bindings.cssWorkspaceBinding.rawLocationToUILocation(new SDK.CSSLocation(header, line, column));
InspectorTest.assertEquals(uiSourceCode, uiLocation.uiSourceCode,
`Incorrect uiSourceCode, expected ${uiSourceCode.url()}, but got ${location.uiSourceCode ? location.uiSourceCode.url() : null}`);
var reverseRaw = Bindings.cssWorkspaceBinding.uiLocationToRawLocations(uiLocation)[0];
InspectorTest.addResult(`${line}:${column} ${uiLocation.lineNumber}:${uiLocation.columnNumber}` +
`(expected: ${expectedLine}:${expectedColumn}) -> ${reverseRaw.lineNumber}:${reverseRaw.columnNumber}`);
} }
function scssUISourceCodeAdded(uiSourceCode) function scssUISourceCodeAdded(uiSourceCode)
...@@ -57,17 +61,17 @@ function test() ...@@ -57,17 +61,17 @@ function test()
var cssUISourceCode = Workspace.workspace.uiSourceCodeForURL(styleSheetURL); var cssUISourceCode = Workspace.workspace.uiSourceCodeForURL(styleSheetURL);
var scssUISourceCode = Workspace.workspace.uiSourceCodeForURL(sourceURL); var scssUISourceCode = Workspace.workspace.uiSourceCodeForURL(sourceURL);
InspectorTest.checkUILocation(cssUISourceCode, 0, 3, rawLocationToUILocation(0, 3)); testAndDumpLocation(cssUISourceCode, 0, 3, 0, 3);
InspectorTest.checkUILocation(scssUISourceCode, 1, 0, rawLocationToUILocation(1, 0)); testAndDumpLocation(scssUISourceCode, 1, 0, 1, 0);
InspectorTest.checkUILocation(scssUISourceCode, 2, 2, rawLocationToUILocation(2, 4)); testAndDumpLocation(scssUISourceCode, 2, 2, 2, 4);
InspectorTest.checkUILocation(scssUISourceCode, 2, 5, rawLocationToUILocation(2, 6)); testAndDumpLocation(scssUISourceCode, 2, 5, 2, 6);
InspectorTest.checkUILocation(scssUISourceCode, 2, 7, rawLocationToUILocation(2, 9)); testAndDumpLocation(scssUISourceCode, 2, 7, 2, 9);
InspectorTest.checkUILocation(scssUISourceCode, 2, 10, rawLocationToUILocation(3, 7)); testAndDumpLocation(scssUISourceCode, 2, 10, 3, 7);
InspectorTest.checkUILocation(scssUISourceCode, 4, 2, rawLocationToUILocation(4, 8)); testAndDumpLocation(scssUISourceCode, 4, 2, 4, 8);
InspectorTest.checkUILocation(scssUISourceCode, 4, 2, rawLocationToUILocation(4, 10)); testAndDumpLocation(scssUISourceCode, 4, 2, 4, 10);
InspectorTest.checkUILocation(scssUISourceCode, 4, 11, rawLocationToUILocation(4, 11)); testAndDumpLocation(scssUISourceCode, 4, 11, 4, 11);
InspectorTest.checkUILocation(scssUISourceCode, 4, 13, rawLocationToUILocation(4, 15)); testAndDumpLocation(scssUISourceCode, 4, 13, 4, 15);
InspectorTest.checkUILocation(scssUISourceCode, 4, 17, rawLocationToUILocation(4, 20)); testAndDumpLocation(scssUISourceCode, 4, 17, 4, 20);
scssUISourceCode.requestContent().then(didRequestContent); scssUISourceCode.requestContent().then(didRequestContent);
function didRequestContent(content, contentEncoded, mimeType) function didRequestContent(content, contentEncoded, mimeType)
......
...@@ -15,18 +15,18 @@ body { ...@@ -15,18 +15,18 @@ body {
Location mapping with formatted source: Location mapping with formatted source:
Mapped locations: Mapped locations:
0:15 -> 0:14 0:15 -> 0:14 -> 0:15
0:22 -> 1:9 0:22 -> 1:9 -> 0:22
0:65 -> 8:5 0:65 -> 8:5 -> 0:65
Live locations (updated: 3): Live locations (updated: 3):
0:14 0:14
1:9 1:9
8:5 8:5
Location mapping without formatted source: Location mapping without formatted source:
Mapped locations: Mapped locations:
0:15 -> 0:15 0:15 -> 0:15 -> 0:15
0:22 -> 0:22 0:22 -> 0:22 -> 0:22
0:65 -> 0:65 0:65 -> 0:65 -> 0:65
Live locations (updated: 6): Live locations (updated: 6):
0:15 0:15
0:22 0:22
......
...@@ -41,7 +41,9 @@ async function test() ...@@ -41,7 +41,9 @@ async function test()
InspectorTest.addResult("Mapped locations:"); InspectorTest.addResult("Mapped locations:");
for (var rawLocation of rawLocations) { for (var rawLocation of rawLocations) {
var uiLocation = Bindings.cssWorkspaceBinding.rawLocationToUILocation(rawLocation); var uiLocation = Bindings.cssWorkspaceBinding.rawLocationToUILocation(rawLocation);
InspectorTest.addResult(`${rawLocation.lineNumber}:${rawLocation.columnNumber} -> ${uiLocation.lineNumber}:${uiLocation.columnNumber}`); var reverseRawLocation = Bindings.cssWorkspaceBinding.uiLocationToRawLocations(uiLocation)[0];
InspectorTest.addResult(`${rawLocation.lineNumber}:${rawLocation.columnNumber} -> ${uiLocation.lineNumber}:${uiLocation.columnNumber} ` +
`-> ${reverseRawLocation.lineNumber}:${reverseRawLocation.columnNumber}`);
} }
InspectorTest.addResult(`Live locations (updated: ${locationUpdateCount}):`); InspectorTest.addResult(`Live locations (updated: ${locationUpdateCount}):`);
for (var liveLocation of liveLocations) { for (var liveLocation of liveLocations) {
......
...@@ -67,35 +67,35 @@ function formatted2() { ...@@ -67,35 +67,35 @@ function formatted2() {
} }
Location mapping with formatted source: Location mapping with formatted source:
1:0 -> 0:22 1:0 -> 0:22 -> 1:0
6:0 -> 4:24 6:0 -> 4:24 -> 6:0
11:3 -> 9:4 11:3 -> 9:4 -> 11:3
11:29 -> 10:32 11:29 -> 10:32 -> 11:29
11:150 -> 14:20 11:150 -> 14:20 -> 11:150
11:227 -> 20:30 11:227 -> 20:30 -> 11:227
12:0 -> 22:30 12:0 -> 22:30 -> 12:0
12:157 -> 30:51 12:157 -> 30:51 -> 12:157
12:170 -> 31:22 12:170 -> 31:22 -> 12:170
13:0 -> 37:21 13:0 -> 37:21 -> 13:0
14:71 -> 50:23 14:71 -> 50:23 -> 14:71
14:97 -> 53:18 14:97 -> 53:18 -> 14:97
14:168 -> 56:18 14:168 -> 56:18 -> 14:168
14:237 -> 59:12 14:237 -> 59:12 -> 14:237
17:0 -> 61:22 17:0 -> 61:22 -> 17:0
Location mapping without formatted source: Location mapping without formatted source:
1:0 -> 1:0 1:0 -> 1:0 -> 1:0
6:0 -> 6:0 6:0 -> 6:0 -> 6:0
11:3 -> 11:3 11:3 -> 11:3 -> 11:3
11:29 -> 11:29 11:29 -> 11:29 -> 11:29
11:150 -> 11:150 11:150 -> 11:150 -> 11:150
11:227 -> 11:227 11:227 -> 11:227 -> 11:227
12:0 -> 12:0 12:0 -> 12:0 -> 12:0
12:157 -> 12:157 12:157 -> 12:157 -> 12:157
12:170 -> 12:170 12:170 -> 12:170 -> 12:170
13:0 -> 13:0 13:0 -> 13:0 -> 13:0
14:71 -> 14:71 14:71 -> 14:71 -> 14:71
14:97 -> 14:97 14:97 -> 14:97 -> 14:97
14:168 -> 14:168 14:168 -> 14:168 -> 14:168
14:237 -> 14:237 14:237 -> 14:237 -> 14:237
17:0 -> 17:0 17:0 -> 17:0 -> 17:0
...@@ -34,7 +34,9 @@ async function test() ...@@ -34,7 +34,9 @@ async function test()
for (var position of positions) { for (var position of positions) {
var rawLocation = InspectorTest.debuggerModel.createRawLocation(script, position.lineNumber, position.columnNumber); var rawLocation = InspectorTest.debuggerModel.createRawLocation(script, position.lineNumber, position.columnNumber);
var uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation); var uiLocation = Bindings.debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation);
InspectorTest.addResult(`${rawLocation.lineNumber}:${rawLocation.columnNumber} -> ${uiLocation.lineNumber}:${uiLocation.columnNumber}`); var reverseRawLocation = Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber);
InspectorTest.addResult(`${rawLocation.lineNumber}:${rawLocation.columnNumber} -> ${uiLocation.lineNumber}:${uiLocation.columnNumber}` +
` -> ${reverseRawLocation.lineNumber}:${reverseRawLocation.columnNumber}`);
} }
} }
} }
......
...@@ -79,12 +79,10 @@ Bindings.CSSWorkspaceBinding = class { ...@@ -79,12 +79,10 @@ Bindings.CSSWorkspaceBinding = class {
} }
/** /**
* @param {?SDK.CSSLocation} rawLocation * @param {!SDK.CSSLocation} rawLocation
* @return {?Workspace.UILocation} * @return {?Workspace.UILocation}
*/ */
rawLocationToUILocation(rawLocation) { rawLocationToUILocation(rawLocation) {
if (!rawLocation)
return null;
for (var i = this._sourceMappings.length - 1; i >= 0; --i) { for (var i = this._sourceMappings.length - 1; i >= 0; --i) {
var uiLocation = this._sourceMappings[i].rawLocationToUILocation(rawLocation); var uiLocation = this._sourceMappings[i].rawLocationToUILocation(rawLocation);
if (uiLocation) if (uiLocation)
...@@ -93,6 +91,22 @@ Bindings.CSSWorkspaceBinding = class { ...@@ -93,6 +91,22 @@ Bindings.CSSWorkspaceBinding = class {
return this._modelToInfo.get(rawLocation.cssModel())._rawLocationToUILocation(rawLocation); return this._modelToInfo.get(rawLocation.cssModel())._rawLocationToUILocation(rawLocation);
} }
/**
* @param {!Workspace.UILocation} uiLocation
* @return {!Array<!SDK.CSSLocation>}
*/
uiLocationToRawLocations(uiLocation) {
for (var i = this._sourceMappings.length - 1; i >= 0; --i) {
var rawLocations = this._sourceMappings[i].uiLocationToRawLocations(uiLocation);
if (rawLocations.length)
return rawLocations;
}
var rawLocations = [];
for (var modelInfo of this._modelToInfo.values())
rawLocations.pushAll(modelInfo._uiLocationToRawLocations(uiLocation));
return rawLocations;
}
/** /**
* @param {!Bindings.CSSWorkspaceBinding.SourceMapping} sourceMapping * @param {!Bindings.CSSWorkspaceBinding.SourceMapping} sourceMapping
*/ */
...@@ -112,6 +126,12 @@ Bindings.CSSWorkspaceBinding.SourceMapping.prototype = { ...@@ -112,6 +126,12 @@ Bindings.CSSWorkspaceBinding.SourceMapping.prototype = {
* @return {?Workspace.UILocation} * @return {?Workspace.UILocation}
*/ */
rawLocationToUILocation(rawLocation) {}, rawLocationToUILocation(rawLocation) {},
/**
* @param {!Workspace.UILocation} uiLocation
* @return {!Array<!SDK.CSSLocation>}
*/
uiLocationToRawLocations(uiLocation) {},
}; };
Bindings.CSSWorkspaceBinding.ModelInfo = class { Bindings.CSSWorkspaceBinding.ModelInfo = class {
...@@ -213,6 +233,18 @@ Bindings.CSSWorkspaceBinding.ModelInfo = class { ...@@ -213,6 +233,18 @@ Bindings.CSSWorkspaceBinding.ModelInfo = class {
return uiLocation; return uiLocation;
} }
/**
* @param {!Workspace.UILocation} uiLocation
* @return {!Array<!SDK.CSSLocation>}
*/
_uiLocationToRawLocations(uiLocation) {
var rawLocations = this._sassSourceMapping.uiLocationToRawLocations(uiLocation);
if (rawLocations.length)
return rawLocations;
return this._stylesSourceMapping.uiLocationToRawLocations(uiLocation);
}
_dispose() { _dispose() {
Common.EventTarget.removeEventListeners(this._eventListeners); Common.EventTarget.removeEventListeners(this._eventListeners);
this._stylesSourceMapping.dispose(); this._stylesSourceMapping.dispose();
......
...@@ -87,7 +87,9 @@ Bindings.SASSSourceMapping = class { ...@@ -87,7 +87,9 @@ Bindings.SASSSourceMapping = class {
var contentProvider = sourceMap.sourceContentProvider(sassURL, Common.resourceTypes.SourceMapStyleSheet); var contentProvider = sourceMap.sourceContentProvider(sassURL, Common.resourceTypes.SourceMapStyleSheet);
var embeddedContent = sourceMap.embeddedContentByURL(sassURL); var embeddedContent = sourceMap.embeddedContentByURL(sassURL);
var embeddedContentLength = typeof embeddedContent === 'string' ? embeddedContent.length : null; var embeddedContentLength = typeof embeddedContent === 'string' ? embeddedContent.length : null;
this._networkProject.addSourceMapFile(contentProvider, header.frameId, false, embeddedContentLength); var uiSourceCode =
this._networkProject.addSourceMapFile(contentProvider, header.frameId, false, embeddedContentLength);
uiSourceCode[Bindings.SASSSourceMapping._sourceMapSymbol] = sourceMap;
} }
Bindings.cssWorkspaceBinding.updateLocations(header); Bindings.cssWorkspaceBinding.updateLocations(header);
this._sourceMapAttachedForTest(sourceMap); this._sourceMapAttachedForTest(sourceMap);
...@@ -127,6 +129,7 @@ Bindings.SASSSourceMapping = class { ...@@ -127,6 +129,7 @@ Bindings.SASSSourceMapping = class {
if (handledUISourceCodes.has(uiSourceCode)) if (handledUISourceCodes.has(uiSourceCode))
continue; continue;
handledUISourceCodes.add(uiSourceCode); handledUISourceCodes.add(uiSourceCode);
uiSourceCode[Bindings.SASSSourceMapping._sourceMapSymbol] = sourceMap;
var sassText = /** @type {string} */ (newSources.get(sourceURL)); var sassText = /** @type {string} */ (newSources.get(sourceURL));
uiSourceCode.setWorkingCopy(sassText); uiSourceCode.setWorkingCopy(sassText);
} }
...@@ -154,7 +157,26 @@ Bindings.SASSSourceMapping = class { ...@@ -154,7 +157,26 @@ Bindings.SASSSourceMapping = class {
return uiSourceCode.uiLocation(entry.sourceLineNumber || 0, entry.sourceColumnNumber); return uiSourceCode.uiLocation(entry.sourceLineNumber || 0, entry.sourceColumnNumber);
} }
/**
* @override
* @param {!Workspace.UILocation} uiLocation
* @return {!Array<!SDK.CSSLocation>}
*/
uiLocationToRawLocations(uiLocation) {
var sourceMap = uiLocation.uiSourceCode[Bindings.SASSSourceMapping._sourceMapSymbol];
if (!sourceMap)
return [];
var entries =
sourceMap.findReverseEntries(uiLocation.uiSourceCode.url(), uiLocation.lineNumber, uiLocation.columnNumber);
var locations = [];
for (var header of this._sourceMapManager.clientsForSourceMap(sourceMap))
locations.pushAll(entries.map(entry => new SDK.CSSLocation(header, entry.lineNumber, entry.columnNumber)));
return locations;
}
dispose() { dispose() {
Common.EventTarget.removeEventListeners(this._eventListeners); Common.EventTarget.removeEventListeners(this._eventListeners);
} }
}; };
\ No newline at end of file
Bindings.SASSSourceMapping._sourceMapSymbol = Symbol('sourceMap');
...@@ -74,13 +74,32 @@ Bindings.StylesSourceMapping = class { ...@@ -74,13 +74,32 @@ Bindings.StylesSourceMapping = class {
return null; return null;
var lineNumber = rawLocation.lineNumber; var lineNumber = rawLocation.lineNumber;
var columnNumber = rawLocation.columnNumber; var columnNumber = rawLocation.columnNumber;
if (header && header.isInline && header.hasSourceURL) { if (header.isInline && header.hasSourceURL) {
lineNumber -= header.lineNumberInSource(0); lineNumber -= header.lineNumberInSource(0);
columnNumber -= header.columnNumberInSource(lineNumber, 0); columnNumber -= header.columnNumberInSource(lineNumber, 0);
} }
return uiSourceCode.uiLocation(lineNumber, columnNumber); return uiSourceCode.uiLocation(lineNumber, columnNumber);
} }
/**
* @override
* @param {!Workspace.UILocation} uiLocation
* @return {!Array<!SDK.CSSLocation>}
*/
uiLocationToRawLocations(uiLocation) {
// TODO(caseq,lushnikov): return multiple raw locations.
var header = Bindings.NetworkProject.styleHeaderForUISourceCode(uiLocation.uiSourceCode);
if (!header)
return [];
var lineNumber = uiLocation.lineNumber;
var columnNumber = uiLocation.columnNumber;
if (header.isInline && header.hasSourceURL) {
columnNumber = header.columnNumberInSource(lineNumber, columnNumber);
lineNumber = header.lineNumberInSource(lineNumber);
}
return [new SDK.CSSLocation(header, lineNumber, columnNumber)];
}
/** /**
* @param {!Common.Event} event * @param {!Common.Event} event
*/ */
......
...@@ -364,6 +364,24 @@ SDK.TextSourceMap = class { ...@@ -364,6 +364,24 @@ SDK.TextSourceMap = class {
} }
} }
/**
* @param {string} sourceURL
* @param {number} lineNumber
* @param {number} columnNumber
* @return {!Array<!SDK.SourceMapEntry>}
*/
findReverseEntries(sourceURL, lineNumber, columnNumber) {
var mappings = this._reversedMappings(sourceURL);
var endIndex = mappings.upperBound(
undefined, (unused, entry) => lineNumber - entry.sourceLineNumber || columnNumber - entry.sourceColumnNumber);
var startIndex = endIndex;
while (startIndex > 0 && mappings[startIndex - 1].sourceLineNumber === mappings[endIndex - 1].sourceLineNumber &&
mappings[startIndex - 1].sourceColumnNumber === mappings[endIndex - 1].sourceColumnNumber)
--startIndex;
return mappings.slice(startIndex, endIndex);
}
/** /**
* @return {!Array<!SDK.SourceMapEntry>} * @return {!Array<!SDK.SourceMapEntry>}
*/ */
......
...@@ -256,6 +256,22 @@ Sources.SourceFormatter.StyleMapping = class { ...@@ -256,6 +256,22 @@ Sources.SourceFormatter.StyleMapping = class {
return formatData.formattedSourceCode.uiLocation(formattedLocation[0], formattedLocation[1]); return formatData.formattedSourceCode.uiLocation(formattedLocation[0], formattedLocation[1]);
} }
/**
* @override
* @param {!Workspace.UILocation} uiLocation
* @return {!Array<!SDK.CSSLocation>}
*/
uiLocationToRawLocations(uiLocation) {
var formatData = Sources.SourceFormatData._for(uiLocation.uiSourceCode);
if (!formatData)
return [];
var originalLocation = formatData.mapping.formattedToOriginal(uiLocation.lineNumber, uiLocation.columnNumber);
var header = Bindings.NetworkProject.styleHeaderForUISourceCode(formatData.originalSourceCode);
if (!header)
return [];
return [new SDK.CSSLocation(header, originalLocation[0], originalLocation[1])];
}
/** /**
* @param {!Sources.SourceFormatData} formatData * @param {!Sources.SourceFormatData} formatData
* @param {boolean} enable * @param {boolean} enable
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment