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