Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update SSR render method, and introduce <:Head> #1024

Merged
merged 10 commits into from
Dec 14, 2017
Merged
5 changes: 4 additions & 1 deletion src/generators/Generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,9 @@ export default class Generator {

this.computations = [];
this.templateProperties = {};
this.name = this.alias(name);

this.walkJs(dom);
this.name = this.alias(name);

if (options.customElement === true) {
this.customElement = {
Expand Down Expand Up @@ -727,6 +727,9 @@ export default class Generator {
} else if (node.name === ':Window') { // TODO do this in parse?
node.type = 'Window';
node.__proto__ = nodes.Window.prototype;
} else if (node.name === ':Head') { // TODO do this in parse?
node.type = 'Head';
node.__proto__ = nodes.Head.prototype;
} else if (node.type === 'Element' && node.name === 'slot' && !generator.customElement) {
node.type = 'Slot';
node.__proto__ = nodes.Slot.prototype;
Expand Down
7 changes: 4 additions & 3 deletions src/generators/dom/Block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,11 @@ export default class Block {
) {
this.addVariable(name);
this.builders.create.addLine(`${name} = ${renderStatement};`);
this.builders.claim.addLine(`${name} = ${claimStatement};`);
this.builders.claim.addLine(`${name} = ${claimStatement || renderStatement};`);

if (parentNode) {
this.builders.mount.addLine(`@appendNode(${name}, ${parentNode});`);
if (parentNode === 'document.head') this.builders.unmount.addLine(`@detachNode(${name});`);
} else {
this.builders.mount.addLine(`@insertNode(${name}, #target, anchor);`);
this.builders.unmount.addLine(`@detachNode(${name});`);
Expand Down Expand Up @@ -203,7 +204,7 @@ export default class Block {
this.builders.hydrate.addLine(`this.first = ${this.first};`);
}

if (this.builders.create.isEmpty()) {
if (this.builders.create.isEmpty() && this.builders.hydrate.isEmpty()) {
properties.addBlock(`c: @noop,`);
} else {
properties.addBlock(deindent`
Expand All @@ -215,7 +216,7 @@ export default class Block {
}

if (this.generator.hydratable) {
if (this.builders.claim.isEmpty()) {
if (this.builders.claim.isEmpty() && this.builders.hydrate.isEmpty()) {
properties.addBlock(`l: @noop,`);
} else {
properties.addBlock(deindent`
Expand Down
11 changes: 7 additions & 4 deletions src/generators/nodes/Attribute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,7 @@ export default class Attribute {
? '@setXlinkAttribute'
: '@setAttribute';

const isDynamic =
(this.value !== true && this.value.length > 1) ||
(this.value.length === 1 && this.value[0].type !== 'Text');

const isDynamic = this.isDynamic();
const isLegacyInputType = this.generator.legacy && name === 'type' && this.parent.name === 'input';

const isDataSet = /^data-/.test(name) && !this.generator.legacy && !node.namespace;
Expand Down Expand Up @@ -310,6 +307,12 @@ export default class Attribute {
);
});
}

isDynamic() {
if (this.value === true || this.value.length === 0) return false;
if (this.value.length > 1) return true;
return this.value[0].type !== 'Text';
}
}

// source: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
Expand Down
10 changes: 6 additions & 4 deletions src/generators/nodes/AwaitBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export default class AwaitBlock extends Node {
) {
const name = this.var;

const anchor = this.getOrCreateAnchor(block, parentNode);
const anchor = this.getOrCreateAnchor(block, parentNode, parentNodes);
const updateMountNode = this.getUpdateMountNode(anchor);

const params = block.params.join(', ');
Expand Down Expand Up @@ -143,9 +143,11 @@ export default class AwaitBlock extends Node {
${await_block}.c();
`);

block.builders.claim.addBlock(deindent`
${await_block}.l(${parentNodes});
`);
if (parentNodes) {
block.builders.claim.addBlock(deindent`
${await_block}.l(${parentNodes});
`);
}

const initialMountNode = parentNode || '#target';
const anchorNode = parentNode ? 'null' : 'anchor';
Expand Down
18 changes: 11 additions & 7 deletions src/generators/nodes/Component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ export default class Component extends Node {
block.contextualise(this.expression);
const { dependencies, snippet } = this.metadata;

const anchor = this.getOrCreateAnchor(block, parentNode);
const anchor = this.getOrCreateAnchor(block, parentNode, parentNodes);

const params = block.params.join(', ');

Expand Down Expand Up @@ -281,9 +281,11 @@ export default class Component extends Node {
`if (${name}) ${name}._fragment.c();`
);

block.builders.claim.addLine(
`if (${name}) ${name}._fragment.l(${parentNodes});`
);
if (parentNodes) {
block.builders.claim.addLine(
`if (${name}) ${name}._fragment.l(${parentNodes});`
);
}

block.builders.mount.addLine(
`if (${name}) ${name}._mount(${parentNode || '#target'}, ${parentNode ? 'null' : 'anchor'});`
Expand Down Expand Up @@ -350,9 +352,11 @@ export default class Component extends Node {

block.builders.create.addLine(`${name}._fragment.c();`);

block.builders.claim.addLine(
`${name}._fragment.l(${parentNodes});`
);
if (parentNodes) {
block.builders.claim.addLine(
`${name}._fragment.l(${parentNodes});`
);
}

block.builders.mount.addLine(
`${name}._mount(${parentNode || '#target'}, ${parentNode ? 'null' : 'anchor'});`
Expand Down
32 changes: 18 additions & 14 deletions src/generators/nodes/EachBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export default class EachBlock extends Node {
block.addElement(
anchor,
`@createComment()`,
`@createComment()`,
parentNodes && `@createComment()`,
parentNode
);
}
Expand Down Expand Up @@ -263,7 +263,7 @@ export default class EachBlock extends Node {
this.block.addElement(
this.block.first,
`@createComment()`,
`@createComment()`,
parentNodes && `@createComment()`,
null
);
}
Expand Down Expand Up @@ -293,13 +293,15 @@ export default class EachBlock extends Node {
}
`);

block.builders.claim.addBlock(deindent`
var ${iteration} = ${head};
while (${iteration}) {
${iteration}.l(${parentNodes});
${iteration} = ${iteration}.next;
}
`);
if (parentNodes) {
block.builders.claim.addBlock(deindent`
var ${iteration} = ${head};
while (${iteration}) {
${iteration}.l(${parentNodes});
${iteration} = ${iteration}.next;
}
`);
}

block.builders.mount.addBlock(deindent`
var ${iteration} = ${head};
Expand Down Expand Up @@ -481,11 +483,13 @@ export default class EachBlock extends Node {
}
`);

block.builders.claim.addBlock(deindent`
for (var #i = 0; #i < ${iterations}.length; #i += 1) {
${iterations}[#i].l(${parentNodes});
}
`);
if (parentNodes) {
block.builders.claim.addBlock(deindent`
for (var #i = 0; #i < ${iterations}.length; #i += 1) {
${iterations}[#i].l(${parentNodes});
}
`);
}

block.builders.mount.addBlock(deindent`
for (var #i = 0; #i < ${iterations}.length; #i += 1) {
Expand Down
35 changes: 22 additions & 13 deletions src/generators/nodes/Element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ export default class Element extends Node {

const childState = {
parentNode: this.var,
parentNodes: block.getUniqueName(`${this.var}_nodes`)
parentNodes: parentNodes && block.getUniqueName(`${this.var}_nodes`) // if we're in unclaimable territory, i.e. <head>, parentNodes is null
};

const name = this.var;
Expand All @@ -175,25 +175,32 @@ export default class Element extends Node {
parentNode;

block.addVariable(name);
const renderStatement = getRenderStatement(this.generator, this.namespace, this.name);
block.builders.create.addLine(
`${name} = ${getRenderStatement(
this.generator,
this.namespace,
this.name
)};`
`${name} = ${renderStatement};`
);

if (this.generator.hydratable) {
block.builders.claim.addBlock(deindent`
${name} = ${getClaimStatement(generator, this.namespace, parentNodes, this)};
var ${childState.parentNodes} = @children(${name});
`);
if (parentNodes) {
block.builders.claim.addBlock(deindent`
${name} = ${getClaimStatement(generator, this.namespace, parentNodes, this)};
var ${childState.parentNodes} = @children(${name});
`);
} else {
block.builders.claim.addLine(
`${name} = ${renderStatement};`
);
}
}

if (initialMountNode) {
block.builders.mount.addLine(
`@appendNode(${name}, ${initialMountNode});`
);

if (initialMountNode === 'document.head') {
block.builders.unmount.addLine(`@detachNode(${name});`);
}
} else {
block.builders.mount.addLine(`@insertNode(${name}, #target, anchor);`);

Expand Down Expand Up @@ -394,9 +401,11 @@ export default class Element extends Node {
block.builders.mount.addBlock(this.initialUpdate);
}

block.builders.claim.addLine(
`${childState.parentNodes}.forEach(@detachNode);`
);
if (childState.parentNodes) {
block.builders.claim.addLine(
`${childState.parentNodes}.forEach(@detachNode);`
);
}

function toHTML(node: Element | Text) {
if (node.type === 'Text') return node.data;
Expand Down
32 changes: 32 additions & 0 deletions src/generators/nodes/Head.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import deindent from '../../utils/deindent';
import { stringify } from '../../utils/stringify';
import Node from './shared/Node';
import Block from '../dom/Block';
import Attribute from './Attribute';

export default class Head extends Node {
type: 'Head';
attributes: Attribute[];

init(
block: Block,
stripWhitespace: boolean,
nextSibling: Node
) {
this.initChildren(block, true, null);
}

build(
block: Block,
parentNode: string,
parentNodes: string
) {
const { generator } = this;

this.var = 'document.head';

this.children.forEach((child: Node) => {
child.build(block, 'document.head', null);
});
}
}
10 changes: 6 additions & 4 deletions src/generators/nodes/IfBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,15 +133,17 @@ export default class IfBlock extends Node {

block.builders.create.addLine(`${if_name}${name}.c();`);

block.builders.claim.addLine(
`${if_name}${name}.l(${parentNodes});`
);
if (parentNodes) {
block.builders.claim.addLine(
`${if_name}${name}.l(${parentNodes});`
);
}

if (needsAnchor) {
block.addElement(
anchor,
`@createComment()`,
`@createComment()`,
parentNodes && `@createComment()`,
parentNode
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/generators/nodes/MustacheTag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default class MustacheTag extends Tag {
block.addElement(
this.var,
`@createText(${init})`,
`@claimText(${parentNodes}, ${init})`,
parentNodes && `@claimText(${parentNodes}, ${init})`,
parentNode
);
}
Expand Down
4 changes: 2 additions & 2 deletions src/generators/nodes/RawMustacheTag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export default class RawMustacheTag extends Tag {
block.addElement(
anchorBefore,
`@createElement('noscript')`,
`@createElement('noscript')`,
parentNodes && `@createElement('noscript')`,
parentNode
);
}
Expand All @@ -70,7 +70,7 @@ export default class RawMustacheTag extends Tag {
block.addElement(
anchorAfter,
`@createElement('noscript')`,
`@createElement('noscript')`,
parentNodes && `@createElement('noscript')`,
parentNode
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/generators/nodes/Text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default class Text extends Node {
block.addElement(
this.var,
`@createText(${stringify(this.data)})`,
`@claimText(${parentNodes}, ${stringify(this.data)})`,
parentNodes && `@claimText(${parentNodes}, ${stringify(this.data)})`,
parentNode
);
}
Expand Down
2 changes: 2 additions & 0 deletions src/generators/nodes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Element from './Element';
import ElseBlock from './ElseBlock';
import EventHandler from './EventHandler';
import Fragment from './Fragment';
import Head from './Head';
import IfBlock from './IfBlock';
import MustacheTag from './MustacheTag';
import PendingBlock from './PendingBlock';
Expand All @@ -33,6 +34,7 @@ const nodes: Record<string, any> = {
ElseBlock,
EventHandler,
Fragment,
Head,
IfBlock,
MustacheTag,
PendingBlock,
Expand Down
4 changes: 2 additions & 2 deletions src/generators/nodes/shared/Node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export default class Node {
if (this.parent) return this.parent.findNearest(selector);
}

getOrCreateAnchor(block: Block, parentNode: string) {
getOrCreateAnchor(block: Block, parentNode: string, parentNodes: string) {
// TODO use this in EachBlock and IfBlock — tricky because
// children need to be created first
const needsAnchor = this.next ? !this.next.isDomNode() : !parentNode || !this.parent.isDomNode();
Expand All @@ -150,7 +150,7 @@ export default class Node {
block.addElement(
anchor,
`@createComment()`,
`@createComment()`,
parentNodes && `@createComment()`,
parentNode
);
}
Expand Down
Loading