Merge branch 'master' into gh-371

pull/391/head
Rich-Harris 8 years ago
commit 89f0fb00e6

@ -1,5 +1,10 @@
# Svelte changelog # Svelte changelog
## 1.12.1
* Deconflict non-helper functions (`addCss` etc) ([#388](https://github.com/sveltejs/svelte/issues/388))
* Allow reserved words in tags, e.g. `{{class}}` ([#383](https://github.com/sveltejs/svelte/issues/383))
## 1.12.0 ## 1.12.0
* Shorthand attributes — `<Widget :foo/>` is equivalent to `<Widget foo='{{foo}}'/>` ([#384](https://github.com/sveltejs/svelte/pull/384)) * Shorthand attributes — `<Widget :foo/>` is equivalent to `<Widget foo='{{foo}}'/>` ([#384](https://github.com/sveltejs/svelte/pull/384))

@ -1,6 +1,6 @@
{ {
"name": "svelte", "name": "svelte",
"version": "1.12.0", "version": "1.12.1",
"description": "The magical disappearing UI framework", "description": "The magical disappearing UI framework",
"main": "compiler/svelte.js", "main": "compiler/svelte.js",
"files": [ "files": [

@ -232,6 +232,7 @@ export default class Generator {
const imports = this.imports; const imports = this.imports;
const computations = []; const computations = [];
let defaultExport = null;
const templateProperties = {}; const templateProperties = {};
if ( js ) { if ( js ) {
@ -251,7 +252,7 @@ export default class Generator {
} }
} }
const defaultExport = js.content.body.find( node => node.type === 'ExportDefaultDeclaration' ); defaultExport = js.content.body.find( node => node.type === 'ExportDefaultDeclaration' );
if ( defaultExport ) { if ( defaultExport ) {
const finalNode = js.content.body[ js.content.body.length - 1 ]; const finalNode = js.content.body[ js.content.body.length - 1 ];
@ -319,6 +320,7 @@ export default class Generator {
return { return {
computations, computations,
defaultExport,
templateProperties templateProperties
}; };
} }

@ -3,6 +3,7 @@ import getBuilders from './utils/getBuilders.js';
import CodeBuilder from '../../utils/CodeBuilder.js'; import CodeBuilder from '../../utils/CodeBuilder.js';
import namespaces from '../../utils/namespaces.js'; import namespaces from '../../utils/namespaces.js';
import processCss from '../shared/processCss.js'; import processCss from '../shared/processCss.js';
import removeObjectKey from '../../utils/removeObjectKey.js';
import visitors from './visitors/index.js'; import visitors from './visitors/index.js';
import Generator from '../Generator.js'; import Generator from '../Generator.js';
import * as shared from '../../shared/index.js'; import * as shared from '../../shared/index.js';
@ -17,6 +18,8 @@ class DomGenerator extends Generator {
// Svelte's builtin `import { get, ... } from 'svelte/shared.js'`; // Svelte's builtin `import { get, ... } from 'svelte/shared.js'`;
this.importedNames = {}; this.importedNames = {};
this.aliases = {}; this.aliases = {};
this.importedComponents = {};
} }
addElement ( name, renderStatement, needsIdentifier = false ) { addElement ( name, renderStatement, needsIdentifier = false ) {
@ -138,6 +141,10 @@ class DomGenerator extends Generator {
this.uses[ name ] = true; this.uses[ name ] = true;
return this.alias( name );
}
alias ( name ) {
if ( !( name in this.aliases ) ) { if ( !( name in this.aliases ) ) {
let alias = name; let alias = name;
let i = 1; let i = 1;
@ -158,7 +165,7 @@ export default function dom ( parsed, source, options, names ) {
const generator = new DomGenerator( parsed, source, name, names, visitors, options ); const generator = new DomGenerator( parsed, source, name, names, visitors, options );
const { computations, templateProperties } = generator.parseJs(); const { computations, defaultExport, templateProperties } = generator.parseJs();
// Remove these after version 2 // Remove these after version 2
if ( templateProperties.onrender ) { if ( templateProperties.onrender ) {
@ -184,11 +191,33 @@ export default function dom ( parsed, source, options, names ) {
const ns = templateProperties.namespace.value.value; const ns = templateProperties.namespace.value.value;
namespace = namespaces[ ns ] || ns; namespace = namespaces[ ns ] || ns;
// TODO remove the namespace property from the generated code, it's unused past this point removeObjectKey( generator, defaultExport.declaration, 'namespace' );
}
if ( templateProperties.components ) {
let hasNonImportedComponent = false;
templateProperties.components.value.properties.forEach( property => {
const key = property.key.name;
const value = source.slice( property.value.start, property.value.end );
if ( generator.importedNames[ value ] ) {
generator.importedComponents[ key ] = value;
} else {
hasNonImportedComponent = true;
}
});
if ( hasNonImportedComponent ) {
// remove the specific components which were imported, as we'll refer to them directly
Object.keys( generator.importedComponents ).forEach ( key => {
removeObjectKey( generator, templateProperties.components.value, key );
});
} else {
// remove the entire components portion of the export
removeObjectKey( generator, defaultExport.declaration, 'components' );
}
} }
generator.push({ generator.push({
name: 'renderMainFragment', name: generator.alias( 'renderMainFragment' ),
namespace, namespace,
target: 'target', target: 'target',
localElementDepth: 0, localElementDepth: 0,
@ -238,12 +267,12 @@ export default function dom ( parsed, source, options, names ) {
}); });
builders.main.addBlock( deindent` builders.main.addBlock( deindent`
function applyComputations ( state, newState, oldState, isInitial ) { function ${generator.alias( 'applyComputations' )} ( state, newState, oldState, isInitial ) {
${builder} ${builder}
} }
` ); ` );
builders._set.addLine( `applyComputations( this._state, newState, oldState, false )` ); builders._set.addLine( `${generator.alias( 'applyComputations' )}( this._state, newState, oldState, false )` );
} }
// TODO is the `if` necessary? // TODO is the `if` necessary?
@ -259,13 +288,13 @@ export default function dom ( parsed, source, options, names ) {
if ( parsed.css && options.css !== false ) { if ( parsed.css && options.css !== false ) {
builders.main.addBlock( deindent` builders.main.addBlock( deindent`
var addedCss = false; var ${generator.alias( 'addedCss' )} = false;
function addCss () { function ${generator.alias( 'addCss' )} () {
var style = ${generator.helper( 'createElement' )}( 'style' ); var style = ${generator.helper( 'createElement' )}( 'style' );
style.textContent = ${JSON.stringify( processCss( parsed, generator.code ) )}; style.textContent = ${JSON.stringify( processCss( parsed, generator.code ) )};
${generator.helper( 'appendNode' )}( style, document.head ); ${generator.helper( 'appendNode' )}( style, document.head );
addedCss = true; ${generator.alias( 'addedCss' )} = true;
} }
` ); ` );
} }
@ -276,7 +305,7 @@ export default function dom ( parsed, source, options, names ) {
builders.init.addLine( `this._torndown = false;` ); builders.init.addLine( `this._torndown = false;` );
if ( parsed.css && options.css !== false ) { if ( parsed.css && options.css !== false ) {
builders.init.addLine( `if ( !addedCss ) addCss();` ); builders.init.addLine( `if ( !${generator.alias( 'addedCss' )} ) ${generator.alias( 'addCss' )}();` );
} }
if ( generator.hasComponents ) { if ( generator.hasComponents ) {
@ -286,7 +315,7 @@ export default function dom ( parsed, source, options, names ) {
if ( generator.hasComplexBindings ) { if ( generator.hasComplexBindings ) {
builders.init.addBlock( deindent` builders.init.addBlock( deindent`
this._bindings = []; this._bindings = [];
this._fragment = renderMainFragment( this._state, this ); this._fragment = ${generator.alias( 'renderMainFragment' )}( this._state, this );
if ( options.target ) this._fragment.mount( options.target, null ); if ( options.target ) this._fragment.mount( options.target, null );
while ( this._bindings.length ) this._bindings.pop()(); while ( this._bindings.length ) this._bindings.pop()();
` ); ` );
@ -294,7 +323,7 @@ export default function dom ( parsed, source, options, names ) {
builders._set.addLine( `while ( this._bindings.length ) this._bindings.pop()();` ); builders._set.addLine( `while ( this._bindings.length ) this._bindings.pop()();` );
} else { } else {
builders.init.addBlock( deindent` builders.init.addBlock( deindent`
this._fragment = renderMainFragment( this._state, this ); this._fragment = ${generator.alias( 'renderMainFragment' )}( this._state, this );
if ( options.target ) this._fragment.mount( options.target, null ); if ( options.target ) this._fragment.mount( options.target, null );
` ); ` );
} }
@ -327,7 +356,7 @@ export default function dom ( parsed, source, options, names ) {
if ( templateProperties.computed ) { if ( templateProperties.computed ) {
constructorBlock.addLine( constructorBlock.addLine(
`applyComputations( this._state, this._state, {}, true );` `${generator.alias( 'applyComputations' )}( this._state, this._state, {}, true );`
); );
} }

@ -106,7 +106,7 @@ export default {
componentInitProperties.push(`data: ${name}_initialData`); componentInitProperties.push(`data: ${name}_initialData`);
} }
const expression = node.name === ':Self' ? generator.name : `template.components.${node.name}`; const expression = node.name === ':Self' ? generator.name : generator.importedComponents[ node.name ] || `template.components.${node.name}`;
local.init.addBlockAtStart( deindent` local.init.addBlockAtStart( deindent`
${statements.join( '\n\n' )} ${statements.join( '\n\n' )}

@ -0,0 +1,9 @@
export default function removeObjectKey ( generator, node, key ) {
if ( node.type !== 'ObjectExpression' ) return;
const properties = node.properties;
const index = properties.findIndex( property => property.key.type === 'Identifier' && property.key.name === key );
if ( index === -1 ) return;
const a = properties[ index ].start;
const b = index < properties.length - 1 ? properties[ index + 1 ].start : properties[ index ].end;
generator.code.remove( a, b );
}

@ -0,0 +1,8 @@
export default {
html: `ABCD`,
test ( assert, component ) {
assert.equal( component.get( 'compute' ), 'ABCD' );
component.destroy();
}
};

@ -0,0 +1,17 @@
{{compute}}
<script>
import { addCss, addedCss, applyComputations, renderMainFragment } from './module.js';
export default {
data() {
return {
value: addCss + addedCss + applyComputations + renderMainFragment
};
},
computed: {
compute: value => value.toUpperCase()
}
};
</script>
<style>
</style>

@ -0,0 +1,4 @@
export const addCss = 'a';
export const addedCss = 'b';
export const applyComputations = 'c';
export const renderMainFragment = 'd';

@ -0,0 +1,10 @@
<RenamedComponentOne/><RenamedComponentTwo/>
<script>
import ComponentOne from './ComponentOne.html';
import ComponentTwo from './ComponentTwo.html';
export default {
components: { RenamedComponentOne: ComponentOne, RenamedComponentTwo: ComponentTwo }
};
</script>
Loading…
Cancel
Save