From 98d9cdbea712a2e2f00c798a4c21da67ffd16390 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 28 Feb 2017 16:22:06 -0500 Subject: [PATCH] allow each blocks to introduce reserved words as contexts (#222) --- src/generators/Generator.js | 8 +++++++- src/generators/dom/index.js | 2 +- src/generators/dom/visitors/EachBlock.js | 17 +++++++++++++++-- .../server-side-rendering/visitors/EachBlock.js | 2 +- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/generators/Generator.js b/src/generators/Generator.js index f28b2a0f43..20618ee60e 100644 --- a/src/generators/Generator.js +++ b/src/generators/Generator.js @@ -58,7 +58,13 @@ export default class Generator { // noop } - else if ( contexts[ name ] ) { + else if ( name in contexts ) { + const context = contexts[ name ]; + if ( context !== name ) { + // this is true for 'reserved' names like `root` and `component` + code.overwrite( node.start, node.start + name.length, context, true ); + } + dependencies.push( ...contextDependencies[ name ] ); if ( !~usedContexts.indexOf( name ) ) usedContexts.push( name ); } diff --git a/src/generators/dom/index.js b/src/generators/dom/index.js index df2b25840a..3bb4369da8 100644 --- a/src/generators/dom/index.js +++ b/src/generators/dom/index.js @@ -180,7 +180,7 @@ export default function dom ( parsed, source, options, names ) { contexts: {}, indexes: {}, - params: 'root', + params: [ 'root' ], indexNames: {}, listNames: {}, diff --git a/src/generators/dom/visitors/EachBlock.js b/src/generators/dom/visitors/EachBlock.js index e9e0eb4fd3..8113e93803 100644 --- a/src/generators/dom/visitors/EachBlock.js +++ b/src/generators/dom/visitors/EachBlock.js @@ -2,6 +2,11 @@ import CodeBuilder from '../../../utils/CodeBuilder.js'; import deindent from '../../../utils/deindent.js'; import getBuilders from '../utils/getBuilders.js'; +const reserved = { + component: true, + root: true +}; + export default { enter ( generator, node ) { const name = generator.getUniqueName( `eachBlock` ); @@ -172,8 +177,16 @@ export default { const listNames = Object.assign( {}, generator.current.listNames ); listNames[ node.context ] = listName; + // ensure that contexts like `root` or `component` don't blow up the whole show + let context = node.context; + let c = 1; + + while ( context in reserved || ~generator.current.params.indexOf( context ) ) { + context = `${node.context}$${c++}`; + } + const contexts = Object.assign( {}, generator.current.contexts ); - contexts[ node.context ] = true; + contexts[ node.context ] = context; const indexes = Object.assign( {}, generator.current.indexes ); if ( node.index ) indexes[ indexName ] = node.context; @@ -181,7 +194,7 @@ export default { const contextDependencies = Object.assign( {}, generator.current.contextDependencies ); contextDependencies[ node.context ] = dependencies; - const blockParams = generator.current.params + `, ${listName}, ${node.context}, ${indexName}`; + const blockParams = generator.current.params.concat( listName, context, indexName ); generator.push({ name: renderer, diff --git a/src/generators/server-side-rendering/visitors/EachBlock.js b/src/generators/server-side-rendering/visitors/EachBlock.js index de4bfffe6d..70a9527a1a 100644 --- a/src/generators/server-side-rendering/visitors/EachBlock.js +++ b/src/generators/server-side-rendering/visitors/EachBlock.js @@ -8,7 +8,7 @@ export default { // TODO should this be the generator's job? It's duplicated between // here and the equivalent DOM compiler visitor const contexts = Object.assign( {}, generator.current.contexts ); - contexts[ node.context ] = true; + contexts[ node.context ] = node.context; const indexes = Object.assign( {}, generator.current.indexes ); if ( node.index ) indexes[ node.index ] = node.context;