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.
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
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
......@@ -45,10 +45,14 @@ function test()
InspectorTest.waitForUISourceCode(sourceURL).then(scssUISourceCodeAdded);
}
function rawLocationToUILocation(line, column)
{
function testAndDumpLocation(uiSourceCode, expectedLine, expectedColumn, line, column) {
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)
......@@ -57,17 +61,17 @@ function test()
var cssUISourceCode = Workspace.workspace.uiSourceCodeForURL(styleSheetURL);
var scssUISourceCode = Workspace.workspace.uiSourceCodeForURL(sourceURL);
InspectorTest.checkUILocation(cssUISourceCode, 0, 3, rawLocationToUILocation(0, 3));
InspectorTest.checkUILocation(scssUISourceCode, 1, 0, rawLocationToUILocation(1, 0));
InspectorTest.checkUILocation(scssUISourceCode, 2, 2, rawLocationToUILocation(2, 4));
InspectorTest.checkUILocation(scssUISourceCode, 2, 5, rawLocationToUILocation(2, 6));
InspectorTest.checkUILocation(scssUISourceCode, 2, 7, rawLocationToUILocation(2, 9));
InspectorTest.checkUILocation(scssUISourceCode, 2, 10, rawLocationToUILocation(3, 7));
InspectorTest.checkUILocation(scssUISourceCode, 4, 2, rawLocationToUILocation(4, 8));
InspectorTest.checkUILocation(scssUISourceCode, 4, 2, rawLocationToUILocation(4, 10));
InspectorTest.checkUILocation(scssUISourceCode, 4, 11, rawLocationToUILocation(4, 11));
InspectorTest.checkUILocation(scssUISourceCode, 4, 13, rawLocationToUILocation(4, 15));
InspectorTest.checkUILocation(scssUISourceCode, 4, 17, rawLocationToUILocation(4, 20));
testAndDumpLocation(cssUISourceCode, 0, 3, 0, 3);
testAndDumpLocation(scssUISourceCode, 1, 0, 1, 0);
testAndDumpLocation(scssUISourceCode, 2, 2, 2, 4);
testAndDumpLocation(scssUISourceCode, 2, 5, 2, 6);
testAndDumpLocation(scssUISourceCode, 2, 7, 2, 9);
testAndDumpLocation(scssUISourceCode, 2, 10, 3, 7);
testAndDumpLocation(scssUISourceCode, 4, 2, 4, 8);
testAndDumpLocation(scssUISourceCode, 4, 2, 4, 10);
testAndDumpLocation(scssUISourceCode, 4, 11, 4, 11);
testAndDumpLocation(scssUISourceCode, 4, 13, 4, 15);
testAndDumpLocation(scssUISourceCode, 4, 17, 4, 20);
scssUISourceCode.requestContent().then(didRequestContent);
function didRequestContent(content, contentEncoded, mimeType)
......
......@@ -15,18 +15,18 @@ body {
Location mapping with formatted source:
Mapped locations:
0:15 -> 0:14
0:22 -> 1:9
0:65 -> 8:5
0:15 -> 0:14 -> 0:15
0:22 -> 1:9 -> 0:22
0:65 -> 8:5 -> 0:65
Live locations (updated: 3):
0:14
1:9
8:5
Location mapping without formatted source:
Mapped locations:
0:15 -> 0:15
0:22 -> 0:22
0:65 -> 0:65
0:15 -> 0:15 -> 0:15
0:22 -> 0:22 -> 0:22
0:65 -> 0:65 -> 0:65
Live locations (updated: 6):
0:15
0:22
......
......@@ -41,7 +41,9 @@ async function test()
InspectorTest.addResult("Mapped locations:");
for (var rawLocation of rawLocations) {
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}):`);
for (var liveLocation of liveLocations) {
......
......@@ -67,35 +67,35 @@ function formatted2() {
}
Location mapping with formatted source:
1:0 -> 0:22
6:0 -> 4:24
11:3 -> 9:4
11:29 -> 10:32
11:150 -> 14:20
11:227 -> 20:30
12:0 -> 22:30
12:157 -> 30:51
12:170 -> 31:22
13:0 -> 37:21
14:71 -> 50:23
14:97 -> 53:18
14:168 -> 56:18
14:237 -> 59:12
17:0 -> 61:22
1:0 -> 0:22 -> 1:0
6:0 -> 4:24 -> 6:0
11:3 -> 9:4 -> 11:3
11:29 -> 10:32 -> 11:29
11:150 -> 14:20 -> 11:150
11:227 -> 20:30 -> 11:227
12:0 -> 22:30 -> 12:0
12:157 -> 30:51 -> 12:157
12:170 -> 31:22 -> 12:170
13:0 -> 37:21 -> 13:0
14:71 -> 50:23 -> 14:71
14:97 -> 53:18 -> 14:97
14:168 -> 56:18 -> 14:168
14:237 -> 59:12 -> 14:237
17:0 -> 61:22 -> 17:0
Location mapping without formatted source:
1:0 -> 1:0
6:0 -> 6:0
11:3 -> 11:3
11:29 -> 11:29
11:150 -> 11:150
11:227 -> 11:227
12:0 -> 12:0
12:157 -> 12:157
12:170 -> 12:170
13:0 -> 13:0
14:71 -> 14:71
14:97 -> 14:97
14:168 -> 14:168
14:237 -> 14:237
17:0 -> 17:0
1:0 -> 1:0 -> 1:0
6:0 -> 6:0 -> 6:0
11:3 -> 11:3 -> 11:3
11:29 -> 11:29 -> 11:29
11:150 -> 11:150 -> 11:150
11:227 -> 11:227 -> 11:227
12:0 -> 12:0 -> 12:0
12:157 -> 12:157 -> 12:157
12:170 -> 12:170 -> 12:170
13:0 -> 13:0 -> 13:0
14:71 -> 14:71 -> 14:71
14:97 -> 14:97 -> 14:97
14:168 -> 14:168 -> 14:168
14:237 -> 14:237 -> 14:237
17:0 -> 17:0 -> 17:0
......@@ -34,7 +34,9 @@ async function test()
for (var position of positions) {
var rawLocation = InspectorTest.debuggerModel.createRawLocation(script, position.lineNumber, position.columnNumber);
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 {
}
/**
* @param {?SDK.CSSLocation} rawLocation
* @param {!SDK.CSSLocation} rawLocation
* @return {?Workspace.UILocation}
*/
rawLocationToUILocation(rawLocation) {
if (!rawLocation)
return null;
for (var i = this._sourceMappings.length - 1; i >= 0; --i) {
var uiLocation = this._sourceMappings[i].rawLocationToUILocation(rawLocation);
if (uiLocation)
......@@ -93,6 +91,22 @@ Bindings.CSSWorkspaceBinding = class {
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
*/
......@@ -112,6 +126,12 @@ Bindings.CSSWorkspaceBinding.SourceMapping.prototype = {
* @return {?Workspace.UILocation}
*/
rawLocationToUILocation(rawLocation) {},
/**
* @param {!Workspace.UILocation} uiLocation
* @return {!Array<!SDK.CSSLocation>}
*/
uiLocationToRawLocations(uiLocation) {},
};
Bindings.CSSWorkspaceBinding.ModelInfo = class {
......@@ -213,6 +233,18 @@ Bindings.CSSWorkspaceBinding.ModelInfo = class {
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() {
Common.EventTarget.removeEventListeners(this._eventListeners);
this._stylesSourceMapping.dispose();
......
......@@ -87,7 +87,9 @@ Bindings.SASSSourceMapping = class {
var contentProvider = sourceMap.sourceContentProvider(sassURL, Common.resourceTypes.SourceMapStyleSheet);
var embeddedContent = sourceMap.embeddedContentByURL(sassURL);
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);
this._sourceMapAttachedForTest(sourceMap);
......@@ -127,6 +129,7 @@ Bindings.SASSSourceMapping = class {
if (handledUISourceCodes.has(uiSourceCode))
continue;
handledUISourceCodes.add(uiSourceCode);
uiSourceCode[Bindings.SASSSourceMapping._sourceMapSymbol] = sourceMap;
var sassText = /** @type {string} */ (newSources.get(sourceURL));
uiSourceCode.setWorkingCopy(sassText);
}
......@@ -154,7 +157,26 @@ Bindings.SASSSourceMapping = class {
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() {
Common.EventTarget.removeEventListeners(this._eventListeners);
}
};
\ No newline at end of file
};
Bindings.SASSSourceMapping._sourceMapSymbol = Symbol('sourceMap');
......@@ -74,13 +74,32 @@ Bindings.StylesSourceMapping = class {
return null;
var lineNumber = rawLocation.lineNumber;
var columnNumber = rawLocation.columnNumber;
if (header && header.isInline && header.hasSourceURL) {
if (header.isInline && header.hasSourceURL) {
lineNumber -= header.lineNumberInSource(0);
columnNumber -= header.columnNumberInSource(lineNumber, 0);
}
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
*/
......
......@@ -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>}
*/
......
......@@ -256,6 +256,22 @@ Sources.SourceFormatter.StyleMapping = class {
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 {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