Skip to content

Commit a8eaa7e

Browse files
committed
refactor
1 parent e859597 commit a8eaa7e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+4215
-4273
lines changed

src/css/Stylesheet.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { walk } from 'estree-walker';
33
import { getLocator } from 'locate-character';
44
import Selector from './Selector';
55
import getCodeFrame from '../utils/getCodeFrame';
6+
import Element from '../generators/nodes/Element';
67
import { Validator } from '../validate/index';
78
import { Node, Parsed, Warning } from '../interfaces';
89

@@ -19,7 +20,7 @@ class Rule {
1920
this.declarations = node.block.children.map((node: Node) => new Declaration(node));
2021
}
2122

22-
apply(node: Node, stack: Node[]) {
23+
apply(node: Element, stack: Element[]) {
2324
this.selectors.forEach(selector => selector.apply(node, stack)); // TODO move the logic in here?
2425
}
2526

@@ -159,7 +160,7 @@ class Atrule {
159160
this.children = [];
160161
}
161162

162-
apply(node: Node, stack: Node[]) {
163+
apply(node: Element, stack: Element[]) {
163164
if (this.node.name === 'media') {
164165
this.children.forEach(child => {
165166
child.apply(node, stack);
@@ -330,9 +331,15 @@ export default class Stylesheet {
330331
}
331332
}
332333

333-
apply(node: Node, stack: Node[]) {
334+
apply(node: Element) {
334335
if (!this.hasStyles) return;
335336

337+
const stack: Element[] = [];
338+
let parent: Node = node;
339+
while (parent = parent.parent) {
340+
if (parent.type === 'Element') stack.unshift(<Element>parent);
341+
}
342+
336343
if (this.cascade) {
337344
if (stack.length === 0) node._needsCssAttribute = true;
338345
return;

src/generators/Generator.ts

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@ import flattenReference from '../utils/flattenReference';
99
import reservedNames from '../utils/reservedNames';
1010
import namespaces from '../utils/namespaces';
1111
import { removeNode, removeObjectKey } from '../utils/removeNode';
12-
import wrapModule from './shared/utils/wrapModule';
12+
import wrapModule from './wrapModule';
1313
import annotateWithScopes, { Scope } from '../utils/annotateWithScopes';
1414
import getName from '../utils/getName';
1515
import clone from '../utils/clone';
16-
import DomBlock from './dom/Block';
17-
import SsrBlock from './server-side-rendering/Block';
1816
import Stylesheet from '../css/Stylesheet';
1917
import { test } from '../config';
18+
import nodes from './nodes/index';
2019
import { Node, GenerateOptions, Parsed, CompileOptions, CustomElementOptions } from '../interfaces';
2120

2221
interface Computation {
@@ -162,11 +161,9 @@ export default class Generator {
162161

163162
this.computations = [];
164163
this.templateProperties = {};
164+
this.name = this.alias(name);
165165

166166
this.walkJs(dom);
167-
this.walkTemplate();
168-
169-
this.name = this.alias(name);
170167

171168
if (options.customElement === true) {
172169
this.customElement = {
@@ -180,6 +177,8 @@ export default class Generator {
180177
if (this.customElement && !this.customElement.tag) {
181178
throw new Error(`No tag name specified`); // TODO better error
182179
}
180+
181+
this.walkTemplate();
183182
}
184183

185184
addSourcemapLocations(node: Node) {
@@ -200,7 +199,8 @@ export default class Generator {
200199
}
201200

202201
contextualise(
203-
block: DomBlock | SsrBlock,
202+
contexts: Map<string, string>,
203+
indexes: Map<string, string>,
204204
expression: Node,
205205
context: string,
206206
isEventHandler: boolean
@@ -214,7 +214,6 @@ export default class Generator {
214214
const usedIndexes: Set<string> = new Set();
215215

216216
const { code, helpers } = this;
217-
const { contexts, indexes } = block;
218217

219218
let scope: Scope;
220219
let lexicalDepth = 0;
@@ -638,6 +637,7 @@ export default class Generator {
638637
}
639638

640639
walkTemplate() {
640+
const generator = this;
641641
const {
642642
code,
643643
expectedProperties,
@@ -703,7 +703,30 @@ export default class Generator {
703703
const indexesStack: Set<string>[] = [indexes];
704704

705705
walk(html, {
706-
enter(node: Node, parent: Node) {
706+
enter(node: Node, parent: Node, key: string) {
707+
// TODO this is hacky as hell
708+
if (key === 'parent') return this.skip();
709+
node.parent = parent;
710+
711+
node.generator = generator;
712+
713+
if (node.type === 'Element' && (node.name === ':Component' || node.name === ':Self' || generator.components.has(node.name))) {
714+
node.type = 'Component';
715+
node.__proto__ = nodes.Component.prototype;
716+
} else if (node.name === ':Window') { // TODO do this in parse?
717+
node.type = 'Window';
718+
node.__proto__ = nodes.Window.prototype;
719+
} else if (node.type === 'Element' && node.name === 'slot' && !generator.customElement) {
720+
node.type = 'Slot';
721+
node.__proto__ = nodes.Slot.prototype;
722+
} else if (node.type in nodes) {
723+
node.__proto__ = nodes[node.type].prototype;
724+
}
725+
726+
if (node.type === 'Element') {
727+
generator.stylesheet.apply(node);
728+
}
729+
707730
if (node.type === 'EachBlock') {
708731
node.metadata = contextualise(node.expression, contextDependencies, indexes);
709732

@@ -764,7 +787,7 @@ export default class Generator {
764787
this.skip();
765788
}
766789

767-
if (node.type === 'Element' && node.name === ':Component') {
790+
if (node.type === 'Component' && node.name === ':Component') {
768791
node.metadata = contextualise(node.expression, contextDependencies, indexes);
769792
}
770793
},
@@ -779,6 +802,22 @@ export default class Generator {
779802
indexes = indexesStack[indexesStack.length - 1];
780803
}
781804
}
805+
806+
if (node.type === 'Element' && node.name === 'option') {
807+
// Special case — treat these the same way:
808+
// <option>{{foo}}</option>
809+
// <option value='{{foo}}'>{{foo}}</option>
810+
const valueAttribute = node.attributes.find((attribute: Node) => attribute.name === 'value');
811+
812+
if (!valueAttribute) {
813+
node.attributes.push(new nodes.Attribute({
814+
generator,
815+
name: 'value',
816+
value: node.children,
817+
parent: node
818+
}));
819+
}
820+
}
782821
}
783822
});
784823
}

src/generators/dom/Block.ts

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -130,15 +130,14 @@ export default class Block {
130130
claimStatement: string,
131131
parentNode: string
132132
) {
133-
const isToplevel = !parentNode;
134-
135133
this.addVariable(name);
136134
this.builders.create.addLine(`${name} = ${renderStatement};`);
137135
this.builders.claim.addLine(`${name} = ${claimStatement};`);
138136

139-
this.mount(name, parentNode);
140-
141-
if (isToplevel) {
137+
if (parentNode) {
138+
this.builders.mount.addLine(`@appendNode(${name}, ${parentNode});`);
139+
} else {
140+
this.builders.mount.addLine(`@insertNode(${name}, #target, anchor);`);
142141
this.builders.unmount.addLine(`@detachNode(${name});`);
143142
}
144143
}
@@ -166,20 +165,7 @@ export default class Block {
166165
}
167166

168167
contextualise(expression: Node, context?: string, isEventHandler?: boolean) {
169-
return this.generator.contextualise(
170-
this,
171-
expression,
172-
context,
173-
isEventHandler
174-
);
175-
}
176-
177-
mount(name: string, parentNode: string) {
178-
if (parentNode) {
179-
this.builders.mount.addLine(`@appendNode(${name}, ${parentNode});`);
180-
} else {
181-
this.builders.mount.addLine(`@insertNode(${name}, #target, anchor);`);
182-
}
168+
return this.generator.contextualise(this.contexts, this.indexes, expression, context, isEventHandler);
183169
}
184170

185171
toString() {

src/generators/dom/index.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@ import { stringify, escape } from '../../utils/stringify';
88
import CodeBuilder from '../../utils/CodeBuilder';
99
import globalWhitelist from '../../utils/globalWhitelist';
1010
import reservedNames from '../../utils/reservedNames';
11-
import visit from './visit';
1211
import shared from './shared';
1312
import Generator from '../Generator';
1413
import Stylesheet from '../../css/Stylesheet';
15-
import preprocess from './preprocess';
1614
import Block from './Block';
1715
import { test } from '../../config';
1816
import { Parsed, CompileOptions, Node } from '../../interfaces';
@@ -96,14 +94,11 @@ export default function dom(
9694
namespace,
9795
} = generator;
9896

99-
const { block, state } = preprocess(generator, namespace, parsed.html);
97+
parsed.html.build();
98+
const { block } = parsed.html;
10099

101100
generator.stylesheet.warnOnUnusedSelectors(options.onwarn);
102101

103-
parsed.html.children.forEach((node: Node) => {
104-
visit(generator, block, state, node, [], []);
105-
});
106-
107102
const builder = new CodeBuilder();
108103
const computationBuilder = new CodeBuilder();
109104
const computationDeps = new Set();

src/generators/dom/interfaces.ts

Lines changed: 0 additions & 23 deletions
This file was deleted.

0 commit comments

Comments
 (0)