finish moving validation

pull/10482/head
Rich Harris 3 years ago
parent aedc4cbd03
commit 0d0cc80cec

@ -124,68 +124,6 @@ export class ComplexSelector {
}
}
}
/** @param {import('../phases/types.js').ComponentAnalysis} analysis */
validate(analysis) {
this.validate_global_with_multiple_selectors();
this.validate_global_compound_selector();
this.validate_invalid_combinator_without_selector(analysis);
}
validate_global_with_multiple_selectors() {
if (this.relative_selectors.length === 1 && this.relative_selectors[0].selectors.length === 1) {
// standalone :global() with multiple selectors is OK
return;
}
for (const relative_selector of this.relative_selectors) {
for (const selector of relative_selector.selectors) {
if (
selector.type === 'PseudoClassSelector' &&
selector.name === 'global' &&
selector.args !== null &&
selector.args.children.length > 1
) {
error(selector, 'invalid-css-global-selector');
}
}
}
}
/** @param {import('../phases/types.js').ComponentAnalysis} analysis */
validate_invalid_combinator_without_selector(analysis) {
for (let i = 0; i < this.relative_selectors.length; i++) {
const relative_selector = this.relative_selectors[i];
if (relative_selector.selectors.length === 0) {
error(this.node, 'invalid-css-selector');
}
}
}
validate_global_compound_selector() {
for (const relative_selector of this.relative_selectors) {
if (relative_selector.selectors.length === 1) continue;
for (let i = 0; i < relative_selector.selectors.length; i++) {
const selector = relative_selector.selectors[i];
if (selector.type === 'PseudoClassSelector' && selector.name === 'global') {
const child = selector.args?.children[0].children[0];
if (
child?.selectors[0].type === 'TypeSelector' &&
!/[.:#]/.test(child.selectors[0].name[0]) &&
(i !== 0 ||
relative_selector.selectors
.slice(1)
.some(
(s) => s.type !== 'PseudoElementSelector' && s.type !== 'PseudoClassSelector'
))
) {
error(selector, 'invalid-css-global-selector-list');
}
}
}
}
}
}
/**

@ -115,13 +115,6 @@ class Rule {
this.declarations.forEach((declaration) => declaration.transform(code, keyframes));
}
/** @param {import('../phases/types.js').ComponentAnalysis} analysis */
validate(analysis) {
this.selectors.forEach((selector) => {
selector.validate(analysis);
});
}
/** @param {(selector: ComplexSelector) => void} handler */
warn_on_unused_selector(handler) {
this.selectors.forEach((selector) => {
@ -309,13 +302,6 @@ class Atrule {
});
}
/** @param {import('../phases/types.js').ComponentAnalysis} analysis */
validate(analysis) {
this.children.forEach((child) => {
child.validate(analysis);
});
}
/** @param {(selector: ComplexSelector) => void} handler */
warn_on_unused_selector(handler) {
if (this.node.name !== 'media') return;
@ -510,13 +496,6 @@ export class Stylesheet {
};
}
/** @param {import('../phases/types.js').ComponentAnalysis} analysis */
validate(analysis) {
this.children.forEach((child) => {
child.validate(analysis);
});
}
/** @param {import('../phases/types.js').ComponentAnalysis} analysis */
warn_on_unused_selectors(analysis) {
// const ignores = !this.ast

@ -457,8 +457,6 @@ export function analyze_component(root, options) {
walk(root.css, {}, validation_css);
}
analysis.stylesheet.validate(analysis);
for (const element of analysis.elements) {
analysis.stylesheet.apply(element);
}

@ -32,5 +32,45 @@ export const validation_css = {
}
}
}
// ensure `:global(...)`contains a single selector
// (standalone :global() with multiple selectors is OK)
if (node.children.length > 1 || node.children[0].selectors.length > 1) {
for (const relative_selector of node.children) {
for (const selector of relative_selector.selectors) {
if (
selector.type === 'PseudoClassSelector' &&
selector.name === 'global' &&
selector.args !== null &&
selector.args.children.length > 1
) {
error(selector, 'invalid-css-global-selector');
}
}
}
}
// ensure `:global(...)` is not part of a larger compound selector
for (const relative_selector of node.children) {
for (let i = 0; i < relative_selector.selectors.length; i++) {
const selector = relative_selector.selectors[i];
if (selector.type === 'PseudoClassSelector' && selector.name === 'global') {
const child = selector.args?.children[0].children[0];
if (
child?.selectors[0].type === 'TypeSelector' &&
!/[.:#]/.test(child.selectors[0].name[0]) &&
(i !== 0 ||
relative_selector.selectors
.slice(1)
.some(
(s) => s.type !== 'PseudoElementSelector' && s.type !== 'PseudoClassSelector'
))
) {
error(selector, 'invalid-css-global-selector-list');
}
}
}
}
}
};

Loading…
Cancel
Save