@master/css-language-service 2.0.0-rc.2 → 2.0.0-rc.21
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/dist/constant.cjs +3064 -0
- package/dist/constant.mjs +3055 -0
- package/dist/index.cjs +21 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.mjs +5 -0
- package/dist/position-check.cjs +37 -0
- package/dist/position-check.d.ts +5 -18
- package/dist/position-check.mjs +35 -0
- package/dist/providers/color.cjs +319 -0
- package/dist/providers/color.mjs +315 -0
- package/dist/providers/completion.cjs +289 -0
- package/dist/providers/completion.mjs +283 -0
- package/dist/providers/hover.cjs +65 -0
- package/dist/providers/hover.mjs +63 -0
- package/dist/settings.cjs +37 -0
- package/dist/settings.mjs +35 -0
- package/dist/utils/get-css-entry-markdown-description.cjs +77 -0
- package/dist/utils/get-css-entry-markdown-description.mjs +75 -0
- package/dist/utils/hex-to-rgb.cjs +13 -0
- package/dist/utils/hex-to-rgb.mjs +11 -0
- package/dist/utils/oklab-to-rgb.cjs +33 -0
- package/dist/utils/oklab-to-rgb.mjs +31 -0
- package/dist/utils/oklch-to-oklab.cjs +11 -0
- package/dist/utils/oklch-to-oklab.mjs +9 -0
- package/dist/utils/regex.cjs +5 -0
- package/dist/utils/regex.mjs +3 -0
- package/dist/utils/to-two-digit-hex.cjs +8 -0
- package/dist/utils/to-two-digit-hex.mjs +6 -0
- package/package.json +1 -1
- package/dist/index.bundle.js +0 -33
- package/dist/settings.bundle.js +0 -1
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { MasterCSS } from '@master/css';
|
|
2
|
+
import { hexToRgb } from '../utils/hex-to-rgb.mjs';
|
|
3
|
+
import { instancePattern } from '../utils/regex.mjs';
|
|
4
|
+
import { toTwoDigitHex } from '../utils/to-two-digit-hex.mjs';
|
|
5
|
+
import { hsl, hwb, lch, lab, cmyk, rgb } from 'color-convert';
|
|
6
|
+
import { oklabToRgb } from '../utils/oklab-to-rgb.mjs';
|
|
7
|
+
import { oklchToOklab } from '../utils/oklch-to-oklab.mjs';
|
|
8
|
+
|
|
9
|
+
async function getDocumentColors(text, css = new MasterCSS()) {
|
|
10
|
+
const colors = [];
|
|
11
|
+
let instanceMatch;
|
|
12
|
+
while((instanceMatch = instancePattern.exec(text)) !== null){
|
|
13
|
+
const instanceStartIndex = instanceMatch.index;
|
|
14
|
+
// todo: refactor theme
|
|
15
|
+
// const theme = css.themeNames.find(x => instanceMatch?.[0]?.endsWith(`@${x}`)) ?? ''
|
|
16
|
+
const theme = '';
|
|
17
|
+
const colorPattern = /(?<=[|:\s"'`]|^)(?:#?[\w-]+(?:-[\d]{1,2})?(?:\/.?[\d]*)?(?:\([^\s)]+\))?(?![:]))/g;
|
|
18
|
+
let colorMatch;
|
|
19
|
+
//check color
|
|
20
|
+
while((colorMatch = colorPattern.exec(instanceMatch[0])) !== null){
|
|
21
|
+
const colorValue = parseColorString(colorMatch[0], theme, css);
|
|
22
|
+
if (colorValue) {
|
|
23
|
+
const colorIndex = {
|
|
24
|
+
index: {
|
|
25
|
+
start: instanceStartIndex + colorMatch.index,
|
|
26
|
+
end: instanceStartIndex + colorMatch.index + colorMatch[0].length
|
|
27
|
+
},
|
|
28
|
+
color: colorValue
|
|
29
|
+
};
|
|
30
|
+
colors.push(colorIndex);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return colors;
|
|
35
|
+
}
|
|
36
|
+
function percentageConverter(value, max = 1) {
|
|
37
|
+
if (value === 'none') {
|
|
38
|
+
return 0;
|
|
39
|
+
} else if (value.endsWith('%')) {
|
|
40
|
+
return max * Number(value.replace('%', '')) / 100;
|
|
41
|
+
} else {
|
|
42
|
+
return Number(value);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function degConverter(value) {
|
|
46
|
+
if (value === 'none') {
|
|
47
|
+
return 0;
|
|
48
|
+
} else if (value.endsWith('turn')) {
|
|
49
|
+
return Number(value.replace('turn', '')) * 360;
|
|
50
|
+
} else if (value.endsWith('grad')) {
|
|
51
|
+
return Number(value.replace('grad', '')) * 0.9;
|
|
52
|
+
} else if (value.endsWith('rad')) {
|
|
53
|
+
return Number(value.replace('rad', '')) * 57.2957795;
|
|
54
|
+
} else if (value.endsWith('deg')) {
|
|
55
|
+
return Number(value.replace('deg', ''));
|
|
56
|
+
} else {
|
|
57
|
+
return Number(value);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function parseColorString(colorString, theme, css = new MasterCSS()) {
|
|
61
|
+
const rgbaColorPattern = /rgb(?:a)?\(([\d.]+)[,|]([\d.]+)[,|]([\d.]+)(?:[,/]([\d.]+(?:%)?))?\)/g;
|
|
62
|
+
const hslaColorPattern = /hsl(?:a)?\(([\d.]+(?:deg|turn|grad|rad)?|none)[,|]([\d.]+%|none)[,|]([\d.]+%|none)(?:[,/]([\d.]+(?:%)?))?\)/g;
|
|
63
|
+
const hwbColorPattern = /hwb\(([\d.]+(?:deg|turn|grad|rad)?|none)[|]([\d.]+%|none)[|]([\d.]+%|none)(?:[/]([\d.]+(?:%)?))?\)/g;
|
|
64
|
+
const oklchColorPattern = /oklch\(([\d.]+(?:%)?|none)[|]([\d.]+(?:%)?|none)[|]([\d.]+(?:deg|turn|grad|rad)?|none)(?:[/]([\d.]+(?:%)?))?\)/g;
|
|
65
|
+
const lchColorPattern = /lch\(([\d.]+(?:%)?|none)[|]([\d.]+(?:%)?|none)[|]([\d.]+(?:deg|turn|grad|rad)?|none)(?:[/]([\d.]+(?:%)?))?\)/g;
|
|
66
|
+
const oklabColorPattern = /oklab\(([\d.]+(?:%)?|none)[|](-?[\d.]+(?:%)?|none)[|](-?[\d.]+(?:%)?|none)(?:[/]([\d.]+(?:%)?))?\)/g;
|
|
67
|
+
const labColorPattern = /lab\(([\d.]+(?:%)?|none)[|](-?[\d.]+(?:%)?|none)[|](-?[\d.]+(?:%)?|none)(?:[/]([\d.]+(?:%)?))?\)/g;
|
|
68
|
+
const cmykColorPattern = /device-cmyk\(([\d.]+(?:%)?|none)[|]([\d.]+(?:%)?|none)[|]([\d.]+(?:%)?|none)[|]([\d.]+(?:%)?|none)(?:[/]([\d.]+(?:%)?))?(?:,\w+\(.*\))?\)/g;
|
|
69
|
+
const hexColorPattern = /#([0-9a-fA-F]{6,8})/g;
|
|
70
|
+
const colorFunctionPattern = /color?\((?:srgb|srgb-linear|display-p3|a98-rgb|prophoto-rgb|rec2020|xyz|xyz-d50|xyz-d65)[|]([\d.]+)[|]([\d.]+)[|]([\d.]+)(?:[/]([\d.]+(?:%)?))?\)/g;
|
|
71
|
+
let colorMatch2;
|
|
72
|
+
//#region for rgb、hls
|
|
73
|
+
if (colorMatch2 = rgbaColorPattern.exec(colorString)) {
|
|
74
|
+
return getColorValue({
|
|
75
|
+
red: Number(colorMatch2[1]),
|
|
76
|
+
green: Number(colorMatch2[2]),
|
|
77
|
+
blue: Number(colorMatch2[3]),
|
|
78
|
+
alpha: colorMatch2[4] == undefined ? 1 : percentageConverter(colorMatch2[4])
|
|
79
|
+
});
|
|
80
|
+
} else if (colorMatch2 = hslaColorPattern.exec(colorString)) {
|
|
81
|
+
const rgb = hsl.rgb([
|
|
82
|
+
degConverter(colorMatch2[1]),
|
|
83
|
+
percentageConverter(colorMatch2[2], 100),
|
|
84
|
+
percentageConverter(colorMatch2[3], 100)
|
|
85
|
+
]);
|
|
86
|
+
return getColorValue({
|
|
87
|
+
red: rgb[0],
|
|
88
|
+
green: rgb[1],
|
|
89
|
+
blue: rgb[2],
|
|
90
|
+
alpha: colorMatch2[4] == undefined ? 1 : percentageConverter(colorMatch2[4])
|
|
91
|
+
});
|
|
92
|
+
} else if (colorMatch2 = hwbColorPattern.exec(colorString)) {
|
|
93
|
+
const rgb = hwb.rgb([
|
|
94
|
+
degConverter(colorMatch2[1]),
|
|
95
|
+
percentageConverter(colorMatch2[2], 100),
|
|
96
|
+
percentageConverter(colorMatch2[3], 100)
|
|
97
|
+
]);
|
|
98
|
+
return getColorValue({
|
|
99
|
+
red: rgb[0],
|
|
100
|
+
green: rgb[1],
|
|
101
|
+
blue: rgb[2],
|
|
102
|
+
alpha: colorMatch2[4] == undefined ? 1 : percentageConverter(colorMatch2[4])
|
|
103
|
+
});
|
|
104
|
+
} else if (colorMatch2 = oklchColorPattern.exec(colorString)) {
|
|
105
|
+
const oklab = oklchToOklab([
|
|
106
|
+
percentageConverter(colorMatch2[1]),
|
|
107
|
+
percentageConverter(colorMatch2[2], 0.4),
|
|
108
|
+
degConverter(colorMatch2[3])
|
|
109
|
+
]);
|
|
110
|
+
const rgb = oklabToRgb(oklab);
|
|
111
|
+
return getColorValue({
|
|
112
|
+
red: rgb[0],
|
|
113
|
+
green: rgb[1],
|
|
114
|
+
blue: rgb[2],
|
|
115
|
+
alpha: colorMatch2[4] == undefined ? 1 : percentageConverter(colorMatch2[4])
|
|
116
|
+
});
|
|
117
|
+
} else if (colorMatch2 = lchColorPattern.exec(colorString)) {
|
|
118
|
+
const rgb = lch.rgb([
|
|
119
|
+
percentageConverter(colorMatch2[1], 100),
|
|
120
|
+
percentageConverter(colorMatch2[2], 150),
|
|
121
|
+
degConverter(colorMatch2[3])
|
|
122
|
+
]);
|
|
123
|
+
return getColorValue({
|
|
124
|
+
red: rgb[0],
|
|
125
|
+
green: rgb[1],
|
|
126
|
+
blue: rgb[2],
|
|
127
|
+
alpha: colorMatch2[4] == undefined ? 1 : percentageConverter(colorMatch2[4])
|
|
128
|
+
});
|
|
129
|
+
} else if (colorMatch2 = oklabColorPattern.exec(colorString)) {
|
|
130
|
+
const rgb = oklabToRgb([
|
|
131
|
+
percentageConverter(colorMatch2[1]),
|
|
132
|
+
percentageConverter(colorMatch2[2], 0.4),
|
|
133
|
+
percentageConverter(colorMatch2[3], 0.4)
|
|
134
|
+
]);
|
|
135
|
+
return getColorValue({
|
|
136
|
+
red: rgb[0],
|
|
137
|
+
green: rgb[1],
|
|
138
|
+
blue: rgb[2],
|
|
139
|
+
alpha: colorMatch2[4] == undefined ? 1 : percentageConverter(colorMatch2[4])
|
|
140
|
+
});
|
|
141
|
+
} else if (colorMatch2 = labColorPattern.exec(colorString)) {
|
|
142
|
+
const rgb = lab.rgb([
|
|
143
|
+
percentageConverter(colorMatch2[1], 100),
|
|
144
|
+
percentageConverter(colorMatch2[2], 125),
|
|
145
|
+
percentageConverter(colorMatch2[3], 125)
|
|
146
|
+
]);
|
|
147
|
+
return getColorValue({
|
|
148
|
+
red: rgb[0],
|
|
149
|
+
green: rgb[1],
|
|
150
|
+
blue: rgb[2],
|
|
151
|
+
alpha: colorMatch2[4] == undefined ? 1 : percentageConverter(colorMatch2[4])
|
|
152
|
+
});
|
|
153
|
+
} else if (colorMatch2 = cmykColorPattern.exec(colorString)) {
|
|
154
|
+
const rgb = cmyk.rgb([
|
|
155
|
+
percentageConverter(colorMatch2[1], 100),
|
|
156
|
+
percentageConverter(colorMatch2[2], 100),
|
|
157
|
+
percentageConverter(colorMatch2[3], 100),
|
|
158
|
+
percentageConverter(colorMatch2[4], 100)
|
|
159
|
+
]);
|
|
160
|
+
return getColorValue({
|
|
161
|
+
red: rgb[0],
|
|
162
|
+
green: rgb[1],
|
|
163
|
+
blue: rgb[2],
|
|
164
|
+
alpha: colorMatch2[5] == undefined ? 1 : percentageConverter(colorMatch2[5])
|
|
165
|
+
});
|
|
166
|
+
} else if (colorMatch2 = hexColorPattern.exec(colorString)) {
|
|
167
|
+
return getColorValue(hexToRgb(colorMatch2[1]));
|
|
168
|
+
} else if (colorMatch2 = colorFunctionPattern.exec(colorString)) {
|
|
169
|
+
return getColorValue({
|
|
170
|
+
red: Number(colorMatch2[1]) * 255,
|
|
171
|
+
green: Number(colorMatch2[2]) * 255,
|
|
172
|
+
blue: Number(colorMatch2[3]) * 255,
|
|
173
|
+
alpha: colorMatch2[4] == undefined ? 1 : percentageConverter(colorMatch2[4])
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
//#endregion for rgb、hls
|
|
177
|
+
//#region for mastercss color
|
|
178
|
+
let colorAlpha = 1;
|
|
179
|
+
let colorName = colorString;
|
|
180
|
+
const allCSSColorNames = [];
|
|
181
|
+
// todo: refactor css.variables
|
|
182
|
+
for(const eachVariableName in css.variables){
|
|
183
|
+
const eachVariable = css.variables[eachVariableName];
|
|
184
|
+
if (eachVariable.type === 'color') allCSSColorNames.push(eachVariableName);
|
|
185
|
+
}
|
|
186
|
+
if (colorString.split('/').length == 2) {
|
|
187
|
+
colorAlpha = Number('0' + colorString.split('/')[1]);
|
|
188
|
+
}
|
|
189
|
+
if (colorString.split('-').length == 1) {
|
|
190
|
+
colorName = colorString.split('/')[0];
|
|
191
|
+
colorName = colorName.endsWith('_') ? colorName.replace('_', '') : colorName;
|
|
192
|
+
}
|
|
193
|
+
if (allCSSColorNames.find((x)=>x == colorName)) {
|
|
194
|
+
return getColorsRGBA(colorName, colorAlpha, theme, css);
|
|
195
|
+
}
|
|
196
|
+
//#endregion for mastercss color
|
|
197
|
+
}
|
|
198
|
+
function getColorsRGBA(colorName, colorAlpha = 1, theme = '', css = new MasterCSS()) {
|
|
199
|
+
try {
|
|
200
|
+
// todo: refactor colorNumberMap
|
|
201
|
+
const colorNumberMap = css.variables[colorName];
|
|
202
|
+
const levelRgb = hexToRgb(colorNumberMap[theme] ?? colorNumberMap[''] ?? Object.values(colorNumberMap)[0]);
|
|
203
|
+
return {
|
|
204
|
+
red: levelRgb.red / 255,
|
|
205
|
+
green: levelRgb.green / 255,
|
|
206
|
+
blue: levelRgb.blue / 255,
|
|
207
|
+
alpha: colorAlpha
|
|
208
|
+
};
|
|
209
|
+
} catch (ex) {
|
|
210
|
+
return {
|
|
211
|
+
red: 0,
|
|
212
|
+
green: 0,
|
|
213
|
+
blue: 0,
|
|
214
|
+
alpha: 1
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
function getColorValue(color) {
|
|
219
|
+
return {
|
|
220
|
+
red: color.red / 255.0,
|
|
221
|
+
green: color.green / 255.0,
|
|
222
|
+
blue: color.blue / 255.0,
|
|
223
|
+
alpha: color.alpha
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
function getColorPresentation(params, isColorRender = false) {
|
|
227
|
+
const result = [];
|
|
228
|
+
const color = params.color;
|
|
229
|
+
const range = params.range;
|
|
230
|
+
const red256 = Math.round(color.red * 255), green256 = Math.round(color.green * 255), blue256 = Math.round(color.blue * 255);
|
|
231
|
+
let label;
|
|
232
|
+
if (isColorRender) {
|
|
233
|
+
if (color.alpha === 1) {
|
|
234
|
+
label = `'#${toTwoDigitHex(red256)}${toTwoDigitHex(green256)}${toTwoDigitHex(blue256)}`;
|
|
235
|
+
} else {
|
|
236
|
+
label = `'#${toTwoDigitHex(red256)}${toTwoDigitHex(green256)}${toTwoDigitHex(blue256)}${toTwoDigitHex(Math.round(color.alpha * 255))}`;
|
|
237
|
+
}
|
|
238
|
+
result.push({
|
|
239
|
+
label: label,
|
|
240
|
+
textEdit: {
|
|
241
|
+
range: range,
|
|
242
|
+
newText: label
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
return result;
|
|
246
|
+
}
|
|
247
|
+
if (color.alpha === 1) {
|
|
248
|
+
label = `rgb(${red256},${green256},${blue256})`;
|
|
249
|
+
} else {
|
|
250
|
+
label = `rgba(${red256},${green256},${blue256},${color.alpha})`;
|
|
251
|
+
}
|
|
252
|
+
result.push({
|
|
253
|
+
label: label,
|
|
254
|
+
textEdit: {
|
|
255
|
+
range: range,
|
|
256
|
+
newText: label
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
if (color.alpha === 1) {
|
|
260
|
+
label = `#${toTwoDigitHex(red256)}${toTwoDigitHex(green256)}${toTwoDigitHex(blue256)}`;
|
|
261
|
+
} else {
|
|
262
|
+
label = `#${toTwoDigitHex(red256)}${toTwoDigitHex(green256)}${toTwoDigitHex(blue256)}${toTwoDigitHex(Math.round(color.alpha * 255))}`;
|
|
263
|
+
}
|
|
264
|
+
result.push({
|
|
265
|
+
label: label,
|
|
266
|
+
textEdit: {
|
|
267
|
+
range: range,
|
|
268
|
+
newText: label
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
const hsl = rgb.hsl(red256, green256, blue256);
|
|
272
|
+
if (color.alpha === 1) {
|
|
273
|
+
label = `hsl(${hsl[0]},${Math.round(hsl[1])}%,${Math.round(hsl[2])}%)`;
|
|
274
|
+
} else {
|
|
275
|
+
label = `hsla(${hsl[0]},${Math.round(hsl[1])}%,${Math.round(hsl[2])}%,${color.alpha})`;
|
|
276
|
+
}
|
|
277
|
+
result.push({
|
|
278
|
+
label: label,
|
|
279
|
+
textEdit: {
|
|
280
|
+
range: range,
|
|
281
|
+
newText: label
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
// const hwb = rgb.hwb(red256, green256, blue256)
|
|
285
|
+
// if (color.alpha === 1) {
|
|
286
|
+
// label = `hwb(${hwb[0]}|${hwb[1]}%|${hwb[2]}%)`
|
|
287
|
+
// } else {
|
|
288
|
+
// label = `hwb(${hwb[0]}|${hwb[1]}%|${hwb[2]}%/${color.alpha})`
|
|
289
|
+
// }
|
|
290
|
+
// result.push({ label: label, textEdit: { range: range, newText: label } })
|
|
291
|
+
// const lab = rgb.lab(red256, green256, blue256)
|
|
292
|
+
// if (color.alpha === 1) {
|
|
293
|
+
// label = `lab(${lab[0]}%|${lab[1]}|${lab[2]})`
|
|
294
|
+
// } else {
|
|
295
|
+
// label = `lab(${lab[0]}%|${lab[1]}|${lab[2]}/${color.alpha})`
|
|
296
|
+
// }
|
|
297
|
+
// result.push({ label: label, textEdit: { range: range, newText: label } })
|
|
298
|
+
// const lch = rgb.lch(red256, green256, blue256)
|
|
299
|
+
// if (color.alpha === 1) {
|
|
300
|
+
// label = `lch(${lch[0]}%|${lch[1]}|${lch[2]})`
|
|
301
|
+
// } else {
|
|
302
|
+
// label = `lch(${lch[0]}%|${lch[1]}|${lch[2]}/${color.alpha})`
|
|
303
|
+
// }
|
|
304
|
+
// result.push({ label: label, textEdit: { range: range, newText: label } })
|
|
305
|
+
// const cmyk = rgb.cmyk(red256, green256, blue256)
|
|
306
|
+
// if (color.alpha === 1) {
|
|
307
|
+
// label = `device-cmyk(${cmyk[0]}%|${cmyk[1]}%|${cmyk[2]}%|${cmyk[3]}%)`
|
|
308
|
+
// } else {
|
|
309
|
+
// label = `device-cmyk(${cmyk[0]}%|${cmyk[1]}%|${cmyk[2]}%|${cmyk[3]}%/${color.alpha})`
|
|
310
|
+
// }
|
|
311
|
+
// result.push({ label: label, textEdit: { range: range, newText: label } })
|
|
312
|
+
return result;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
export { getColorPresentation, getColorValue, getDocumentColors };
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var constant = require('../constant.cjs');
|
|
4
|
+
var css = require('@master/css');
|
|
5
|
+
var webCustomData = require('vscode-css-languageservice/lib/umd/data/webCustomData');
|
|
6
|
+
var dataProvider = require('vscode-css-languageservice/lib/umd/languageFacts/dataProvider');
|
|
7
|
+
|
|
8
|
+
let cssKeys = [];
|
|
9
|
+
cssKeys = cssKeys.concat(constant.masterCssOtherKeys);
|
|
10
|
+
constant.masterCssKeyValues.forEach((x)=>{
|
|
11
|
+
cssKeys = cssKeys.concat(x.key);
|
|
12
|
+
});
|
|
13
|
+
const masterCssKeys = [
|
|
14
|
+
...new Set(cssKeys)
|
|
15
|
+
];
|
|
16
|
+
// temporary
|
|
17
|
+
function checkConfigColorsBlock(document, position) {
|
|
18
|
+
const lineText = (document?.getText({
|
|
19
|
+
start: {
|
|
20
|
+
line: position.line,
|
|
21
|
+
character: 0
|
|
22
|
+
},
|
|
23
|
+
end: {
|
|
24
|
+
line: position.line,
|
|
25
|
+
character: position.character
|
|
26
|
+
}
|
|
27
|
+
}) ?? '').trim();
|
|
28
|
+
if ((lineText.match(/'|"|`/g)?.length ?? 0) % 2 === 0) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
for(let i = position.line; i > 0; i--){
|
|
32
|
+
const text = document.getText({
|
|
33
|
+
start: {
|
|
34
|
+
line: i - 1,
|
|
35
|
+
character: 0
|
|
36
|
+
},
|
|
37
|
+
end: {
|
|
38
|
+
line: i,
|
|
39
|
+
character: 0
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
if (text.includes('}')) {
|
|
43
|
+
return false;
|
|
44
|
+
} else if (text.includes('colors:')) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
function getLastInstance(lineText, position, language) {
|
|
51
|
+
const classPattern = /(?:[^"{'\s])+(?=>\s|\b)/g;
|
|
52
|
+
let classMatch;
|
|
53
|
+
let lastKey = '';
|
|
54
|
+
let triggerKey = lineText.charAt(lineText.length - 1);
|
|
55
|
+
let isStart = position.character == 1 || lineText.charAt(lineText.length - 2) === ' ' || lineText.charAt(lineText.length - 2) === '' || lineText.charAt(lineText.length - 2) === '"' || lineText.charAt(lineText.length - 2) === '\'' || lineText.charAt(lineText.length - 2) === '{';
|
|
56
|
+
if (lineText.match(classPattern) === null) {
|
|
57
|
+
return {
|
|
58
|
+
isInstance: false,
|
|
59
|
+
lastKey: '',
|
|
60
|
+
triggerKey: '',
|
|
61
|
+
isStart: false,
|
|
62
|
+
language: language
|
|
63
|
+
};
|
|
64
|
+
} else {
|
|
65
|
+
while((classMatch = classPattern.exec(lineText)) !== null){
|
|
66
|
+
lastKey = classMatch[0];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (lineText.charAt(lineText.length - 2) === ':' && lineText.charAt(lineText.length - 1) === ':') {
|
|
70
|
+
triggerKey = '::';
|
|
71
|
+
isStart = false;
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
isInstance: true,
|
|
75
|
+
lastKey: lastKey,
|
|
76
|
+
triggerKey: triggerKey,
|
|
77
|
+
isStart: isStart,
|
|
78
|
+
language: language
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function getConfigColorsCompletionItem(css$1 = new css.MasterCSS()) {
|
|
82
|
+
let masterStyleCompletionItem = [];
|
|
83
|
+
masterStyleCompletionItem = masterStyleCompletionItem.concat(getColorsItem(css$1));
|
|
84
|
+
return masterStyleCompletionItem;
|
|
85
|
+
}
|
|
86
|
+
function getCompletionItem(instance, triggerKey, isStart, language, css$1 = new css.MasterCSS()) {
|
|
87
|
+
const cssDataProvider = new dataProvider.CSSDataProvider(webCustomData.cssData);
|
|
88
|
+
const cssProperties = cssDataProvider.provideProperties();
|
|
89
|
+
let masterStyleCompletionItem = [];
|
|
90
|
+
const haveValue = instance.split(':').length;
|
|
91
|
+
let key = instance.split(':')[0];
|
|
92
|
+
key = key.trim();
|
|
93
|
+
const instanceLength = instance.split(':|@').length;
|
|
94
|
+
const last = instance.split(':|@')[instanceLength - 1];
|
|
95
|
+
const mediaPattern = /[^\\s"]+@+([^\\s:"@]+)/g;
|
|
96
|
+
const elementsPattern = /[^\\s"]+::+([^\\s:"@]+)/g;
|
|
97
|
+
let isColorful = false;
|
|
98
|
+
const isMedia = !(mediaPattern.exec(instance) === null && triggerKey !== '@');
|
|
99
|
+
const isElements = !(elementsPattern.exec(instance) === null && triggerKey !== '::');
|
|
100
|
+
const masterCssKeyCompletionItems = [];
|
|
101
|
+
let masterCssValues = [];
|
|
102
|
+
const masterCustomSelectors = Object.keys(css$1.config?.selectors ?? {}).map((x)=>x.endsWith('(') ? `${x})` : x).filter((x)=>x.match(/:[^:]+/) && !constant.masterCssSelectors.find((existedSelector)=>(typeof existedSelector === 'string' ? existedSelector : existedSelector.label) === `:${x}`)).map((x)=>{
|
|
103
|
+
x = x.substring(1);
|
|
104
|
+
if (x.endsWith(')')) {
|
|
105
|
+
return {
|
|
106
|
+
label: x,
|
|
107
|
+
kind: 3
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
return x;
|
|
111
|
+
});
|
|
112
|
+
const masterCustomElements = Object.keys(css$1.config?.selectors ?? {}).map((x)=>x.endsWith('(') ? `${x})` : x).filter((x)=>x.match(/::[^:]+/) && !constant.masterCssElements.find((existedElement)=>(typeof existedElement === 'string' ? existedElement : existedElement.label) === `::${x}`)).map((x)=>{
|
|
113
|
+
x = x.substring(2);
|
|
114
|
+
if (x.endsWith(')')) {
|
|
115
|
+
return {
|
|
116
|
+
label: x,
|
|
117
|
+
kind: 3
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
return x;
|
|
121
|
+
});
|
|
122
|
+
constant.masterCssKeyValues.forEach((x)=>{
|
|
123
|
+
const fullKey = x.key[0];
|
|
124
|
+
const originalCssProperty = cssProperties.find((x)=>x.name == fullKey);
|
|
125
|
+
const originalCssValues = originalCssProperty?.values ?? [];
|
|
126
|
+
for (const masterKey of x.key){
|
|
127
|
+
if (!masterCssKeyCompletionItems.find((existedValue)=>existedValue.label === masterKey + ':')) {
|
|
128
|
+
masterCssKeyCompletionItems.push({
|
|
129
|
+
label: masterKey + ':',
|
|
130
|
+
kind: 10,
|
|
131
|
+
documentation: originalCssProperty?.description ?? '',
|
|
132
|
+
command: {
|
|
133
|
+
title: 'triggerSuggest',
|
|
134
|
+
command: 'editor.action.triggerSuggest'
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (x.key.includes(key)) {
|
|
140
|
+
// constant.ts custom values
|
|
141
|
+
masterCssValues = masterCssValues.concat(x.values.filter((cssValue)=>!masterCssValues.find((existedValue)=>(typeof existedValue === 'string' ? existedValue : existedValue.label) === (typeof cssValue === 'string' ? cssValue : cssValue.label))));
|
|
142
|
+
masterCssValues = masterCssValues.concat(originalCssValues.filter((cssValue, index)=>cssValue.description || !cssValue.description && originalCssValues.indexOf(cssValue) === index).map((cssValue)=>({
|
|
143
|
+
label: cssValue.name.replace(/,\s/g, ',').replace(/\s/g, '|').replace(/["']/g, ''),
|
|
144
|
+
kind: 10,
|
|
145
|
+
documentation: cssValue?.description ?? ''
|
|
146
|
+
})).filter((cssValue)=>!masterCssValues.find((existedValue)=>(typeof existedValue === 'string' ? existedValue : existedValue.label) === (typeof cssValue === 'string' ? cssValue : cssValue.label))));
|
|
147
|
+
if (css$1.config?.variables?.[fullKey]) {
|
|
148
|
+
const masterCustomVariables = Object.keys(css$1.config?.variables[fullKey]);
|
|
149
|
+
masterCssValues = masterCssValues.concat(masterCustomVariables.filter((customValue)=>!masterCssValues.find((existedValue)=>(typeof existedValue === 'string' ? existedValue : existedValue.label) === customValue)));
|
|
150
|
+
}
|
|
151
|
+
if (x.colored) {
|
|
152
|
+
isColorful = true;
|
|
153
|
+
const needPushList = constant.masterCssType.find((y)=>y.type === 'color')?.values.filter((z)=>!masterCssValues.find((a)=>(typeof a === 'string' ? a : a.label) === (typeof z === 'string' ? z : z.label)));
|
|
154
|
+
if (needPushList) {
|
|
155
|
+
masterCssValues = masterCssValues.concat(needPushList);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
if ((isStart == true || !masterCssKeys.includes(key)) && triggerKey !== '@' && triggerKey !== ':') {
|
|
161
|
+
masterStyleCompletionItem = masterStyleCompletionItem.concat(masterCssKeyCompletionItems);
|
|
162
|
+
masterStyleCompletionItem = masterStyleCompletionItem.concat(getReturnItem(Object.keys(css$1.config?.semantics ?? {}), 10));
|
|
163
|
+
if (language == 'tsx' || language == 'vue' || language == 'jsx') {
|
|
164
|
+
return HaveDash(key, masterStyleCompletionItem);
|
|
165
|
+
}
|
|
166
|
+
return masterStyleCompletionItem;
|
|
167
|
+
} else if (isStart == true) {
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
if (masterCssKeys.includes(key) && key !== null && isElements === true) {
|
|
171
|
+
masterStyleCompletionItem = masterStyleCompletionItem.concat(getReturnItem(constant.masterCssElements, 10));
|
|
172
|
+
masterStyleCompletionItem = masterStyleCompletionItem.concat(getReturnItem(masterCustomElements, 10));
|
|
173
|
+
if ((language == 'tsx' || language == 'vue' || language == 'jsx') && triggerKey !== '@' && triggerKey !== ':') {
|
|
174
|
+
return HaveDash(last, masterStyleCompletionItem);
|
|
175
|
+
}
|
|
176
|
+
return masterStyleCompletionItem;
|
|
177
|
+
}
|
|
178
|
+
if (masterCssKeys.includes(key) && key !== null && isMedia === true) {
|
|
179
|
+
masterStyleCompletionItem = masterStyleCompletionItem.concat(getReturnItem(constant.masterCssMedia, 10));
|
|
180
|
+
// todo: refactor theme
|
|
181
|
+
masterStyleCompletionItem = masterStyleCompletionItem.concat(getReturnItem([
|
|
182
|
+
'light',
|
|
183
|
+
'dark'
|
|
184
|
+
], 10));
|
|
185
|
+
if ((language == 'tsx' || language == 'vue' || language == 'jsx') && triggerKey !== '@' && triggerKey !== ':') {
|
|
186
|
+
return HaveDash('@' + last, masterStyleCompletionItem);
|
|
187
|
+
}
|
|
188
|
+
return masterStyleCompletionItem;
|
|
189
|
+
}
|
|
190
|
+
if (Object.keys(css$1.config?.semantics ?? {}).includes(key) && !constant.masterCssKeyValues.find((x)=>x.key.includes(key))) {
|
|
191
|
+
masterStyleCompletionItem = masterStyleCompletionItem.concat(getReturnItem(constant.masterCssSelectors, 10));
|
|
192
|
+
masterStyleCompletionItem = masterStyleCompletionItem.concat(getReturnItem(masterCustomSelectors, 10));
|
|
193
|
+
if ((language == 'tsx' || language == 'vue' || language == 'jsx') && triggerKey !== '@' && triggerKey !== ':') {
|
|
194
|
+
return HaveDash(last, masterStyleCompletionItem);
|
|
195
|
+
}
|
|
196
|
+
return masterStyleCompletionItem;
|
|
197
|
+
} else if (masterCssKeys.includes(key) && haveValue <= 2 && !(haveValue == 2 && triggerKey === ':')) {
|
|
198
|
+
masterStyleCompletionItem = masterStyleCompletionItem.concat(getReturnItem(masterCssValues, 10));
|
|
199
|
+
masterStyleCompletionItem = masterStyleCompletionItem.concat(getReturnItem(constant.masterCssCommonValues, 13).map((x)=>{
|
|
200
|
+
x.sortText = 'z' + x;
|
|
201
|
+
return x;
|
|
202
|
+
}));
|
|
203
|
+
if (isColorful) {
|
|
204
|
+
masterStyleCompletionItem = masterStyleCompletionItem.concat(getColorsItem(css$1));
|
|
205
|
+
}
|
|
206
|
+
if ((language == 'tsx' || language == 'vue' || language == 'jsx') && triggerKey !== '@' && triggerKey !== ':') {
|
|
207
|
+
return HaveDash(last, masterStyleCompletionItem);
|
|
208
|
+
}
|
|
209
|
+
return masterStyleCompletionItem;
|
|
210
|
+
}
|
|
211
|
+
if (masterCssKeys.includes(key) && (haveValue == 2 && triggerKey === ':' || haveValue >= 3) || constant.masterCssKeyValues.find((x)=>x.values.includes(key))) {
|
|
212
|
+
masterStyleCompletionItem = masterStyleCompletionItem.concat(getReturnItem(constant.masterCssSelectors, 3));
|
|
213
|
+
masterStyleCompletionItem = masterStyleCompletionItem.concat(getReturnItem(masterCustomSelectors, 10));
|
|
214
|
+
}
|
|
215
|
+
if ((language == 'tsx' || language == 'vue' || language == 'jsx') && triggerKey !== '@' && triggerKey !== ':') {
|
|
216
|
+
return HaveDash(last, masterStyleCompletionItem);
|
|
217
|
+
}
|
|
218
|
+
return masterStyleCompletionItem;
|
|
219
|
+
}
|
|
220
|
+
function getReturnItem(items, kind, insertText = '') {
|
|
221
|
+
const masterStyleCompletionItem = [];
|
|
222
|
+
items.forEach((x)=>{
|
|
223
|
+
if (typeof x === 'string') {
|
|
224
|
+
masterStyleCompletionItem.push({
|
|
225
|
+
label: x + insertText,
|
|
226
|
+
kind: kind,
|
|
227
|
+
insertText: x + insertText,
|
|
228
|
+
insertTextMode: 2,
|
|
229
|
+
command: insertText === ':' ? {
|
|
230
|
+
title: 'triggerSuggest',
|
|
231
|
+
command: 'editor.action.triggerSuggest'
|
|
232
|
+
} : undefined
|
|
233
|
+
});
|
|
234
|
+
} else {
|
|
235
|
+
masterStyleCompletionItem.push({
|
|
236
|
+
insertText: x.label + insertText,
|
|
237
|
+
insertTextMode: 2,
|
|
238
|
+
command: insertText === ':' ? {
|
|
239
|
+
title: 'triggerSuggest',
|
|
240
|
+
command: 'editor.action.triggerSuggest'
|
|
241
|
+
} : undefined,
|
|
242
|
+
...x
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
return masterStyleCompletionItem;
|
|
247
|
+
}
|
|
248
|
+
function getColorsItem(css$1 = new css.MasterCSS()) {
|
|
249
|
+
const masterStyleCompletionItem = [];
|
|
250
|
+
// todo: refactor css.variables
|
|
251
|
+
for(const eachVariableName in css$1.variables){
|
|
252
|
+
const eachVariable = css$1.variables[eachVariableName];
|
|
253
|
+
if (eachVariable.type === 'color') {
|
|
254
|
+
masterStyleCompletionItem.push({
|
|
255
|
+
label: eachVariableName,
|
|
256
|
+
documentation: eachVariable.value,
|
|
257
|
+
kind: 16,
|
|
258
|
+
sortText: eachVariableName
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return masterStyleCompletionItem;
|
|
263
|
+
}
|
|
264
|
+
function HaveDash(str, itemList) {
|
|
265
|
+
const completionItem = [];
|
|
266
|
+
if (str.split('-').length - 1 <= 0) {
|
|
267
|
+
return itemList;
|
|
268
|
+
} else {
|
|
269
|
+
const start = str.split('-')[0] + '-';
|
|
270
|
+
itemList.map((x)=>{
|
|
271
|
+
if (x.label.includes(start)) {
|
|
272
|
+
completionItem.push({
|
|
273
|
+
label: x.label,
|
|
274
|
+
kind: x.kind,
|
|
275
|
+
insertText: x.insertText?.substring(start.length),
|
|
276
|
+
insertTextMode: x.insertTextMode,
|
|
277
|
+
command: x.command
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
return completionItem;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
exports.checkConfigColorsBlock = checkConfigColorsBlock;
|
|
286
|
+
exports.getCompletionItem = getCompletionItem;
|
|
287
|
+
exports.getConfigColorsCompletionItem = getConfigColorsCompletionItem;
|
|
288
|
+
exports.getLastInstance = getLastInstance;
|
|
289
|
+
exports.getReturnItem = getReturnItem;
|