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.
Files changed (83) hide show
  1. package/CHANGELOG.md +7 -1
  2. package/SECURITY.md +41 -0
  3. package/lib/esm/beautify/beautify-css.js +11 -4
  4. package/lib/esm/cssLanguageService.d.ts +2 -1
  5. package/lib/esm/cssLanguageService.js +15 -17
  6. package/lib/esm/cssLanguageTypes.js +2 -2
  7. package/lib/esm/data/webCustomData.js +356 -232
  8. package/lib/esm/languageFacts/builtinData.js +15 -15
  9. package/lib/esm/languageFacts/colors.js +66 -69
  10. package/lib/esm/languageFacts/dataManager.js +38 -42
  11. package/lib/esm/languageFacts/dataProvider.js +17 -23
  12. package/lib/esm/languageFacts/entry.js +22 -23
  13. package/lib/esm/parser/cssErrors.js +5 -7
  14. package/lib/esm/parser/cssNodes.js +869 -1377
  15. package/lib/esm/parser/cssParser.js +419 -376
  16. package/lib/esm/parser/cssScanner.js +168 -175
  17. package/lib/esm/parser/cssSymbolScope.js +107 -137
  18. package/lib/esm/parser/lessParser.js +177 -202
  19. package/lib/esm/parser/lessScanner.js +22 -43
  20. package/lib/esm/parser/scssErrors.js +5 -7
  21. package/lib/esm/parser/scssParser.js +196 -208
  22. package/lib/esm/parser/scssScanner.js +33 -54
  23. package/lib/esm/services/cssCodeActions.js +36 -40
  24. package/lib/esm/services/cssCompletion.js +300 -395
  25. package/lib/esm/services/cssFolding.js +32 -35
  26. package/lib/esm/services/cssFormatter.js +22 -22
  27. package/lib/esm/services/cssHover.js +30 -33
  28. package/lib/esm/services/cssNavigation.js +260 -289
  29. package/lib/esm/services/cssSelectionRange.js +6 -6
  30. package/lib/esm/services/cssValidation.js +13 -16
  31. package/lib/esm/services/lessCompletion.js +351 -370
  32. package/lib/esm/services/lint.js +161 -175
  33. package/lib/esm/services/lintRules.js +20 -27
  34. package/lib/esm/services/lintUtil.js +19 -28
  35. package/lib/esm/services/pathCompletion.js +84 -158
  36. package/lib/esm/services/scssCompletion.js +283 -307
  37. package/lib/esm/services/scssNavigation.js +65 -137
  38. package/lib/esm/services/selectorPrinting.js +131 -175
  39. package/lib/esm/utils/arrays.js +6 -12
  40. package/lib/esm/utils/objects.js +1 -1
  41. package/lib/esm/utils/resources.js +3 -16
  42. package/lib/esm/utils/strings.js +10 -12
  43. package/lib/umd/beautify/beautify-css.js +11 -4
  44. package/lib/umd/cssLanguageService.d.ts +2 -1
  45. package/lib/umd/cssLanguageService.js +34 -32
  46. package/lib/umd/cssLanguageTypes.js +4 -3
  47. package/lib/umd/data/webCustomData.js +355 -231
  48. package/lib/umd/languageFacts/colors.js +65 -68
  49. package/lib/umd/languageFacts/dataManager.js +41 -44
  50. package/lib/umd/languageFacts/dataProvider.js +17 -22
  51. package/lib/umd/languageFacts/entry.js +22 -23
  52. package/lib/umd/languageFacts/facts.js +5 -1
  53. package/lib/umd/parser/cssErrors.js +5 -6
  54. package/lib/umd/parser/cssNodes.js +870 -1307
  55. package/lib/umd/parser/cssParser.js +424 -380
  56. package/lib/umd/parser/cssScanner.js +168 -173
  57. package/lib/umd/parser/cssSymbolScope.js +109 -134
  58. package/lib/umd/parser/lessParser.js +182 -206
  59. package/lib/umd/parser/lessScanner.js +22 -42
  60. package/lib/umd/parser/scssErrors.js +5 -6
  61. package/lib/umd/parser/scssParser.js +202 -213
  62. package/lib/umd/parser/scssScanner.js +25 -45
  63. package/lib/umd/services/cssCodeActions.js +41 -44
  64. package/lib/umd/services/cssCompletion.js +308 -402
  65. package/lib/umd/services/cssFolding.js +35 -38
  66. package/lib/umd/services/cssFormatter.js +25 -25
  67. package/lib/umd/services/cssHover.js +36 -38
  68. package/lib/umd/services/cssNavigation.js +267 -295
  69. package/lib/umd/services/cssSelectionRange.js +8 -8
  70. package/lib/umd/services/cssValidation.js +17 -19
  71. package/lib/umd/services/lessCompletion.js +354 -372
  72. package/lib/umd/services/lint.js +167 -180
  73. package/lib/umd/services/lintRules.js +20 -24
  74. package/lib/umd/services/lintUtil.js +20 -28
  75. package/lib/umd/services/pathCompletion.js +87 -160
  76. package/lib/umd/services/scssCompletion.js +287 -310
  77. package/lib/umd/services/scssNavigation.js +69 -140
  78. package/lib/umd/services/selectorPrinting.js +134 -174
  79. package/lib/umd/utils/arrays.js +6 -12
  80. package/lib/umd/utils/objects.js +1 -1
  81. package/lib/umd/utils/resources.js +4 -17
  82. package/lib/umd/utils/strings.js +10 -12
  83. package/package.json +16 -15
