@master/css-language-service 2.0.0-rc.6 → 2.0.0-rc.60
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/README.md +63 -0
- 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 +29 -0
- package/dist/utils/get-color-completion-items.d.ts +3 -0
- package/dist/utils/get-color-completion-items.mjs +27 -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 +106 -0
- package/dist/utils/get-main-completion-items.d.ts +3 -0
- package/dist/utils/get-main-completion-items.mjs +104 -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 +184 -0
- package/dist/utils/get-value-completion-items.d.ts +3 -0
- package/dist/utils/get-value-completion-items.mjs +182 -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,54 @@
|
|
|
1
|
+
import { MasterCSS, generateCSS } from '@master/css';
|
|
2
|
+
import cssDataProvider from './css-data-provider.mjs';
|
|
3
|
+
import { CompletionItemKind } from 'vscode-languageserver-protocol';
|
|
4
|
+
import sortCompletionItems from './sort-completion-items.mjs';
|
|
5
|
+
import { getCSSDataDocumentation } from './get-css-data-documentation.mjs';
|
|
6
|
+
|
|
7
|
+
const kind = CompletionItemKind.Function;
|
|
8
|
+
function getPseudoElementCompletionItems(css = new MasterCSS(), syntax) {
|
|
9
|
+
const pseudoElementDataList = cssDataProvider.providePseudoElements();
|
|
10
|
+
const completionItems = pseudoElementDataList.map((data)=>{
|
|
11
|
+
// fix https://github.com/microsoft/vscode-custom-data/issues/78
|
|
12
|
+
const name = /::(?:part|slotted)/.test(data.name) ? data.name + '()' : data.name;
|
|
13
|
+
let sortText = name.startsWith('::-') ? 'zzzz' + name.slice(3) : 'zz' + name.replace(/^::/, '');
|
|
14
|
+
if (sortText.endsWith('()')) sortText = 'z' + sortText;
|
|
15
|
+
return {
|
|
16
|
+
label: name,
|
|
17
|
+
sortText,
|
|
18
|
+
documentation: getCSSDataDocumentation(data, {
|
|
19
|
+
generatedCSS: generateCSS([
|
|
20
|
+
syntax + name.slice(2)
|
|
21
|
+
], css),
|
|
22
|
+
docs: '/guide/syntax#selectors'
|
|
23
|
+
}),
|
|
24
|
+
kind,
|
|
25
|
+
data
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
for(const selectorName in css.config.selectors){
|
|
29
|
+
if (!selectorName.startsWith('::')) continue;
|
|
30
|
+
const selectorValue = css.config.selectors[selectorName];
|
|
31
|
+
const name = selectorName.endsWith('(') ? selectorName + ')' : selectorName;
|
|
32
|
+
const value = typeof selectorValue === 'string' ? selectorValue.endsWith('(') ? selectorValue + ')' : selectorValue : selectorValue;
|
|
33
|
+
const data = pseudoElementDataList.find((data)=>typeof value === 'string' ? value.startsWith(data.name) : false);
|
|
34
|
+
let sortText = name.startsWith('::-') ? 'zzzz' + name.slice(3) : 'zz' + name.replace(/^::/, '');
|
|
35
|
+
if (sortText.endsWith('()')) sortText = 'z' + sortText;
|
|
36
|
+
const completionItem = {
|
|
37
|
+
label: name,
|
|
38
|
+
documentation: getCSSDataDocumentation(data, {
|
|
39
|
+
generatedCSS: generateCSS([
|
|
40
|
+
syntax + name.slice(2)
|
|
41
|
+
], css),
|
|
42
|
+
docs: '/guide/syntax#selectors'
|
|
43
|
+
}),
|
|
44
|
+
sortText,
|
|
45
|
+
kind,
|
|
46
|
+
detail: String(value),
|
|
47
|
+
data
|
|
48
|
+
};
|
|
49
|
+
completionItems.push(completionItem);
|
|
50
|
+
}
|
|
51
|
+
return sortCompletionItems(completionItems);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { getPseudoElementCompletionItems as default };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var css = require('@master/css');
|
|
4
|
+
var vscodeLanguageserverProtocol = require('vscode-languageserver-protocol');
|
|
5
|
+
var sortCompletionItems = require('./sort-completion-items.cjs');
|
|
6
|
+
var getCssDataDocumentation = require('./get-css-data-documentation.cjs');
|
|
7
|
+
var cssDataProvider = require('./css-data-provider.cjs');
|
|
8
|
+
|
|
9
|
+
function getQueryCompletionItems(css$1 = new css.MasterCSS(), triggerCharacter = css.AT_SIGN, syntax) {
|
|
10
|
+
const atDataList = cssDataProvider.provideAtDirectives();
|
|
11
|
+
const completionItems = [];
|
|
12
|
+
if (!css.QUERY_COMPARISON_OPERATORS.includes(triggerCharacter)) {
|
|
13
|
+
completionItems.push({
|
|
14
|
+
label: triggerCharacter + 'media()',
|
|
15
|
+
filterText: 'media()',
|
|
16
|
+
insertText: 'media()',
|
|
17
|
+
sortText: 'media()',
|
|
18
|
+
documentation: getCssDataDocumentation.getCSSDataDocumentation(atDataList.find(({ name })=>name === '@media'), {
|
|
19
|
+
generatedCSS: css.generateCSS([
|
|
20
|
+
syntax + 'media()'
|
|
21
|
+
], css$1),
|
|
22
|
+
docs: '/guide/syntax#at-rules'
|
|
23
|
+
})
|
|
24
|
+
}, {
|
|
25
|
+
label: triggerCharacter + 'supports()',
|
|
26
|
+
filterText: 'supports()',
|
|
27
|
+
insertText: 'supports()',
|
|
28
|
+
sortText: 'supports()',
|
|
29
|
+
documentation: getCssDataDocumentation.getCSSDataDocumentation(atDataList.find(({ name })=>name === '@supports'), {
|
|
30
|
+
generatedCSS: css.generateCSS([
|
|
31
|
+
syntax + 'supports()'
|
|
32
|
+
], css$1),
|
|
33
|
+
docs: '/guide/syntax#at-rules'
|
|
34
|
+
})
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
css$1.at.forEach((value, name)=>{
|
|
38
|
+
const completionItem = {
|
|
39
|
+
filterText: name,
|
|
40
|
+
insertText: name,
|
|
41
|
+
documentation: getCssDataDocumentation.getCSSDataDocumentation(undefined, {
|
|
42
|
+
generatedCSS: css.generateCSS([
|
|
43
|
+
syntax + name
|
|
44
|
+
], css$1),
|
|
45
|
+
docs: '/guide/syntax#at-rules'
|
|
46
|
+
})
|
|
47
|
+
};
|
|
48
|
+
if ([
|
|
49
|
+
css.AT_SIGN,
|
|
50
|
+
...css.QUERY_LOGICAL_OPERATORS
|
|
51
|
+
].includes(triggerCharacter)) {
|
|
52
|
+
if (typeof value === 'number') {
|
|
53
|
+
completionItems.push({
|
|
54
|
+
...completionItem,
|
|
55
|
+
label: triggerCharacter + name,
|
|
56
|
+
sortText: String(value).padStart(8, '0'),
|
|
57
|
+
filterText: name,
|
|
58
|
+
insertText: name,
|
|
59
|
+
documentation: getCssDataDocumentation.getCSSDataDocumentation(undefined, {
|
|
60
|
+
generatedCSS: css.generateCSS([
|
|
61
|
+
syntax + name
|
|
62
|
+
], css$1),
|
|
63
|
+
docs: '/guide/syntax#at-rules'
|
|
64
|
+
}),
|
|
65
|
+
detail: `screen width ${'>='} ${value}px`,
|
|
66
|
+
kind: vscodeLanguageserverProtocol.CompletionItemKind.Keyword
|
|
67
|
+
});
|
|
68
|
+
} else {
|
|
69
|
+
completionItems.push({
|
|
70
|
+
...completionItem,
|
|
71
|
+
label: triggerCharacter + name,
|
|
72
|
+
detail: value,
|
|
73
|
+
sortText: name,
|
|
74
|
+
kind: vscodeLanguageserverProtocol.CompletionItemKind.Keyword
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
} else if (css.QUERY_COMPARISON_OPERATORS.includes(triggerCharacter)) {
|
|
78
|
+
if (typeof value === 'number') {
|
|
79
|
+
const prevComparisonCharacter = syntax.charAt(syntax.length - 2);
|
|
80
|
+
const comparisonCharacter = prevComparisonCharacter === '>' || prevComparisonCharacter === '<' ? prevComparisonCharacter + triggerCharacter : triggerCharacter;
|
|
81
|
+
completionItems.push({
|
|
82
|
+
...completionItem,
|
|
83
|
+
label: comparisonCharacter + name,
|
|
84
|
+
sortText: comparisonCharacter + String(value).padStart(8, '0'),
|
|
85
|
+
filterText: name,
|
|
86
|
+
insertText: name,
|
|
87
|
+
documentation: getCssDataDocumentation.getCSSDataDocumentation(undefined, {
|
|
88
|
+
generatedCSS: css.generateCSS([
|
|
89
|
+
syntax + name
|
|
90
|
+
], css$1),
|
|
91
|
+
docs: '/guide/syntax#at-rules'
|
|
92
|
+
}),
|
|
93
|
+
detail: `screen width ${comparisonCharacter} ${value}px`,
|
|
94
|
+
kind: vscodeLanguageserverProtocol.CompletionItemKind.Keyword
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
return sortCompletionItems(completionItems);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
module.exports = getQueryCompletionItems;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { MasterCSS, AT_SIGN, QUERY_COMPARISON_OPERATORS, generateCSS, QUERY_LOGICAL_OPERATORS } from '@master/css';
|
|
2
|
+
import { CompletionItemKind } from 'vscode-languageserver-protocol';
|
|
3
|
+
import sortCompletionItems from './sort-completion-items.mjs';
|
|
4
|
+
import { getCSSDataDocumentation } from './get-css-data-documentation.mjs';
|
|
5
|
+
import cssDataProvider from './css-data-provider.mjs';
|
|
6
|
+
|
|
7
|
+
function getQueryCompletionItems(css = new MasterCSS(), triggerCharacter = AT_SIGN, syntax) {
|
|
8
|
+
const atDataList = cssDataProvider.provideAtDirectives();
|
|
9
|
+
const completionItems = [];
|
|
10
|
+
if (!QUERY_COMPARISON_OPERATORS.includes(triggerCharacter)) {
|
|
11
|
+
completionItems.push({
|
|
12
|
+
label: triggerCharacter + 'media()',
|
|
13
|
+
filterText: 'media()',
|
|
14
|
+
insertText: 'media()',
|
|
15
|
+
sortText: 'media()',
|
|
16
|
+
documentation: getCSSDataDocumentation(atDataList.find(({ name })=>name === '@media'), {
|
|
17
|
+
generatedCSS: generateCSS([
|
|
18
|
+
syntax + 'media()'
|
|
19
|
+
], css),
|
|
20
|
+
docs: '/guide/syntax#at-rules'
|
|
21
|
+
})
|
|
22
|
+
}, {
|
|
23
|
+
label: triggerCharacter + 'supports()',
|
|
24
|
+
filterText: 'supports()',
|
|
25
|
+
insertText: 'supports()',
|
|
26
|
+
sortText: 'supports()',
|
|
27
|
+
documentation: getCSSDataDocumentation(atDataList.find(({ name })=>name === '@supports'), {
|
|
28
|
+
generatedCSS: generateCSS([
|
|
29
|
+
syntax + 'supports()'
|
|
30
|
+
], css),
|
|
31
|
+
docs: '/guide/syntax#at-rules'
|
|
32
|
+
})
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
css.at.forEach((value, name)=>{
|
|
36
|
+
const completionItem = {
|
|
37
|
+
filterText: name,
|
|
38
|
+
insertText: name,
|
|
39
|
+
documentation: getCSSDataDocumentation(undefined, {
|
|
40
|
+
generatedCSS: generateCSS([
|
|
41
|
+
syntax + name
|
|
42
|
+
], css),
|
|
43
|
+
docs: '/guide/syntax#at-rules'
|
|
44
|
+
})
|
|
45
|
+
};
|
|
46
|
+
if ([
|
|
47
|
+
AT_SIGN,
|
|
48
|
+
...QUERY_LOGICAL_OPERATORS
|
|
49
|
+
].includes(triggerCharacter)) {
|
|
50
|
+
if (typeof value === 'number') {
|
|
51
|
+
completionItems.push({
|
|
52
|
+
...completionItem,
|
|
53
|
+
label: triggerCharacter + name,
|
|
54
|
+
sortText: String(value).padStart(8, '0'),
|
|
55
|
+
filterText: name,
|
|
56
|
+
insertText: name,
|
|
57
|
+
documentation: getCSSDataDocumentation(undefined, {
|
|
58
|
+
generatedCSS: generateCSS([
|
|
59
|
+
syntax + name
|
|
60
|
+
], css),
|
|
61
|
+
docs: '/guide/syntax#at-rules'
|
|
62
|
+
}),
|
|
63
|
+
detail: `screen width ${'>='} ${value}px`,
|
|
64
|
+
kind: CompletionItemKind.Keyword
|
|
65
|
+
});
|
|
66
|
+
} else {
|
|
67
|
+
completionItems.push({
|
|
68
|
+
...completionItem,
|
|
69
|
+
label: triggerCharacter + name,
|
|
70
|
+
detail: value,
|
|
71
|
+
sortText: name,
|
|
72
|
+
kind: CompletionItemKind.Keyword
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
} else if (QUERY_COMPARISON_OPERATORS.includes(triggerCharacter)) {
|
|
76
|
+
if (typeof value === 'number') {
|
|
77
|
+
const prevComparisonCharacter = syntax.charAt(syntax.length - 2);
|
|
78
|
+
const comparisonCharacter = prevComparisonCharacter === '>' || prevComparisonCharacter === '<' ? prevComparisonCharacter + triggerCharacter : triggerCharacter;
|
|
79
|
+
completionItems.push({
|
|
80
|
+
...completionItem,
|
|
81
|
+
label: comparisonCharacter + name,
|
|
82
|
+
sortText: comparisonCharacter + String(value).padStart(8, '0'),
|
|
83
|
+
filterText: name,
|
|
84
|
+
insertText: name,
|
|
85
|
+
documentation: getCSSDataDocumentation(undefined, {
|
|
86
|
+
generatedCSS: generateCSS([
|
|
87
|
+
syntax + name
|
|
88
|
+
], css),
|
|
89
|
+
docs: '/guide/syntax#at-rules'
|
|
90
|
+
}),
|
|
91
|
+
detail: `screen width ${comparisonCharacter} ${value}px`,
|
|
92
|
+
kind: CompletionItemKind.Keyword
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
return sortCompletionItems(completionItems);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export { getQueryCompletionItems as default };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// todo: unstable range calculation
|
|
4
|
+
function getRange(searchString, doc) {
|
|
5
|
+
const text = doc.getText();
|
|
6
|
+
const regex = new RegExp(`(\\b(?:className|class)\\s?=\\s?(['"\`]))(.*?)\\2`, 'g');
|
|
7
|
+
const classAttMatch = regex.exec(text);
|
|
8
|
+
if (classAttMatch) {
|
|
9
|
+
const attrIndex = classAttMatch.index + classAttMatch[1].length;
|
|
10
|
+
const className = classAttMatch[3];
|
|
11
|
+
const index = className.indexOf(searchString);
|
|
12
|
+
return {
|
|
13
|
+
start: doc.positionAt(attrIndex + index),
|
|
14
|
+
end: doc.positionAt(attrIndex + index + searchString.length)
|
|
15
|
+
};
|
|
16
|
+
} else {
|
|
17
|
+
throw new Error(`Cannot find ${searchString} in ${text}`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = getRange;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// todo: unstable range calculation
|
|
2
|
+
function getRange(searchString, doc) {
|
|
3
|
+
const text = doc.getText();
|
|
4
|
+
const regex = new RegExp(`(\\b(?:className|class)\\s?=\\s?(['"\`]))(.*?)\\2`, 'g');
|
|
5
|
+
const classAttMatch = regex.exec(text);
|
|
6
|
+
if (classAttMatch) {
|
|
7
|
+
const attrIndex = classAttMatch.index + classAttMatch[1].length;
|
|
8
|
+
const className = classAttMatch[3];
|
|
9
|
+
const index = className.indexOf(searchString);
|
|
10
|
+
return {
|
|
11
|
+
start: doc.positionAt(attrIndex + index),
|
|
12
|
+
end: doc.positionAt(attrIndex + index + searchString.length)
|
|
13
|
+
};
|
|
14
|
+
} else {
|
|
15
|
+
throw new Error(`Cannot find ${searchString} in ${text}`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export { getRange as default };
|
|
@@ -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,184 @@
|
|
|
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
|
+
css$1.animations.forEach((animation, animationName)=>{
|
|
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
|
+
css$1.variables.forEach((variable)=>{
|
|
174
|
+
const completionItem = generateVariableCompletionItem(variable);
|
|
175
|
+
if (completionItem) {
|
|
176
|
+
completionItem.sortText = GLOBAL_VARIABLE_PRIORITY + (completionItem.sortText || completionItem.label);
|
|
177
|
+
completionItem.detail = '(global) ' + completionItem.detail;
|
|
178
|
+
completionItems.push(completionItem);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
return sortCompletionItems(completionItems);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
module.exports = getValueCompletionItems;
|