diff --git a/src/css/Stylesheet.ts b/src/css/Stylesheet.ts index cb83804f1d..e94dce6a62 100644 --- a/src/css/Stylesheet.ts +++ b/src/css/Stylesheet.ts @@ -3,6 +3,7 @@ import { walk } from 'estree-walker'; import { getLocator } from 'locate-character'; import Selector from './Selector'; import getCodeFrame from '../utils/getCodeFrame'; +import Element from '../generators/nodes/Element'; import { Validator } from '../validate/index'; import { Node, Parsed, Warning } from '../interfaces'; @@ -19,7 +20,7 @@ class Rule { this.declarations = node.block.children.map((node: Node) => new Declaration(node)); } - apply(node: Node, stack: Node[]) { + apply(node: Element, stack: Element[]) { this.selectors.forEach(selector => selector.apply(node, stack)); // TODO move the logic in here? } @@ -159,7 +160,7 @@ class Atrule { this.children = []; } - apply(node: Node, stack: Node[]) { + apply(node: Element, stack: Element[]) { if (this.node.name === 'media') { this.children.forEach(child => { child.apply(node, stack); @@ -330,9 +331,15 @@ export default class Stylesheet { } } - apply(node: Node, stack: Node[]) { + apply(node: Element) { if (!this.hasStyles) return; + const stack: Element[] = []; + let parent: Node = node; + while (parent = parent.parent) { + if (parent.type === 'Element') stack.unshift(parent); + } + if (this.cascade) { if (stack.length === 0) node._needsCssAttribute = true; return; diff --git a/src/generators/dom/index.ts b/src/generators/dom/index.ts index d9998c063f..9566ba936f 100644 --- a/src/generators/dom/index.ts +++ b/src/generators/dom/index.ts @@ -94,16 +94,11 @@ export default function dom( namespace, } = generator; - parsed.html.init(); - const { block, state } = parsed.html; + parsed.html.build(); + const { block } = parsed.html; generator.stylesheet.warnOnUnusedSelectors(options.onwarn); - // parsed.html.children.forEach((node: Node) => { - // visit(generator, block, state, node, [], []); - // }); - parsed.html.build(block, state); - const builder = new CodeBuilder(); const computationBuilder = new CodeBuilder(); const computationDeps = new Set(); diff --git a/src/generators/nodes/AwaitBlock.ts b/src/generators/nodes/AwaitBlock.ts index 9836dde120..0418d42710 100644 --- a/src/generators/nodes/AwaitBlock.ts +++ b/src/generators/nodes/AwaitBlock.ts @@ -21,7 +21,6 @@ export default class AwaitBlock extends Node { block: Block, state: State, inEachBlock: boolean, - elementStack: Node[], componentStack: Node[], stripWhitespace: boolean, nextSibling: Node @@ -54,7 +53,7 @@ export default class AwaitBlock extends Node { child._state = state.child(); - child.initChildren(child._block, child._state, inEachBlock, elementStack, componentStack, stripWhitespace, nextSibling); + child.initChildren(child._block, child._state, inEachBlock, componentStack, stripWhitespace, nextSibling); this.generator.blocks.push(child._block); if (child._block.dependencies.size > 0) { @@ -71,7 +70,6 @@ export default class AwaitBlock extends Node { build( block: Block, state: State, - elementStack: Node[], componentStack: Node[] ) { const name = this.var; @@ -213,7 +211,7 @@ export default class AwaitBlock extends Node { [this.pending, this.then, this.catch].forEach(status => { status.children.forEach(child => { - child.build(status._block, status._state, elementStack, componentStack); + child.build(status._block, status._state, componentStack); }); }); } diff --git a/src/generators/nodes/Component.ts b/src/generators/nodes/Component.ts index 222e58a597..75541bab86 100644 --- a/src/generators/nodes/Component.ts +++ b/src/generators/nodes/Component.ts @@ -21,7 +21,6 @@ export default class Component extends Node { block: Block, state: State, inEachBlock: boolean, - elementStack: Node[], componentStack: Node[], stripWhitespace: boolean, nextSibling: Node @@ -63,7 +62,7 @@ export default class Component extends Node { this._slots = new Set(['default']); this.children.forEach(child => { - child.init(block, state, inEachBlock, elementStack, componentStack.concat(this), stripWhitespace, nextSibling); + child.init(block, state, inEachBlock, componentStack.concat(this), stripWhitespace, nextSibling); }); } } @@ -71,7 +70,6 @@ export default class Component extends Node { build( block: Block, state: State, - elementStack: Node[], componentStack: Node[] ) { const { generator } = this; @@ -86,7 +84,7 @@ export default class Component extends Node { componentInitProperties.push(`slots: { ${slots.join(', ')} }`); this.children.forEach((child: Node) => { - child.build(block, this._state, elementStack, componentStack.concat(this)); + child.build(block, this._state, componentStack.concat(this)); }); } diff --git a/src/generators/nodes/EachBlock.ts b/src/generators/nodes/EachBlock.ts index 2d8dab239d..eb2c348d96 100644 --- a/src/generators/nodes/EachBlock.ts +++ b/src/generators/nodes/EachBlock.ts @@ -25,7 +25,6 @@ export default class EachBlock extends Node { block: Block, state: State, inEachBlock: boolean, - elementStack: Node[], componentStack: Node[], stripWhitespace: boolean, nextSibling: Node @@ -90,7 +89,7 @@ export default class EachBlock extends Node { }); this.generator.blocks.push(this._block); - this.initChildren(this._block, this._state, true, elementStack, componentStack, stripWhitespace, nextSibling); + this.initChildren(this._block, this._state, true, componentStack, stripWhitespace, nextSibling); block.addDependencies(this._block.dependencies); this._block.hasUpdateMethod = this._block.dependencies.size > 0; @@ -107,7 +106,6 @@ export default class EachBlock extends Node { this.else._block, this.else._state, inEachBlock, - elementStack, componentStack, stripWhitespace, nextSibling @@ -119,7 +117,6 @@ export default class EachBlock extends Node { build( block: Block, state: State, - elementStack: Node[], componentStack: Node[] ) { const { generator } = this; @@ -238,12 +235,12 @@ export default class EachBlock extends Node { } this.children.forEach((child: Node) => { - child.build(this._block, this._state, elementStack, componentStack); + child.build(this._block, this._state, componentStack); }); if (this.else) { this.else.children.forEach((child: Node) => { - child.build(this.else._block, this.else._state, elementStack, componentStack); + child.build(this.else._block, this.else._state, componentStack); }); } } diff --git a/src/generators/nodes/Element.ts b/src/generators/nodes/Element.ts index 1f0f041a0f..10c6904e45 100644 --- a/src/generators/nodes/Element.ts +++ b/src/generators/nodes/Element.ts @@ -28,7 +28,6 @@ export default class Element extends Node { block: Block, state: State, inEachBlock: boolean, - elementStack: Node[], componentStack: Node[], stripWhitespace: boolean, nextSibling: Node @@ -156,18 +155,17 @@ export default class Element extends Node { allUsedContexts: [], }); - this.generator.stylesheet.apply(this, elementStack); + this.generator.stylesheet.apply(this); if (this.children.length) { if (this.name === 'pre' || this.name === 'textarea') stripWhitespace = false; - this.initChildren(block, this._state, inEachBlock, elementStack.concat(this), componentStack, stripWhitespace, nextSibling); + this.initChildren(block, this._state, inEachBlock, componentStack, stripWhitespace, nextSibling); } } build( block: Block, state: State, - elementStack: Node[], componentStack: Node[] ) { const { generator } = this; @@ -240,7 +238,7 @@ export default class Element extends Node { } } else { this.children.forEach((child: Node) => { - child.build(block, childState, elementStack.concat(this), componentStack); + child.build(block, childState, componentStack); }); } diff --git a/src/generators/nodes/Fragment.ts b/src/generators/nodes/Fragment.ts index 277b803242..e6628628d9 100644 --- a/src/generators/nodes/Fragment.ts +++ b/src/generators/nodes/Fragment.ts @@ -8,9 +8,7 @@ export default class Fragment extends Node { state: State; children: Node[]; - init( - namespace: string - ) { + init() { this.block = new Block({ generator: this.generator, name: '@create_main_fragment', @@ -34,17 +32,16 @@ export default class Fragment extends Node { }); this.generator.blocks.push(this.block); - this.initChildren(this.block, this.state, false, [], [], true, null); + this.initChildren(this.block, this.state, false, [], true, null); this.block.hasUpdateMethod = true; } - build( - block: Block, - state: State - ) { + build() { + this.init(); + this.children.forEach(child => { - child.build(block, state, [], []); + child.build(this.block, this.state, []); }); } } \ No newline at end of file diff --git a/src/generators/nodes/IfBlock.ts b/src/generators/nodes/IfBlock.ts index eedb47a614..835d6743fd 100644 --- a/src/generators/nodes/IfBlock.ts +++ b/src/generators/nodes/IfBlock.ts @@ -27,7 +27,6 @@ export default class IfBlock extends Node { block: Block, state: State, inEachBlock: boolean, - elementStack: Node[], componentStack: Node[], stripWhitespace: boolean, nextSibling: Node @@ -54,7 +53,7 @@ export default class IfBlock extends Node { node._state = state.child(); blocks.push(node._block); - node.initChildren(node._block, node._state, inEachBlock, elementStack, componentStack, stripWhitespace, nextSibling); + node.initChildren(node._block, node._state, inEachBlock, componentStack, stripWhitespace, nextSibling); if (node._block.dependencies.size > 0) { dynamic = true; @@ -79,7 +78,6 @@ export default class IfBlock extends Node { node.else._block, node.else._state, inEachBlock, - elementStack, componentStack, stripWhitespace, nextSibling @@ -106,7 +104,6 @@ export default class IfBlock extends Node { build( block: Block, state: State, - elementStack: Node[], componentStack: Node[] ) { const name = this.var; @@ -117,7 +114,7 @@ export default class IfBlock extends Node { : (this.next && this.next.var) || 'null'; const params = block.params.join(', '); - const branches = getBranches(this.generator, block, state, this, elementStack, componentStack); + const branches = getBranches(this.generator, block, state, this, componentStack); const hasElse = isElseBranch(branches[branches.length - 1]); const if_name = hasElse ? '' : `if (${name}) `; @@ -173,7 +170,6 @@ function getBranches( block: Block, state: State, node: Node, - elementStack: Node[], componentStack: Node[] ) { block.contextualise(node.expression); // TODO remove @@ -188,11 +184,11 @@ function getBranches( }, ]; - visitChildren(generator, block, state, node, elementStack, componentStack); + visitChildren(generator, block, state, node, componentStack); if (isElseIf(node.else)) { branches.push( - ...getBranches(generator, block, state, node.else.children[0], elementStack, componentStack) + ...getBranches(generator, block, state, node.else.children[0], componentStack) ); } else { branches.push({ @@ -204,7 +200,7 @@ function getBranches( }); if (node.else) { - visitChildren(generator, block, state, node.else, elementStack, componentStack); + visitChildren(generator, block, state, node.else, componentStack); } } @@ -216,11 +212,10 @@ function visitChildren( block: Block, state: State, node: Node, - elementStack: Node[], componentStack: Node[] ) { node.children.forEach((child: Node) => { - child.build(node._block, node._state, elementStack, componentStack); + child.build(node._block, node._state, componentStack); }); } diff --git a/src/generators/nodes/MustacheTag.ts b/src/generators/nodes/MustacheTag.ts index a353896299..d39e1479d1 100644 --- a/src/generators/nodes/MustacheTag.ts +++ b/src/generators/nodes/MustacheTag.ts @@ -13,7 +13,6 @@ export default class MustacheTag extends Tag { build( block: Block, state: State, - elementStack: Node[], componentStack: Node[] ) { const { init } = this.renameThisMethod( diff --git a/src/generators/nodes/RawMustacheTag.ts b/src/generators/nodes/RawMustacheTag.ts index dda177f18c..7d9ccde65f 100644 --- a/src/generators/nodes/RawMustacheTag.ts +++ b/src/generators/nodes/RawMustacheTag.ts @@ -14,7 +14,6 @@ export default class RawMustacheTag extends Tag { build( block: Block, state: State, - elementStack: Node[], componentStack: Node[] ) { const name = this.var; diff --git a/src/generators/nodes/Slot.ts b/src/generators/nodes/Slot.ts index 66c575ba6f..a8f03927ef 100644 --- a/src/generators/nodes/Slot.ts +++ b/src/generators/nodes/Slot.ts @@ -15,7 +15,6 @@ export default class Slot extends Element { block: Block, state: State, inEachBlock: boolean, - elementStack: Node[], componentStack: Node[], stripWhitespace: boolean, nextSibling: Node @@ -35,14 +34,13 @@ export default class Slot extends Element { }); if (this.children.length) { - this.initChildren(block, this._state, inEachBlock, elementStack.concat(this), componentStack, stripWhitespace, nextSibling); + this.initChildren(block, this._state, inEachBlock, componentStack, stripWhitespace, nextSibling); } } build( block: Block, state: State, - elementStack: Node[], componentStack: Node[] ) { const { generator } = this; @@ -74,7 +72,7 @@ export default class Slot extends Element { block.builders.destroy.pushCondition(`!${content_name}`); this.children.forEach((child: Node) => { - child.build(block, state, elementStack, componentStack); + child.build(block, state, componentStack); }); block.builders.create.popCondition(); diff --git a/src/generators/nodes/Text.ts b/src/generators/nodes/Text.ts index a31669eb98..11926fd903 100644 --- a/src/generators/nodes/Text.ts +++ b/src/generators/nodes/Text.ts @@ -34,7 +34,6 @@ export default class Text extends Node { build( block: Block, state: State, - elementStack: Node[], componentStack: Node[] ) { if (this.shouldSkip) return; diff --git a/src/generators/nodes/Window.ts b/src/generators/nodes/Window.ts index 9343347c4e..6441133c74 100644 --- a/src/generators/nodes/Window.ts +++ b/src/generators/nodes/Window.ts @@ -35,7 +35,6 @@ export default class Window extends Node { block: Block, state: State, inEachBlock: boolean, - elementStack: Node[], componentStack: Node[], stripWhitespace: boolean, nextSibling: Node @@ -46,7 +45,6 @@ export default class Window extends Node { build( block: Block, state: State, - elementStack: Node[], componentStack: Node[] ) { const { generator } = this; diff --git a/src/generators/nodes/shared/Node.ts b/src/generators/nodes/shared/Node.ts index e1e5861e3a..82addcf3f9 100644 --- a/src/generators/nodes/shared/Node.ts +++ b/src/generators/nodes/shared/Node.ts @@ -38,7 +38,6 @@ export default class Node { block: Block, state: State, inEachBlock: boolean, - elementStack: Node[], componentStack: Node[], stripWhitespace: boolean, nextSibling: Node @@ -50,7 +49,6 @@ export default class Node { block: Block, state: State, inEachBlock: boolean, - elementStack: Node[], componentStack: Node[], stripWhitespace: boolean, nextSibling: Node @@ -91,7 +89,7 @@ export default class Node { cleaned.forEach((child: Node, i: number) => { child.canUseInnerHTML = !this.generator.hydratable; - child.init(block, state, inEachBlock, elementStack, componentStack, stripWhitespace, cleaned[i + 1] || nextSibling); + child.init(block, state, inEachBlock, componentStack, stripWhitespace, cleaned[i + 1] || nextSibling); if (child.shouldSkip) return; @@ -125,7 +123,6 @@ export default class Node { build( block: Block, state: State, - elementStack: Node[], componentStack: Node[] ) { // implemented by subclasses diff --git a/src/generators/server-side-rendering/preprocess.ts b/src/generators/server-side-rendering/preprocess.ts index 8556cad3fd..af1478b14c 100644 --- a/src/generators/server-side-rendering/preprocess.ts +++ b/src/generators/server-side-rendering/preprocess.ts @@ -1,5 +1,6 @@ import getStaticAttributeValue from '../../utils/getStaticAttributeValue'; import isChildOfComponent from '../shared/utils/isChildOfComponent'; +import Element from '../nodes/Element'; import { SsrGenerator } from './index'; import { Node } from '../../interfaces'; @@ -54,10 +55,10 @@ const preprocessors = { Element: ( generator: SsrGenerator, - node: Node, + node: Element, elementStack: Node[] ) => { - generator.stylesheet.apply(node, elementStack); + generator.stylesheet.apply(node); const slot = getStaticAttributeValue(node, 'slot'); if (slot && node.isChildOfComponent()) {