@@ -3,42 +3,6 @@
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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
7
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
8
- return new (P || (P = Promise))(function (resolve, reject) {
9
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
10
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
11
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
12
- step((generator = generator.apply(thisArg, _arguments || [])).next());
13
- });
14
- };
15
- var __generator = (this && this.__generator) || function (thisArg, body) {
16
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
17
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
18
- function verb(n) { return function (v) { return step([n, v]); }; }
19
- function step(op) {
20
- if (f) throw new TypeError("Generator is already executing.");
21
- while (_) try {
22
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
23
- if (y = 0, t) op = [op[0] & 2, t.value];
24
- switch (op[0]) {
25
- case 0: case 1: t = op; break;
26
- case 4: _.label++; return { value: op[1], done: false };
27
- case 5: _.label++; y = op[1]; op = [0]; continue;
28
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
29
- default:
30
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
31
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
32
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
33
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
34
- if (t[2]) _.ops.pop();
35
- _.trys.pop(); continue;
36
- }
37
- op = body.call(thisArg, _);
38
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
39
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
40
- }
41
- };
42
6
  import { DocumentHighlightKind, Location, Range, SymbolKind, TextEdit, FileType } from '../cssLanguageTypes';
43
7
  import * as nls from 'vscode-nls';
44
8
  import * as nodes from '../parser/cssNodes';
@@ -46,22 +10,22 @@ import { Symbols } from '../parser/cssSymbolScope';
46
10
  import { getColorValue, hslFromColor, hwbFromColor } from '../languageFacts/facts';
47
11
  import { startsWith } from '../utils/strings';
48
12
  import { dirname, joinPath } from '../utils/resources';
49
- var localize = nls.loadMessageBundle();
50
- var startsWithSchemeRegex = /^\w+:\/\//;
51
- var startsWithData = /^data:/;
52
- var CSSNavigation = /** @class */ (function () {
53
- function CSSNavigation(fileSystemProvider, resolveModuleReferences) {
13
+ const localize = nls.loadMessageBundle();
14
+ const startsWithSchemeRegex = /^\w+:\/\//;
15
+ const startsWithData = /^data:/;
16
+ export class CSSNavigation {
17
+ constructor(fileSystemProvider, resolveModuleReferences) {
54
18
  this.fileSystemProvider = fileSystemProvider;
55
19
  this.resolveModuleReferences = resolveModuleReferences;
56
20
  }
57
- CSSNavigation.prototype.findDefinition = function (document, position, stylesheet) {
58
- var symbols = new Symbols(stylesheet);
59
- var offset = document.offsetAt(position);
60
- var node = nodes.getNodeAtOffset(stylesheet, offset);
21
+ findDefinition(document, position, stylesheet) {
22
+ const symbols = new Symbols(stylesheet);
23
+ const offset = document.offsetAt(position);
24
+ const node = nodes.getNodeAtOffset(stylesheet, offset);
61
25
  if (!node) {
62
26
  return null;
63
27
  }
64
- var symbol = symbols.findSymbolFromNode(node);
28
+ const symbol = symbols.findSymbolFromNode(node);
65
29
  if (!symbol) {
66
30
  return null;
67
31
  }
@@ -69,30 +33,30 @@ var CSSNavigation = /** @class */ (function () {
69
33
  uri: document.uri,
70
34
  range: getRange(symbol.node, document)
71
35
  };
72
- };
73
- CSSNavigation.prototype.findReferences = function (document, position, stylesheet) {
74
- var highlights = this.findDocumentHighlights(document, position, stylesheet);
75
- return highlights.map(function (h) {
36
+ }
37
+ findReferences(document, position, stylesheet) {
38
+ const highlights = this.findDocumentHighlights(document, position, stylesheet);
39
+ return highlights.map(h => {
76
40
  return {
77
41
  uri: document.uri,
78
42
  range: h.range
79
43
  };
80
44
  });
81
- };
82
- CSSNavigation.prototype.findDocumentHighlights = function (document, position, stylesheet) {
83
- var result = [];
84
- var offset = document.offsetAt(position);
85
- var node = nodes.getNodeAtOffset(stylesheet, offset);
45
+ }
46
+ findDocumentHighlights(document, position, stylesheet) {
47
+ const result = [];
48
+ const offset = document.offsetAt(position);
49
+ let node = nodes.getNodeAtOffset(stylesheet, offset);
86
50
  if (!node || node.type === nodes.NodeType.Stylesheet || node.type === nodes.NodeType.Declarations) {
87
51
  return result;
88
52
  }
89
53
  if (node.type === nodes.NodeType.Identifier && node.parent && node.parent.type === nodes.NodeType.ClassSelector) {
90
54
  node = node.parent;
91
55
  }
92
- var symbols = new Symbols(stylesheet);
93
- var symbol = symbols.findSymbolFromNode(node);
94
- var name = node.getText();
95
- stylesheet.accept(function (candidate) {
56
+ const symbols = new Symbols(stylesheet);
57
+ const symbol = symbols.findSymbolFromNode(node);
58
+ const name = node.getText();
59
+ stylesheet.accept(candidate => {
96
60
  if (symbol) {
97
61
  if (symbols.matchesSymbol(candidate, symbol)) {
98
62
  result.push({
@@ -112,17 +76,16 @@ var CSSNavigation = /** @class */ (function () {
112
76
  return true;
113
77
  });
114
78
  return result;
115
- };
116
- CSSNavigation.prototype.isRawStringDocumentLinkNode = function (node) {
79
+ }
80
+ isRawStringDocumentLinkNode(node) {
117
81
  return node.type === nodes.NodeType.Import;
118
- };
119
- CSSNavigation.prototype.findDocumentLinks = function (document, stylesheet, documentContext) {
120
- var linkData = this.findUnresolvedLinks(document, stylesheet);
121
- var resolvedLinks = [];
122
- for (var _i = 0, linkData_1 = linkData; _i < linkData_1.length; _i++) {
123
- var data = linkData_1[_i];
124
- var link = data.link;
125
- var target = link.target;
82
+ }
83
+ findDocumentLinks(document, stylesheet, documentContext) {
84
+ const linkData = this.findUnresolvedLinks(document, stylesheet);
85
+ const resolvedLinks = [];
86
+ for (let data of linkData) {
87
+ const link = data.link;
88
+ const target = link.target;
126
89
  if (!target || startsWithData.test(target)) {
127
90
  // no links for data:
128
91
  }
@@ -130,7 +93,7 @@ var CSSNavigation = /** @class */ (function () {
130
93
  resolvedLinks.push(link);
131
94
  }
132
95
  else {
133
- var resolved = documentContext.resolveReference(target, document.uri);
96
+ const resolved = documentContext.resolveReference(target, document.uri);
134
97
  if (resolved) {
135
98
  link.target = resolved;
136
99
  }
@@ -138,63 +101,47 @@ var CSSNavigation = /** @class */ (function () {
138
101
  }
139
102
  }
140
103
  return resolvedLinks;
141
- };
142
- CSSNavigation.prototype.findDocumentLinks2 = function (document, stylesheet, documentContext) {
143
- return __awaiter(this, void 0, void 0, function () {
144
- var linkData, resolvedLinks, _i, linkData_2, data, link, target, resolvedTarget;
145
- return __generator(this, function (_a) {
146
- switch (_a.label) {
147
- case 0:
148
- linkData = this.findUnresolvedLinks(document, stylesheet);
149
- resolvedLinks = [];
150
- _i = 0, linkData_2 = linkData;
151
- _a.label = 1;
152
- case 1:
153
- if (!(_i < linkData_2.length)) return [3 /*break*/, 6];
154
- data = linkData_2[_i];
155
- link = data.link;
156
- target = link.target;
157
- if (!(!target || startsWithData.test(target))) return [3 /*break*/, 2];
158
- return [3 /*break*/, 5];
159
- case 2:
160
- if (!startsWithSchemeRegex.test(target)) return [3 /*break*/, 3];
161
- resolvedLinks.push(link);
162
- return [3 /*break*/, 5];
163
- case 3: return [4 /*yield*/, this.resolveRelativeReference(target, document.uri, documentContext, data.isRawLink)];
164
- case 4:
165
- resolvedTarget = _a.sent();
166
- if (resolvedTarget !== undefined) {
167
- link.target = resolvedTarget;
168
- resolvedLinks.push(link);
169
- }
170
- _a.label = 5;
171
- case 5:
172
- _i++;
173
- return [3 /*break*/, 1];
174
- case 6: return [2 /*return*/, resolvedLinks];
104
+ }
105
+ async findDocumentLinks2(document, stylesheet, documentContext) {
106
+ const linkData = this.findUnresolvedLinks(document, stylesheet);
107
+ const resolvedLinks = [];
108
+ for (let data of linkData) {
109
+ const link = data.link;
110
+ const target = link.target;
111
+ if (!target || startsWithData.test(target)) {
112
+ // no links for data:
113
+ }
114
+ else if (startsWithSchemeRegex.test(target)) {
115
+ resolvedLinks.push(link);
116
+ }
117
+ else {
118
+ const resolvedTarget = await this.resolveRelativeReference(target, document.uri, documentContext, data.isRawLink);
119
+ if (resolvedTarget !== undefined) {
120
+ link.target = resolvedTarget;
121
+ resolvedLinks.push(link);
175
122
  }
176
- });
177
- });
178
- };
179
- CSSNavigation.prototype.findUnresolvedLinks = function (document, stylesheet) {
180
- var _this = this;
181
- var result = [];
182
- var collect = function (uriStringNode) {
183
- var rawUri = uriStringNode.getText();
184
- var range = getRange(uriStringNode, document);
123
+ }
124
+ }
125
+ return resolvedLinks;
126
+ }
127
+ findUnresolvedLinks(document, stylesheet) {
128
+ const result = [];
129
+ const collect = (uriStringNode) => {
130
+ let rawUri = uriStringNode.getText();
131
+ const range = getRange(uriStringNode, document);
185
132
  // Make sure the range is not empty
186
133
  if (range.start.line === range.end.line && range.start.character === range.end.character) {
187
134
  return;
188
135
  }
189
- if (startsWith(rawUri, "'") || startsWith(rawUri, "\"")) {
136
+ if (startsWith(rawUri, `'`) || startsWith(rawUri, `"`)) {
190
137
  rawUri = rawUri.slice(1, -1);
191
138
  }
192
- var isRawLink = uriStringNode.parent ? _this.isRawStringDocumentLinkNode(uriStringNode.parent) : false;
193
- result.push({ link: { target: rawUri, range: range }, isRawLink: isRawLink });
139
+ const isRawLink = uriStringNode.parent ? this.isRawStringDocumentLinkNode(uriStringNode.parent) : false;
140
+ result.push({ link: { target: rawUri, range }, isRawLink });
194
141
  };
195
- stylesheet.accept(function (candidate) {
142
+ stylesheet.accept(candidate => {
196
143
  if (candidate.type === nodes.NodeType.URILiteral) {
197
- var first = candidate.getChild(0);
144
+ const first = candidate.getChild(0);
198
145
  if (first) {
199
146
  collect(first);
200
147
  }
@@ -204,9 +151,9 @@ var CSSNavigation = /** @class */ (function () {
204
151
  * In @import, it is possible to include links that do not use `url()`
205
152
  * For example, `@import 'foo.css';`
206
153
  */
207
- if (candidate.parent && _this.isRawStringDocumentLinkNode(candidate.parent)) {
208
- var rawText = candidate.getText();
209
- if (startsWith(rawText, "'") || startsWith(rawText, "\"")) {
154
+ if (candidate.parent && this.isRawStringDocumentLinkNode(candidate.parent)) {
155
+ const rawText = candidate.getText();
156
+ if (startsWith(rawText, `'`) || startsWith(rawText, `"`)) {
210
157
  collect(candidate);
211
158
  }
212
159
  return false;
@@ -214,226 +161,241 @@ var CSSNavigation = /** @class */ (function () {
214
161
  return true;
215
162
  });
216
163
  return result;
217
- };
218
- CSSNavigation.prototype.findDocumentSymbols = function (document, stylesheet) {
219
- var result = [];
220
- stylesheet.accept(function (node) {
221
- var entry = {
222
- name: null,
223
- kind: SymbolKind.Class,
224
- location: null
164
+ }
165
+ findSymbolInformations(document, stylesheet) {
166
+ const result = [];
167
+ const addSymbolInformation = (name, kind, symbolNodeOrRange) => {
168
+ const range = symbolNodeOrRange instanceof nodes.Node ? getRange(symbolNodeOrRange, document) : symbolNodeOrRange;
169
+ const entry = {
170
+ name,
171
+ kind,
172
+ location: Location.create(document.uri, range)
225
173
  };
226
- var locationNode = node;
227
- if (node instanceof nodes.Selector) {
228
- entry.name = node.getText();
229
- locationNode = node.findAParent(nodes.NodeType.Ruleset, nodes.NodeType.ExtendsReference);
230
- if (locationNode) {
231
- entry.location = Location.create(document.uri, getRange(locationNode, document));
232
- result.push(entry);
174
+ result.push(entry);
175
+ };
176
+ this.collectDocumentSymbols(document, stylesheet, addSymbolInformation);
177
+ return result;
178
+ }
179
+ findDocumentSymbols(document, stylesheet) {
180
+ const result = [];
181
+ const parents = [];
182
+ const addDocumentSymbol = (name, kind, symbolNodeOrRange, nameNodeOrRange, bodyNode) => {
183
+ const range = symbolNodeOrRange instanceof nodes.Node ? getRange(symbolNodeOrRange, document) : symbolNodeOrRange;
184
+ const selectionRange = (nameNodeOrRange instanceof nodes.Node ? getRange(nameNodeOrRange, document) : nameNodeOrRange) ?? Range.create(range.start, range.start);
185
+ const entry = {
186
+ name,
187
+ kind,
188
+ range,
189
+ selectionRange
190
+ };
191
+ let top = parents.pop();
192
+ while (top && !containsRange(top[1], range)) {
193
+ top = parents.pop();
194
+ }
195
+ if (top) {
196
+ const topSymbol = top[0];
197
+ if (!topSymbol.children) {
198
+ topSymbol.children = [];
199
+ }
200
+ topSymbol.children.push(entry);
201
+ parents.push(top); // put back top
202
+ }
203
+ else {
204
+ result.push(entry);
205
+ }
206
+ if (bodyNode) {
207
+ parents.push([entry, getRange(bodyNode, document)]);
208
+ }
209
+ };
210
+ this.collectDocumentSymbols(document, stylesheet, addDocumentSymbol);
211
+ return result;
212
+ }
213
+ collectDocumentSymbols(document, stylesheet, collect) {
214
+ stylesheet.accept(node => {
215
+ if (node instanceof nodes.RuleSet) {
216
+ for (const selector of node.getSelectors().getChildren()) {
217
+ if (selector instanceof nodes.Selector) {
218
+ const range = Range.create(document.positionAt(selector.offset), document.positionAt(node.end));
219
+ collect(selector.getText(), SymbolKind.Class, range, selector, node.getDeclarations());
220
+ }
233
221
  }
234
- return false;
235
222
  }
236
223
  else if (node instanceof nodes.VariableDeclaration) {
237
- entry.name = node.getName();
238
- entry.kind = SymbolKind.Variable;
224
+ collect(node.getName(), SymbolKind.Variable, node, node.getVariable(), undefined);
239
225
  }
240
226
  else if (node instanceof nodes.MixinDeclaration) {
241
- entry.name = node.getName();
242
- entry.kind = SymbolKind.Method;
227
+ collect(node.getName(), SymbolKind.Method, node, node.getIdentifier(), node.getDeclarations());
243
228
  }
244
229
  else if (node instanceof nodes.FunctionDeclaration) {
245
- entry.name = node.getName();
246
- entry.kind = SymbolKind.Function;
230
+ collect(node.getName(), SymbolKind.Function, node, node.getIdentifier(), node.getDeclarations());
247
231
  }
248
232
  else if (node instanceof nodes.Keyframe) {
249
- entry.name = localize('literal.keyframes', "@keyframes {0}", node.getName());
233
+ const name = localize('literal.keyframes', "@keyframes {0}", node.getName());
234
+ collect(name, SymbolKind.Class, node, node.getIdentifier(), node.getDeclarations());
250
235
  }
251
236
  else if (node instanceof nodes.FontFace) {
252
- entry.name = localize('literal.fontface', "@font-face");
237
+ const name = localize('literal.fontface', "@font-face");
238
+ collect(name, SymbolKind.Class, node, undefined, node.getDeclarations());
253
239
  }
254
240
  else if (node instanceof nodes.Media) {
255
- var mediaList = node.getChild(0);
241
+ const mediaList = node.getChild(0);
256
242
  if (mediaList instanceof nodes.Medialist) {
257
- entry.name = '@media ' + mediaList.getText();
258
- entry.kind = SymbolKind.Module;
243
+ const name = '@media ' + mediaList.getText();
244
+ collect(name, SymbolKind.Module, node, mediaList, node.getDeclarations());
259
245
  }
260
246
  }
261
- if (entry.name) {
262
- entry.location = Location.create(document.uri, getRange(locationNode, document));
263
- result.push(entry);
264
- }
265
247
  return true;
266
248
  });
267
- return result;
268
- };
269
- CSSNavigation.prototype.findDocumentColors = function (document, stylesheet) {
270
- var result = [];
271
- stylesheet.accept(function (node) {
272
- var colorInfo = getColorInformation(node, document);
249
+ }
250
+ findDocumentColors(document, stylesheet) {
251
+ const result = [];
252
+ stylesheet.accept((node) => {
253
+ const colorInfo = getColorInformation(node, document);
273
254
  if (colorInfo) {
274
255
  result.push(colorInfo);
275
256
  }
276
257
  return true;
277
258
  });
278
259
  return result;
279
- };
280
- CSSNavigation.prototype.getColorPresentations = function (document, stylesheet, color, range) {
281
- var result = [];
282
- var red256 = Math.round(color.red * 255), green256 = Math.round(color.green * 255), blue256 = Math.round(color.blue * 255);
283
- var label;
260
+ }
261
+ getColorPresentations(document, stylesheet, color, range) {
262
+ const result = [];
263
+ const red256 = Math.round(color.red * 255), green256 = Math.round(color.green * 255), blue256 = Math.round(color.blue * 255);
264
+ let label;
284
265
  if (color.alpha === 1) {
285
- label = "rgb(".concat(red256, ", ").concat(green256, ", ").concat(blue256, ")");
266
+ label = `rgb(${red256}, ${green256}, ${blue256})`;
286
267
  }
287
268
  else {
288
- label = "rgba(".concat(red256, ", ").concat(green256, ", ").concat(blue256, ", ").concat(color.alpha, ")");
269
+ label = `rgba(${red256}, ${green256}, ${blue256}, ${color.alpha})`;
289
270
  }
290
271
  result.push({ label: label, textEdit: TextEdit.replace(range, label) });
291
272
  if (color.alpha === 1) {
292
- label = "#".concat(toTwoDigitHex(red256)).concat(toTwoDigitHex(green256)).concat(toTwoDigitHex(blue256));
273
+ label = `#${toTwoDigitHex(red256)}${toTwoDigitHex(green256)}${toTwoDigitHex(blue256)}`;
293
274
  }
294
275
  else {
295
- label = "#".concat(toTwoDigitHex(red256)).concat(toTwoDigitHex(green256)).concat(toTwoDigitHex(blue256)).concat(toTwoDigitHex(Math.round(color.alpha * 255)));
276
+ label = `#${toTwoDigitHex(red256)}${toTwoDigitHex(green256)}${toTwoDigitHex(blue256)}${toTwoDigitHex(Math.round(color.alpha * 255))}`;
296
277
  }
297
278
  result.push({ label: label, textEdit: TextEdit.replace(range, label) });
298
- var hsl = hslFromColor(color);
279
+ const hsl = hslFromColor(color);
299
280
  if (hsl.a === 1) {
300
- label = "hsl(".concat(hsl.h, ", ").concat(Math.round(hsl.s * 100), "%, ").concat(Math.round(hsl.l * 100), "%)");
281
+ label = `hsl(${hsl.h}, ${Math.round(hsl.s * 100)}%, ${Math.round(hsl.l * 100)}%)`;
301
282
  }
302
283
  else {
303
- label = "hsla(".concat(hsl.h, ", ").concat(Math.round(hsl.s * 100), "%, ").concat(Math.round(hsl.l * 100), "%, ").concat(hsl.a, ")");
284
+ label = `hsla(${hsl.h}, ${Math.round(hsl.s * 100)}%, ${Math.round(hsl.l * 100)}%, ${hsl.a})`;
304
285
  }
305
286
  result.push({ label: label, textEdit: TextEdit.replace(range, label) });
306
- var hwb = hwbFromColor(color);
287
+ const hwb = hwbFromColor(color);
307
288
  if (hwb.a === 1) {
308
- label = "hwb(".concat(hwb.h, " ").concat(Math.round(hwb.w * 100), "% ").concat(Math.round(hwb.b * 100), "%)");
289
+ label = `hwb(${hwb.h} ${Math.round(hwb.w * 100)}% ${Math.round(hwb.b * 100)}%)`;
309
290
  }
310
291
  else {
311
- label = "hwb(".concat(hwb.h, " ").concat(Math.round(hwb.w * 100), "% ").concat(Math.round(hwb.b * 100), "% / ").concat(hwb.a, ")");
292
+ label = `hwb(${hwb.h} ${Math.round(hwb.w * 100)}% ${Math.round(hwb.b * 100)}% / ${hwb.a})`;
312
293
  }
313
294
  result.push({ label: label, textEdit: TextEdit.replace(range, label) });
314
295
  return result;
315
- };
316
- CSSNavigation.prototype.doRename = function (document, position, newName, stylesheet) {
317
- var _a;
318
- var highlights = this.findDocumentHighlights(document, position, stylesheet);
319
- var edits = highlights.map(function (h) { return TextEdit.replace(h.range, newName); });
296
+ }
297
+ doRename(document, position, newName, stylesheet) {
298
+ const highlights = this.findDocumentHighlights(document, position, stylesheet);
299
+ const edits = highlights.map(h => TextEdit.replace(h.range, newName));
320
300
  return {
321
- changes: (_a = {}, _a[document.uri] = edits, _a)
301
+ changes: { [document.uri]: edits }
322
302
  };
323
- };
324
- CSSNavigation.prototype.resolveModuleReference = function (ref, documentUri, documentContext) {
325
- return __awaiter(this, void 0, void 0, function () {
326
- var moduleName, rootFolderUri, documentFolderUri, modulePath, pathWithinModule;
327
- return __generator(this, function (_a) {
328
- switch (_a.label) {
329
- case 0:
330
- if (!startsWith(documentUri, 'file://')) return [3 /*break*/, 2];
331
- moduleName = getModuleNameFromPath(ref);
332
- rootFolderUri = documentContext.resolveReference('/', documentUri);
333
- documentFolderUri = dirname(documentUri);
334
- return [4 /*yield*/, this.resolvePathToModule(moduleName, documentFolderUri, rootFolderUri)];
335
- case 1:
336
- modulePath = _a.sent();
337
- if (modulePath) {
338
- pathWithinModule = ref.substring(moduleName.length + 1);
339
- return [2 /*return*/, joinPath(modulePath, pathWithinModule)];
340
- }
341
- _a.label = 2;
342
- case 2: return [2 /*return*/, undefined];
343
- }
344
- });
345
- });
346
- };
347
- CSSNavigation.prototype.resolveRelativeReference = function (ref, documentUri, documentContext, isRawLink) {
348
- return __awaiter(this, void 0, void 0, function () {
349
- var relativeReference, _a;
350
- return __generator(this, function (_b) {
351
- switch (_b.label) {
352
- case 0:
353
- relativeReference = documentContext.resolveReference(ref, documentUri);
354
- if (!(ref[0] === '~' && ref[1] !== '/' && this.fileSystemProvider)) return [3 /*break*/, 2];
355
- ref = ref.substring(1);
356
- return [4 /*yield*/, this.resolveModuleReference(ref, documentUri, documentContext)];
357
- case 1: return [2 /*return*/, (_b.sent()) || relativeReference];
358
- case 2:
359
- if (!this.resolveModuleReferences) return [3 /*break*/, 7];
360
- _a = relativeReference;
361
- if (!_a) return [3 /*break*/, 4];
362
- return [4 /*yield*/, this.fileExists(relativeReference)];
363
- case 3:
364
- _a = (_b.sent());
365
- _b.label = 4;
366
- case 4:
367
- if (!_a) return [3 /*break*/, 5];
368
- return [2 /*return*/, relativeReference];
369
- case 5: return [4 /*yield*/, this.resolveModuleReference(ref, documentUri, documentContext)];
370
- case 6: return [2 /*return*/, (_b.sent()) || relativeReference];
371
- case 7: return [2 /*return*/, relativeReference];
372
- }
373
- });
374
- });
375
- };
376
- CSSNavigation.prototype.resolvePathToModule = function (_moduleName, documentFolderUri, rootFolderUri) {
377
- return __awaiter(this, void 0, void 0, function () {
378
- var packPath;
379
- return __generator(this, function (_a) {
380
- switch (_a.label) {
381
- case 0:
382
- packPath = joinPath(documentFolderUri, 'node_modules', _moduleName, 'package.json');
383
- return [4 /*yield*/, this.fileExists(packPath)];
384
- case 1:
385
- if (_a.sent()) {
386
- return [2 /*return*/, dirname(packPath)];
387
- }
388
- else if (rootFolderUri && documentFolderUri.startsWith(rootFolderUri) && (documentFolderUri.length !== rootFolderUri.length)) {
389
- return [2 /*return*/, this.resolvePathToModule(_moduleName, dirname(documentFolderUri), rootFolderUri)];
390
- }
391
- return [2 /*return*/, undefined];
392
- }
393
- });
394
- });
395
- };
396
- CSSNavigation.prototype.fileExists = function (uri) {
397
- return __awaiter(this, void 0, void 0, function () {
398
- var stat, err_1;
399
- return __generator(this, function (_a) {
400
- switch (_a.label) {
401
- case 0:
402
- if (!this.fileSystemProvider) {
403
- return [2 /*return*/, false];
404
- }
405
- _a.label = 1;
406
- case 1:
407
- _a.trys.push([1, 3, , 4]);
408
- return [4 /*yield*/, this.fileSystemProvider.stat(uri)];
409
- case 2:
410
- stat = _a.sent();
411
- if (stat.type === FileType.Unknown && stat.size === -1) {
412
- return [2 /*return*/, false];
413
- }
414
- return [2 /*return*/, true];
415
- case 3:
416
- err_1 = _a.sent();
417
- return [2 /*return*/, false];
418
- case 4: return [2 /*return*/];
419
- }
420
- });
421
- });
422
- };
423
- return CSSNavigation;
424
- }());
425
- export { CSSNavigation };
303
+ }
304
+ async resolveModuleReference(ref, documentUri, documentContext) {
305
+ if (startsWith(documentUri, 'file://')) {
306
+ const moduleName = getModuleNameFromPath(ref);
307
+ const rootFolderUri = documentContext.resolveReference('/', documentUri);
308
+ const documentFolderUri = dirname(documentUri);
309
+ const modulePath = await this.resolvePathToModule(moduleName, documentFolderUri, rootFolderUri);
310
+ if (modulePath) {
311
+ const pathWithinModule = ref.substring(moduleName.length + 1);
312
+ return joinPath(modulePath, pathWithinModule);
313
+ }
314
+ }
315
+ return undefined;
316
+ }
317
+ async resolveRelativeReference(ref, documentUri, documentContext, isRawLink) {
318
+ const relativeReference = documentContext.resolveReference(ref, documentUri);
319
+ // Following [css-loader](https://github.com/webpack-contrib/css-loader#url)
320
+ // and [sass-loader's](https://github.com/webpack-contrib/sass-loader#imports)
321
+ // convention, if an import path starts with ~ then use node module resolution
322
+ // *unless* it starts with "~/" as this refers to the user's home directory.
323
+ if (ref[0] === '~' && ref[1] !== '/' && this.fileSystemProvider) {
324
+ ref = ref.substring(1);
325
+ return await this.resolveModuleReference(ref, documentUri, documentContext) || relativeReference;
326
+ }
327
+ // Following [less-loader](https://github.com/webpack-contrib/less-loader#imports)
328
+ // and [sass-loader's](https://github.com/webpack-contrib/sass-loader#resolving-import-at-rules)
329
+ // new resolving import at-rules (~ is deprecated). The loader will first try to resolve @import as a relative path. If it cannot be resolved,
330
+ // then the loader will try to resolve @import inside node_modules.
331
+ if (this.resolveModuleReferences) {
332
+ if (relativeReference && await this.fileExists(relativeReference)) {
333
+ return relativeReference;
334
+ }
335
+ else {
336
+ return await this.resolveModuleReference(ref, documentUri, documentContext) || relativeReference;
337
+ }
338
+ }
339
+ return relativeReference;
340
+ }
341
+ async resolvePathToModule(_moduleName, documentFolderUri, rootFolderUri) {
342
+ // resolve the module relative to the document. We can't use `require` here as the code is webpacked.
343
+ const packPath = joinPath(documentFolderUri, 'node_modules', _moduleName, 'package.json');
344
+ if (await this.fileExists(packPath)) {
345
+ return dirname(packPath);
346
+ }
347
+ else if (rootFolderUri && documentFolderUri.startsWith(rootFolderUri) && (documentFolderUri.length !== rootFolderUri.length)) {
348
+ return this.resolvePathToModule(_moduleName, dirname(documentFolderUri), rootFolderUri);
349
+ }
350
+ return undefined;
351
+ }
352
+ async fileExists(uri) {
353
+ if (!this.fileSystemProvider) {
354
+ return false;
355
+ }
356
+ try {
357
+ const stat = await this.fileSystemProvider.stat(uri);
358
+ if (stat.type === FileType.Unknown && stat.size === -1) {
359
+ return false;
360
+ }
361
+ return true;
362
+ }
363
+ catch (err) {
364
+ return false;
365
+ }
366
+ }
367
+ }
426
368
  function getColorInformation(node, document) {
427
- var color = getColorValue(node);
369
+ const color = getColorValue(node);
428
370
  if (color) {
429
- var range = getRange(node, document);
430
- return { color: color, range: range };
371
+ const range = getRange(node, document);
372
+ return { color, range };
431
373
  }
432
374
  return null;
433
375
  }
434
376
  function getRange(node, document) {
435
377
  return Range.create(document.positionAt(node.offset), document.positionAt(node.end));
436
378
  }
379
+ /**
380
+ * Test if `otherRange` is in `range`. If the ranges are equal, will return true.
381
+ */
382
+ function containsRange(range, otherRange) {
383
+ const otherStartLine = otherRange.start.line, otherEndLine = otherRange.end.line;
384
+ const rangeStartLine = range.start.line, rangeEndLine = range.end.line;
385
+ if (otherStartLine < rangeStartLine || otherEndLine < rangeStartLine) {
386
+ return false;
387
+ }
388
+ if (otherStartLine > rangeEndLine || otherEndLine > rangeEndLine) {
389
+ return false;
390
+ }
391
+ if (otherStartLine === rangeStartLine && otherRange.start.character < range.start.character) {
392
+ return false;
393
+ }
394
+ if (otherEndLine === rangeEndLine && otherRange.end.character > range.end.character) {
395
+ return false;
396
+ }
397
+ return true;
398
+ }
437
399
  function getHighlightKind(node) {
438
400
  if (node.type === nodes.NodeType.Selector) {
439
401
  return DocumentHighlightKind.Write;
@@ -458,13 +420,22 @@ function getHighlightKind(node) {
458
420
  return DocumentHighlightKind.Read;
459
421
  }
460
422
  function toTwoDigitHex(n) {
461
- var r = n.toString(16);
423
+ const r = n.toString(16);
462
424
  return r.length !== 2 ? '0' + r : r;
463
425
  }
464
426
  function getModuleNameFromPath(path) {
465
- // If a scoped module (starts with @) then get up until second instance of '/', otherwise get until first instance of '/'
427
+ const firstSlash = path.indexOf('/');
428
+ if (firstSlash === -1) {
429
+ return '';
430
+ }
431
+ // If a scoped module (starts with @) then get up until second instance of '/', or to the end of the string for root-level imports.
466
432
  if (path[0] === '@') {
467
- return path.substring(0, path.indexOf('/', path.indexOf('/') + 1));
433
+ const secondSlash = path.indexOf('/', firstSlash + 1);
434
+ if (secondSlash === -1) {
435
+ return path;
436
+ }
437
+ return path.substring(0, secondSlash);
468
438
  }
469
- return path.substring(0, path.indexOf('/'));
439
+ // Otherwise get until first instance of '/'
440
+ return path.substring(0, firstSlash);
470
441
  }