Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(131)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/formatter_worker/SCSSParser.js

Issue 1917863008: DevTools: [SASS] introduce Gonzales-PE for SCSS parsing (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix compilation Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 /**
6 * @constructor
7 */
8 WebInspector.SCSSParser = function()
9 {
10 }
11
12 /**
13 * @constructor
14 */
15 WebInspector.SCSSParser.Result = function()
16 {
17 this.properties = [];
18 this.variables = [];
19 this.mixins = [];
20 }
21
22 WebInspector.SCSSParser.prototype = {
23 /**
24 * @param {string} content
25 * @return {!Promise<!WebInspector.SCSSParser.Result>}
26 */
27 parse: function(content)
28 {
29 this._content = content;
dgozman 2016/04/29 01:16:17 Stateless!
lushnikov 2016/04/29 01:55:41 Done.
30 return self.runtime.loadModulePromise("gonzales")
dgozman 2016/04/29 01:16:17 Let's put this file into gonzales module and have
lushnikov 2016/04/29 01:55:42 Done.
31 .then(this._innerParse.bind(this, content))
32 .catch(onError)
33
34 /**
35 * @param {*} error
36 */
37 function onError(error)
38 {
39 console.error(error);
40 return new WebInspector.SCSSParser.Result();
41 }
42 },
43
44 /**
45 * @param {string} content
46 * @return {!WebInspector.SCSSParser.Result}
47 */
48 _innerParse: function(content)
49 {
50 var result = new WebInspector.SCSSParser.Result();
51 var ast = null;
52 try {
53 ast = gonzales.parse(content, {syntax: "scss"});
54 } catch (e) {
55 return result;
56 }
57
58 var extractedNodes = [];
59 WebInspector.SCSSParser.extractNodes(ast, extractedNodes);
60
61 for (var node of extractedNodes) {
62 if (node.type === "declaration")
63 this._handleDeclaration(node, result);
64 else if (node.type === "include")
65 this._handleInclude(node, result);
66 else if (node.type === "multilineComment" && node.start.line === nod e.end.line)
67 this._handleComment(node, result);
68 }
69 return result;
70 },
71
72 /**
73 * @param {!Gonzales.Node} node
74 * @param {!WebInspector.SCSSParser.Result} result
75 */
76 _handleDeclaration: function(node, result)
77 {
78 var propertyNode = node.content.find(node => node.type === "property");
79 var delimeterNode = node.content.find(node => node.type === "propertyDel imiter");
80 var valueNode = node.content.find(node => node.type === "value");
81 if (!propertyNode || !delimeterNode || !valueNode)
82 return;
83
84 var nameRange = new WebInspector.TextRange(propertyNode.start.line - 1, propertyNode.start.column - 1, delimeterNode.start.line - 1, delimeterNode.start .column - 1);
85 var valueRange = new WebInspector.TextRange(delimeterNode.end.line - 1, delimeterNode.end.column, valueNode.end.line - 1, valueNode.end.column);
86 var range = /** @type {!WebInspector.TextRange} */(node.declarationRange );
87
88 var property = new WebInspector.SCSSParser.Property(range, nameRange, va lueRange, false);
89 var isVariable = !!propertyNode.content.find(node => node.type === "vari able");
90 if (isVariable)
91 result.variables.push(property);
92 else
93 result.properties.push(property);
94 },
95
96 /**
97 * @param {!Gonzales.Node} node
98 * @param {!WebInspector.SCSSParser.Result} result
99 */
100 _handleInclude: function(node, result)
101 {
102 var mixinName = node.content.find(node => node.type === "ident");
103 if (!mixinName)
104 return;
105 var nameRange = WebInspector.SCSSParser.rangeFromNode(mixinName);
106 var mixinArguments = node.content.find(node => node.type === "arguments" );
107 if (!mixinArguments)
108 return;
109 var parameters = mixinArguments.content.filter(node => node.type !== "de limiter" && node.type !== "space");
dgozman 2016/04/29 01:16:17 Can we whitelist them?
lushnikov 2016/04/29 01:55:41 There are multiple different nodes: "15px" would b
110 for (var parameter of parameters) {
111 var range = WebInspector.SCSSParser.rangeFromNode(node);
112 var valueRange = WebInspector.SCSSParser.rangeFromNode(parameter);
113 var property = new WebInspector.SCSSParser.Property(range, nameRange , valueRange, false);
114 result.mixins.push(property);
115 }
116 },
117
118 /**
119 * @param {!Gonzales.Node} node
120 * @param {!WebInspector.SCSSParser.Result} result
121 */
122 _handleComment: function(node, result)
123 {
124 if (node.start.line !== node.end.line)
125 return;
126 var innerText = /** @type {string} */(node.content);
127 var innerResult = this._innerParse(innerText);
128 if (innerResult.properties.length !== 1 || innerResult.variables.length !== 0 || innerResult.mixins.length !== 0)
129 return;
130 var property = innerResult.properties[0];
131 var disabledProperty = property.rebaseInsideOneLineComment(node);
132 result.properties.push(disabledProperty);
133 },
134 }
135
136 /**
137 * @param {!Gonzales.Node} node
138 * @return {!WebInspector.TextRange}
139 */
140 WebInspector.SCSSParser.rangeFromNode = function(node)
141 {
142 return new WebInspector.TextRange(node.start.line - 1, node.start.column - 1 , node.end.line - 1, node.end.column);
143 }
144
145 /**
146 * @constructor
147 * @param {!WebInspector.TextRange} range
148 * @param {!WebInspector.TextRange} nameRange
149 * @param {!WebInspector.TextRange} valueRange
150 * @param {boolean} disabled
151 */
152 WebInspector.SCSSParser.Property = function(range, nameRange, valueRange, disabl ed)
153 {
154 this.range = range;
155 this.name = nameRange;
156 this.value = valueRange;
157 this.disabled = disabled;
158 }
159
160 WebInspector.SCSSParser.Property.prototype = {
161 /**
162 * @param {!Gonzales.Node} commentNode
163 * @return {!WebInspector.SCSSParser.Property}
164 */
165 rebaseInsideOneLineComment: function(commentNode)
166 {
167 var lineOffset = commentNode.start.line - 1;
168 var columnOffset = commentNode.start.column - 1 + 2;
dgozman 2016/04/29 01:16:17 // account 2 for "/*"
lushnikov 2016/04/29 01:55:41 Done.
169 var range = WebInspector.SCSSParser.rangeFromNode(commentNode);
170 var name = rebaseRange(this.name, lineOffset, columnOffset);
171 var value = rebaseRange(this.value, lineOffset, columnOffset);
172 return new WebInspector.SCSSParser.Property(range, name, value, true);
173
174 /**
175 * @param {!WebInspector.TextRange} range
176 * @param {number} lineOffset
177 * @param {number} columnOffset
178 * @return {!WebInspector.TextRange}
179 */
180 function rebaseRange(range, lineOffset, columnOffset)
181 {
182 return new WebInspector.TextRange(range.startLine + lineOffset, rang e.startColumn + columnOffset, range.endLine + lineOffset, range.endColumn + colu mnOffset);
183 }
184 }
185 }
186
187 /**
188 * @param {!Gonzales.Node} node
189 * @param {!Array<!Gonzales.Node>} output
190 */
191 WebInspector.SCSSParser.extractNodes = function(node, output)
192 {
193 if (!Array.isArray(node.content))
194 return;
195 var lastDeclaration = null;
196 for (var i = 0; i < node.content.length; ++i) {
197 var child = node.content[i];
198 if (child.type === "declarationDelimiter" && lastDeclaration) {
199 lastDeclaration.declarationRange.endLine = child.end.line - 1;
200 lastDeclaration.declarationRange.endColumn = child.end.column;
201 lastDeclaration = null;
202 }
203 if (child.type === "include" || child.type === "declaration" || child.ty pe === "multilineComment")
204 output.push(child);
205 if (child.type === "declaration") {
206 lastDeclaration = child;
207 lastDeclaration.declarationRange = WebInspector.TextRange.createFrom Location(child.start.line - 1, child.start.column - 1);
208 }
209 WebInspector.SCSSParser.extractNodes(child, output);
210 }
211 if (lastDeclaration) {
212 lastDeclaration.declarationRange.endLine = node.end.line - 1;
213 lastDeclaration.declarationRange.endColumn = node.end.column - 1;
214 }
215 }
216
217 /**
218 * @param {string} text
219 */
220 WebInspector.SCSSParser.parse = function(text)
221 {
222 var parser = new WebInspector.SCSSParser();
223 parser.parse(text).then(postMessage);
224 }
225
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698