@master/css-language-service 2.0.0-rc.5 → 2.0.0-rc.51
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/common.cjs +57 -0
- package/dist/common.d.ts +9 -0
- package/dist/common.mjs +48 -0
- package/dist/core.cjs +246 -0
- package/dist/core.d.ts +29 -0
- package/dist/core.mjs +244 -0
- package/dist/features/edit-syntax-colors.cjs +19 -0
- package/dist/features/edit-syntax-colors.d.ts +4 -0
- package/dist/features/edit-syntax-colors.mjs +17 -0
- package/dist/features/inspect-syntax.cjs +70 -0
- package/dist/features/inspect-syntax.d.ts +4 -0
- package/dist/features/inspect-syntax.mjs +68 -0
- package/dist/features/render-syntax-colors.cjs +88 -0
- package/dist/features/render-syntax-colors.d.ts +4 -0
- package/dist/features/render-syntax-colors.mjs +86 -0
- package/dist/features/suggest-syntax.cjs +20 -0
- package/dist/features/suggest-syntax.d.ts +4 -0
- package/dist/features/suggest-syntax.mjs +18 -0
- package/dist/index.cjs +29 -0
- package/dist/index.d.ts +7 -5
- package/dist/index.mjs +7 -0
- package/dist/settings.cjs +84 -0
- package/dist/settings.d.ts +19 -9
- package/dist/settings.mjs +82 -0
- package/dist/utils/beautify-css.cjs +13 -0
- package/dist/utils/beautify-css.d.ts +1 -0
- package/dist/utils/beautify-css.mjs +11 -0
- package/dist/utils/convert-color-space.cjs +40 -0
- package/dist/utils/convert-color-space.d.ts +2 -0
- package/dist/utils/convert-color-space.mjs +38 -0
- package/dist/utils/convert-color-token.cjs +28 -0
- package/dist/utils/convert-color-token.d.ts +3 -0
- package/dist/utils/convert-color-token.mjs +26 -0
- package/dist/utils/create-doc.cjs +26 -0
- package/dist/utils/create-doc.d.ts +16 -0
- package/dist/utils/create-doc.mjs +21 -0
- package/dist/utils/css-data-provider.cjs +9 -0
- package/dist/utils/css-data-provider.d.ts +3 -0
- package/dist/utils/css-data-provider.mjs +7 -0
- package/dist/utils/find-matching-brackets.cjs +29 -0
- package/dist/utils/find-matching-brackets.d.ts +1 -0
- package/dist/utils/find-matching-brackets.mjs +27 -0
- package/dist/utils/get-color-completion-items.cjs +30 -0
- package/dist/utils/get-color-completion-items.d.ts +3 -0
- package/dist/utils/get-color-completion-items.mjs +28 -0
- package/dist/utils/get-css-data-documentation.cjs +90 -0
- package/dist/utils/get-css-data-documentation.d.ts +5 -0
- package/dist/utils/get-css-data-documentation.mjs +88 -0
- package/dist/utils/get-main-completion-items.cjs +105 -0
- package/dist/utils/get-main-completion-items.d.ts +3 -0
- package/dist/utils/get-main-completion-items.mjs +103 -0
- package/dist/utils/get-position.cjs +12 -0
- package/dist/utils/get-position.d.ts +1 -0
- package/dist/utils/get-position.mjs +10 -0
- package/dist/utils/get-pseudo-class-completion-items.cjs +65 -0
- package/dist/utils/get-pseudo-class-completion-items.d.ts +3 -0
- package/dist/utils/get-pseudo-class-completion-items.mjs +63 -0
- package/dist/utils/get-pseudo-element-completion-items.cjs +56 -0
- package/dist/utils/get-pseudo-element-completion-items.d.ts +3 -0
- package/dist/utils/get-pseudo-element-completion-items.mjs +54 -0
- package/dist/utils/get-query-completion-items.cjs +102 -0
- package/dist/utils/get-query-completion-items.d.ts +3 -0
- package/dist/utils/get-query-completion-items.mjs +100 -0
- package/dist/utils/get-range.cjs +21 -0
- package/dist/utils/get-range.d.ts +2 -0
- package/dist/utils/get-range.mjs +19 -0
- package/dist/utils/get-utility-info.cjs +32 -0
- package/dist/utils/get-utility-info.d.ts +7 -0
- package/dist/utils/get-utility-info.mjs +30 -0
- package/dist/utils/get-value-completion-items.cjs +185 -0
- package/dist/utils/get-value-completion-items.d.ts +3 -0
- package/dist/utils/get-value-completion-items.mjs +183 -0
- package/dist/utils/query-syntax-completions.cjs +115 -0
- package/dist/utils/query-syntax-completions.d.ts +3 -0
- package/dist/utils/query-syntax-completions.mjs +113 -0
- package/dist/utils/regex.cjs +5 -0
- package/dist/utils/regex.mjs +3 -0
- package/dist/utils/sort-completion-items.cjs +11 -0
- package/dist/utils/sort-completion-items.d.ts +2 -0
- package/dist/utils/sort-completion-items.mjs +9 -0
- package/package.json +1 -1
- package/dist/constant.d.ts +0 -33
- package/dist/index.bundle.js +0 -33
- package/dist/position-check.d.ts +0 -20
- package/dist/providers/color.d.ts +0 -5
- package/dist/providers/completion.d.ts +0 -14
- package/dist/providers/hover.d.ts +0 -2
- package/dist/settings.bundle.js +0 -1
- package/dist/utils/get-css-entry-markdown-description.d.ts +0 -1
- package/dist/utils/hex-to-rgb.d.ts +0 -2
- package/dist/utils/oklab-to-rgb.d.ts +0 -1
- package/dist/utils/oklch-to-oklab.d.ts +0 -1
- package/dist/utils/to-two-digit-hex.d.ts +0 -1
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var cssDataProvider = require('./css-data-provider.cjs');
|
|
4
|
+
|
|
5
|
+
function getUtilityInfo(syntax, css = new MasterCSS()) {
|
|
6
|
+
const nativeProperties = cssDataProvider.provideProperties();
|
|
7
|
+
const declarations = syntax.definition.declarations;
|
|
8
|
+
const propsLength = Object.keys(declarations || {}).length;
|
|
9
|
+
const propName = Object.keys(declarations || {})[0];
|
|
10
|
+
const propValue = declarations?.[propName];
|
|
11
|
+
let data;
|
|
12
|
+
let detail;
|
|
13
|
+
/**
|
|
14
|
+
* Remaps to native CSS properties when only one property is declared
|
|
15
|
+
* */ if (propsLength === 1) {
|
|
16
|
+
const nativeCSSPropertyData = nativeProperties.find(({ name })=>name === propName);
|
|
17
|
+
data = nativeCSSPropertyData?.values?.find(({ name })=>name === propValue || name.replace(/^-(ms|moz)-/, '') === propValue);
|
|
18
|
+
if (data) {
|
|
19
|
+
detail = `${propName}: ${propValue}`;
|
|
20
|
+
} else {
|
|
21
|
+
data = nativeCSSPropertyData;
|
|
22
|
+
detail = nativeCSSPropertyData?.syntax;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
docs: '/reference/' + (data ? propName : 'utilities'),
|
|
27
|
+
data,
|
|
28
|
+
detail
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = getUtilityInfo;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { DefinedRule } from '@master/css';
|
|
2
|
+
import type { IPropertyData } from 'vscode-css-languageservice';
|
|
3
|
+
export default function getUtilityInfo(syntax: DefinedRule, css?: import("@master/css").MasterCSS): {
|
|
4
|
+
docs: string;
|
|
5
|
+
data: IPropertyData | undefined;
|
|
6
|
+
detail: string | undefined;
|
|
7
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import cssDataProvider from './css-data-provider.mjs';
|
|
2
|
+
|
|
3
|
+
function getUtilityInfo(syntax, css = new MasterCSS()) {
|
|
4
|
+
const nativeProperties = cssDataProvider.provideProperties();
|
|
5
|
+
const declarations = syntax.definition.declarations;
|
|
6
|
+
const propsLength = Object.keys(declarations || {}).length;
|
|
7
|
+
const propName = Object.keys(declarations || {})[0];
|
|
8
|
+
const propValue = declarations?.[propName];
|
|
9
|
+
let data;
|
|
10
|
+
let detail;
|
|
11
|
+
/**
|
|
12
|
+
* Remaps to native CSS properties when only one property is declared
|
|
13
|
+
* */ if (propsLength === 1) {
|
|
14
|
+
const nativeCSSPropertyData = nativeProperties.find(({ name })=>name === propName);
|
|
15
|
+
data = nativeCSSPropertyData?.values?.find(({ name })=>name === propValue || name.replace(/^-(ms|moz)-/, '') === propValue);
|
|
16
|
+
if (data) {
|
|
17
|
+
detail = `${propName}: ${propValue}`;
|
|
18
|
+
} else {
|
|
19
|
+
data = nativeCSSPropertyData;
|
|
20
|
+
detail = nativeCSSPropertyData?.syntax;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
docs: '/reference/' + (data ? propName : 'utilities'),
|
|
25
|
+
data,
|
|
26
|
+
detail
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { getUtilityInfo as default };
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var vscodeLanguageserverProtocol = require('vscode-languageserver-protocol');
|
|
4
|
+
var cssDataProvider = require('./css-data-provider.cjs');
|
|
5
|
+
var css = require('@master/css');
|
|
6
|
+
var getCssDataDocumentation = require('./get-css-data-documentation.cjs');
|
|
7
|
+
var sortCompletionItems = require('./sort-completion-items.cjs');
|
|
8
|
+
|
|
9
|
+
const SCOPED_VARIABLE_PRIORITY = 'aaaa';
|
|
10
|
+
const AMBIGUOUS_PRIORITY = 'bbbb';
|
|
11
|
+
const NATIVE_PRIORITY = 'ccccc';
|
|
12
|
+
const GLOBAL_VARIABLE_PRIORITY = 'zzzz';
|
|
13
|
+
function getValueCompletionItems(css$1 = new css.MasterCSS(), ruleKey) {
|
|
14
|
+
const nativeProperties = cssDataProvider.provideProperties();
|
|
15
|
+
const completionItems = [];
|
|
16
|
+
const nativeKey = css$1.definedRules.find(({ keys })=>keys.includes(ruleKey))?.id;
|
|
17
|
+
const nativePropertyData = nativeProperties.find(({ name })=>name === nativeKey);
|
|
18
|
+
const generateVariableCompletionItem = (variable, { scoped } = {
|
|
19
|
+
scoped: false
|
|
20
|
+
})=>{
|
|
21
|
+
const eachNativePropertyData = nativeProperties.find((x)=>x.name === variable.group) || nativePropertyData;
|
|
22
|
+
const appliedValue = scoped ? variable.key : variable.name;
|
|
23
|
+
const documentation = getCssDataDocumentation.getCSSDataDocumentation(eachNativePropertyData, {
|
|
24
|
+
generatedCSS: css.generateCSS([
|
|
25
|
+
ruleKey + ':' + appliedValue
|
|
26
|
+
], css$1),
|
|
27
|
+
docs: '/reference/' + (eachNativePropertyData?.name || 'variables')
|
|
28
|
+
});
|
|
29
|
+
const completionItem = {
|
|
30
|
+
label: variable.name,
|
|
31
|
+
kind: vscodeLanguageserverProtocol.CompletionItemKind.Value
|
|
32
|
+
};
|
|
33
|
+
const conflicted = completionItems.find(({ label })=>label === variable.name);
|
|
34
|
+
if (conflicted) {
|
|
35
|
+
completionItem.label = '$(' + completionItem.label + ')';
|
|
36
|
+
completionItem.documentation = getCssDataDocumentation.getCSSDataDocumentation(eachNativePropertyData, {
|
|
37
|
+
generatedCSS: css.generateCSS([
|
|
38
|
+
ruleKey + ':' + completionItem.label
|
|
39
|
+
], css$1),
|
|
40
|
+
docs: '/reference/' + (eachNativePropertyData?.name || 'variables')
|
|
41
|
+
});
|
|
42
|
+
} else {
|
|
43
|
+
completionItem.documentation = getCssDataDocumentation.getCSSDataDocumentation(eachNativePropertyData, {
|
|
44
|
+
generatedCSS: css.generateCSS([
|
|
45
|
+
ruleKey + ':' + appliedValue
|
|
46
|
+
], css$1),
|
|
47
|
+
docs: '/reference/' + (eachNativePropertyData?.name || 'variables')
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (variable.type === 'color') {
|
|
51
|
+
if (Object.keys(variable.modes || {}).length) {
|
|
52
|
+
completionItem.kind = vscodeLanguageserverProtocol.CompletionItemKind.Color;
|
|
53
|
+
completionItem.detail = variable.name;
|
|
54
|
+
} else {
|
|
55
|
+
// todo: packages/core should support getTextByVariable(variable)
|
|
56
|
+
const configKey = 'variables.' + (variable.group ? variable.group + '.' + variable.key : variable.name);
|
|
57
|
+
const valueToken = variable.space && variable.value ? `${variable.space}(${variable.value.split(' ').join(',')})` : variable.value;
|
|
58
|
+
// detail is shown in the detail pane
|
|
59
|
+
// todo: variable.token should be recorded as original config variable
|
|
60
|
+
completionItem.detail = String(configKey);
|
|
61
|
+
completionItem.documentation = {
|
|
62
|
+
kind: 'markdown',
|
|
63
|
+
value: valueToken + '\n\n' + documentation?.value
|
|
64
|
+
};
|
|
65
|
+
completionItem.kind = vscodeLanguageserverProtocol.CompletionItemKind.Color;
|
|
66
|
+
completionItem.sortText = 'color-' + variable.name.replace(/(.+?)-(\d+)/, (match, prefix, num)=>prefix + num.padStart(10, '0'));
|
|
67
|
+
}
|
|
68
|
+
} else if (variable.type === 'number') {
|
|
69
|
+
if (variable.name.startsWith('-') && eachNativePropertyData?.syntax?.includes('absolute')) return;
|
|
70
|
+
completionItem.detail = String(variable.name);
|
|
71
|
+
completionItem.sortText = (variable.group || '') + (variable.value >= 0 ? String(variable.value).padStart(10, '0') : '-' + String(Math.abs(variable.value)).padStart(10, '0'));
|
|
72
|
+
} else {
|
|
73
|
+
completionItem.detail = String(variable.value || variable.name);
|
|
74
|
+
}
|
|
75
|
+
return completionItem;
|
|
76
|
+
};
|
|
77
|
+
for (const eachDefinedRule of css$1.definedRules){
|
|
78
|
+
/**
|
|
79
|
+
* Scoped variables
|
|
80
|
+
* @example box: + content -> box-sizing:content
|
|
81
|
+
*/ if (eachDefinedRule.definition.key === ruleKey || eachDefinedRule.definition.subkey === ruleKey || eachDefinedRule.definition.ambiguousKeys?.includes(ruleKey)) {
|
|
82
|
+
for(const variableName in eachDefinedRule.variables){
|
|
83
|
+
if (completionItems.find(({ label })=>label === variableName)) continue;
|
|
84
|
+
const variable = eachDefinedRule.variables[variableName];
|
|
85
|
+
const completionItem = generateVariableCompletionItem(variable, {
|
|
86
|
+
scoped: true
|
|
87
|
+
});
|
|
88
|
+
if (completionItem) {
|
|
89
|
+
completionItem.label = variableName;
|
|
90
|
+
completionItem.sortText = SCOPED_VARIABLE_PRIORITY + variableName;
|
|
91
|
+
completionItem.detail = '(scope) ' + completionItem.detail;
|
|
92
|
+
completionItems.push(completionItem);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* @example animation:fade
|
|
98
|
+
*/ if (eachDefinedRule.keys.includes(ruleKey) && eachDefinedRule.definition.includeAnimations) {
|
|
99
|
+
for(const animationName in css$1.animations){
|
|
100
|
+
const isNative = eachDefinedRule.definition.type && [
|
|
101
|
+
css.SyntaxRuleType.Native,
|
|
102
|
+
css.SyntaxRuleType.NativeShorthand
|
|
103
|
+
].includes(eachDefinedRule.definition.type);
|
|
104
|
+
completionItems.push({
|
|
105
|
+
label: animationName,
|
|
106
|
+
kind: vscodeLanguageserverProtocol.CompletionItemKind.Value,
|
|
107
|
+
documentation: getCssDataDocumentation.getCSSDataDocumentation(undefined, {
|
|
108
|
+
generatedCSS: css.generateCSS([
|
|
109
|
+
ruleKey + ':' + animationName
|
|
110
|
+
], css$1),
|
|
111
|
+
docs: '/reference/' + css.isCoreRule(eachDefinedRule.id) && eachDefinedRule.id
|
|
112
|
+
}),
|
|
113
|
+
detail: isNative ? eachDefinedRule.id + ': ' + animationName : animationName
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Ambiguous values
|
|
119
|
+
* @example text: -> center, left, right, justify
|
|
120
|
+
* @example t: -> center, left, right, justify
|
|
121
|
+
*/ if (eachDefinedRule.definition.ambiguousKeys?.includes(ruleKey) && eachDefinedRule.definition.ambiguousValues?.length) {
|
|
122
|
+
const nativePropertyData = nativeProperties.find((x)=>x.name === eachDefinedRule.id);
|
|
123
|
+
for (const ambiguousValue of eachDefinedRule.definition.ambiguousValues){
|
|
124
|
+
if (typeof ambiguousValue !== 'string') continue;
|
|
125
|
+
const nativeValueData = nativePropertyData?.values?.find((x)=>x.name === ambiguousValue);
|
|
126
|
+
const isNative = eachDefinedRule.definition.type && [
|
|
127
|
+
css.SyntaxRuleType.Native,
|
|
128
|
+
css.SyntaxRuleType.NativeShorthand
|
|
129
|
+
].includes(eachDefinedRule.definition.type);
|
|
130
|
+
completionItems.push({
|
|
131
|
+
label: ambiguousValue,
|
|
132
|
+
kind: vscodeLanguageserverProtocol.CompletionItemKind.Value,
|
|
133
|
+
sortText: AMBIGUOUS_PRIORITY + ambiguousValue,
|
|
134
|
+
documentation: getCssDataDocumentation.getCSSDataDocumentation({
|
|
135
|
+
...nativeValueData || {},
|
|
136
|
+
// use nativePropertyData.reference because nativeValueData does not have references
|
|
137
|
+
references: nativePropertyData?.references
|
|
138
|
+
}, {
|
|
139
|
+
generatedCSS: css.generateCSS([
|
|
140
|
+
ruleKey + ':' + ambiguousValue
|
|
141
|
+
], css$1),
|
|
142
|
+
docs: '/reference/' + css.isCoreRule(eachDefinedRule.id) && eachDefinedRule.id
|
|
143
|
+
}),
|
|
144
|
+
detail: isNative ? eachDefinedRule.id + ': ' + ambiguousValue : ambiguousValue
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Native values
|
|
151
|
+
*/ if (nativeKey) {
|
|
152
|
+
nativePropertyData?.values?.forEach((value)=>{
|
|
153
|
+
if (completionItems.find((x)=>x.label === value.name) || nativePropertyData.name === 'font' && typeof +value.name === 'number' || value.name.includes(' ')) return;
|
|
154
|
+
completionItems.push({
|
|
155
|
+
label: value.name,
|
|
156
|
+
kind: vscodeLanguageserverProtocol.CompletionItemKind.Value,
|
|
157
|
+
sortText: NATIVE_PRIORITY + (value.name.startsWith('-') ? 'zz' + value.name.slice(1) : value.name),
|
|
158
|
+
documentation: getCssDataDocumentation.getCSSDataDocumentation({
|
|
159
|
+
...value,
|
|
160
|
+
// use nativePropertyData.reference because nativeValueData does not have references
|
|
161
|
+
references: nativePropertyData?.references
|
|
162
|
+
}, {
|
|
163
|
+
generatedCSS: css.generateCSS([
|
|
164
|
+
ruleKey + ':' + value.name
|
|
165
|
+
], css$1),
|
|
166
|
+
docs: '/reference/' + nativeKey
|
|
167
|
+
}),
|
|
168
|
+
detail: nativeKey + ': ' + value.name
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
// global variables
|
|
173
|
+
for(const variableName in css$1.variables){
|
|
174
|
+
const variable = css$1.variables[variableName];
|
|
175
|
+
const completionItem = generateVariableCompletionItem(variable);
|
|
176
|
+
if (completionItem) {
|
|
177
|
+
completionItem.sortText = GLOBAL_VARIABLE_PRIORITY + (completionItem.sortText || completionItem.label);
|
|
178
|
+
completionItem.detail = '(global) ' + completionItem.detail;
|
|
179
|
+
completionItems.push(completionItem);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return sortCompletionItems(completionItems);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
module.exports = getValueCompletionItems;
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { CompletionItemKind } from 'vscode-languageserver-protocol';
|
|
2
|
+
import cssDataProvider from './css-data-provider.mjs';
|
|
3
|
+
import { SyntaxRuleType, generateCSS, isCoreRule, MasterCSS } from '@master/css';
|
|
4
|
+
import { getCSSDataDocumentation } from './get-css-data-documentation.mjs';
|
|
5
|
+
import sortCompletionItems from './sort-completion-items.mjs';
|
|
6
|
+
|
|
7
|
+
const SCOPED_VARIABLE_PRIORITY = 'aaaa';
|
|
8
|
+
const AMBIGUOUS_PRIORITY = 'bbbb';
|
|
9
|
+
const NATIVE_PRIORITY = 'ccccc';
|
|
10
|
+
const GLOBAL_VARIABLE_PRIORITY = 'zzzz';
|
|
11
|
+
function getValueCompletionItems(css = new MasterCSS(), ruleKey) {
|
|
12
|
+
const nativeProperties = cssDataProvider.provideProperties();
|
|
13
|
+
const completionItems = [];
|
|
14
|
+
const nativeKey = css.definedRules.find(({ keys })=>keys.includes(ruleKey))?.id;
|
|
15
|
+
const nativePropertyData = nativeProperties.find(({ name })=>name === nativeKey);
|
|
16
|
+
const generateVariableCompletionItem = (variable, { scoped } = {
|
|
17
|
+
scoped: false
|
|
18
|
+
})=>{
|
|
19
|
+
const eachNativePropertyData = nativeProperties.find((x)=>x.name === variable.group) || nativePropertyData;
|
|
20
|
+
const appliedValue = scoped ? variable.key : variable.name;
|
|
21
|
+
const documentation = getCSSDataDocumentation(eachNativePropertyData, {
|
|
22
|
+
generatedCSS: generateCSS([
|
|
23
|
+
ruleKey + ':' + appliedValue
|
|
24
|
+
], css),
|
|
25
|
+
docs: '/reference/' + (eachNativePropertyData?.name || 'variables')
|
|
26
|
+
});
|
|
27
|
+
const completionItem = {
|
|
28
|
+
label: variable.name,
|
|
29
|
+
kind: CompletionItemKind.Value
|
|
30
|
+
};
|
|
31
|
+
const conflicted = completionItems.find(({ label })=>label === variable.name);
|
|
32
|
+
if (conflicted) {
|
|
33
|
+
completionItem.label = '$(' + completionItem.label + ')';
|
|
34
|
+
completionItem.documentation = getCSSDataDocumentation(eachNativePropertyData, {
|
|
35
|
+
generatedCSS: generateCSS([
|
|
36
|
+
ruleKey + ':' + completionItem.label
|
|
37
|
+
], css),
|
|
38
|
+
docs: '/reference/' + (eachNativePropertyData?.name || 'variables')
|
|
39
|
+
});
|
|
40
|
+
} else {
|
|
41
|
+
completionItem.documentation = getCSSDataDocumentation(eachNativePropertyData, {
|
|
42
|
+
generatedCSS: generateCSS([
|
|
43
|
+
ruleKey + ':' + appliedValue
|
|
44
|
+
], css),
|
|
45
|
+
docs: '/reference/' + (eachNativePropertyData?.name || 'variables')
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
if (variable.type === 'color') {
|
|
49
|
+
if (Object.keys(variable.modes || {}).length) {
|
|
50
|
+
completionItem.kind = CompletionItemKind.Color;
|
|
51
|
+
completionItem.detail = variable.name;
|
|
52
|
+
} else {
|
|
53
|
+
// todo: packages/core should support getTextByVariable(variable)
|
|
54
|
+
const configKey = 'variables.' + (variable.group ? variable.group + '.' + variable.key : variable.name);
|
|
55
|
+
const valueToken = variable.space && variable.value ? `${variable.space}(${variable.value.split(' ').join(',')})` : variable.value;
|
|
56
|
+
// detail is shown in the detail pane
|
|
57
|
+
// todo: variable.token should be recorded as original config variable
|
|
58
|
+
completionItem.detail = String(configKey);
|
|
59
|
+
completionItem.documentation = {
|
|
60
|
+
kind: 'markdown',
|
|
61
|
+
value: valueToken + '\n\n' + documentation?.value
|
|
62
|
+
};
|
|
63
|
+
completionItem.kind = CompletionItemKind.Color;
|
|
64
|
+
completionItem.sortText = 'color-' + variable.name.replace(/(.+?)-(\d+)/, (match, prefix, num)=>prefix + num.padStart(10, '0'));
|
|
65
|
+
}
|
|
66
|
+
} else if (variable.type === 'number') {
|
|
67
|
+
if (variable.name.startsWith('-') && eachNativePropertyData?.syntax?.includes('absolute')) return;
|
|
68
|
+
completionItem.detail = String(variable.name);
|
|
69
|
+
completionItem.sortText = (variable.group || '') + (variable.value >= 0 ? String(variable.value).padStart(10, '0') : '-' + String(Math.abs(variable.value)).padStart(10, '0'));
|
|
70
|
+
} else {
|
|
71
|
+
completionItem.detail = String(variable.value || variable.name);
|
|
72
|
+
}
|
|
73
|
+
return completionItem;
|
|
74
|
+
};
|
|
75
|
+
for (const eachDefinedRule of css.definedRules){
|
|
76
|
+
/**
|
|
77
|
+
* Scoped variables
|
|
78
|
+
* @example box: + content -> box-sizing:content
|
|
79
|
+
*/ if (eachDefinedRule.definition.key === ruleKey || eachDefinedRule.definition.subkey === ruleKey || eachDefinedRule.definition.ambiguousKeys?.includes(ruleKey)) {
|
|
80
|
+
for(const variableName in eachDefinedRule.variables){
|
|
81
|
+
if (completionItems.find(({ label })=>label === variableName)) continue;
|
|
82
|
+
const variable = eachDefinedRule.variables[variableName];
|
|
83
|
+
const completionItem = generateVariableCompletionItem(variable, {
|
|
84
|
+
scoped: true
|
|
85
|
+
});
|
|
86
|
+
if (completionItem) {
|
|
87
|
+
completionItem.label = variableName;
|
|
88
|
+
completionItem.sortText = SCOPED_VARIABLE_PRIORITY + variableName;
|
|
89
|
+
completionItem.detail = '(scope) ' + completionItem.detail;
|
|
90
|
+
completionItems.push(completionItem);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* @example animation:fade
|
|
96
|
+
*/ if (eachDefinedRule.keys.includes(ruleKey) && eachDefinedRule.definition.includeAnimations) {
|
|
97
|
+
for(const animationName in css.animations){
|
|
98
|
+
const isNative = eachDefinedRule.definition.type && [
|
|
99
|
+
SyntaxRuleType.Native,
|
|
100
|
+
SyntaxRuleType.NativeShorthand
|
|
101
|
+
].includes(eachDefinedRule.definition.type);
|
|
102
|
+
completionItems.push({
|
|
103
|
+
label: animationName,
|
|
104
|
+
kind: CompletionItemKind.Value,
|
|
105
|
+
documentation: getCSSDataDocumentation(undefined, {
|
|
106
|
+
generatedCSS: generateCSS([
|
|
107
|
+
ruleKey + ':' + animationName
|
|
108
|
+
], css),
|
|
109
|
+
docs: '/reference/' + isCoreRule(eachDefinedRule.id) && eachDefinedRule.id
|
|
110
|
+
}),
|
|
111
|
+
detail: isNative ? eachDefinedRule.id + ': ' + animationName : animationName
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Ambiguous values
|
|
117
|
+
* @example text: -> center, left, right, justify
|
|
118
|
+
* @example t: -> center, left, right, justify
|
|
119
|
+
*/ if (eachDefinedRule.definition.ambiguousKeys?.includes(ruleKey) && eachDefinedRule.definition.ambiguousValues?.length) {
|
|
120
|
+
const nativePropertyData = nativeProperties.find((x)=>x.name === eachDefinedRule.id);
|
|
121
|
+
for (const ambiguousValue of eachDefinedRule.definition.ambiguousValues){
|
|
122
|
+
if (typeof ambiguousValue !== 'string') continue;
|
|
123
|
+
const nativeValueData = nativePropertyData?.values?.find((x)=>x.name === ambiguousValue);
|
|
124
|
+
const isNative = eachDefinedRule.definition.type && [
|
|
125
|
+
SyntaxRuleType.Native,
|
|
126
|
+
SyntaxRuleType.NativeShorthand
|
|
127
|
+
].includes(eachDefinedRule.definition.type);
|
|
128
|
+
completionItems.push({
|
|
129
|
+
label: ambiguousValue,
|
|
130
|
+
kind: CompletionItemKind.Value,
|
|
131
|
+
sortText: AMBIGUOUS_PRIORITY + ambiguousValue,
|
|
132
|
+
documentation: getCSSDataDocumentation({
|
|
133
|
+
...nativeValueData || {},
|
|
134
|
+
// use nativePropertyData.reference because nativeValueData does not have references
|
|
135
|
+
references: nativePropertyData?.references
|
|
136
|
+
}, {
|
|
137
|
+
generatedCSS: generateCSS([
|
|
138
|
+
ruleKey + ':' + ambiguousValue
|
|
139
|
+
], css),
|
|
140
|
+
docs: '/reference/' + isCoreRule(eachDefinedRule.id) && eachDefinedRule.id
|
|
141
|
+
}),
|
|
142
|
+
detail: isNative ? eachDefinedRule.id + ': ' + ambiguousValue : ambiguousValue
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Native values
|
|
149
|
+
*/ if (nativeKey) {
|
|
150
|
+
nativePropertyData?.values?.forEach((value)=>{
|
|
151
|
+
if (completionItems.find((x)=>x.label === value.name) || nativePropertyData.name === 'font' && typeof +value.name === 'number' || value.name.includes(' ')) return;
|
|
152
|
+
completionItems.push({
|
|
153
|
+
label: value.name,
|
|
154
|
+
kind: CompletionItemKind.Value,
|
|
155
|
+
sortText: NATIVE_PRIORITY + (value.name.startsWith('-') ? 'zz' + value.name.slice(1) : value.name),
|
|
156
|
+
documentation: getCSSDataDocumentation({
|
|
157
|
+
...value,
|
|
158
|
+
// use nativePropertyData.reference because nativeValueData does not have references
|
|
159
|
+
references: nativePropertyData?.references
|
|
160
|
+
}, {
|
|
161
|
+
generatedCSS: generateCSS([
|
|
162
|
+
ruleKey + ':' + value.name
|
|
163
|
+
], css),
|
|
164
|
+
docs: '/reference/' + nativeKey
|
|
165
|
+
}),
|
|
166
|
+
detail: nativeKey + ': ' + value.name
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
// global variables
|
|
171
|
+
for(const variableName in css.variables){
|
|
172
|
+
const variable = css.variables[variableName];
|
|
173
|
+
const completionItem = generateVariableCompletionItem(variable);
|
|
174
|
+
if (completionItem) {
|
|
175
|
+
completionItem.sortText = GLOBAL_VARIABLE_PRIORITY + (completionItem.sortText || completionItem.label);
|
|
176
|
+
completionItem.detail = '(global) ' + completionItem.detail;
|
|
177
|
+
completionItems.push(completionItem);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return sortCompletionItems(completionItems);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export { getValueCompletionItems as default };
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var vscodeLanguageserverProtocol = require('vscode-languageserver-protocol');
|
|
4
|
+
var getPseudoClassCompletionItems = require('./get-pseudo-class-completion-items.cjs');
|
|
5
|
+
var getPseudoElementCompletionItems = require('./get-pseudo-element-completion-items.cjs');
|
|
6
|
+
var css = require('@master/css');
|
|
7
|
+
var common = require('../common.cjs');
|
|
8
|
+
var getMainCompletionItems = require('./get-main-completion-items.cjs');
|
|
9
|
+
var getValueCompletionItems = require('./get-value-completion-items.cjs');
|
|
10
|
+
var getQueryCompletionItems = require('./get-query-completion-items.cjs');
|
|
11
|
+
var getCssDataDocumentation = require('./get-css-data-documentation.cjs');
|
|
12
|
+
|
|
13
|
+
function querySyntaxCompletions(q = '', css$1 = new css.MasterCSS()) {
|
|
14
|
+
const fields = q.split(' ');
|
|
15
|
+
let field = fields[fields.length - 1];
|
|
16
|
+
const triggerCharacter = q.charAt(q.length - 1);
|
|
17
|
+
const invoked = triggerCharacter === ' ' || field.length === 0;
|
|
18
|
+
if (invoked || field === common.GROUP_TRIGGER_CHARACTER || triggerCharacter === ';') {
|
|
19
|
+
return getMainCompletionItems(css$1);
|
|
20
|
+
}
|
|
21
|
+
const isGroup = field.startsWith(common.GROUP_TRIGGER_CHARACTER);
|
|
22
|
+
if (isGroup) {
|
|
23
|
+
const declarationSeparatorMatches = Array.from(field.matchAll(/;(?=(?:[^'"]|'[^']*'|"[^"]*")*$)/g));
|
|
24
|
+
if (declarationSeparatorMatches.length) {
|
|
25
|
+
field = field.slice(declarationSeparatorMatches[declarationSeparatorMatches.length - 1].index + 1);
|
|
26
|
+
} else {
|
|
27
|
+
field = field.slice(1);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const signs = css$1.definedRules.filter(({ definition })=>definition.sign).map(({ definition })=>definition.sign);
|
|
31
|
+
const keyMatch = field.match(new RegExp(`^[^${signs}'":\\s]+:`));
|
|
32
|
+
const atMatches = Array.from(field.matchAll(/@(?=(?:[^'"]|'[^']*'|"[^"]*")*$)/g));
|
|
33
|
+
const valueSeparatorMatch = field.match(/\|(?=(?:[^'"]|'[^']*'|"[^"]*")*$)/g);
|
|
34
|
+
const atInvoked = atMatches.findIndex(({ index })=>index !== 0) !== -1;
|
|
35
|
+
const firstColonIndex = keyMatch ? keyMatch[0].length - 1 : -1;
|
|
36
|
+
const selectorInvokedRegex = new RegExp(`[${css.SELECTOR_SIGNS.join('')}](?=(?:[^'"]|'[^']*'|"[^"]*")*$)`);
|
|
37
|
+
const key = keyMatch ? keyMatch[0].slice(0, firstColonIndex) : undefined;
|
|
38
|
+
const componentNames = Object.keys(css$1.config.components || {});
|
|
39
|
+
const utilityNames = Object.keys(css$1.config.utilities || {});
|
|
40
|
+
const isStyle = !!componentNames.find((eachStyleName)=>new RegExp(`^${eachStyleName}(?:\\b|_)`).test(field));
|
|
41
|
+
const isUtility = !!utilityNames.find((eachUtilityName)=>new RegExp(`^${eachUtilityName}(?:\\b|_)`).test(field));
|
|
42
|
+
// check by utilities and components
|
|
43
|
+
if (!isStyle && !isUtility) {
|
|
44
|
+
if (key === undefined && !valueSeparatorMatch) {
|
|
45
|
+
/**
|
|
46
|
+
* The server capability sets '@' '~' as the trigger characters for at and adjacent selectors,
|
|
47
|
+
* but these two characters are also the prefix symbols of `animation` and `transition`,
|
|
48
|
+
* and should be filtered to prevent hints all completions items.
|
|
49
|
+
* @example class="@"
|
|
50
|
+
* @example class="~"
|
|
51
|
+
*/ if (field.startsWith(css.ANIMATION_SIGN) || field.startsWith(css.TRANSITION_SIGN)) {
|
|
52
|
+
return getMainCompletionItems(css$1).filter((completionItem)=>completionItem.label.startsWith(field)).map((completionItem)=>({
|
|
53
|
+
...completionItem,
|
|
54
|
+
label: completionItem.label.slice(1)
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
return getMainCompletionItems(css$1);
|
|
58
|
+
}
|
|
59
|
+
if (!atInvoked && !selectorInvokedRegex.test(field.slice(firstColonIndex + 1))) {
|
|
60
|
+
if (field.startsWith(css.ANIMATION_SIGN) && firstColonIndex === -1) {
|
|
61
|
+
return getValueCompletionItems(css$1, 'animation');
|
|
62
|
+
} else if (field.startsWith(css.TRANSITION_SIGN) && firstColonIndex === -1) {
|
|
63
|
+
return getValueCompletionItems(css$1, 'transition');
|
|
64
|
+
} else if (key && firstColonIndex !== -1) {
|
|
65
|
+
return getValueCompletionItems(css$1, key);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Not support conditional btn:hover and group
|
|
71
|
+
*/ if (isStyle || isGroup) return;
|
|
72
|
+
if (atInvoked && [
|
|
73
|
+
css.AT_SIGN,
|
|
74
|
+
...css.QUERY_COMPARISON_OPERATORS,
|
|
75
|
+
...css.QUERY_LOGICAL_OPERATORS
|
|
76
|
+
].includes(triggerCharacter)) {
|
|
77
|
+
return getQueryCompletionItems(css$1, triggerCharacter, field);
|
|
78
|
+
}
|
|
79
|
+
if (!atInvoked && common.SELECTOR_TRIGGER_CHARACTERS.includes(triggerCharacter)) {
|
|
80
|
+
const pseudoElementCompletionItems = getPseudoElementCompletionItems(css$1, field);
|
|
81
|
+
if (field.endsWith('::')) {
|
|
82
|
+
/**
|
|
83
|
+
* Consider trigger characters and fix insertText.
|
|
84
|
+
* @incorrect class="text:center::" -> class="text:center::::after"
|
|
85
|
+
* @correct class="text:center::" -> class="text:center::after"
|
|
86
|
+
*/ pseudoElementCompletionItems.forEach((completionItem)=>completionItem.insertText = completionItem.label.slice(2));
|
|
87
|
+
return pseudoElementCompletionItems;
|
|
88
|
+
} else {
|
|
89
|
+
const completionItems = getPseudoClassCompletionItems(css$1, field);
|
|
90
|
+
completionItems.push(...pseudoElementCompletionItems);
|
|
91
|
+
/**
|
|
92
|
+
* Consider trigger characters and fix insertText.
|
|
93
|
+
* @incorrect class="text:center:" -> class="text:center::active"
|
|
94
|
+
* @correct class="text:center:" -> class="text:center:active"
|
|
95
|
+
*/ if (triggerCharacter === ':') {
|
|
96
|
+
completionItems.forEach((completionItem)=>completionItem.insertText = completionItem.label.slice(1));
|
|
97
|
+
} else {
|
|
98
|
+
completionItems.push({
|
|
99
|
+
label: '.<class>',
|
|
100
|
+
insertText: '.',
|
|
101
|
+
documentation: getCssDataDocumentation.getCSSDataDocumentation(undefined, {
|
|
102
|
+
generatedCSS: css.generateCSS([
|
|
103
|
+
field + '.class'
|
|
104
|
+
], css$1),
|
|
105
|
+
docs: '/guide/syntax#selectors'
|
|
106
|
+
}),
|
|
107
|
+
kind: vscodeLanguageserverProtocol.CompletionItemKind.Class
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
return completionItems;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
module.exports = querySyntaxCompletions;
|