refactor: tidy up compile/css

pull/8000/head
Simon He 4 years ago
parent b05b684b95
commit dd248bd15a

@ -42,11 +42,7 @@ export default class Selector {
this.blocks = group_selectors(node);
// take trailing :global(...) selectors out of consideration
let i = this.blocks.length;
while (i > 0) {
if (!this.blocks[i - 1].global) break;
i -= 1;
}
const i = this.blocks.findIndex(block => !block.global);
this.local_blocks = this.blocks.slice(0, i);
@ -74,11 +70,9 @@ export default class Selector {
minify(code: MagicString) {
let c: number = null;
this.blocks.forEach((block, i) => {
if (i > 0) {
if (block.start - c > 1) {
if (i > 0 && block.start - c > 1) {
code.overwrite(c, block.start, block.combinator.name || ' ');
}
}
c = block.end;
});
@ -105,8 +99,8 @@ export default class Selector {
while (i--) {
const selector = block.selectors[i];
if (selector.type === 'PseudoElementSelector' || selector.type === 'PseudoClassSelector') {
if (selector.name !== 'root' && selector.name !== 'host') {
if (i === 0) code.prependRight(selector.start, attr);
if (selector.name !== 'root' && selector.name !== 'host' && i === 0) {
code.prependRight(selector.start, attr);
}
continue;
}
@ -159,14 +153,12 @@ export default class Selector {
for (const block of this.blocks) {
for (const selector of block.selectors) {
if (selector.type === 'PseudoClassSelector' && selector.name === 'global') {
if (regex_is_single_css_selector.test(selector.children[0].value)) {
if (selector.type === 'PseudoClassSelector' && selector.name === 'global' && regex_is_single_css_selector.test(selector.children[0].value)) {
component.error(selector, compiler_errors.css_invalid_global_selector);
}
}
}
}
}
validate_invalid_combinator_without_selector(component: Component) {
for (let i = 0; i < this.blocks.length; i++) {
const block = this.blocks[i];
@ -293,11 +285,10 @@ function block_might_apply_to_node(block: Block, node: Element): BlockAppliesToN
const selector = block.selectors[i];
const name = typeof selector.name === 'string' && selector.name.replace(regex_backslash_and_following_character, '$1');
if (selector.type === 'PseudoClassSelector' && (name === 'host' || name === 'root')) {
return BlockAppliesToNode.NotPossible;
}
if (block.selectors.length === 1 && selector.type === 'PseudoClassSelector' && name === 'global') {
if ((
selector.type === 'PseudoClassSelector' && (name === 'host' || name === 'root')) ||
block.selectors.length === 1 && selector.type === 'PseudoClassSelector' && name === 'global'
) {
return BlockAppliesToNode.NotPossible;
}
@ -343,9 +334,7 @@ function test_attribute(operator, expected_value, case_insensitive, value) {
function attribute_matches(node: CssNode, name: string, expected_value: string, operator: string, case_insensitive: boolean) {
const spread = node.attributes.find(attr => attr.type === 'Spread');
if (spread) return true;
if (node.bindings.some((binding: CssNode) => binding.name === name)) return true;
if (spread || node.bindings.some((binding: CssNode) => binding.name === name)) return true;
const attr = node.attributes.find((attr: CssNode) => attr.name === name);
if (!attr) return false;
@ -428,13 +417,10 @@ function attribute_matches(node: CssNode, name: string, expected_value: string,
}
prev_values.forEach(prev_value => possible_values.add(prev_value));
if (possible_values.has(UNKNOWN)) return true;
for (const value of possible_values) {
if (test_attribute(operator, expected_value, case_insensitive, value)) return true;
}
return false;
return possible_values.has(UNKNOWN) ||
[...possible_values].some(value =>
test_attribute(operator, expected_value, case_insensitive, value)
);
}
function unquote(value: CssNode) {
@ -552,24 +538,21 @@ function get_possible_last_child(block: EachBlock | IfBlock | AwaitBlock, adjace
}
function has_definite_elements(result: Map<Element, NodeExist>): boolean {
if (result.size === 0) return false;
for (const exist of result.values()) {
if (exist === NodeExist.Definitely) {
return true;
}
}
return false;
return result.size === 0
? false
: [...result.values()].some(exist => exist === NodeExist.Definitely);
}
function add_to_map(from: Map<Element, NodeExist>, to: Map<Element, NodeExist>) {
from.forEach((exist, element) => {
to.set(element, higher_existence(exist, to.get(element)));
});
from.forEach((exist, element) =>
to.set(element, higher_existence(exist, to.get(element)))
);
}
function higher_existence(exist1: NodeExist | null, exist2: NodeExist | null): NodeExist {
if (exist1 === undefined || exist2 === undefined) return exist1 || exist2;
return exist1 > exist2 ? exist1 : exist2;
return exist1 === undefined || exist2 === undefined
? exist1 || exist2
: Math.max(exist1, exist2);
}
function mark_as_probably(result: Map<Element, NodeExist>) {

@ -30,18 +30,14 @@ function minify_declarations(
start: number,
declarations: Declaration[]
): number {
let c = start;
declarations.forEach((declaration, i) => {
return declarations.reduce((result, declaration, i) => {
const separator = i > 0 ? ';' : '';
if ((declaration.node.start - c) > separator.length) {
code.overwrite(c, declaration.node.start, separator);
if ((declaration.node.start - result) > separator.length) {
code.overwrite(result, declaration.node.start, separator);
}
declaration.minify(code);
c = declaration.node.end;
});
return c;
return declaration.node.end;
}, start);
}
class Rule {
@ -72,7 +68,7 @@ class Rule {
let started = false;
this.selectors.forEach((selector) => {
if (selector.used) {
if (!selector.used) return;
const separator = started ? ',' : '';
if ((selector.node.start - c) > separator.length) {
code.overwrite(c, selector.node.start, separator);
@ -82,7 +78,6 @@ class Rule {
c = selector.node.end;
started = true;
}
});
code.remove(c, this.node.block.start);
@ -128,17 +123,15 @@ class Declaration {
transform(code: MagicString, keyframes: Map<string, string>) {
const property = this.node.property && remove_css_prefix(this.node.property.toLowerCase());
if (property === 'animation' || property === 'animation-name') {
if (property !== 'animation' && property !== 'animation-name') return;
this.node.value.children.forEach((block: CssNode) => {
if (block.type === 'Identifier') {
if (block.type !== 'Identifier') return;
const name = block.name;
if (keyframes.has(name)) {
code.overwrite(block.start, block.end, keyframes.get(name));
}
}
});
}
}
minify(code: MagicString) {
if (!this.node.property) return; // @apply, and possibly other weird cases?
@ -174,9 +167,7 @@ class Atrule {
apply(node: Element) {
if (this.node.name === 'media' || this.node.name === 'supports' || this.node.name === 'layer') {
this.children.forEach(child => {
child.apply(node);
});
this.children.forEach(child => child.apply(node));
} else if (is_keyframes_node(this.node)) {
this.children.forEach((rule: Rule) => {
rule.selectors.forEach(selector => {
@ -246,7 +237,7 @@ class Atrule {
transform(code: MagicString, id: string, keyframes: Map<string, string>, max_amount_class_specificity_increased: number) {
if (is_keyframes_node(this.node)) {
this.node.prelude.children.forEach(({ type, name, start, end }: CssNode) => {
if (type === 'Identifier') {
if (type !== 'Identifier') return;
if (name.startsWith('-global-')) {
code.remove(start, start + 8);
this.children.forEach((rule: Rule) => {
@ -257,7 +248,6 @@ class Atrule {
} else {
code.overwrite(start, end, keyframes.get(name));
}
}
});
}
@ -267,17 +257,12 @@ class Atrule {
}
validate(component: Component) {
this.children.forEach(child => {
child.validate(component);
});
this.children.forEach(child => child.validate(component));
}
warn_on_unused_selector(handler: (selector: Selector) => void) {
if (this.node.name !== 'media') return;
this.children.forEach(child => {
child.warn_on_unused_selector(handler);
});
this.children.forEach(child => child.warn_on_unused_selector(handler));
}
get_max_amount_class_specificity_increased() {
@ -322,8 +307,11 @@ export default class Stylesheet {
this.ast = ast;
this.filename = filename;
this.dev = dev;
if (!ast.css || !ast.css.children.length) {
this.has_styles = false;
return;
}
if (ast.css && ast.css.children.length) {
this.id = get_css_hash({
filename,
name: component_name,
@ -387,9 +375,7 @@ export default class Stylesheet {
depth -= 1;
}
});
} else {
this.has_styles = false;
}
}
apply(node: Element) {
@ -402,9 +388,7 @@ export default class Stylesheet {
}
reify() {
this.nodes_with_css_class.forEach((node: Element) => {
node.add_css_class();
});
this.nodes_with_css_class.forEach((node: Element) => node.add_css_class());
}
render(file: string, should_transform_selectors: boolean) {
@ -450,9 +434,7 @@ export default class Stylesheet {
}
validate(component: Component) {
this.children.forEach(child => {
child.validate(component);
});
this.children.forEach(child => child.validate(component));
}
warn_on_unused_selectors(component: Component) {

Loading…
Cancel
Save