vscode-css-languageservice 5.3.0 → 6.0.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 (87) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +1 -0
  3. package/lib/esm/beautify/beautify-css.js +57 -15
  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 -228
  7. package/lib/esm/cssLanguageTypes.js +42 -42
  8. package/lib/esm/data/webCustomData.js +21965 -21959
  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 -117
  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 +57 -15
  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 -228
  49. package/lib/umd/cssLanguageTypes.js +89 -88
  50. package/lib/umd/data/webCustomData.js +21978 -21972
  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 -131
  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,470 +1,378 @@
1
- /*---------------------------------------------------------------------------------------------
2
- * Copyright (c) Microsoft Corporation. All rights reserved.
3
- * Licensed under the MIT License. See License.txt in the project root for license information.
4
- *--------------------------------------------------------------------------------------------*/
5
- '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
- import { DocumentHighlightKind, Location, Range, SymbolKind, TextEdit, FileType } from '../cssLanguageTypes';
43
- import * as nls from 'vscode-nls';
44
- import * as nodes from '../parser/cssNodes';
45
- import { Symbols } from '../parser/cssSymbolScope';
46
- import { getColorValue, hslFromColor, hwbFromColor } from '../languageFacts/facts';
47
- import { startsWith } from '../utils/strings';
48
- 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) {
54
- this.fileSystemProvider = fileSystemProvider;
55
- this.resolveModuleReferences = resolveModuleReferences;
56
- }
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);
61
- if (!node) {
62
- return null;
63
- }
64
- var symbol = symbols.findSymbolFromNode(node);
65
- if (!symbol) {
66
- return null;
67
- }
68
- return {
69
- uri: document.uri,
70
- range: getRange(symbol.node, document)
71
- };
72
- };
73
- CSSNavigation.prototype.findReferences = function (document, position, stylesheet) {
74
- var highlights = this.findDocumentHighlights(document, position, stylesheet);
75
- return highlights.map(function (h) {
76
- return {
77
- uri: document.uri,
78
- range: h.range
79
- };
80
- });
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);
86
- if (!node || node.type === nodes.NodeType.Stylesheet || node.type === nodes.NodeType.Declarations) {
87
- return result;
88
- }
89
- if (node.type === nodes.NodeType.Identifier && node.parent && node.parent.type === nodes.NodeType.ClassSelector) {
90
- node = node.parent;
91
- }
92
- var symbols = new Symbols(stylesheet);
93
- var symbol = symbols.findSymbolFromNode(node);
94
- var name = node.getText();
95
- stylesheet.accept(function (candidate) {
96
- if (symbol) {
97
- if (symbols.matchesSymbol(candidate, symbol)) {
98
- result.push({
99
- kind: getHighlightKind(candidate),
100
- range: getRange(candidate, document)
101
- });
102
- return false;
103
- }
104
- }
105
- else if (node && node.type === candidate.type && candidate.matches(name)) {
106
- // Same node type and data
107
- result.push({
108
- kind: getHighlightKind(candidate),
109
- range: getRange(candidate, document)
110
- });
111
- }
112
- return true;
113
- });
114
- return result;
115
- };
116
- CSSNavigation.prototype.isRawStringDocumentLinkNode = function (node) {
117
- 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;
126
- if (!target || startsWithData.test(target)) {
127
- // no links for data:
128
- }
129
- else if (startsWithSchemeRegex.test(target)) {
130
- resolvedLinks.push(link);
131
- }
132
- else {
133
- var resolved = documentContext.resolveReference(target, document.uri);
134
- if (resolved) {
135
- link.target = resolved;
136
- }
137
- resolvedLinks.push(link);
138
- }
139
- }
140
- 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];
175
- }
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);
185
- // Make sure the range is not empty
186
- if (range.start.line === range.end.line && range.start.character === range.end.character) {
187
- return;
188
- }
189
- if (startsWith(rawUri, "'") || startsWith(rawUri, "\"")) {
190
- rawUri = rawUri.slice(1, -1);
191
- }
192
- var isRawLink = uriStringNode.parent ? _this.isRawStringDocumentLinkNode(uriStringNode.parent) : false;
193
- result.push({ link: { target: rawUri, range: range }, isRawLink: isRawLink });
194
- };
195
- stylesheet.accept(function (candidate) {
196
- if (candidate.type === nodes.NodeType.URILiteral) {
197
- var first = candidate.getChild(0);
198
- if (first) {
199
- collect(first);
200
- }
201
- return false;
202
- }
203
- /**
204
- * In @import, it is possible to include links that do not use `url()`
205
- * For example, `@import 'foo.css';`
206
- */
207
- if (candidate.parent && _this.isRawStringDocumentLinkNode(candidate.parent)) {
208
- var rawText = candidate.getText();
209
- if (startsWith(rawText, "'") || startsWith(rawText, "\"")) {
210
- collect(candidate);
211
- }
212
- return false;
213
- }
214
- return true;
215
- });
216
- 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
225
- };
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);
233
- }
234
- return false;
235
- }
236
- else if (node instanceof nodes.VariableDeclaration) {
237
- entry.name = node.getName();
238
- entry.kind = SymbolKind.Variable;
239
- }
240
- else if (node instanceof nodes.MixinDeclaration) {
241
- entry.name = node.getName();
242
- entry.kind = SymbolKind.Method;
243
- }
244
- else if (node instanceof nodes.FunctionDeclaration) {
245
- entry.name = node.getName();
246
- entry.kind = SymbolKind.Function;
247
- }
248
- else if (node instanceof nodes.Keyframe) {
249
- entry.name = localize('literal.keyframes', "@keyframes {0}", node.getName());
250
- }
251
- else if (node instanceof nodes.FontFace) {
252
- entry.name = localize('literal.fontface', "@font-face");
253
- }
254
- else if (node instanceof nodes.Media) {
255
- var mediaList = node.getChild(0);
256
- if (mediaList instanceof nodes.Medialist) {
257
- entry.name = '@media ' + mediaList.getText();
258
- entry.kind = SymbolKind.Module;
259
- }
260
- }
261
- if (entry.name) {
262
- entry.location = Location.create(document.uri, getRange(locationNode, document));
263
- result.push(entry);
264
- }
265
- return true;
266
- });
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);
273
- if (colorInfo) {
274
- result.push(colorInfo);
275
- }
276
- return true;
277
- });
278
- 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;
284
- if (color.alpha === 1) {
285
- label = "rgb(".concat(red256, ", ").concat(green256, ", ").concat(blue256, ")");
286
- }
287
- else {
288
- label = "rgba(".concat(red256, ", ").concat(green256, ", ").concat(blue256, ", ").concat(color.alpha, ")");
289
- }
290
- result.push({ label: label, textEdit: TextEdit.replace(range, label) });
291
- if (color.alpha === 1) {
292
- label = "#".concat(toTwoDigitHex(red256)).concat(toTwoDigitHex(green256)).concat(toTwoDigitHex(blue256));
293
- }
294
- else {
295
- label = "#".concat(toTwoDigitHex(red256)).concat(toTwoDigitHex(green256)).concat(toTwoDigitHex(blue256)).concat(toTwoDigitHex(Math.round(color.alpha * 255)));
296
- }
297
- result.push({ label: label, textEdit: TextEdit.replace(range, label) });
298
- var hsl = hslFromColor(color);
299
- if (hsl.a === 1) {
300
- label = "hsl(".concat(hsl.h, ", ").concat(Math.round(hsl.s * 100), "%, ").concat(Math.round(hsl.l * 100), "%)");
301
- }
302
- else {
303
- label = "hsla(".concat(hsl.h, ", ").concat(Math.round(hsl.s * 100), "%, ").concat(Math.round(hsl.l * 100), "%, ").concat(hsl.a, ")");
304
- }
305
- result.push({ label: label, textEdit: TextEdit.replace(range, label) });
306
- var hwb = hwbFromColor(color);
307
- if (hwb.a === 1) {
308
- label = "hwb(".concat(hwb.h, " ").concat(Math.round(hwb.w * 100), "% ").concat(Math.round(hwb.b * 100), "%)");
309
- }
310
- else {
311
- label = "hwb(".concat(hwb.h, " ").concat(Math.round(hwb.w * 100), "% ").concat(Math.round(hwb.b * 100), "% / ").concat(hwb.a, ")");
312
- }
313
- result.push({ label: label, textEdit: TextEdit.replace(range, label) });
314
- 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); });
320
- return {
321
- changes: (_a = {}, _a[document.uri] = edits, _a)
322
- };
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 };
426
- function getColorInformation(node, document) {
427
- var color = getColorValue(node);
428
- if (color) {
429
- var range = getRange(node, document);
430
- return { color: color, range: range };
431
- }
432
- return null;
433
- }
434
- function getRange(node, document) {
435
- return Range.create(document.positionAt(node.offset), document.positionAt(node.end));
436
- }
437
- function getHighlightKind(node) {
438
- if (node.type === nodes.NodeType.Selector) {
439
- return DocumentHighlightKind.Write;
440
- }
441
- if (node instanceof nodes.Identifier) {
442
- if (node.parent && node.parent instanceof nodes.Property) {
443
- if (node.isCustomProperty) {
444
- return DocumentHighlightKind.Write;
445
- }
446
- }
447
- }
448
- if (node.parent) {
449
- switch (node.parent.type) {
450
- case nodes.NodeType.FunctionDeclaration:
451
- case nodes.NodeType.MixinDeclaration:
452
- case nodes.NodeType.Keyframe:
453
- case nodes.NodeType.VariableDeclaration:
454
- case nodes.NodeType.FunctionParameter:
455
- return DocumentHighlightKind.Write;
456
- }
457
- }
458
- return DocumentHighlightKind.Read;
459
- }
460
- function toTwoDigitHex(n) {
461
- var r = n.toString(16);
462
- return r.length !== 2 ? '0' + r : r;
463
- }
464
- function getModuleNameFromPath(path) {
465
- // If a scoped module (starts with @) then get up until second instance of '/', otherwise get until first instance of '/'
466
- if (path[0] === '@') {
467
- return path.substring(0, path.indexOf('/', path.indexOf('/') + 1));
468
- }
469
- return path.substring(0, path.indexOf('/'));
470
- }
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ 'use strict';
6
+ import { DocumentHighlightKind, Location, Range, SymbolKind, TextEdit, FileType } from '../cssLanguageTypes';
7
+ import * as nls from 'vscode-nls';
8
+ import * as nodes from '../parser/cssNodes';
9
+ import { Symbols } from '../parser/cssSymbolScope';
10
+ import { getColorValue, hslFromColor, hwbFromColor } from '../languageFacts/facts';
11
+ import { startsWith } from '../utils/strings';
12
+ import { dirname, joinPath } from '../utils/resources';
13
+ const localize = nls.loadMessageBundle();
14
+ const startsWithSchemeRegex = /^\w+:\/\//;
15
+ const startsWithData = /^data:/;
16
+ export class CSSNavigation {
17
+ constructor(fileSystemProvider, resolveModuleReferences) {
18
+ this.fileSystemProvider = fileSystemProvider;
19
+ this.resolveModuleReferences = resolveModuleReferences;
20
+ }
21
+ findDefinition(document, position, stylesheet) {
22
+ const symbols = new Symbols(stylesheet);
23
+ const offset = document.offsetAt(position);
24
+ const node = nodes.getNodeAtOffset(stylesheet, offset);
25
+ if (!node) {
26
+ return null;
27
+ }
28
+ const symbol = symbols.findSymbolFromNode(node);
29
+ if (!symbol) {
30
+ return null;
31
+ }
32
+ return {
33
+ uri: document.uri,
34
+ range: getRange(symbol.node, document)
35
+ };
36
+ }
37
+ findReferences(document, position, stylesheet) {
38
+ const highlights = this.findDocumentHighlights(document, position, stylesheet);
39
+ return highlights.map(h => {
40
+ return {
41
+ uri: document.uri,
42
+ range: h.range
43
+ };
44
+ });
45
+ }
46
+ findDocumentHighlights(document, position, stylesheet) {
47
+ const result = [];
48
+ const offset = document.offsetAt(position);
49
+ let node = nodes.getNodeAtOffset(stylesheet, offset);
50
+ if (!node || node.type === nodes.NodeType.Stylesheet || node.type === nodes.NodeType.Declarations) {
51
+ return result;
52
+ }
53
+ if (node.type === nodes.NodeType.Identifier && node.parent && node.parent.type === nodes.NodeType.ClassSelector) {
54
+ node = node.parent;
55
+ }
56
+ const symbols = new Symbols(stylesheet);
57
+ const symbol = symbols.findSymbolFromNode(node);
58
+ const name = node.getText();
59
+ stylesheet.accept(candidate => {
60
+ if (symbol) {
61
+ if (symbols.matchesSymbol(candidate, symbol)) {
62
+ result.push({
63
+ kind: getHighlightKind(candidate),
64
+ range: getRange(candidate, document)
65
+ });
66
+ return false;
67
+ }
68
+ }
69
+ else if (node && node.type === candidate.type && candidate.matches(name)) {
70
+ // Same node type and data
71
+ result.push({
72
+ kind: getHighlightKind(candidate),
73
+ range: getRange(candidate, document)
74
+ });
75
+ }
76
+ return true;
77
+ });
78
+ return result;
79
+ }
80
+ isRawStringDocumentLinkNode(node) {
81
+ return node.type === nodes.NodeType.Import;
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;
89
+ if (!target || startsWithData.test(target)) {
90
+ // no links for data:
91
+ }
92
+ else if (startsWithSchemeRegex.test(target)) {
93
+ resolvedLinks.push(link);
94
+ }
95
+ else {
96
+ const resolved = documentContext.resolveReference(target, document.uri);
97
+ if (resolved) {
98
+ link.target = resolved;
99
+ }
100
+ resolvedLinks.push(link);
101
+ }
102
+ }
103
+ 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);
122
+ }
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);
132
+ // Make sure the range is not empty
133
+ if (range.start.line === range.end.line && range.start.character === range.end.character) {
134
+ return;
135
+ }
136
+ if (startsWith(rawUri, `'`) || startsWith(rawUri, `"`)) {
137
+ rawUri = rawUri.slice(1, -1);
138
+ }
139
+ const isRawLink = uriStringNode.parent ? this.isRawStringDocumentLinkNode(uriStringNode.parent) : false;
140
+ result.push({ link: { target: rawUri, range }, isRawLink });
141
+ };
142
+ stylesheet.accept(candidate => {
143
+ if (candidate.type === nodes.NodeType.URILiteral) {
144
+ const first = candidate.getChild(0);
145
+ if (first) {
146
+ collect(first);
147
+ }
148
+ return false;
149
+ }
150
+ /**
151
+ * In @import, it is possible to include links that do not use `url()`
152
+ * For example, `@import 'foo.css';`
153
+ */
154
+ if (candidate.parent && this.isRawStringDocumentLinkNode(candidate.parent)) {
155
+ const rawText = candidate.getText();
156
+ if (startsWith(rawText, `'`) || startsWith(rawText, `"`)) {
157
+ collect(candidate);
158
+ }
159
+ return false;
160
+ }
161
+ return true;
162
+ });
163
+ return result;
164
+ }
165
+ findDocumentSymbols(document, stylesheet) {
166
+ const result = [];
167
+ stylesheet.accept((node) => {
168
+ const entry = {
169
+ name: null,
170
+ kind: SymbolKind.Class,
171
+ location: null
172
+ };
173
+ let locationNode = node;
174
+ if (node instanceof nodes.Selector) {
175
+ entry.name = node.getText();
176
+ locationNode = node.findAParent(nodes.NodeType.Ruleset, nodes.NodeType.ExtendsReference);
177
+ if (locationNode) {
178
+ entry.location = Location.create(document.uri, getRange(locationNode, document));
179
+ result.push(entry);
180
+ }
181
+ return false;
182
+ }
183
+ else if (node instanceof nodes.VariableDeclaration) {
184
+ entry.name = node.getName();
185
+ entry.kind = SymbolKind.Variable;
186
+ }
187
+ else if (node instanceof nodes.MixinDeclaration) {
188
+ entry.name = node.getName();
189
+ entry.kind = SymbolKind.Method;
190
+ }
191
+ else if (node instanceof nodes.FunctionDeclaration) {
192
+ entry.name = node.getName();
193
+ entry.kind = SymbolKind.Function;
194
+ }
195
+ else if (node instanceof nodes.Keyframe) {
196
+ entry.name = localize('literal.keyframes', "@keyframes {0}", node.getName());
197
+ }
198
+ else if (node instanceof nodes.FontFace) {
199
+ entry.name = localize('literal.fontface', "@font-face");
200
+ }
201
+ else if (node instanceof nodes.Media) {
202
+ const mediaList = node.getChild(0);
203
+ if (mediaList instanceof nodes.Medialist) {
204
+ entry.name = '@media ' + mediaList.getText();
205
+ entry.kind = SymbolKind.Module;
206
+ }
207
+ }
208
+ if (entry.name) {
209
+ entry.location = Location.create(document.uri, getRange(locationNode, document));
210
+ result.push(entry);
211
+ }
212
+ return true;
213
+ });
214
+ return result;
215
+ }
216
+ findDocumentColors(document, stylesheet) {
217
+ const result = [];
218
+ stylesheet.accept((node) => {
219
+ const colorInfo = getColorInformation(node, document);
220
+ if (colorInfo) {
221
+ result.push(colorInfo);
222
+ }
223
+ return true;
224
+ });
225
+ return result;
226
+ }
227
+ getColorPresentations(document, stylesheet, color, range) {
228
+ const result = [];
229
+ const red256 = Math.round(color.red * 255), green256 = Math.round(color.green * 255), blue256 = Math.round(color.blue * 255);
230
+ let label;
231
+ if (color.alpha === 1) {
232
+ label = `rgb(${red256}, ${green256}, ${blue256})`;
233
+ }
234
+ else {
235
+ label = `rgba(${red256}, ${green256}, ${blue256}, ${color.alpha})`;
236
+ }
237
+ result.push({ label: label, textEdit: TextEdit.replace(range, label) });
238
+ if (color.alpha === 1) {
239
+ label = `#${toTwoDigitHex(red256)}${toTwoDigitHex(green256)}${toTwoDigitHex(blue256)}`;
240
+ }
241
+ else {
242
+ label = `#${toTwoDigitHex(red256)}${toTwoDigitHex(green256)}${toTwoDigitHex(blue256)}${toTwoDigitHex(Math.round(color.alpha * 255))}`;
243
+ }
244
+ result.push({ label: label, textEdit: TextEdit.replace(range, label) });
245
+ const hsl = hslFromColor(color);
246
+ if (hsl.a === 1) {
247
+ label = `hsl(${hsl.h}, ${Math.round(hsl.s * 100)}%, ${Math.round(hsl.l * 100)}%)`;
248
+ }
249
+ else {
250
+ label = `hsla(${hsl.h}, ${Math.round(hsl.s * 100)}%, ${Math.round(hsl.l * 100)}%, ${hsl.a})`;
251
+ }
252
+ result.push({ label: label, textEdit: TextEdit.replace(range, label) });
253
+ const hwb = hwbFromColor(color);
254
+ if (hwb.a === 1) {
255
+ label = `hwb(${hwb.h} ${Math.round(hwb.w * 100)}% ${Math.round(hwb.b * 100)}%)`;
256
+ }
257
+ else {
258
+ label = `hwb(${hwb.h} ${Math.round(hwb.w * 100)}% ${Math.round(hwb.b * 100)}% / ${hwb.a})`;
259
+ }
260
+ result.push({ label: label, textEdit: TextEdit.replace(range, label) });
261
+ return result;
262
+ }
263
+ doRename(document, position, newName, stylesheet) {
264
+ const highlights = this.findDocumentHighlights(document, position, stylesheet);
265
+ const edits = highlights.map(h => TextEdit.replace(h.range, newName));
266
+ return {
267
+ changes: { [document.uri]: edits }
268
+ };
269
+ }
270
+ async resolveModuleReference(ref, documentUri, documentContext) {
271
+ if (startsWith(documentUri, 'file://')) {
272
+ const moduleName = getModuleNameFromPath(ref);
273
+ const rootFolderUri = documentContext.resolveReference('/', documentUri);
274
+ const documentFolderUri = dirname(documentUri);
275
+ const modulePath = await this.resolvePathToModule(moduleName, documentFolderUri, rootFolderUri);
276
+ if (modulePath) {
277
+ const pathWithinModule = ref.substring(moduleName.length + 1);
278
+ return joinPath(modulePath, pathWithinModule);
279
+ }
280
+ }
281
+ return undefined;
282
+ }
283
+ async resolveRelativeReference(ref, documentUri, documentContext, isRawLink) {
284
+ const relativeReference = documentContext.resolveReference(ref, documentUri);
285
+ // Following [css-loader](https://github.com/webpack-contrib/css-loader#url)
286
+ // and [sass-loader's](https://github.com/webpack-contrib/sass-loader#imports)
287
+ // convention, if an import path starts with ~ then use node module resolution
288
+ // *unless* it starts with "~/" as this refers to the user's home directory.
289
+ if (ref[0] === '~' && ref[1] !== '/' && this.fileSystemProvider) {
290
+ ref = ref.substring(1);
291
+ return await this.resolveModuleReference(ref, documentUri, documentContext) || relativeReference;
292
+ }
293
+ // Following [less-loader](https://github.com/webpack-contrib/less-loader#imports)
294
+ // and [sass-loader's](https://github.com/webpack-contrib/sass-loader#resolving-import-at-rules)
295
+ // new resolving import at-rules (~ is deprecated). The loader will first try to resolve @import as a relative path. If it cannot be resolved,
296
+ // then the loader will try to resolve @import inside node_modules.
297
+ if (this.resolveModuleReferences) {
298
+ if (relativeReference && await this.fileExists(relativeReference)) {
299
+ return relativeReference;
300
+ }
301
+ else {
302
+ return await this.resolveModuleReference(ref, documentUri, documentContext) || relativeReference;
303
+ }
304
+ }
305
+ return relativeReference;
306
+ }
307
+ async resolvePathToModule(_moduleName, documentFolderUri, rootFolderUri) {
308
+ // resolve the module relative to the document. We can't use `require` here as the code is webpacked.
309
+ const packPath = joinPath(documentFolderUri, 'node_modules', _moduleName, 'package.json');
310
+ if (await this.fileExists(packPath)) {
311
+ return dirname(packPath);
312
+ }
313
+ else if (rootFolderUri && documentFolderUri.startsWith(rootFolderUri) && (documentFolderUri.length !== rootFolderUri.length)) {
314
+ return this.resolvePathToModule(_moduleName, dirname(documentFolderUri), rootFolderUri);
315
+ }
316
+ return undefined;
317
+ }
318
+ async fileExists(uri) {
319
+ if (!this.fileSystemProvider) {
320
+ return false;
321
+ }
322
+ try {
323
+ const stat = await this.fileSystemProvider.stat(uri);
324
+ if (stat.type === FileType.Unknown && stat.size === -1) {
325
+ return false;
326
+ }
327
+ return true;
328
+ }
329
+ catch (err) {
330
+ return false;
331
+ }
332
+ }
333
+ }
334
+ function getColorInformation(node, document) {
335
+ const color = getColorValue(node);
336
+ if (color) {
337
+ const range = getRange(node, document);
338
+ return { color, range };
339
+ }
340
+ return null;
341
+ }
342
+ function getRange(node, document) {
343
+ return Range.create(document.positionAt(node.offset), document.positionAt(node.end));
344
+ }
345
+ function getHighlightKind(node) {
346
+ if (node.type === nodes.NodeType.Selector) {
347
+ return DocumentHighlightKind.Write;
348
+ }
349
+ if (node instanceof nodes.Identifier) {
350
+ if (node.parent && node.parent instanceof nodes.Property) {
351
+ if (node.isCustomProperty) {
352
+ return DocumentHighlightKind.Write;
353
+ }
354
+ }
355
+ }
356
+ if (node.parent) {
357
+ switch (node.parent.type) {
358
+ case nodes.NodeType.FunctionDeclaration:
359
+ case nodes.NodeType.MixinDeclaration:
360
+ case nodes.NodeType.Keyframe:
361
+ case nodes.NodeType.VariableDeclaration:
362
+ case nodes.NodeType.FunctionParameter:
363
+ return DocumentHighlightKind.Write;
364
+ }
365
+ }
366
+ return DocumentHighlightKind.Read;
367
+ }
368
+ function toTwoDigitHex(n) {
369
+ const r = n.toString(16);
370
+ return r.length !== 2 ? '0' + r : r;
371
+ }
372
+ function getModuleNameFromPath(path) {
373
+ // If a scoped module (starts with @) then get up until second instance of '/', otherwise get until first instance of '/'
374
+ if (path[0] === '@') {
375
+ return path.substring(0, path.indexOf('/', path.indexOf('/') + 1));
376
+ }
377
+ return path.substring(0, path.indexOf('/'));
378
+ }