diff --git a/src/generators/dom/index.ts b/src/generators/dom/index.ts
index c6d9e94df2..6a8624a601 100644
--- a/src/generators/dom/index.ts
+++ b/src/generators/dom/index.ts
@@ -12,7 +12,6 @@ import visit from './visit';
import shared from './shared';
import Generator from '../Generator';
import Stylesheet from '../../css/Stylesheet';
-import preprocess from './preprocess';
import Block from './Block';
import { test } from '../../config';
import { Parsed, CompileOptions, Node } from '../../interfaces';
@@ -96,7 +95,8 @@ export default function dom(
namespace,
} = generator;
- const { block, state } = preprocess(generator, namespace, parsed.html);
+ parsed.html.init();
+ const { block, state } = parsed.html;
generator.stylesheet.warnOnUnusedSelectors(options.onwarn);
diff --git a/src/generators/dom/preprocess.ts b/src/generators/dom/preprocess.ts
deleted file mode 100644
index fdddfb1acf..0000000000
--- a/src/generators/dom/preprocess.ts
+++ /dev/null
@@ -1,587 +0,0 @@
-import Block from './Block';
-import { trimStart, trimEnd } from '../../utils/trim';
-import { assign } from '../../shared/index.js';
-import getStaticAttributeValue from '../../utils/getStaticAttributeValue';
-import isChildOfComponent from '../shared/utils/isChildOfComponent';
-import { DomGenerator } from './index';
-import { Node } from '../../interfaces';
-import { State } from './interfaces';
-
-function isElseIf(node: Node) {
- return (
- node && node.children.length === 1 && node.children[0].type === 'IfBlock'
- );
-}
-
-function getChildState(parent: State, child = {}) {
- return assign(
- {},
- parent,
- { parentNode: null, parentNodes: 'nodes' },
- child || {}
- );
-}
-
-function createDebuggingComment(node: Node, generator: DomGenerator) {
- const { locate, source } = generator;
-
- let c = node.start;
- if (node.type === 'ElseBlock') {
- while (source[c] !== '{') c -= 1;
- c -= 1;
- }
-
- let d = node.expression ? node.expression.end : c;
- while (source[d] !== '}') d += 1;
- d += 2;
-
- const start = locate(c);
- const loc = `(${start.line + 1}:${start.column})`;
-
- return `${loc} ${source.slice(c, d)}`.replace(/\n/g, ' ');
-}
-
-function cannotUseInnerHTML(node: Node) {
- while (node && node.canUseInnerHTML) {
- node.canUseInnerHTML = false;
- node = node.parent;
- }
-}
-
-const preprocessors = {
- MustacheTag: (
- generator: DomGenerator,
- block: Block,
- state: State,
- node: Node,
- elementStack: Node[],
- componentStack: Node[],
- stripWhitespace: boolean
- ) => {
- node.init(block);
- },
-
- RawMustacheTag: (
- generator: DomGenerator,
- block: Block,
- state: State,
- node: Node,
- elementStack: Node[],
- componentStack: Node[],
- stripWhitespace: boolean
- ) => {
- node.init(block);
- },
-
- Text: (
- generator: DomGenerator,
- block: Block,
- state: State,
- node: Node,
- elementStack: Node[],
- componentStack: Node[],
- stripWhitespace: boolean
- ) => {
- node.init(block, state);
- },
-
- AwaitBlock: (
- generator: DomGenerator,
- block: Block,
- state: State,
- node: Node,
- inEachBlock: boolean,
- elementStack: Node[],
- componentStack: Node[],
- stripWhitespace: boolean,
- nextSibling: Node
- ) => {
- cannotUseInnerHTML(node);
-
- node.var = block.getUniqueName('await_block');
- block.addDependencies(node.metadata.dependencies);
-
- let dynamic = false;
-
- [
- ['pending', null],
- ['then', node.value],
- ['catch', node.error]
- ].forEach(([status, arg]) => {
- const child = node[status];
-
- const context = block.getUniqueName(arg || '_');
- const contexts = new Map(block.contexts);
- contexts.set(arg, context);
-
- child._block = block.child({
- comment: createDebuggingComment(child, generator),
- name: generator.getUniqueName(`create_${status}_block`),
- params: block.params.concat(context),
- context,
- contexts
- });
-
- child._state = getChildState(state);
-
- preprocessChildren(generator, child._block, child._state, child, inEachBlock, elementStack, componentStack, stripWhitespace, nextSibling);
- generator.blocks.push(child._block);
-
- if (child._block.dependencies.size > 0) {
- dynamic = true;
- block.addDependencies(child._block.dependencies);
- }
- });
-
- node.pending._block.hasUpdateMethod = dynamic;
- node.then._block.hasUpdateMethod = dynamic;
- node.catch._block.hasUpdateMethod = dynamic;
- },
-
- IfBlock: (
- generator: DomGenerator,
- block: Block,
- state: State,
- node: Node,
- inEachBlock: boolean,
- elementStack: Node[],
- componentStack: Node[],
- stripWhitespace: boolean,
- nextSibling: Node
- ) => {
- cannotUseInnerHTML(node);
-
- const blocks: Block[] = [];
- let dynamic = false;
- let hasIntros = false;
- let hasOutros = false;
-
- function attachBlocks(node: Node) {
- node.var = block.getUniqueName(`if_block`);
-
- block.addDependencies(node.metadata.dependencies);
-
- node._block = block.child({
- comment: createDebuggingComment(node, generator),
- name: generator.getUniqueName(`create_if_block`),
- });
-
- node._state = getChildState(state);
-
- blocks.push(node._block);
- preprocessChildren(generator, node._block, node._state, node, inEachBlock, elementStack, componentStack, stripWhitespace, nextSibling);
-
- if (node._block.dependencies.size > 0) {
- dynamic = true;
- block.addDependencies(node._block.dependencies);
- }
-
- if (node._block.hasIntroMethod) hasIntros = true;
- if (node._block.hasOutroMethod) hasOutros = true;
-
- if (isElseIf(node.else)) {
- attachBlocks(node.else.children[0]);
- } else if (node.else) {
- node.else._block = block.child({
- comment: createDebuggingComment(node.else, generator),
- name: generator.getUniqueName(`create_if_block`),
- });
-
- node.else._state = getChildState(state);
-
- blocks.push(node.else._block);
- preprocessChildren(
- generator,
- node.else._block,
- node.else._state,
- node.else,
- inEachBlock,
- elementStack,
- componentStack,
- stripWhitespace,
- nextSibling
- );
-
- if (node.else._block.dependencies.size > 0) {
- dynamic = true;
- block.addDependencies(node.else._block.dependencies);
- }
- }
- }
-
- attachBlocks(node);
-
- blocks.forEach(block => {
- block.hasUpdateMethod = dynamic;
- block.hasIntroMethod = hasIntros;
- block.hasOutroMethod = hasOutros;
- });
-
- generator.blocks.push(...blocks);
- },
-
- EachBlock: (
- generator: DomGenerator,
- block: Block,
- state: State,
- node: Node,
- inEachBlock: boolean,
- elementStack: Node[],
- componentStack: Node[],
- stripWhitespace: boolean,
- nextSibling: Node
- ) => {
- cannotUseInnerHTML(node);
- node.var = block.getUniqueName(`each`);
- node.iterations = block.getUniqueName(`${node.var}_blocks`);
-
- const { dependencies } = node.metadata;
- block.addDependencies(dependencies);
-
- const indexNames = new Map(block.indexNames);
- const indexName =
- node.index || block.getUniqueName(`${node.context}_index`);
- indexNames.set(node.context, indexName);
-
- const listNames = new Map(block.listNames);
- const listName = block.getUniqueName(
- (node.expression.type === 'MemberExpression' && !node.expression.computed) ? node.expression.property.name :
- node.expression.type === 'Identifier' ? node.expression.name :
- `each_value`
- );
- listNames.set(node.context, listName);
-
- const context = block.getUniqueName(node.context);
- const contexts = new Map(block.contexts);
- contexts.set(node.context, context);
-
- const indexes = new Map(block.indexes);
- if (node.index) indexes.set(node.index, node.context);
-
- const changeableIndexes = new Map(block.changeableIndexes);
- if (node.index) changeableIndexes.set(node.index, node.key);
-
- if (node.destructuredContexts) {
- for (let i = 0; i < node.destructuredContexts.length; i += 1) {
- contexts.set(node.destructuredContexts[i], `${context}[${i}]`);
- }
- }
-
- node._block = block.child({
- comment: createDebuggingComment(node, generator),
- name: generator.getUniqueName('create_each_block'),
- context: node.context,
- key: node.key,
-
- contexts,
- indexes,
- changeableIndexes,
-
- listName,
- indexName,
-
- indexNames,
- listNames,
- params: block.params.concat(listName, context, indexName),
- });
-
- node._state = getChildState(state, {
- inEachBlock: true,
- });
-
- generator.blocks.push(node._block);
- preprocessChildren(generator, node._block, node._state, node, true, elementStack, componentStack, stripWhitespace, nextSibling);
- block.addDependencies(node._block.dependencies);
- node._block.hasUpdateMethod = node._block.dependencies.size > 0;
-
- if (node.else) {
- node.else._block = block.child({
- comment: createDebuggingComment(node.else, generator),
- name: generator.getUniqueName(`${node._block.name}_else`),
- });
-
- node.else._state = getChildState(state);
-
- generator.blocks.push(node.else._block);
- preprocessChildren(
- generator,
- node.else._block,
- node.else._state,
- node.else,
- inEachBlock,
- elementStack,
- componentStack,
- stripWhitespace,
- nextSibling
- );
- node.else._block.hasUpdateMethod = node.else._block.dependencies.size > 0;
- }
- },
-
- Element: (
- generator: DomGenerator,
- block: Block,
- state: State,
- node: Node,
- inEachBlock: boolean,
- elementStack: Node[],
- componentStack: Node[],
- stripWhitespace: boolean,
- nextSibling: Node
- ) => {
- if (node.name === 'slot' || node.name === 'option') {
- cannotUseInnerHTML(node);
- }
-
- node.attributes.forEach((attribute: Node) => {
- if (attribute.type === 'Attribute' && attribute.value !== true) {
- attribute.value.forEach((chunk: Node) => {
- if (chunk.type !== 'Text') {
- if (node.parent) cannotUseInnerHTML(node.parent);
-
- const dependencies = chunk.metadata.dependencies;
- block.addDependencies(dependencies);
-
- // special case —
- //
- if (node.name === 'option' && !valueAttribute) {
- node.attributes.push({
- type: 'Attribute',
- name: 'value',
- value: node.children
- });
- }
-
- // special case — in a case like this...
- //
- //