vscode-css-languageservice 5.4.2 → 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 (84) hide show
  1. package/CHANGELOG.md +5 -1
  2. package/lib/esm/cssLanguageService.d.ts +37 -37
  3. package/lib/esm/cssLanguageService.js +72 -75
  4. package/lib/esm/cssLanguageTypes.d.ts +238 -238
  5. package/lib/esm/cssLanguageTypes.js +42 -42
  6. package/lib/esm/data/webCustomData.js +21965 -21965
  7. package/lib/esm/languageFacts/builtinData.js +142 -142
  8. package/lib/esm/languageFacts/colors.js +469 -472
  9. package/lib/esm/languageFacts/dataManager.js +88 -92
  10. package/lib/esm/languageFacts/dataProvider.js +73 -79
  11. package/lib/esm/languageFacts/entry.js +137 -138
  12. package/lib/esm/languageFacts/facts.js +8 -8
  13. package/lib/esm/parser/cssErrors.js +48 -50
  14. package/lib/esm/parser/cssNodes.js +1502 -2019
  15. package/lib/esm/parser/cssParser.js +1534 -1563
  16. package/lib/esm/parser/cssScanner.js +592 -599
  17. package/lib/esm/parser/cssSymbolScope.js +311 -341
  18. package/lib/esm/parser/lessParser.js +714 -740
  19. package/lib/esm/parser/lessScanner.js +57 -78
  20. package/lib/esm/parser/scssErrors.js +18 -20
  21. package/lib/esm/parser/scssParser.js +796 -818
  22. package/lib/esm/parser/scssScanner.js +95 -116
  23. package/lib/esm/services/cssCodeActions.js +77 -81
  24. package/lib/esm/services/cssCompletion.js +1054 -1149
  25. package/lib/esm/services/cssFolding.js +190 -193
  26. package/lib/esm/services/cssFormatter.js +136 -136
  27. package/lib/esm/services/cssHover.js +148 -151
  28. package/lib/esm/services/cssNavigation.js +378 -470
  29. package/lib/esm/services/cssSelectionRange.js +47 -47
  30. package/lib/esm/services/cssValidation.js +41 -44
  31. package/lib/esm/services/lessCompletion.js +378 -397
  32. package/lib/esm/services/lint.js +518 -532
  33. package/lib/esm/services/lintRules.js +76 -83
  34. package/lib/esm/services/lintUtil.js +196 -205
  35. package/lib/esm/services/pathCompletion.js +157 -231
  36. package/lib/esm/services/scssCompletion.js +354 -378
  37. package/lib/esm/services/scssNavigation.js +82 -154
  38. package/lib/esm/services/selectorPrinting.js +492 -536
  39. package/lib/esm/utils/arrays.js +40 -46
  40. package/lib/esm/utils/objects.js +11 -11
  41. package/lib/esm/utils/resources.js +11 -24
  42. package/lib/esm/utils/strings.js +102 -104
  43. package/lib/umd/cssLanguageService.d.ts +37 -37
  44. package/lib/umd/cssLanguageService.js +99 -102
  45. package/lib/umd/cssLanguageTypes.d.ts +238 -238
  46. package/lib/umd/cssLanguageTypes.js +89 -88
  47. package/lib/umd/data/webCustomData.js +21978 -21978
  48. package/lib/umd/languageFacts/builtinData.js +154 -154
  49. package/lib/umd/languageFacts/colors.js +492 -495
  50. package/lib/umd/languageFacts/dataManager.js +101 -104
  51. package/lib/umd/languageFacts/dataProvider.js +86 -91
  52. package/lib/umd/languageFacts/entry.js +152 -153
  53. package/lib/umd/languageFacts/facts.js +29 -29
  54. package/lib/umd/parser/cssErrors.js +61 -62
  55. package/lib/umd/parser/cssNodes.js +1587 -2034
  56. package/lib/umd/parser/cssParser.js +1547 -1575
  57. package/lib/umd/parser/cssScanner.js +606 -611
  58. package/lib/umd/parser/cssSymbolScope.js +328 -353
  59. package/lib/umd/parser/lessParser.js +727 -752
  60. package/lib/umd/parser/lessScanner.js +70 -90
  61. package/lib/umd/parser/scssErrors.js +31 -32
  62. package/lib/umd/parser/scssParser.js +809 -830
  63. package/lib/umd/parser/scssScanner.js +108 -128
  64. package/lib/umd/services/cssCodeActions.js +90 -93
  65. package/lib/umd/services/cssCompletion.js +1067 -1161
  66. package/lib/umd/services/cssFolding.js +203 -206
  67. package/lib/umd/services/cssFormatter.js +150 -150
  68. package/lib/umd/services/cssHover.js +161 -163
  69. package/lib/umd/services/cssNavigation.js +391 -482
  70. package/lib/umd/services/cssSelectionRange.js +60 -60
  71. package/lib/umd/services/cssValidation.js +54 -56
  72. package/lib/umd/services/lessCompletion.js +391 -409
  73. package/lib/umd/services/lint.js +531 -544
  74. package/lib/umd/services/lintRules.js +91 -95
  75. package/lib/umd/services/lintUtil.js +210 -218
  76. package/lib/umd/services/pathCompletion.js +171 -244
  77. package/lib/umd/services/scssCompletion.js +367 -390
  78. package/lib/umd/services/scssNavigation.js +95 -166
  79. package/lib/umd/services/selectorPrinting.js +510 -550
  80. package/lib/umd/utils/arrays.js +55 -61
  81. package/lib/umd/utils/objects.js +25 -25
  82. package/lib/umd/utils/resources.js +26 -39
  83. package/lib/umd/utils/strings.js +120 -122
  84. package/package.json +10 -10
