pull/573/head
Rich-Harris 8 years ago
parent 78adc5b226
commit dc82db609c

@ -10,7 +10,9 @@ import getIntro from './shared/utils/getIntro';
import getOutro from './shared/utils/getOutro'; import getOutro from './shared/utils/getOutro';
import processCss from './shared/processCss'; import processCss from './shared/processCss';
import annotateWithScopes from '../utils/annotateWithScopes'; import annotateWithScopes from '../utils/annotateWithScopes';
import { Node, Parsed, CompileOptions } from '../../interfaces'; import DomBlock from './dom/Block';
import SsrBlock from './server-side-rendering/Block';
import { Node, Parsed, CompileOptions } from '../interfaces';
const test = typeof global !== 'undefined' && global.__svelte_test; const test = typeof global !== 'undefined' && global.__svelte_test;
@ -85,7 +87,7 @@ export default class Generator {
return this.aliases.get( name ); return this.aliases.get( name );
} }
contextualise ( block, expression: Node, context, isEventHandler ) { contextualise ( block: DomBlock | SsrBlock, expression: Node, context: string, isEventHandler: boolean ) {
this.addSourcemapLocations( expression ); this.addSourcemapLocations( expression );
const usedContexts: string[] = []; const usedContexts: string[] = [];
@ -219,7 +221,7 @@ export default class Generator {
generate ( result, options, { name, format } ) { generate ( result, options, { name, format } ) {
if ( this.imports.length ) { if ( this.imports.length ) {
const statements = []; const statements: string[] = [];
this.imports.forEach( ( declaration, i ) => { this.imports.forEach( ( declaration, i ) => {
if ( format === 'es' ) { if ( format === 'es' ) {
@ -227,14 +229,14 @@ export default class Generator {
return; return;
} }
const defaultImport = declaration.specifiers.find( x => x.type === 'ImportDefaultSpecifier' || x.type === 'ImportSpecifier' && x.imported.name === 'default' ); const defaultImport = declaration.specifiers.find( ( x: Node ) => x.type === 'ImportDefaultSpecifier' || x.type === 'ImportSpecifier' && x.imported.name === 'default' );
const namespaceImport = declaration.specifiers.find( x => x.type === 'ImportNamespaceSpecifier' ); const namespaceImport = declaration.specifiers.find( ( x: Node ) => x.type === 'ImportNamespaceSpecifier' );
const namedImports = declaration.specifiers.filter( x => x.type === 'ImportSpecifier' && x.imported.name !== 'default' ); const namedImports = declaration.specifiers.filter( ( x: Node ) => x.type === 'ImportSpecifier' && x.imported.name !== 'default' );
const name = ( defaultImport || namespaceImport ) ? ( defaultImport || namespaceImport ).local.name : `__import${i}`; const name = ( defaultImport || namespaceImport ) ? ( defaultImport || namespaceImport ).local.name : `__import${i}`;
declaration.name = name; // hacky but makes life a bit easier later declaration.name = name; // hacky but makes life a bit easier later
namedImports.forEach( specifier => { namedImports.forEach( ( specifier: Node ) => {
statements.push( `var ${specifier.local.name} = ${name}.${specifier.imported.name}` ); statements.push( `var ${specifier.local.name} = ${name}.${specifier.imported.name}` );
}); });
@ -253,7 +255,7 @@ export default class Generator {
const compiled = new Bundle({ separator: '' }); const compiled = new Bundle({ separator: '' });
function addString ( str ) { function addString ( str: string ) {
compiled.addSource({ compiled.addSource({
content: new MagicString( str ) content: new MagicString( str )
}); });
@ -273,7 +275,7 @@ export default class Generator {
}); });
} }
parts.forEach( str => { parts.forEach( ( str: string ) => {
const chunk = str.replace( pattern, '' ); const chunk = str.replace( pattern, '' );
if ( chunk ) addString( chunk ); if ( chunk ) addString( chunk );

@ -4,16 +4,43 @@ import { DomGenerator } from './index';
import { Node } from '../../interfaces'; import { Node } from '../../interfaces';
export interface BlockOptions { export interface BlockOptions {
generator: DomGenerator generator: DomGenerator;
name: string name: string;
expression: Node expression: Node;
context: string context: string;
key: string;
} }
export default class Block { export default class Block {
generator: DomGenerator; generator: DomGenerator;
name: string; name: string;
expression: Node; expression: Node;
context: string;
key: string;
builders: {
create: CodeBuilder;
mount: CodeBuilder;
update: CodeBuilder;
intro: CodeBuilder;
outro: CodeBuilder;
detach: CodeBuilder;
detachRaw: CodeBuilder;
destroy: CodeBuilder;
}
hasIntroMethod: boolean;
hasOutroMethod: boolean;
outros: number;
aliases: Map<string, string>;
variables: Map<string, string>;
getUniqueName: (name: string) => string;
component: string;
target: string;
hasUpdateMethod: boolean;
constructor ( options: BlockOptions ) { constructor ( options: BlockOptions ) {
this.generator = options.generator; this.generator = options.generator;
@ -85,7 +112,7 @@ export default class Block {
} }
} }
addVariable ( name: string, init ) { addVariable ( name: string, init?: string ) {
if ( this.variables.has( name ) && this.variables.get( name ) !== init ) { if ( this.variables.has( name ) && this.variables.get( name ) !== init ) {
throw new Error( `Variable '${name}' already initialised with a different value` ); throw new Error( `Variable '${name}' already initialised with a different value` );
} }
@ -101,11 +128,11 @@ export default class Block {
return this.aliases.get( name ); return this.aliases.get( name );
} }
child ( options ) { child ( options: BlockOptions ) {
return new Block( Object.assign( {}, this, options, { parent: this } ) ); return new Block( Object.assign( {}, this, options, { parent: this } ) );
} }
contextualise ( expression, context, isEventHandler ) { contextualise ( expression: Node, context?: string, isEventHandler?: boolean ) {
return this.generator.contextualise( this, expression, context, isEventHandler ); return this.generator.contextualise( this, expression, context, isEventHandler );
} }

@ -1,4 +1,8 @@
export default function visitAttribute ( generator, block, state, node, attribute, local ) { import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
export default function visitAttribute ( generator: DomGenerator, block: Block, state, node: Node, attribute, local ) {
if ( attribute.value === true ) { if ( attribute.value === true ) {
// attributes without values, e.g. <textarea readonly> // attributes without values, e.g. <textarea readonly>
local.staticAttributes.push({ local.staticAttributes.push({

@ -1,8 +1,11 @@
import deindent from '../../../../utils/deindent.js'; import deindent from '../../../../utils/deindent.js';
import flattenReference from '../../../../utils/flattenReference'; import flattenReference from '../../../../utils/flattenReference';
import getSetter from '../shared/binding/getSetter'; import getSetter from '../shared/binding/getSetter';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
export default function visitBinding ( generator, block, state, node, attribute, local ) { export default function visitBinding ( generator: DomGenerator, block: Block, state, node: Node, attribute, local ) {
const { name } = flattenReference( attribute.value ); const { name } = flattenReference( attribute.value );
const { snippet, contexts, dependencies } = block.contextualise( attribute.value ); const { snippet, contexts, dependencies } = block.contextualise( attribute.value );

@ -5,6 +5,9 @@ import visitAttribute from './Attribute';
import visitEventHandler from './EventHandler'; import visitEventHandler from './EventHandler';
import visitBinding from './Binding'; import visitBinding from './Binding';
import visitRef from './Ref'; import visitRef from './Ref';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
function stringifyProps ( props ) { function stringifyProps ( props ) {
if ( !props.length ) return '{}'; if ( !props.length ) return '{}';
@ -32,7 +35,7 @@ const visitors = {
Ref: visitRef Ref: visitRef
}; };
export default function visitComponent ( generator, block, state, node ) { export default function visitComponent ( generator: DomGenerator, block: Block, state, node: Node ) {
const hasChildren = node.children.length > 0; const hasChildren = node.children.length > 0;
const name = block.getUniqueName( ( node.name === ':Self' ? generator.name : node.name ).toLowerCase() ); const name = block.getUniqueName( ( node.name === ':Self' ? generator.name : node.name ).toLowerCase() );

@ -1,6 +1,9 @@
import deindent from '../../../../utils/deindent.js'; import deindent from '../../../../utils/deindent.js';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
export default function visitEventHandler ( generator, block, state, node, attribute, local ) { export default function visitEventHandler ( generator: DomGenerator, block: Block, state, node: Node, attribute, local ) {
// TODO verify that it's a valid callee (i.e. built-in or declared method) // TODO verify that it's a valid callee (i.e. built-in or declared method)
generator.addSourcemapLocations( attribute.expression ); generator.addSourcemapLocations( attribute.expression );
generator.code.prependRight( attribute.expression.start, `${block.component}.` ); generator.code.prependRight( attribute.expression.start, `${block.component}.` );

@ -1,6 +1,9 @@
import deindent from '../../../../utils/deindent.js'; import deindent from '../../../../utils/deindent.js';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
export default function visitRef ( generator, block, state, node, attribute, local ) { export default function visitRef ( generator: DomGenerator, block: Block, state, node: Node, attribute, local ) {
generator.usesRefs = true; generator.usesRefs = true;
local.create.addLine( local.create.addLine(

@ -1,7 +1,10 @@
import deindent from '../../../utils/deindent.js'; import deindent from '../../../utils/deindent.js';
import visit from '../visit'; import visit from '../visit';
import { DomGenerator } from '../index';
import Block from '../Block';
import { Node } from '../../../interfaces';
export default function visitEachBlock ( generator, block, state, node ) { export default function visitEachBlock ( generator: DomGenerator, block: Block, state, node: Node ) {
const each_block = generator.getUniqueName( `each_block` ); const each_block = generator.getUniqueName( `each_block` );
const create_each_block = node._block.name; const create_each_block = node._block.name;
const each_block_value = node._block.listName; const each_block_value = node._block.listName;
@ -86,18 +89,18 @@ export default function visitEachBlock ( generator, block, state, node ) {
` ); ` );
} }
node.children.forEach( child => { node.children.forEach( ( child: Node ) => {
visit( generator, node._block, node._state, child ); visit( generator, node._block, node._state, child );
}); });
if ( node.else ) { if ( node.else ) {
node.else.children.forEach( child => { node.else.children.forEach( ( child: Node ) => {
visit( generator, node.else._block, node.else._state, child ); visit( generator, node.else._block, node.else._state, child );
}); });
} }
} }
function keyed ( generator, block, state, node, snippet, { each_block, create_each_block, each_block_value, i, params, anchor, mountOrIntro } ) { function keyed ( generator: DomGenerator, block: Block, state, node: Node, snippet, { each_block, create_each_block, each_block_value, i, params, anchor, mountOrIntro } ) {
const key = block.getUniqueName( 'key' ); const key = block.getUniqueName( 'key' );
const lookup = block.getUniqueName( `${each_block}_lookup` ); const lookup = block.getUniqueName( `${each_block}_lookup` );
const iteration = block.getUniqueName( `${each_block}_iteration` ); const iteration = block.getUniqueName( `${each_block}_iteration` );
@ -271,7 +274,7 @@ function keyed ( generator, block, state, node, snippet, { each_block, create_ea
` ); ` );
} }
function unkeyed ( generator, block, state, node, snippet, { create_each_block, each_block_value, iterations, i, params, anchor, mountOrIntro } ) { function unkeyed ( generator: DomGenerator, block: Block, state, node: Node, snippet, { create_each_block, each_block_value, iterations, i, params, anchor, mountOrIntro } ) {
block.builders.create.addBlock( deindent` block.builders.create.addBlock( deindent`
var ${iterations} = []; var ${iterations} = [];

@ -1,8 +1,11 @@
import attributeLookup from './lookup'; import attributeLookup from './lookup';
import deindent from '../../../../utils/deindent.js'; import deindent from '../../../../utils/deindent.js';
import getStaticAttributeValue from './getStaticAttributeValue'; import getStaticAttributeValue from './getStaticAttributeValue';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
export default function visitAttribute ( generator, block, state, node, attribute ) { export default function visitAttribute ( generator: DomGenerator, block: Block, state, node: Node, attribute ) {
const name = attribute.name; const name = attribute.name;
let metadata = state.namespace ? null : attributeLookup[ name ]; let metadata = state.namespace ? null : attributeLookup[ name ];

@ -2,8 +2,11 @@ import deindent from '../../../../utils/deindent.js';
import flattenReference from '../../../../utils/flattenReference'; import flattenReference from '../../../../utils/flattenReference';
import getSetter from '../shared/binding/getSetter'; import getSetter from '../shared/binding/getSetter';
import getStaticAttributeValue from './getStaticAttributeValue'; import getStaticAttributeValue from './getStaticAttributeValue';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
export default function visitBinding ( generator, block, state, node, attribute ) { export default function visitBinding ( generator: DomGenerator, block: Block, state, node: Node, attribute ) {
const { name, parts } = flattenReference( attribute.value ); const { name, parts } = flattenReference( attribute.value );
const { snippet, contexts, dependencies } = block.contextualise( attribute.value ); const { snippet, contexts, dependencies } = block.contextualise( attribute.value );

@ -7,6 +7,9 @@ import visitEventHandler from './EventHandler';
import visitBinding from './Binding'; import visitBinding from './Binding';
import visitRef from './Ref'; import visitRef from './Ref';
import addTransitions from './addTransitions'; import addTransitions from './addTransitions';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
const meta = { const meta = {
':Window': visitWindow ':Window': visitWindow
@ -26,7 +29,7 @@ const visitors = {
Ref: visitRef Ref: visitRef
}; };
export default function visitElement ( generator, block, state, node ) { export default function visitElement ( generator: DomGenerator, block: Block, state, node: Node ) {
if ( node.name in meta ) { if ( node.name in meta ) {
return meta[ node.name ]( generator, block, node ); return meta[ node.name ]( generator, block, node );
} }
@ -131,7 +134,7 @@ export default function visitElement ( generator, block, state, node ) {
} }
} }
function getRenderStatement ( generator, namespace, name ) { function getRenderStatement ( generator: DomGenerator, namespace, name ) {
if ( namespace === 'http://www.w3.org/2000/svg' ) { if ( namespace === 'http://www.w3.org/2000/svg' ) {
return `${generator.helper( 'createSvgElement' )}( '${name}' )`; return `${generator.helper( 'createSvgElement' )}( '${name}' )`;
} }

@ -1,7 +1,10 @@
import deindent from '../../../../utils/deindent.js'; import deindent from '../../../../utils/deindent.js';
import flattenReference from '../../../../utils/flattenReference'; import flattenReference from '../../../../utils/flattenReference';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
export default function visitEventHandler ( generator, block, state, node, attribute ) { export default function visitEventHandler ( generator: DomGenerator, block: Block, state, node: Node, attribute ) {
const name = attribute.name; const name = attribute.name;
const isCustomEvent = generator.events.has( name ); const isCustomEvent = generator.events.has( name );
const shouldHoist = !isCustomEvent && state.inEachBlock; const shouldHoist = !isCustomEvent && state.inEachBlock;

@ -1,6 +1,9 @@
import deindent from '../../../../utils/deindent.js'; import deindent from '../../../../utils/deindent.js';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
export default function visitRef ( generator, block, state, node, attribute ) { export default function visitRef ( generator: DomGenerator, block: Block, state, node: Node, attribute ) {
const name = attribute.name; const name = attribute.name;
block.builders.create.addLine( block.builders.create.addLine(

@ -1,6 +1,9 @@
import deindent from '../../../../utils/deindent.js'; import deindent from '../../../../utils/deindent.js';
import { DomGenerator } from '../../index';
import Block from '../../Block';
import { Node } from '../../../../interfaces';
export default function addTransitions ( generator, block, state, node, intro, outro ) { export default function addTransitions ( generator: DomGenerator, block: Block, state, node: Node, intro, outro ) {
const wrapTransition = generator.helper( 'wrapTransition' ); const wrapTransition = generator.helper( 'wrapTransition' );
if ( intro === outro ) { if ( intro === outro ) {

@ -1,5 +1,7 @@
export default function getStaticAttributeValue ( node, name ) { import { Node } from '../../../../interfaces';
const attribute = node.attributes.find( attr => attr.name.toLowerCase() === name );
export default function getStaticAttributeValue ( node: Node, name: string ) {
const attribute = node.attributes.find( ( attr: Node ) => attr.name.toLowerCase() === name );
if ( !attribute ) return null; if ( !attribute ) return null;
if ( attribute.value.length !== 1 || attribute.value[0].type !== 'Text' ) { if ( attribute.value.length !== 1 || attribute.value[0].type !== 'Text' ) {

@ -1,5 +1,8 @@
import flattenReference from '../../../../../utils/flattenReference'; import flattenReference from '../../../../../utils/flattenReference';
import deindent from '../../../../../utils/deindent.js'; import deindent from '../../../../../utils/deindent.js';
import { DomGenerator } from '../../../index';
import Block from '../../../Block';
import { Node } from '../../../../../interfaces';
const associatedEvents = { const associatedEvents = {
innerWidth: 'resize', innerWidth: 'resize',
@ -19,18 +22,18 @@ const readonly = new Set([
'online' 'online'
]); ]);
export default function visitWindow ( generator, block, node ) { export default function visitWindow ( generator: DomGenerator, block: Block, node: Node ) {
const events = {}; const events = {};
const bindings = {}; const bindings = {};
node.attributes.forEach( attribute => { node.attributes.forEach( ( attribute: Node ) => {
if ( attribute.type === 'EventHandler' ) { if ( attribute.type === 'EventHandler' ) {
// TODO verify that it's a valid callee (i.e. built-in or declared method) // TODO verify that it's a valid callee (i.e. built-in or declared method)
generator.addSourcemapLocations( attribute.expression ); generator.addSourcemapLocations( attribute.expression );
let usesState = false; let usesState = false;
attribute.expression.arguments.forEach( arg => { attribute.expression.arguments.forEach( ( arg: Node ) => {
const { contexts } = block.contextualise( arg, null, true ); const { contexts } = block.contextualise( arg, null, true );
if ( contexts.length ) usesState = true; if ( contexts.length ) usesState = true;
}); });

@ -1,7 +1,10 @@
import deindent from '../../../utils/deindent.js'; import deindent from '../../../utils/deindent.js';
import visit from '../visit'; import visit from '../visit';
import { DomGenerator } from '../index';
import Block from '../Block';
import { Node } from '../../../interfaces';
function isElseIf ( node ) { function isElseIf ( node: Node ) {
return node && node.children.length === 1 && node.children[0].type === 'IfBlock'; return node && node.children.length === 1 && node.children[0].type === 'IfBlock';
} }
@ -9,7 +12,7 @@ function isElseBranch ( branch ) {
return branch.block && !branch.condition; return branch.block && !branch.condition;
} }
function getBranches ( generator, block, state, node ) { function getBranches ( generator: DomGenerator, block: Block, state, node: Node ) {
const branches = [{ const branches = [{
condition: block.contextualise( node.expression ).snippet, condition: block.contextualise( node.expression ).snippet,
block: node._block.name, block: node._block.name,
@ -41,13 +44,13 @@ function getBranches ( generator, block, state, node ) {
return branches; return branches;
} }
function visitChildren ( generator, block, state, node ) { function visitChildren ( generator: DomGenerator, block: Block, state, node: Node ) {
node.children.forEach( child => { node.children.forEach( ( child: Node ) => {
visit( generator, node._block, node._state, child ); visit( generator, node._block, node._state, child );
}); });
} }
export default function visitIfBlock ( generator, block, state, node ) { export default function visitIfBlock ( generator: DomGenerator, block: Block, state, node: Node ) {
const name = generator.getUniqueName( `if_block` ); const name = generator.getUniqueName( `if_block` );
const anchor = node.needsAnchor ? block.getUniqueName( `${name}_anchor` ) : ( node.next && node.next._state.name ) || 'null'; const anchor = node.needsAnchor ? block.getUniqueName( `${name}_anchor` ) : ( node.next && node.next._state.name ) || 'null';
const params = block.params.join( ', ' ); const params = block.params.join( ', ' );
@ -79,7 +82,7 @@ export default function visitIfBlock ( generator, block, state, node ) {
} }
} }
function simple ( generator, block, state, node, branch, dynamic, { name, anchor, params, if_name } ) { function simple ( generator: DomGenerator, block: Block, state, node: Node, branch, dynamic, { name, anchor, params, if_name } ) {
block.builders.create.addBlock( deindent` block.builders.create.addBlock( deindent`
var ${name} = (${branch.condition}) && ${branch.block}( ${params}, ${block.component} ); var ${name} = (${branch.condition}) && ${branch.block}( ${params}, ${block.component} );
` ); ` );
@ -153,7 +156,7 @@ function simple ( generator, block, state, node, branch, dynamic, { name, anchor
); );
} }
function compound ( generator, block, state, node, branches, dynamic, { name, anchor, params, hasElse, if_name } ) { function compound ( generator: DomGenerator, block: Block, state, node: Node, branches, dynamic, { name, anchor, params, hasElse, if_name } ) {
const get_block = block.getUniqueName( `get_block` ); const get_block = block.getUniqueName( `get_block` );
const current_block = block.getUniqueName( `current_block` ); const current_block = block.getUniqueName( `current_block` );
const current_block_and = hasElse ? '' : `${current_block} && `; const current_block_and = hasElse ? '' : `${current_block} && `;
@ -209,7 +212,7 @@ function compound ( generator, block, state, node, branches, dynamic, { name, an
// if any of the siblings have outros, we need to keep references to the blocks // if any of the siblings have outros, we need to keep references to the blocks
// (TODO does this only apply to bidi transitions?) // (TODO does this only apply to bidi transitions?)
function compoundWithOutros ( generator, block, state, node, branches, dynamic, { name, anchor, params, hasElse } ) { function compoundWithOutros ( generator: DomGenerator, block: Block, state, node: Node, branches, dynamic, { name, anchor, params, hasElse } ) {
const get_block = block.getUniqueName( `get_block` ); const get_block = block.getUniqueName( `get_block` );
const current_block_index = block.getUniqueName( `current_block_index` ); const current_block_index = block.getUniqueName( `current_block_index` );
const previous_block_index = block.getUniqueName( `previous_block_index` ); const previous_block_index = block.getUniqueName( `previous_block_index` );

@ -1,6 +1,9 @@
import deindent from '../../../utils/deindent.js'; import deindent from '../../../utils/deindent.js';
import { DomGenerator } from '../index';
import Block from '../Block';
import { Node } from '../../../interfaces';
export default function visitMustacheTag ( generator, block, state, node ) { export default function visitMustacheTag ( generator: DomGenerator, block: Block, state, node: Node ) {
const name = node._state.name; const name = node._state.name;
const value = block.getUniqueName( `${name}_value` ); const value = block.getUniqueName( `${name}_value` );

@ -1,6 +1,9 @@
import deindent from '../../../utils/deindent.js'; import deindent from '../../../utils/deindent.js';
import { DomGenerator } from '../index';
import Block from '../Block';
import { Node } from '../../../interfaces';
export default function visitRawMustacheTag ( generator, block, state, node ) { export default function visitRawMustacheTag ( generator: DomGenerator, block: Block, state, node: Node ) {
const name = node._state.basename; const name = node._state.basename;
const before = node._state.name; const before = node._state.name;
const value = block.getUniqueName( `${name}_value` ); const value = block.getUniqueName( `${name}_value` );

@ -1,6 +1,8 @@
import { DomGenerator } from '../index';
import Block from '../Block';
import { Node } from '../../../interfaces';
export default function visitText ( generator: DomGenerator, block: Block, state, node: Node ) {
export default function visitText ( generator, block, state, node ) {
if ( !node._state.shouldCreate ) return; if ( !node._state.shouldCreate ) return;
block.addElement( node._state.name, `${generator.helper( 'createText' )}( ${JSON.stringify( node.data )} )`, state.parentNode, node.usedAsAnchor ); block.addElement( node._state.name, `${generator.helper( 'createText' )}( ${JSON.stringify( node.data )} )`, state.parentNode, node.usedAsAnchor );
} }
Loading…
Cancel
Save