vscode-css-languageservice 5.4.2 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -1
- package/SECURITY.md +41 -0
- package/lib/esm/beautify/beautify-css.js +11 -4
- package/lib/esm/cssLanguageService.d.ts +2 -1
- package/lib/esm/cssLanguageService.js +15 -17
- package/lib/esm/cssLanguageTypes.js +2 -2
- package/lib/esm/data/webCustomData.js +356 -232
- package/lib/esm/languageFacts/builtinData.js +15 -15
- package/lib/esm/languageFacts/colors.js +66 -69
- package/lib/esm/languageFacts/dataManager.js +38 -42
- package/lib/esm/languageFacts/dataProvider.js +17 -23
- package/lib/esm/languageFacts/entry.js +22 -23
- package/lib/esm/parser/cssErrors.js +5 -7
- package/lib/esm/parser/cssNodes.js +869 -1377
- package/lib/esm/parser/cssParser.js +419 -376
- package/lib/esm/parser/cssScanner.js +168 -175
- package/lib/esm/parser/cssSymbolScope.js +107 -137
- package/lib/esm/parser/lessParser.js +177 -202
- package/lib/esm/parser/lessScanner.js +22 -43
- package/lib/esm/parser/scssErrors.js +5 -7
- package/lib/esm/parser/scssParser.js +196 -208
- package/lib/esm/parser/scssScanner.js +33 -54
- package/lib/esm/services/cssCodeActions.js +36 -40
- package/lib/esm/services/cssCompletion.js +300 -395
- package/lib/esm/services/cssFolding.js +32 -35
- package/lib/esm/services/cssFormatter.js +22 -22
- package/lib/esm/services/cssHover.js +30 -33
- package/lib/esm/services/cssNavigation.js +260 -289
- package/lib/esm/services/cssSelectionRange.js +6 -6
- package/lib/esm/services/cssValidation.js +13 -16
- package/lib/esm/services/lessCompletion.js +351 -370
- package/lib/esm/services/lint.js +161 -175
- package/lib/esm/services/lintRules.js +20 -27
- package/lib/esm/services/lintUtil.js +19 -28
- package/lib/esm/services/pathCompletion.js +84 -158
- package/lib/esm/services/scssCompletion.js +283 -307
- package/lib/esm/services/scssNavigation.js +65 -137
- package/lib/esm/services/selectorPrinting.js +131 -175
- package/lib/esm/utils/arrays.js +6 -12
- package/lib/esm/utils/objects.js +1 -1
- package/lib/esm/utils/resources.js +3 -16
- package/lib/esm/utils/strings.js +10 -12
- package/lib/umd/beautify/beautify-css.js +11 -4
- package/lib/umd/cssLanguageService.d.ts +2 -1
- package/lib/umd/cssLanguageService.js +34 -32
- package/lib/umd/cssLanguageTypes.js +4 -3
- package/lib/umd/data/webCustomData.js +355 -231
- package/lib/umd/languageFacts/colors.js +65 -68
- package/lib/umd/languageFacts/dataManager.js +41 -44
- package/lib/umd/languageFacts/dataProvider.js +17 -22
- package/lib/umd/languageFacts/entry.js +22 -23
- package/lib/umd/languageFacts/facts.js +5 -1
- package/lib/umd/parser/cssErrors.js +5 -6
- package/lib/umd/parser/cssNodes.js +870 -1307
- package/lib/umd/parser/cssParser.js +424 -380
- package/lib/umd/parser/cssScanner.js +168 -173
- package/lib/umd/parser/cssSymbolScope.js +109 -134
- package/lib/umd/parser/lessParser.js +182 -206
- package/lib/umd/parser/lessScanner.js +22 -42
- package/lib/umd/parser/scssErrors.js +5 -6
- package/lib/umd/parser/scssParser.js +202 -213
- package/lib/umd/parser/scssScanner.js +25 -45
- package/lib/umd/services/cssCodeActions.js +41 -44
- package/lib/umd/services/cssCompletion.js +308 -402
- package/lib/umd/services/cssFolding.js +35 -38
- package/lib/umd/services/cssFormatter.js +25 -25
- package/lib/umd/services/cssHover.js +36 -38
- package/lib/umd/services/cssNavigation.js +267 -295
- package/lib/umd/services/cssSelectionRange.js +8 -8
- package/lib/umd/services/cssValidation.js +17 -19
- package/lib/umd/services/lessCompletion.js +354 -372
- package/lib/umd/services/lint.js +167 -180
- package/lib/umd/services/lintRules.js +20 -24
- package/lib/umd/services/lintUtil.js +20 -28
- package/lib/umd/services/pathCompletion.js +87 -160
- package/lib/umd/services/scssCompletion.js +287 -310
- package/lib/umd/services/scssNavigation.js +69 -140
- package/lib/umd/services/selectorPrinting.js +134 -174
- package/lib/umd/utils/arrays.js +6 -12
- package/lib/umd/utils/objects.js +1 -1
- package/lib/umd/utils/resources.js +4 -17
- package/lib/umd/utils/strings.js +10 -12
- package/package.json +16 -15
|
@@ -14,31 +14,29 @@
|
|
|
14
14
|
'use strict';
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
16
|
exports.LintConfigurationSettings = exports.Settings = exports.Rules = exports.Setting = exports.Rule = void 0;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
const nodes = require("../parser/cssNodes");
|
|
18
|
+
const nls = require("vscode-nls");
|
|
19
|
+
const localize = nls.loadMessageBundle();
|
|
20
|
+
const Warning = nodes.Level.Warning;
|
|
21
|
+
const Error = nodes.Level.Error;
|
|
22
|
+
const Ignore = nodes.Level.Ignore;
|
|
23
|
+
class Rule {
|
|
24
|
+
constructor(id, message, defaultValue) {
|
|
25
25
|
this.id = id;
|
|
26
26
|
this.message = message;
|
|
27
27
|
this.defaultValue = defaultValue;
|
|
28
28
|
// nothing to do
|
|
29
29
|
}
|
|
30
|
-
|
|
31
|
-
}());
|
|
30
|
+
}
|
|
32
31
|
exports.Rule = Rule;
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
class Setting {
|
|
33
|
+
constructor(id, message, defaultValue) {
|
|
35
34
|
this.id = id;
|
|
36
35
|
this.message = message;
|
|
37
36
|
this.defaultValue = defaultValue;
|
|
38
37
|
// nothing to do
|
|
39
38
|
}
|
|
40
|
-
|
|
41
|
-
}());
|
|
39
|
+
}
|
|
42
40
|
exports.Setting = Setting;
|
|
43
41
|
exports.Rules = {
|
|
44
42
|
AllVendorPrefixes: new Rule('compatibleVendorPrefixes', localize('rule.vendorprefixes.all', "When using a vendor-specific prefix make sure to also include all other vendor-specific properties"), Ignore),
|
|
@@ -64,25 +62,23 @@
|
|
|
64
62
|
exports.Settings = {
|
|
65
63
|
ValidProperties: new Setting('validProperties', localize('rule.validProperties', "A list of properties that are not validated against the `unknownProperties` rule."), [])
|
|
66
64
|
};
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (conf === void 0) { conf = {}; }
|
|
65
|
+
class LintConfigurationSettings {
|
|
66
|
+
constructor(conf = {}) {
|
|
70
67
|
this.conf = conf;
|
|
71
68
|
}
|
|
72
|
-
|
|
69
|
+
getRule(rule) {
|
|
73
70
|
if (this.conf.hasOwnProperty(rule.id)) {
|
|
74
|
-
|
|
71
|
+
const level = toLevel(this.conf[rule.id]);
|
|
75
72
|
if (level) {
|
|
76
73
|
return level;
|
|
77
74
|
}
|
|
78
75
|
}
|
|
79
76
|
return rule.defaultValue;
|
|
80
|
-
}
|
|
81
|
-
|
|
77
|
+
}
|
|
78
|
+
getSetting(setting) {
|
|
82
79
|
return this.conf[setting.id];
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
}());
|
|
80
|
+
}
|
|
81
|
+
}
|
|
86
82
|
exports.LintConfigurationSettings = LintConfigurationSettings;
|
|
87
83
|
function toLevel(level) {
|
|
88
84
|
switch (level) {
|
|
@@ -14,17 +14,16 @@
|
|
|
14
14
|
'use strict';
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
16
|
exports.Element = void 0;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
const arrays_1 = require("../utils/arrays");
|
|
18
|
+
class Element {
|
|
19
|
+
constructor(decl) {
|
|
20
20
|
this.fullPropertyName = decl.getFullPropertyName().toLowerCase();
|
|
21
21
|
this.node = decl;
|
|
22
22
|
}
|
|
23
|
-
|
|
24
|
-
}());
|
|
23
|
+
}
|
|
25
24
|
exports.Element = Element;
|
|
26
25
|
function setSide(model, side, value, property) {
|
|
27
|
-
|
|
26
|
+
const state = model[side];
|
|
28
27
|
state.value = value;
|
|
29
28
|
if (value) {
|
|
30
29
|
if (!(0, arrays_1.includes)(state.properties, property)) {
|
|
@@ -73,8 +72,7 @@
|
|
|
73
72
|
}
|
|
74
73
|
}
|
|
75
74
|
function matches(value, candidates) {
|
|
76
|
-
for (
|
|
77
|
-
var candidate = candidates_1[_i];
|
|
75
|
+
for (let candidate of candidates) {
|
|
78
76
|
if (value.matches(candidate)) {
|
|
79
77
|
return true;
|
|
80
78
|
}
|
|
@@ -85,8 +83,7 @@
|
|
|
85
83
|
* @param allowsKeywords whether the initial value of property is zero, so keywords `initial` and `unset` count as zero
|
|
86
84
|
* @return `true` if this node represents a non-zero border; otherwise, `false`
|
|
87
85
|
*/
|
|
88
|
-
function checkLineWidth(value, allowsKeywords) {
|
|
89
|
-
if (allowsKeywords === void 0) { allowsKeywords = true; }
|
|
86
|
+
function checkLineWidth(value, allowsKeywords = true) {
|
|
90
87
|
if (allowsKeywords && matches(value, ['initial', 'unset'])) {
|
|
91
88
|
return false;
|
|
92
89
|
}
|
|
@@ -94,16 +91,14 @@
|
|
|
94
91
|
// so use `parseFloat` to strip the unit
|
|
95
92
|
return parseFloat(value.getText()) !== 0;
|
|
96
93
|
}
|
|
97
|
-
function checkLineWidthList(nodes, allowsKeywords) {
|
|
98
|
-
|
|
99
|
-
return nodes.map(function (node) { return checkLineWidth(node, allowsKeywords); });
|
|
94
|
+
function checkLineWidthList(nodes, allowsKeywords = true) {
|
|
95
|
+
return nodes.map(node => checkLineWidth(node, allowsKeywords));
|
|
100
96
|
}
|
|
101
97
|
/**
|
|
102
98
|
* @param allowsKeywords whether keywords `initial` and `unset` count as zero
|
|
103
99
|
* @return `true` if this node represents a non-zero border; otherwise, `false`
|
|
104
100
|
*/
|
|
105
|
-
function checkLineStyle(valueNode, allowsKeywords) {
|
|
106
|
-
if (allowsKeywords === void 0) { allowsKeywords = true; }
|
|
101
|
+
function checkLineStyle(valueNode, allowsKeywords = true) {
|
|
107
102
|
if (matches(valueNode, ['none', 'hidden'])) {
|
|
108
103
|
return false;
|
|
109
104
|
}
|
|
@@ -112,23 +107,21 @@
|
|
|
112
107
|
}
|
|
113
108
|
return true;
|
|
114
109
|
}
|
|
115
|
-
function checkLineStyleList(nodes, allowsKeywords) {
|
|
116
|
-
|
|
117
|
-
return nodes.map(function (node) { return checkLineStyle(node, allowsKeywords); });
|
|
110
|
+
function checkLineStyleList(nodes, allowsKeywords = true) {
|
|
111
|
+
return nodes.map(node => checkLineStyle(node, allowsKeywords));
|
|
118
112
|
}
|
|
119
113
|
function checkBorderShorthand(node) {
|
|
120
|
-
|
|
114
|
+
const children = node.getChildren();
|
|
121
115
|
// the only child can be a keyword, a <line-width>, or a <line-style>
|
|
122
116
|
// if either check returns false, the result is no border
|
|
123
117
|
if (children.length === 1) {
|
|
124
|
-
|
|
118
|
+
const value = children[0];
|
|
125
119
|
return checkLineWidth(value) && checkLineStyle(value);
|
|
126
120
|
}
|
|
127
121
|
// multiple children can't contain keywords
|
|
128
122
|
// if any child means no border, the result is no border
|
|
129
|
-
for (
|
|
130
|
-
|
|
131
|
-
var value = child;
|
|
123
|
+
for (const child of children) {
|
|
124
|
+
const value = child;
|
|
132
125
|
if (!checkLineWidth(value, /* allowsKeywords: */ false) ||
|
|
133
126
|
!checkLineStyle(value, /* allowsKeywords: */ false)) {
|
|
134
127
|
return false;
|
|
@@ -137,15 +130,14 @@
|
|
|
137
130
|
return true;
|
|
138
131
|
}
|
|
139
132
|
function calculateBoxModel(propertyTable) {
|
|
140
|
-
|
|
133
|
+
const model = {
|
|
141
134
|
top: { value: false, properties: [] },
|
|
142
135
|
right: { value: false, properties: [] },
|
|
143
136
|
bottom: { value: false, properties: [] },
|
|
144
137
|
left: { value: false, properties: [] },
|
|
145
138
|
};
|
|
146
|
-
for (
|
|
147
|
-
|
|
148
|
-
var value = property.node.value;
|
|
139
|
+
for (const property of propertyTable) {
|
|
140
|
+
const value = property.node.value;
|
|
149
141
|
if (typeof value === 'undefined') {
|
|
150
142
|
continue;
|
|
151
143
|
}
|
|
@@ -165,7 +157,7 @@
|
|
|
165
157
|
model.height = property;
|
|
166
158
|
break;
|
|
167
159
|
default:
|
|
168
|
-
|
|
160
|
+
const segments = property.fullPropertyName.split('-');
|
|
169
161
|
switch (segments[0]) {
|
|
170
162
|
case 'border':
|
|
171
163
|
switch (segments[1]) {
|
|
@@ -2,42 +2,6 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
6
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
7
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
8
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
9
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
10
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
11
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
12
|
-
});
|
|
13
|
-
};
|
|
14
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
15
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
16
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
17
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
18
|
-
function step(op) {
|
|
19
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
20
|
-
while (_) try {
|
|
21
|
-
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;
|
|
22
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
23
|
-
switch (op[0]) {
|
|
24
|
-
case 0: case 1: t = op; break;
|
|
25
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
26
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
27
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
28
|
-
default:
|
|
29
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
30
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
31
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
32
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
33
|
-
if (t[2]) _.ops.pop();
|
|
34
|
-
_.trys.pop(); continue;
|
|
35
|
-
}
|
|
36
|
-
op = body.call(thisArg, _);
|
|
37
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
38
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
5
|
(function (factory) {
|
|
42
6
|
if (typeof module === "object" && typeof module.exports === "object") {
|
|
43
7
|
var v = factory(require, exports);
|
|
@@ -50,134 +14,97 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
50
14
|
"use strict";
|
|
51
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
52
16
|
exports.PathCompletionParticipant = void 0;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
17
|
+
const cssLanguageTypes_1 = require("../cssLanguageTypes");
|
|
18
|
+
const strings_1 = require("../utils/strings");
|
|
19
|
+
const resources_1 = require("../utils/resources");
|
|
20
|
+
class PathCompletionParticipant {
|
|
21
|
+
constructor(readDirectory) {
|
|
58
22
|
this.readDirectory = readDirectory;
|
|
59
23
|
this.literalCompletions = [];
|
|
60
24
|
this.importCompletions = [];
|
|
61
25
|
}
|
|
62
|
-
|
|
26
|
+
onCssURILiteralValue(context) {
|
|
63
27
|
this.literalCompletions.push(context);
|
|
64
|
-
}
|
|
65
|
-
|
|
28
|
+
}
|
|
29
|
+
onCssImportPath(context) {
|
|
66
30
|
this.importCompletions.push(context);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
uriValue = literalCompletion.uriValue;
|
|
81
|
-
fullValue = stripQuotes(uriValue);
|
|
82
|
-
if (!(fullValue === '.' || fullValue === '..')) return [3 /*break*/, 2];
|
|
83
|
-
result.isIncomplete = true;
|
|
84
|
-
return [3 /*break*/, 4];
|
|
85
|
-
case 2: return [4 /*yield*/, this.providePathSuggestions(uriValue, literalCompletion.position, literalCompletion.range, document, documentContext)];
|
|
86
|
-
case 3:
|
|
87
|
-
items = _f.sent();
|
|
88
|
-
for (_b = 0, items_1 = items; _b < items_1.length; _b++) {
|
|
89
|
-
item = items_1[_b];
|
|
90
|
-
result.items.push(item);
|
|
91
|
-
}
|
|
92
|
-
_f.label = 4;
|
|
93
|
-
case 4:
|
|
94
|
-
_i++;
|
|
95
|
-
return [3 /*break*/, 1];
|
|
96
|
-
case 5:
|
|
97
|
-
_c = 0, _d = this.importCompletions;
|
|
98
|
-
_f.label = 6;
|
|
99
|
-
case 6:
|
|
100
|
-
if (!(_c < _d.length)) return [3 /*break*/, 10];
|
|
101
|
-
importCompletion = _d[_c];
|
|
102
|
-
pathValue = importCompletion.pathValue;
|
|
103
|
-
fullValue = stripQuotes(pathValue);
|
|
104
|
-
if (!(fullValue === '.' || fullValue === '..')) return [3 /*break*/, 7];
|
|
105
|
-
result.isIncomplete = true;
|
|
106
|
-
return [3 /*break*/, 9];
|
|
107
|
-
case 7: return [4 /*yield*/, this.providePathSuggestions(pathValue, importCompletion.position, importCompletion.range, document, documentContext)];
|
|
108
|
-
case 8:
|
|
109
|
-
suggestions = _f.sent();
|
|
110
|
-
if (document.languageId === 'scss') {
|
|
111
|
-
suggestions.forEach(function (s) {
|
|
112
|
-
if ((0, strings_1.startsWith)(s.label, '_') && (0, strings_1.endsWith)(s.label, '.scss')) {
|
|
113
|
-
if (s.textEdit) {
|
|
114
|
-
s.textEdit.newText = s.label.slice(1, -5);
|
|
115
|
-
}
|
|
116
|
-
else {
|
|
117
|
-
s.label = s.label.slice(1, -5);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
for (_e = 0, suggestions_1 = suggestions; _e < suggestions_1.length; _e++) {
|
|
123
|
-
item = suggestions_1[_e];
|
|
124
|
-
result.items.push(item);
|
|
125
|
-
}
|
|
126
|
-
_f.label = 9;
|
|
127
|
-
case 9:
|
|
128
|
-
_c++;
|
|
129
|
-
return [3 /*break*/, 6];
|
|
130
|
-
case 10: return [2 /*return*/, result];
|
|
31
|
+
}
|
|
32
|
+
async computeCompletions(document, documentContext) {
|
|
33
|
+
const result = { items: [], isIncomplete: false };
|
|
34
|
+
for (const literalCompletion of this.literalCompletions) {
|
|
35
|
+
const uriValue = literalCompletion.uriValue;
|
|
36
|
+
const fullValue = stripQuotes(uriValue);
|
|
37
|
+
if (fullValue === '.' || fullValue === '..') {
|
|
38
|
+
result.isIncomplete = true;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
const items = await this.providePathSuggestions(uriValue, literalCompletion.position, literalCompletion.range, document, documentContext);
|
|
42
|
+
for (let item of items) {
|
|
43
|
+
result.items.push(item);
|
|
131
44
|
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
parentDir = documentContext.resolveReference(valueBeforeLastSlash || '.', currentDocUri);
|
|
151
|
-
if (!parentDir) return [3 /*break*/, 4];
|
|
152
|
-
_b.label = 1;
|
|
153
|
-
case 1:
|
|
154
|
-
_b.trys.push([1, 3, , 4]);
|
|
155
|
-
result = [];
|
|
156
|
-
return [4 /*yield*/, this.readDirectory(parentDir)];
|
|
157
|
-
case 2:
|
|
158
|
-
infos = _b.sent();
|
|
159
|
-
for (_i = 0, infos_1 = infos; _i < infos_1.length; _i++) {
|
|
160
|
-
_a = infos_1[_i], name = _a[0], type = _a[1];
|
|
161
|
-
// Exclude paths that start with `.`
|
|
162
|
-
if (name.charCodeAt(0) !== CharCode_dot && (type === cssLanguageTypes_1.FileType.Directory || (0, resources_1.joinPath)(parentDir, name) !== currentDocUri)) {
|
|
163
|
-
result.push(createCompletionItem(name, type === cssLanguageTypes_1.FileType.Directory, replaceRange));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
for (const importCompletion of this.importCompletions) {
|
|
48
|
+
const pathValue = importCompletion.pathValue;
|
|
49
|
+
const fullValue = stripQuotes(pathValue);
|
|
50
|
+
if (fullValue === '.' || fullValue === '..') {
|
|
51
|
+
result.isIncomplete = true;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
let suggestions = await this.providePathSuggestions(pathValue, importCompletion.position, importCompletion.range, document, documentContext);
|
|
55
|
+
if (document.languageId === 'scss') {
|
|
56
|
+
suggestions.forEach(s => {
|
|
57
|
+
if ((0, strings_1.startsWith)(s.label, '_') && (0, strings_1.endsWith)(s.label, '.scss')) {
|
|
58
|
+
if (s.textEdit) {
|
|
59
|
+
s.textEdit.newText = s.label.slice(1, -5);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
s.label = s.label.slice(1, -5);
|
|
164
63
|
}
|
|
165
64
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
for (let item of suggestions) {
|
|
68
|
+
result.items.push(item);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
async providePathSuggestions(pathValue, position, range, document, documentContext) {
|
|
75
|
+
const fullValue = stripQuotes(pathValue);
|
|
76
|
+
const isValueQuoted = (0, strings_1.startsWith)(pathValue, `'`) || (0, strings_1.startsWith)(pathValue, `"`);
|
|
77
|
+
const valueBeforeCursor = isValueQuoted
|
|
78
|
+
? fullValue.slice(0, position.character - (range.start.character + 1))
|
|
79
|
+
: fullValue.slice(0, position.character - range.start.character);
|
|
80
|
+
const currentDocUri = document.uri;
|
|
81
|
+
const fullValueRange = isValueQuoted ? shiftRange(range, 1, -1) : range;
|
|
82
|
+
const replaceRange = pathToReplaceRange(valueBeforeCursor, fullValue, fullValueRange);
|
|
83
|
+
const valueBeforeLastSlash = valueBeforeCursor.substring(0, valueBeforeCursor.lastIndexOf('/') + 1); // keep the last slash
|
|
84
|
+
let parentDir = documentContext.resolveReference(valueBeforeLastSlash || '.', currentDocUri);
|
|
85
|
+
if (parentDir) {
|
|
86
|
+
try {
|
|
87
|
+
const result = [];
|
|
88
|
+
const infos = await this.readDirectory(parentDir);
|
|
89
|
+
for (const [name, type] of infos) {
|
|
90
|
+
// Exclude paths that start with `.`
|
|
91
|
+
if (name.charCodeAt(0) !== CharCode_dot && (type === cssLanguageTypes_1.FileType.Directory || (0, resources_1.joinPath)(parentDir, name) !== currentDocUri)) {
|
|
92
|
+
result.push(createCompletionItem(name, type === cssLanguageTypes_1.FileType.Directory, replaceRange));
|
|
93
|
+
}
|
|
171
94
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
catch (e) {
|
|
98
|
+
// ignore
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return [];
|
|
102
|
+
}
|
|
103
|
+
}
|
|
177
104
|
exports.PathCompletionParticipant = PathCompletionParticipant;
|
|
178
|
-
|
|
105
|
+
const CharCode_dot = '.'.charCodeAt(0);
|
|
179
106
|
function stripQuotes(fullValue) {
|
|
180
|
-
if ((0, strings_1.startsWith)(fullValue,
|
|
107
|
+
if ((0, strings_1.startsWith)(fullValue, `'`) || (0, strings_1.startsWith)(fullValue, `"`)) {
|
|
181
108
|
return fullValue.slice(1, -1);
|
|
182
109
|
}
|
|
183
110
|
else {
|
|
@@ -185,19 +112,19 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
185
112
|
}
|
|
186
113
|
}
|
|
187
114
|
function pathToReplaceRange(valueBeforeCursor, fullValue, fullValueRange) {
|
|
188
|
-
|
|
189
|
-
|
|
115
|
+
let replaceRange;
|
|
116
|
+
const lastIndexOfSlash = valueBeforeCursor.lastIndexOf('/');
|
|
190
117
|
if (lastIndexOfSlash === -1) {
|
|
191
118
|
replaceRange = fullValueRange;
|
|
192
119
|
}
|
|
193
120
|
else {
|
|
194
121
|
// For cases where cursor is in the middle of attribute value, like <script src="./s|rc/test.js">
|
|
195
122
|
// Find the last slash before cursor, and calculate the start of replace range from there
|
|
196
|
-
|
|
197
|
-
|
|
123
|
+
const valueAfterLastSlash = fullValue.slice(lastIndexOfSlash + 1);
|
|
124
|
+
const startPos = shiftPosition(fullValueRange.end, -valueAfterLastSlash.length);
|
|
198
125
|
// If whitespace exists, replace until it
|
|
199
|
-
|
|
200
|
-
|
|
126
|
+
const whitespaceIndex = valueAfterLastSlash.indexOf(' ');
|
|
127
|
+
let endPos;
|
|
201
128
|
if (whitespaceIndex !== -1) {
|
|
202
129
|
endPos = shiftPosition(startPos, whitespaceIndex);
|
|
203
130
|
}
|
|
@@ -237,8 +164,8 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
237
164
|
return cssLanguageTypes_1.Position.create(pos.line, pos.character + offset);
|
|
238
165
|
}
|
|
239
166
|
function shiftRange(range, startOffset, endOffset) {
|
|
240
|
-
|
|
241
|
-
|
|
167
|
+
const start = shiftPosition(range.start, startOffset);
|
|
168
|
+
const end = shiftPosition(range.end, endOffset);
|
|
242
169
|
return cssLanguageTypes_1.Range.create(start, end);
|
|
243
170
|
}
|
|
244
171
|
});
|