refactor a bit, fix typing error

pull/689/head
Rich Harris 7 years ago
parent f79e901429
commit 6f01d5f62f

@ -13,7 +13,8 @@ import annotateWithScopes from '../utils/annotateWithScopes';
import clone from '../utils/clone';
import DomBlock from './dom/Block';
import SsrBlock from './server-side-rendering/Block';
import extractSelectors from './extractSelectors';
import { walkRules } from '../utils/css';
import Selector from './Selector';
import { Node, Parsed, CompileOptions } from '../interfaces';
const test = typeof global !== 'undefined' && global.__svelte_test;
@ -41,7 +42,7 @@ export default class Generator {
cssId: string;
usesRefs: boolean;
selectors: any[]; // TODO how to indicate it takes `(Node[]) => boolean` functions?
selectors: Selector[];
importedNames: Set<string>;
aliases: Map<string, string>;
@ -74,12 +75,21 @@ export default class Generator {
this.expectedProperties = new Set();
this.code = new MagicString(source);
this.usesRefs = false;
// styles
this.cascade = options.cascade !== false; // TODO remove this option in v2
this.css = parsed.css ? processCss(parsed, this.code, this.cascade) : null;
this.cssId = parsed.css ? `svelte-${parsed.hash}` : '';
this.usesRefs = false;
this.selectors = [];
this.selectors = extractSelectors(parsed.css);
if (parsed.css) {
walkRules(parsed.css.children, node => {
node.selector.children.forEach((child: Node) => {
this.selectors.push(new Selector(child));
});
});
}
// allow compiler to deconflict user's `import { get } from 'whatever'` and
// Svelte's builtin `import { get, ... } from 'svelte/shared.ts'`;

@ -1,21 +1,19 @@
import { walkRules } from '../utils/css';
import { Node } from '../interfaces';
export default function extractSelectors(css: Node) :Node[] {
if (!css) return [];
export default class Selector {
node: Node;
parts: Node[];
used: boolean;
const selectors = [];
constructor(node: Node) {
this.node = node;
walkRules(css.children, node => {
node.selector.children.forEach(processSelector);
});
function processSelector(selector: Node) {
// take trailing :global(...) selectors out of consideration
let i = selector.children.length;
let i = node.children.length;
while (i > 2) {
const last = selector.children[i-1];
const penultimate = selector.children[i-2];
const last = node.children[i-1];
const penultimate = node.children[i-2];
if (last.type === 'PseudoClassSelector' && last.name === 'global') {
i -= 2;
@ -24,24 +22,21 @@ export default function extractSelectors(css: Node) :Node[] {
}
}
const parts = selector.children.slice(0, i);
selectors.push({
used: false, // TODO use this! warn on unused selectors
apply: (node: Node, stack: Node[]) => {
const applies = selectorAppliesTo(parts, node, stack.slice());
this.parts = node.children.slice(0, i);
if (applies) {
// add svelte-123xyz attribute to outermost and innermost
// elements — no need to add it to intermediate elements
node._needsCssAttribute = true;
if (stack[0] && selector.children.find(isDescendantSelector)) stack[0]._needsCssAttribute = true;
}
}
});
this.used = false; // TODO use this! warn on unused selectors
}
return selectors;
apply(node: Node, stack: Node[]) {
const applies = selectorAppliesTo(this.parts, node, stack.slice());
if (applies) {
// add svelte-123xyz attribute to outermost and innermost
// elements — no need to add it to intermediate elements
node._needsCssAttribute = true;
if (stack[0] && this.node.children.find(isDescendantSelector)) stack[0]._needsCssAttribute = true;
}
}
}
function isDescendantSelector(selector: Node) {
Loading…
Cancel
Save