Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/generators/Generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,8 @@ export default class Generator {
return alias;
}

getUniqueNameMaker(params: string[]) {
const localUsedNames = new Set(params);
getUniqueNameMaker() {
const localUsedNames = new Set();

function add(name: string) {
localUsedNames.add(name);
Expand Down
38 changes: 31 additions & 7 deletions src/generators/dom/Block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export interface BlockOptions {
contextTypes?: Map<string, string>;
indexes?: Map<string, string>;
changeableIndexes?: Map<string, boolean>;
params?: string[];
indexNames?: Map<string, string>;
listNames?: Map<string, string>;
indexName?: string;
Expand All @@ -41,7 +40,6 @@ export default class Block {
indexes: Map<string, string>;
changeableIndexes: Map<string, boolean>;
dependencies: Set<string>;
params: string[];
indexNames: Map<string, string>;
listNames: Map<string, string>;
indexName: string;
Expand Down Expand Up @@ -90,10 +88,10 @@ export default class Block {
this.changeableIndexes = options.changeableIndexes;
this.dependencies = new Set();

this.params = options.params;
this.indexNames = options.indexNames;
this.listNames = options.listNames;

this.indexName = options.indexName;
this.listName = options.listName;

this.builders = {
Expand All @@ -116,7 +114,7 @@ export default class Block {

this.aliases = new Map();
this.variables = new Map();
this.getUniqueName = this.generator.getUniqueNameMaker(options.params);
this.getUniqueName = this.generator.getUniqueNameMaker();

this.hasUpdateMethod = false; // determined later
}
Expand Down Expand Up @@ -191,6 +189,29 @@ export default class Block {
this.builders.mount.addLine(`${this.autofocus}.focus();`);
}

// TODO `this.contexts` is possibly redundant post-#1122
const initializers = [];
const updaters = [];
this.contexts.forEach((alias, name) => {
// TODO only the ones that are actually used in this block...
const assignment = `${alias} = state.${name}`;

initializers.push(assignment);
updaters.push(`${assignment};`);

this.hasUpdateMethod = true;
});

this.indexNames.forEach((alias, name) => {
// TODO only the ones that are actually used in this block...
const assignment = `${alias} = state.${alias}`; // TODO this is wrong!!!

initializers.push(assignment);
updaters.push(`${assignment};`);

this.hasUpdateMethod = true;
});

// minor hack – we need to ensure that any {{{triples}}} are detached first
this.builders.unmount.addBlockAtStart(this.builders.detachRaw.toString());

Expand Down Expand Up @@ -250,11 +271,12 @@ export default class Block {
}

if (this.hasUpdateMethod) {
if (this.builders.update.isEmpty()) {
if (this.builders.update.isEmpty() && updaters.length === 0) {
properties.addBlock(`p: @noop,`);
} else {
properties.addBlock(deindent`
p: function update(changed, ${this.params.join(', ')}) {
p: function update(changed, state) {
${updaters}
${this.builders.update}
},
`);
Expand Down Expand Up @@ -328,7 +350,9 @@ export default class Block {

return deindent`
${this.comment && `// ${escape(this.comment)}`}
function ${this.name}(${this.params.join(', ')}, #component${this.key ? `, ${localKey}` : ''}) {
function ${this.name}(#component${this.key ? `, ${localKey}` : ''}, state) {
${initializers.length > 0 &&
`var ${initializers.join(', ')};`}
${this.variables.size > 0 &&
`var ${Array.from(this.variables.keys())
.map(key => {
Expand Down
6 changes: 3 additions & 3 deletions src/generators/dom/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ export class DomGenerator extends Generator {
this.metaBindings = [];
}

getUniqueNameMaker(params: string[]) {
const localUsedNames = new Set(params);
getUniqueNameMaker() {
const localUsedNames = new Set();

function add(name: string) {
localUsedNames.add(name);
Expand Down Expand Up @@ -257,7 +257,7 @@ export default function dom(

${generator.slots.size && `this.slots = {};`}

this._fragment = @create_main_fragment(this._state, this);
this._fragment = @create_main_fragment(this, this._state);

${(templateProperties.oncreate) && deindent`
this.root._oncreate.push(_oncreate);
Expand Down
57 changes: 31 additions & 26 deletions src/generators/nodes/AwaitBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,19 @@ export default class AwaitBlock extends Node {
].forEach(([status, arg]) => {
const child = this[status];

const context = block.getUniqueName(arg || '_'); // TODO can we remove the extra param from pending blocks?
const contexts = new Map(block.contexts);
contexts.set(arg, context);

const contextTypes = new Map(block.contextTypes);
contextTypes.set(arg, status);

child.block = block.child({
comment: createDebuggingComment(child, this.generator),
name: this.generator.getUniqueName(`create_${status}_block`),
params: block.params.concat(context),
context,
contexts,
contextTypes
contexts: new Map(block.contexts),
contextTypes: new Map(block.contextTypes)
});

if (arg) {
child.block.context = arg;
child.block.contexts.set(arg, arg); // TODO should be using getUniqueName
child.block.contextTypes.set(arg, status);
}

child.initChildren(child.block, stripWhitespace, nextSibling);
this.generator.blocks.push(child.block);

Expand All @@ -75,8 +72,6 @@ export default class AwaitBlock extends Node {
const anchor = this.getOrCreateAnchor(block, parentNode, parentNodes);
const updateMountNode = this.getUpdateMountNode(anchor);

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

block.contextualise(this.expression);
const { snippet } = this.metadata;

Expand Down Expand Up @@ -106,11 +101,11 @@ export default class AwaitBlock extends Node {
// but it's probably not worth it

block.builders.init.addBlock(deindent`
function ${replace_await_block}(${token}, type, ${value}, ${params}) {
function ${replace_await_block}(${token}, type, state) {
if (${token} !== ${await_token}) return;

var ${old_block} = ${await_block};
${await_block} = (${await_block_type} = type)(${params}, ${resolved} = ${value}, #component);
${await_block} = type && (${await_block_type} = type)(#component, state);

if (${old_block}) {
${old_block}.u();
Expand All @@ -122,33 +117,43 @@ export default class AwaitBlock extends Node {
}
}

function ${handle_promise}(${promise}, ${params}) {
function ${handle_promise}(${promise}, state) {
var ${token} = ${await_token} = {};

if (@isPromise(${promise})) {
${promise}.then(function(${value}) {
var state = #component.get();
${replace_await_block}(${token}, ${create_then_block}, ${value}, ${params});
${this.then.block.context ? deindent`
var state = #component.get();
${resolved} = { ${this.then.block.context}: ${value} };
${replace_await_block}(${token}, ${create_then_block}, @assign({}, state, ${resolved}));
` : deindent`
${replace_await_block}(${token}, null, null);
`}
}, function (${error}) {
var state = #component.get();
${replace_await_block}(${token}, ${create_catch_block}, ${error}, ${params});
${this.catch.block.context ? deindent`
var state = #component.get();
${resolved} = { ${this.catch.block.context}: ${error} };
${replace_await_block}(${token}, ${create_catch_block}, @assign({}, state, ${resolved}));
` : deindent`
${replace_await_block}(${token}, null, null);
`}
});

// if we previously had a then/catch block, destroy it
if (${await_block_type} !== ${create_pending_block}) {
${replace_await_block}(${token}, ${create_pending_block}, null, ${params});
${replace_await_block}(${token}, ${create_pending_block}, state);
return true;
}
} else {
${resolved} = ${promise};
${resolved} = { ${this.then.block.context}: ${promise} };
if (${await_block_type} !== ${create_then_block}) {
${replace_await_block}(${token}, ${create_then_block}, ${resolved}, ${params});
${replace_await_block}(${token}, ${create_then_block}, @assign({}, state, ${resolved}));
return true;
}
}
}

${handle_promise}(${promise} = ${snippet}, ${params});
${handle_promise}(${promise} = ${snippet}, state);
`);

block.builders.create.addBlock(deindent`
Expand Down Expand Up @@ -177,15 +182,15 @@ export default class AwaitBlock extends Node {

conditions.push(
`${promise} !== (${promise} = ${snippet})`,
`${handle_promise}(${promise}, ${params})`
`${handle_promise}(${promise}, state)`
);

if (this.pending.block.hasUpdateMethod) {
block.builders.update.addBlock(deindent`
if (${conditions.join(' && ')}) {
// nothing
} else {
${await_block}.p(changed, ${params}, ${resolved});
${await_block}.p(changed, @assign({}, state, ${resolved}));
}
`);
} else {
Expand Down
Loading