mirror of https://github.com/sveltejs/svelte
parent
e960e8b5c5
commit
4a782bc8f6
@ -0,0 +1,62 @@
|
|||||||
|
import deindent from '../../../../utils/deindent.js';
|
||||||
|
import flattenReference from '../../../../utils/flattenReference.js';
|
||||||
|
|
||||||
|
export default function visitEventHandler ( generator, block, state, node, attribute ) {
|
||||||
|
const name = attribute.name;
|
||||||
|
|
||||||
|
// TODO verify that it's a valid callee (i.e. built-in or declared method)
|
||||||
|
generator.addSourcemapLocations( attribute.expression );
|
||||||
|
|
||||||
|
const flattened = flattenReference( attribute.expression.callee );
|
||||||
|
if ( flattened.name !== 'event' && flattened.name !== 'this' ) {
|
||||||
|
// allow event.stopPropagation(), this.select() etc
|
||||||
|
generator.code.prependRight( attribute.expression.start, `${block.component}.` );
|
||||||
|
}
|
||||||
|
|
||||||
|
const usedContexts = [];
|
||||||
|
attribute.expression.arguments.forEach( arg => {
|
||||||
|
const { contexts } = generator.contextualise( block, arg, true );
|
||||||
|
|
||||||
|
contexts.forEach( context => {
|
||||||
|
if ( !~usedContexts.indexOf( context ) ) usedContexts.push( context );
|
||||||
|
if ( !~state.allUsedContexts.indexOf( context ) ) state.allUsedContexts.push( context );
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO hoist event handlers? can do `this.__component.method(...)`
|
||||||
|
const declarations = usedContexts.map( name => {
|
||||||
|
if ( name === 'root' ) return 'var root = this.__svelte.root;';
|
||||||
|
|
||||||
|
const listName = block.listNames.get( name );
|
||||||
|
const indexName = block.indexNames.get( name );
|
||||||
|
|
||||||
|
return `var ${listName} = this.__svelte.${listName}, ${indexName} = this.__svelte.${indexName}, ${name} = ${listName}[${indexName}]`;
|
||||||
|
});
|
||||||
|
|
||||||
|
const handlerName = block.getUniqueName( `${name}_handler` );
|
||||||
|
const handlerBody = ( declarations.length ? declarations.join( '\n' ) + '\n\n' : '' ) + `[✂${attribute.expression.start}-${attribute.expression.end}✂];`;
|
||||||
|
|
||||||
|
if ( generator.events.has( name ) ) {
|
||||||
|
block.builders.create.addBlock( deindent`
|
||||||
|
var ${handlerName} = ${generator.alias( 'template' )}.events.${name}.call( ${block.component}, ${state.parentNode}, function ( event ) {
|
||||||
|
${handlerBody}
|
||||||
|
}.bind( ${state.parentNode} ) );
|
||||||
|
` );
|
||||||
|
|
||||||
|
block.builders.destroy.addLine( deindent`
|
||||||
|
${handlerName}.teardown();
|
||||||
|
` );
|
||||||
|
} else {
|
||||||
|
block.builders.create.addBlock( deindent`
|
||||||
|
function ${handlerName} ( event ) {
|
||||||
|
${handlerBody}
|
||||||
|
}
|
||||||
|
|
||||||
|
${generator.helper( 'addEventListener' )}( ${state.parentNode}, '${name}', ${handlerName} );
|
||||||
|
` );
|
||||||
|
|
||||||
|
block.builders.destroy.addLine( deindent`
|
||||||
|
${generator.helper( 'removeEventListener' )}( ${state.parentNode}, '${name}', ${handlerName} );
|
||||||
|
` );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
import deindent from '../../../../utils/deindent.js';
|
||||||
|
|
||||||
|
export default function visitRef ( generator, block, state, node, attribute ) {
|
||||||
|
const name = attribute.name;
|
||||||
|
|
||||||
|
block.builders.create.addLine(
|
||||||
|
`${block.component}.refs.${name} = ${state.parentNode};`
|
||||||
|
);
|
||||||
|
|
||||||
|
block.builders.destroy.addLine( deindent`
|
||||||
|
if ( ${block.component}.refs.${name} === ${state.parentNode} ) ${block.component}.refs.${name} = null;
|
||||||
|
` );
|
||||||
|
|
||||||
|
generator.usesRefs = true; // so this component.refs object is created
|
||||||
|
}
|
Loading…
Reference in new issue