parserlib: reuse global keywords
This commit is contained in:
parent
9d6542a39d
commit
8e36e0277f
|
@ -16,17 +16,11 @@
|
|||
const rxVAR = /(^|[^-.\w\u0080-\uFFFF])var\(/iyu;
|
||||
const rxCONSUME = /([-\w]*\s*:\s?)?/yu;
|
||||
const cssMime = CodeMirror.mimeModes['text/css'];
|
||||
const cssGlobalValues = [
|
||||
'inherit',
|
||||
'initial',
|
||||
'revert',
|
||||
'unset',
|
||||
];
|
||||
const docFuncs = addSuffix(cssMime.documentTypes, '(');
|
||||
const {tokenHooks} = cssMime;
|
||||
const originalCommentHook = tokenHooks['/'];
|
||||
const originalHelper = CodeMirror.hint.css || (() => {});
|
||||
let cssMedia, cssProps, cssPropsValues;
|
||||
let cssMedia, cssProps, cssValues;
|
||||
|
||||
const AOT_ID = 'autocompleteOnTyping';
|
||||
const AOT_PREF_ID = 'editor.' + AOT_ID;
|
||||
|
@ -148,8 +142,8 @@
|
|||
leftLC = leftLC.replace(/^[^\w\s]\s*/, '');
|
||||
}
|
||||
if (prop.startsWith('--')) prop = 'color'; // assuming 90% of variables are colors
|
||||
if (!cssPropsValues) cssPropsValues = await linterMan.worker.getCssPropsValues();
|
||||
list = [...new Set([...cssPropsValues[prop] || [], ...cssGlobalValues])];
|
||||
if (!cssValues) cssValues = await linterMan.worker.getCssPropsValues();
|
||||
list = [...new Set([...cssValues.own[prop] || [], ...cssValues.global])];
|
||||
end = prev + execAt(/(\s*[-a-z(]+)?/y, prev, text)[0].length;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,10 @@
|
|||
|
||||
getCssPropsValues() {
|
||||
require(['/js/csslint/parserlib']); /* global parserlib */
|
||||
const {css: {Colors, Properties}, util: {describeProp}} = parserlib;
|
||||
const {
|
||||
css: {Colors, GlobalKeywords, Properties},
|
||||
util: {describeProp},
|
||||
} = parserlib;
|
||||
const namedColors = Object.keys(Colors);
|
||||
const rxNonWord = /(?:<.+?>|[^-\w<(]+\d*)+/g;
|
||||
const res = {};
|
||||
|
@ -41,7 +44,7 @@
|
|||
if (uniq.length) res[k] = uniq;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
return {own: res, global: GlobalKeywords};
|
||||
},
|
||||
|
||||
getRules(linter) {
|
||||
|
|
|
@ -30,12 +30,18 @@ self.parserlib = (() => {
|
|||
|
||||
//#region Properties
|
||||
|
||||
// Global keywords that can be set for any property are conveniently listed in `all` prop:
|
||||
// https://drafts.csswg.org/css-cascade/#all-shorthand
|
||||
const GlobalKeywords = ['initial', 'inherit', 'revert', 'unset'];
|
||||
const isGlobalKeyword = RegExp.prototype.test.bind(
|
||||
new RegExp(`^(${GlobalKeywords.join('|')})$`, 'i'));
|
||||
|
||||
const Properties = {
|
||||
'accent-color': 'auto | <color>',
|
||||
'align-items': 'normal | stretch | <baseline-position> | [ <overflow-position>? <self-position> ]',
|
||||
'align-content': '<align-content>',
|
||||
'align-self': '<align-self>',
|
||||
'all': 'initial | inherit | revert | unset',
|
||||
'all': GlobalKeywords.join(' | '),
|
||||
'alignment-adjust': 'auto | baseline | before-edge | text-before-edge | middle | central | ' +
|
||||
'after-edge | text-after-edge | ideographic | alphabetic | hanging | ' +
|
||||
'mathematical | <length-pct>',
|
||||
|
@ -702,8 +708,8 @@ self.parserlib = (() => {
|
|||
const VTSimple = {
|
||||
'<absolute-size>': 'xx-small | x-small | small | medium | large | x-large | xx-large',
|
||||
'<animateable-feature>': 'scroll-position | contents | <animateable-feature-name>',
|
||||
'<animateable-feature-name>': p => vtIsIdent(p) &&
|
||||
!/^(unset|initial|inherit|will-change|auto|scroll-position|contents)$/i.test(p),
|
||||
'<animateable-feature-name>': p => vtIsIdent(p) && !isGlobalKeyword(p) &&
|
||||
!/^(will-change|auto|scroll-position|contents)$/i.test(p),
|
||||
'<angle>': p => p.type === 'angle' || p.isCalc,
|
||||
'<angle-or-0>': p => p.text === '0' || p.type === 'angle' || p.isCalc,
|
||||
'<attr>': vtIsAttr,
|
||||
|
@ -752,8 +758,8 @@ self.parserlib = (() => {
|
|||
'<hex-color>': p => p.tokenType === Tokens.HASH, //eslint-disable-line no-use-before-define
|
||||
'<icccolor>': 'cielab() | cielch() | cielchab() | icc-color() | icc-named-color()',
|
||||
'<ident>': vtIsIdent,
|
||||
'<ident-for-grid>': p => vtIsIdent(p) &&
|
||||
!/^(span|auto|initial|inherit|unset|default)$/i.test(p.value),
|
||||
'<ident-for-grid>': p => vtIsIdent(p) && !isGlobalKeyword(p.value) &&
|
||||
!/^(span|auto|default)$/i.test(p.value),
|
||||
'<ident-not-generic-family>': p => vtIsIdent(p) && !VTSimple['<generic-family>'](p),
|
||||
'<ident-not-none>': p => vtIsIdent(p) && !lowerCmp(p.value, 'none'),
|
||||
'<image>': '<uri> | <gradient> | cross-fade()',
|
||||
|
@ -793,8 +799,8 @@ self.parserlib = (() => {
|
|||
'<shape-box>': '<box> | margin-box',
|
||||
'<single-animation-direction>': 'normal | reverse | alternate | alternate-reverse',
|
||||
'<single-animation-fill-mode>': 'none | forwards | backwards | both',
|
||||
'<single-animation-name>': p => vtIsIdent(p) &&
|
||||
/^(?!(none|unset|initial|inherit)$)-?[a-z_][-a-z0-9_]+$/i.test(p),
|
||||
'<single-animation-name>': p => vtIsIdent(p) && !isGlobalKeyword(p) &&
|
||||
/^-?[a-z_][-a-z0-9_]+$/i.test(p),
|
||||
'<string>': p => p.type === 'string',
|
||||
'<text-align>': 'start | end | left | right | center | justify | match-parent',
|
||||
'<text-decoration-style>': 'solid | double | dotted | dashed | wavy',
|
||||
|
@ -2395,10 +2401,8 @@ self.parserlib = (() => {
|
|||
|
||||
const validationCache = new Map();
|
||||
|
||||
function validateProperty(property, value) {
|
||||
// Global keywords that can be set for any property are conveniently listed in `all` prop:
|
||||
// https://drafts.csswg.org/css-cascade/#all-shorthand
|
||||
if (/^(inherit|initial|unset|revert)$/i.test(value.parts[0])) {
|
||||
function validateProperty(name, property, value) {
|
||||
if (isGlobalKeyword(value.parts[0])) {
|
||||
if (value.parts.length > 1) {
|
||||
throwEndExpected(value.parts[1], true);
|
||||
}
|
||||
|
@ -2407,7 +2411,7 @@ self.parserlib = (() => {
|
|||
if (hasVarParts(value)) {
|
||||
return;
|
||||
}
|
||||
const prop = lower(property);
|
||||
const prop = lower(name);
|
||||
let known = validationCache.get(prop);
|
||||
if (known && known.has(value.text)) {
|
||||
return;
|
||||
|
@ -2417,7 +2421,7 @@ self.parserlib = (() => {
|
|||
return;
|
||||
}
|
||||
if (!spec) {
|
||||
throw new ValidationError(`Unknown property '${property}'.`, value);
|
||||
throw new ValidationError(`Unknown property '${name}'.`, value);
|
||||
}
|
||||
// Property-specific validation.
|
||||
const expr = new PropertyValueIterator(value);
|
||||
|
@ -4066,7 +4070,7 @@ self.parserlib = (() => {
|
|||
this.options.underscoreHack && property.hack === '_'
|
||||
? property.text
|
||||
: property.toString();
|
||||
validateProperty(name, value);
|
||||
validateProperty(name, property, value);
|
||||
} catch (ex) {
|
||||
if (!(ex instanceof ValidationError)) {
|
||||
ex.message = ex.stack;
|
||||
|
@ -4650,14 +4654,15 @@ self.parserlib = (() => {
|
|||
css: {
|
||||
Colors,
|
||||
Combinator,
|
||||
GlobalKeywords,
|
||||
Matcher,
|
||||
MediaFeature,
|
||||
MediaQuery,
|
||||
Parser,
|
||||
Properties,
|
||||
PropertyName,
|
||||
PropertyValue,
|
||||
PropertyValuePart,
|
||||
Matcher,
|
||||
MediaFeature,
|
||||
MediaQuery,
|
||||
Selector,
|
||||
SelectorPart,
|
||||
SelectorSubPart,
|
||||
|
|
Loading…
Reference in New Issue
Block a user