From 0d67026904b91b75cd6fa090ff385076ed8822f3 Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 3 May 2017 21:19:48 -0400 Subject: [PATCH] more simplification --- src/generators/dom/index.js | 59 ++++++++----------- .../dom/visitors/Element/EventHandler.js | 18 ++---- .../dom/visitors/Element/meta/Window.js | 23 ++++---- src/utils/CodeBuilder.js | 9 +-- 4 files changed, 44 insertions(+), 65 deletions(-) diff --git a/src/generators/dom/index.js b/src/generators/dom/index.js index 478806b5eb..04c50b42e0 100644 --- a/src/generators/dom/index.js +++ b/src/generators/dom/index.js @@ -55,7 +55,6 @@ export default function dom ( parsed, source, options ) { const builders = { main: new CodeBuilder(), - init: new CodeBuilder(), _set: new CodeBuilder() }; @@ -84,22 +83,18 @@ export default function dom ( parsed, source, options ) { ` ); } - if ( options.dev ) { - builders._set.addBlock( deindent` + // TODO is the `if ( this._fragment )` condition necessary? + builders._set.addBlock( deindent` + ${options.dev && deindent` if ( typeof newState !== 'object' ) { throw new Error( 'Component .set was called without an object of data key-values to update.' ); } - ${ - Array.from( generator.readonly ).map( prop => - `if ( '${prop}' in newState && !this._updatingReadonlyProperty ) throw new Error( "Cannot set read-only property '${prop}'" );` - ) - } - `); - } + ${Array.from( generator.readonly ).map( prop => + `if ( '${prop}' in newState && !this._updatingReadonlyProperty ) throw new Error( "Cannot set read-only property '${prop}'" );` + )} + `} - // TODO is the `if ( this._fragment )` condition necessary? - builders._set.addBlock( deindent` var oldState = this._state; this._state = ${generator.helper( 'assign' )}( {}, oldState, newState ); ${computations.length && `${generator.alias( 'recompute' )}( this._state, newState, oldState, false )`} @@ -129,28 +124,6 @@ export default function dom ( parsed, source, options ) { builders.main.addBlock( block.render() ); }); - builders.init.addBlock( deindent` - this._torndown = false; - ${parsed.css && options.css !== false && `if ( !document.getElementById( ${JSON.stringify( generator.cssId + '-style' )} ) ) ${generator.alias( 'add_css' )}();`} - ${( generator.hasComponents || generator.hasIntroTransitions ) && `this._renderHooks = [];`} - ${generator.hasComplexBindings && `this._bindings = [];`} - - this._fragment = ${generator.alias( 'create_main_fragment' )}( this._state, this ); - if ( options.target ) this._fragment.mount( options.target, null ); - ${generator.hasComplexBindings && `while ( this._bindings.length ) this._bindings.pop()();`} - ${( generator.hasComponents || generator.hasIntroTransitions ) && `this._flush();`} - ` ); - - if ( templateProperties.oncreate ) { - builders.init.addBlock( deindent` - if ( options._root ) { - options._root._renderHooks.push( ${generator.alias( 'template' )}.oncreate.bind( this ) ); - } else { - ${generator.alias( 'template' )}.oncreate.call( this ); - } - ` ); - } - const sharedPath = options.shared === true ? 'svelte/shared.js' : options.shared; const prototypeBase = `${name}.prototype` + ( templateProperties.methods ? `, ${generator.alias( 'template' )}.methods` : '' ); @@ -185,7 +158,23 @@ export default function dom ( parsed, source, options ) { this._root = options._root || this; this._yield = options._yield; - ${builders.init} + this._torndown = false; + ${parsed.css && options.css !== false && `if ( !document.getElementById( ${JSON.stringify( generator.cssId + '-style' )} ) ) ${generator.alias( 'add_css' )}();`} + ${( generator.hasComponents || generator.hasIntroTransitions ) && `this._renderHooks = [];`} + ${generator.hasComplexBindings && `this._bindings = [];`} + + this._fragment = ${generator.alias( 'create_main_fragment' )}( this._state, this ); + if ( options.target ) this._fragment.mount( options.target, null ); + ${generator.hasComplexBindings && `while ( this._bindings.length ) this._bindings.pop()();`} + ${( generator.hasComponents || generator.hasIntroTransitions ) && `this._flush();`} + + ${templateProperties.oncreate && deindent` + if ( options._root ) { + options._root._renderHooks.push( ${generator.alias( 'template' )}.oncreate.bind( this ) ); + } else { + ${generator.alias( 'template' )}.oncreate.call( this ); + } + `} } ${generator.helper( 'assign' )}( ${prototypeBase}, ${proto}); diff --git a/src/generators/dom/visitors/Element/EventHandler.js b/src/generators/dom/visitors/Element/EventHandler.js index 5439bceee2..2979d5d2f9 100644 --- a/src/generators/dom/visitors/Element/EventHandler.js +++ b/src/generators/dom/visitors/Element/EventHandler.js @@ -1,5 +1,4 @@ import deindent from '../../../../utils/deindent.js'; -import CodeBuilder from '../../../../utils/CodeBuilder.js'; import flattenReference from '../../../../utils/flattenReference.js'; export default function visitEventHandler ( generator, block, state, node, attribute ) { @@ -49,18 +48,11 @@ export default function visitEventHandler ( generator, block, state, node, attri block.getUniqueName( `${name}_handler` ); // create the handler body - const handlerBody = new CodeBuilder(); - - if ( state.usesComponent ) { - // TODO the element needs to know to create `thing._svelte = { component: component }` - handlerBody.addLine( `var ${block.component} = this._svelte.component;` ); - } - - declarations.forEach( declaration => { - handlerBody.addLine( declaration ); - }); - - handlerBody.addLine( `[✂${attribute.expression.start}-${attribute.expression.end}✂];` ); + const handlerBody = deindent` + ${state.usesComponent && `var ${block.component} = this._svelte.component;`} + ${declarations} + [✂${attribute.expression.start}-${attribute.expression.end}✂]; + `; const handler = isCustomEvent ? deindent` diff --git a/src/generators/dom/visitors/Element/meta/Window.js b/src/generators/dom/visitors/Element/meta/Window.js index 01f1bbf4ca..4af5984811 100644 --- a/src/generators/dom/visitors/Element/meta/Window.js +++ b/src/generators/dom/visitors/Element/meta/Window.js @@ -1,6 +1,5 @@ import flattenReference from '../../../../../utils/flattenReference.js'; import deindent from '../../../../../utils/deindent.js'; -import CodeBuilder from '../../../../../utils/CodeBuilder.js'; const associatedEvents = { innerWidth: 'resize', @@ -43,8 +42,10 @@ export default function visitWindow ( generator, block, node ) { } const handlerName = block.getUniqueName( `onwindow${attribute.name}` ); - const handlerBody = ( usesState ? `var state = ${block.component}.get();\n` : '' ) + - `[✂${attribute.expression.start}-${attribute.expression.end}✂];`; + const handlerBody = deindent` + ${usesState && `var state = ${block.component}.get();`} + [✂${attribute.expression.start}-${attribute.expression.end}✂]; + `; block.builders.create.addBlock( deindent` function ${handlerName} ( event ) { @@ -96,25 +97,21 @@ export default function visitWindow ( generator, block, node ) { const handlerName = block.getUniqueName( `onwindow${event}` ); const props = events[ event ].join( ',\n' ); - const handlerBody = new CodeBuilder(); if ( event === 'scroll' ) { // TODO other bidirectional bindings... block.addVariable( lock, 'false' ); - handlerBody.addLine( `${lock} = true;` ); } - if ( generator.options.dev ) handlerBody.addLine( `component._updatingReadonlyProperty = true;` ); + const handlerBody = deindent` + ${event === 'scroll' && `${lock} = true;`} + ${generator.options.dev && `component._updatingReadonlyProperty = true;`} - handlerBody.addBlock( deindent` ${block.component}.set({ ${props} }); - ` ); - - if ( generator.options.dev ) handlerBody.addLine( `component._updatingReadonlyProperty = false;` ); - if ( event === 'scroll' ) { - handlerBody.addLine( `${lock} = false;` ); - } + ${generator.options.dev && `component._updatingReadonlyProperty = false;`} + ${event === 'scroll' && `${lock} = false;`} + `; block.builders.create.addBlock( deindent` function ${handlerName} ( event ) { diff --git a/src/utils/CodeBuilder.js b/src/utils/CodeBuilder.js index eb2e215c40..ff898776a0 100644 --- a/src/utils/CodeBuilder.js +++ b/src/utils/CodeBuilder.js @@ -2,11 +2,12 @@ const LINE = {}; const BLOCK = {}; export default class CodeBuilder { - constructor () { - this.result = ''; + constructor ( str = '' ) { + this.result = str; - this.first = null; - this.last = null; + const initial = str ? ( /\n/.test( str ) ? BLOCK : LINE ) : null; + this.first = initial; + this.last = initial; this.lastCondition = null; }