@@ -1,1161 +1,1067 @@
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
- (function (factory) {
38
- if (typeof module === "object" && typeof module.exports === "object") {
39
- var v = factory(require, exports);
40
- if (v !== undefined) module.exports = v;
41
- }
42
- else if (typeof define === "function" && define.amd) {
43
- define(["require", "exports", "../parser/cssNodes", "../parser/cssSymbolScope", "../languageFacts/facts", "../utils/strings", "../cssLanguageTypes", "vscode-nls", "../utils/objects", "./pathCompletion"], factory);
44
- }
45
- })(function (require, exports) {
46
- /*---------------------------------------------------------------------------------------------
47
- * Copyright (c) Microsoft Corporation. All rights reserved.
48
- * Licensed under the MIT License. See License.txt in the project root for license information.
49
- *--------------------------------------------------------------------------------------------*/
50
- 'use strict';
51
- Object.defineProperty(exports, "__esModule", { value: true });
52
- exports.CSSCompletion = void 0;
53
- var nodes = require("../parser/cssNodes");
54
- var cssSymbolScope_1 = require("../parser/cssSymbolScope");
55
- var languageFacts = require("../languageFacts/facts");
56
- var strings = require("../utils/strings");
57
- var cssLanguageTypes_1 = require("../cssLanguageTypes");
58
- var nls = require("vscode-nls");
59
- var objects_1 = require("../utils/objects");
60
- var pathCompletion_1 = require("./pathCompletion");
61
- var localize = nls.loadMessageBundle();
62
- var SnippetFormat = cssLanguageTypes_1.InsertTextFormat.Snippet;
63
- var retriggerCommand = {
64
- title: 'Suggest',
65
- command: 'editor.action.triggerSuggest'
66
- };
67
- var SortTexts;
68
- (function (SortTexts) {
69
- // char code 32, comes before everything
70
- SortTexts["Enums"] = " ";
71
- SortTexts["Normal"] = "d";
72
- SortTexts["VendorPrefixed"] = "x";
73
- SortTexts["Term"] = "y";
74
- SortTexts["Variable"] = "z";
75
- })(SortTexts || (SortTexts = {}));
76
- var CSSCompletion = /** @class */ (function () {
77
- function CSSCompletion(variablePrefix, lsOptions, cssDataManager) {
78
- if (variablePrefix === void 0) { variablePrefix = null; }
79
- this.variablePrefix = variablePrefix;
80
- this.lsOptions = lsOptions;
81
- this.cssDataManager = cssDataManager;
82
- this.completionParticipants = [];
83
- }
84
- CSSCompletion.prototype.configure = function (settings) {
85
- this.defaultSettings = settings;
86
- };
87
- CSSCompletion.prototype.getSymbolContext = function () {
88
- if (!this.symbolContext) {
89
- this.symbolContext = new cssSymbolScope_1.Symbols(this.styleSheet);
90
- }
91
- return this.symbolContext;
92
- };
93
- CSSCompletion.prototype.setCompletionParticipants = function (registeredCompletionParticipants) {
94
- this.completionParticipants = registeredCompletionParticipants || [];
95
- };
96
- CSSCompletion.prototype.doComplete2 = function (document, position, styleSheet, documentContext, completionSettings) {
97
- if (completionSettings === void 0) { completionSettings = this.defaultSettings; }
98
- return __awaiter(this, void 0, void 0, function () {
99
- var participant, contributedParticipants, result, pathCompletionResult;
100
- return __generator(this, function (_a) {
101
- switch (_a.label) {
102
- case 0:
103
- if (!this.lsOptions.fileSystemProvider || !this.lsOptions.fileSystemProvider.readDirectory) {
104
- return [2 /*return*/, this.doComplete(document, position, styleSheet, completionSettings)];
105
- }
106
- participant = new pathCompletion_1.PathCompletionParticipant(this.lsOptions.fileSystemProvider.readDirectory);
107
- contributedParticipants = this.completionParticipants;
108
- this.completionParticipants = [participant].concat(contributedParticipants);
109
- result = this.doComplete(document, position, styleSheet, completionSettings);
110
- _a.label = 1;
111
- case 1:
112
- _a.trys.push([1, , 3, 4]);
113
- return [4 /*yield*/, participant.computeCompletions(document, documentContext)];
114
- case 2:
115
- pathCompletionResult = _a.sent();
116
- return [2 /*return*/, {
117
- isIncomplete: result.isIncomplete || pathCompletionResult.isIncomplete,
118
- items: pathCompletionResult.items.concat(result.items)
119
- }];
120
- case 3:
121
- this.completionParticipants = contributedParticipants;
122
- return [7 /*endfinally*/];
123
- case 4: return [2 /*return*/];
124
- }
125
- });
126
- });
127
- };
128
- CSSCompletion.prototype.doComplete = function (document, position, styleSheet, documentSettings) {
129
- this.offset = document.offsetAt(position);
130
- this.position = position;
131
- this.currentWord = getCurrentWord(document, this.offset);
132
- this.defaultReplaceRange = cssLanguageTypes_1.Range.create(cssLanguageTypes_1.Position.create(this.position.line, this.position.character - this.currentWord.length), this.position);
133
- this.textDocument = document;
134
- this.styleSheet = styleSheet;
135
- this.documentSettings = documentSettings;
136
- try {
137
- var result = { isIncomplete: false, items: [] };
138
- this.nodePath = nodes.getNodePath(this.styleSheet, this.offset);
139
- for (var i = this.nodePath.length - 1; i >= 0; i--) {
140
- var node = this.nodePath[i];
141
- if (node instanceof nodes.Property) {
142
- this.getCompletionsForDeclarationProperty(node.getParent(), result);
143
- }
144
- else if (node instanceof nodes.Expression) {
145
- if (node.parent instanceof nodes.Interpolation) {
146
- this.getVariableProposals(null, result);
147
- }
148
- else {
149
- this.getCompletionsForExpression(node, result);
150
- }
151
- }
152
- else if (node instanceof nodes.SimpleSelector) {
153
- var parentRef = node.findAParent(nodes.NodeType.ExtendsReference, nodes.NodeType.Ruleset);
154
- if (parentRef) {
155
- if (parentRef.type === nodes.NodeType.ExtendsReference) {
156
- this.getCompletionsForExtendsReference(parentRef, node, result);
157
- }
158
- else {
159
- var parentRuleSet = parentRef;
160
- this.getCompletionsForSelector(parentRuleSet, parentRuleSet && parentRuleSet.isNested(), result);
161
- }
162
- }
163
- }
164
- else if (node instanceof nodes.FunctionArgument) {
165
- this.getCompletionsForFunctionArgument(node, node.getParent(), result);
166
- }
167
- else if (node instanceof nodes.Declarations) {
168
- this.getCompletionsForDeclarations(node, result);
169
- }
170
- else if (node instanceof nodes.VariableDeclaration) {
171
- this.getCompletionsForVariableDeclaration(node, result);
172
- }
173
- else if (node instanceof nodes.RuleSet) {
174
- this.getCompletionsForRuleSet(node, result);
175
- }
176
- else if (node instanceof nodes.Interpolation) {
177
- this.getCompletionsForInterpolation(node, result);
178
- }
179
- else if (node instanceof nodes.FunctionDeclaration) {
180
- this.getCompletionsForFunctionDeclaration(node, result);
181
- }
182
- else if (node instanceof nodes.MixinReference) {
183
- this.getCompletionsForMixinReference(node, result);
184
- }
185
- else if (node instanceof nodes.Function) {
186
- this.getCompletionsForFunctionArgument(null, node, result);
187
- }
188
- else if (node instanceof nodes.Supports) {
189
- this.getCompletionsForSupports(node, result);
190
- }
191
- else if (node instanceof nodes.SupportsCondition) {
192
- this.getCompletionsForSupportsCondition(node, result);
193
- }
194
- else if (node instanceof nodes.ExtendsReference) {
195
- this.getCompletionsForExtendsReference(node, null, result);
196
- }
197
- else if (node.type === nodes.NodeType.URILiteral) {
198
- this.getCompletionForUriLiteralValue(node, result);
199
- }
200
- else if (node.parent === null) {
201
- this.getCompletionForTopLevel(result);
202
- }
203
- else if (node.type === nodes.NodeType.StringLiteral && this.isImportPathParent(node.parent.type)) {
204
- this.getCompletionForImportPath(node, result);
205
- // } else if (node instanceof nodes.Variable) {
206
- // this.getCompletionsForVariableDeclaration()
207
- }
208
- else {
209
- continue;
210
- }
211
- if (result.items.length > 0 || this.offset > node.offset) {
212
- return this.finalize(result);
213
- }
214
- }
215
- this.getCompletionsForStylesheet(result);
216
- if (result.items.length === 0) {
217
- if (this.variablePrefix && this.currentWord.indexOf(this.variablePrefix) === 0) {
218
- this.getVariableProposals(null, result);
219
- }
220
- }
221
- return this.finalize(result);
222
- }
223
- finally {
224
- // don't hold on any state, clear symbolContext
225
- this.position = null;
226
- this.currentWord = null;
227
- this.textDocument = null;
228
- this.styleSheet = null;
229
- this.symbolContext = null;
230
- this.defaultReplaceRange = null;
231
- this.nodePath = null;
232
- }
233
- };
234
- CSSCompletion.prototype.isImportPathParent = function (type) {
235
- return type === nodes.NodeType.Import;
236
- };
237
- CSSCompletion.prototype.finalize = function (result) {
238
- return result;
239
- };
240
- CSSCompletion.prototype.findInNodePath = function () {
241
- var types = [];
242
- for (var _i = 0; _i < arguments.length; _i++) {
243
- types[_i] = arguments[_i];
244
- }
245
- for (var i = this.nodePath.length - 1; i >= 0; i--) {
246
- var node = this.nodePath[i];
247
- if (types.indexOf(node.type) !== -1) {
248
- return node;
249
- }
250
- }
251
- return null;
252
- };
253
- CSSCompletion.prototype.getCompletionsForDeclarationProperty = function (declaration, result) {
254
- return this.getPropertyProposals(declaration, result);
255
- };
256
- CSSCompletion.prototype.getPropertyProposals = function (declaration, result) {
257
- var _this = this;
258
- var triggerPropertyValueCompletion = this.isTriggerPropertyValueCompletionEnabled;
259
- var completePropertyWithSemicolon = this.isCompletePropertyWithSemicolonEnabled;
260
- var properties = this.cssDataManager.getProperties();
261
- properties.forEach(function (entry) {
262
- var range;
263
- var insertText;
264
- var retrigger = false;
265
- if (declaration) {
266
- range = _this.getCompletionRange(declaration.getProperty());
267
- insertText = entry.name;
268
- if (!(0, objects_1.isDefined)(declaration.colonPosition)) {
269
- insertText += ': ';
270
- retrigger = true;
271
- }
272
- }
273
- else {
274
- range = _this.getCompletionRange(null);
275
- insertText = entry.name + ': ';
276
- retrigger = true;
277
- }
278
- // Empty .selector { | } case
279
- if (!declaration && completePropertyWithSemicolon) {
280
- insertText += '$0;';
281
- }
282
- // Cases such as .selector { p; } or .selector { p:; }
283
- if (declaration && !declaration.semicolonPosition) {
284
- if (completePropertyWithSemicolon && _this.offset >= _this.textDocument.offsetAt(range.end)) {
285
- insertText += '$0;';
286
- }
287
- }
288
- var item = {
289
- label: entry.name,
290
- documentation: languageFacts.getEntryDescription(entry, _this.doesSupportMarkdown()),
291
- tags: isDeprecated(entry) ? [cssLanguageTypes_1.CompletionItemTag.Deprecated] : [],
292
- textEdit: cssLanguageTypes_1.TextEdit.replace(range, insertText),
293
- insertTextFormat: cssLanguageTypes_1.InsertTextFormat.Snippet,
294
- kind: cssLanguageTypes_1.CompletionItemKind.Property
295
- };
296
- if (!entry.restrictions) {
297
- retrigger = false;
298
- }
299
- if (triggerPropertyValueCompletion && retrigger) {
300
- item.command = retriggerCommand;
301
- }
302
- var relevance = typeof entry.relevance === 'number' ? Math.min(Math.max(entry.relevance, 0), 99) : 50;
303
- var sortTextSuffix = (255 - relevance).toString(16);
304
- var sortTextPrefix = strings.startsWith(entry.name, '-') ? SortTexts.VendorPrefixed : SortTexts.Normal;
305
- item.sortText = sortTextPrefix + '_' + sortTextSuffix;
306
- result.items.push(item);
307
- });
308
- this.completionParticipants.forEach(function (participant) {
309
- if (participant.onCssProperty) {
310
- participant.onCssProperty({
311
- propertyName: _this.currentWord,
312
- range: _this.defaultReplaceRange
313
- });
314
- }
315
- });
316
- return result;
317
- };
318
- Object.defineProperty(CSSCompletion.prototype, "isTriggerPropertyValueCompletionEnabled", {
319
- get: function () {
320
- var _a, _b;
321
- return (_b = (_a = this.documentSettings) === null || _a === void 0 ? void 0 : _a.triggerPropertyValueCompletion) !== null && _b !== void 0 ? _b : true;
322
- },
323
- enumerable: false,
324
- configurable: true
325
- });
326
- Object.defineProperty(CSSCompletion.prototype, "isCompletePropertyWithSemicolonEnabled", {
327
- get: function () {
328
- var _a, _b;
329
- return (_b = (_a = this.documentSettings) === null || _a === void 0 ? void 0 : _a.completePropertyWithSemicolon) !== null && _b !== void 0 ? _b : true;
330
- },
331
- enumerable: false,
332
- configurable: true
333
- });
334
- CSSCompletion.prototype.getCompletionsForDeclarationValue = function (node, result) {
335
- var _this = this;
336
- var propertyName = node.getFullPropertyName();
337
- var entry = this.cssDataManager.getProperty(propertyName);
338
- var existingNode = node.getValue() || null;
339
- while (existingNode && existingNode.hasChildren()) {
340
- existingNode = existingNode.findChildAtOffset(this.offset, false);
341
- }
342
- this.completionParticipants.forEach(function (participant) {
343
- if (participant.onCssPropertyValue) {
344
- participant.onCssPropertyValue({
345
- propertyName: propertyName,
346
- propertyValue: _this.currentWord,
347
- range: _this.getCompletionRange(existingNode)
348
- });
349
- }
350
- });
351
- if (entry) {
352
- if (entry.restrictions) {
353
- for (var _i = 0, _a = entry.restrictions; _i < _a.length; _i++) {
354
- var restriction = _a[_i];
355
- switch (restriction) {
356
- case 'color':
357
- this.getColorProposals(entry, existingNode, result);
358
- break;
359
- case 'position':
360
- this.getPositionProposals(entry, existingNode, result);
361
- break;
362
- case 'repeat':
363
- this.getRepeatStyleProposals(entry, existingNode, result);
364
- break;
365
- case 'line-style':
366
- this.getLineStyleProposals(entry, existingNode, result);
367
- break;
368
- case 'line-width':
369
- this.getLineWidthProposals(entry, existingNode, result);
370
- break;
371
- case 'geometry-box':
372
- this.getGeometryBoxProposals(entry, existingNode, result);
373
- break;
374
- case 'box':
375
- this.getBoxProposals(entry, existingNode, result);
376
- break;
377
- case 'image':
378
- this.getImageProposals(entry, existingNode, result);
379
- break;
380
- case 'timing-function':
381
- this.getTimingFunctionProposals(entry, existingNode, result);
382
- break;
383
- case 'shape':
384
- this.getBasicShapeProposals(entry, existingNode, result);
385
- break;
386
- }
387
- }
388
- }
389
- this.getValueEnumProposals(entry, existingNode, result);
390
- this.getCSSWideKeywordProposals(entry, existingNode, result);
391
- this.getUnitProposals(entry, existingNode, result);
392
- }
393
- else {
394
- var existingValues = collectValues(this.styleSheet, node);
395
- for (var _b = 0, _c = existingValues.getEntries(); _b < _c.length; _b++) {
396
- var existingValue = _c[_b];
397
- result.items.push({
398
- label: existingValue,
399
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), existingValue),
400
- kind: cssLanguageTypes_1.CompletionItemKind.Value
401
- });
402
- }
403
- }
404
- this.getVariableProposals(existingNode, result);
405
- this.getTermProposals(entry, existingNode, result);
406
- return result;
407
- };
408
- CSSCompletion.prototype.getValueEnumProposals = function (entry, existingNode, result) {
409
- if (entry.values) {
410
- for (var _i = 0, _a = entry.values; _i < _a.length; _i++) {
411
- var value = _a[_i];
412
- var insertString = value.name;
413
- var insertTextFormat = void 0;
414
- if (strings.endsWith(insertString, ')')) {
415
- var from = insertString.lastIndexOf('(');
416
- if (from !== -1) {
417
- insertString = insertString.substr(0, from) + '($1)';
418
- insertTextFormat = SnippetFormat;
419
- }
420
- }
421
- var sortText = SortTexts.Enums;
422
- if (strings.startsWith(value.name, '-')) {
423
- sortText += SortTexts.VendorPrefixed;
424
- }
425
- var item = {
426
- label: value.name,
427
- documentation: languageFacts.getEntryDescription(value, this.doesSupportMarkdown()),
428
- tags: isDeprecated(entry) ? [cssLanguageTypes_1.CompletionItemTag.Deprecated] : [],
429
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), insertString),
430
- sortText: sortText,
431
- kind: cssLanguageTypes_1.CompletionItemKind.Value,
432
- insertTextFormat: insertTextFormat
433
- };
434
- result.items.push(item);
435
- }
436
- }
437
- return result;
438
- };
439
- CSSCompletion.prototype.getCSSWideKeywordProposals = function (entry, existingNode, result) {
440
- for (var keywords in languageFacts.cssWideKeywords) {
441
- result.items.push({
442
- label: keywords,
443
- documentation: languageFacts.cssWideKeywords[keywords],
444
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), keywords),
445
- kind: cssLanguageTypes_1.CompletionItemKind.Value
446
- });
447
- }
448
- for (var func in languageFacts.cssWideFunctions) {
449
- var insertText = moveCursorInsideParenthesis(func);
450
- result.items.push({
451
- label: func,
452
- documentation: languageFacts.cssWideFunctions[func],
453
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), insertText),
454
- kind: cssLanguageTypes_1.CompletionItemKind.Function,
455
- insertTextFormat: SnippetFormat,
456
- command: strings.startsWith(func, 'var') ? retriggerCommand : undefined
457
- });
458
- }
459
- return result;
460
- };
461
- CSSCompletion.prototype.getCompletionsForInterpolation = function (node, result) {
462
- if (this.offset >= node.offset + 2) {
463
- this.getVariableProposals(null, result);
464
- }
465
- return result;
466
- };
467
- CSSCompletion.prototype.getVariableProposals = function (existingNode, result) {
468
- var symbols = this.getSymbolContext().findSymbolsAtOffset(this.offset, nodes.ReferenceType.Variable);
469
- for (var _i = 0, symbols_1 = symbols; _i < symbols_1.length; _i++) {
470
- var symbol = symbols_1[_i];
471
- var insertText = strings.startsWith(symbol.name, '--') ? "var(".concat(symbol.name, ")") : symbol.name;
472
- var completionItem = {
473
- label: symbol.name,
474
- documentation: symbol.value ? strings.getLimitedString(symbol.value) : symbol.value,
475
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), insertText),
476
- kind: cssLanguageTypes_1.CompletionItemKind.Variable,
477
- sortText: SortTexts.Variable
478
- };
479
- if (typeof completionItem.documentation === 'string' && isColorString(completionItem.documentation)) {
480
- completionItem.kind = cssLanguageTypes_1.CompletionItemKind.Color;
481
- }
482
- if (symbol.node.type === nodes.NodeType.FunctionParameter) {
483
- var mixinNode = (symbol.node.getParent());
484
- if (mixinNode.type === nodes.NodeType.MixinDeclaration) {
485
- completionItem.detail = localize('completion.argument', 'argument from \'{0}\'', mixinNode.getName());
486
- }
487
- }
488
- result.items.push(completionItem);
489
- }
490
- return result;
491
- };
492
- CSSCompletion.prototype.getVariableProposalsForCSSVarFunction = function (result) {
493
- var allReferencedVariables = new Set();
494
- this.styleSheet.acceptVisitor(new VariableCollector(allReferencedVariables, this.offset));
495
- var symbols = this.getSymbolContext().findSymbolsAtOffset(this.offset, nodes.ReferenceType.Variable);
496
- for (var _i = 0, symbols_2 = symbols; _i < symbols_2.length; _i++) {
497
- var symbol = symbols_2[_i];
498
- if (strings.startsWith(symbol.name, '--')) {
499
- var completionItem = {
500
- label: symbol.name,
501
- documentation: symbol.value ? strings.getLimitedString(symbol.value) : symbol.value,
502
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(null), symbol.name),
503
- kind: cssLanguageTypes_1.CompletionItemKind.Variable
504
- };
505
- if (typeof completionItem.documentation === 'string' && isColorString(completionItem.documentation)) {
506
- completionItem.kind = cssLanguageTypes_1.CompletionItemKind.Color;
507
- }
508
- result.items.push(completionItem);
509
- }
510
- allReferencedVariables.remove(symbol.name);
511
- }
512
- for (var _a = 0, _b = allReferencedVariables.getEntries(); _a < _b.length; _a++) {
513
- var name = _b[_a];
514
- if (strings.startsWith(name, '--')) {
515
- var completionItem = {
516
- label: name,
517
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(null), name),
518
- kind: cssLanguageTypes_1.CompletionItemKind.Variable
519
- };
520
- result.items.push(completionItem);
521
- }
522
- }
523
- return result;
524
- };
525
- CSSCompletion.prototype.getUnitProposals = function (entry, existingNode, result) {
526
- var currentWord = '0';
527
- if (this.currentWord.length > 0) {
528
- var numMatch = this.currentWord.match(/^-?\d[\.\d+]*/);
529
- if (numMatch) {
530
- currentWord = numMatch[0];
531
- result.isIncomplete = currentWord.length === this.currentWord.length;
532
- }
533
- }
534
- else if (this.currentWord.length === 0) {
535
- result.isIncomplete = true;
536
- }
537
- if (existingNode && existingNode.parent && existingNode.parent.type === nodes.NodeType.Term) {
538
- existingNode = existingNode.getParent(); // include the unary operator
539
- }
540
- if (entry.restrictions) {
541
- for (var _i = 0, _a = entry.restrictions; _i < _a.length; _i++) {
542
- var restriction = _a[_i];
543
- var units = languageFacts.units[restriction];
544
- if (units) {
545
- for (var _b = 0, units_1 = units; _b < units_1.length; _b++) {
546
- var unit = units_1[_b];
547
- var insertText = currentWord + unit;
548
- result.items.push({
549
- label: insertText,
550
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), insertText),
551
- kind: cssLanguageTypes_1.CompletionItemKind.Unit
552
- });
553
- }
554
- }
555
- }
556
- }
557
- return result;
558
- };
559
- CSSCompletion.prototype.getCompletionRange = function (existingNode) {
560
- if (existingNode && existingNode.offset <= this.offset && this.offset <= existingNode.end) {
561
- var end = existingNode.end !== -1 ? this.textDocument.positionAt(existingNode.end) : this.position;
562
- var start = this.textDocument.positionAt(existingNode.offset);
563
- if (start.line === end.line) {
564
- return cssLanguageTypes_1.Range.create(start, end); // multi line edits are not allowed
565
- }
566
- }
567
- return this.defaultReplaceRange;
568
- };
569
- CSSCompletion.prototype.getColorProposals = function (entry, existingNode, result) {
570
- for (var color in languageFacts.colors) {
571
- result.items.push({
572
- label: color,
573
- documentation: languageFacts.colors[color],
574
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), color),
575
- kind: cssLanguageTypes_1.CompletionItemKind.Color
576
- });
577
- }
578
- for (var color in languageFacts.colorKeywords) {
579
- result.items.push({
580
- label: color,
581
- documentation: languageFacts.colorKeywords[color],
582
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), color),
583
- kind: cssLanguageTypes_1.CompletionItemKind.Value
584
- });
585
- }
586
- var colorValues = new Set();
587
- this.styleSheet.acceptVisitor(new ColorValueCollector(colorValues, this.offset));
588
- for (var _i = 0, _a = colorValues.getEntries(); _i < _a.length; _i++) {
589
- var color = _a[_i];
590
- result.items.push({
591
- label: color,
592
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), color),
593
- kind: cssLanguageTypes_1.CompletionItemKind.Color
594
- });
595
- }
596
- var _loop_1 = function (p) {
597
- var tabStop = 1;
598
- var replaceFunction = function (_match, p1) { return '${' + tabStop++ + ':' + p1 + '}'; };
599
- var insertText = p.func.replace(/\[?\$(\w+)\]?/g, replaceFunction);
600
- result.items.push({
601
- label: p.func.substr(0, p.func.indexOf('(')),
602
- detail: p.func,
603
- documentation: p.desc,
604
- textEdit: cssLanguageTypes_1.TextEdit.replace(this_1.getCompletionRange(existingNode), insertText),
605
- insertTextFormat: SnippetFormat,
606
- kind: cssLanguageTypes_1.CompletionItemKind.Function
607
- });
608
- };
609
- var this_1 = this;
610
- for (var _b = 0, _c = languageFacts.colorFunctions; _b < _c.length; _b++) {
611
- var p = _c[_b];
612
- _loop_1(p);
613
- }
614
- return result;
615
- };
616
- CSSCompletion.prototype.getPositionProposals = function (entry, existingNode, result) {
617
- for (var position in languageFacts.positionKeywords) {
618
- result.items.push({
619
- label: position,
620
- documentation: languageFacts.positionKeywords[position],
621
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), position),
622
- kind: cssLanguageTypes_1.CompletionItemKind.Value
623
- });
624
- }
625
- return result;
626
- };
627
- CSSCompletion.prototype.getRepeatStyleProposals = function (entry, existingNode, result) {
628
- for (var repeat in languageFacts.repeatStyleKeywords) {
629
- result.items.push({
630
- label: repeat,
631
- documentation: languageFacts.repeatStyleKeywords[repeat],
632
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), repeat),
633
- kind: cssLanguageTypes_1.CompletionItemKind.Value
634
- });
635
- }
636
- return result;
637
- };
638
- CSSCompletion.prototype.getLineStyleProposals = function (entry, existingNode, result) {
639
- for (var lineStyle in languageFacts.lineStyleKeywords) {
640
- result.items.push({
641
- label: lineStyle,
642
- documentation: languageFacts.lineStyleKeywords[lineStyle],
643
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), lineStyle),
644
- kind: cssLanguageTypes_1.CompletionItemKind.Value
645
- });
646
- }
647
- return result;
648
- };
649
- CSSCompletion.prototype.getLineWidthProposals = function (entry, existingNode, result) {
650
- for (var _i = 0, _a = languageFacts.lineWidthKeywords; _i < _a.length; _i++) {
651
- var lineWidth = _a[_i];
652
- result.items.push({
653
- label: lineWidth,
654
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), lineWidth),
655
- kind: cssLanguageTypes_1.CompletionItemKind.Value
656
- });
657
- }
658
- return result;
659
- };
660
- CSSCompletion.prototype.getGeometryBoxProposals = function (entry, existingNode, result) {
661
- for (var box in languageFacts.geometryBoxKeywords) {
662
- result.items.push({
663
- label: box,
664
- documentation: languageFacts.geometryBoxKeywords[box],
665
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), box),
666
- kind: cssLanguageTypes_1.CompletionItemKind.Value
667
- });
668
- }
669
- return result;
670
- };
671
- CSSCompletion.prototype.getBoxProposals = function (entry, existingNode, result) {
672
- for (var box in languageFacts.boxKeywords) {
673
- result.items.push({
674
- label: box,
675
- documentation: languageFacts.boxKeywords[box],
676
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), box),
677
- kind: cssLanguageTypes_1.CompletionItemKind.Value
678
- });
679
- }
680
- return result;
681
- };
682
- CSSCompletion.prototype.getImageProposals = function (entry, existingNode, result) {
683
- for (var image in languageFacts.imageFunctions) {
684
- var insertText = moveCursorInsideParenthesis(image);
685
- result.items.push({
686
- label: image,
687
- documentation: languageFacts.imageFunctions[image],
688
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), insertText),
689
- kind: cssLanguageTypes_1.CompletionItemKind.Function,
690
- insertTextFormat: image !== insertText ? SnippetFormat : void 0
691
- });
692
- }
693
- return result;
694
- };
695
- CSSCompletion.prototype.getTimingFunctionProposals = function (entry, existingNode, result) {
696
- for (var timing in languageFacts.transitionTimingFunctions) {
697
- var insertText = moveCursorInsideParenthesis(timing);
698
- result.items.push({
699
- label: timing,
700
- documentation: languageFacts.transitionTimingFunctions[timing],
701
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), insertText),
702
- kind: cssLanguageTypes_1.CompletionItemKind.Function,
703
- insertTextFormat: timing !== insertText ? SnippetFormat : void 0
704
- });
705
- }
706
- return result;
707
- };
708
- CSSCompletion.prototype.getBasicShapeProposals = function (entry, existingNode, result) {
709
- for (var shape in languageFacts.basicShapeFunctions) {
710
- var insertText = moveCursorInsideParenthesis(shape);
711
- result.items.push({
712
- label: shape,
713
- documentation: languageFacts.basicShapeFunctions[shape],
714
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), insertText),
715
- kind: cssLanguageTypes_1.CompletionItemKind.Function,
716
- insertTextFormat: shape !== insertText ? SnippetFormat : void 0
717
- });
718
- }
719
- return result;
720
- };
721
- CSSCompletion.prototype.getCompletionsForStylesheet = function (result) {
722
- var node = this.styleSheet.findFirstChildBeforeOffset(this.offset);
723
- if (!node) {
724
- return this.getCompletionForTopLevel(result);
725
- }
726
- if (node instanceof nodes.RuleSet) {
727
- return this.getCompletionsForRuleSet(node, result);
728
- }
729
- if (node instanceof nodes.Supports) {
730
- return this.getCompletionsForSupports(node, result);
731
- }
732
- return result;
733
- };
734
- CSSCompletion.prototype.getCompletionForTopLevel = function (result) {
735
- var _this = this;
736
- this.cssDataManager.getAtDirectives().forEach(function (entry) {
737
- result.items.push({
738
- label: entry.name,
739
- textEdit: cssLanguageTypes_1.TextEdit.replace(_this.getCompletionRange(null), entry.name),
740
- documentation: languageFacts.getEntryDescription(entry, _this.doesSupportMarkdown()),
741
- tags: isDeprecated(entry) ? [cssLanguageTypes_1.CompletionItemTag.Deprecated] : [],
742
- kind: cssLanguageTypes_1.CompletionItemKind.Keyword
743
- });
744
- });
745
- this.getCompletionsForSelector(null, false, result);
746
- return result;
747
- };
748
- CSSCompletion.prototype.getCompletionsForRuleSet = function (ruleSet, result) {
749
- var declarations = ruleSet.getDeclarations();
750
- var isAfter = declarations && declarations.endsWith('}') && this.offset >= declarations.end;
751
- if (isAfter) {
752
- return this.getCompletionForTopLevel(result);
753
- }
754
- var isInSelectors = !declarations || this.offset <= declarations.offset;
755
- if (isInSelectors) {
756
- return this.getCompletionsForSelector(ruleSet, ruleSet.isNested(), result);
757
- }
758
- return this.getCompletionsForDeclarations(ruleSet.getDeclarations(), result);
759
- };
760
- CSSCompletion.prototype.getCompletionsForSelector = function (ruleSet, isNested, result) {
761
- var _this = this;
762
- var existingNode = this.findInNodePath(nodes.NodeType.PseudoSelector, nodes.NodeType.IdentifierSelector, nodes.NodeType.ClassSelector, nodes.NodeType.ElementNameSelector);
763
- if (!existingNode && this.hasCharacterAtPosition(this.offset - this.currentWord.length - 1, ':')) {
764
- // after the ':' of a pseudo selector, no node generated for just ':'
765
- this.currentWord = ':' + this.currentWord;
766
- if (this.hasCharacterAtPosition(this.offset - this.currentWord.length - 1, ':')) {
767
- this.currentWord = ':' + this.currentWord; // for '::'
768
- }
769
- this.defaultReplaceRange = cssLanguageTypes_1.Range.create(cssLanguageTypes_1.Position.create(this.position.line, this.position.character - this.currentWord.length), this.position);
770
- }
771
- var pseudoClasses = this.cssDataManager.getPseudoClasses();
772
- pseudoClasses.forEach(function (entry) {
773
- var insertText = moveCursorInsideParenthesis(entry.name);
774
- var item = {
775
- label: entry.name,
776
- textEdit: cssLanguageTypes_1.TextEdit.replace(_this.getCompletionRange(existingNode), insertText),
777
- documentation: languageFacts.getEntryDescription(entry, _this.doesSupportMarkdown()),
778
- tags: isDeprecated(entry) ? [cssLanguageTypes_1.CompletionItemTag.Deprecated] : [],
779
- kind: cssLanguageTypes_1.CompletionItemKind.Function,
780
- insertTextFormat: entry.name !== insertText ? SnippetFormat : void 0
781
- };
782
- if (strings.startsWith(entry.name, ':-')) {
783
- item.sortText = SortTexts.VendorPrefixed;
784
- }
785
- result.items.push(item);
786
- });
787
- var pseudoElements = this.cssDataManager.getPseudoElements();
788
- pseudoElements.forEach(function (entry) {
789
- var insertText = moveCursorInsideParenthesis(entry.name);
790
- var item = {
791
- label: entry.name,
792
- textEdit: cssLanguageTypes_1.TextEdit.replace(_this.getCompletionRange(existingNode), insertText),
793
- documentation: languageFacts.getEntryDescription(entry, _this.doesSupportMarkdown()),
794
- tags: isDeprecated(entry) ? [cssLanguageTypes_1.CompletionItemTag.Deprecated] : [],
795
- kind: cssLanguageTypes_1.CompletionItemKind.Function,
796
- insertTextFormat: entry.name !== insertText ? SnippetFormat : void 0
797
- };
798
- if (strings.startsWith(entry.name, '::-')) {
799
- item.sortText = SortTexts.VendorPrefixed;
800
- }
801
- result.items.push(item);
802
- });
803
- if (!isNested) { // show html tags only for top level
804
- for (var _i = 0, _a = languageFacts.html5Tags; _i < _a.length; _i++) {
805
- var entry = _a[_i];
806
- result.items.push({
807
- label: entry,
808
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), entry),
809
- kind: cssLanguageTypes_1.CompletionItemKind.Keyword
810
- });
811
- }
812
- for (var _b = 0, _c = languageFacts.svgElements; _b < _c.length; _b++) {
813
- var entry = _c[_b];
814
- result.items.push({
815
- label: entry,
816
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), entry),
817
- kind: cssLanguageTypes_1.CompletionItemKind.Keyword
818
- });
819
- }
820
- }
821
- var visited = {};
822
- visited[this.currentWord] = true;
823
- var docText = this.textDocument.getText();
824
- this.styleSheet.accept(function (n) {
825
- if (n.type === nodes.NodeType.SimpleSelector && n.length > 0) {
826
- var selector = docText.substr(n.offset, n.length);
827
- if (selector.charAt(0) === '.' && !visited[selector]) {
828
- visited[selector] = true;
829
- result.items.push({
830
- label: selector,
831
- textEdit: cssLanguageTypes_1.TextEdit.replace(_this.getCompletionRange(existingNode), selector),
832
- kind: cssLanguageTypes_1.CompletionItemKind.Keyword
833
- });
834
- }
835
- return false;
836
- }
837
- return true;
838
- });
839
- if (ruleSet && ruleSet.isNested()) {
840
- var selector = ruleSet.getSelectors().findFirstChildBeforeOffset(this.offset);
841
- if (selector && ruleSet.getSelectors().getChildren().indexOf(selector) === 0) {
842
- this.getPropertyProposals(null, result);
843
- }
844
- }
845
- return result;
846
- };
847
- CSSCompletion.prototype.getCompletionsForDeclarations = function (declarations, result) {
848
- if (!declarations || this.offset === declarations.offset) { // incomplete nodes
849
- return result;
850
- }
851
- var node = declarations.findFirstChildBeforeOffset(this.offset);
852
- if (!node) {
853
- return this.getCompletionsForDeclarationProperty(null, result);
854
- }
855
- if (node instanceof nodes.AbstractDeclaration) {
856
- var declaration = node;
857
- if (!(0, objects_1.isDefined)(declaration.colonPosition) || this.offset <= declaration.colonPosition) {
858
- // complete property
859
- return this.getCompletionsForDeclarationProperty(declaration, result);
860
- }
861
- else if (((0, objects_1.isDefined)(declaration.semicolonPosition) && declaration.semicolonPosition < this.offset)) {
862
- if (this.offset === declaration.semicolonPosition + 1) {
863
- return result; // don't show new properties right after semicolon (see Bug 15421:[intellisense] [css] Be less aggressive when manually typing CSS)
864
- }
865
- // complete next property
866
- return this.getCompletionsForDeclarationProperty(null, result);
867
- }
868
- if (declaration instanceof nodes.Declaration) {
869
- // complete value
870
- return this.getCompletionsForDeclarationValue(declaration, result);
871
- }
872
- }
873
- else if (node instanceof nodes.ExtendsReference) {
874
- this.getCompletionsForExtendsReference(node, null, result);
875
- }
876
- else if (this.currentWord && this.currentWord[0] === '@') {
877
- this.getCompletionsForDeclarationProperty(null, result);
878
- }
879
- else if (node instanceof nodes.RuleSet) {
880
- this.getCompletionsForDeclarationProperty(null, result);
881
- }
882
- return result;
883
- };
884
- CSSCompletion.prototype.getCompletionsForVariableDeclaration = function (declaration, result) {
885
- if (this.offset && (0, objects_1.isDefined)(declaration.colonPosition) && this.offset > declaration.colonPosition) {
886
- this.getVariableProposals(declaration.getValue(), result);
887
- }
888
- return result;
889
- };
890
- CSSCompletion.prototype.getCompletionsForExpression = function (expression, result) {
891
- var parent = expression.getParent();
892
- if (parent instanceof nodes.FunctionArgument) {
893
- this.getCompletionsForFunctionArgument(parent, parent.getParent(), result);
894
- return result;
895
- }
896
- var declaration = expression.findParent(nodes.NodeType.Declaration);
897
- if (!declaration) {
898
- this.getTermProposals(undefined, null, result);
899
- return result;
900
- }
901
- var node = expression.findChildAtOffset(this.offset, true);
902
- if (!node) {
903
- return this.getCompletionsForDeclarationValue(declaration, result);
904
- }
905
- if (node instanceof nodes.NumericValue || node instanceof nodes.Identifier) {
906
- return this.getCompletionsForDeclarationValue(declaration, result);
907
- }
908
- return result;
909
- };
910
- CSSCompletion.prototype.getCompletionsForFunctionArgument = function (arg, func, result) {
911
- var identifier = func.getIdentifier();
912
- if (identifier && identifier.matches('var')) {
913
- if (!func.getArguments().hasChildren() || func.getArguments().getChild(0) === arg) {
914
- this.getVariableProposalsForCSSVarFunction(result);
915
- }
916
- }
917
- return result;
918
- };
919
- CSSCompletion.prototype.getCompletionsForFunctionDeclaration = function (decl, result) {
920
- var declarations = decl.getDeclarations();
921
- if (declarations && this.offset > declarations.offset && this.offset < declarations.end) {
922
- this.getTermProposals(undefined, null, result);
923
- }
924
- return result;
925
- };
926
- CSSCompletion.prototype.getCompletionsForMixinReference = function (ref, result) {
927
- var _this = this;
928
- var allMixins = this.getSymbolContext().findSymbolsAtOffset(this.offset, nodes.ReferenceType.Mixin);
929
- for (var _i = 0, allMixins_1 = allMixins; _i < allMixins_1.length; _i++) {
930
- var mixinSymbol = allMixins_1[_i];
931
- if (mixinSymbol.node instanceof nodes.MixinDeclaration) {
932
- result.items.push(this.makeTermProposal(mixinSymbol, mixinSymbol.node.getParameters(), null));
933
- }
934
- }
935
- var identifierNode = ref.getIdentifier() || null;
936
- this.completionParticipants.forEach(function (participant) {
937
- if (participant.onCssMixinReference) {
938
- participant.onCssMixinReference({
939
- mixinName: _this.currentWord,
940
- range: _this.getCompletionRange(identifierNode)
941
- });
942
- }
943
- });
944
- return result;
945
- };
946
- CSSCompletion.prototype.getTermProposals = function (entry, existingNode, result) {
947
- var allFunctions = this.getSymbolContext().findSymbolsAtOffset(this.offset, nodes.ReferenceType.Function);
948
- for (var _i = 0, allFunctions_1 = allFunctions; _i < allFunctions_1.length; _i++) {
949
- var functionSymbol = allFunctions_1[_i];
950
- if (functionSymbol.node instanceof nodes.FunctionDeclaration) {
951
- result.items.push(this.makeTermProposal(functionSymbol, functionSymbol.node.getParameters(), existingNode));
952
- }
953
- }
954
- return result;
955
- };
956
- CSSCompletion.prototype.makeTermProposal = function (symbol, parameters, existingNode) {
957
- var decl = symbol.node;
958
- var params = parameters.getChildren().map(function (c) {
959
- return (c instanceof nodes.FunctionParameter) ? c.getName() : c.getText();
960
- });
961
- var insertText = symbol.name + '(' + params.map(function (p, index) { return '${' + (index + 1) + ':' + p + '}'; }).join(', ') + ')';
962
- return {
963
- label: symbol.name,
964
- detail: symbol.name + '(' + params.join(', ') + ')',
965
- textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), insertText),
966
- insertTextFormat: SnippetFormat,
967
- kind: cssLanguageTypes_1.CompletionItemKind.Function,
968
- sortText: SortTexts.Term
969
- };
970
- };
971
- CSSCompletion.prototype.getCompletionsForSupportsCondition = function (supportsCondition, result) {
972
- var child = supportsCondition.findFirstChildBeforeOffset(this.offset);
973
- if (child) {
974
- if (child instanceof nodes.Declaration) {
975
- if (!(0, objects_1.isDefined)(child.colonPosition) || this.offset <= child.colonPosition) {
976
- return this.getCompletionsForDeclarationProperty(child, result);
977
- }
978
- else {
979
- return this.getCompletionsForDeclarationValue(child, result);
980
- }
981
- }
982
- else if (child instanceof nodes.SupportsCondition) {
983
- return this.getCompletionsForSupportsCondition(child, result);
984
- }
985
- }
986
- if ((0, objects_1.isDefined)(supportsCondition.lParent) && this.offset > supportsCondition.lParent && (!(0, objects_1.isDefined)(supportsCondition.rParent) || this.offset <= supportsCondition.rParent)) {
987
- return this.getCompletionsForDeclarationProperty(null, result);
988
- }
989
- return result;
990
- };
991
- CSSCompletion.prototype.getCompletionsForSupports = function (supports, result) {
992
- var declarations = supports.getDeclarations();
993
- var inInCondition = !declarations || this.offset <= declarations.offset;
994
- if (inInCondition) {
995
- var child = supports.findFirstChildBeforeOffset(this.offset);
996
- if (child instanceof nodes.SupportsCondition) {
997
- return this.getCompletionsForSupportsCondition(child, result);
998
- }
999
- return result;
1000
- }
1001
- return this.getCompletionForTopLevel(result);
1002
- };
1003
- CSSCompletion.prototype.getCompletionsForExtendsReference = function (extendsRef, existingNode, result) {
1004
- return result;
1005
- };
1006
- CSSCompletion.prototype.getCompletionForUriLiteralValue = function (uriLiteralNode, result) {
1007
- var uriValue;
1008
- var position;
1009
- var range;
1010
- // No children, empty value
1011
- if (!uriLiteralNode.hasChildren()) {
1012
- uriValue = '';
1013
- position = this.position;
1014
- var emptyURIValuePosition = this.textDocument.positionAt(uriLiteralNode.offset + 'url('.length);
1015
- range = cssLanguageTypes_1.Range.create(emptyURIValuePosition, emptyURIValuePosition);
1016
- }
1017
- else {
1018
- var uriValueNode = uriLiteralNode.getChild(0);
1019
- uriValue = uriValueNode.getText();
1020
- position = this.position;
1021
- range = this.getCompletionRange(uriValueNode);
1022
- }
1023
- this.completionParticipants.forEach(function (participant) {
1024
- if (participant.onCssURILiteralValue) {
1025
- participant.onCssURILiteralValue({
1026
- uriValue: uriValue,
1027
- position: position,
1028
- range: range
1029
- });
1030
- }
1031
- });
1032
- return result;
1033
- };
1034
- CSSCompletion.prototype.getCompletionForImportPath = function (importPathNode, result) {
1035
- var _this = this;
1036
- this.completionParticipants.forEach(function (participant) {
1037
- if (participant.onCssImportPath) {
1038
- participant.onCssImportPath({
1039
- pathValue: importPathNode.getText(),
1040
- position: _this.position,
1041
- range: _this.getCompletionRange(importPathNode)
1042
- });
1043
- }
1044
- });
1045
- return result;
1046
- };
1047
- CSSCompletion.prototype.hasCharacterAtPosition = function (offset, char) {
1048
- var text = this.textDocument.getText();
1049
- return (offset >= 0 && offset < text.length) && text.charAt(offset) === char;
1050
- };
1051
- CSSCompletion.prototype.doesSupportMarkdown = function () {
1052
- var _a, _b, _c;
1053
- if (!(0, objects_1.isDefined)(this.supportsMarkdown)) {
1054
- if (!(0, objects_1.isDefined)(this.lsOptions.clientCapabilities)) {
1055
- this.supportsMarkdown = true;
1056
- return this.supportsMarkdown;
1057
- }
1058
- var documentationFormat = (_c = (_b = (_a = this.lsOptions.clientCapabilities.textDocument) === null || _a === void 0 ? void 0 : _a.completion) === null || _b === void 0 ? void 0 : _b.completionItem) === null || _c === void 0 ? void 0 : _c.documentationFormat;
1059
- this.supportsMarkdown = Array.isArray(documentationFormat) && documentationFormat.indexOf(cssLanguageTypes_1.MarkupKind.Markdown) !== -1;
1060
- }
1061
- return this.supportsMarkdown;
1062
- };
1063
- return CSSCompletion;
1064
- }());
1065
- exports.CSSCompletion = CSSCompletion;
1066
- function isDeprecated(entry) {
1067
- if (entry.status && (entry.status === 'nonstandard' || entry.status === 'obsolete')) {
1068
- return true;
1069
- }
1070
- return false;
1071
- }
1072
- var Set = /** @class */ (function () {
1073
- function Set() {
1074
- this.entries = {};
1075
- }
1076
- Set.prototype.add = function (entry) {
1077
- this.entries[entry] = true;
1078
- };
1079
- Set.prototype.remove = function (entry) {
1080
- delete this.entries[entry];
1081
- };
1082
- Set.prototype.getEntries = function () {
1083
- return Object.keys(this.entries);
1084
- };
1085
- return Set;
1086
- }());
1087
- function moveCursorInsideParenthesis(text) {
1088
- return text.replace(/\(\)$/, "($1)");
1089
- }
1090
- function collectValues(styleSheet, declaration) {
1091
- var fullPropertyName = declaration.getFullPropertyName();
1092
- var entries = new Set();
1093
- function visitValue(node) {
1094
- if (node instanceof nodes.Identifier || node instanceof nodes.NumericValue || node instanceof nodes.HexColorValue) {
1095
- entries.add(node.getText());
1096
- }
1097
- return true;
1098
- }
1099
- function matchesProperty(decl) {
1100
- var propertyName = decl.getFullPropertyName();
1101
- return fullPropertyName === propertyName;
1102
- }
1103
- function vistNode(node) {
1104
- if (node instanceof nodes.Declaration && node !== declaration) {
1105
- if (matchesProperty(node)) {
1106
- var value = node.getValue();
1107
- if (value) {
1108
- value.accept(visitValue);
1109
- }
1110
- }
1111
- }
1112
- return true;
1113
- }
1114
- styleSheet.accept(vistNode);
1115
- return entries;
1116
- }
1117
- var ColorValueCollector = /** @class */ (function () {
1118
- function ColorValueCollector(entries, currentOffset) {
1119
- this.entries = entries;
1120
- this.currentOffset = currentOffset;
1121
- // nothing to do
1122
- }
1123
- ColorValueCollector.prototype.visitNode = function (node) {
1124
- if (node instanceof nodes.HexColorValue || (node instanceof nodes.Function && languageFacts.isColorConstructor(node))) {
1125
- if (this.currentOffset < node.offset || node.end < this.currentOffset) {
1126
- this.entries.add(node.getText());
1127
- }
1128
- }
1129
- return true;
1130
- };
1131
- return ColorValueCollector;
1132
- }());
1133
- var VariableCollector = /** @class */ (function () {
1134
- function VariableCollector(entries, currentOffset) {
1135
- this.entries = entries;
1136
- this.currentOffset = currentOffset;
1137
- // nothing to do
1138
- }
1139
- VariableCollector.prototype.visitNode = function (node) {
1140
- if (node instanceof nodes.Identifier && node.isCustomProperty) {
1141
- if (this.currentOffset < node.offset || node.end < this.currentOffset) {
1142
- this.entries.add(node.getText());
1143
- }
1144
- }
1145
- return true;
1146
- };
1147
- return VariableCollector;
1148
- }());
1149
- function getCurrentWord(document, offset) {
1150
- var i = offset - 1;
1151
- var text = document.getText();
1152
- while (i >= 0 && ' \t\n\r":{[()]},*>+'.indexOf(text.charAt(i)) === -1) {
1153
- i--;
1154
- }
1155
- return text.substring(i + 1, offset);
1156
- }
1157
- function isColorString(s) {
1158
- // From https://stackoverflow.com/questions/8027423/how-to-check-if-a-string-is-a-valid-hex-color-representation/8027444
1159
- return (s.toLowerCase() in languageFacts.colors) || /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(s);
1160
- }
1161
- });
1
+ (function (factory) {
2
+ if (typeof module === "object" && typeof module.exports === "object") {
3
+ var v = factory(require, exports);
4
+ if (v !== undefined) module.exports = v;
5
+ }
6
+ else if (typeof define === "function" && define.amd) {
7
+ define(["require", "exports", "../parser/cssNodes", "../parser/cssSymbolScope", "../languageFacts/facts", "../utils/strings", "../cssLanguageTypes", "vscode-nls", "../utils/objects", "./pathCompletion"], factory);
8
+ }
9
+ })(function (require, exports) {
10
+ /*---------------------------------------------------------------------------------------------
11
+ * Copyright (c) Microsoft Corporation. All rights reserved.
12
+ * Licensed under the MIT License. See License.txt in the project root for license information.
13
+ *--------------------------------------------------------------------------------------------*/
14
+ 'use strict';
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.CSSCompletion = void 0;
17
+ const nodes = require("../parser/cssNodes");
18
+ const cssSymbolScope_1 = require("../parser/cssSymbolScope");
19
+ const languageFacts = require("../languageFacts/facts");
20
+ const strings = require("../utils/strings");
21
+ const cssLanguageTypes_1 = require("../cssLanguageTypes");
22
+ const nls = require("vscode-nls");
23
+ const objects_1 = require("../utils/objects");
24
+ const pathCompletion_1 = require("./pathCompletion");
25
+ const localize = nls.loadMessageBundle();
26
+ const SnippetFormat = cssLanguageTypes_1.InsertTextFormat.Snippet;
27
+ const retriggerCommand = {
28
+ title: 'Suggest',
29
+ command: 'editor.action.triggerSuggest'
30
+ };
31
+ var SortTexts;
32
+ (function (SortTexts) {
33
+ // char code 32, comes before everything
34
+ SortTexts["Enums"] = " ";
35
+ SortTexts["Normal"] = "d";
36
+ SortTexts["VendorPrefixed"] = "x";
37
+ SortTexts["Term"] = "y";
38
+ SortTexts["Variable"] = "z";
39
+ })(SortTexts || (SortTexts = {}));
40
+ class CSSCompletion {
41
+ constructor(variablePrefix = null, lsOptions, cssDataManager) {
42
+ this.variablePrefix = variablePrefix;
43
+ this.lsOptions = lsOptions;
44
+ this.cssDataManager = cssDataManager;
45
+ this.completionParticipants = [];
46
+ }
47
+ configure(settings) {
48
+ this.defaultSettings = settings;
49
+ }
50
+ getSymbolContext() {
51
+ if (!this.symbolContext) {
52
+ this.symbolContext = new cssSymbolScope_1.Symbols(this.styleSheet);
53
+ }
54
+ return this.symbolContext;
55
+ }
56
+ setCompletionParticipants(registeredCompletionParticipants) {
57
+ this.completionParticipants = registeredCompletionParticipants || [];
58
+ }
59
+ async doComplete2(document, position, styleSheet, documentContext, completionSettings = this.defaultSettings) {
60
+ if (!this.lsOptions.fileSystemProvider || !this.lsOptions.fileSystemProvider.readDirectory) {
61
+ return this.doComplete(document, position, styleSheet, completionSettings);
62
+ }
63
+ const participant = new pathCompletion_1.PathCompletionParticipant(this.lsOptions.fileSystemProvider.readDirectory);
64
+ const contributedParticipants = this.completionParticipants;
65
+ this.completionParticipants = [participant].concat(contributedParticipants);
66
+ const result = this.doComplete(document, position, styleSheet, completionSettings);
67
+ try {
68
+ const pathCompletionResult = await participant.computeCompletions(document, documentContext);
69
+ return {
70
+ isIncomplete: result.isIncomplete || pathCompletionResult.isIncomplete,
71
+ items: pathCompletionResult.items.concat(result.items)
72
+ };
73
+ }
74
+ finally {
75
+ this.completionParticipants = contributedParticipants;
76
+ }
77
+ }
78
+ doComplete(document, position, styleSheet, documentSettings) {
79
+ this.offset = document.offsetAt(position);
80
+ this.position = position;
81
+ this.currentWord = getCurrentWord(document, this.offset);
82
+ this.defaultReplaceRange = cssLanguageTypes_1.Range.create(cssLanguageTypes_1.Position.create(this.position.line, this.position.character - this.currentWord.length), this.position);
83
+ this.textDocument = document;
84
+ this.styleSheet = styleSheet;
85
+ this.documentSettings = documentSettings;
86
+ try {
87
+ const result = { isIncomplete: false, items: [] };
88
+ this.nodePath = nodes.getNodePath(this.styleSheet, this.offset);
89
+ for (let i = this.nodePath.length - 1; i >= 0; i--) {
90
+ const node = this.nodePath[i];
91
+ if (node instanceof nodes.Property) {
92
+ this.getCompletionsForDeclarationProperty(node.getParent(), result);
93
+ }
94
+ else if (node instanceof nodes.Expression) {
95
+ if (node.parent instanceof nodes.Interpolation) {
96
+ this.getVariableProposals(null, result);
97
+ }
98
+ else {
99
+ this.getCompletionsForExpression(node, result);
100
+ }
101
+ }
102
+ else if (node instanceof nodes.SimpleSelector) {
103
+ const parentRef = node.findAParent(nodes.NodeType.ExtendsReference, nodes.NodeType.Ruleset);
104
+ if (parentRef) {
105
+ if (parentRef.type === nodes.NodeType.ExtendsReference) {
106
+ this.getCompletionsForExtendsReference(parentRef, node, result);
107
+ }
108
+ else {
109
+ const parentRuleSet = parentRef;
110
+ this.getCompletionsForSelector(parentRuleSet, parentRuleSet && parentRuleSet.isNested(), result);
111
+ }
112
+ }
113
+ }
114
+ else if (node instanceof nodes.FunctionArgument) {
115
+ this.getCompletionsForFunctionArgument(node, node.getParent(), result);
116
+ }
117
+ else if (node instanceof nodes.Declarations) {
118
+ this.getCompletionsForDeclarations(node, result);
119
+ }
120
+ else if (node instanceof nodes.VariableDeclaration) {
121
+ this.getCompletionsForVariableDeclaration(node, result);
122
+ }
123
+ else if (node instanceof nodes.RuleSet) {
124
+ this.getCompletionsForRuleSet(node, result);
125
+ }
126
+ else if (node instanceof nodes.Interpolation) {
127
+ this.getCompletionsForInterpolation(node, result);
128
+ }
129
+ else if (node instanceof nodes.FunctionDeclaration) {
130
+ this.getCompletionsForFunctionDeclaration(node, result);
131
+ }
132
+ else if (node instanceof nodes.MixinReference) {
133
+ this.getCompletionsForMixinReference(node, result);
134
+ }
135
+ else if (node instanceof nodes.Function) {
136
+ this.getCompletionsForFunctionArgument(null, node, result);
137
+ }
138
+ else if (node instanceof nodes.Supports) {
139
+ this.getCompletionsForSupports(node, result);
140
+ }
141
+ else if (node instanceof nodes.SupportsCondition) {
142
+ this.getCompletionsForSupportsCondition(node, result);
143
+ }
144
+ else if (node instanceof nodes.ExtendsReference) {
145
+ this.getCompletionsForExtendsReference(node, null, result);
146
+ }
147
+ else if (node.type === nodes.NodeType.URILiteral) {
148
+ this.getCompletionForUriLiteralValue(node, result);
149
+ }
150
+ else if (node.parent === null) {
151
+ this.getCompletionForTopLevel(result);
152
+ }
153
+ else if (node.type === nodes.NodeType.StringLiteral && this.isImportPathParent(node.parent.type)) {
154
+ this.getCompletionForImportPath(node, result);
155
+ // } else if (node instanceof nodes.Variable) {
156
+ // this.getCompletionsForVariableDeclaration()
157
+ }
158
+ else {
159
+ continue;
160
+ }
161
+ if (result.items.length > 0 || this.offset > node.offset) {
162
+ return this.finalize(result);
163
+ }
164
+ }
165
+ this.getCompletionsForStylesheet(result);
166
+ if (result.items.length === 0) {
167
+ if (this.variablePrefix && this.currentWord.indexOf(this.variablePrefix) === 0) {
168
+ this.getVariableProposals(null, result);
169
+ }
170
+ }
171
+ return this.finalize(result);
172
+ }
173
+ finally {
174
+ // don't hold on any state, clear symbolContext
175
+ this.position = null;
176
+ this.currentWord = null;
177
+ this.textDocument = null;
178
+ this.styleSheet = null;
179
+ this.symbolContext = null;
180
+ this.defaultReplaceRange = null;
181
+ this.nodePath = null;
182
+ }
183
+ }
184
+ isImportPathParent(type) {
185
+ return type === nodes.NodeType.Import;
186
+ }
187
+ finalize(result) {
188
+ return result;
189
+ }
190
+ findInNodePath(...types) {
191
+ for (let i = this.nodePath.length - 1; i >= 0; i--) {
192
+ const node = this.nodePath[i];
193
+ if (types.indexOf(node.type) !== -1) {
194
+ return node;
195
+ }
196
+ }
197
+ return null;
198
+ }
199
+ getCompletionsForDeclarationProperty(declaration, result) {
200
+ return this.getPropertyProposals(declaration, result);
201
+ }
202
+ getPropertyProposals(declaration, result) {
203
+ const triggerPropertyValueCompletion = this.isTriggerPropertyValueCompletionEnabled;
204
+ const completePropertyWithSemicolon = this.isCompletePropertyWithSemicolonEnabled;
205
+ const properties = this.cssDataManager.getProperties();
206
+ properties.forEach(entry => {
207
+ let range;
208
+ let insertText;
209
+ let retrigger = false;
210
+ if (declaration) {
211
+ range = this.getCompletionRange(declaration.getProperty());
212
+ insertText = entry.name;
213
+ if (!(0, objects_1.isDefined)(declaration.colonPosition)) {
214
+ insertText += ': ';
215
+ retrigger = true;
216
+ }
217
+ }
218
+ else {
219
+ range = this.getCompletionRange(null);
220
+ insertText = entry.name + ': ';
221
+ retrigger = true;
222
+ }
223
+ // Empty .selector { | } case
224
+ if (!declaration && completePropertyWithSemicolon) {
225
+ insertText += '$0;';
226
+ }
227
+ // Cases such as .selector { p; } or .selector { p:; }
228
+ if (declaration && !declaration.semicolonPosition) {
229
+ if (completePropertyWithSemicolon && this.offset >= this.textDocument.offsetAt(range.end)) {
230
+ insertText += '$0;';
231
+ }
232
+ }
233
+ const item = {
234
+ label: entry.name,
235
+ documentation: languageFacts.getEntryDescription(entry, this.doesSupportMarkdown()),
236
+ tags: isDeprecated(entry) ? [cssLanguageTypes_1.CompletionItemTag.Deprecated] : [],
237
+ textEdit: cssLanguageTypes_1.TextEdit.replace(range, insertText),
238
+ insertTextFormat: cssLanguageTypes_1.InsertTextFormat.Snippet,
239
+ kind: cssLanguageTypes_1.CompletionItemKind.Property
240
+ };
241
+ if (!entry.restrictions) {
242
+ retrigger = false;
243
+ }
244
+ if (triggerPropertyValueCompletion && retrigger) {
245
+ item.command = retriggerCommand;
246
+ }
247
+ const relevance = typeof entry.relevance === 'number' ? Math.min(Math.max(entry.relevance, 0), 99) : 50;
248
+ const sortTextSuffix = (255 - relevance).toString(16);
249
+ const sortTextPrefix = strings.startsWith(entry.name, '-') ? SortTexts.VendorPrefixed : SortTexts.Normal;
250
+ item.sortText = sortTextPrefix + '_' + sortTextSuffix;
251
+ result.items.push(item);
252
+ });
253
+ this.completionParticipants.forEach(participant => {
254
+ if (participant.onCssProperty) {
255
+ participant.onCssProperty({
256
+ propertyName: this.currentWord,
257
+ range: this.defaultReplaceRange
258
+ });
259
+ }
260
+ });
261
+ return result;
262
+ }
263
+ get isTriggerPropertyValueCompletionEnabled() {
264
+ return this.documentSettings?.triggerPropertyValueCompletion ?? true;
265
+ }
266
+ get isCompletePropertyWithSemicolonEnabled() {
267
+ return this.documentSettings?.completePropertyWithSemicolon ?? true;
268
+ }
269
+ getCompletionsForDeclarationValue(node, result) {
270
+ const propertyName = node.getFullPropertyName();
271
+ const entry = this.cssDataManager.getProperty(propertyName);
272
+ let existingNode = node.getValue() || null;
273
+ while (existingNode && existingNode.hasChildren()) {
274
+ existingNode = existingNode.findChildAtOffset(this.offset, false);
275
+ }
276
+ this.completionParticipants.forEach(participant => {
277
+ if (participant.onCssPropertyValue) {
278
+ participant.onCssPropertyValue({
279
+ propertyName,
280
+ propertyValue: this.currentWord,
281
+ range: this.getCompletionRange(existingNode)
282
+ });
283
+ }
284
+ });
285
+ if (entry) {
286
+ if (entry.restrictions) {
287
+ for (const restriction of entry.restrictions) {
288
+ switch (restriction) {
289
+ case 'color':
290
+ this.getColorProposals(entry, existingNode, result);
291
+ break;
292
+ case 'position':
293
+ this.getPositionProposals(entry, existingNode, result);
294
+ break;
295
+ case 'repeat':
296
+ this.getRepeatStyleProposals(entry, existingNode, result);
297
+ break;
298
+ case 'line-style':
299
+ this.getLineStyleProposals(entry, existingNode, result);
300
+ break;
301
+ case 'line-width':
302
+ this.getLineWidthProposals(entry, existingNode, result);
303
+ break;
304
+ case 'geometry-box':
305
+ this.getGeometryBoxProposals(entry, existingNode, result);
306
+ break;
307
+ case 'box':
308
+ this.getBoxProposals(entry, existingNode, result);
309
+ break;
310
+ case 'image':
311
+ this.getImageProposals(entry, existingNode, result);
312
+ break;
313
+ case 'timing-function':
314
+ this.getTimingFunctionProposals(entry, existingNode, result);
315
+ break;
316
+ case 'shape':
317
+ this.getBasicShapeProposals(entry, existingNode, result);
318
+ break;
319
+ }
320
+ }
321
+ }
322
+ this.getValueEnumProposals(entry, existingNode, result);
323
+ this.getCSSWideKeywordProposals(entry, existingNode, result);
324
+ this.getUnitProposals(entry, existingNode, result);
325
+ }
326
+ else {
327
+ const existingValues = collectValues(this.styleSheet, node);
328
+ for (const existingValue of existingValues.getEntries()) {
329
+ result.items.push({
330
+ label: existingValue,
331
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), existingValue),
332
+ kind: cssLanguageTypes_1.CompletionItemKind.Value
333
+ });
334
+ }
335
+ }
336
+ this.getVariableProposals(existingNode, result);
337
+ this.getTermProposals(entry, existingNode, result);
338
+ return result;
339
+ }
340
+ getValueEnumProposals(entry, existingNode, result) {
341
+ if (entry.values) {
342
+ for (const value of entry.values) {
343
+ let insertString = value.name;
344
+ let insertTextFormat;
345
+ if (strings.endsWith(insertString, ')')) {
346
+ const from = insertString.lastIndexOf('(');
347
+ if (from !== -1) {
348
+ insertString = insertString.substr(0, from) + '($1)';
349
+ insertTextFormat = SnippetFormat;
350
+ }
351
+ }
352
+ let sortText = SortTexts.Enums;
353
+ if (strings.startsWith(value.name, '-')) {
354
+ sortText += SortTexts.VendorPrefixed;
355
+ }
356
+ const item = {
357
+ label: value.name,
358
+ documentation: languageFacts.getEntryDescription(value, this.doesSupportMarkdown()),
359
+ tags: isDeprecated(entry) ? [cssLanguageTypes_1.CompletionItemTag.Deprecated] : [],
360
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), insertString),
361
+ sortText,
362
+ kind: cssLanguageTypes_1.CompletionItemKind.Value,
363
+ insertTextFormat
364
+ };
365
+ result.items.push(item);
366
+ }
367
+ }
368
+ return result;
369
+ }
370
+ getCSSWideKeywordProposals(entry, existingNode, result) {
371
+ for (const keywords in languageFacts.cssWideKeywords) {
372
+ result.items.push({
373
+ label: keywords,
374
+ documentation: languageFacts.cssWideKeywords[keywords],
375
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), keywords),
376
+ kind: cssLanguageTypes_1.CompletionItemKind.Value
377
+ });
378
+ }
379
+ for (const func in languageFacts.cssWideFunctions) {
380
+ const insertText = moveCursorInsideParenthesis(func);
381
+ result.items.push({
382
+ label: func,
383
+ documentation: languageFacts.cssWideFunctions[func],
384
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), insertText),
385
+ kind: cssLanguageTypes_1.CompletionItemKind.Function,
386
+ insertTextFormat: SnippetFormat,
387
+ command: strings.startsWith(func, 'var') ? retriggerCommand : undefined
388
+ });
389
+ }
390
+ return result;
391
+ }
392
+ getCompletionsForInterpolation(node, result) {
393
+ if (this.offset >= node.offset + 2) {
394
+ this.getVariableProposals(null, result);
395
+ }
396
+ return result;
397
+ }
398
+ getVariableProposals(existingNode, result) {
399
+ const symbols = this.getSymbolContext().findSymbolsAtOffset(this.offset, nodes.ReferenceType.Variable);
400
+ for (const symbol of symbols) {
401
+ const insertText = strings.startsWith(symbol.name, '--') ? `var(${symbol.name})` : symbol.name;
402
+ const completionItem = {
403
+ label: symbol.name,
404
+ documentation: symbol.value ? strings.getLimitedString(symbol.value) : symbol.value,
405
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), insertText),
406
+ kind: cssLanguageTypes_1.CompletionItemKind.Variable,
407
+ sortText: SortTexts.Variable
408
+ };
409
+ if (typeof completionItem.documentation === 'string' && isColorString(completionItem.documentation)) {
410
+ completionItem.kind = cssLanguageTypes_1.CompletionItemKind.Color;
411
+ }
412
+ if (symbol.node.type === nodes.NodeType.FunctionParameter) {
413
+ const mixinNode = (symbol.node.getParent());
414
+ if (mixinNode.type === nodes.NodeType.MixinDeclaration) {
415
+ completionItem.detail = localize('completion.argument', 'argument from \'{0}\'', mixinNode.getName());
416
+ }
417
+ }
418
+ result.items.push(completionItem);
419
+ }
420
+ return result;
421
+ }
422
+ getVariableProposalsForCSSVarFunction(result) {
423
+ const allReferencedVariables = new Set();
424
+ this.styleSheet.acceptVisitor(new VariableCollector(allReferencedVariables, this.offset));
425
+ let symbols = this.getSymbolContext().findSymbolsAtOffset(this.offset, nodes.ReferenceType.Variable);
426
+ for (const symbol of symbols) {
427
+ if (strings.startsWith(symbol.name, '--')) {
428
+ const completionItem = {
429
+ label: symbol.name,
430
+ documentation: symbol.value ? strings.getLimitedString(symbol.value) : symbol.value,
431
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(null), symbol.name),
432
+ kind: cssLanguageTypes_1.CompletionItemKind.Variable
433
+ };
434
+ if (typeof completionItem.documentation === 'string' && isColorString(completionItem.documentation)) {
435
+ completionItem.kind = cssLanguageTypes_1.CompletionItemKind.Color;
436
+ }
437
+ result.items.push(completionItem);
438
+ }
439
+ allReferencedVariables.remove(symbol.name);
440
+ }
441
+ for (const name of allReferencedVariables.getEntries()) {
442
+ if (strings.startsWith(name, '--')) {
443
+ const completionItem = {
444
+ label: name,
445
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(null), name),
446
+ kind: cssLanguageTypes_1.CompletionItemKind.Variable
447
+ };
448
+ result.items.push(completionItem);
449
+ }
450
+ }
451
+ return result;
452
+ }
453
+ getUnitProposals(entry, existingNode, result) {
454
+ let currentWord = '0';
455
+ if (this.currentWord.length > 0) {
456
+ const numMatch = this.currentWord.match(/^-?\d[\.\d+]*/);
457
+ if (numMatch) {
458
+ currentWord = numMatch[0];
459
+ result.isIncomplete = currentWord.length === this.currentWord.length;
460
+ }
461
+ }
462
+ else if (this.currentWord.length === 0) {
463
+ result.isIncomplete = true;
464
+ }
465
+ if (existingNode && existingNode.parent && existingNode.parent.type === nodes.NodeType.Term) {
466
+ existingNode = existingNode.getParent(); // include the unary operator
467
+ }
468
+ if (entry.restrictions) {
469
+ for (const restriction of entry.restrictions) {
470
+ const units = languageFacts.units[restriction];
471
+ if (units) {
472
+ for (const unit of units) {
473
+ const insertText = currentWord + unit;
474
+ result.items.push({
475
+ label: insertText,
476
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), insertText),
477
+ kind: cssLanguageTypes_1.CompletionItemKind.Unit
478
+ });
479
+ }
480
+ }
481
+ }
482
+ }
483
+ return result;
484
+ }
485
+ getCompletionRange(existingNode) {
486
+ if (existingNode && existingNode.offset <= this.offset && this.offset <= existingNode.end) {
487
+ const end = existingNode.end !== -1 ? this.textDocument.positionAt(existingNode.end) : this.position;
488
+ const start = this.textDocument.positionAt(existingNode.offset);
489
+ if (start.line === end.line) {
490
+ return cssLanguageTypes_1.Range.create(start, end); // multi line edits are not allowed
491
+ }
492
+ }
493
+ return this.defaultReplaceRange;
494
+ }
495
+ getColorProposals(entry, existingNode, result) {
496
+ for (const color in languageFacts.colors) {
497
+ result.items.push({
498
+ label: color,
499
+ documentation: languageFacts.colors[color],
500
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), color),
501
+ kind: cssLanguageTypes_1.CompletionItemKind.Color
502
+ });
503
+ }
504
+ for (const color in languageFacts.colorKeywords) {
505
+ result.items.push({
506
+ label: color,
507
+ documentation: languageFacts.colorKeywords[color],
508
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), color),
509
+ kind: cssLanguageTypes_1.CompletionItemKind.Value
510
+ });
511
+ }
512
+ const colorValues = new Set();
513
+ this.styleSheet.acceptVisitor(new ColorValueCollector(colorValues, this.offset));
514
+ for (const color of colorValues.getEntries()) {
515
+ result.items.push({
516
+ label: color,
517
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), color),
518
+ kind: cssLanguageTypes_1.CompletionItemKind.Color
519
+ });
520
+ }
521
+ for (const p of languageFacts.colorFunctions) {
522
+ let tabStop = 1;
523
+ const replaceFunction = (_match, p1) => '${' + tabStop++ + ':' + p1 + '}';
524
+ const insertText = p.func.replace(/\[?\$(\w+)\]?/g, replaceFunction);
525
+ result.items.push({
526
+ label: p.func.substr(0, p.func.indexOf('(')),
527
+ detail: p.func,
528
+ documentation: p.desc,
529
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), insertText),
530
+ insertTextFormat: SnippetFormat,
531
+ kind: cssLanguageTypes_1.CompletionItemKind.Function
532
+ });
533
+ }
534
+ return result;
535
+ }
536
+ getPositionProposals(entry, existingNode, result) {
537
+ for (const position in languageFacts.positionKeywords) {
538
+ result.items.push({
539
+ label: position,
540
+ documentation: languageFacts.positionKeywords[position],
541
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), position),
542
+ kind: cssLanguageTypes_1.CompletionItemKind.Value
543
+ });
544
+ }
545
+ return result;
546
+ }
547
+ getRepeatStyleProposals(entry, existingNode, result) {
548
+ for (const repeat in languageFacts.repeatStyleKeywords) {
549
+ result.items.push({
550
+ label: repeat,
551
+ documentation: languageFacts.repeatStyleKeywords[repeat],
552
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), repeat),
553
+ kind: cssLanguageTypes_1.CompletionItemKind.Value
554
+ });
555
+ }
556
+ return result;
557
+ }
558
+ getLineStyleProposals(entry, existingNode, result) {
559
+ for (const lineStyle in languageFacts.lineStyleKeywords) {
560
+ result.items.push({
561
+ label: lineStyle,
562
+ documentation: languageFacts.lineStyleKeywords[lineStyle],
563
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), lineStyle),
564
+ kind: cssLanguageTypes_1.CompletionItemKind.Value
565
+ });
566
+ }
567
+ return result;
568
+ }
569
+ getLineWidthProposals(entry, existingNode, result) {
570
+ for (const lineWidth of languageFacts.lineWidthKeywords) {
571
+ result.items.push({
572
+ label: lineWidth,
573
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), lineWidth),
574
+ kind: cssLanguageTypes_1.CompletionItemKind.Value
575
+ });
576
+ }
577
+ return result;
578
+ }
579
+ getGeometryBoxProposals(entry, existingNode, result) {
580
+ for (const box in languageFacts.geometryBoxKeywords) {
581
+ result.items.push({
582
+ label: box,
583
+ documentation: languageFacts.geometryBoxKeywords[box],
584
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), box),
585
+ kind: cssLanguageTypes_1.CompletionItemKind.Value
586
+ });
587
+ }
588
+ return result;
589
+ }
590
+ getBoxProposals(entry, existingNode, result) {
591
+ for (const box in languageFacts.boxKeywords) {
592
+ result.items.push({
593
+ label: box,
594
+ documentation: languageFacts.boxKeywords[box],
595
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), box),
596
+ kind: cssLanguageTypes_1.CompletionItemKind.Value
597
+ });
598
+ }
599
+ return result;
600
+ }
601
+ getImageProposals(entry, existingNode, result) {
602
+ for (const image in languageFacts.imageFunctions) {
603
+ const insertText = moveCursorInsideParenthesis(image);
604
+ result.items.push({
605
+ label: image,
606
+ documentation: languageFacts.imageFunctions[image],
607
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), insertText),
608
+ kind: cssLanguageTypes_1.CompletionItemKind.Function,
609
+ insertTextFormat: image !== insertText ? SnippetFormat : void 0
610
+ });
611
+ }
612
+ return result;
613
+ }
614
+ getTimingFunctionProposals(entry, existingNode, result) {
615
+ for (const timing in languageFacts.transitionTimingFunctions) {
616
+ const insertText = moveCursorInsideParenthesis(timing);
617
+ result.items.push({
618
+ label: timing,
619
+ documentation: languageFacts.transitionTimingFunctions[timing],
620
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), insertText),
621
+ kind: cssLanguageTypes_1.CompletionItemKind.Function,
622
+ insertTextFormat: timing !== insertText ? SnippetFormat : void 0
623
+ });
624
+ }
625
+ return result;
626
+ }
627
+ getBasicShapeProposals(entry, existingNode, result) {
628
+ for (const shape in languageFacts.basicShapeFunctions) {
629
+ const insertText = moveCursorInsideParenthesis(shape);
630
+ result.items.push({
631
+ label: shape,
632
+ documentation: languageFacts.basicShapeFunctions[shape],
633
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), insertText),
634
+ kind: cssLanguageTypes_1.CompletionItemKind.Function,
635
+ insertTextFormat: shape !== insertText ? SnippetFormat : void 0
636
+ });
637
+ }
638
+ return result;
639
+ }
640
+ getCompletionsForStylesheet(result) {
641
+ const node = this.styleSheet.findFirstChildBeforeOffset(this.offset);
642
+ if (!node) {
643
+ return this.getCompletionForTopLevel(result);
644
+ }
645
+ if (node instanceof nodes.RuleSet) {
646
+ return this.getCompletionsForRuleSet(node, result);
647
+ }
648
+ if (node instanceof nodes.Supports) {
649
+ return this.getCompletionsForSupports(node, result);
650
+ }
651
+ return result;
652
+ }
653
+ getCompletionForTopLevel(result) {
654
+ this.cssDataManager.getAtDirectives().forEach(entry => {
655
+ result.items.push({
656
+ label: entry.name,
657
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(null), entry.name),
658
+ documentation: languageFacts.getEntryDescription(entry, this.doesSupportMarkdown()),
659
+ tags: isDeprecated(entry) ? [cssLanguageTypes_1.CompletionItemTag.Deprecated] : [],
660
+ kind: cssLanguageTypes_1.CompletionItemKind.Keyword
661
+ });
662
+ });
663
+ this.getCompletionsForSelector(null, false, result);
664
+ return result;
665
+ }
666
+ getCompletionsForRuleSet(ruleSet, result) {
667
+ const declarations = ruleSet.getDeclarations();
668
+ const isAfter = declarations && declarations.endsWith('}') && this.offset >= declarations.end;
669
+ if (isAfter) {
670
+ return this.getCompletionForTopLevel(result);
671
+ }
672
+ const isInSelectors = !declarations || this.offset <= declarations.offset;
673
+ if (isInSelectors) {
674
+ return this.getCompletionsForSelector(ruleSet, ruleSet.isNested(), result);
675
+ }
676
+ return this.getCompletionsForDeclarations(ruleSet.getDeclarations(), result);
677
+ }
678
+ getCompletionsForSelector(ruleSet, isNested, result) {
679
+ const existingNode = this.findInNodePath(nodes.NodeType.PseudoSelector, nodes.NodeType.IdentifierSelector, nodes.NodeType.ClassSelector, nodes.NodeType.ElementNameSelector);
680
+ if (!existingNode && this.hasCharacterAtPosition(this.offset - this.currentWord.length - 1, ':')) {
681
+ // after the ':' of a pseudo selector, no node generated for just ':'
682
+ this.currentWord = ':' + this.currentWord;
683
+ if (this.hasCharacterAtPosition(this.offset - this.currentWord.length - 1, ':')) {
684
+ this.currentWord = ':' + this.currentWord; // for '::'
685
+ }
686
+ this.defaultReplaceRange = cssLanguageTypes_1.Range.create(cssLanguageTypes_1.Position.create(this.position.line, this.position.character - this.currentWord.length), this.position);
687
+ }
688
+ const pseudoClasses = this.cssDataManager.getPseudoClasses();
689
+ pseudoClasses.forEach(entry => {
690
+ const insertText = moveCursorInsideParenthesis(entry.name);
691
+ const item = {
692
+ label: entry.name,
693
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), insertText),
694
+ documentation: languageFacts.getEntryDescription(entry, this.doesSupportMarkdown()),
695
+ tags: isDeprecated(entry) ? [cssLanguageTypes_1.CompletionItemTag.Deprecated] : [],
696
+ kind: cssLanguageTypes_1.CompletionItemKind.Function,
697
+ insertTextFormat: entry.name !== insertText ? SnippetFormat : void 0
698
+ };
699
+ if (strings.startsWith(entry.name, ':-')) {
700
+ item.sortText = SortTexts.VendorPrefixed;
701
+ }
702
+ result.items.push(item);
703
+ });
704
+ const pseudoElements = this.cssDataManager.getPseudoElements();
705
+ pseudoElements.forEach(entry => {
706
+ const insertText = moveCursorInsideParenthesis(entry.name);
707
+ const item = {
708
+ label: entry.name,
709
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), insertText),
710
+ documentation: languageFacts.getEntryDescription(entry, this.doesSupportMarkdown()),
711
+ tags: isDeprecated(entry) ? [cssLanguageTypes_1.CompletionItemTag.Deprecated] : [],
712
+ kind: cssLanguageTypes_1.CompletionItemKind.Function,
713
+ insertTextFormat: entry.name !== insertText ? SnippetFormat : void 0
714
+ };
715
+ if (strings.startsWith(entry.name, '::-')) {
716
+ item.sortText = SortTexts.VendorPrefixed;
717
+ }
718
+ result.items.push(item);
719
+ });
720
+ if (!isNested) { // show html tags only for top level
721
+ for (const entry of languageFacts.html5Tags) {
722
+ result.items.push({
723
+ label: entry,
724
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), entry),
725
+ kind: cssLanguageTypes_1.CompletionItemKind.Keyword
726
+ });
727
+ }
728
+ for (const entry of languageFacts.svgElements) {
729
+ result.items.push({
730
+ label: entry,
731
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), entry),
732
+ kind: cssLanguageTypes_1.CompletionItemKind.Keyword
733
+ });
734
+ }
735
+ }
736
+ const visited = {};
737
+ visited[this.currentWord] = true;
738
+ const docText = this.textDocument.getText();
739
+ this.styleSheet.accept(n => {
740
+ if (n.type === nodes.NodeType.SimpleSelector && n.length > 0) {
741
+ const selector = docText.substr(n.offset, n.length);
742
+ if (selector.charAt(0) === '.' && !visited[selector]) {
743
+ visited[selector] = true;
744
+ result.items.push({
745
+ label: selector,
746
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), selector),
747
+ kind: cssLanguageTypes_1.CompletionItemKind.Keyword
748
+ });
749
+ }
750
+ return false;
751
+ }
752
+ return true;
753
+ });
754
+ if (ruleSet && ruleSet.isNested()) {
755
+ const selector = ruleSet.getSelectors().findFirstChildBeforeOffset(this.offset);
756
+ if (selector && ruleSet.getSelectors().getChildren().indexOf(selector) === 0) {
757
+ this.getPropertyProposals(null, result);
758
+ }
759
+ }
760
+ return result;
761
+ }
762
+ getCompletionsForDeclarations(declarations, result) {
763
+ if (!declarations || this.offset === declarations.offset) { // incomplete nodes
764
+ return result;
765
+ }
766
+ const node = declarations.findFirstChildBeforeOffset(this.offset);
767
+ if (!node) {
768
+ return this.getCompletionsForDeclarationProperty(null, result);
769
+ }
770
+ if (node instanceof nodes.AbstractDeclaration) {
771
+ const declaration = node;
772
+ if (!(0, objects_1.isDefined)(declaration.colonPosition) || this.offset <= declaration.colonPosition) {
773
+ // complete property
774
+ return this.getCompletionsForDeclarationProperty(declaration, result);
775
+ }
776
+ else if (((0, objects_1.isDefined)(declaration.semicolonPosition) && declaration.semicolonPosition < this.offset)) {
777
+ if (this.offset === declaration.semicolonPosition + 1) {
778
+ return result; // don't show new properties right after semicolon (see Bug 15421:[intellisense] [css] Be less aggressive when manually typing CSS)
779
+ }
780
+ // complete next property
781
+ return this.getCompletionsForDeclarationProperty(null, result);
782
+ }
783
+ if (declaration instanceof nodes.Declaration) {
784
+ // complete value
785
+ return this.getCompletionsForDeclarationValue(declaration, result);
786
+ }
787
+ }
788
+ else if (node instanceof nodes.ExtendsReference) {
789
+ this.getCompletionsForExtendsReference(node, null, result);
790
+ }
791
+ else if (this.currentWord && this.currentWord[0] === '@') {
792
+ this.getCompletionsForDeclarationProperty(null, result);
793
+ }
794
+ else if (node instanceof nodes.RuleSet) {
795
+ this.getCompletionsForDeclarationProperty(null, result);
796
+ }
797
+ return result;
798
+ }
799
+ getCompletionsForVariableDeclaration(declaration, result) {
800
+ if (this.offset && (0, objects_1.isDefined)(declaration.colonPosition) && this.offset > declaration.colonPosition) {
801
+ this.getVariableProposals(declaration.getValue(), result);
802
+ }
803
+ return result;
804
+ }
805
+ getCompletionsForExpression(expression, result) {
806
+ const parent = expression.getParent();
807
+ if (parent instanceof nodes.FunctionArgument) {
808
+ this.getCompletionsForFunctionArgument(parent, parent.getParent(), result);
809
+ return result;
810
+ }
811
+ const declaration = expression.findParent(nodes.NodeType.Declaration);
812
+ if (!declaration) {
813
+ this.getTermProposals(undefined, null, result);
814
+ return result;
815
+ }
816
+ const node = expression.findChildAtOffset(this.offset, true);
817
+ if (!node) {
818
+ return this.getCompletionsForDeclarationValue(declaration, result);
819
+ }
820
+ if (node instanceof nodes.NumericValue || node instanceof nodes.Identifier) {
821
+ return this.getCompletionsForDeclarationValue(declaration, result);
822
+ }
823
+ return result;
824
+ }
825
+ getCompletionsForFunctionArgument(arg, func, result) {
826
+ const identifier = func.getIdentifier();
827
+ if (identifier && identifier.matches('var')) {
828
+ if (!func.getArguments().hasChildren() || func.getArguments().getChild(0) === arg) {
829
+ this.getVariableProposalsForCSSVarFunction(result);
830
+ }
831
+ }
832
+ return result;
833
+ }
834
+ getCompletionsForFunctionDeclaration(decl, result) {
835
+ const declarations = decl.getDeclarations();
836
+ if (declarations && this.offset > declarations.offset && this.offset < declarations.end) {
837
+ this.getTermProposals(undefined, null, result);
838
+ }
839
+ return result;
840
+ }
841
+ getCompletionsForMixinReference(ref, result) {
842
+ const allMixins = this.getSymbolContext().findSymbolsAtOffset(this.offset, nodes.ReferenceType.Mixin);
843
+ for (const mixinSymbol of allMixins) {
844
+ if (mixinSymbol.node instanceof nodes.MixinDeclaration) {
845
+ result.items.push(this.makeTermProposal(mixinSymbol, mixinSymbol.node.getParameters(), null));
846
+ }
847
+ }
848
+ const identifierNode = ref.getIdentifier() || null;
849
+ this.completionParticipants.forEach(participant => {
850
+ if (participant.onCssMixinReference) {
851
+ participant.onCssMixinReference({
852
+ mixinName: this.currentWord,
853
+ range: this.getCompletionRange(identifierNode)
854
+ });
855
+ }
856
+ });
857
+ return result;
858
+ }
859
+ getTermProposals(entry, existingNode, result) {
860
+ const allFunctions = this.getSymbolContext().findSymbolsAtOffset(this.offset, nodes.ReferenceType.Function);
861
+ for (const functionSymbol of allFunctions) {
862
+ if (functionSymbol.node instanceof nodes.FunctionDeclaration) {
863
+ result.items.push(this.makeTermProposal(functionSymbol, functionSymbol.node.getParameters(), existingNode));
864
+ }
865
+ }
866
+ return result;
867
+ }
868
+ makeTermProposal(symbol, parameters, existingNode) {
869
+ const decl = symbol.node;
870
+ const params = parameters.getChildren().map((c) => {
871
+ return (c instanceof nodes.FunctionParameter) ? c.getName() : c.getText();
872
+ });
873
+ const insertText = symbol.name + '(' + params.map((p, index) => '${' + (index + 1) + ':' + p + '}').join(', ') + ')';
874
+ return {
875
+ label: symbol.name,
876
+ detail: symbol.name + '(' + params.join(', ') + ')',
877
+ textEdit: cssLanguageTypes_1.TextEdit.replace(this.getCompletionRange(existingNode), insertText),
878
+ insertTextFormat: SnippetFormat,
879
+ kind: cssLanguageTypes_1.CompletionItemKind.Function,
880
+ sortText: SortTexts.Term
881
+ };
882
+ }
883
+ getCompletionsForSupportsCondition(supportsCondition, result) {
884
+ const child = supportsCondition.findFirstChildBeforeOffset(this.offset);
885
+ if (child) {
886
+ if (child instanceof nodes.Declaration) {
887
+ if (!(0, objects_1.isDefined)(child.colonPosition) || this.offset <= child.colonPosition) {
888
+ return this.getCompletionsForDeclarationProperty(child, result);
889
+ }
890
+ else {
891
+ return this.getCompletionsForDeclarationValue(child, result);
892
+ }
893
+ }
894
+ else if (child instanceof nodes.SupportsCondition) {
895
+ return this.getCompletionsForSupportsCondition(child, result);
896
+ }
897
+ }
898
+ if ((0, objects_1.isDefined)(supportsCondition.lParent) && this.offset > supportsCondition.lParent && (!(0, objects_1.isDefined)(supportsCondition.rParent) || this.offset <= supportsCondition.rParent)) {
899
+ return this.getCompletionsForDeclarationProperty(null, result);
900
+ }
901
+ return result;
902
+ }
903
+ getCompletionsForSupports(supports, result) {
904
+ const declarations = supports.getDeclarations();
905
+ const inInCondition = !declarations || this.offset <= declarations.offset;
906
+ if (inInCondition) {
907
+ const child = supports.findFirstChildBeforeOffset(this.offset);
908
+ if (child instanceof nodes.SupportsCondition) {
909
+ return this.getCompletionsForSupportsCondition(child, result);
910
+ }
911
+ return result;
912
+ }
913
+ return this.getCompletionForTopLevel(result);
914
+ }
915
+ getCompletionsForExtendsReference(extendsRef, existingNode, result) {
916
+ return result;
917
+ }
918
+ getCompletionForUriLiteralValue(uriLiteralNode, result) {
919
+ let uriValue;
920
+ let position;
921
+ let range;
922
+ // No children, empty value
923
+ if (!uriLiteralNode.hasChildren()) {
924
+ uriValue = '';
925
+ position = this.position;
926
+ const emptyURIValuePosition = this.textDocument.positionAt(uriLiteralNode.offset + 'url('.length);
927
+ range = cssLanguageTypes_1.Range.create(emptyURIValuePosition, emptyURIValuePosition);
928
+ }
929
+ else {
930
+ const uriValueNode = uriLiteralNode.getChild(0);
931
+ uriValue = uriValueNode.getText();
932
+ position = this.position;
933
+ range = this.getCompletionRange(uriValueNode);
934
+ }
935
+ this.completionParticipants.forEach(participant => {
936
+ if (participant.onCssURILiteralValue) {
937
+ participant.onCssURILiteralValue({
938
+ uriValue,
939
+ position,
940
+ range
941
+ });
942
+ }
943
+ });
944
+ return result;
945
+ }
946
+ getCompletionForImportPath(importPathNode, result) {
947
+ this.completionParticipants.forEach(participant => {
948
+ if (participant.onCssImportPath) {
949
+ participant.onCssImportPath({
950
+ pathValue: importPathNode.getText(),
951
+ position: this.position,
952
+ range: this.getCompletionRange(importPathNode)
953
+ });
954
+ }
955
+ });
956
+ return result;
957
+ }
958
+ hasCharacterAtPosition(offset, char) {
959
+ const text = this.textDocument.getText();
960
+ return (offset >= 0 && offset < text.length) && text.charAt(offset) === char;
961
+ }
962
+ doesSupportMarkdown() {
963
+ if (!(0, objects_1.isDefined)(this.supportsMarkdown)) {
964
+ if (!(0, objects_1.isDefined)(this.lsOptions.clientCapabilities)) {
965
+ this.supportsMarkdown = true;
966
+ return this.supportsMarkdown;
967
+ }
968
+ const documentationFormat = this.lsOptions.clientCapabilities.textDocument?.completion?.completionItem?.documentationFormat;
969
+ this.supportsMarkdown = Array.isArray(documentationFormat) && documentationFormat.indexOf(cssLanguageTypes_1.MarkupKind.Markdown) !== -1;
970
+ }
971
+ return this.supportsMarkdown;
972
+ }
973
+ }
974
+ exports.CSSCompletion = CSSCompletion;
975
+ function isDeprecated(entry) {
976
+ if (entry.status && (entry.status === 'nonstandard' || entry.status === 'obsolete')) {
977
+ return true;
978
+ }
979
+ return false;
980
+ }
981
+ class Set {
982
+ constructor() {
983
+ this.entries = {};
984
+ }
985
+ add(entry) {
986
+ this.entries[entry] = true;
987
+ }
988
+ remove(entry) {
989
+ delete this.entries[entry];
990
+ }
991
+ getEntries() {
992
+ return Object.keys(this.entries);
993
+ }
994
+ }
995
+ function moveCursorInsideParenthesis(text) {
996
+ return text.replace(/\(\)$/, "($1)");
997
+ }
998
+ function collectValues(styleSheet, declaration) {
999
+ const fullPropertyName = declaration.getFullPropertyName();
1000
+ const entries = new Set();
1001
+ function visitValue(node) {
1002
+ if (node instanceof nodes.Identifier || node instanceof nodes.NumericValue || node instanceof nodes.HexColorValue) {
1003
+ entries.add(node.getText());
1004
+ }
1005
+ return true;
1006
+ }
1007
+ function matchesProperty(decl) {
1008
+ const propertyName = decl.getFullPropertyName();
1009
+ return fullPropertyName === propertyName;
1010
+ }
1011
+ function vistNode(node) {
1012
+ if (node instanceof nodes.Declaration && node !== declaration) {
1013
+ if (matchesProperty(node)) {
1014
+ const value = node.getValue();
1015
+ if (value) {
1016
+ value.accept(visitValue);
1017
+ }
1018
+ }
1019
+ }
1020
+ return true;
1021
+ }
1022
+ styleSheet.accept(vistNode);
1023
+ return entries;
1024
+ }
1025
+ class ColorValueCollector {
1026
+ constructor(entries, currentOffset) {
1027
+ this.entries = entries;
1028
+ this.currentOffset = currentOffset;
1029
+ // nothing to do
1030
+ }
1031
+ visitNode(node) {
1032
+ if (node instanceof nodes.HexColorValue || (node instanceof nodes.Function && languageFacts.isColorConstructor(node))) {
1033
+ if (this.currentOffset < node.offset || node.end < this.currentOffset) {
1034
+ this.entries.add(node.getText());
1035
+ }
1036
+ }
1037
+ return true;
1038
+ }
1039
+ }
1040
+ class VariableCollector {
1041
+ constructor(entries, currentOffset) {
1042
+ this.entries = entries;
1043
+ this.currentOffset = currentOffset;
1044
+ // nothing to do
1045
+ }
1046
+ visitNode(node) {
1047
+ if (node instanceof nodes.Identifier && node.isCustomProperty) {
1048
+ if (this.currentOffset < node.offset || node.end < this.currentOffset) {
1049
+ this.entries.add(node.getText());
1050
+ }
1051
+ }
1052
+ return true;
1053
+ }
1054
+ }
1055
+ function getCurrentWord(document, offset) {
1056
+ let i = offset - 1;
1057
+ const text = document.getText();
1058
+ while (i >= 0 && ' \t\n\r":{[()]},*>+'.indexOf(text.charAt(i)) === -1) {
1059
+ i--;
1060
+ }
1061
+ return text.substring(i + 1, offset);
1062
+ }
1063
+ function isColorString(s) {
1064
+ // From https://stackoverflow.com/questions/8027423/how-to-check-if-a-string-is-a-valid-hex-color-representation/8027444
1065
+ return (s.toLowerCase() in languageFacts.colors) || /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(s);
1066
+ }
1067
+ });