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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/gonzales/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: rebaseline 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 * @implements {WebInspector.FormatterWorkerContentParser}
8 */
9 WebInspector.SCSSParser = function()
10 {
11 }
12
13 /**
14 * @constructor
15 */
16 WebInspector.SCSSParser.Result = function()
17 {
18 this.properties = [];
19 this.variables = [];
20 this.mixins = [];
21 }
22
23 WebInspector.SCSSParser.prototype = {
24 /**
25 * @override
26 * @param {string} content
27 * @return {!WebInspector.SCSSParser.Result}
28 */
29 parse: function(content)
30 {
31 var result = new WebInspector.SCSSParser.Result();
32 var ast = null;
33 try {
34 ast = gonzales.parse(content, {syntax: "scss"});
35 } catch (e) {
36 return result;
37 }
38
39 var extractedNodes = [];
40 WebInspector.SCSSParser.extractNodes(ast, extractedNodes);
41
42 for (var node of extractedNodes) {
43 if (node.type === "declaration")
44 this._handleDeclaration(node, result);
45 else if (node.type === "include")
46 this._handleInclude(node, result);
47 else if (node.type === "multilineComment" && node.start.line === nod e.end.line)
48 this._handleComment(node, result);
49 }
50 return result;
51 },
52
53 /**
54 * @param {!Gonzales.Node} node
55 * @param {!WebInspector.SCSSParser.Result} result
56 */
57 _handleDeclaration: function(node, result)
58 {
59 var propertyNode = node.content.find(node => node.type === "property");
60 var delimeterNode = node.content.find(node => node.type === "propertyDel imiter");
61 var valueNode = node.content.find(node => node.type === "value");
62 if (!propertyNode || !delimeterNode || !valueNode)
63 return;
64
65 var nameRange = new WebInspector.TextRange(propertyNode.start.line - 1, propertyNode.start.column - 1, delimeterNode.start.line - 1, delimeterNode.start .column - 1);
66 var valueRange = new WebInspector.TextRange(delimeterNode.end.line - 1, delimeterNode.end.column, valueNode.end.line - 1, valueNode.end.column);
67 var range = /** @type {!WebInspector.TextRange} */(node.declarationRange );
68
69 var property = new WebInspector.SCSSParser.Property(range, nameRange, va lueRange, false);
70 var isVariable = !!propertyNode.content.find(node => node.type === "vari able");
71 if (isVariable)
72 result.variables.push(property);
73 else
74 result.properties.push(property);
75 },
76
77 /**
78 * @param {!Gonzales.Node} node
79 * @param {!WebInspector.SCSSParser.Result} result
80 */
81 _handleInclude: function(node, result)
82 {
83 var mixinName = node.content.find(node => node.type === "ident");
84 if (!mixinName)
85 return;
86 var nameRange = WebInspector.SCSSParser.rangeFromNode(mixinName);
87 var mixinArguments = node.content.find(node => node.type === "arguments" );
88 if (!mixinArguments)
89 return;
90 var parameters = mixinArguments.content.filter(node => node.type !== "de limiter" && node.type !== "space");
91 for (var parameter of parameters) {
92 var range = WebInspector.SCSSParser.rangeFromNode(node);
93 var valueRange = WebInspector.SCSSParser.rangeFromNode(parameter);
94 var property = new WebInspector.SCSSParser.Property(range, nameRange , valueRange, false);
95 result.mixins.push(property);
96 }
97 },
98
99 /**
100 * @param {!Gonzales.Node} node
101 * @param {!WebInspector.SCSSParser.Result} result
102 */
103 _handleComment: function(node, result)
104 {
105 if (node.start.line !== node.end.line)
106 return;
107 var innerText = /** @type {string} */(node.content);
108 var innerResult = this.parse(innerText);
109 if (innerResult.properties.length !== 1 || innerResult.variables.length !== 0 || innerResult.mixins.length !== 0)
110 return;
111 var property = innerResult.properties[0];
112 var disabledProperty = property.rebaseInsideOneLineComment(node);
113 result.properties.push(disabledProperty);
114 },
115 }
116
117 /**
118 * @param {!Gonzales.Node} node
119 * @return {!WebInspector.TextRange}
120 */
121 WebInspector.SCSSParser.rangeFromNode = function(node)
122 {
123 return new WebInspector.TextRange(node.start.line - 1, node.start.column - 1 , node.end.line - 1, node.end.column);
124 }
125
126 /**
127 * @constructor
128 * @param {!WebInspector.TextRange} range
129 * @param {!WebInspector.TextRange} nameRange
130 * @param {!WebInspector.TextRange} valueRange
131 * @param {boolean} disabled
132 */
133 WebInspector.SCSSParser.Property = function(range, nameRange, valueRange, disabl ed)
134 {
135 this.range = range;
136 this.name = nameRange;
137 this.value = valueRange;
138 this.disabled = disabled;
139 }
140
141 WebInspector.SCSSParser.Property.prototype = {
142 /**
143 * @param {!Gonzales.Node} commentNode
144 * @return {!WebInspector.SCSSParser.Property}
145 */
146 rebaseInsideOneLineComment: function(commentNode)
147 {
148 var lineOffset = commentNode.start.line - 1;
149 // Account for the "/*".
150 var columnOffset = commentNode.start.column - 1 + 2;
151 var range = WebInspector.SCSSParser.rangeFromNode(commentNode);
152 var name = rebaseRange(this.name, lineOffset, columnOffset);
153 var value = rebaseRange(this.value, lineOffset, columnOffset);
154 return new WebInspector.SCSSParser.Property(range, name, value, true);
155
156 /**
157 * @param {!WebInspector.TextRange} range
158 * @param {number} lineOffset
159 * @param {number} columnOffset
160 * @return {!WebInspector.TextRange}
161 */
162 function rebaseRange(range, lineOffset, columnOffset)
163 {
164 return new WebInspector.TextRange(range.startLine + lineOffset, rang e.startColumn + columnOffset, range.endLine + lineOffset, range.endColumn + colu mnOffset);
165 }
166 }
167 }
168
169 /**
170 * @param {!Gonzales.Node} node
171 * @param {!Array<!Gonzales.Node>} output
172 */
173 WebInspector.SCSSParser.extractNodes = function(node, output)
174 {
175 if (!Array.isArray(node.content))
176 return;
177 var lastDeclaration = null;
178 for (var i = 0; i < node.content.length; ++i) {
179 var child = node.content[i];
180 if (child.type === "declarationDelimiter" && lastDeclaration) {
181 lastDeclaration.declarationRange.endLine = child.end.line - 1;
182 lastDeclaration.declarationRange.endColumn = child.end.column;
183 lastDeclaration = null;
184 }
185 if (child.type === "include" || child.type === "declaration" || child.ty pe === "multilineComment")
186 output.push(child);
187 if (child.type === "declaration") {
188 lastDeclaration = child;
189 lastDeclaration.declarationRange = WebInspector.TextRange.createFrom Location(child.start.line - 1, child.start.column - 1);
190 }
191 WebInspector.SCSSParser.extractNodes(child, output);
192 }
193 if (lastDeclaration) {
194 lastDeclaration.declarationRange.endLine = node.end.line - 1;
195 lastDeclaration.declarationRange.endColumn = node.end.column - 1;
196 }
197 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698