vscode-css-languageservice 5.4.2 → 6.1.0
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 +7 -1
- package/SECURITY.md +41 -0
- package/lib/esm/beautify/beautify-css.js +11 -4
- package/lib/esm/cssLanguageService.d.ts +2 -1
- package/lib/esm/cssLanguageService.js +15 -17
- package/lib/esm/cssLanguageTypes.js +2 -2
- package/lib/esm/data/webCustomData.js +356 -232
- package/lib/esm/languageFacts/builtinData.js +15 -15
- package/lib/esm/languageFacts/colors.js +66 -69
- package/lib/esm/languageFacts/dataManager.js +38 -42
- package/lib/esm/languageFacts/dataProvider.js +17 -23
- package/lib/esm/languageFacts/entry.js +22 -23
- package/lib/esm/parser/cssErrors.js +5 -7
- package/lib/esm/parser/cssNodes.js +869 -1377
- package/lib/esm/parser/cssParser.js +419 -376
- package/lib/esm/parser/cssScanner.js +168 -175
- package/lib/esm/parser/cssSymbolScope.js +107 -137
- package/lib/esm/parser/lessParser.js +177 -202
- package/lib/esm/parser/lessScanner.js +22 -43
- package/lib/esm/parser/scssErrors.js +5 -7
- package/lib/esm/parser/scssParser.js +196 -208
- package/lib/esm/parser/scssScanner.js +33 -54
- package/lib/esm/services/cssCodeActions.js +36 -40
- package/lib/esm/services/cssCompletion.js +300 -395
- package/lib/esm/services/cssFolding.js +32 -35
- package/lib/esm/services/cssFormatter.js +22 -22
- package/lib/esm/services/cssHover.js +30 -33
- package/lib/esm/services/cssNavigation.js +260 -289
- package/lib/esm/services/cssSelectionRange.js +6 -6
- package/lib/esm/services/cssValidation.js +13 -16
- package/lib/esm/services/lessCompletion.js +351 -370
- package/lib/esm/services/lint.js +161 -175
- package/lib/esm/services/lintRules.js +20 -27
- package/lib/esm/services/lintUtil.js +19 -28
- package/lib/esm/services/pathCompletion.js +84 -158
- package/lib/esm/services/scssCompletion.js +283 -307
- package/lib/esm/services/scssNavigation.js +65 -137
- package/lib/esm/services/selectorPrinting.js +131 -175
- package/lib/esm/utils/arrays.js +6 -12
- package/lib/esm/utils/objects.js +1 -1
- package/lib/esm/utils/resources.js +3 -16
- package/lib/esm/utils/strings.js +10 -12
- package/lib/umd/beautify/beautify-css.js +11 -4
- package/lib/umd/cssLanguageService.d.ts +2 -1
- package/lib/umd/cssLanguageService.js +34 -32
- package/lib/umd/cssLanguageTypes.js +4 -3
- package/lib/umd/data/webCustomData.js +355 -231
- package/lib/umd/languageFacts/colors.js +65 -68
- package/lib/umd/languageFacts/dataManager.js +41 -44
- package/lib/umd/languageFacts/dataProvider.js +17 -22
- package/lib/umd/languageFacts/entry.js +22 -23
- package/lib/umd/languageFacts/facts.js +5 -1
- package/lib/umd/parser/cssErrors.js +5 -6
- package/lib/umd/parser/cssNodes.js +870 -1307
- package/lib/umd/parser/cssParser.js +424 -380
- package/lib/umd/parser/cssScanner.js +168 -173
- package/lib/umd/parser/cssSymbolScope.js +109 -134
- package/lib/umd/parser/lessParser.js +182 -206
- package/lib/umd/parser/lessScanner.js +22 -42
- package/lib/umd/parser/scssErrors.js +5 -6
- package/lib/umd/parser/scssParser.js +202 -213
- package/lib/umd/parser/scssScanner.js +25 -45
- package/lib/umd/services/cssCodeActions.js +41 -44
- package/lib/umd/services/cssCompletion.js +308 -402
- package/lib/umd/services/cssFolding.js +35 -38
- package/lib/umd/services/cssFormatter.js +25 -25
- package/lib/umd/services/cssHover.js +36 -38
- package/lib/umd/services/cssNavigation.js +267 -295
- package/lib/umd/services/cssSelectionRange.js +8 -8
- package/lib/umd/services/cssValidation.js +17 -19
- package/lib/umd/services/lessCompletion.js +354 -372
- package/lib/umd/services/lint.js +167 -180
- package/lib/umd/services/lintRules.js +20 -24
- package/lib/umd/services/lintUtil.js +20 -28
- package/lib/umd/services/pathCompletion.js +87 -160
- package/lib/umd/services/scssCompletion.js +287 -310
- package/lib/umd/services/scssNavigation.js +69 -140
- package/lib/umd/services/selectorPrinting.js +134 -174
- package/lib/umd/utils/arrays.js +6 -12
- package/lib/umd/utils/objects.js +1 -1
- package/lib/umd/utils/resources.js +4 -17
- package/lib/umd/utils/strings.js +10 -12
- package/package.json +16 -15
|
@@ -3,43 +3,27 @@
|
|
|
3
3
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
'use strict';
|
|
6
|
-
var __extends = (this && this.__extends) || (function () {
|
|
7
|
-
var extendStatics = function (d, b) {
|
|
8
|
-
extendStatics = Object.setPrototypeOf ||
|
|
9
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
10
|
-
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
11
|
-
return extendStatics(d, b);
|
|
12
|
-
};
|
|
13
|
-
return function (d, b) {
|
|
14
|
-
if (typeof b !== "function" && b !== null)
|
|
15
|
-
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
16
|
-
extendStatics(d, b);
|
|
17
|
-
function __() { this.constructor = d; }
|
|
18
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
19
|
-
};
|
|
20
|
-
})();
|
|
21
6
|
import * as nodes from '../parser/cssNodes';
|
|
22
7
|
import { Scanner } from '../parser/cssScanner';
|
|
23
8
|
import * as nls from 'vscode-nls';
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
9
|
+
const localize = nls.loadMessageBundle();
|
|
10
|
+
export class Element {
|
|
11
|
+
constructor() {
|
|
27
12
|
this.parent = null;
|
|
28
13
|
this.children = null;
|
|
29
14
|
this.attributes = null;
|
|
30
15
|
}
|
|
31
|
-
|
|
16
|
+
findAttribute(name) {
|
|
32
17
|
if (this.attributes) {
|
|
33
|
-
for (
|
|
34
|
-
var attribute = _a[_i];
|
|
18
|
+
for (const attribute of this.attributes) {
|
|
35
19
|
if (attribute.name === name) {
|
|
36
20
|
return attribute.value;
|
|
37
21
|
}
|
|
38
22
|
}
|
|
39
23
|
}
|
|
40
24
|
return null;
|
|
41
|
-
}
|
|
42
|
-
|
|
25
|
+
}
|
|
26
|
+
addChild(child) {
|
|
43
27
|
if (child instanceof Element) {
|
|
44
28
|
child.parent = this;
|
|
45
29
|
}
|
|
@@ -47,103 +31,88 @@ var Element = /** @class */ (function () {
|
|
|
47
31
|
this.children = [];
|
|
48
32
|
}
|
|
49
33
|
this.children.push(child);
|
|
50
|
-
}
|
|
51
|
-
|
|
34
|
+
}
|
|
35
|
+
append(text) {
|
|
52
36
|
if (this.attributes) {
|
|
53
|
-
|
|
37
|
+
const last = this.attributes[this.attributes.length - 1];
|
|
54
38
|
last.value = last.value + text;
|
|
55
39
|
}
|
|
56
|
-
}
|
|
57
|
-
|
|
40
|
+
}
|
|
41
|
+
prepend(text) {
|
|
58
42
|
if (this.attributes) {
|
|
59
|
-
|
|
43
|
+
const first = this.attributes[0];
|
|
60
44
|
first.value = text + first.value;
|
|
61
45
|
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
46
|
+
}
|
|
47
|
+
findRoot() {
|
|
48
|
+
let curr = this;
|
|
65
49
|
while (curr.parent && !(curr.parent instanceof RootElement)) {
|
|
66
50
|
curr = curr.parent;
|
|
67
51
|
}
|
|
68
52
|
return curr;
|
|
69
|
-
}
|
|
70
|
-
|
|
53
|
+
}
|
|
54
|
+
removeChild(child) {
|
|
71
55
|
if (this.children) {
|
|
72
|
-
|
|
56
|
+
const index = this.children.indexOf(child);
|
|
73
57
|
if (index !== -1) {
|
|
74
58
|
this.children.splice(index, 1);
|
|
75
59
|
return true;
|
|
76
60
|
}
|
|
77
61
|
}
|
|
78
62
|
return false;
|
|
79
|
-
}
|
|
80
|
-
|
|
63
|
+
}
|
|
64
|
+
addAttr(name, value) {
|
|
81
65
|
if (!this.attributes) {
|
|
82
66
|
this.attributes = [];
|
|
83
67
|
}
|
|
84
|
-
for (
|
|
85
|
-
var attribute = _a[_i];
|
|
68
|
+
for (const attribute of this.attributes) {
|
|
86
69
|
if (attribute.name === name) {
|
|
87
70
|
attribute.value += ' ' + value;
|
|
88
71
|
return;
|
|
89
72
|
}
|
|
90
73
|
}
|
|
91
|
-
this.attributes.push({ name
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
var elem = new Element();
|
|
74
|
+
this.attributes.push({ name, value });
|
|
75
|
+
}
|
|
76
|
+
clone(cloneChildren = true) {
|
|
77
|
+
const elem = new Element();
|
|
96
78
|
if (this.attributes) {
|
|
97
79
|
elem.attributes = [];
|
|
98
|
-
for (
|
|
99
|
-
var attribute = _a[_i];
|
|
80
|
+
for (const attribute of this.attributes) {
|
|
100
81
|
elem.addAttr(attribute.name, attribute.value);
|
|
101
82
|
}
|
|
102
83
|
}
|
|
103
84
|
if (cloneChildren && this.children) {
|
|
104
85
|
elem.children = [];
|
|
105
|
-
for (
|
|
86
|
+
for (let index = 0; index < this.children.length; index++) {
|
|
106
87
|
elem.addChild(this.children[index].clone());
|
|
107
88
|
}
|
|
108
89
|
}
|
|
109
90
|
return elem;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
91
|
+
}
|
|
92
|
+
cloneWithParent() {
|
|
93
|
+
const clone = this.clone(false);
|
|
113
94
|
if (this.parent && !(this.parent instanceof RootElement)) {
|
|
114
|
-
|
|
95
|
+
const parentClone = this.parent.cloneWithParent();
|
|
115
96
|
parentClone.addChild(clone);
|
|
116
97
|
}
|
|
117
98
|
return clone;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
var LabelElement = /** @class */ (function (_super) {
|
|
131
|
-
__extends(LabelElement, _super);
|
|
132
|
-
function LabelElement(label) {
|
|
133
|
-
var _this = _super.call(this) || this;
|
|
134
|
-
_this.addAttr('name', label);
|
|
135
|
-
return _this;
|
|
136
|
-
}
|
|
137
|
-
return LabelElement;
|
|
138
|
-
}(Element));
|
|
139
|
-
export { LabelElement };
|
|
140
|
-
var MarkedStringPrinter = /** @class */ (function () {
|
|
141
|
-
function MarkedStringPrinter(quote) {
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
export class RootElement extends Element {
|
|
102
|
+
}
|
|
103
|
+
export class LabelElement extends Element {
|
|
104
|
+
constructor(label) {
|
|
105
|
+
super();
|
|
106
|
+
this.addAttr('name', label);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
class MarkedStringPrinter {
|
|
110
|
+
constructor(quote) {
|
|
142
111
|
this.quote = quote;
|
|
143
112
|
this.result = [];
|
|
144
113
|
// empty
|
|
145
114
|
}
|
|
146
|
-
|
|
115
|
+
print(element) {
|
|
147
116
|
this.result = [];
|
|
148
117
|
if (element instanceof RootElement) {
|
|
149
118
|
if (element.children) {
|
|
@@ -153,31 +122,30 @@ var MarkedStringPrinter = /** @class */ (function () {
|
|
|
153
122
|
else {
|
|
154
123
|
this.doPrint([element], 0);
|
|
155
124
|
}
|
|
156
|
-
|
|
157
|
-
return [{ language: 'html', value
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
for (
|
|
161
|
-
var element = elements_1[_i];
|
|
125
|
+
const value = this.result.join('\n');
|
|
126
|
+
return [{ language: 'html', value }];
|
|
127
|
+
}
|
|
128
|
+
doPrint(elements, indent) {
|
|
129
|
+
for (const element of elements) {
|
|
162
130
|
this.doPrintElement(element, indent);
|
|
163
131
|
if (element.children) {
|
|
164
132
|
this.doPrint(element.children, indent + 1);
|
|
165
133
|
}
|
|
166
134
|
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
|
|
135
|
+
}
|
|
136
|
+
writeLine(level, content) {
|
|
137
|
+
const indent = new Array(level + 1).join(' ');
|
|
170
138
|
this.result.push(indent + content);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
|
|
139
|
+
}
|
|
140
|
+
doPrintElement(element, indent) {
|
|
141
|
+
const name = element.findAttribute('name');
|
|
174
142
|
// special case: a simple label
|
|
175
143
|
if (element instanceof LabelElement || name === '\u2026') {
|
|
176
144
|
this.writeLine(indent, name);
|
|
177
145
|
return;
|
|
178
146
|
}
|
|
179
147
|
// the real deal
|
|
180
|
-
|
|
148
|
+
const content = ['<'];
|
|
181
149
|
// element name
|
|
182
150
|
if (name) {
|
|
183
151
|
content.push(name);
|
|
@@ -187,12 +155,11 @@ var MarkedStringPrinter = /** @class */ (function () {
|
|
|
187
155
|
}
|
|
188
156
|
// attributes
|
|
189
157
|
if (element.attributes) {
|
|
190
|
-
for (
|
|
191
|
-
var attr = _a[_i];
|
|
158
|
+
for (const attr of element.attributes) {
|
|
192
159
|
if (attr.name !== 'name') {
|
|
193
160
|
content.push(' ');
|
|
194
161
|
content.push(attr.name);
|
|
195
|
-
|
|
162
|
+
const value = attr.value;
|
|
196
163
|
if (value) {
|
|
197
164
|
content.push('=');
|
|
198
165
|
content.push(quotes.ensure(value, this.quote));
|
|
@@ -202,9 +169,8 @@ var MarkedStringPrinter = /** @class */ (function () {
|
|
|
202
169
|
}
|
|
203
170
|
content.push('>');
|
|
204
171
|
this.writeLine(indent, content.join(''));
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
}());
|
|
172
|
+
}
|
|
173
|
+
}
|
|
208
174
|
var quotes;
|
|
209
175
|
(function (quotes) {
|
|
210
176
|
function ensure(value, which) {
|
|
@@ -212,7 +178,7 @@ var quotes;
|
|
|
212
178
|
}
|
|
213
179
|
quotes.ensure = ensure;
|
|
214
180
|
function remove(value) {
|
|
215
|
-
|
|
181
|
+
const match = value.match(/^['"](.*)["']$/);
|
|
216
182
|
if (match) {
|
|
217
183
|
return match[1];
|
|
218
184
|
}
|
|
@@ -220,8 +186,8 @@ var quotes;
|
|
|
220
186
|
}
|
|
221
187
|
quotes.remove = remove;
|
|
222
188
|
})(quotes || (quotes = {}));
|
|
223
|
-
|
|
224
|
-
|
|
189
|
+
class Specificity {
|
|
190
|
+
constructor() {
|
|
225
191
|
/** Count of identifiers (e.g., `#app`) */
|
|
226
192
|
this.id = 0;
|
|
227
193
|
/** Count of attributes (`[type="number"]`), classes (`.container-fluid`), and pseudo-classes (`:hover`) */
|
|
@@ -229,16 +195,14 @@ var Specificity = /** @class */ (function () {
|
|
|
229
195
|
/** Count of tag names (`div`), and pseudo-elements (`::before`) */
|
|
230
196
|
this.tag = 0;
|
|
231
197
|
}
|
|
232
|
-
|
|
233
|
-
}());
|
|
198
|
+
}
|
|
234
199
|
export function toElement(node, parentElement) {
|
|
235
|
-
|
|
236
|
-
for (
|
|
237
|
-
var child = _a[_i];
|
|
200
|
+
let result = new Element();
|
|
201
|
+
for (const child of node.getChildren()) {
|
|
238
202
|
switch (child.type) {
|
|
239
203
|
case nodes.NodeType.SelectorCombinator:
|
|
240
204
|
if (parentElement) {
|
|
241
|
-
|
|
205
|
+
const segments = child.getText().split('&');
|
|
242
206
|
if (segments.length === 1) {
|
|
243
207
|
// should not happen
|
|
244
208
|
result.addAttr('name', segments[0]);
|
|
@@ -246,12 +210,12 @@ export function toElement(node, parentElement) {
|
|
|
246
210
|
}
|
|
247
211
|
result = parentElement.cloneWithParent();
|
|
248
212
|
if (segments[0]) {
|
|
249
|
-
|
|
213
|
+
const root = result.findRoot();
|
|
250
214
|
root.prepend(segments[0]);
|
|
251
215
|
}
|
|
252
|
-
for (
|
|
216
|
+
for (let i = 1; i < segments.length; i++) {
|
|
253
217
|
if (i > 1) {
|
|
254
|
-
|
|
218
|
+
const clone = parentElement.cloneWithParent();
|
|
255
219
|
result.addChild(clone.findRoot());
|
|
256
220
|
result = clone;
|
|
257
221
|
}
|
|
@@ -265,7 +229,7 @@ export function toElement(node, parentElement) {
|
|
|
265
229
|
}
|
|
266
230
|
// fall through
|
|
267
231
|
case nodes.NodeType.ElementNameSelector:
|
|
268
|
-
|
|
232
|
+
const text = child.getText();
|
|
269
233
|
result.addAttr('name', text === '*' ? 'element' : unescape(text));
|
|
270
234
|
break;
|
|
271
235
|
case nodes.NodeType.ClassSelector:
|
|
@@ -281,33 +245,33 @@ export function toElement(node, parentElement) {
|
|
|
281
245
|
result.addAttr(unescape(child.getText()), '');
|
|
282
246
|
break;
|
|
283
247
|
case nodes.NodeType.AttributeSelector:
|
|
284
|
-
|
|
285
|
-
|
|
248
|
+
const selector = child;
|
|
249
|
+
const identifier = selector.getIdentifier();
|
|
286
250
|
if (identifier) {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
251
|
+
const expression = selector.getValue();
|
|
252
|
+
const operator = selector.getOperator();
|
|
253
|
+
let value;
|
|
290
254
|
if (expression && operator) {
|
|
291
255
|
switch (unescape(operator.getText())) {
|
|
292
256
|
case '|=':
|
|
293
257
|
// excatly or followed by -words
|
|
294
|
-
value =
|
|
258
|
+
value = `${quotes.remove(unescape(expression.getText()))}-\u2026`;
|
|
295
259
|
break;
|
|
296
260
|
case '^=':
|
|
297
261
|
// prefix
|
|
298
|
-
value =
|
|
262
|
+
value = `${quotes.remove(unescape(expression.getText()))}\u2026`;
|
|
299
263
|
break;
|
|
300
264
|
case '$=':
|
|
301
265
|
// suffix
|
|
302
|
-
value =
|
|
266
|
+
value = `\u2026${quotes.remove(unescape(expression.getText()))}`;
|
|
303
267
|
break;
|
|
304
268
|
case '~=':
|
|
305
269
|
// one of a list of words
|
|
306
|
-
value =
|
|
270
|
+
value = ` \u2026 ${quotes.remove(unescape(expression.getText()))} \u2026 `;
|
|
307
271
|
break;
|
|
308
272
|
case '*=':
|
|
309
273
|
// substring
|
|
310
|
-
value =
|
|
274
|
+
value = `\u2026${quotes.remove(unescape(expression.getText()))}\u2026`;
|
|
311
275
|
break;
|
|
312
276
|
default:
|
|
313
277
|
value = quotes.remove(unescape(expression.getText()));
|
|
@@ -322,49 +286,47 @@ export function toElement(node, parentElement) {
|
|
|
322
286
|
return result;
|
|
323
287
|
}
|
|
324
288
|
function unescape(content) {
|
|
325
|
-
|
|
289
|
+
const scanner = new Scanner();
|
|
326
290
|
scanner.setSource(content);
|
|
327
|
-
|
|
291
|
+
const token = scanner.scanUnquotedString();
|
|
328
292
|
if (token) {
|
|
329
293
|
return token.text;
|
|
330
294
|
}
|
|
331
295
|
return content;
|
|
332
296
|
}
|
|
333
|
-
|
|
334
|
-
|
|
297
|
+
export class SelectorPrinting {
|
|
298
|
+
constructor(cssDataManager) {
|
|
335
299
|
this.cssDataManager = cssDataManager;
|
|
336
300
|
}
|
|
337
|
-
|
|
338
|
-
|
|
301
|
+
selectorToMarkedString(node) {
|
|
302
|
+
const root = selectorToElement(node);
|
|
339
303
|
if (root) {
|
|
340
|
-
|
|
304
|
+
const markedStrings = new MarkedStringPrinter('"').print(root);
|
|
341
305
|
markedStrings.push(this.selectorToSpecificityMarkedString(node));
|
|
342
306
|
return markedStrings;
|
|
343
307
|
}
|
|
344
308
|
else {
|
|
345
309
|
return [];
|
|
346
310
|
}
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
311
|
+
}
|
|
312
|
+
simpleSelectorToMarkedString(node) {
|
|
313
|
+
const element = toElement(node);
|
|
314
|
+
const markedStrings = new MarkedStringPrinter('"').print(element);
|
|
351
315
|
markedStrings.push(this.selectorToSpecificityMarkedString(node));
|
|
352
316
|
return markedStrings;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
|
|
317
|
+
}
|
|
318
|
+
isPseudoElementIdentifier(text) {
|
|
319
|
+
const match = text.match(/^::?([\w-]+)/);
|
|
356
320
|
if (!match) {
|
|
357
321
|
return false;
|
|
358
322
|
}
|
|
359
323
|
return !!this.cssDataManager.getPseudoElement("::" + match[1]);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
var _this = this;
|
|
324
|
+
}
|
|
325
|
+
selectorToSpecificityMarkedString(node) {
|
|
363
326
|
//https://www.w3.org/TR/selectors-3/#specificity
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
elementLoop: for (
|
|
367
|
-
var element = _a[_i];
|
|
327
|
+
const calculateScore = (node) => {
|
|
328
|
+
const specificity = new Specificity();
|
|
329
|
+
elementLoop: for (const element of node.getChildren()) {
|
|
368
330
|
switch (element.type) {
|
|
369
331
|
case nodes.NodeType.IdentifierSelector:
|
|
370
332
|
specificity.id++;
|
|
@@ -381,8 +343,8 @@ var SelectorPrinting = /** @class */ (function () {
|
|
|
381
343
|
specificity.tag++;
|
|
382
344
|
break;
|
|
383
345
|
case nodes.NodeType.PseudoSelector:
|
|
384
|
-
|
|
385
|
-
if (
|
|
346
|
+
const text = element.getText();
|
|
347
|
+
if (this.isPseudoElementIdentifier(text)) {
|
|
386
348
|
specificity.tag++; // pseudo element
|
|
387
349
|
continue elementLoop;
|
|
388
350
|
}
|
|
@@ -392,19 +354,17 @@ var SelectorPrinting = /** @class */ (function () {
|
|
|
392
354
|
}
|
|
393
355
|
// the most specific child selector
|
|
394
356
|
if (text.match(/^:(not|has|is)/i) && element.getChildren().length > 0) {
|
|
395
|
-
|
|
396
|
-
for (
|
|
397
|
-
|
|
398
|
-
var list = void 0;
|
|
357
|
+
let mostSpecificListItem = new Specificity();
|
|
358
|
+
for (const containerElement of element.getChildren()) {
|
|
359
|
+
let list;
|
|
399
360
|
if (containerElement.type === nodes.NodeType.Undefined) { // containerElement is a list of selectors
|
|
400
361
|
list = containerElement.getChildren();
|
|
401
362
|
}
|
|
402
363
|
else { // containerElement is a selector
|
|
403
364
|
list = [containerElement];
|
|
404
365
|
}
|
|
405
|
-
for (
|
|
406
|
-
|
|
407
|
-
var itemSpecificity = calculateScore(childElement);
|
|
366
|
+
for (const childElement of containerElement.getChildren()) {
|
|
367
|
+
const itemSpecificity = calculateScore(childElement);
|
|
408
368
|
if (itemSpecificity.id > mostSpecificListItem.id) {
|
|
409
369
|
mostSpecificListItem = itemSpecificity;
|
|
410
370
|
continue;
|
|
@@ -434,7 +394,7 @@ var SelectorPrinting = /** @class */ (function () {
|
|
|
434
394
|
continue elementLoop;
|
|
435
395
|
}
|
|
436
396
|
if (element.getChildren().length > 0) {
|
|
437
|
-
|
|
397
|
+
const itemSpecificity = calculateScore(element);
|
|
438
398
|
specificity.id += itemSpecificity.id;
|
|
439
399
|
specificity.attr += itemSpecificity.attr;
|
|
440
400
|
specificity.tag += itemSpecificity.tag;
|
|
@@ -442,23 +402,21 @@ var SelectorPrinting = /** @class */ (function () {
|
|
|
442
402
|
}
|
|
443
403
|
return specificity;
|
|
444
404
|
};
|
|
445
|
-
|
|
405
|
+
const specificity = calculateScore(node);
|
|
446
406
|
;
|
|
447
407
|
return localize('specificity', "[Selector Specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity): ({0}, {1}, {2})", specificity.id, specificity.attr, specificity.tag);
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
var SelectorElementBuilder = /** @class */ (function () {
|
|
453
|
-
function SelectorElementBuilder(element) {
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
class SelectorElementBuilder {
|
|
411
|
+
constructor(element) {
|
|
454
412
|
this.prev = null;
|
|
455
413
|
this.element = element;
|
|
456
414
|
}
|
|
457
|
-
|
|
458
|
-
|
|
415
|
+
processSelector(selector) {
|
|
416
|
+
let parentElement = null;
|
|
459
417
|
if (!(this.element instanceof RootElement)) {
|
|
460
|
-
if (selector.getChildren().some(
|
|
461
|
-
|
|
418
|
+
if (selector.getChildren().some((c) => c.hasChildren() && c.getChild(0).type === nodes.NodeType.SelectorCombinator)) {
|
|
419
|
+
const curr = this.element.findRoot();
|
|
462
420
|
if (curr.parent instanceof RootElement) {
|
|
463
421
|
parentElement = this.element;
|
|
464
422
|
this.element = curr.parent;
|
|
@@ -467,11 +425,10 @@ var SelectorElementBuilder = /** @class */ (function () {
|
|
|
467
425
|
}
|
|
468
426
|
}
|
|
469
427
|
}
|
|
470
|
-
for (
|
|
471
|
-
var selectorChild = _a[_i];
|
|
428
|
+
for (const selectorChild of selector.getChildren()) {
|
|
472
429
|
if (selectorChild instanceof nodes.SimpleSelector) {
|
|
473
430
|
if (this.prev instanceof nodes.SimpleSelector) {
|
|
474
|
-
|
|
431
|
+
const labelElement = new LabelElement('\u2026');
|
|
475
432
|
this.element.addChild(labelElement);
|
|
476
433
|
this.element = labelElement;
|
|
477
434
|
}
|
|
@@ -481,8 +438,8 @@ var SelectorElementBuilder = /** @class */ (function () {
|
|
|
481
438
|
if (this.prev && this.prev.matches('~')) {
|
|
482
439
|
this.element.addChild(new LabelElement('\u22EE'));
|
|
483
440
|
}
|
|
484
|
-
|
|
485
|
-
|
|
441
|
+
const thisElement = toElement(selectorChild, parentElement);
|
|
442
|
+
const root = thisElement.findRoot();
|
|
486
443
|
this.element.addChild(root);
|
|
487
444
|
this.element = thisElement;
|
|
488
445
|
}
|
|
@@ -494,9 +451,8 @@ var SelectorElementBuilder = /** @class */ (function () {
|
|
|
494
451
|
this.prev = selectorChild;
|
|
495
452
|
}
|
|
496
453
|
}
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
}());
|
|
454
|
+
}
|
|
455
|
+
}
|
|
500
456
|
function isNewSelectorContext(node) {
|
|
501
457
|
switch (node.type) {
|
|
502
458
|
case nodes.NodeType.MixinDeclaration:
|
|
@@ -509,11 +465,11 @@ export function selectorToElement(node) {
|
|
|
509
465
|
if (node.matches('@at-root')) {
|
|
510
466
|
return null;
|
|
511
467
|
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
468
|
+
const root = new RootElement();
|
|
469
|
+
const parentRuleSets = [];
|
|
470
|
+
const ruleSet = node.getParent();
|
|
515
471
|
if (ruleSet instanceof nodes.RuleSet) {
|
|
516
|
-
|
|
472
|
+
let parent = ruleSet.getParent(); // parent of the selector's ruleset
|
|
517
473
|
while (parent && !isNewSelectorContext(parent)) {
|
|
518
474
|
if (parent instanceof nodes.RuleSet) {
|
|
519
475
|
if (parent.getSelectors().matches('@at-root')) {
|
|
@@ -524,9 +480,9 @@ export function selectorToElement(node) {
|
|
|
524
480
|
parent = parent.getParent();
|
|
525
481
|
}
|
|
526
482
|
}
|
|
527
|
-
|
|
528
|
-
for (
|
|
529
|
-
|
|
483
|
+
const builder = new SelectorElementBuilder(root);
|
|
484
|
+
for (let i = parentRuleSets.length - 1; i >= 0; i--) {
|
|
485
|
+
const selector = parentRuleSets[i].getSelectors().getChild(0);
|
|
530
486
|
if (selector) {
|
|
531
487
|
builder.processSelector(selector);
|
|
532
488
|
}
|
package/lib/esm/utils/arrays.js
CHANGED
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
* @returns the least x for which p(x) is true or array.length if no element fullfills the given function.
|
|
10
10
|
*/
|
|
11
11
|
export function findFirst(array, p) {
|
|
12
|
-
|
|
12
|
+
let low = 0, high = array.length;
|
|
13
13
|
if (high === 0) {
|
|
14
14
|
return 0; // no children
|
|
15
15
|
}
|
|
16
16
|
while (low < high) {
|
|
17
|
-
|
|
17
|
+
let mid = Math.floor((low + high) / 2);
|
|
18
18
|
if (p(array[mid])) {
|
|
19
19
|
high = mid;
|
|
20
20
|
}
|
|
@@ -27,16 +27,10 @@ export function findFirst(array, p) {
|
|
|
27
27
|
export function includes(array, item) {
|
|
28
28
|
return array.indexOf(item) !== -1;
|
|
29
29
|
}
|
|
30
|
-
export function union() {
|
|
31
|
-
|
|
32
|
-
for (
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
var result = [];
|
|
36
|
-
for (var _a = 0, arrays_1 = arrays; _a < arrays_1.length; _a++) {
|
|
37
|
-
var array = arrays_1[_a];
|
|
38
|
-
for (var _b = 0, array_1 = array; _b < array_1.length; _b++) {
|
|
39
|
-
var item = array_1[_b];
|
|
30
|
+
export function union(...arrays) {
|
|
31
|
+
const result = [];
|
|
32
|
+
for (const array of arrays) {
|
|
33
|
+
for (const item of array) {
|
|
40
34
|
if (!includes(result, item)) {
|
|
41
35
|
result.push(item);
|
|
42
36
|
}
|
package/lib/esm/utils/objects.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
'use strict';
|
|
6
6
|
export function values(obj) {
|
|
7
|
-
return Object.keys(obj).map(
|
|
7
|
+
return Object.keys(obj).map(key => obj[key]);
|
|
8
8
|
}
|
|
9
9
|
export function isDefined(obj) {
|
|
10
10
|
return typeof obj !== 'undefined';
|
|
@@ -2,23 +2,10 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
6
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
7
|
-
if (ar || !(i in from)) {
|
|
8
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
9
|
-
ar[i] = from[i];
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
13
|
-
};
|
|
14
5
|
import { URI, Utils } from 'vscode-uri';
|
|
15
6
|
export function dirname(uriString) {
|
|
16
|
-
return Utils.dirname(URI.parse(uriString)).toString();
|
|
7
|
+
return Utils.dirname(URI.parse(uriString)).toString(true);
|
|
17
8
|
}
|
|
18
|
-
export function joinPath(uriString) {
|
|
19
|
-
|
|
20
|
-
for (var _i = 1; _i < arguments.length; _i++) {
|
|
21
|
-
paths[_i - 1] = arguments[_i];
|
|
22
|
-
}
|
|
23
|
-
return Utils.joinPath.apply(Utils, __spreadArray([URI.parse(uriString)], paths, false)).toString();
|
|
9
|
+
export function joinPath(uriString, ...paths) {
|
|
10
|
+
return Utils.joinPath(URI.parse(uriString), ...paths).toString(true);
|
|
24
11
|
}
|