From 47d07c3e25b0c0182d0f1d80af0d7cc736567bee Mon Sep 17 00:00:00 2001 From: Mathias Picker Date: Fri, 23 Dec 2022 10:25:45 +0100 Subject: [PATCH] fixed double up initialization on svelte:element elements --- .../render_dom/wrappers/Element/index.ts | 135 +++++++++--------- .../svelte-element-event-handlers/expected.js | 125 ++++++++++++++++ .../input.svelte | 3 + 3 files changed, 198 insertions(+), 65 deletions(-) create mode 100644 test/js/samples/svelte-element-event-handlers/expected.js create mode 100644 test/js/samples/svelte-element-event-handlers/input.svelte diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts index 8d0429879e..30ca9a266d 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts @@ -169,8 +169,8 @@ export default class ElementWrapper extends Wrapper { next_sibling: Wrapper ) { super(renderer, block, parent, node); - - if (node.is_dynamic_element && block.type !== CHILD_DYNAMIC_ELEMENT_BLOCK) { + const is_original_dynamic_element = node.is_dynamic_element && block.type !== CHILD_DYNAMIC_ELEMENT_BLOCK; + if (is_original_dynamic_element) { this.child_dynamic_element_block = block.child({ comment: create_debugging_comment(node, renderer.component), name: renderer.component.get_unique_name('create_dynamic_element'), @@ -187,82 +187,87 @@ export default class ElementWrapper extends Wrapper { ); } - this.var = { - type: 'Identifier', - name: node.name.replace(regex_invalid_variable_identifier_characters, '_') - }; - - this.void = is_void(node.name); - - this.class_dependencies = []; - - if (this.node.children.length) { - this.node.lets.forEach(l => { - extract_names(l.value || l.name).forEach(name => { - renderer.add_to_context(name, true); + // the original svelte:element is never used for rendering, because + // it gets assigned a child_dynamic_element which is used in all rendering logic. + // so doing all of this on the original svelte:element will just cause double + // code, because it will be done again on the child_dynamic_element. + if (!is_original_dynamic_element) { + this.var = { + type: 'Identifier', + name: node.name.replace(regex_invalid_variable_identifier_characters, '_') + }; + + this.void = is_void(node.name); + + this.class_dependencies = []; + if (this.node.children.length) { + this.node.lets.forEach(l => { + extract_names(l.value || l.name).forEach(name => { + renderer.add_to_context(name, true); + }); }); + } + + this.attributes = this.node.attributes.map(attribute => { + if (attribute.name === 'style') { + return new StyleAttributeWrapper(this, block, attribute); + } + if (attribute.type === 'Spread') { + return new SpreadAttributeWrapper(this, block, attribute); + } + return new AttributeWrapper(this, block, attribute); }); - } - this.attributes = this.node.attributes.map(attribute => { - if (attribute.name === 'style') { - return new StyleAttributeWrapper(this, block, attribute); - } - if (attribute.type === 'Spread') { - return new SpreadAttributeWrapper(this, block, attribute); - } - return new AttributeWrapper(this, block, attribute); - }); + // ordinarily, there'll only be one... but we need to handle + // the rare case where an element can have multiple bindings, + // e.g.