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