Merge pull request #512 from sveltejs/gh-3

Anchor-less if and each blocks
pull/526/head
Rich Harris 8 years ago committed by GitHub
commit b42ef4952e

@ -87,11 +87,6 @@ export default class Block {
return this.generator.contextualise( this, expression, context, isEventHandler );
}
createAnchor ( name, parentNode ) {
const renderStatement = `${this.generator.helper( 'createComment' )}()`;
this.addElement( name, renderStatement, parentNode, true );
}
findDependencies ( expression ) {
return this.generator.findDependencies( this.contextDependencies, this.indexes, expression );
}

@ -43,14 +43,14 @@ export default function dom ( parsed, source, options ) {
const { computations, hasJs, templateProperties, namespace } = generator.parseJs();
const block = preprocess( generator, parsed.html );
const state = {
namespace,
parentNode: null,
isTopLevel: true
};
const block = preprocess( generator, state, parsed.html );
parsed.html.children.forEach( node => {
visit( generator, block, state, node );
});

@ -1,17 +1,62 @@
import Block from './Block.js';
import { trimStart, trimEnd } from '../../utils/trim.js';
import { assign } from '../../shared/index.js';
function isElseIf ( node ) {
return node && node.children.length === 1 && node.children[0].type === 'IfBlock';
}
function getChildState ( parent, child ) {
return assign( {}, parent, { name: null, parentNode: null }, child || {} );
}
// Whitespace inside one of these elements will not result in
// a whitespace node being created in any circumstances. (This
// list is almost certainly very incomplete)
const elementsWithoutText = new Set([
'audio',
'datalist',
'dl',
'ol',
'optgroup',
'select',
'ul',
'video'
]);
const preprocessors = {
MustacheTag: ( generator, block, node ) => {
MustacheTag: ( generator, block, state, node ) => {
const dependencies = block.findDependencies( node.expression );
block.addDependencies( dependencies );
node._state = getChildState( state, {
name: block.getUniqueName( 'text' )
});
},
RawMustacheTag: ( generator, block, state, node ) => {
const dependencies = block.findDependencies( node.expression );
block.addDependencies( dependencies );
const basename = block.getUniqueName( 'raw' );
const name = block.getUniqueName( `${basename}_before` );
node._state = getChildState( state, { basename, name });
},
Text: ( generator, block, state, node ) => {
node._state = getChildState( state );
if ( !/\S/.test( node.data ) ) {
if ( state.namespace ) return;
if ( elementsWithoutText.has( state.parentNodeName ) ) return;
}
node._state.shouldCreate = true;
node._state.name = block.getUniqueName( `text` );
},
IfBlock: ( generator, block, node ) => {
IfBlock: ( generator, block, state, node ) => {
const blocks = [];
let dynamic = false;
@ -23,8 +68,10 @@ const preprocessors = {
name: generator.getUniqueName( `create_if_block` )
});
node._state = getChildState( state );
blocks.push( node._block );
preprocessChildren( generator, node._block, node );
preprocessChildren( generator, node._block, node._state, node );
if ( node._block.dependencies.size > 0 ) {
dynamic = true;
@ -38,8 +85,10 @@ const preprocessors = {
name: generator.getUniqueName( `create_if_block` )
});
node.else._state = getChildState( state );
blocks.push( node.else._block );
preprocessChildren( generator, node.else._block, node.else );
preprocessChildren( generator, node.else._block, node.else._state, node.else );
if ( node.else._block.dependencies.size > 0 ) {
dynamic = true;
@ -57,7 +106,7 @@ const preprocessors = {
generator.blocks.push( ...blocks );
},
EachBlock: ( generator, block, node ) => {
EachBlock: ( generator, block, state, node ) => {
const dependencies = block.findDependencies( node.expression );
block.addDependencies( dependencies );
@ -97,8 +146,12 @@ const preprocessors = {
params: block.params.concat( listName, context, indexName )
});
node._state = getChildState( state, {
inEachBlock: true
});
generator.blocks.push( node._block );
preprocessChildren( generator, node._block, node );
preprocessChildren( generator, node._block, node._state, node );
block.addDependencies( node._block.dependencies );
node._block.hasUpdateMethod = node._block.dependencies.size > 0;
@ -107,13 +160,32 @@ const preprocessors = {
name: generator.getUniqueName( `${node._block.name}_else` )
});
node.else._state = getChildState( state );
generator.blocks.push( node.else._block );
preprocessChildren( generator, node.else._block, node.else );
preprocessChildren( generator, node.else._block, node.else._state, node.else );
node.else._block.hasUpdateMethod = node.else._block.dependencies.size > 0;
}
},
Element: ( generator, block, node ) => {
Element: ( generator, block, state, node ) => {
const isComponent = generator.components.has( node.name ) || node.name === ':Self';
if ( isComponent ) {
node._state = getChildState( state );
} else {
const name = block.getUniqueName( node.name.replace( /[^a-zA-Z0-9_$]/g, '_' ) );
node._state = getChildState( state, {
isTopLevel: false,
name,
parentNode: name,
parentNodeName: node.name,
namespace: node.name === 'svg' ? 'http://www.w3.org/2000/svg' : state.namespace,
allUsedContexts: []
});
}
node.attributes.forEach( attribute => {
if ( attribute.type === 'Attribute' && attribute.value !== true ) {
attribute.value.forEach( chunk => {
@ -130,8 +202,6 @@ const preprocessors = {
}
});
const isComponent = generator.components.has( node.name ) || node.name === ':Self';
if ( node.children.length ) {
if ( isComponent ) {
const name = block.getUniqueName( ( node.name === ':Self' ? generator.name : node.name ).toLowerCase() );
@ -141,21 +211,19 @@ const preprocessors = {
});
generator.blocks.push( node._block );
preprocessChildren( generator, node._block, node );
preprocessChildren( generator, node._block, node._state, node );
block.addDependencies( node._block.dependencies );
node._block.hasUpdateMethod = node._block.dependencies.size > 0;
}
else {
preprocessChildren( generator, block, node );
preprocessChildren( generator, block, node._state, node );
}
}
}
};
preprocessors.RawMustacheTag = preprocessors.MustacheTag;
function preprocessChildren ( generator, block, node ) {
function preprocessChildren ( generator, block, state, node, isTopLevel ) {
// glue text nodes together
const cleaned = [];
let lastChild;
@ -173,15 +241,43 @@ function preprocessChildren ( generator, block, node ) {
lastChild = child;
});
node.children = cleaned;
if ( isTopLevel ) {
// trim leading and trailing whitespace from the top level
const firstChild = cleaned[0];
if ( firstChild && firstChild.type === 'Text' ) {
firstChild.data = trimStart( firstChild.data );
if ( !firstChild.data ) cleaned.shift();
}
const lastChild = cleaned[ cleaned.length - 1 ];
if ( lastChild && lastChild.type === 'Text' ) {
lastChild.data = trimEnd( lastChild.data );
if ( !lastChild.data ) cleaned.pop();
}
}
lastChild = null;
cleaned.forEach( child => {
const preprocess = preprocessors[ child.type ];
if ( preprocess ) preprocess( generator, block, child );
if ( preprocess ) preprocess( generator, block, state, child );
if ( lastChild ) {
lastChild.next = child;
lastChild.needsAnchor = !child._state.name;
}
lastChild = child;
});
if ( lastChild ) {
lastChild.needsAnchor = !state.parentNode;
}
node.children = cleaned;
}
export default function preprocess ( generator, node ) {
export default function preprocess ( generator, state, node ) {
const block = new Block({
generator,
name: generator.alias( 'create_main_fragment' ),
@ -199,21 +295,8 @@ export default function preprocess ( generator, node ) {
});
generator.blocks.push( block );
preprocessChildren( generator, block, node );
preprocessChildren( generator, block, state, node, true );
block.hasUpdateMethod = block.dependencies.size > 0;
// trim leading and trailing whitespace from the top level
const firstChild = node.children[0];
if ( firstChild && firstChild.type === 'Text' ) {
firstChild.data = trimStart( firstChild.data );
if ( !firstChild.data ) node.children.shift();
}
const lastChild = node.children[ node.children.length - 1 ];
if ( lastChild && lastChild.type === 'Text' ) {
lastChild.data = trimEnd( lastChild.data );
if ( !lastChild.data ) node.children.pop();
}
return block;
}

@ -36,9 +36,7 @@ export default function visitComponent ( generator, block, state, node ) {
const hasChildren = node.children.length > 0;
const name = block.getUniqueName( ( node.name === ':Self' ? generator.name : node.name ).toLowerCase() );
const childState = Object.assign( {}, state, {
parentNode: null
});
const childState = node._state;
const local = {
name,

@ -9,13 +9,12 @@ export default function visitEachBlock ( generator, block, state, node ) {
const iterations = block.getUniqueName( `${each_block}_iterations` );
const i = block.alias( `i` );
const params = block.params.join( ', ' );
const anchor = block.getUniqueName( `${each_block}_anchor` );
const anchor = node.needsAnchor ? block.getUniqueName( `${each_block}_anchor` ) : ( node.next && node.next._state.name ) || 'null';
const vars = { each_block, create_each_block, each_block_value, iterations, i, params, anchor };
const { snippet } = block.contextualise( node.expression );
block.createAnchor( anchor, state.parentNode );
block.builders.create.addLine( `var ${each_block_value} = ${snippet};` );
block.builders.create.addLine( `var ${iterations} = [];` );
@ -30,11 +29,17 @@ export default function visitEachBlock ( generator, block, state, node ) {
if ( isToplevel ) {
block.builders.mount.addBlock( deindent`
for ( var ${i} = 0; ${i} < ${iterations}.length; ${i} += 1 ) {
${iterations}[${i}].mount( ${block.target}, ${anchor} );
${iterations}[${i}].mount( ${block.target}, null );
}
` );
}
if ( node.needsAnchor ) {
block.addElement( anchor, `${generator.helper( 'createComment' )}()`, state.parentNode, true );
} else if ( node.next ) {
node.next.usedAsAnchor = true;
}
block.builders.destroy.addBlock(
`${generator.helper( 'destroyEach' )}( ${iterations}, ${isToplevel ? 'detach' : 'false'}, 0 );` );
@ -47,23 +52,25 @@ export default function visitEachBlock ( generator, block, state, node ) {
block.builders.create.addBlock( deindent`
if ( !${each_block_value}.length ) {
${each_block_else} = ${node.else._block.name}( ${params}, ${block.component} );
${!isToplevel ? `${each_block_else}.mount( ${state.parentNode}, ${anchor} );` : ''}
${!isToplevel ? `${each_block_else}.mount( ${state.parentNode}, null );` : ''}
}
` );
block.builders.mount.addBlock( deindent`
if ( ${each_block_else} ) {
${each_block_else}.mount( ${state.parentNode || block.target}, ${anchor} );
${each_block_else}.mount( ${state.parentNode || block.target}, null );
}
` );
const parentNode = state.parentNode || `${anchor}.parentNode`;
if ( node.else._block.hasUpdateMethod ) {
block.builders.update.addBlock( deindent`
if ( !${each_block_value}.length && ${each_block_else} ) {
${each_block_else}.update( changed, ${params} );
} else if ( !${each_block_value}.length ) {
${each_block_else} = ${node.else._block.name}( ${params}, ${block.component} );
${each_block_else}.mount( ${anchor}.parentNode, ${anchor} );
${each_block_else}.mount( ${parentNode}, ${anchor} );
} else if ( ${each_block_else} ) {
${each_block_else}.destroy( true );
${each_block_else} = null;
@ -78,7 +85,7 @@ export default function visitEachBlock ( generator, block, state, node ) {
}
} else if ( !${each_block_else} ) {
${each_block_else} = ${node.else._block.name}( ${params}, ${block.component} );
${each_block_else}.mount( ${anchor}.parentNode, ${anchor} );
${each_block_else}.mount( ${parentNode}, ${anchor} );
}
` );
}
@ -91,22 +98,13 @@ export default function visitEachBlock ( generator, block, state, node ) {
` );
}
const childState = Object.assign( {}, state, {
parentNode: null,
inEachBlock: true
});
node.children.forEach( child => {
visit( generator, node._block, childState, child );
visit( generator, node._block, node._state, child );
});
if ( node.else ) {
const childState = Object.assign( {}, state, {
parentNode: null
});
node.else.children.forEach( child => {
visit( generator, node.else._block, childState, child );
visit( generator, node.else._block, node.else._state, child );
});
}
}
@ -131,7 +129,7 @@ function keyed ( generator, block, state, node, snippet, { each_block, create_ea
if ( state.parentNode ) {
create.addLine(
`${iterations}[${i}].mount( ${state.parentNode}, ${anchor} );`
`${iterations}[${i}].mount( ${state.parentNode}, null );`
);
}
@ -148,6 +146,8 @@ function keyed ( generator, block, state, node, snippet, { each_block, create_ea
` :
`${_iterations}[${i}] = ${_lookup}[ ${key} ] = ${lookup}[ ${key} ];`;
const parentNode = state.parentNode || `${anchor}.parentNode`;
block.builders.update.addBlock( deindent`
var ${each_block_value} = ${snippet};
var ${_iterations} = [];
@ -177,7 +177,7 @@ function keyed ( generator, block, state, node, snippet, { each_block, create_ea
}
}
${anchor}.parentNode.insertBefore( ${fragment}, ${anchor} );
${parentNode}.insertBefore( ${fragment}, ${anchor} );
${iterations} = ${_iterations};
${lookup} = ${_lookup};
@ -193,7 +193,7 @@ function unkeyed ( generator, block, state, node, snippet, { create_each_block,
if ( state.parentNode ) {
create.addLine(
`${iterations}[${i}].mount( ${state.parentNode}, ${anchor} );`
`${iterations}[${i}].mount( ${state.parentNode}, null );`
);
}
@ -213,6 +213,8 @@ function unkeyed ( generator, block, state, node, snippet, { create_each_block,
.map( dependency => `'${dependency}' in changed` )
.join( ' || ' );
const parentNode = state.parentNode || `${anchor}.parentNode`;
if ( condition !== '' ) {
const forLoopBody = node._block.hasUpdateMethod ?
deindent`
@ -220,12 +222,12 @@ function unkeyed ( generator, block, state, node, snippet, { create_each_block,
${iterations}[${i}].update( changed, ${params}, ${each_block_value}, ${each_block_value}[${i}], ${i} );
} else {
${iterations}[${i}] = ${create_each_block}( ${params}, ${each_block_value}, ${each_block_value}[${i}], ${i}, ${block.component} );
${iterations}[${i}].mount( ${anchor}.parentNode, ${anchor} );
${iterations}[${i}].mount( ${parentNode}, ${anchor} );
}
` :
deindent`
${iterations}[${i}] = ${create_each_block}( ${params}, ${each_block_value}, ${each_block_value}[${i}], ${i}, ${block.component} );
${iterations}[${i}].mount( ${anchor}.parentNode, ${anchor} );
${iterations}[${i}].mount( ${parentNode}, ${anchor} );
`;
const start = node._block.hasUpdateMethod ? '0' : `${iterations}.length`;

@ -34,15 +34,8 @@ export default function visitElement ( generator, block, state, node ) {
return visitComponent( generator, block, state, node );
}
const name = block.getUniqueName( node.name.replace( /[^a-zA-Z_$]/g, '_' ) );
const childState = Object.assign( {}, state, {
isTopLevel: false,
parentNode: name,
parentNodeName: node.name,
namespace: node.name === 'svg' ? 'http://www.w3.org/2000/svg' : state.namespace,
allUsedContexts: []
});
const childState = node._state;
const name = childState.parentNode;
block.builders.create.addLine( `var ${name} = ${getRenderStatement( generator, childState.namespace, node.name )};` );
block.mount( name, state.parentNode );

@ -34,23 +34,23 @@ function getBranches ( generator, block, state, node ) {
}
function visitChildren ( generator, block, state, node ) {
const childState = Object.assign( {}, state, {
parentNode: null
});
node.children.forEach( child => {
visit( generator, node._block, childState, child );
visit( generator, node._block, node._state, child );
});
}
export default function visitIfBlock ( generator, block, state, node ) {
const name = generator.getUniqueName( `if_block` );
const anchor = generator.getUniqueName( `${name}_anchor` );
const anchor = node.needsAnchor ? block.getUniqueName( `${name}_anchor` ) : ( node.next && node.next._state.name ) || 'null';
const params = block.params.join( ', ' );
const vars = { name, anchor, params };
block.createAnchor( anchor, state.parentNode );
if ( node.needsAnchor ) {
block.addElement( anchor, `${generator.helper( 'createComment' )}()`, state.parentNode, true );
} else if ( node.next ) {
node.next.usedAsAnchor = true;
}
const branches = getBranches( generator, block, state, node, generator.getUniqueName( `create_if_block` ) );
const dynamic = branches.some( branch => branch.dynamic );
@ -74,11 +74,13 @@ function simple ( generator, block, state, node, branch, dynamic, { name, anchor
const isToplevel = !state.parentNode;
if ( isToplevel ) {
block.builders.mount.addLine( `if ( ${name} ) ${name}.mount( ${block.target}, ${anchor} );` );
block.builders.mount.addLine( `if ( ${name} ) ${name}.mount( ${block.target}, null );` );
} else {
block.builders.create.addLine( `if ( ${name} ) ${name}.mount( ${state.parentNode}, ${anchor} );` );
block.builders.create.addLine( `if ( ${name} ) ${name}.mount( ${state.parentNode}, null );` );
}
const parentNode = state.parentNode || `${anchor}.parentNode`;
if ( dynamic ) {
block.builders.update.addBlock( deindent`
if ( ${branch.condition} ) {
@ -86,7 +88,7 @@ function simple ( generator, block, state, node, branch, dynamic, { name, anchor
${name}.update( changed, ${params} );
} else {
${name} = ${branch.block}( ${params}, ${block.component} );
${name}.mount( ${anchor}.parentNode, ${anchor} );
${name}.mount( ${parentNode}, ${anchor} );
}
} else if ( ${name} ) {
${name}.destroy( true );
@ -98,7 +100,7 @@ function simple ( generator, block, state, node, branch, dynamic, { name, anchor
if ( ${branch.condition} ) {
if ( !${name} ) {
${name} = ${branch.block}( ${params}, ${block.component} );
${name}.mount( ${anchor}.parentNode, ${anchor} );
${name}.mount( ${parentNode}, ${anchor} );
}
} else if ( ${name} ) {
${name}.destroy( true );
@ -126,11 +128,13 @@ function compound ( generator, block, state, node, branches, dynamic, { name, an
const isToplevel = !state.parentNode;
if ( isToplevel ) {
block.builders.mount.addLine( `if ( ${name} ) ${name}.mount( ${block.target}, ${anchor} );` );
block.builders.mount.addLine( `if ( ${name} ) ${name}.mount( ${block.target}, null );` );
} else {
block.builders.create.addLine( `if ( ${name} ) ${name}.mount( ${state.parentNode}, ${anchor} );` );
block.builders.create.addLine( `if ( ${name} ) ${name}.mount( ${state.parentNode}, null );` );
}
const parentNode = state.parentNode || `${anchor}.parentNode`;
if ( dynamic ) {
block.builders.update.addBlock( deindent`
if ( ${current_block} === ( ${current_block} = ${getBlock}( ${params} ) ) && ${name} ) {
@ -138,7 +142,7 @@ function compound ( generator, block, state, node, branches, dynamic, { name, an
} else {
if ( ${name} ) ${name}.destroy( true );
${name} = ${current_block} && ${current_block}( ${params}, ${block.component} );
if ( ${name} ) ${name}.mount( ${anchor}.parentNode, ${anchor} );
if ( ${name} ) ${name}.mount( ${parentNode}, ${anchor} );
}
` );
} else {
@ -146,7 +150,7 @@ function compound ( generator, block, state, node, branches, dynamic, { name, an
if ( ${current_block} !== ( ${current_block} = ${getBlock}( ${params} ) ) ) {
if ( ${name} ) ${name}.destroy( true );
${name} = ${current_block} && ${current_block}( ${params}, ${block.component} );
if ( ${name} ) ${name}.mount( ${anchor}.parentNode, ${anchor} );
if ( ${name} ) ${name}.mount( ${parentNode}, ${anchor} );
}
` );
}

@ -1,7 +1,7 @@
import deindent from '../../../utils/deindent.js';
export default function visitMustacheTag ( generator, block, state, node ) {
const name = block.getUniqueName( 'text' );
const name = node._state.name;
const value = block.getUniqueName( `${name}_value` );
const { snippet } = block.contextualise( node.expression );

@ -1,9 +1,9 @@
import deindent from '../../../utils/deindent.js';
export default function visitRawMustacheTag ( generator, block, state, node ) {
const name = block.getUniqueName( 'raw' );
const name = node._state.basename;
const before = node._state.name;
const value = block.getUniqueName( `${name}_value` );
const before = block.getUniqueName( `${name}_before` );
const after = block.getUniqueName( `${name}_after` );
const { snippet } = block.contextualise( node.expression );

@ -1,23 +1,6 @@
// Whitespace inside one of these elements will not result in
// a whitespace node being created in any circumstances. (This
// list is almost certainly very incomplete)
const elementsWithoutText = new Set([
'audio',
'datalist',
'dl',
'ol',
'optgroup',
'select',
'ul',
'video'
]);
export default function visitText ( generator, block, state, node ) {
if ( !/\S/.test( node.data ) ) {
if ( state.namespace ) return;
if ( elementsWithoutText.has( state.parentNodeName) ) return;
}
const name = block.getUniqueName( `text` );
block.addElement( name, `${generator.helper( 'createText' )}( ${JSON.stringify( node.data )} )`, state.parentNode, false );
export default function visitText ( generator, block, state, node ) {
if ( !node._state.shouldCreate ) return;
block.addElement( node._state.name, `${generator.helper( 'createText' )}( ${JSON.stringify( node.data )} )`, state.parentNode, node.usedAsAnchor );
}

@ -1,9 +1,6 @@
export default function visitYieldTag ( generator, block, state ) {
const anchor = `yield_anchor`;
block.createAnchor( anchor, state.parentNode );
block.builders.mount.addLine(
`${block.component}._yield && ${block.component}._yield.mount( ${state.parentNode || block.target}, ${anchor} );`
`${block.component}._yield && ${block.component}._yield.mount( ${state.parentNode || block.target}, null );`
);
block.builders.destroy.addLine(

@ -1,9 +1,8 @@
import { appendNode, assign, createComment, createElement, createText, destroyEach, detachBetween, detachNode, dispatchObservers, insertNode, proto } from "svelte/shared.js";
import { appendNode, assign, createElement, createText, destroyEach, detachBetween, detachNode, dispatchObservers, insertNode, proto } from "svelte/shared.js";
function create_main_fragment ( state, component ) {
var text_1_value;
var each_block_anchor = createComment();
var each_block_value = state.comments;
var each_block_iterations = [];
@ -18,10 +17,8 @@ function create_main_fragment ( state, component ) {
return {
mount: function ( target, anchor ) {
insertNode( each_block_anchor, target, anchor );
for ( var i = 0; i < each_block_iterations.length; i += 1 ) {
each_block_iterations[i].mount( target, each_block_anchor );
each_block_iterations[i].mount( target, null );
}
insertNode( text, target, anchor );
@ -37,7 +34,7 @@ function create_main_fragment ( state, component ) {
each_block_iterations[i].update( changed, state, each_block_value, each_block_value[i], i );
} else {
each_block_iterations[i] = create_each_block( state, each_block_value, each_block_value[i], i, component );
each_block_iterations[i].mount( each_block_anchor.parentNode, each_block_anchor );
each_block_iterations[i].mount( text.parentNode, text );
}
}
@ -55,7 +52,6 @@ function create_main_fragment ( state, component ) {
destroyEach( each_block_iterations, detach, 0 );
if ( detach ) {
detachNode( each_block_anchor );
detachNode( text );
detachNode( p );
}

@ -14,7 +14,7 @@ function create_main_fragment ( state, component ) {
return {
mount: function ( target, anchor ) {
insertNode( if_block_anchor, target, anchor );
if ( if_block ) if_block.mount( target, if_block_anchor );
if ( if_block ) if_block.mount( target, null );
},
update: function ( changed, state ) {

@ -8,7 +8,7 @@ function create_main_fragment ( state, component ) {
return {
mount: function ( target, anchor ) {
insertNode( if_block_anchor, target, anchor );
if ( if_block ) if_block.mount( target, if_block_anchor );
if ( if_block ) if_block.mount( target, null );
},
update: function ( changed, state ) {

@ -0,0 +1,243 @@
import { appendNode, assign, createComment, createElement, createText, detachNode, dispatchObservers, insertNode, proto } from "svelte/shared.js";
function create_main_fragment ( state, component ) {
var div = createElement( 'div' );
var if_block = state.a && create_if_block( state, component );
if ( if_block ) if_block.mount( div, null );
var text = createText( "\n\n\t" );
appendNode( text, div );
var p = createElement( 'p' );
appendNode( p, div );
appendNode( createText( "this can be used as an anchor" ), p );
appendNode( createText( "\n\n\t" ), div );
var if_block_1 = state.b && create_if_block_1( state, component );
if ( if_block_1 ) if_block_1.mount( div, null );
var text_3 = createText( "\n\n\t" );
appendNode( text_3, div );
var if_block_2 = state.c && create_if_block_2( state, component );
if ( if_block_2 ) if_block_2.mount( div, null );
var text_4 = createText( "\n\n\t" );
appendNode( text_4, div );
var p_1 = createElement( 'p' );
appendNode( p_1, div );
appendNode( createText( "so can this" ), p_1 );
appendNode( createText( "\n\n\t" ), div );
var if_block_3 = state.d && create_if_block_3( state, component );
if ( if_block_3 ) if_block_3.mount( div, null );
var text_7 = createText( "\n\n\t" );
appendNode( text_7, div );
var text_8 = createText( "\n\n" );
var if_block_4_anchor = createComment();
var if_block_4 = state.e && create_if_block_4( state, component );
return {
mount: function ( target, anchor ) {
insertNode( div, target, anchor );
insertNode( text_8, target, anchor );
insertNode( if_block_4_anchor, target, anchor );
if ( if_block_4 ) if_block_4.mount( target, null );
},
update: function ( changed, state ) {
if ( state.a ) {
if ( !if_block ) {
if_block = create_if_block( state, component );
if_block.mount( div, text );
}
} else if ( if_block ) {
if_block.destroy( true );
if_block = null;
}
if ( state.b ) {
if ( !if_block_1 ) {
if_block_1 = create_if_block_1( state, component );
if_block_1.mount( div, text_3 );
}
} else if ( if_block_1 ) {
if_block_1.destroy( true );
if_block_1 = null;
}
if ( state.c ) {
if ( !if_block_2 ) {
if_block_2 = create_if_block_2( state, component );
if_block_2.mount( div, text_4 );
}
} else if ( if_block_2 ) {
if_block_2.destroy( true );
if_block_2 = null;
}
if ( state.d ) {
if ( !if_block_3 ) {
if_block_3 = create_if_block_3( state, component );
if_block_3.mount( div, text_7 );
}
} else if ( if_block_3 ) {
if_block_3.destroy( true );
if_block_3 = null;
}
if ( state.e ) {
if ( !if_block_4 ) {
if_block_4 = create_if_block_4( state, component );
if_block_4.mount( if_block_4_anchor.parentNode, if_block_4_anchor );
}
} else if ( if_block_4 ) {
if_block_4.destroy( true );
if_block_4 = null;
}
},
destroy: function ( detach ) {
if ( if_block ) if_block.destroy( false );
if ( if_block_1 ) if_block_1.destroy( false );
if ( if_block_2 ) if_block_2.destroy( false );
if ( if_block_3 ) if_block_3.destroy( false );
if ( if_block_4 ) if_block_4.destroy( detach );
if ( detach ) {
detachNode( div );
detachNode( text_8 );
detachNode( if_block_4_anchor );
}
}
};
}
function create_if_block ( state, component ) {
var p = createElement( 'p' );
appendNode( createText( "a" ), p );
return {
mount: function ( target, anchor ) {
insertNode( p, target, anchor );
},
destroy: function ( detach ) {
if ( detach ) {
detachNode( p );
}
}
};
}
function create_if_block_1 ( state, component ) {
var p = createElement( 'p' );
appendNode( createText( "b" ), p );
return {
mount: function ( target, anchor ) {
insertNode( p, target, anchor );
},
destroy: function ( detach ) {
if ( detach ) {
detachNode( p );
}
}
};
}
function create_if_block_2 ( state, component ) {
var p = createElement( 'p' );
appendNode( createText( "c" ), p );
return {
mount: function ( target, anchor ) {
insertNode( p, target, anchor );
},
destroy: function ( detach ) {
if ( detach ) {
detachNode( p );
}
}
};
}
function create_if_block_3 ( state, component ) {
var p = createElement( 'p' );
appendNode( createText( "d" ), p );
return {
mount: function ( target, anchor ) {
insertNode( p, target, anchor );
},
destroy: function ( detach ) {
if ( detach ) {
detachNode( p );
}
}
};
}
function create_if_block_4 ( state, component ) {
var p = createElement( 'p' );
appendNode( createText( "e" ), p );
return {
mount: function ( target, anchor ) {
insertNode( p, target, anchor );
},
destroy: function ( detach ) {
if ( detach ) {
detachNode( p );
}
}
};
}
function SvelteComponent ( options ) {
options = options || {};
this._state = options.data || {};
this._observers = {
pre: Object.create( null ),
post: Object.create( null )
};
this._handlers = Object.create( null );
this._root = options._root;
this._yield = options._yield;
this._torndown = false;
this._fragment = create_main_fragment( this._state, this );
if ( options.target ) this._fragment.mount( options.target, null );
}
assign( SvelteComponent.prototype, proto );
SvelteComponent.prototype._set = function _set ( newState ) {
var oldState = this._state;
this._state = assign( {}, oldState, newState );
dispatchObservers( this, this._observers.pre, newState, oldState );
if ( this._fragment ) this._fragment.update( newState, this._state );
dispatchObservers( this, this._observers.post, newState, oldState );
};
SvelteComponent.prototype.teardown = SvelteComponent.prototype.destroy = function destroy ( detach ) {
this.fire( 'destroy' );
this._fragment.destroy( detach !== false );
this._fragment = null;
this._state = {};
this._torndown = true;
};
export default SvelteComponent;

@ -0,0 +1,27 @@
<div>
{{#if a}}
<p>a</p>
{{/if}}
<p>this can be used as an anchor</p>
{{#if b}}
<p>b</p>
{{/if}}
{{#if c}}
<p>c</p>
{{/if}}
<p>so can this</p>
{{#if d}}
<p>d</p>
{{/if}}
<!-- d can use 'null' as its anchor -->
</div>
{{#if e}}
<p>e</p>
{{/if}}

@ -2,11 +2,26 @@ export default {
data: {
visible: true
},
html: 'before\n<p>Widget</p><!---->\nafter',
html: `
before
<p>Widget</p>
after
`,
test ( assert, component, target ) {
component.set({ visible: false });
assert.equal( target.innerHTML, 'before\n<!---->\nafter' );
assert.htmlEqual( target.innerHTML, `
before
after
` );
component.set({ visible: true });
assert.equal( target.innerHTML, 'before\n<p>Widget</p><!---->\nafter' );
assert.htmlEqual( target.innerHTML, `
before
<p>Widget</p>
after
` );
}
};

Loading…
Cancel
Save