diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index a5a31c807004..9fe3cca84dab 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -445,8 +445,12 @@ export default class Component { }); } - extract_imports(node) { + extract_imports(node: ImportDeclaration) { this.imports.push(node); + for (const specifier of node.specifiers) { + const variable = this.var_lookup.get(specifier.local.name); + variable.imported = true; + } } extract_exports(node) { diff --git a/src/compiler/compile/render_dom/wrappers/Element/Binding.ts b/src/compiler/compile/render_dom/wrappers/Element/Binding.ts index ac5732eae7b0..f2b080c81258 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/Binding.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/Binding.ts @@ -121,18 +121,30 @@ export default class BindingWrapper { switch (this.node.name) { case 'group': { - const binding_group = get_binding_group(parent.renderer, this.node.expression.node); - - block.renderer.add_to_context(`$$binding_groups`); - const reference = block.renderer.reference(`$$binding_groups`); - - block.chunks.hydrate.push( - b`${reference}[${binding_group}].push(${parent.var});` - ); - - block.chunks.destroy.push( - b`${reference}[${binding_group}].splice(${reference}[${binding_group}].indexOf(${parent.var}), 1);` - ); + const variable = block.renderer.component.var_lookup.get(this.object); + const use_global_binding_group = variable && (variable.imported || variable.export_name); + if (use_global_binding_group) { + block.chunks.hydrate.push( + b`@add_into_binding_group(${this.snippet}, ${parent.var});` + ); + + block.chunks.destroy.push( + b`@remove_from_binding_group(${this.snippet}, ${parent.var});` + ); + } else { + const binding_group = get_binding_group(parent.renderer, this.node.expression.node); + + block.renderer.add_to_context(`$$binding_groups`); + const reference = block.renderer.reference(`$$binding_groups`); + + block.chunks.hydrate.push( + b`${reference}[${binding_group}].push(${parent.var});` + ); + + block.chunks.destroy.push( + b`${reference}[${binding_group}].splice(${reference}[${binding_group}].indexOf(${parent.var}), 1);` + ); + } break; } @@ -233,7 +245,10 @@ function get_dom_updater( ? x`~${binding.snippet}.indexOf(${element.var}.__value)` : x`${element.var}.__value === ${binding.snippet}`; - return b`${element.var}.checked = ${condition};`; + return b` + @reattach_binding_group(${binding.snippet}, ${element.var}); + ${element.var}.checked = ${condition}; + `; } if (binding.node.name === 'value') { @@ -332,6 +347,11 @@ function get_value_from_dom( // if (name === 'group') { + const variable = renderer.component.var_lookup.get(binding.object); + if (variable && (variable.imported || variable.export_name)) { + return x`@get_global_binding_group_value(${binding.snippet})`; + } + const binding_group = get_binding_group(renderer, binding.node.expression.node); if (type === 'checkbox') { return x`@get_binding_group_value($$binding_groups[${binding_group}])`; diff --git a/src/compiler/interfaces.ts b/src/compiler/interfaces.ts index a5e286462ff3..9889e16151cf 100644 --- a/src/compiler/interfaces.ts +++ b/src/compiler/interfaces.ts @@ -161,6 +161,7 @@ export interface Var { hoistable?: boolean; subscribable?: boolean; is_reactive_dependency?: boolean; + imported?: boolean; } export interface CssResult { diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts index 02fd3dc23ecb..51efedb4c073 100644 --- a/src/runtime/internal/dom.ts +++ b/src/runtime/internal/dom.ts @@ -126,6 +126,38 @@ export function xlink_attr(node, attribute, value) { node.setAttributeNS('http://www.w3.org/1999/xlink', attribute, value); } +const global_binding_group = new WeakMap(); + +export function add_into_binding_group(array, input) { + if (!global_binding_group.has(array)) { + global_binding_group.set(array, []); + } + global_binding_group.get(array).push(input); +} + +export function remove_from_global_binding_group(array, input) { + const binding_group = global_binding_group.get(array); + if (binding_group) { + binding_group.splice(binding_group.indexOf(input), 1); + } +} + +export function reattach_global_binding_group(array, input) { + // if the array got reassigned, reattach binding group + if (!global_binding_group.has(array)) { + add_into_binding_group(array, input); + } +} + +export function get_global_binding_group_value(array) { + const group = global_binding_group.get(array); + const value = []; + for (let i = 0; i < group.length; i += 1) { + if (group[i].checked) value.push(group[i].__value); + } + return value; +} + export function get_binding_group_value(group) { const value = []; for (let i = 0; i < group.length; i += 1) { diff --git a/src/runtime/internal/index.ts b/src/runtime/internal/index.ts index e1dd2a1fcf36..aaf8ddc79330 100644 --- a/src/runtime/internal/index.ts +++ b/src/runtime/internal/index.ts @@ -12,4 +12,4 @@ export * from './ssr'; export * from './transitions'; export * from './utils'; export * from './Component'; -export * from './dev'; +export * from './dev'; \ No newline at end of file