OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 /** |
| 5 * @implements {WebInspector.SourceMapFactory} |
| 6 * @unrestricted |
| 7 */ |
| 8 WebInspector.SASSSourceMapFactory = class { |
| 9 constructor() { |
| 10 this._astService = new WebInspector.ASTService(); |
| 11 } |
4 | 12 |
5 /** | 13 /** |
6 * @constructor | 14 * @override |
7 * @implements {WebInspector.SourceMapFactory} | 15 * @param {!WebInspector.Target} target |
8 */ | 16 * @param {!WebInspector.SourceMap} sourceMap |
9 WebInspector.SASSSourceMapFactory = function() | 17 * @return {!Promise<?WebInspector.SourceMap>} |
10 { | 18 */ |
11 this._astService = new WebInspector.ASTService(); | 19 editableSourceMap(target, sourceMap) { |
12 }; | 20 var cssModel = WebInspector.CSSModel.fromTarget(target); |
| 21 if (!cssModel) |
| 22 return Promise.resolve(/** @type {?WebInspector.SourceMap} */ (null)); |
13 | 23 |
14 WebInspector.SASSSourceMapFactory.prototype = { | 24 var header = |
15 /** | 25 cssModel.styleSheetHeaders().find(styleSheetHeader => styleSheetHeader.s
ourceMapURL === sourceMap.url()); |
16 * @override | 26 if (!header) |
17 * @param {!WebInspector.Target} target | 27 return Promise.resolve(/** @type {?WebInspector.SourceMap} */ (null)); |
18 * @param {!WebInspector.SourceMap} sourceMap | |
19 * @return {!Promise<?WebInspector.SourceMap>} | |
20 */ | |
21 editableSourceMap: function(target, sourceMap) | |
22 { | |
23 var cssModel = WebInspector.CSSModel.fromTarget(target); | |
24 if (!cssModel) | |
25 return Promise.resolve(/** @type {?WebInspector.SourceMap} */(null))
; | |
26 | 28 |
27 var header = cssModel.styleSheetHeaders().find(styleSheetHeader => style
SheetHeader.sourceMapURL === sourceMap.url()); | 29 /** @type {!Map<string, !WebInspector.SASSSupport.AST>} */ |
28 if (!header) | 30 var models = new Map(); |
29 return Promise.resolve(/** @type {?WebInspector.SourceMap} */(null))
; | 31 var promises = []; |
| 32 for (let url of sourceMap.sourceURLs()) { |
| 33 var contentProvider = sourceMap.sourceContentProvider(url, WebInspector.re
sourceTypes.SourceMapStyleSheet); |
| 34 var sassPromise = contentProvider.requestContent() |
| 35 .then(text => this._astService.parseSCSS(url, text |
| '')) |
| 36 .then(ast => models.set(ast.document.url, ast)); |
| 37 promises.push(sassPromise); |
| 38 } |
| 39 var cssURL = sourceMap.compiledURL(); |
| 40 var cssPromise = header.originalContentProvider() |
| 41 .requestContent() |
| 42 .then(text => this._astService.parseCSS(cssURL, text ||
'')) |
| 43 .then(ast => models.set(ast.document.url, ast)); |
| 44 promises.push(cssPromise); |
30 | 45 |
31 /** @type {!Map<string, !WebInspector.SASSSupport.AST>} */ | 46 return Promise.all(promises) |
32 var models = new Map(); | 47 .then(this._onSourcesParsed.bind(this, sourceMap, models)) |
33 var promises = []; | 48 .catchException(/** @type {?WebInspector.SourceMap} */ (null)); |
34 for (let url of sourceMap.sourceURLs()) { | 49 } |
35 var contentProvider = sourceMap.sourceContentProvider(url, WebInspec
tor.resourceTypes.SourceMapStyleSheet); | |
36 var sassPromise = contentProvider.requestContent() | |
37 .then(text => this._astService.parseSCSS(url, text || "")) | |
38 .then(ast => models.set(ast.document.url, ast)); | |
39 promises.push(sassPromise); | |
40 } | |
41 var cssURL = sourceMap.compiledURL(); | |
42 var cssPromise = header.originalContentProvider().requestContent() | |
43 .then(text => this._astService.parseCSS(cssURL, text || "")) | |
44 .then(ast => models.set(ast.document.url, ast)); | |
45 promises.push(cssPromise); | |
46 | 50 |
47 return Promise.all(promises) | 51 /** |
48 .then(this._onSourcesParsed.bind(this, sourceMap, models)) | 52 * @param {!WebInspector.SourceMap} sourceMap |
49 .catchException(/** @type {?WebInspector.SourceMap} */(null)); | 53 * @param {!Map<string, !WebInspector.SASSSupport.AST>} models |
50 }, | 54 * @return {?WebInspector.SourceMap} |
| 55 */ |
| 56 _onSourcesParsed(sourceMap, models) { |
| 57 var editCallback = WebInspector.SASSProcessor.processCSSEdits.bind(WebInspec
tor.SASSProcessor, this._astService); |
| 58 var map = new WebInspector.ASTSourceMap(sourceMap.compiledURL(), sourceMap.u
rl(), models, editCallback); |
| 59 var valid = true; |
| 60 map.compiledModel().visit(onNode); |
| 61 return valid ? map : null; |
51 | 62 |
52 /** | 63 /** |
53 * @param {!WebInspector.SourceMap} sourceMap | 64 * @param {!WebInspector.SASSSupport.Node} cssNode |
54 * @param {!Map<string, !WebInspector.SASSSupport.AST>} models | |
55 * @return {?WebInspector.SourceMap} | |
56 */ | 65 */ |
57 _onSourcesParsed: function(sourceMap, models) | 66 function onNode(cssNode) { |
58 { | 67 if (!valid) |
59 var editCallback = WebInspector.SASSProcessor.processCSSEdits.bind(WebIn
spector.SASSProcessor, this._astService); | 68 return; |
60 var map = new WebInspector.ASTSourceMap(sourceMap.compiledURL(), sourceM
ap.url(), models, editCallback); | 69 if (!(cssNode instanceof WebInspector.SASSSupport.TextNode)) |
61 var valid = true; | 70 return; |
62 map.compiledModel().visit(onNode); | 71 var entry = sourceMap.findEntry(cssNode.range.startLine, cssNode.range.sta
rtColumn); |
63 return valid ? map : null; | 72 if (!entry || !entry.sourceURL || typeof entry.sourceLineNumber === 'undef
ined' || |
| 73 typeof entry.sourceColumnNumber === 'undefined') |
| 74 return; |
| 75 var sassAST = models.get(entry.sourceURL); |
| 76 if (!sassAST) |
| 77 return; |
| 78 var sassNode = sassAST.findNodeForPosition(entry.sourceLineNumber, entry.s
ourceColumnNumber); |
| 79 if (!sassNode) |
| 80 return; |
| 81 if (cssNode.parent && (cssNode.parent instanceof WebInspector.SASSSupport.
Property) && |
| 82 cssNode === cssNode.parent.name && cssNode.text.trim() !== sassNode.te
xt.trim()) { |
| 83 valid = false; |
| 84 reportError(cssNode, sassNode); |
| 85 return; |
| 86 } |
| 87 map.addMapping(cssNode, sassNode); |
| 88 } |
64 | 89 |
65 /** | 90 /** |
66 * @param {!WebInspector.SASSSupport.Node} cssNode | 91 * @param {!WebInspector.SASSSupport.TextNode} cssNode |
67 */ | 92 * @param {!WebInspector.SASSSupport.TextNode} sassNode |
68 function onNode(cssNode) | 93 */ |
69 { | 94 function reportError(cssNode, sassNode) { |
70 if (!valid) | 95 var text = WebInspector.UIString('LiveSASS failed to start: %s', sourceMap
.url()); |
71 return; | 96 text += WebInspector.UIString('\nSourceMap is misaligned: %s != %s', cssNo
de.text.trim(), sassNode.text.trim()); |
72 if (!(cssNode instanceof WebInspector.SASSSupport.TextNode)) | 97 text += '\ncompiled: ' + cssNode.document.url + ':' + (cssNode.range.start
Line + 1) + ':' + |
73 return; | 98 (cssNode.range.startColumn + 1); |
74 var entry = sourceMap.findEntry(cssNode.range.startLine, cssNode.ran
ge.startColumn); | 99 text += '\nsource: ' + sassNode.document.url + ':' + (sassNode.range.start
Line + 1) + ':' + |
75 if (!entry || !entry.sourceURL || typeof entry.sourceLineNumber ===
"undefined" || typeof entry.sourceColumnNumber === "undefined") | 100 (sassNode.range.startColumn + 1); |
76 return; | 101 WebInspector.console.error(text); |
77 var sassAST = models.get(entry.sourceURL); | 102 } |
78 if (!sassAST) | 103 } |
79 return; | |
80 var sassNode = sassAST.findNodeForPosition(entry.sourceLineNumber, e
ntry.sourceColumnNumber); | |
81 if (!sassNode) | |
82 return; | |
83 if (cssNode.parent && (cssNode.parent instanceof WebInspector.SASSSu
pport.Property) && cssNode === cssNode.parent.name && cssNode.text.trim() !== sa
ssNode.text.trim()) { | |
84 valid = false; | |
85 reportError(cssNode, sassNode); | |
86 return; | |
87 } | |
88 map.addMapping(cssNode, sassNode); | |
89 } | |
90 | |
91 /** | |
92 * @param {!WebInspector.SASSSupport.TextNode} cssNode | |
93 * @param {!WebInspector.SASSSupport.TextNode} sassNode | |
94 */ | |
95 function reportError(cssNode, sassNode) | |
96 { | |
97 var text = WebInspector.UIString("LiveSASS failed to start: %s", sou
rceMap.url()); | |
98 text += WebInspector.UIString("\nSourceMap is misaligned: %s != %s",
cssNode.text.trim(), sassNode.text.trim()); | |
99 text += "\ncompiled: " + cssNode.document.url + ":" + (cssNode.range
.startLine + 1) + ":" + (cssNode.range.startColumn + 1); | |
100 text += "\nsource: " + sassNode.document.url + ":" + (sassNode.range
.startLine + 1) + ":" + (sassNode.range.startColumn + 1); | |
101 WebInspector.console.error(text); | |
102 } | |
103 }, | |
104 }; | 104 }; |
OLD | NEW |