From 3b5155e46c341621d69c611c1f03222c70852f95 Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Sun, 24 Nov 2019 15:47:23 -0500 Subject: [PATCH] WIP - start seeing if we can unify init and update --- src/compiler/compile/render_dom/Block.ts | 9 ++++++- .../compile/render_dom/wrappers/EachBlock.ts | 25 ++++++------------- .../compile/render_dom/wrappers/IfBlock.ts | 14 ++--------- .../compile/render_dom/wrappers/Window.ts | 12 ++++++--- .../compile/render_dom/wrappers/shared/Tag.ts | 12 ++++++--- test/runtime/index.js | 2 +- .../window-bind-scroll-update/_config.js | 2 +- 7 files changed, 37 insertions(+), 39 deletions(-) diff --git a/src/compiler/compile/render_dom/Block.ts b/src/compiler/compile/render_dom/Block.ts index c8fa884721..43d0438b84 100644 --- a/src/compiler/compile/render_dom/Block.ts +++ b/src/compiler/compile/render_dom/Block.ts @@ -287,11 +287,18 @@ export default class Block { }`; } - if (this.chunks.mount.length === 0) { + const needs_update_method = this.maintain_context || (this.chunks.update.length > 0 && this.has_update_method); + + if (this.chunks.mount.length === 0 && this.chunks.update.length === 0) { properties.mount = noop; } else { + const dirty = this.renderer.context_overflow + ? x`TODO` // this.renderer.dirty_expression + : this.parent ? x`-1` : x`[-1]`; + properties.mount = x`function #mount(#target, anchor) { ${this.chunks.mount} + ${needs_update_method && b`this.p(#ctx, ${dirty});`} }`; } diff --git a/src/compiler/compile/render_dom/wrappers/EachBlock.ts b/src/compiler/compile/render_dom/wrappers/EachBlock.ts index 5b13b486e6..f2b14e14f4 100644 --- a/src/compiler/compile/render_dom/wrappers/EachBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/EachBlock.ts @@ -203,7 +203,7 @@ export default class EachBlockWrapper extends Wrapper { const snippet = this.node.expression.manipulate(block); - block.chunks.init.push(b`let ${this.vars.each_block_value} = ${snippet};`); + block.chunks.init.push(b`let ${this.vars.each_block_value} = [];`); // TODO which is better — Object.create(array) or array.slice()? renderer.blocks.push(b` @@ -261,12 +261,12 @@ export default class EachBlockWrapper extends Wrapper { block.chunks.init.push(b`let ${each_block_else} = null;`); // TODO neaten this up... will end up with an empty line in the block - block.chunks.init.push(b` - if (!${this.vars.data_length}) { - ${each_block_else} = ${this.else.block.name}(#ctx); - ${each_block_else}.c(); - } - `); + // block.chunks.init.push(b` + // if (!${this.vars.data_length}) { + // ${each_block_else} = ${this.else.block.name}(#ctx); + // ${each_block_else}.c(); + // } + // `); block.chunks.mount.push(b` if (${each_block_else}) { @@ -336,7 +336,6 @@ export default class EachBlockWrapper extends Wrapper { const { create_each_block, iterations, - data_length, view_length } = this.vars; @@ -360,12 +359,6 @@ export default class EachBlockWrapper extends Wrapper { block.chunks.init.push(b` const ${get_key} = #ctx => ${this.node.key.manipulate(block)}; - - for (let #i = 0; #i < ${data_length}; #i += 1) { - let child_ctx = ${this.vars.get_each_context}(#ctx, ${this.vars.each_block_value}, #i); - let key = ${get_key}(child_ctx); - ${lookup}.set(key, ${iterations}[#i] = ${create_each_block}(key, child_ctx)); - } `); block.chunks.create.push(b` @@ -450,10 +443,6 @@ export default class EachBlockWrapper extends Wrapper { block.chunks.init.push(b` let ${iterations} = []; - - for (let #i = 0; #i < ${data_length}; #i += 1) { - ${iterations}[#i] = ${create_each_block}(${this.vars.get_each_context}(#ctx, ${this.vars.each_block_value}, #i)); - } `); block.chunks.create.push(b` diff --git a/src/compiler/compile/render_dom/wrappers/IfBlock.ts b/src/compiler/compile/render_dom/wrappers/IfBlock.ts index d2d4c79486..dbf244b35f 100644 --- a/src/compiler/compile/render_dom/wrappers/IfBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/IfBlock.ts @@ -500,7 +500,7 @@ export default class IfBlockWrapper extends Wrapper { render_simple( block: Block, - parent_node: Identifier, + _parent_node: Identifier, _parent_nodes: Identifier, dynamic, { name, anchor, if_exists_condition, has_transitions }, @@ -509,17 +509,7 @@ export default class IfBlockWrapper extends Wrapper { const branch = this.branches[0]; if (branch.snippet) block.add_variable(branch.condition, branch.snippet); - - block.chunks.init.push(b` - let ${name} = ${branch.condition} && ${branch.block.name}(#ctx); - `); - - const initial_mount_node = parent_node || '#target'; - const anchor_node = parent_node ? 'null' : 'anchor'; - - block.chunks.mount.push( - b`if (${name}) ${name}.m(${initial_mount_node}, ${anchor_node});` - ); + block.add_variable(name); if (branch.dependencies.length > 0) { const update_mount_node = this.get_update_mount_node(anchor); diff --git a/src/compiler/compile/render_dom/wrappers/Window.ts b/src/compiler/compile/render_dom/wrappers/Window.ts index 18691ae9a8..d55da4a2b6 100644 --- a/src/compiler/compile/render_dom/wrappers/Window.ts +++ b/src/compiler/compile/render_dom/wrappers/Window.ts @@ -139,13 +139,19 @@ export default class WindowWrapper extends Wrapper { // special case... might need to abstract this out if we add more special cases if (bindings.scrollX || bindings.scrollY) { - const condition = renderer.dirty([bindings.scrollX, bindings.scrollY].filter(Boolean)); - const scrollX = bindings.scrollX ? renderer.reference(bindings.scrollX) : x`@_window.pageXOffset`; const scrollY = bindings.scrollY ? renderer.reference(bindings.scrollY) : x`@_window.pageYOffset`; + let condition = x` + ${renderer.dirty([bindings.scrollX, bindings.scrollY].filter(Boolean))} && + !${scrolling} + `; + + if (bindings.scrollX) condition = x`${condition} && !isNaN(${scrollX})`; + if (bindings.scrollY) condition = x`${condition} && !isNaN(${scrollY})`; + block.chunks.update.push(b` - if (${condition} && !${scrolling}) { + if (${condition}) { ${scrolling} = true; @_clearTimeout(${scrolling_timeout}); @_scrollTo(${scrollX}, ${scrollY}); diff --git a/src/compiler/compile/render_dom/wrappers/shared/Tag.ts b/src/compiler/compile/render_dom/wrappers/shared/Tag.ts index 10e2a4a18d..65e240ecb5 100644 --- a/src/compiler/compile/render_dom/wrappers/shared/Tag.ts +++ b/src/compiler/compile/render_dom/wrappers/shared/Tag.ts @@ -31,12 +31,16 @@ export default class Tag extends Wrapper { const dependencies = this.node.expression.dynamic_dependencies(); let snippet = this.node.expression.manipulate(block); - const value = this.node.should_cache && block.get_unique_name(`${this.var.name}_value`); + const value = block.get_unique_name(`${this.var.name}_value`); const content = this.node.should_cache ? value : snippet; snippet = x`${snippet} + ""`; - if (this.node.should_cache) block.add_variable(value, snippet); // TODO may need to coerce snippet to string + if (dependencies.length > 0) { + block.add_variable(value); + } else { + block.add_variable(value, snippet); + } if (dependencies.length > 0) { let condition = block.renderer.dirty(dependencies); @@ -54,6 +58,8 @@ export default class Tag extends Wrapper { block.chunks.update.push(b`if (${condition}) ${update(content as Node)}`); } - return { init: content }; + return { + init: value + }; } } \ No newline at end of file diff --git a/test/runtime/index.js b/test/runtime/index.js index fc989d352f..79dfd9e050 100644 --- a/test/runtime/index.js +++ b/test/runtime/index.js @@ -26,7 +26,7 @@ process.on('unhandledRejection', err => { unhandled_rejection = err; }); -describe("runtime", () => { +describe.only("runtime", () => { before(() => { svelte = loadSvelte(false); svelte$ = loadSvelte(true); diff --git a/test/runtime/samples/window-bind-scroll-update/_config.js b/test/runtime/samples/window-bind-scroll-update/_config.js index cb13ea11c2..7c78060a8d 100644 --- a/test/runtime/samples/window-bind-scroll-update/_config.js +++ b/test/runtime/samples/window-bind-scroll-update/_config.js @@ -3,7 +3,7 @@ import { env, useFakeTimers } from "../../../helpers"; let clock; export default { - before_test() { + before_test() { clock = useFakeTimers(); const window = env();