simplify helpers

pull/673/head
Rich Harris 8 years ago
parent 9b4550d2e8
commit 078f3ad8b6

@ -1 +1,2 @@
--bail
test/test.js

@ -2,6 +2,7 @@ import CodeBuilder from '../../utils/CodeBuilder';
import deindent from '../../utils/deindent';
import { DomGenerator } from './index';
import { Node } from '../../interfaces';
import shared from './shared';
export interface BlockOptions {
name: string;
@ -140,7 +141,7 @@ export default class Block {
if (isToplevel) {
this.builders.unmount.addLine(
`${this.generator.helper('detachNode')}( ${name} );`
`@detachNode( ${name} );`
);
}
}
@ -187,12 +188,11 @@ export default class Block {
mount(name: string, parentNode: string) {
if (parentNode) {
this.builders.mount.addLine(
`${this.generator.helper('appendNode')}( ${name}, ${parentNode} );`
`@appendNode( ${name}, ${parentNode} );`
);
} else {
this.builders.mount.addLine(
`${this.generator.helper('insertNode')}( ${name}, ${this
.target}, anchor );`
`@insertNode( ${name}, ${this.target}, anchor );`
);
}
}
@ -233,7 +233,7 @@ export default class Block {
}
if (this.builders.create.isEmpty()) {
properties.addBlock(`create: ${this.generator.helper('noop')},`);
properties.addBlock(`create: @noop,`);
} else {
properties.addBlock(deindent`
create: function () {
@ -245,7 +245,7 @@ export default class Block {
if (this.generator.hydratable) {
if (this.builders.claim.isEmpty()) {
properties.addBlock(`claim: ${this.generator.helper('noop')},`);
properties.addBlock(`claim: @noop,`);
} else {
properties.addBlock(deindent`
claim: function ( nodes ) {
@ -265,7 +265,7 @@ export default class Block {
}
if (this.builders.mount.isEmpty()) {
properties.addBlock(`mount: ${this.generator.helper('noop')},`);
properties.addBlock(`mount: @noop,`);
} else {
properties.addBlock(deindent`
mount: function ( ${this.target}, anchor ) {
@ -276,7 +276,7 @@ export default class Block {
if (this.hasUpdateMethod) {
if (this.builders.update.isEmpty()) {
properties.addBlock(`update: ${this.generator.helper('noop')},`);
properties.addBlock(`update: @noop,`);
} else {
properties.addBlock(deindent`
update: function ( changed, ${this.params.join(', ')} ) {
@ -331,7 +331,7 @@ export default class Block {
}
if (this.builders.unmount.isEmpty()) {
properties.addBlock(`unmount: ${this.generator.helper('noop')},`);
properties.addBlock(`unmount: @noop,`);
} else {
properties.addBlock(deindent`
unmount: function () {
@ -341,7 +341,7 @@ export default class Block {
}
if (this.builders.destroy.isEmpty()) {
properties.addBlock(`destroy: ${this.generator.helper('noop')}`);
properties.addBlock(`destroy: @noop`);
} else {
properties.addBlock(deindent`
destroy: function () {

@ -12,6 +12,8 @@ import preprocess from './preprocess';
import Block from './Block';
import { Parsed, CompileOptions, Node } from '../../interfaces';
const helperPattern = new RegExp(`@(${Object.keys(shared).join('|')})\\b`, 'g');
export class DomGenerator extends Generator {
blocks: Block[];
uses: Set<string>;
@ -83,7 +85,6 @@ export default function dom(
if (computations.length) {
const builder = new CodeBuilder();
const differs = generator.helper('differs');
computations.forEach(({ key, deps }) => {
if (generator.readonly.has(key)) {
@ -98,7 +99,7 @@ export default function dom(
const condition = `isInitial || ${deps
.map(
dep =>
`( '${dep}' in newState && ${differs}( state.${dep}, oldState.${dep} ) )`
`( '${dep}' in newState && @differs( state.${dep}, oldState.${dep} ) )`
)
.join(' || ')}`;
const statement = `state.${key} = newState.${key} = ${generator.alias(
@ -131,18 +132,14 @@ export default function dom(
`}
var oldState = this._state;
this._state = ${generator.helper('assign')}( {}, oldState, newState );
this._state = @assign( {}, oldState, newState );
${computations.length &&
`${generator.alias(
'recompute'
)}( this._state, newState, oldState, false )`}
${generator.helper(
'dispatchObservers'
)}( this, this._observers.pre, newState, oldState );
@dispatchObservers( this, this._observers.pre, newState, oldState );
${block.hasUpdateMethod && `this._fragment.update( newState, this._state );`}
${generator.helper(
'dispatchObservers'
)}( this, this._observers.post, newState, oldState );
@dispatchObservers( this, this._observers.post, newState, oldState );
${generator.hasComplexBindings &&
`while ( this._bindings.length ) this._bindings.pop()();`}
${(generator.hasComponents || generator.hasIntroTransitions) &&
@ -158,10 +155,10 @@ export default function dom(
if (generator.css && options.css !== false) {
builders.main.addBlock(deindent`
function ${generator.alias('add_css')} () {
var style = ${generator.helper('createElement')}( 'style' );
var style = @createElement( 'style' );
style.id = ${JSON.stringify(generator.cssId + '-style')};
style.textContent = ${JSON.stringify(generator.css)};
${generator.helper('appendNode')}( style, document.head );
@appendNode( style, document.head );
}
`);
}
@ -180,7 +177,7 @@ export default function dom(
? `, ${generator.alias('template')}.methods`
: '');
const proto = sharedPath
? `${generator.helper('proto')} `
? `@proto `
: deindent`
{
${['get', 'fire', 'observe', 'on', 'set', '_flush']
@ -196,7 +193,7 @@ export default function dom(
`if ( !options.target && !options._root ) throw new Error( "'target' is a required option" );`}
${generator.usesRefs && `this.refs = {};`}
this._state = ${templateProperties.data
? `${generator.helper('assign')}( ${generator.alias(
? `@assign( ${generator.alias(
'template'
)}.data(), options.data )`
: `options.data || {}`};
@ -242,9 +239,9 @@ export default function dom(
if ( options.target ) {
${generator.hydratable ?
deindent`
var nodes = ${generator.helper('children')}( options.target );
var nodes = @children( options.target );
options.hydrate ? this._fragment.claim( nodes ) : this._fragment.create();
nodes.forEach( ${generator.helper('detachNode')} );
nodes.forEach( @detachNode );
` :
deindent`
this._fragment.create();
@ -269,7 +266,7 @@ export default function dom(
`}
}
${generator.helper('assign')}( ${prototypeBase}, ${proto});
@assign( ${prototypeBase}, ${proto});
${name}.prototype._set = function _set ( newState ) {
${builders._set}
@ -289,6 +286,9 @@ export default function dom(
};
`);
let result = builders.main.toString()
.replace(helperPattern, (match: string, name: string) => generator.helper(name));
if (sharedPath) {
if (format !== 'es') {
throw new Error(
@ -302,9 +302,7 @@ export default function dom(
: name;
});
builders.main.addLineAtStart(
`import { ${names.join(', ')} } from ${JSON.stringify(sharedPath)};`
);
result = `import { ${names.join(', ')} } from ${JSON.stringify(sharedPath)};\n\n` + result;
} else {
generator.uses.forEach(key => {
const str = shared[key];
@ -343,22 +341,20 @@ export default function dom(
// special case
const global = `_svelteTransitionManager`;
builders.main.addBlock(
`var ${generator.alias(
'transitionManager'
)} = window.${global} || ( window.${global} = ${code});`
);
result += `\n\nvar ${generator.alias(
'transitionManager'
)} = window.${global} || ( window.${global} = ${code});`;
} else {
const alias = generator.alias(expression.id.name);
if (alias !== expression.id.name)
code.overwrite(expression.id.start, expression.id.end, alias);
builders.main.addBlock(code.toString());
result += `\n\n${code}`;
}
});
}
return generator.generate(builders.main.toString(), options, {
return generator.generate(result, options, {
name,
format,
});

@ -73,9 +73,7 @@ export default function visitBinding(
${updating} = true;
${setter}
${updating} = false;
}, { init: ${generator.helper(
'differs'
)}( ${local.name}.get( '${attribute.name}' ), ${snippet} ) });
}, { init: @differs( ${local.name}.get( '${attribute.name}' ), ${snippet} ) });
});
`);

@ -48,8 +48,8 @@ export default function visitEachBlock(
if (node.needsAnchor) {
block.addElement(
anchor,
`${generator.helper('createComment')}()`,
`${generator.helper('createComment')}()`,
`@createComment()`,
`@createComment()`,
state.parentNode,
true
);
@ -162,8 +162,8 @@ function keyed(
node._block.first = node._block.getUniqueName('first');
node._block.addElement(
node._block.first,
`${generator.helper('createComment')}()`,
`${generator.helper('createComment')}()`,
`@createComment()`,
`@createComment()`,
null,
true
);
@ -479,6 +479,6 @@ function unkeyed(
`);
block.builders.destroy.addBlock(
`${generator.helper('destroyEach')}( ${iterations}, false, 0 );`
`@destroyEach( ${iterations}, false, 0 );`
);
}

@ -36,8 +36,8 @@ export default function visitAttribute(
// namespaced attributes but I'm not sure that's applicable in
// HTML5?
const method = name.slice(0, 6) === 'xlink:'
? 'setXlinkAttribute'
: 'setAttribute';
? '@setXlinkAttribute'
: '@setAttribute';
const isDynamic =
(attribute.value !== true && attribute.value.length > 1) ||
@ -112,13 +112,9 @@ export default function visitAttribute(
updater = `${state.parentNode}.${propertyName} = ${last};`;
} else {
block.builders.hydrate.addLine(
`${generator.helper(
method
)}( ${state.parentNode}, '${name}', ${last} = ${value} );`
`${method}( ${state.parentNode}, '${name}', ${last} = ${value} );`
);
updater = `${generator.helper(
method
)}( ${state.parentNode}, '${name}', ${last} );`;
updater = `${method}( ${state.parentNode}, '${name}', ${last} );`;
}
block.builders.update.addBlock(deindent`
@ -135,9 +131,7 @@ export default function visitAttribute(
const statement = propertyName
? `${state.parentNode}.${propertyName} = ${value};`
: `${generator.helper(
method
)}( ${state.parentNode}, '${name}', ${value} );`;
: `${method}( ${state.parentNode}, '${name}', ${value} );`;
block.builders.hydrate.addLine(statement);

@ -152,11 +152,9 @@ export default function visitBinding(
}
`);
block.builders.hydrate.addBlock(deindent`
${generator.helper(
'addListener'
)}( ${state.parentNode}, '${eventName}', ${handler} );
`);
block.builders.hydrate.addBlock(
`@addListener( ${state.parentNode}, '${eventName}', ${handler} );`
);
if (node.name !== 'audio' && node.name !== 'video')
node.initialUpdate = updateElement;
@ -170,22 +168,15 @@ export default function visitBinding(
`);
}
block.builders.destroy.addLine(deindent`
${generator.helper(
'removeListener'
)}( ${state.parentNode}, '${eventName}', ${handler} );
`);
block.builders.destroy.addLine(
`@removeListener( ${state.parentNode}, '${eventName}', ${handler} );`);
if (attribute.name === 'paused') {
block.builders.create.addLine(
`${generator.helper(
'addListener'
)}( ${state.parentNode}, 'play', ${handler} );`
`@addListener( ${state.parentNode}, 'play', ${handler} );`
);
block.builders.destroy.addLine(
`${generator.helper(
'removeListener'
)}( ${state.parentNode}, 'play', ${handler} );`
`@removeListener( ${state.parentNode}, 'play', ${handler} );`
);
}
}
@ -231,9 +222,7 @@ function getBindingValue(
// <input type='checkbox' bind:group='foo'>
if (attribute.name === 'group') {
if (type === 'checkbox') {
return `${generator.helper(
'getBindingGroupValue'
)}( ${block.component}._bindingGroups[${bindingGroup}] )`;
return `@getBindingGroupValue( ${block.component}._bindingGroups[${bindingGroup}] )`;
}
return `${state.parentNode}.__value`;
@ -241,9 +230,7 @@ function getBindingValue(
// <input type='range|number' bind:value>
if (type === 'range' || type === 'number') {
return `${generator.helper(
'toNumber'
)}( ${state.parentNode}.${attribute.name} )`;
return `@toNumber( ${state.parentNode}.${attribute.name} )`;
}
// everything else

@ -56,22 +56,20 @@ export default function visitElement(
if (generator.hydratable) {
block.builders.claim.addBlock(deindent`
${name} = ${getClaimStatement(generator, childState.namespace, state.parentNodes, node)};
var ${childState.parentNodes} = ${generator.helper('children')}( ${name} );
var ${childState.parentNodes} = @children( ${name} );
`);
}
if (state.parentNode) {
block.builders.mount.addLine(`${block.generator.helper('appendNode')}( ${name}, ${state.parentNode} );`);
block.builders.mount.addLine(`@appendNode( ${name}, ${state.parentNode} );`);
} else {
block.builders.mount.addLine(`${block.generator.helper('insertNode')}( ${name}, ${block.target}, anchor );`);
block.builders.mount.addLine(`@insertNode( ${name}, ${block.target}, anchor );`);
}
// add CSS encapsulation attribute
if (generator.cssId && (!generator.cascade || state.isTopLevel)) {
block.builders.hydrate.addLine(
`${generator.helper(
'setAttribute'
)}( ${name}, '${generator.cssId}', '' );`
`@setAttribute( ${name}, '${generator.cssId}', '' );`
);
}
@ -134,7 +132,7 @@ export default function visitElement(
// TODO we eventually need to consider what happens to elements
// that belong to the same outgroup as an outroing element...
block.builders.unmount.addLine(
`${generator.helper('detachNode')}( ${name} );`
`@detachNode( ${name} );`
);
}
@ -188,7 +186,7 @@ export default function visitElement(
}
block.builders.claim.addLine(
`${childState.parentNodes}.forEach( ${generator.helper('detachNode')} );`
`${childState.parentNodes}.forEach( @detachNode );`
);
}
@ -198,14 +196,14 @@ function getRenderStatement(
name: string
) {
if (namespace === 'http://www.w3.org/2000/svg') {
return `${generator.helper('createSvgElement')}( '${name}' )`;
return `@createSvgElement( '${name}' )`;
}
if (namespace) {
return `document.createElementNS( '${namespace}', '${name}' )`;
}
return `${generator.helper('createElement')}( '${name}' )`;
return `@createElement( '${name}' )`;
}
function getClaimStatement(
@ -221,7 +219,7 @@ function getClaimStatement(
const name = namespace ? node.name : node.name.toUpperCase();
return `${generator.helper('claimElement')}( ${nodes}, '${name}', ${attributes ? `{ ${attributes} }` : `{}`}, ${namespace === namespaces.svg ? true : false} )`;
return `@claimElement( ${nodes}, '${name}', ${attributes ? `{ ${attributes} }` : `{}`}, ${namespace === namespaces.svg ? true : false} )`;
}
function quoteProp(name: string) {

@ -99,16 +99,12 @@ export default function visitEventHandler(
block.builders.init.addBlock(handler);
}
block.builders.hydrate.addLine(deindent`
${generator.helper(
'addListener'
)}( ${state.parentNode}, '${name}', ${handlerName} );
`);
block.builders.hydrate.addLine(
`@addListener( ${state.parentNode}, '${name}', ${handlerName} );`
);
block.builders.destroy.addLine(deindent`
${generator.helper(
'removeListener'
)}( ${state.parentNode}, '${name}', ${handlerName} );
`);
block.builders.destroy.addLine(
`@removeListener( ${state.parentNode}, '${name}', ${handlerName} );`
);
}
}

@ -12,8 +12,6 @@ export default function addTransitions(
intro,
outro
) {
const wrapTransition = generator.helper('wrapTransition');
if (intro === outro) {
const name = block.getUniqueName(`${state.name}_transition`);
const snippet = intro.expression
@ -26,7 +24,7 @@ export default function addTransitions(
block.builders.intro.addBlock(deindent`
${block.component}._renderHooks.push( function () {
if ( !${name} ) ${name} = ${wrapTransition}( ${state.name}, ${fn}, ${snippet}, true, null );
if ( !${name} ) ${name} = @wrapTransition( ${state.name}, ${fn}, ${snippet}, true, null );
${name}.run( true, function () {
${block.component}.fire( 'intro.end', { node: ${state.name} });
});
@ -61,7 +59,7 @@ export default function addTransitions(
block.builders.intro.addBlock(deindent`
${block.component}._renderHooks.push( function () {
${introName} = ${wrapTransition}( ${state.name}, ${fn}, ${snippet}, true, null );
${introName} = @wrapTransition( ${state.name}, ${fn}, ${snippet}, true, null );
${introName}.run( true, function () {
${block.component}.fire( 'intro.end', { node: ${state.name} });
});
@ -80,7 +78,7 @@ export default function addTransitions(
// TODO hide elements that have outro'd (unless they belong to a still-outroing
// group) prior to their removal from the DOM
block.builders.outro.addBlock(deindent`
${outroName} = ${wrapTransition}( ${state.name}, ${fn}, ${snippet}, false, null );
${outroName} = @wrapTransition( ${state.name}, ${fn}, ${snippet}, false, null );
${outroName}.run( false, function () {
${block.component}.fire( 'outro.end', { node: ${state.name} });
if ( --${block.alias('outros')} === 0 ) ${block.alias('outrocallback')}();

@ -116,8 +116,8 @@ export default function visitIfBlock(
if (node.needsAnchor) {
block.addElement(
anchor,
`${generator.helper('createComment')}()`,
`${generator.helper('createComment')}()`,
`@createComment()`,
`@createComment()`,
state.parentNode,
true
);

@ -18,8 +18,8 @@ export default function visitMustacheTag(
block.addVariable(value);
block.addElement(
name,
`${generator.helper('createText')}( ${value} = ${snippet} )`,
generator.hydratable ? `${generator.helper('claimText')}( ${state.parentNodes}, ${value} = ${snippet} )` : '',
`@createText( ${value} = ${snippet} )`,
generator.hydratable ? `@claimText( ${state.parentNodes}, ${value} = ${snippet} )` : '',
state.parentNode,
true
);

@ -23,15 +23,15 @@ export default function visitRawMustacheTag(
// exists for `Element`s.
block.addElement(
before,
`${generator.helper('createElement')}( 'noscript' )`,
`${generator.helper('createElement')}( 'noscript' )`,
`@createElement( 'noscript' )`,
`@createElement( 'noscript' )`,
state.parentNode,
true
);
block.addElement(
after,
`${generator.helper('createElement')}( 'noscript' )`,
`${generator.helper('createElement')}( 'noscript' )`,
`@createElement( 'noscript' )`,
`@createElement( 'noscript' )`,
state.parentNode,
true
);
@ -39,9 +39,7 @@ export default function visitRawMustacheTag(
const isToplevel = !state.parentNode;
const mountStatement = `${before}.insertAdjacentHTML( 'afterend', ${value} = ${snippet} );`;
const detachStatement = `${generator.helper(
'detachBetween'
)}( ${before}, ${after} );`;
const detachStatement = `@detachBetween( ${before}, ${after} );`;
block.builders.mount.addLine(mountStatement);

@ -12,8 +12,8 @@ export default function visitText(
if (!node._state.shouldCreate) return;
block.addElement(
node._state.name,
`${generator.helper('createText')}( ${JSON.stringify(node.data)} )`,
generator.hydratable ? `${generator.helper('claimText')}( ${state.parentNodes}, ${JSON.stringify(node.data)} )` : '',
`@createText( ${JSON.stringify(node.data)} )`,
generator.hydratable ? `@claimText( ${state.parentNodes}, ${JSON.stringify(node.data)} )` : '',
state.parentNode,
node.usedAsAnchor
);

@ -1,4 +1,5 @@
import { assign, noop } from './utils.js';
import { createElement } from './dom.js';
export function linear(t) {
return t;
@ -45,7 +46,7 @@ export function wrapTransition(node, fn, params, intro, outgroup) {
// TODO share <style> tag between all transitions?
if (obj.css) {
var style = document.createElement('style');
var style = createElement('style');
}
if (intro) {

Loading…
Cancel
Save