|
|
@ -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 );`
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -419,4 +448,4 @@ export default function dom ( parsed, source, options, names ) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return generator.generate( builders.main.toString(), options, { name, format } );
|
|
|
|
return generator.generate( builders.main.toString(), options, { name, format } );
|
|
|
|
}
|
|
|
|
}
|
|
|
|