vscode-css-languageservice 6.2.4 → 6.2.6

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.
@@ -117,7 +117,7 @@ export const basicShapeFunctions = {
117
117
  'polygon()': 'Defines a polygon.'
118
118
  };
119
119
  export const units = {
120
- 'length': ['cap', 'ch', 'cm', 'cqb', 'cqh', 'cqi', 'cqmax', 'cqmin', 'cqw', 'dvb', 'dvh', 'dvi', 'dvw', 'em', 'ex', 'ic', 'in', 'lh', 'lvb', 'lvh', 'lvi', 'lvw', 'mm', 'pc', 'pt', 'px', 'q', 'rem', 'svb', 'svh', 'svi', 'svw', 'vb', 'vh', 'vi', 'vmax', 'vmin', 'vw'],
120
+ 'length': ['cap', 'ch', 'cm', 'cqb', 'cqh', 'cqi', 'cqmax', 'cqmin', 'cqw', 'dvb', 'dvh', 'dvi', 'dvw', 'em', 'ex', 'ic', 'in', 'lh', 'lvb', 'lvh', 'lvi', 'lvw', 'mm', 'pc', 'pt', 'px', 'q', 'rcap', 'rch', 'rem', 'rex', 'ric', 'rlh', 'svb', 'svh', 'svi', 'svw', 'vb', 'vh', 'vi', 'vmax', 'vmin', 'vw'],
121
121
  'angle': ['deg', 'rad', 'grad', 'turn'],
122
122
  'time': ['ms', 's'],
123
123
  'frequency': ['Hz', 'kHz'],
@@ -4,13 +4,130 @@
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import * as nodes from '../parser/cssNodes';
6
6
  import * as l10n from '@vscode/l10n';
7
+ const hexColorRegExp = /(^#([0-9A-F]{3}){1,2}$)|(^#([0-9A-F]{4}){1,2}$)/i;
7
8
  export const colorFunctions = [
8
- { func: 'rgb($red, $green, $blue)', desc: l10n.t('Creates a Color from red, green, and blue values.') },
9
- { func: 'rgba($red, $green, $blue, $alpha)', desc: l10n.t('Creates a Color from red, green, blue, and alpha values.') },
10
- { func: 'hsl($hue, $saturation, $lightness)', desc: l10n.t('Creates a Color from hue, saturation, and lightness values.') },
11
- { func: 'hsla($hue, $saturation, $lightness, $alpha)', desc: l10n.t('Creates a Color from hue, saturation, lightness, and alpha values.') },
12
- { func: 'hwb($hue $white $black)', desc: l10n.t('Creates a Color from hue, white and black.') }
9
+ {
10
+ label: 'rgb',
11
+ func: 'rgb($red, $green, $blue)',
12
+ insertText: 'rgb(${1:red}, ${2:green}, ${3:blue})',
13
+ desc: l10n.t('Creates a Color from red, green, and blue values.')
14
+ },
15
+ {
16
+ label: 'rgba',
17
+ func: 'rgba($red, $green, $blue, $alpha)',
18
+ insertText: 'rgba(${1:red}, ${2:green}, ${3:blue}, ${4:alpha})',
19
+ desc: l10n.t('Creates a Color from red, green, blue, and alpha values.')
20
+ },
21
+ {
22
+ label: 'rgb relative',
23
+ func: 'rgb(from $color $red $green $blue)',
24
+ insertText: 'rgb(from ${1:color} ${2:r} ${3:g} ${4:b})',
25
+ desc: l10n.t('Creates a Color from the red, green, and blue values of another Color.')
26
+ },
27
+ {
28
+ label: 'hsl',
29
+ func: 'hsl($hue, $saturation, $lightness)',
30
+ insertText: 'hsl(${1:hue}, ${2:saturation}, ${3:lightness})',
31
+ desc: l10n.t('Creates a Color from hue, saturation, and lightness values.')
32
+ },
33
+ {
34
+ label: 'hsla',
35
+ func: 'hsla($hue, $saturation, $lightness, $alpha)',
36
+ insertText: 'hsla(${1:hue}, ${2:saturation}, ${3:lightness}, ${4:alpha})',
37
+ desc: l10n.t('Creates a Color from hue, saturation, lightness, and alpha values.')
38
+ },
39
+ {
40
+ label: 'hsl relative',
41
+ func: 'hsl(from $color $hue $saturation $lightness)',
42
+ insertText: 'hsl(from ${1:color} ${2:h} ${3:s} ${4:l})',
43
+ desc: l10n.t('Creates a Color from the hue, saturation, and lightness values of another Color.')
44
+ },
45
+ {
46
+ label: 'hwb',
47
+ func: 'hwb($hue $white $black)',
48
+ insertText: 'hwb(${1:hue} ${2:white} ${3:black})',
49
+ desc: l10n.t('Creates a Color from hue, white, and black values.')
50
+ },
51
+ {
52
+ label: 'hwb relative',
53
+ func: 'hwb(from $color $hue $white $black)',
54
+ insertText: 'hwb(from ${1:color} ${2:h} ${3:w} ${4:b})',
55
+ desc: l10n.t('Creates a Color from the hue, white, and black values of another Color.')
56
+ },
57
+ {
58
+ label: 'lab',
59
+ func: 'lab($lightness $a $b)',
60
+ insertText: 'lab(${1:lightness} ${2:a} ${3:b})',
61
+ desc: l10n.t('Creates a Color from lightness, a, and b values.')
62
+ },
63
+ {
64
+ label: 'lab relative',
65
+ func: 'lab(from $color $lightness $a $b)',
66
+ insertText: 'lab(from ${1:color} ${2:l} ${3:a} ${4:b})',
67
+ desc: l10n.t('Creates a Color from the lightness, a, and b values of another Color.')
68
+ },
69
+ {
70
+ label: 'oklab',
71
+ func: 'oklab($lightness $a $b)',
72
+ insertText: 'oklab(${1:lightness} ${2:a} ${3:b})',
73
+ desc: l10n.t('Creates a Color from lightness, a, and b values.')
74
+ },
75
+ {
76
+ label: 'oklab relative',
77
+ func: 'oklab(from $color $lightness $a $b)',
78
+ insertText: 'oklab(from ${1:color} ${2:l} ${3:a} ${4:b})',
79
+ desc: l10n.t('Creates a Color from the lightness, a, and b values of another Color.')
80
+ },
81
+ {
82
+ label: 'lch',
83
+ func: 'lch($lightness $chroma $hue)',
84
+ insertText: 'lch(${1:lightness} ${2:chroma} ${3:hue})',
85
+ desc: l10n.t('Creates a Color from lightness, chroma, and hue values.')
86
+ },
87
+ {
88
+ label: 'lch relative',
89
+ func: 'lch(from $color $lightness $chroma $hue)',
90
+ insertText: 'lch(from ${1:color} ${2:l} ${3:c} ${4:h})',
91
+ desc: l10n.t('Creates a Color from the lightness, chroma, and hue values of another Color.')
92
+ },
93
+ {
94
+ label: 'oklch',
95
+ func: 'oklch($lightness $chroma $hue)',
96
+ insertText: 'oklch(${1:lightness} ${2:chroma} ${3:hue})',
97
+ desc: l10n.t('Creates a Color from lightness, chroma, and hue values.')
98
+ },
99
+ {
100
+ label: 'oklch relative',
101
+ func: 'oklch(from $color $lightness $chroma $hue)',
102
+ insertText: 'oklch(from ${1:color} ${2:l} ${3:c} ${4:h})',
103
+ desc: l10n.t('Creates a Color from the lightness, chroma, and hue values of another Color.')
104
+ },
105
+ {
106
+ label: 'color',
107
+ func: 'color($color-space $red $green $blue)',
108
+ insertText: 'color(${1|srgb,srgb-linear,display-p3,a98-rgb,prophoto-rgb,rec2020,xyx,xyz-d50,xyz-d65|} ${2:red} ${3:green} ${4:blue})',
109
+ desc: l10n.t('Creates a Color in a specific color space from red, green, and blue values.')
110
+ },
111
+ {
112
+ label: 'color relative',
113
+ func: 'color(from $color $color-space $red $green $blue)',
114
+ insertText: 'color(from ${1:color} ${2|srgb,srgb-linear,display-p3,a98-rgb,prophoto-rgb,rec2020,xyx,xyz-d50,xyz-d65|} ${3:r} ${4:g} ${5:b})',
115
+ desc: l10n.t('Creates a Color in a specific color space from the red, green, and blue values of another Color.')
116
+ },
117
+ {
118
+ label: 'color-mix',
119
+ func: 'color-mix(in $color-space, $color $percentage, $color $percentage)',
120
+ insertText: 'color-mix(in ${1|srgb,srgb-linear,lab,oklab,xyz,xyz-d50,xyz-d65|}, ${3:color} ${4:percentage}, ${5:color} ${6:percentage})',
121
+ desc: l10n.t('Mix two colors together in a rectangular color space.')
122
+ },
123
+ {
124
+ label: 'color-mix hue',
125
+ func: 'color-mix(in $color-space $interpolation-method hue, $color $percentage, $color $percentage)',
126
+ insertText: 'color-mix(in ${1|hsl,hwb,lch,oklch|} ${2|shorter hue,longer hue,increasing hue,decreasing hue|}, ${3:color} ${4:percentage}, ${5:color} ${6:percentage})',
127
+ desc: l10n.t('Mix two colors together in a polar color space.')
128
+ },
13
129
  ];
130
+ const colorFunctionNameRegExp = /^(rgb|rgba|hsl|hsla|hwb)$/i;
14
131
  export const colors = {
15
132
  aliceblue: '#f0f8ff',
16
133
  antiquewhite: '#faebd7',
@@ -161,10 +278,12 @@ export const colors = {
161
278
  yellow: '#ffff00',
162
279
  yellowgreen: '#9acd32'
163
280
  };
281
+ const colorsRegExp = new RegExp(`^(${Object.keys(colors).join('|')})$`, "i");
164
282
  export const colorKeywords = {
165
283
  'currentColor': 'The value of the \'color\' property. The computed value of the \'currentColor\' keyword is the computed value of the \'color\' property. If the \'currentColor\' keyword is set on the \'color\' property itself, it is treated as \'color:inherit\' at parse time.',
166
284
  'transparent': 'Fully transparent. This keyword can be considered a shorthand for rgba(0,0,0,0) which is its computed value.',
167
285
  };
286
+ const colorKeywordsRegExp = new RegExp(`^(${Object.keys(colorKeywords).join('|')})$`, "i");
168
287
  function getNumericValue(node, factor) {
169
288
  const val = node.getText();
170
289
  const m = val.match(/^([-+]?[0-9]*\.?[0-9]+)(%?)$/);
@@ -205,7 +324,10 @@ export function isColorConstructor(node) {
205
324
  if (!name) {
206
325
  return false;
207
326
  }
208
- return /^(rgb|rgba|hsl|hsla|hwb)$/gi.test(name);
327
+ return colorFunctionNameRegExp.test(name);
328
+ }
329
+ export function isColorString(s) {
330
+ return hexColorRegExp.test(s) || colorsRegExp.test(s) || colorKeywordsRegExp.test(s);
209
331
  }
210
332
  /**
211
333
  * Returns true if the node is a color value - either
@@ -1197,7 +1197,7 @@ export class MixinContentDeclaration extends BodyDeclaration {
1197
1197
  super(offset, length);
1198
1198
  }
1199
1199
  get type() {
1200
- return NodeType.MixinContentReference;
1200
+ return NodeType.MixinContentDeclaration;
1201
1201
  }
1202
1202
  getParameters() {
1203
1203
  if (!this.parameters) {
@@ -271,7 +271,7 @@ export class Parser {
271
271
  || this._parseFontFace()
272
272
  || this._parseKeyframe()
273
273
  || this._parseSupports(isNested)
274
- || this._parseLayer()
274
+ || this._parseLayer(isNested)
275
275
  || this._parsePropertyAtRule()
276
276
  || this._parseViewPort()
277
277
  || this._parseNamespace()
@@ -306,14 +306,20 @@ export class Parser {
306
306
  return this._parseBody(node, this._parseRuleSetDeclaration.bind(this));
307
307
  }
308
308
  _parseRuleSetDeclarationAtStatement() {
309
- return this._parseUnknownAtRule();
309
+ return this._parseMedia(true)
310
+ || this._parseSupports(true)
311
+ || this._parseLayer(true)
312
+ || this._parseUnknownAtRule();
310
313
  }
311
314
  _parseRuleSetDeclaration() {
312
315
  // https://www.w3.org/TR/css-syntax-3/#consume-a-list-of-declarations
313
316
  if (this.peek(TokenType.AtKeyword)) {
314
317
  return this._parseRuleSetDeclarationAtStatement();
315
318
  }
316
- return this._parseDeclaration();
319
+ if (!this.peek(TokenType.Ident)) {
320
+ return this._parseRuleset(true);
321
+ }
322
+ return this._tryParseRuleset(true) || this._parseDeclaration();
317
323
  }
318
324
  _needsSemicolonAfter(node) {
319
325
  switch (node.type) {
@@ -395,9 +401,9 @@ export class Parser {
395
401
  return hasContent ? this.finish(node) : null;
396
402
  }
397
403
  _parseDeclaration(stopTokens) {
398
- const custonProperty = this._tryParseCustomPropertyDeclaration(stopTokens);
399
- if (custonProperty) {
400
- return custonProperty;
404
+ const customProperty = this._tryParseCustomPropertyDeclaration(stopTokens);
405
+ if (customProperty) {
406
+ return customProperty;
401
407
  }
402
408
  const node = this.create(nodes.Declaration);
403
409
  if (!node.setProperty(this._parseProperty())) {
@@ -732,7 +738,7 @@ export class Parser {
732
738
  }
733
739
  return this._parseBody(node, this._parseDeclaration.bind(this));
734
740
  }
735
- _parseLayer() {
741
+ _parseLayer(isNested = false) {
736
742
  // @layer layer-name {rules}
737
743
  // @layer layer-name;
738
744
  // @layer layer-name, layer-name, layer-name;
@@ -747,13 +753,22 @@ export class Parser {
747
753
  node.setNames(names);
748
754
  }
749
755
  if ((!names || names.getChildren().length === 1) && this.peek(TokenType.CurlyL)) {
750
- return this._parseBody(node, this._parseStylesheetStatement.bind(this));
756
+ return this._parseBody(node, this._parseLayerDeclaration.bind(this, isNested));
751
757
  }
752
758
  if (!this.accept(TokenType.SemiColon)) {
753
759
  return this.finish(node, ParseError.SemiColonExpected);
754
760
  }
755
761
  return this.finish(node);
756
762
  }
763
+ _parseLayerDeclaration(isNested = false) {
764
+ if (isNested) {
765
+ // if nested, the body can contain rulesets, but also declarations
766
+ return this._tryParseRuleset(true)
767
+ || this._tryToParseDeclaration()
768
+ || this._parseStylesheetStatement(true);
769
+ }
770
+ return this._parseStylesheetStatement(false);
771
+ }
757
772
  _parseLayerNameList() {
758
773
  const node = this.createNode(nodes.NodeType.LayerNameList);
759
774
  if (!node.addChild(this._parseLayerName())) {
@@ -1251,7 +1266,7 @@ export class Parser {
1251
1266
  // : element_name [ HASH | class | attrib | pseudo ]* | [ HASH | class | attrib | pseudo ]+ ;
1252
1267
  const node = this.create(nodes.SimpleSelector);
1253
1268
  let c = 0;
1254
- if (node.addChild(this._parseElementName())) {
1269
+ if (node.addChild(this._parseElementName() || this._parseNestingSelector())) {
1255
1270
  c++;
1256
1271
  }
1257
1272
  while ((c === 0 || !this.hasWhitespace()) && node.addChild(this._parseSimpleSelectorBody())) {
@@ -1259,6 +1274,14 @@ export class Parser {
1259
1274
  }
1260
1275
  return c > 0 ? this.finish(node) : null;
1261
1276
  }
1277
+ _parseNestingSelector() {
1278
+ if (this.peekDelim('&')) {
1279
+ const node = this.createNode(nodes.NodeType.SelectorCombinator);
1280
+ this.consumeToken();
1281
+ return this.finish(node);
1282
+ }
1283
+ return null;
1284
+ }
1262
1285
  _parseSimpleSelectorBody() {
1263
1286
  return this._parsePseudo() || this._parseHash() || this._parseClass() || this._parseAttrib();
1264
1287
  }
@@ -276,14 +276,14 @@ export class LESSParser extends cssParser.Parser {
276
276
  || this._parsePropertyAtRule() // @property
277
277
  || this._parseDetachedRuleSetMixin() // less detached ruleset mixin
278
278
  || this._parseVariableDeclaration() // Variable declarations
279
- || super._parseRuleSetDeclarationAtStatement();
279
+ || this._parseRuleSetDeclarationAtStatement();
280
280
  }
281
281
  return this._tryParseMixinDeclaration()
282
282
  || this._tryParseRuleset(true) // nested ruleset
283
283
  || this._tryParseMixinReference() // less mixin reference
284
284
  || this._parseFunction()
285
285
  || this._parseExtend() // less extend declaration
286
- || super._parseRuleSetDeclaration(); // try css ruleset declaration as the last option
286
+ || this._parseDeclaration(); // try css ruleset declaration as the last option
287
287
  }
288
288
  _parseKeyframeIdent() {
289
289
  return this._parseIdent([nodes.ReferenceType.Keyframe]) || this._parseVariable();
@@ -292,9 +292,9 @@ export class LESSParser extends cssParser.Parser {
292
292
  return this._parseDetachedRuleSetMixin() // less detached ruleset mixin
293
293
  || super._parseKeyframeSelector();
294
294
  }
295
- _parseSimpleSelectorBody() {
296
- return this._parseSelectorCombinator() || super._parseSimpleSelectorBody();
297
- }
295
+ // public _parseSimpleSelectorBody(): nodes.Node | null {
296
+ // return this._parseNestingSelector() || super._parseSimpleSelectorBody();
297
+ // }
298
298
  _parseSelector(isNested) {
299
299
  // CSS Guards
300
300
  const node = this.create(nodes.Selector);
@@ -314,7 +314,7 @@ export class LESSParser extends cssParser.Parser {
314
314
  }
315
315
  return hasContent ? this.finish(node) : null;
316
316
  }
317
- _parseSelectorCombinator() {
317
+ _parseNestingSelector() {
318
318
  if (this.peekDelim('&')) {
319
319
  const node = this.createNode(nodes.NodeType.SelectorCombinator);
320
320
  this.consumeToken();
@@ -161,7 +161,7 @@ export class SCSSParser extends cssParser.Parser {
161
161
  _parseTermExpression() {
162
162
  return this._parseModuleMember() ||
163
163
  this._parseVariable() ||
164
- this._parseSelectorCombinator() ||
164
+ this._parseNestingSelector() ||
165
165
  //this._tryParsePrio() ||
166
166
  super._parseTermExpression();
167
167
  }
@@ -169,7 +169,7 @@ export class SCSSParser extends cssParser.Parser {
169
169
  if (this.peek(scssScanner.InterpolationFunction)) {
170
170
  const node = this.create(nodes.Interpolation);
171
171
  this.consumeToken();
172
- if (!node.addChild(this._parseExpr()) && !this._parseSelectorCombinator()) {
172
+ if (!node.addChild(this._parseExpr()) && !this._parseNestingSelector()) {
173
173
  if (this.accept(TokenType.CurlyR)) {
174
174
  return this.finish(node);
175
175
  }
@@ -219,11 +219,11 @@ export class SCSSParser extends cssParser.Parser {
219
219
  || this._parseSupports(true) // @supports
220
220
  || this._parseLayer() // @layer
221
221
  || this._parsePropertyAtRule() // @property
222
- || super._parseRuleSetDeclarationAtStatement();
222
+ || this._parseRuleSetDeclarationAtStatement();
223
223
  }
224
224
  return this._parseVariableDeclaration() // variable declaration
225
225
  || this._tryParseRuleset(true) // nested ruleset
226
- || super._parseRuleSetDeclaration(); // try css ruleset declaration as last so in the error case, the ast will contain a declaration
226
+ || this._parseDeclaration(); // try css ruleset declaration as last so in the error case, the ast will contain a declaration
227
227
  }
228
228
  _parseDeclaration(stopTokens) {
229
229
  const custonProperty = this._tryParseCustomPropertyDeclaration(stopTokens);
@@ -282,9 +282,9 @@ export class SCSSParser extends cssParser.Parser {
282
282
  return null;
283
283
  }
284
284
  _parseSimpleSelectorBody() {
285
- return this._parseSelectorCombinator() || this._parseSelectorPlaceholder() || super._parseSimpleSelectorBody();
285
+ return this._parseSelectorPlaceholder() || super._parseSimpleSelectorBody();
286
286
  }
287
- _parseSelectorCombinator() {
287
+ _parseNestingSelector() {
288
288
  if (this.peekDelim('&')) {
289
289
  const node = this.createNode(nodes.NodeType.SelectorCombinator);
290
290
  this.consumeToken();
@@ -404,7 +404,7 @@ export class CSSCompletion {
404
404
  kind: CompletionItemKind.Variable,
405
405
  sortText: SortTexts.Variable
406
406
  };
407
- if (typeof completionItem.documentation === 'string' && isColorString(completionItem.documentation)) {
407
+ if (typeof completionItem.documentation === 'string' && languageFacts.isColorString(completionItem.documentation)) {
408
408
  completionItem.kind = CompletionItemKind.Color;
409
409
  }
410
410
  if (symbol.node.type === nodes.NodeType.FunctionParameter) {
@@ -429,7 +429,7 @@ export class CSSCompletion {
429
429
  textEdit: TextEdit.replace(this.getCompletionRange(null), symbol.name),
430
430
  kind: CompletionItemKind.Variable
431
431
  };
432
- if (typeof completionItem.documentation === 'string' && isColorString(completionItem.documentation)) {
432
+ if (typeof completionItem.documentation === 'string' && languageFacts.isColorString(completionItem.documentation)) {
433
433
  completionItem.kind = CompletionItemKind.Color;
434
434
  }
435
435
  result.items.push(completionItem);
@@ -517,14 +517,11 @@ export class CSSCompletion {
517
517
  });
518
518
  }
519
519
  for (const p of languageFacts.colorFunctions) {
520
- let tabStop = 1;
521
- const replaceFunction = (_match, p1) => '${' + tabStop++ + ':' + p1 + '}';
522
- const insertText = p.func.replace(/\[?\$(\w+)\]?/g, replaceFunction);
523
520
  result.items.push({
524
- label: p.func.substr(0, p.func.indexOf('(')),
521
+ label: p.label,
525
522
  detail: p.func,
526
523
  documentation: p.desc,
527
- textEdit: TextEdit.replace(this.getCompletionRange(existingNode), insertText),
524
+ textEdit: TextEdit.replace(this.getCompletionRange(existingNode), p.insertText),
528
525
  insertTextFormat: SnippetFormat,
529
526
  kind: CompletionItemKind.Function
530
527
  });
@@ -1057,7 +1054,3 @@ function getCurrentWord(document, offset) {
1057
1054
  }
1058
1055
  return text.substring(i + 1, offset);
1059
1056
  }
1060
- function isColorString(s) {
1061
- // From https://stackoverflow.com/questions/8027423/how-to-check-if-a-string-is-a-valid-hex-color-representation/8027444
1062
- return (s.toLowerCase() in languageFacts.colors) || /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(s);
1063
- }
@@ -173,7 +173,7 @@ export class CSSNavigation {
173
173
  const addSymbolInformation = (name, kind, symbolNodeOrRange) => {
174
174
  const range = symbolNodeOrRange instanceof nodes.Node ? getRange(symbolNodeOrRange, document) : symbolNodeOrRange;
175
175
  const entry = {
176
- name,
176
+ name: name || l10n.t('<undefined>'),
177
177
  kind,
178
178
  location: Location.create(document.uri, range)
179
179
  };
@@ -187,9 +187,12 @@ export class CSSNavigation {
187
187
  const parents = [];
188
188
  const addDocumentSymbol = (name, kind, symbolNodeOrRange, nameNodeOrRange, bodyNode) => {
189
189
  const range = symbolNodeOrRange instanceof nodes.Node ? getRange(symbolNodeOrRange, document) : symbolNodeOrRange;
190
- const selectionRange = (nameNodeOrRange instanceof nodes.Node ? getRange(nameNodeOrRange, document) : nameNodeOrRange) ?? Range.create(range.start, range.start);
190
+ let selectionRange = nameNodeOrRange instanceof nodes.Node ? getRange(nameNodeOrRange, document) : nameNodeOrRange;
191
+ if (!selectionRange || !containsRange(range, selectionRange)) {
192
+ selectionRange = Range.create(range.start, range.start);
193
+ }
191
194
  const entry = {
192
- name,
195
+ name: name || l10n.t('<undefined>'),
193
196
  kind,
194
197
  range,
195
198
  selectionRange
@@ -6,7 +6,7 @@
6
6
  import { CSSCompletion } from './cssCompletion';
7
7
  import { CompletionItemKind, InsertTextFormat, TextEdit } from '../cssLanguageTypes';
8
8
  import * as l10n from '@vscode/l10n';
9
- export class LESSCompletion extends CSSCompletion {
9
+ class LESSCompletion extends CSSCompletion {
10
10
  constructor(lsOptions, cssDataManager) {
11
11
  super('@', lsOptions, cssDataManager);
12
12
  }
@@ -375,3 +375,4 @@ LESSCompletion.colorProposals = [
375
375
  'example': 'negation(@color1, @color2);'
376
376
  }
377
377
  ];
378
+ export { LESSCompletion };
@@ -25,7 +25,7 @@ class NodesByRootMap {
25
25
  }
26
26
  }
27
27
  }
28
- export class LintVisitor {
28
+ class LintVisitor {
29
29
  static entries(node, document, settings, cssDataManager, entryFilter) {
30
30
  const visitor = new LintVisitor(document, settings, cssDataManager);
31
31
  node.acceptVisitor(visitor);
@@ -562,3 +562,4 @@ LintVisitor.prefixes = [
562
562
  '-ms-', '-moz-', '-o-', '-webkit-', // Quite common
563
563
  // '-xv-', '-atsc-', '-wap-', '-khtml-', 'mso-', 'prince-', '-ah-', '-hp-', '-ro-', '-rim-', '-tc-' // Quite un-common
564
564
  ];
565
+ export { LintVisitor };
@@ -8,7 +8,7 @@ import * as nodes from '../parser/cssNodes';
8
8
  import { CompletionItemKind, TextEdit, InsertTextFormat } from '../cssLanguageTypes';
9
9
  import * as l10n from '@vscode/l10n';
10
10
  const sassDocumentationName = l10n.t('Sass documentation');
11
- export class SCSSCompletion extends CSSCompletion {
11
+ class SCSSCompletion extends CSSCompletion {
12
12
  constructor(lsServiceOptions, cssDataManager) {
13
13
  super('$', lsServiceOptions, cssDataManager);
14
14
  addReferencesToDocumentation(SCSSCompletion.scssModuleLoaders);
@@ -333,6 +333,7 @@ SCSSCompletion.scssModuleBuiltIns = [
333
333
  references: [{ name: sassDocumentationName, url: 'https://sass-lang.com/documentation/modules/meta' }]
334
334
  },
335
335
  ];
336
+ export { SCSSCompletion };
336
337
  /**
337
338
  * Todo @Pine: Remove this and do it through custom data
338
339
  */
@@ -402,8 +402,7 @@ export class SelectorPrinting {
402
402
  return specificity;
403
403
  };
404
404
  const specificity = calculateScore(node);
405
- ;
406
- return l10n.t("[Selector Specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity): ({0}, {1}, {2})", specificity.id, specificity.attr, specificity.tag);
405
+ return `[${l10n.t("Selector Specificity")}](https://developer.mozilla.org/docs/Web/CSS/Specificity): (${specificity.id}, ${specificity.attr}, ${specificity.tag})`;
407
406
  }
408
407
  }
409
408
  class SelectorElementBuilder {