vscode-css-languageservice 6.3.10 → 7.0.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/lib/esm/beautify/beautify-css.js +1437 -1606
- package/lib/esm/cssLanguageService.d.ts +2 -2
- package/lib/esm/cssLanguageService.js +18 -18
- package/lib/esm/languageFacts/colors.js +1 -1
- package/lib/esm/languageFacts/dataManager.js +3 -3
- package/lib/esm/languageFacts/entry.js +1 -1
- package/lib/esm/languageFacts/facts.js +3 -3
- package/lib/esm/parser/cssNodes.js +1 -1
- package/lib/esm/parser/cssParser.js +5 -5
- package/lib/esm/parser/cssSymbolScope.js +2 -2
- package/lib/esm/parser/lessParser.js +5 -5
- package/lib/esm/parser/lessScanner.js +1 -1
- package/lib/esm/parser/scssParser.js +6 -6
- package/lib/esm/parser/scssScanner.js +1 -1
- package/lib/esm/services/cssCodeActions.js +4 -4
- package/lib/esm/services/cssCompletion.js +7 -7
- package/lib/esm/services/cssFolding.js +3 -3
- package/lib/esm/services/cssFormatter.js +3 -3
- package/lib/esm/services/cssHover.js +6 -6
- package/lib/esm/services/cssNavigation.js +6 -6
- package/lib/esm/services/cssSelectionRange.js +2 -2
- package/lib/esm/services/cssValidation.js +4 -4
- package/lib/esm/services/lessCompletion.js +2 -2
- package/lib/esm/services/lint.js +5 -5
- package/lib/esm/services/lintRules.js +1 -1
- package/lib/esm/services/lintUtil.js +1 -1
- package/lib/esm/services/pathCompletion.js +3 -3
- package/lib/esm/services/scssCompletion.js +3 -3
- package/lib/esm/services/scssNavigation.js +4 -4
- package/lib/esm/services/selectorPrinting.js +3 -3
- package/package.json +15 -15
- package/lib/umd/beautify/beautify-css.js +0 -1695
- package/lib/umd/cssLanguageService.d.ts +0 -39
- package/lib/umd/cssLanguageService.js +0 -105
- package/lib/umd/cssLanguageTypes.d.ts +0 -267
- package/lib/umd/cssLanguageTypes.js +0 -89
- package/lib/umd/data/webCustomData.js +0 -44613
- package/lib/umd/languageFacts/builtinData.js +0 -155
- package/lib/umd/languageFacts/colors.js +0 -949
- package/lib/umd/languageFacts/dataManager.js +0 -101
- package/lib/umd/languageFacts/dataProvider.js +0 -86
- package/lib/umd/languageFacts/entry.js +0 -217
- package/lib/umd/languageFacts/facts.js +0 -33
- package/lib/umd/parser/cssErrors.js +0 -61
- package/lib/umd/parser/cssNodes.js +0 -1676
- package/lib/umd/parser/cssParser.js +0 -2035
- package/lib/umd/parser/cssScanner.js +0 -619
- package/lib/umd/parser/cssSymbolScope.js +0 -328
- package/lib/umd/parser/lessParser.js +0 -732
- package/lib/umd/parser/lessScanner.js +0 -70
- package/lib/umd/parser/scssErrors.js +0 -30
- package/lib/umd/parser/scssParser.js +0 -874
- package/lib/umd/parser/scssScanner.js +0 -108
- package/lib/umd/services/cssCodeActions.js +0 -89
- package/lib/umd/services/cssCompletion.js +0 -1109
- package/lib/umd/services/cssFolding.js +0 -202
- package/lib/umd/services/cssFormatter.js +0 -149
- package/lib/umd/services/cssHover.js +0 -174
- package/lib/umd/services/cssNavigation.js +0 -539
- package/lib/umd/services/cssSelectionRange.js +0 -59
- package/lib/umd/services/cssValidation.js +0 -54
- package/lib/umd/services/lessCompletion.js +0 -390
- package/lib/umd/services/lint.js +0 -577
- package/lib/umd/services/lintRules.js +0 -90
- package/lib/umd/services/lintUtil.js +0 -210
- package/lib/umd/services/pathCompletion.js +0 -171
- package/lib/umd/services/scssCompletion.js +0 -367
- package/lib/umd/services/scssNavigation.js +0 -169
- package/lib/umd/services/selectorPrinting.js +0 -575
- package/lib/umd/utils/arrays.js +0 -54
- package/lib/umd/utils/objects.js +0 -24
- package/lib/umd/utils/resources.js +0 -25
- package/lib/umd/utils/strings.js +0 -123
|
@@ -1,575 +0,0 @@
|
|
|
1
|
-
(function (factory) {
|
|
2
|
-
if (typeof module === "object" && typeof module.exports === "object") {
|
|
3
|
-
var v = factory(require, exports);
|
|
4
|
-
if (v !== undefined) module.exports = v;
|
|
5
|
-
}
|
|
6
|
-
else if (typeof define === "function" && define.amd) {
|
|
7
|
-
define(["require", "exports", "../parser/cssNodes", "../parser/cssScanner", "@vscode/l10n", "../parser/cssParser"], factory);
|
|
8
|
-
}
|
|
9
|
-
})(function (require, exports) {
|
|
10
|
-
/*---------------------------------------------------------------------------------------------
|
|
11
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
12
|
-
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
13
|
-
*--------------------------------------------------------------------------------------------*/
|
|
14
|
-
'use strict';
|
|
15
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
-
exports.SelectorPrinting = exports.LabelElement = exports.RootElement = exports.Element = void 0;
|
|
17
|
-
exports.toElement = toElement;
|
|
18
|
-
exports.selectorToElement = selectorToElement;
|
|
19
|
-
const nodes = require("../parser/cssNodes");
|
|
20
|
-
const cssScanner_1 = require("../parser/cssScanner");
|
|
21
|
-
const l10n = require("@vscode/l10n");
|
|
22
|
-
const cssParser_1 = require("../parser/cssParser");
|
|
23
|
-
class Element {
|
|
24
|
-
constructor() {
|
|
25
|
-
this.parent = null;
|
|
26
|
-
this.children = null;
|
|
27
|
-
this.attributes = null;
|
|
28
|
-
}
|
|
29
|
-
findAttribute(name) {
|
|
30
|
-
if (this.attributes) {
|
|
31
|
-
for (const attribute of this.attributes) {
|
|
32
|
-
if (attribute.name === name) {
|
|
33
|
-
return attribute.value;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
addChild(child) {
|
|
40
|
-
if (child instanceof Element) {
|
|
41
|
-
child.parent = this;
|
|
42
|
-
}
|
|
43
|
-
if (!this.children) {
|
|
44
|
-
this.children = [];
|
|
45
|
-
}
|
|
46
|
-
this.children.push(child);
|
|
47
|
-
}
|
|
48
|
-
append(text) {
|
|
49
|
-
if (this.attributes) {
|
|
50
|
-
const last = this.attributes[this.attributes.length - 1];
|
|
51
|
-
last.value = last.value + text;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
prepend(text) {
|
|
55
|
-
if (this.attributes) {
|
|
56
|
-
const first = this.attributes[0];
|
|
57
|
-
first.value = text + first.value;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
findRoot() {
|
|
61
|
-
let curr = this;
|
|
62
|
-
while (curr.parent && !(curr.parent instanceof RootElement)) {
|
|
63
|
-
curr = curr.parent;
|
|
64
|
-
}
|
|
65
|
-
return curr;
|
|
66
|
-
}
|
|
67
|
-
removeChild(child) {
|
|
68
|
-
if (this.children) {
|
|
69
|
-
const index = this.children.indexOf(child);
|
|
70
|
-
if (index !== -1) {
|
|
71
|
-
this.children.splice(index, 1);
|
|
72
|
-
return true;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
addAttr(name, value) {
|
|
78
|
-
if (!this.attributes) {
|
|
79
|
-
this.attributes = [];
|
|
80
|
-
}
|
|
81
|
-
for (const attribute of this.attributes) {
|
|
82
|
-
if (attribute.name === name) {
|
|
83
|
-
attribute.value += ' ' + value;
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
this.attributes.push({ name, value });
|
|
88
|
-
}
|
|
89
|
-
clone(cloneChildren = true) {
|
|
90
|
-
const elem = new Element();
|
|
91
|
-
if (this.attributes) {
|
|
92
|
-
elem.attributes = [];
|
|
93
|
-
for (const attribute of this.attributes) {
|
|
94
|
-
elem.addAttr(attribute.name, attribute.value);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
if (cloneChildren && this.children) {
|
|
98
|
-
elem.children = [];
|
|
99
|
-
for (let index = 0; index < this.children.length; index++) {
|
|
100
|
-
elem.addChild(this.children[index].clone());
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
return elem;
|
|
104
|
-
}
|
|
105
|
-
cloneWithParent() {
|
|
106
|
-
const clone = this.clone(false);
|
|
107
|
-
if (this.parent && !(this.parent instanceof RootElement)) {
|
|
108
|
-
const parentClone = this.parent.cloneWithParent();
|
|
109
|
-
parentClone.addChild(clone);
|
|
110
|
-
}
|
|
111
|
-
return clone;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
exports.Element = Element;
|
|
115
|
-
class RootElement extends Element {
|
|
116
|
-
}
|
|
117
|
-
exports.RootElement = RootElement;
|
|
118
|
-
class LabelElement extends Element {
|
|
119
|
-
constructor(label) {
|
|
120
|
-
super();
|
|
121
|
-
this.addAttr('name', label);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
exports.LabelElement = LabelElement;
|
|
125
|
-
class MarkedStringPrinter {
|
|
126
|
-
constructor(quote) {
|
|
127
|
-
this.quote = quote;
|
|
128
|
-
this.result = [];
|
|
129
|
-
// empty
|
|
130
|
-
}
|
|
131
|
-
print(element, selectorContexts) {
|
|
132
|
-
this.result = [];
|
|
133
|
-
if (element instanceof RootElement) {
|
|
134
|
-
if (element.children) {
|
|
135
|
-
this.doPrint(element.children, 0);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
this.doPrint([element], 0);
|
|
140
|
-
}
|
|
141
|
-
let value;
|
|
142
|
-
if (selectorContexts) {
|
|
143
|
-
value = [...selectorContexts, ...this.result].join('\n');
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
value = this.result.join('\n');
|
|
147
|
-
}
|
|
148
|
-
return [{ language: 'html', value }];
|
|
149
|
-
}
|
|
150
|
-
doPrint(elements, indent) {
|
|
151
|
-
for (const element of elements) {
|
|
152
|
-
this.doPrintElement(element, indent);
|
|
153
|
-
if (element.children) {
|
|
154
|
-
this.doPrint(element.children, indent + 1);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
writeLine(level, content) {
|
|
159
|
-
const indent = new Array(level + 1).join(' ');
|
|
160
|
-
this.result.push(indent + content);
|
|
161
|
-
}
|
|
162
|
-
doPrintElement(element, indent) {
|
|
163
|
-
const name = element.findAttribute('name');
|
|
164
|
-
// special case: a simple label
|
|
165
|
-
if (element instanceof LabelElement || name === '\u2026') {
|
|
166
|
-
this.writeLine(indent, name);
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
// the real deal
|
|
170
|
-
const content = ['<'];
|
|
171
|
-
// element name
|
|
172
|
-
if (name) {
|
|
173
|
-
content.push(name);
|
|
174
|
-
}
|
|
175
|
-
else {
|
|
176
|
-
content.push('element');
|
|
177
|
-
}
|
|
178
|
-
// attributes
|
|
179
|
-
if (element.attributes) {
|
|
180
|
-
for (const attr of element.attributes) {
|
|
181
|
-
if (attr.name !== 'name') {
|
|
182
|
-
content.push(' ');
|
|
183
|
-
content.push(attr.name);
|
|
184
|
-
const value = attr.value;
|
|
185
|
-
if (value) {
|
|
186
|
-
content.push('=');
|
|
187
|
-
content.push(quotes.ensure(value, this.quote));
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
content.push('>');
|
|
193
|
-
this.writeLine(indent, content.join(''));
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
var quotes;
|
|
197
|
-
(function (quotes) {
|
|
198
|
-
function ensure(value, which) {
|
|
199
|
-
return which + remove(value) + which;
|
|
200
|
-
}
|
|
201
|
-
quotes.ensure = ensure;
|
|
202
|
-
function remove(value) {
|
|
203
|
-
const match = value.match(/^['"](.*)["']$/);
|
|
204
|
-
if (match) {
|
|
205
|
-
return match[1];
|
|
206
|
-
}
|
|
207
|
-
return value;
|
|
208
|
-
}
|
|
209
|
-
quotes.remove = remove;
|
|
210
|
-
})(quotes || (quotes = {}));
|
|
211
|
-
class Specificity {
|
|
212
|
-
constructor() {
|
|
213
|
-
/** Count of identifiers (e.g., `#app`) */
|
|
214
|
-
this.id = 0;
|
|
215
|
-
/** Count of attributes (`[type="number"]`), classes (`.container-fluid`), and pseudo-classes (`:hover`) */
|
|
216
|
-
this.attr = 0;
|
|
217
|
-
/** Count of tag names (`div`), and pseudo-elements (`::before`) */
|
|
218
|
-
this.tag = 0;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
function toElement(node, parentElement) {
|
|
222
|
-
let result = new Element();
|
|
223
|
-
for (const child of node.getChildren()) {
|
|
224
|
-
switch (child.type) {
|
|
225
|
-
case nodes.NodeType.SelectorCombinator:
|
|
226
|
-
if (parentElement) {
|
|
227
|
-
const segments = child.getText().split('&');
|
|
228
|
-
if (segments.length === 1) {
|
|
229
|
-
// should not happen
|
|
230
|
-
result.addAttr('name', segments[0]);
|
|
231
|
-
break;
|
|
232
|
-
}
|
|
233
|
-
result = parentElement.cloneWithParent();
|
|
234
|
-
if (segments[0]) {
|
|
235
|
-
const root = result.findRoot();
|
|
236
|
-
root.prepend(segments[0]);
|
|
237
|
-
}
|
|
238
|
-
for (let i = 1; i < segments.length; i++) {
|
|
239
|
-
if (i > 1) {
|
|
240
|
-
const clone = parentElement.cloneWithParent();
|
|
241
|
-
result.addChild(clone.findRoot());
|
|
242
|
-
result = clone;
|
|
243
|
-
}
|
|
244
|
-
result.append(segments[i]);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
break;
|
|
248
|
-
case nodes.NodeType.SelectorPlaceholder:
|
|
249
|
-
if (child.matches('@at-root')) {
|
|
250
|
-
return result;
|
|
251
|
-
}
|
|
252
|
-
// fall through
|
|
253
|
-
case nodes.NodeType.ElementNameSelector:
|
|
254
|
-
const text = child.getText();
|
|
255
|
-
result.addAttr('name', text === '*' ? 'element' : unescape(text));
|
|
256
|
-
break;
|
|
257
|
-
case nodes.NodeType.ClassSelector:
|
|
258
|
-
result.addAttr('class', unescape(child.getText().substring(1)));
|
|
259
|
-
break;
|
|
260
|
-
case nodes.NodeType.IdentifierSelector:
|
|
261
|
-
result.addAttr('id', unescape(child.getText().substring(1)));
|
|
262
|
-
break;
|
|
263
|
-
case nodes.NodeType.MixinDeclaration:
|
|
264
|
-
result.addAttr('class', child.getName());
|
|
265
|
-
break;
|
|
266
|
-
case nodes.NodeType.PseudoSelector:
|
|
267
|
-
result.addAttr(unescape(child.getText()), '');
|
|
268
|
-
break;
|
|
269
|
-
case nodes.NodeType.AttributeSelector:
|
|
270
|
-
const selector = child;
|
|
271
|
-
const identifier = selector.getIdentifier();
|
|
272
|
-
if (identifier) {
|
|
273
|
-
const expression = selector.getValue();
|
|
274
|
-
const operator = selector.getOperator();
|
|
275
|
-
let value;
|
|
276
|
-
if (expression && operator) {
|
|
277
|
-
switch (unescape(operator.getText())) {
|
|
278
|
-
case '|=':
|
|
279
|
-
// excatly or followed by -words
|
|
280
|
-
value = `${quotes.remove(unescape(expression.getText()))}-\u2026`;
|
|
281
|
-
break;
|
|
282
|
-
case '^=':
|
|
283
|
-
// prefix
|
|
284
|
-
value = `${quotes.remove(unescape(expression.getText()))}\u2026`;
|
|
285
|
-
break;
|
|
286
|
-
case '$=':
|
|
287
|
-
// suffix
|
|
288
|
-
value = `\u2026${quotes.remove(unescape(expression.getText()))}`;
|
|
289
|
-
break;
|
|
290
|
-
case '~=':
|
|
291
|
-
// one of a list of words
|
|
292
|
-
value = ` \u2026 ${quotes.remove(unescape(expression.getText()))} \u2026 `;
|
|
293
|
-
break;
|
|
294
|
-
case '*=':
|
|
295
|
-
// substring
|
|
296
|
-
value = `\u2026${quotes.remove(unescape(expression.getText()))}\u2026`;
|
|
297
|
-
break;
|
|
298
|
-
default:
|
|
299
|
-
value = quotes.remove(unescape(expression.getText()));
|
|
300
|
-
break;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
result.addAttr(unescape(identifier.getText()), value);
|
|
304
|
-
}
|
|
305
|
-
break;
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
return result;
|
|
309
|
-
}
|
|
310
|
-
function unescape(content) {
|
|
311
|
-
const scanner = new cssScanner_1.Scanner();
|
|
312
|
-
scanner.setSource(content);
|
|
313
|
-
const token = scanner.scanUnquotedString();
|
|
314
|
-
if (token) {
|
|
315
|
-
return token.text;
|
|
316
|
-
}
|
|
317
|
-
return content;
|
|
318
|
-
}
|
|
319
|
-
class SelectorPrinting {
|
|
320
|
-
constructor(cssDataManager) {
|
|
321
|
-
this.cssDataManager = cssDataManager;
|
|
322
|
-
}
|
|
323
|
-
selectorToMarkedString(node, selectorContexts) {
|
|
324
|
-
const root = selectorToElement(node);
|
|
325
|
-
if (root) {
|
|
326
|
-
const markedStrings = new MarkedStringPrinter('"').print(root, selectorContexts);
|
|
327
|
-
markedStrings.push(this.selectorToSpecificityMarkedString(node));
|
|
328
|
-
return markedStrings;
|
|
329
|
-
}
|
|
330
|
-
else {
|
|
331
|
-
return [];
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
simpleSelectorToMarkedString(node) {
|
|
335
|
-
const element = toElement(node);
|
|
336
|
-
const markedStrings = new MarkedStringPrinter('"').print(element);
|
|
337
|
-
markedStrings.push(this.selectorToSpecificityMarkedString(node));
|
|
338
|
-
return markedStrings;
|
|
339
|
-
}
|
|
340
|
-
isPseudoElementIdentifier(text) {
|
|
341
|
-
const match = text.match(/^::?([\w-]+)/);
|
|
342
|
-
if (!match) {
|
|
343
|
-
return false;
|
|
344
|
-
}
|
|
345
|
-
return !!this.cssDataManager.getPseudoElement('::' + match[1]);
|
|
346
|
-
}
|
|
347
|
-
selectorToSpecificityMarkedString(node) {
|
|
348
|
-
const calculateMostSpecificListItem = (childElements) => {
|
|
349
|
-
const specificity = new Specificity();
|
|
350
|
-
let mostSpecificListItem = new Specificity();
|
|
351
|
-
for (const containerElement of childElements) {
|
|
352
|
-
for (const childElement of containerElement.getChildren()) {
|
|
353
|
-
const itemSpecificity = calculateScore(childElement);
|
|
354
|
-
if (itemSpecificity.id > mostSpecificListItem.id) {
|
|
355
|
-
mostSpecificListItem = itemSpecificity;
|
|
356
|
-
continue;
|
|
357
|
-
}
|
|
358
|
-
else if (itemSpecificity.id < mostSpecificListItem.id) {
|
|
359
|
-
continue;
|
|
360
|
-
}
|
|
361
|
-
if (itemSpecificity.attr > mostSpecificListItem.attr) {
|
|
362
|
-
mostSpecificListItem = itemSpecificity;
|
|
363
|
-
continue;
|
|
364
|
-
}
|
|
365
|
-
else if (itemSpecificity.attr < mostSpecificListItem.attr) {
|
|
366
|
-
continue;
|
|
367
|
-
}
|
|
368
|
-
if (itemSpecificity.tag > mostSpecificListItem.tag) {
|
|
369
|
-
mostSpecificListItem = itemSpecificity;
|
|
370
|
-
continue;
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
specificity.id += mostSpecificListItem.id;
|
|
375
|
-
specificity.attr += mostSpecificListItem.attr;
|
|
376
|
-
specificity.tag += mostSpecificListItem.tag;
|
|
377
|
-
return specificity;
|
|
378
|
-
};
|
|
379
|
-
//https://www.w3.org/TR/selectors-3/#specificity
|
|
380
|
-
const calculateScore = (node) => {
|
|
381
|
-
const specificity = new Specificity();
|
|
382
|
-
elementLoop: for (const element of node.getChildren()) {
|
|
383
|
-
switch (element.type) {
|
|
384
|
-
case nodes.NodeType.IdentifierSelector:
|
|
385
|
-
specificity.id++;
|
|
386
|
-
break;
|
|
387
|
-
case nodes.NodeType.ClassSelector:
|
|
388
|
-
case nodes.NodeType.AttributeSelector:
|
|
389
|
-
specificity.attr++;
|
|
390
|
-
break;
|
|
391
|
-
case nodes.NodeType.ElementNameSelector:
|
|
392
|
-
//ignore universal selector
|
|
393
|
-
if (element.matches('*')) {
|
|
394
|
-
break;
|
|
395
|
-
}
|
|
396
|
-
specificity.tag++;
|
|
397
|
-
break;
|
|
398
|
-
case nodes.NodeType.PseudoSelector:
|
|
399
|
-
const text = element.getText();
|
|
400
|
-
const childElements = element.getChildren();
|
|
401
|
-
if (this.isPseudoElementIdentifier(text)) {
|
|
402
|
-
if (text.match(/^::slotted/i) && childElements.length > 0) {
|
|
403
|
-
// The specificity of ::slotted() is that of a pseudo-element, plus the specificity of its argument.
|
|
404
|
-
// ::slotted() does not allow a selector list as its argument, but this isn't the right place to give feedback on validity.
|
|
405
|
-
// Reporting the most specific child will be correct for correct CSS and will be forgiving in case of mistakes.
|
|
406
|
-
specificity.tag++;
|
|
407
|
-
let mostSpecificListItem = calculateMostSpecificListItem(childElements);
|
|
408
|
-
specificity.id += mostSpecificListItem.id;
|
|
409
|
-
specificity.attr += mostSpecificListItem.attr;
|
|
410
|
-
specificity.tag += mostSpecificListItem.tag;
|
|
411
|
-
continue elementLoop;
|
|
412
|
-
}
|
|
413
|
-
specificity.tag++; // pseudo element
|
|
414
|
-
continue elementLoop;
|
|
415
|
-
}
|
|
416
|
-
// where and child selectors have zero specificity
|
|
417
|
-
if (text.match(/^:where/i)) {
|
|
418
|
-
continue elementLoop;
|
|
419
|
-
}
|
|
420
|
-
// the most specific child selector
|
|
421
|
-
if (text.match(/^:(?:not|has|is)/i) && childElements.length > 0) {
|
|
422
|
-
let mostSpecificListItem = calculateMostSpecificListItem(childElements);
|
|
423
|
-
specificity.id += mostSpecificListItem.id;
|
|
424
|
-
specificity.attr += mostSpecificListItem.attr;
|
|
425
|
-
specificity.tag += mostSpecificListItem.tag;
|
|
426
|
-
continue elementLoop;
|
|
427
|
-
}
|
|
428
|
-
if (text.match(/^:(?:host|host-context)/i) && childElements.length > 0) {
|
|
429
|
-
// The specificity of :host() is that of a pseudo-class, plus the specificity of its argument.
|
|
430
|
-
// The specificity of :host-context() is that of a pseudo-class, plus the specificity of its argument.
|
|
431
|
-
specificity.attr++;
|
|
432
|
-
let mostSpecificListItem = calculateMostSpecificListItem(childElements);
|
|
433
|
-
specificity.id += mostSpecificListItem.id;
|
|
434
|
-
specificity.attr += mostSpecificListItem.attr;
|
|
435
|
-
specificity.tag += mostSpecificListItem.tag;
|
|
436
|
-
continue elementLoop;
|
|
437
|
-
}
|
|
438
|
-
if (text.match(/^:(?:nth-child|nth-last-child)/i) && childElements.length > 0) {
|
|
439
|
-
/* The specificity of the :nth-child(An+B [of S]?) pseudo-class is the specificity of a single pseudo-class plus, if S is specified, the specificity of the most specific complex selector in S */
|
|
440
|
-
// https://www.w3.org/TR/selectors-4/#the-nth-child-pseudo
|
|
441
|
-
specificity.attr++;
|
|
442
|
-
const lastChild = childElements[childElements.length - 1];
|
|
443
|
-
if (childElements.length > 2 && lastChild.type === nodes.NodeType.SelectorList) {
|
|
444
|
-
// e.g :nth-child(-n+3 of li.important)
|
|
445
|
-
let mostSpecificListItem = calculateMostSpecificListItem(lastChild.getChildren());
|
|
446
|
-
specificity.id += mostSpecificListItem.id;
|
|
447
|
-
specificity.attr += mostSpecificListItem.attr;
|
|
448
|
-
specificity.tag += mostSpecificListItem.tag;
|
|
449
|
-
continue elementLoop;
|
|
450
|
-
}
|
|
451
|
-
// Edge case: 'n' without integer prefix A, with B integer non-existent, is not regarded as a binary expression token.
|
|
452
|
-
const parser = new cssParser_1.Parser();
|
|
453
|
-
const pseudoSelectorText = childElements[1].getText();
|
|
454
|
-
parser.scanner.setSource(pseudoSelectorText);
|
|
455
|
-
const firstToken = parser.scanner.scan();
|
|
456
|
-
const secondToken = parser.scanner.scan();
|
|
457
|
-
if (firstToken.text === 'n' || (firstToken.text === '-n' && secondToken.text === 'of')) {
|
|
458
|
-
const complexSelectorListNodes = [];
|
|
459
|
-
const complexSelectorText = pseudoSelectorText.slice(secondToken.offset + 2);
|
|
460
|
-
const complexSelectorArray = complexSelectorText.split(',');
|
|
461
|
-
for (const selector of complexSelectorArray) {
|
|
462
|
-
const node = parser.internalParse(selector, parser._parseSelector);
|
|
463
|
-
if (node) {
|
|
464
|
-
complexSelectorListNodes.push(node);
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
let mostSpecificListItem = calculateMostSpecificListItem(complexSelectorListNodes);
|
|
468
|
-
specificity.id += mostSpecificListItem.id;
|
|
469
|
-
specificity.attr += mostSpecificListItem.attr;
|
|
470
|
-
specificity.tag += mostSpecificListItem.tag;
|
|
471
|
-
continue elementLoop;
|
|
472
|
-
}
|
|
473
|
-
continue elementLoop;
|
|
474
|
-
}
|
|
475
|
-
specificity.attr++; //pseudo class
|
|
476
|
-
continue elementLoop;
|
|
477
|
-
}
|
|
478
|
-
if (element.getChildren().length > 0) {
|
|
479
|
-
const itemSpecificity = calculateScore(element);
|
|
480
|
-
specificity.id += itemSpecificity.id;
|
|
481
|
-
specificity.attr += itemSpecificity.attr;
|
|
482
|
-
specificity.tag += itemSpecificity.tag;
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
return specificity;
|
|
486
|
-
};
|
|
487
|
-
const specificity = calculateScore(node);
|
|
488
|
-
return `[${l10n.t('Selector Specificity')}](https://developer.mozilla.org/docs/Web/CSS/Specificity): (${specificity.id}, ${specificity.attr}, ${specificity.tag})`;
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
exports.SelectorPrinting = SelectorPrinting;
|
|
492
|
-
class SelectorElementBuilder {
|
|
493
|
-
constructor(element) {
|
|
494
|
-
this.prev = null;
|
|
495
|
-
this.element = element;
|
|
496
|
-
}
|
|
497
|
-
processSelector(selector) {
|
|
498
|
-
let parentElement = null;
|
|
499
|
-
if (!(this.element instanceof RootElement)) {
|
|
500
|
-
if (selector.getChildren().some((c) => c.hasChildren() && c.getChild(0).type === nodes.NodeType.SelectorCombinator)) {
|
|
501
|
-
const curr = this.element.findRoot();
|
|
502
|
-
if (curr.parent instanceof RootElement) {
|
|
503
|
-
parentElement = this.element;
|
|
504
|
-
this.element = curr.parent;
|
|
505
|
-
this.element.removeChild(curr);
|
|
506
|
-
this.prev = null;
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
for (const selectorChild of selector.getChildren()) {
|
|
511
|
-
if (selectorChild instanceof nodes.SimpleSelector) {
|
|
512
|
-
if (this.prev instanceof nodes.SimpleSelector) {
|
|
513
|
-
const labelElement = new LabelElement('\u2026');
|
|
514
|
-
this.element.addChild(labelElement);
|
|
515
|
-
this.element = labelElement;
|
|
516
|
-
}
|
|
517
|
-
else if (this.prev && (this.prev.matches('+') || this.prev.matches('~')) && this.element.parent) {
|
|
518
|
-
this.element = this.element.parent;
|
|
519
|
-
}
|
|
520
|
-
if (this.prev && this.prev.matches('~')) {
|
|
521
|
-
this.element.addChild(new LabelElement('\u22EE'));
|
|
522
|
-
}
|
|
523
|
-
const thisElement = toElement(selectorChild, parentElement);
|
|
524
|
-
const root = thisElement.findRoot();
|
|
525
|
-
this.element.addChild(root);
|
|
526
|
-
this.element = thisElement;
|
|
527
|
-
}
|
|
528
|
-
if (selectorChild instanceof nodes.SimpleSelector ||
|
|
529
|
-
selectorChild.type === nodes.NodeType.SelectorCombinatorParent ||
|
|
530
|
-
selectorChild.type === nodes.NodeType.SelectorCombinatorShadowPiercingDescendant ||
|
|
531
|
-
selectorChild.type === nodes.NodeType.SelectorCombinatorSibling ||
|
|
532
|
-
selectorChild.type === nodes.NodeType.SelectorCombinatorAllSiblings) {
|
|
533
|
-
this.prev = selectorChild;
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
function isNewSelectorContext(node) {
|
|
539
|
-
switch (node.type) {
|
|
540
|
-
case nodes.NodeType.MixinDeclaration:
|
|
541
|
-
case nodes.NodeType.Stylesheet:
|
|
542
|
-
return true;
|
|
543
|
-
}
|
|
544
|
-
return false;
|
|
545
|
-
}
|
|
546
|
-
function selectorToElement(node) {
|
|
547
|
-
if (node.matches('@at-root')) {
|
|
548
|
-
return null;
|
|
549
|
-
}
|
|
550
|
-
const root = new RootElement();
|
|
551
|
-
const parentRuleSets = [];
|
|
552
|
-
const ruleSet = node.getParent();
|
|
553
|
-
if (ruleSet instanceof nodes.RuleSet) {
|
|
554
|
-
let parent = ruleSet.getParent(); // parent of the selector's ruleset
|
|
555
|
-
while (parent && !isNewSelectorContext(parent)) {
|
|
556
|
-
if (parent instanceof nodes.RuleSet) {
|
|
557
|
-
if (parent.getSelectors().matches('@at-root')) {
|
|
558
|
-
break;
|
|
559
|
-
}
|
|
560
|
-
parentRuleSets.push(parent);
|
|
561
|
-
}
|
|
562
|
-
parent = parent.getParent();
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
const builder = new SelectorElementBuilder(root);
|
|
566
|
-
for (let i = parentRuleSets.length - 1; i >= 0; i--) {
|
|
567
|
-
const selector = parentRuleSets[i].getSelectors().getChild(0);
|
|
568
|
-
if (selector) {
|
|
569
|
-
builder.processSelector(selector);
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
builder.processSelector(node);
|
|
573
|
-
return root;
|
|
574
|
-
}
|
|
575
|
-
});
|
package/lib/umd/utils/arrays.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
(function (factory) {
|
|
2
|
-
if (typeof module === "object" && typeof module.exports === "object") {
|
|
3
|
-
var v = factory(require, exports);
|
|
4
|
-
if (v !== undefined) module.exports = v;
|
|
5
|
-
}
|
|
6
|
-
else if (typeof define === "function" && define.amd) {
|
|
7
|
-
define(["require", "exports"], factory);
|
|
8
|
-
}
|
|
9
|
-
})(function (require, exports) {
|
|
10
|
-
/*---------------------------------------------------------------------------------------------
|
|
11
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
12
|
-
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
13
|
-
*--------------------------------------------------------------------------------------------*/
|
|
14
|
-
'use strict';
|
|
15
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
-
exports.findFirst = findFirst;
|
|
17
|
-
exports.includes = includes;
|
|
18
|
-
exports.union = union;
|
|
19
|
-
/**
|
|
20
|
-
* Takes a sorted array and a function p. The array is sorted in such a way that all elements where p(x) is false
|
|
21
|
-
* are located before all elements where p(x) is true.
|
|
22
|
-
* @returns the least x for which p(x) is true or array.length if no element fullfills the given function.
|
|
23
|
-
*/
|
|
24
|
-
function findFirst(array, p) {
|
|
25
|
-
let low = 0, high = array.length;
|
|
26
|
-
if (high === 0) {
|
|
27
|
-
return 0; // no children
|
|
28
|
-
}
|
|
29
|
-
while (low < high) {
|
|
30
|
-
let mid = Math.floor((low + high) / 2);
|
|
31
|
-
if (p(array[mid])) {
|
|
32
|
-
high = mid;
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
low = mid + 1;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return low;
|
|
39
|
-
}
|
|
40
|
-
function includes(array, item) {
|
|
41
|
-
return array.indexOf(item) !== -1;
|
|
42
|
-
}
|
|
43
|
-
function union(...arrays) {
|
|
44
|
-
const result = [];
|
|
45
|
-
for (const array of arrays) {
|
|
46
|
-
for (const item of array) {
|
|
47
|
-
if (!includes(result, item)) {
|
|
48
|
-
result.push(item);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return result;
|
|
53
|
-
}
|
|
54
|
-
});
|
package/lib/umd/utils/objects.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
(function (factory) {
|
|
2
|
-
if (typeof module === "object" && typeof module.exports === "object") {
|
|
3
|
-
var v = factory(require, exports);
|
|
4
|
-
if (v !== undefined) module.exports = v;
|
|
5
|
-
}
|
|
6
|
-
else if (typeof define === "function" && define.amd) {
|
|
7
|
-
define(["require", "exports"], factory);
|
|
8
|
-
}
|
|
9
|
-
})(function (require, exports) {
|
|
10
|
-
/*---------------------------------------------------------------------------------------------
|
|
11
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
12
|
-
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
13
|
-
*--------------------------------------------------------------------------------------------*/
|
|
14
|
-
'use strict';
|
|
15
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
-
exports.values = values;
|
|
17
|
-
exports.isDefined = isDefined;
|
|
18
|
-
function values(obj) {
|
|
19
|
-
return Object.keys(obj).map(key => obj[key]);
|
|
20
|
-
}
|
|
21
|
-
function isDefined(obj) {
|
|
22
|
-
return typeof obj !== 'undefined';
|
|
23
|
-
}
|
|
24
|
-
});
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/*---------------------------------------------------------------------------------------------
|
|
2
|
-
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
|
-
*--------------------------------------------------------------------------------------------*/
|
|
5
|
-
(function (factory) {
|
|
6
|
-
if (typeof module === "object" && typeof module.exports === "object") {
|
|
7
|
-
var v = factory(require, exports);
|
|
8
|
-
if (v !== undefined) module.exports = v;
|
|
9
|
-
}
|
|
10
|
-
else if (typeof define === "function" && define.amd) {
|
|
11
|
-
define(["require", "exports", "vscode-uri"], factory);
|
|
12
|
-
}
|
|
13
|
-
})(function (require, exports) {
|
|
14
|
-
"use strict";
|
|
15
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
-
exports.dirname = dirname;
|
|
17
|
-
exports.joinPath = joinPath;
|
|
18
|
-
const vscode_uri_1 = require("vscode-uri");
|
|
19
|
-
function dirname(uriString) {
|
|
20
|
-
return vscode_uri_1.Utils.dirname(vscode_uri_1.URI.parse(uriString)).toString(true);
|
|
21
|
-
}
|
|
22
|
-
function joinPath(uriString, ...paths) {
|
|
23
|
-
return vscode_uri_1.Utils.joinPath(vscode_uri_1.URI.parse(uriString), ...paths).toString(true);
|
|
24
|
-
}
|
|
25
|
-
});
|