|
|
|
@ -3,7 +3,7 @@ import flattenReference from '../../../../utils/flattenReference.js';
|
|
|
|
|
import getSetter from './binding/getSetter.js';
|
|
|
|
|
import getStaticAttributeValue from './binding/getStaticAttributeValue.js';
|
|
|
|
|
|
|
|
|
|
export default function addElementBinding ( generator, node, attribute, block, local ) {
|
|
|
|
|
export default function addElementBinding ( generator, node, block, state, attribute, local ) {
|
|
|
|
|
const { name, keypath } = flattenReference( attribute.value );
|
|
|
|
|
const { snippet, contexts, dependencies } = generator.contextualise( block, attribute.value );
|
|
|
|
|
|
|
|
|
@ -13,12 +13,12 @@ export default function addElementBinding ( generator, node, attribute, block, l
|
|
|
|
|
if ( !~local.allUsedContexts.indexOf( context ) ) local.allUsedContexts.push( context );
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const handler = block.getUniqueName( `${local.name}_change_handler` );
|
|
|
|
|
const handler = block.getUniqueName( `${state.parentNode}_change_handler` );
|
|
|
|
|
|
|
|
|
|
const isMultipleSelect = node.name === 'select' && node.attributes.find( attr => attr.name.toLowerCase() === 'multiple' ); // TODO use getStaticAttributeValue
|
|
|
|
|
const type = getStaticAttributeValue( node, 'type' );
|
|
|
|
|
const bindingGroup = attribute.name === 'group' ? getBindingGroup( generator, keypath ) : null;
|
|
|
|
|
const value = getBindingValue( generator, block, local, node, attribute, isMultipleSelect, bindingGroup, type );
|
|
|
|
|
const value = getBindingValue( generator, block, state, local, node, attribute, isMultipleSelect, bindingGroup, type );
|
|
|
|
|
const eventName = getBindingEventName( node );
|
|
|
|
|
|
|
|
|
|
let setter = getSetter({ block, name, keypath, context: '__svelte', attribute, dependencies, value });
|
|
|
|
@ -27,7 +27,7 @@ export default function addElementBinding ( generator, node, attribute, block, l
|
|
|
|
|
// <select> special case
|
|
|
|
|
if ( node.name === 'select' ) {
|
|
|
|
|
if ( !isMultipleSelect ) {
|
|
|
|
|
setter = `var selectedOption = ${local.name}.selectedOptions[0] || ${local.name}.options[0];\n${setter}`;
|
|
|
|
|
setter = `var selectedOption = ${state.parentNode}.selectedOptions[0] || ${state.parentNode}.options[0];\n${setter}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const value = block.getUniqueName( 'value' );
|
|
|
|
@ -45,8 +45,8 @@ export default function addElementBinding ( generator, node, attribute, block, l
|
|
|
|
|
|
|
|
|
|
updateElement = deindent`
|
|
|
|
|
var ${value} = ${snippet};
|
|
|
|
|
for ( var ${i} = 0; ${i} < ${local.name}.options.length; ${i} += 1 ) {
|
|
|
|
|
var ${option} = ${local.name}.options[${i}];
|
|
|
|
|
for ( var ${i} = 0; ${i} < ${state.parentNode}.options.length; ${i} += 1 ) {
|
|
|
|
|
var ${option} = ${state.parentNode}.options[${i}];
|
|
|
|
|
|
|
|
|
|
${ifStatement}
|
|
|
|
|
}
|
|
|
|
@ -57,32 +57,32 @@ export default function addElementBinding ( generator, node, attribute, block, l
|
|
|
|
|
else if ( attribute.name === 'group' ) {
|
|
|
|
|
if ( type === 'radio' ) {
|
|
|
|
|
setter = deindent`
|
|
|
|
|
if ( !${local.name}.checked ) return;
|
|
|
|
|
if ( !${state.parentNode}.checked ) return;
|
|
|
|
|
${setter}
|
|
|
|
|
`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const condition = type === 'checkbox' ?
|
|
|
|
|
`~${snippet}.indexOf( ${local.name}.__value )` :
|
|
|
|
|
`${local.name}.__value === ${snippet}`;
|
|
|
|
|
`~${snippet}.indexOf( ${state.parentNode}.__value )` :
|
|
|
|
|
`${state.parentNode}.__value === ${snippet}`;
|
|
|
|
|
|
|
|
|
|
local.create.addLine(
|
|
|
|
|
`${block.component}._bindingGroups[${bindingGroup}].push( ${local.name} );`
|
|
|
|
|
`${block.component}._bindingGroups[${bindingGroup}].push( ${state.parentNode} );`
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
local.destroy.addBlock(
|
|
|
|
|
`${block.component}._bindingGroups[${bindingGroup}].splice( ${block.component}._bindingGroups[${bindingGroup}].indexOf( ${local.name} ), 1 );`
|
|
|
|
|
`${block.component}._bindingGroups[${bindingGroup}].splice( ${block.component}._bindingGroups[${bindingGroup}].indexOf( ${state.parentNode} ), 1 );`
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
updateElement = `${local.name}.checked = ${condition};`;
|
|
|
|
|
updateElement = `${state.parentNode}.checked = ${condition};`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// everything else
|
|
|
|
|
else {
|
|
|
|
|
updateElement = `${local.name}.${attribute.name} = ${snippet};`;
|
|
|
|
|
updateElement = `${state.parentNode}.${attribute.name} = ${snippet};`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const updating = block.getUniqueName( `${local.name}_updating` );
|
|
|
|
|
const updating = block.getUniqueName( `${state.parentNode}_updating` );
|
|
|
|
|
|
|
|
|
|
local.create.addBlock( deindent`
|
|
|
|
|
var ${updating} = false;
|
|
|
|
@ -93,7 +93,7 @@ export default function addElementBinding ( generator, node, attribute, block, l
|
|
|
|
|
${updating} = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
${generator.helper( 'addEventListener' )}( ${local.name}, '${eventName}', ${handler} );
|
|
|
|
|
${generator.helper( 'addEventListener' )}( ${state.parentNode}, '${eventName}', ${handler} );
|
|
|
|
|
` );
|
|
|
|
|
|
|
|
|
|
node.initialUpdate = updateElement;
|
|
|
|
@ -105,7 +105,7 @@ export default function addElementBinding ( generator, node, attribute, block, l
|
|
|
|
|
` );
|
|
|
|
|
|
|
|
|
|
block.builders.destroy.addLine( deindent`
|
|
|
|
|
${generator.helper( 'removeEventListener' )}( ${local.name}, '${eventName}', ${handler} );
|
|
|
|
|
${generator.helper( 'removeEventListener' )}( ${state.parentNode}, '${eventName}', ${handler} );
|
|
|
|
|
` );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -124,10 +124,10 @@ function getBindingEventName ( node ) {
|
|
|
|
|
return 'change';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getBindingValue ( generator, block, local, node, attribute, isMultipleSelect, bindingGroup, type ) {
|
|
|
|
|
function getBindingValue ( generator, block, state, local, node, attribute, isMultipleSelect, bindingGroup, type ) {
|
|
|
|
|
// <select multiple bind:value='selected>
|
|
|
|
|
if ( isMultipleSelect ) {
|
|
|
|
|
return `[].map.call( ${local.name}.selectedOptions, function ( option ) { return option.__value; })`;
|
|
|
|
|
return `[].map.call( ${state.parentNode}.selectedOptions, function ( option ) { return option.__value; })`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <select bind:value='selected>
|
|
|
|
@ -141,16 +141,16 @@ function getBindingValue ( generator, block, local, node, attribute, isMultipleS
|
|
|
|
|
return `${generator.helper( 'getBindingGroupValue' )}( ${block.component}._bindingGroups[${bindingGroup}] )`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return `${local.name}.__value`;
|
|
|
|
|
return `${state.parentNode}.__value`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <input type='range|number' bind:value>
|
|
|
|
|
if ( type === 'range' || type === 'number' ) {
|
|
|
|
|
return `+${local.name}.${attribute.name}`;
|
|
|
|
|
return `+${state.parentNode}.${attribute.name}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// everything else
|
|
|
|
|
return `${local.name}.${attribute.name}`;
|
|
|
|
|
return `${state.parentNode}.${attribute.name}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getBindingGroup ( generator, keypath ) {
|
|
|
|
|