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