OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 | 4 |
5 WebInspector.SASSSupport = {} | 5 WebInspector.SASSSupport = {} |
6 | 6 |
7 /** | 7 /** |
8 * @param {string} url | 8 * @param {string} url |
9 * @param {string} text | 9 * @param {string} text |
10 * @return {!Promise<!WebInspector.SASSSupport.AST>} | 10 * @return {!Promise<!WebInspector.SASSSupport.AST>} |
(...skipping 24 matching lines...) Expand all Loading... |
35 var property = new WebInspector.SASSSupport.Property(document, n
ame, value, WebInspector.TextRange.fromObject(cssProperty.range), !!cssProperty.
disabled); | 35 var property = new WebInspector.SASSSupport.Property(document, n
ame, value, WebInspector.TextRange.fromObject(cssProperty.range), !!cssProperty.
disabled); |
36 properties.push(property); | 36 properties.push(property); |
37 } | 37 } |
38 rules.push(new WebInspector.SASSSupport.Rule(document, rule.selector
Text, WebInspector.TextRange.fromObject(rule.styleRange), properties)); | 38 rules.push(new WebInspector.SASSSupport.Rule(document, rule.selector
Text, WebInspector.TextRange.fromObject(rule.styleRange), properties)); |
39 } | 39 } |
40 return new WebInspector.SASSSupport.AST(document, rules); | 40 return new WebInspector.SASSSupport.AST(document, rules); |
41 } | 41 } |
42 } | 42 } |
43 | 43 |
44 /** | 44 /** |
45 * @param {!WebInspector.TokenizerFactory} tokenizerFactory | |
46 * @param {string} url | 45 * @param {string} url |
47 * @param {string} text | 46 * @param {string} content |
48 * @return {!WebInspector.SASSSupport.AST} | 47 * @return {!Promise<!WebInspector.SASSSupport.AST>} |
49 */ | 48 */ |
50 WebInspector.SASSSupport.parseSCSS = function(tokenizerFactory, url, text) | 49 WebInspector.SASSSupport.parseSCSS = function(url, content) |
51 { | 50 { |
52 var document = new WebInspector.SASSSupport.ASTDocument(url, new WebInspecto
r.Text(text)); | 51 var text = new WebInspector.Text(content); |
53 var result = WebInspector.SASSSupport._innerParseSCSS(document, tokenizerFac
tory); | 52 var document = new WebInspector.SASSSupport.ASTDocument(url, text); |
54 | 53 |
55 var rules = [ | 54 return WebInspector.formatterWorkerPool.runTask("parseSCSS", {content: conte
nt}).then(onParsed); |
56 new WebInspector.SASSSupport.Rule(document, "variables", WebInspector.Te
xtRange.createFromLocation(0, 0), result.variables), | |
57 new WebInspector.SASSSupport.Rule(document, "properties", WebInspector.T
extRange.createFromLocation(0, 0), result.properties), | |
58 new WebInspector.SASSSupport.Rule(document, "mixins", WebInspector.TextR
ange.createFromLocation(0, 0), result.mixins) | |
59 ]; | |
60 | |
61 return new WebInspector.SASSSupport.AST(document, rules); | |
62 } | |
63 | |
64 /** @enum {string} */ | |
65 WebInspector.SASSSupport.SCSSParserStates = { | |
66 Initial: "Initial", | |
67 PropertyName: "PropertyName", | |
68 PropertyValue: "PropertyValue", | |
69 VariableName: "VariableName", | |
70 VariableValue: "VariableValue", | |
71 MixinName: "MixinName", | |
72 MixinValue: "MixinValue", | |
73 Media: "Media" | |
74 } | |
75 | |
76 /** | |
77 * @param {!WebInspector.SASSSupport.ASTDocument} document | |
78 * @param {!WebInspector.TokenizerFactory} tokenizerFactory | |
79 * @return {!{variables: !Array<!WebInspector.SASSSupport.Property>, properties:
!Array<!WebInspector.SASSSupport.Property>, mixins: !Array<!WebInspector.SASSSu
pport.Property>}} | |
80 */ | |
81 WebInspector.SASSSupport._innerParseSCSS = function(document, tokenizerFactory) | |
82 { | |
83 var properties = []; | |
84 var variables = []; | |
85 var mixins = []; | |
86 | |
87 var States = WebInspector.SASSSupport.SCSSParserStates; | |
88 var state = States.Initial; | |
89 var propertyName, propertyValue; | |
90 var variableName, variableValue; | |
91 var mixinName, mixinValue; | |
92 var UndefTokenType = {}; | |
93 | |
94 var cursor = new WebInspector.TextCursor(document.text.lineEndings()); | |
95 | 55 |
96 /** | 56 /** |
97 * @param {string} tokenValue | 57 * @param {?MessageEvent} event |
98 * @param {?string} tokenTypes | 58 * @return {!WebInspector.SASSSupport.AST} |
99 * @param {number} startPosition | |
100 * @param {number} endPosition | |
101 */ | 59 */ |
102 function processToken(tokenValue, tokenTypes, startPosition, endPosition) | 60 function onParsed(event) |
103 { | 61 { |
104 cursor.advance(startPosition); | 62 if (!event) |
105 var startLine = cursor.lineNumber(); | 63 return new WebInspector.SASSSupport.AST(document, []); |
106 var startColumn = cursor.columnNumber(); | 64 var data = /** @type {!{properties: !Array<!Object>, variables: !Array<!
Object>, mixins: !Array<!Object>}} */(event.data); |
107 cursor.advance(endPosition); | 65 var properties = data.properties.map(createProperty); |
108 var endLine = cursor.lineNumber(); | 66 var variables = data.variables.map(createProperty); |
109 var endColumn = cursor.columnNumber(); | 67 var mixins = data.mixins.map(createProperty); |
| 68 var rules = [ |
| 69 new WebInspector.SASSSupport.Rule(document, "variables", WebInspecto
r.TextRange.createFromLocation(0, 0), variables), |
| 70 new WebInspector.SASSSupport.Rule(document, "properties", WebInspect
or.TextRange.createFromLocation(0, 0), properties), |
| 71 new WebInspector.SASSSupport.Rule(document, "mixins", WebInspector.T
extRange.createFromLocation(0, 0), mixins) |
| 72 ]; |
110 | 73 |
111 var tokenType = tokenTypes ? tokenTypes.split(" ").keySet() : UndefToken
Type; | 74 return new WebInspector.SASSSupport.AST(document, rules); |
112 switch (state) { | |
113 case States.Initial: | |
114 if (tokenType["css-variable-2"]) { | |
115 variableName = new WebInspector.SASSSupport.TextNode(document, t
okenValue, new WebInspector.TextRange(startLine, startColumn, endLine, endColumn
)); | |
116 state = States.VariableName; | |
117 } else if (tokenType["css-property"] || tokenType["css-meta"]) { | |
118 propertyName = new WebInspector.SASSSupport.TextNode(document, t
okenValue, new WebInspector.TextRange(startLine, startColumn, endLine, endColumn
)); | |
119 state = States.PropertyName; | |
120 } else if (tokenType["css-def"] && tokenValue === "@include") { | |
121 mixinName = new WebInspector.SASSSupport.TextNode(document, toke
nValue, new WebInspector.TextRange(startLine, startColumn, endLine, endColumn)); | |
122 state = States.MixinName; | |
123 } else if (tokenType["css-comment"]) { | |
124 // Support only a one-line comments. | |
125 if (startLine !== endLine || tokenValue.substring(0, 2) !== "/*"
|| tokenValue.substring(tokenValue.length - 2) !== "*/") | |
126 break; | |
127 var uncommentedText = tokenValue.substring(2, tokenValue.length
- 2); | |
128 var fakeRuleText = "a{" + uncommentedText + "}"; | |
129 var fakeDocument = new WebInspector.SASSSupport.ASTDocument("",
new WebInspector.Text(fakeRuleText)); | |
130 var result = WebInspector.SASSSupport._innerParseSCSS(fakeDocume
nt, tokenizerFactory); | |
131 if (result.properties.length === 1 && result.variables.length ==
= 0 && result.mixins.length === 0) { | |
132 var disabledProperty = result.properties[0]; | |
133 var nameRange = rebaseInsideOneLineComment(disabledProperty.
name.range, startLine, startColumn); | |
134 var valueRange = rebaseInsideOneLineComment(disabledProperty
.value.range, startLine, startColumn); | |
135 var name = new WebInspector.SASSSupport.TextNode(document, d
isabledProperty.name.text, nameRange); | |
136 var value = new WebInspector.SASSSupport.TextNode(document,
disabledProperty.value.text, valueRange); | |
137 var range = new WebInspector.TextRange(startLine, startColum
n, startLine, endColumn); | |
138 var property = new WebInspector.SASSSupport.Property(documen
t, name, value, range, true); | |
139 properties.push(property); | |
140 } | |
141 } else if (tokenType["css-def"] && tokenValue === "@media") { | |
142 state = States.Media; | |
143 } | |
144 break; | |
145 case States.VariableName: | |
146 if (tokenValue === "}" && tokenType === UndefTokenType) { | |
147 state = States.Initial; | |
148 } else if (tokenValue === ")" && tokenType === UndefTokenType) { | |
149 state = States.Initial; | |
150 } else if (tokenValue === ":" && tokenType === UndefTokenType) { | |
151 state = States.VariableValue; | |
152 variableValue = new WebInspector.SASSSupport.TextNode(document,
"", WebInspector.TextRange.createFromLocation(startLine, endColumn)); | |
153 } else if (tokenType !== UndefTokenType) { | |
154 state = States.Initial; | |
155 } | |
156 break; | |
157 case States.VariableValue: | |
158 if (tokenValue === ";" && tokenType === UndefTokenType) { | |
159 variableValue.range.endLine = startLine; | |
160 variableValue.range.endColumn = startColumn; | |
161 var variable = new WebInspector.SASSSupport.Property(document, v
ariableName, variableValue, variableName.range.clone(), false); | |
162 variable.range.endLine = startLine; | |
163 variable.range.endColumn = endColumn; | |
164 variables.push(variable); | |
165 state = States.Initial; | |
166 } else { | |
167 variableValue.text += tokenValue; | |
168 } | |
169 break; | |
170 case States.PropertyName: | |
171 if (tokenValue === "{" && tokenType === UndefTokenType) { | |
172 state = States.Initial; | |
173 } else if (tokenValue === ":" && tokenType === UndefTokenType) { | |
174 state = States.PropertyValue; | |
175 propertyName.range.endLine = startLine; | |
176 propertyName.range.endColumn = startColumn; | |
177 propertyValue = new WebInspector.SASSSupport.TextNode(document,
"", WebInspector.TextRange.createFromLocation(startLine, endColumn)); | |
178 } else if (tokenType["css-property"]) { | |
179 propertyName.text += tokenValue; | |
180 } | |
181 break; | |
182 case States.PropertyValue: | |
183 if (tokenValue === "{" && tokenType === UndefTokenType) { | |
184 state = States.Initial; | |
185 } else if ((tokenValue === "}" || tokenValue === ";") && tokenType =
== UndefTokenType) { | |
186 propertyValue.range.endLine = startLine; | |
187 propertyValue.range.endColumn = startColumn; | |
188 var property = new WebInspector.SASSSupport.Property(document, p
ropertyName, propertyValue, propertyName.range.clone(), false); | |
189 property.range.endLine = startLine; | |
190 property.range.endColumn = endColumn; | |
191 properties.push(property); | |
192 state = States.Initial; | |
193 } else { | |
194 propertyValue.text += tokenValue; | |
195 } | |
196 break; | |
197 case States.MixinName: | |
198 if (tokenValue === "(" && tokenType === UndefTokenType) { | |
199 state = States.MixinValue; | |
200 mixinName.range.endLine = startLine; | |
201 mixinName.range.endColumn = startColumn; | |
202 mixinValue = new WebInspector.SASSSupport.TextNode(document, "",
WebInspector.TextRange.createFromLocation(startLine, endColumn)); | |
203 } else if (tokenValue === ";" && tokenType === UndefTokenType) { | |
204 state = States.Initial; | |
205 mixinValue = null; | |
206 } else { | |
207 mixinName.text += tokenValue; | |
208 } | |
209 break; | |
210 case States.MixinValue: | |
211 if (tokenValue === ")" && tokenType === UndefTokenType) { | |
212 mixinValue.range.endLine = startLine; | |
213 mixinValue.range.endColumn = startColumn; | |
214 var mixin = new WebInspector.SASSSupport.Property(document, mixi
nName, /** @type {!WebInspector.SASSSupport.TextNode} */(mixinValue), mixinName.
range.clone(), false); | |
215 mixin.range.endLine = startLine; | |
216 mixin.range.endColumn = endColumn; | |
217 mixins.push(mixin); | |
218 state = States.Initial; | |
219 } else { | |
220 mixinValue.text += tokenValue; | |
221 } | |
222 break; | |
223 case States.Media: | |
224 if (tokenValue === "{" && tokenType === UndefTokenType) | |
225 state = States.Initial; | |
226 break; | |
227 default: | |
228 console.assert(false, "Unknown SASS parser state."); | |
229 } | |
230 } | 75 } |
231 var tokenizer = tokenizerFactory.createTokenizer("text/x-scss"); | |
232 tokenizer(document.text.value(), processToken); | |
233 | |
234 return { | |
235 variables: variables, | |
236 properties: properties, | |
237 mixins: mixins | |
238 }; | |
239 | 76 |
240 /** | 77 /** |
241 * @param {!WebInspector.TextRange} range | 78 * @param {!Object} payload |
242 * @param {number} startLine | |
243 * @param {number} startColumn | |
244 * @return {!WebInspector.TextRange} | |
245 */ | 79 */ |
246 function rebaseInsideOneLineComment(range, startLine, startColumn) | 80 function createTextNode(payload) |
247 { | 81 { |
248 return new WebInspector.TextRange(range.startLine + startLine, range.sta
rtColumn + startColumn, range.endLine + startLine, range.endColumn + startColumn
); | 82 var range = WebInspector.TextRange.fromObject(payload); |
| 83 var value = text.extract(range); |
| 84 return new WebInspector.SASSSupport.TextNode(document, text.extract(rang
e), range); |
| 85 } |
| 86 |
| 87 /** |
| 88 * @param {!Object} payload |
| 89 */ |
| 90 function createProperty(payload) |
| 91 { |
| 92 var name = createTextNode(payload.name); |
| 93 var value = createTextNode(payload.value); |
| 94 return new WebInspector.SASSSupport.Property(document, name, value, WebI
nspector.TextRange.fromObject(payload.range), payload.disabled); |
249 } | 95 } |
250 } | 96 } |
251 | 97 |
252 /** | 98 /** |
253 * @constructor | 99 * @constructor |
254 * @param {string} url | 100 * @param {string} url |
255 * @param {!WebInspector.Text} text | 101 * @param {!WebInspector.Text} text |
256 */ | 102 */ |
257 WebInspector.SASSSupport.ASTDocument = function(url, text) | 103 WebInspector.SASSSupport.ASTDocument = function(url, text) |
258 { | 104 { |
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
852 mapping.set(oldProperty.name, newProperty.name); | 698 mapping.set(oldProperty.name, newProperty.name); |
853 mapping.set(oldProperty.value, newProperty.value); | 699 mapping.set(oldProperty.value, newProperty.value); |
854 if (oldProperty.name.text.trim() !== newProperty.name.text.trim()) | 700 if (oldProperty.name.text.trim() !== newProperty.name.text.trim()) |
855 addChange(T.NameChanged, oldRule, newRule, oldPropertyIndex, newProp
ertyIndex); | 701 addChange(T.NameChanged, oldRule, newRule, oldPropertyIndex, newProp
ertyIndex); |
856 if (oldProperty.value.text.trim() !== newProperty.value.text.trim()) | 702 if (oldProperty.value.text.trim() !== newProperty.value.text.trim()) |
857 addChange(T.ValueChanged, oldRule, newRule, oldPropertyIndex, newPro
pertyIndex); | 703 addChange(T.ValueChanged, oldRule, newRule, oldPropertyIndex, newPro
pertyIndex); |
858 if (oldProperty.disabled !== newProperty.disabled) | 704 if (oldProperty.disabled !== newProperty.disabled) |
859 addChange(T.PropertyToggled, oldRule, newRule, oldPropertyIndex, new
PropertyIndex); | 705 addChange(T.PropertyToggled, oldRule, newRule, oldPropertyIndex, new
PropertyIndex); |
860 } | 706 } |
861 } | 707 } |
OLD | NEW |