rename Compiler to Component

pull/1721/head
Rich Harris 7 years ago
parent 8f854b4b49
commit d08051b35c

@ -1,5 +1,5 @@
import { Node, Warning } from './interfaces'; import { Node, Warning } from './interfaces';
import Compiler from './compile/Compiler'; import Component from './compile/Component';
const now = (typeof process !== 'undefined' && process.hrtime) const now = (typeof process !== 'undefined' && process.hrtime)
? () => { ? () => {
@ -73,14 +73,14 @@ export default class Stats {
this.currentChildren = this.currentTiming ? this.currentTiming.children : this.timings; this.currentChildren = this.currentTiming ? this.currentTiming.children : this.timings;
} }
render(compiler: Compiler) { render(component: Component) {
const timings = Object.assign({ const timings = Object.assign({
total: now() - this.startTime total: now() - this.startTime
}, collapseTimings(this.timings)); }, collapseTimings(this.timings));
// TODO would be good to have this info even // TODO would be good to have this info even
// if options.generate is false // if options.generate is false
const imports = compiler && compiler.imports.map(node => { const imports = component && component.imports.map(node => {
return { return {
source: node.source.value, source: node.source.value,
specifiers: node.specifiers.map(specifier => { specifiers: node.specifiers.map(specifier => {
@ -96,11 +96,11 @@ export default class Stats {
} }
}); });
const hooks: Record<string, boolean> = compiler && { const hooks: Record<string, boolean> = component && {
oncreate: !!compiler.templateProperties.oncreate, oncreate: !!component.templateProperties.oncreate,
ondestroy: !!compiler.templateProperties.ondestroy, ondestroy: !!component.templateProperties.ondestroy,
onstate: !!compiler.templateProperties.onstate, onstate: !!component.templateProperties.onstate,
onupdate: !!compiler.templateProperties.onupdate onupdate: !!component.templateProperties.onupdate
}; };
return { return {

@ -6,20 +6,19 @@ import { getLocator } from 'locate-character';
import Stats from '../Stats'; import Stats from '../Stats';
import deindent from '../utils/deindent'; import deindent from '../utils/deindent';
import CodeBuilder from '../utils/CodeBuilder'; import CodeBuilder from '../utils/CodeBuilder';
import flattenReference from '../utils/flattenReference';
import reservedNames from '../utils/reservedNames'; import reservedNames from '../utils/reservedNames';
import namespaces from '../utils/namespaces'; import namespaces from '../utils/namespaces';
import { removeNode, removeObjectKey } from '../utils/removeNode'; import { removeNode } from '../utils/removeNode';
import nodeToString from '../utils/nodeToString'; import nodeToString from '../utils/nodeToString';
import wrapModule from './wrapModule'; import wrapModule from './wrapModule';
import annotateWithScopes, { Scope } from '../utils/annotateWithScopes'; import annotateWithScopes from '../utils/annotateWithScopes';
import getName from '../utils/getName'; import getName from '../utils/getName';
import Stylesheet from '../css/Stylesheet'; import Stylesheet from '../css/Stylesheet';
import { test } from '../config'; import { test } from '../config';
import Fragment from './nodes/Fragment'; import Fragment from './nodes/Fragment';
import shared from './shared'; import shared from './shared';
import { DomTarget } from './dom/index'; import { DomTarget } from './dom';
import { SsrTarget } from './ssr/index'; import { SsrTarget } from './ssr';
import { Node, GenerateOptions, ShorthandImport, Ast, CompileOptions, CustomElementOptions } from '../interfaces'; import { Node, GenerateOptions, ShorthandImport, Ast, CompileOptions, CustomElementOptions } from '../interfaces';
interface Computation { interface Computation {
@ -79,7 +78,7 @@ function removeIndentation(
childKeys.EachBlock = childKeys.IfBlock = ['children', 'else']; childKeys.EachBlock = childKeys.IfBlock = ['children', 'else'];
childKeys.Attribute = ['value']; childKeys.Attribute = ['value'];
export default class Compiler { export default class Component {
stats: Stats; stats: Stats;
ast: Ast; ast: Ast;
@ -136,7 +135,6 @@ export default class Compiler {
stylesheet: Stylesheet, stylesheet: Stylesheet,
options: CompileOptions, options: CompileOptions,
stats: Stats, stats: Stats,
dom: boolean,
target: DomTarget | SsrTarget target: DomTarget | SsrTarget
) { ) {
stats.start('compile'); stats.start('compile');
@ -189,7 +187,7 @@ export default class Compiler {
this.computations = []; this.computations = [];
this.templateProperties = {}; this.templateProperties = {};
this.walkJs(dom); this.walkJs();
this.name = this.alias(name); this.name = this.alias(name);
if (options.customElement === true) { if (options.customElement === true) {
@ -266,7 +264,7 @@ export default class Compiler {
} else { } else {
let inlineHelpers = ''; let inlineHelpers = '';
const compiler = this; const component = this;
importedHelpers = []; importedHelpers = [];
@ -291,7 +289,7 @@ export default class Compiler {
const dependency = node.name; const dependency = node.name;
helpers.add(dependency); helpers.add(dependency);
const alias = compiler.alias(dependency); const alias = component.alias(dependency);
if (alias !== node.name) { if (alias !== node.name) {
code.overwrite(node.start, node.end, alias); code.overwrite(node.start, node.end, alias);
} }
@ -432,7 +430,7 @@ export default class Compiler {
}; };
} }
walkJs(dom: boolean) { walkJs() {
const { const {
code, code,
source, source,
@ -532,7 +530,13 @@ export default class Compiler {
`); `);
}; };
const addDeclaration = (key: string, node: Node, allowShorthandImport?: boolean, disambiguator?: string, conflicts?: Record<string, boolean>) => { const addDeclaration = (
key: string,
node: Node,
allowShorthandImport?: boolean,
disambiguator?: string,
conflicts?: Record<string, boolean>
) => {
const qualified = disambiguator ? `${disambiguator}-${key}` : key; const qualified = disambiguator ? `${disambiguator}-${key}` : key;
if (node.type === 'Identifier' && node.name === key) { if (node.type === 'Identifier' && node.name === key) {
@ -634,7 +638,7 @@ export default class Compiler {
addDeclaration('data', templateProperties.data.value); addDeclaration('data', templateProperties.data.value);
} }
if (templateProperties.events && dom) { if (templateProperties.events) {
templateProperties.events.value.properties.forEach((property: Node) => { templateProperties.events.value.properties.forEach((property: Node) => {
addDeclaration(getName(property.key), property.value, false, 'events'); addDeclaration(getName(property.key), property.value, false, 'events');
}); });
@ -646,7 +650,7 @@ export default class Compiler {
}); });
} }
if (templateProperties.methods && dom) { if (templateProperties.methods) {
addDeclaration('methods', templateProperties.methods.value); addDeclaration('methods', templateProperties.methods.value);
templateProperties.methods.value.properties.forEach(prop => { templateProperties.methods.value.properties.forEach(prop => {
@ -659,19 +663,19 @@ export default class Compiler {
this.namespace = namespaces[ns] || ns; this.namespace = namespaces[ns] || ns;
} }
if (templateProperties.oncreate && dom) { if (templateProperties.oncreate) {
addDeclaration('oncreate', templateProperties.oncreate.value); addDeclaration('oncreate', templateProperties.oncreate.value);
} }
if (templateProperties.ondestroy && dom) { if (templateProperties.ondestroy) {
addDeclaration('ondestroy', templateProperties.ondestroy.value); addDeclaration('ondestroy', templateProperties.ondestroy.value);
} }
if (templateProperties.onstate && dom) { if (templateProperties.onstate) {
addDeclaration('onstate', templateProperties.onstate.value); addDeclaration('onstate', templateProperties.onstate.value);
} }
if (templateProperties.onupdate && dom) { if (templateProperties.onupdate) {
addDeclaration('onupdate', templateProperties.onupdate.value); addDeclaration('onupdate', templateProperties.onupdate.value);
} }

@ -1,12 +1,12 @@
import CodeBuilder from '../../utils/CodeBuilder'; import CodeBuilder from '../../utils/CodeBuilder';
import deindent from '../../utils/deindent'; import deindent from '../../utils/deindent';
import { escape } from '../../utils/stringify'; import { escape } from '../../utils/stringify';
import Compiler from '../Compiler'; import Component from '../Component';
export interface BlockOptions { export interface BlockOptions {
parent?: Block; parent?: Block;
name: string; name: string;
compiler?: Compiler; component?: Component;
comment?: string; comment?: string;
key?: string; key?: string;
bindings?: Map<string, string>; bindings?: Map<string, string>;
@ -15,7 +15,7 @@ export interface BlockOptions {
export default class Block { export default class Block {
parent?: Block; parent?: Block;
compiler: Compiler; component: Component;
name: string; name: string;
comment?: string; comment?: string;
@ -58,7 +58,7 @@ export default class Block {
constructor(options: BlockOptions) { constructor(options: BlockOptions) {
this.parent = options.parent; this.parent = options.parent;
this.compiler = options.compiler; this.component = options.component;
this.name = options.name; this.name = options.name;
this.comment = options.comment; this.comment = options.comment;
@ -90,7 +90,7 @@ export default class Block {
this.hasOutroMethod = false; this.hasOutroMethod = false;
this.outros = 0; this.outros = 0;
this.getUniqueName = this.compiler.getUniqueNameMaker(); this.getUniqueName = this.component.getUniqueNameMaker();
this.variables = new Map(); this.variables = new Map();
this.aliases = new Map() this.aliases = new Map()
@ -128,11 +128,11 @@ export default class Block {
} }
addIntro() { addIntro() {
this.hasIntros = this.hasIntroMethod = this.compiler.target.hasIntroTransitions = true; this.hasIntros = this.hasIntroMethod = this.component.target.hasIntroTransitions = true;
} }
addOutro() { addOutro() {
this.hasOutros = this.hasOutroMethod = this.compiler.target.hasOutroTransitions = true; this.hasOutros = this.hasOutroMethod = this.component.target.hasOutroTransitions = true;
this.outros += 1; this.outros += 1;
} }
@ -167,7 +167,7 @@ export default class Block {
} }
toString() { toString() {
const { dev } = this.compiler.options; const { dev } = this.component.options;
if (this.hasIntroMethod || this.hasOutroMethod) { if (this.hasIntroMethod || this.hasOutroMethod) {
this.addVariable('#current'); this.addVariable('#current');
@ -202,7 +202,7 @@ export default class Block {
properties.addBlock(`c: @noop,`); properties.addBlock(`c: @noop,`);
} else { } else {
const hydrate = !this.builders.hydrate.isEmpty() && ( const hydrate = !this.builders.hydrate.isEmpty() && (
this.compiler.options.hydratable this.component.options.hydratable
? `this.h()` ? `this.h()`
: this.builders.hydrate : this.builders.hydrate
); );
@ -215,7 +215,7 @@ export default class Block {
`); `);
} }
if (this.compiler.options.hydratable) { if (this.component.options.hydratable) {
if (this.builders.claim.isEmpty() && this.builders.hydrate.isEmpty()) { if (this.builders.claim.isEmpty() && this.builders.hydrate.isEmpty()) {
properties.addBlock(`l: @noop,`); properties.addBlock(`l: @noop,`);
} else { } else {
@ -228,7 +228,7 @@ export default class Block {
} }
} }
if (this.compiler.options.hydratable && !this.builders.hydrate.isEmpty()) { if (this.component.options.hydratable && !this.builders.hydrate.isEmpty()) {
properties.addBlock(deindent` properties.addBlock(deindent`
${dev ? 'h: function hydrate' : 'h'}() { ${dev ? 'h: function hydrate' : 'h'}() {
${this.builders.hydrate} ${this.builders.hydrate}

@ -2,7 +2,7 @@ import deindent from '../../utils/deindent';
import { stringify, escape } from '../../utils/stringify'; import { stringify, escape } from '../../utils/stringify';
import CodeBuilder from '../../utils/CodeBuilder'; import CodeBuilder from '../../utils/CodeBuilder';
import globalWhitelist from '../../utils/globalWhitelist'; import globalWhitelist from '../../utils/globalWhitelist';
import Compiler from '../Compiler'; import Component from '../Component';
import Stylesheet from '../../css/Stylesheet'; import Stylesheet from '../../css/Stylesheet';
import Stats from '../../Stats'; import Stats from '../../Stats';
import Block from './Block'; import Block from './Block';
@ -36,19 +36,19 @@ export default function dom(
const format = options.format || 'es'; const format = options.format || 'es';
const target = new DomTarget(); const target = new DomTarget();
const compiler = new Compiler(ast, source, options.name || 'SvelteComponent', stylesheet, options, stats, true, target); const component = new Component(ast, source, options.name || 'SvelteComponent', stylesheet, options, stats, target);
const { const {
computations, computations,
name, name,
templateProperties, templateProperties,
namespace, namespace,
} = compiler; } = component;
compiler.fragment.build(); component.fragment.build();
const { block } = compiler.fragment; const { block } = component.fragment;
if (compiler.options.nestedTransitions) { if (component.options.nestedTransitions) {
block.hasOutroMethod = true; block.hasOutroMethod = true;
} }
@ -89,24 +89,24 @@ export default function dom(
}); });
} }
if (compiler.javascript) { if (component.javascript) {
builder.addBlock(compiler.javascript); builder.addBlock(component.javascript);
} }
if (compiler.options.dev) { if (component.options.dev) {
builder.addLine(`const ${compiler.fileVar} = ${JSON.stringify(compiler.file)};`); builder.addLine(`const ${component.fileVar} = ${JSON.stringify(component.file)};`);
} }
const css = compiler.stylesheet.render(options.filename, !compiler.customElement); const css = component.stylesheet.render(options.filename, !component.customElement);
const styles = compiler.stylesheet.hasStyles && stringify(options.dev ? const styles = component.stylesheet.hasStyles && stringify(options.dev ?
`${css.code}\n/*# sourceMappingURL=${css.map.toUrl()} */` : `${css.code}\n/*# sourceMappingURL=${css.map.toUrl()} */` :
css.code, { onlyEscapeAtSymbol: true }); css.code, { onlyEscapeAtSymbol: true });
if (styles && compiler.options.css !== false && !compiler.customElement) { if (styles && component.options.css !== false && !component.customElement) {
builder.addBlock(deindent` builder.addBlock(deindent`
function @add_css() { function @add_css() {
var style = @createElement("style"); var style = @createElement("style");
style.id = '${compiler.stylesheet.id}-style'; style.id = '${component.stylesheet.id}-style';
style.textContent = ${styles}; style.textContent = ${styles};
@append(document.head, style); @append(document.head, style);
} }
@ -130,10 +130,10 @@ export default function dom(
.join(',\n')} .join(',\n')}
}`; }`;
const debugName = `<${compiler.customElement ? compiler.tag : name}>`; const debugName = `<${component.customElement ? component.tag : name}>`;
// generate initial state object // generate initial state object
const expectedProperties = Array.from(compiler.expectedProperties); const expectedProperties = Array.from(component.expectedProperties);
const globals = expectedProperties.filter(prop => globalWhitelist.has(prop)); const globals = expectedProperties.filter(prop => globalWhitelist.has(prop));
const storeProps = expectedProperties.filter(prop => prop[0] === '$'); const storeProps = expectedProperties.filter(prop => prop[0] === '$');
const initialState = []; const initialState = [];
@ -158,32 +158,32 @@ export default function dom(
const constructorBody = deindent` const constructorBody = deindent`
${options.dev && `this._debugName = '${debugName}';`} ${options.dev && `this._debugName = '${debugName}';`}
${options.dev && !compiler.customElement && ${options.dev && !component.customElement &&
`if (!options || (!options.target && !options.root)) throw new Error("'target' is a required option");`} `if (!options || (!options.target && !options.root)) throw new Error("'target' is a required option");`}
@init(this, options); @init(this, options);
${templateProperties.store && `this.store = %store();`} ${templateProperties.store && `this.store = %store();`}
${compiler.usesRefs && `this.refs = {};`} ${component.usesRefs && `this.refs = {};`}
this._state = ${initialState.reduce((state, piece) => `@assign(${state}, ${piece})`)}; this._state = ${initialState.reduce((state, piece) => `@assign(${state}, ${piece})`)};
${storeProps.length > 0 && `this.store._add(this, [${storeProps.map(prop => `"${prop.slice(1)}"`)}]);`} ${storeProps.length > 0 && `this.store._add(this, [${storeProps.map(prop => `"${prop.slice(1)}"`)}]);`}
${target.metaBindings} ${target.metaBindings}
${computations.length && `this._recompute({ ${Array.from(computationDeps).map(dep => `${dep}: 1`).join(', ')} }, this._state);`} ${computations.length && `this._recompute({ ${Array.from(computationDeps).map(dep => `${dep}: 1`).join(', ')} }, this._state);`}
${options.dev && ${options.dev &&
Array.from(compiler.expectedProperties).map(prop => { Array.from(component.expectedProperties).map(prop => {
if (globalWhitelist.has(prop)) return; if (globalWhitelist.has(prop)) return;
if (computations.find(c => c.key === prop)) return; if (computations.find(c => c.key === prop)) return;
const message = compiler.components.has(prop) ? const message = component.components.has(prop) ?
`${debugName} expected to find '${prop}' in \`data\`, but found it in \`components\` instead` : `${debugName} expected to find '${prop}' in \`data\`, but found it in \`components\` instead` :
`${debugName} was created without expected data property '${prop}'`; `${debugName} was created without expected data property '${prop}'`;
const conditions = [`!('${prop}' in this._state)`]; const conditions = [`!('${prop}' in this._state)`];
if (compiler.customElement) conditions.push(`!('${prop}' in this.attributes)`); if (component.customElement) conditions.push(`!('${prop}' in this.attributes)`);
return `if (${conditions.join(' && ')}) console.warn("${message}");` return `if (${conditions.join(' && ')}) console.warn("${message}");`
})} })}
${compiler.bindingGroups.length && ${component.bindingGroups.length &&
`this._bindingGroups = [${Array(compiler.bindingGroups.length).fill('[]').join(', ')}];`} `this._bindingGroups = [${Array(component.bindingGroups.length).fill('[]').join(', ')}];`}
this._intro = ${compiler.options.skipIntroByDefault ? '!!options.intro' : 'true'}; this._intro = ${component.options.skipIntroByDefault ? '!!options.intro' : 'true'};
${templateProperties.onstate && `this._handlers.state = [%onstate];`} ${templateProperties.onstate && `this._handlers.state = [%onstate];`}
${templateProperties.onupdate && `this._handlers.update = [%onupdate];`} ${templateProperties.onupdate && `this._handlers.update = [%onupdate];`}
@ -194,15 +194,15 @@ export default function dom(
}];` }];`
)} )}
${compiler.slots.size && `this._slotted = options.slots || {};`} ${component.slots.size && `this._slotted = options.slots || {};`}
${compiler.customElement ? ${component.customElement ?
deindent` deindent`
this.attachShadow({ mode: 'open' }); this.attachShadow({ mode: 'open' });
${css.code && `this.shadowRoot.innerHTML = \`<style>${escape(css.code, { onlyEscapeAtSymbol: true }).replace(/\\/g, '\\\\')}${options.dev ? `\n/*# sourceMappingURL=${css.map.toUrl()} */` : ''}</style>\`;`} ${css.code && `this.shadowRoot.innerHTML = \`<style>${escape(css.code, { onlyEscapeAtSymbol: true }).replace(/\\/g, '\\\\')}${options.dev ? `\n/*# sourceMappingURL=${css.map.toUrl()} */` : ''}</style>\`;`}
` : ` :
(compiler.stylesheet.hasStyles && options.css !== false && (component.stylesheet.hasStyles && options.css !== false &&
`if (!document.getElementById("${compiler.stylesheet.id}-style")) @add_css();`) `if (!document.getElementById("${component.stylesheet.id}-style")) @add_css();`)
} }
${templateProperties.onstate && `%onstate.call(this, { changed: @assignTrue({}, this._state), current: this._state });`} ${templateProperties.onstate && `%onstate.call(this, { changed: @assignTrue({}, this._state), current: this._state });`}
@ -216,14 +216,14 @@ export default function dom(
}); });
`} `}
${compiler.customElement ? deindent` ${component.customElement ? deindent`
this._fragment.c(); this._fragment.c();
this._fragment.${block.hasIntroMethod ? 'i' : 'm'}(this.shadowRoot, null); this._fragment.${block.hasIntroMethod ? 'i' : 'm'}(this.shadowRoot, null);
if (options.target) this._mount(options.target, options.anchor); if (options.target) this._mount(options.target, options.anchor);
` : deindent` ` : deindent`
if (options.target) { if (options.target) {
${compiler.options.hydratable ${component.options.hydratable
? deindent` ? deindent`
var nodes = @children(options.target); var nodes = @children(options.target);
options.hydrate ? this._fragment.l(nodes) : this._fragment.c(); options.hydrate ? this._fragment.l(nodes) : this._fragment.c();
@ -234,16 +234,16 @@ export default function dom(
this._fragment.c();`} this._fragment.c();`}
this._mount(options.target, options.anchor); this._mount(options.target, options.anchor);
${(compiler.hasComponents || target.hasComplexBindings || hasInitHooks || target.hasIntroTransitions) && ${(component.hasComponents || target.hasComplexBindings || hasInitHooks || target.hasIntroTransitions) &&
`@flush(this);`} `@flush(this);`}
} }
`} `}
${compiler.options.skipIntroByDefault && `this._intro = true;`} ${component.options.skipIntroByDefault && `this._intro = true;`}
`; `;
if (compiler.customElement) { if (component.customElement) {
const props = compiler.props || Array.from(compiler.expectedProperties); const props = component.props || Array.from(component.expectedProperties);
builder.addBlock(deindent` builder.addBlock(deindent`
class ${name} extends HTMLElement { class ${name} extends HTMLElement {
@ -266,7 +266,7 @@ export default function dom(
} }
`).join('\n\n')} `).join('\n\n')}
${compiler.slots.size && deindent` ${component.slots.size && deindent`
connectedCallback() { connectedCallback() {
Object.keys(this._slotted).forEach(key => { Object.keys(this._slotted).forEach(key => {
this.appendChild(this._slotted[key]); this.appendChild(this._slotted[key]);
@ -277,7 +277,7 @@ export default function dom(
this.set({ [attr]: newValue }); this.set({ [attr]: newValue });
} }
${(compiler.hasComponents || target.hasComplexBindings || templateProperties.oncreate || target.hasIntroTransitions) && deindent` ${(component.hasComponents || target.hasComplexBindings || templateProperties.oncreate || target.hasIntroTransitions) && deindent`
connectedCallback() { connectedCallback() {
@flush(this); @flush(this);
} }
@ -292,7 +292,7 @@ export default function dom(
} }
}); });
customElements.define("${compiler.tag}", ${name}); customElements.define("${component.tag}", ${name});
`); `);
} else { } else {
builder.addBlock(deindent` builder.addBlock(deindent`
@ -332,8 +332,8 @@ export default function dom(
let result = builder.toString(); let result = builder.toString();
return compiler.generate(result, options, { return component.generate(result, options, {
banner: `/* ${compiler.file ? `${compiler.file} ` : ``}generated by Svelte v${"__VERSION__"} */`, banner: `/* ${component.file ? `${component.file} ` : ``}generated by Svelte v${"__VERSION__"} */`,
sharedPath, sharedPath,
name, name,
format, format,

@ -6,13 +6,13 @@ export default class Action extends Node {
name: string; name: string;
expression: Expression; expression: Expression;
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.name = info.name; this.name = info.name;
this.expression = info.expression this.expression = info.expression
? new Expression(compiler, this, scope, info.expression) ? new Expression(component, this, scope, info.expression)
: null; : null;
} }
} }

@ -7,13 +7,13 @@ export default class Animation extends Node {
name: string; name: string;
expression: Expression; expression: Expression;
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.name = info.name; this.name = info.name;
this.expression = info.expression this.expression = info.expression
? new Expression(compiler, this, scope, info.expression) ? new Expression(component, this, scope, info.expression)
: null; : null;
} }

@ -2,7 +2,7 @@ import deindent from '../../utils/deindent';
import { escape, escapeTemplate, stringify } from '../../utils/stringify'; import { escape, escapeTemplate, stringify } from '../../utils/stringify';
import fixAttributeCasing from '../../utils/fixAttributeCasing'; import fixAttributeCasing from '../../utils/fixAttributeCasing';
import addToSet from '../../utils/addToSet'; import addToSet from '../../utils/addToSet';
import Compiler from '../Compiler'; import Component from '../Component';
import Node from './shared/Node'; import Node from './shared/Node';
import Element from './Element'; import Element from './Element';
import Text from './Text'; import Text from './Text';
@ -19,7 +19,7 @@ export default class Attribute extends Node {
start: number; start: number;
end: number; end: number;
compiler: Compiler; component: Component;
parent: Element; parent: Element;
name: string; name: string;
isSpread: boolean; isSpread: boolean;
@ -31,8 +31,8 @@ export default class Attribute extends Node {
chunks: (Text | Expression)[]; chunks: (Text | Expression)[];
dependencies: Set<string>; dependencies: Set<string>;
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
if (info.type === 'Spread') { if (info.type === 'Spread') {
this.name = null; this.name = null;
@ -40,7 +40,7 @@ export default class Attribute extends Node {
this.isTrue = false; this.isTrue = false;
this.isSynthetic = false; this.isSynthetic = false;
this.expression = new Expression(compiler, this, scope, info.expression); this.expression = new Expression(component, this, scope, info.expression);
this.dependencies = this.expression.dependencies; this.dependencies = this.expression.dependencies;
this.chunks = null; this.chunks = null;
@ -60,7 +60,7 @@ export default class Attribute extends Node {
: info.value.map(node => { : info.value.map(node => {
if (node.type === 'Text') return node; if (node.type === 'Text') return node;
const expression = new Expression(compiler, this, scope, node.expression); const expression = new Expression(component, this, scope, node.expression);
addToSet(this.dependencies, expression.dependencies); addToSet(this.dependencies, expression.dependencies);
return expression; return expression;
@ -136,9 +136,9 @@ export default class Attribute extends Node {
? '@setXlinkAttribute' ? '@setXlinkAttribute'
: '@setAttribute'; : '@setAttribute';
const isLegacyInputType = this.compiler.options.legacy && name === 'type' && this.parent.name === 'input'; const isLegacyInputType = this.component.options.legacy && name === 'type' && this.parent.name === 'input';
const isDataSet = /^data-/.test(name) && !this.compiler.options.legacy && !node.namespace; const isDataSet = /^data-/.test(name) && !this.component.options.legacy && !node.namespace;
const camelCaseName = isDataSet ? name.replace('data-', '').replace(/(-\w)/g, function (m) { const camelCaseName = isDataSet ? name.replace('data-', '').replace(/(-\w)/g, function (m) {
return m[1].toUpperCase(); return m[1].toUpperCase();
}) : name; }) : name;

@ -17,18 +17,18 @@ export default class AwaitBlock extends Node {
then: ThenBlock; then: ThenBlock;
catch: CatchBlock; catch: CatchBlock;
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.expression = new Expression(compiler, this, scope, info.expression); this.expression = new Expression(component, this, scope, info.expression);
const deps = this.expression.dependencies; const deps = this.expression.dependencies;
this.value = info.value; this.value = info.value;
this.error = info.error; this.error = info.error;
this.pending = new PendingBlock(compiler, this, scope, info.pending); this.pending = new PendingBlock(component, this, scope, info.pending);
this.then = new ThenBlock(compiler, this, scope.add(this.value, deps), info.then); this.then = new ThenBlock(component, this, scope.add(this.value, deps), info.then);
this.catch = new CatchBlock(compiler, this, scope.add(this.error, deps), info.catch); this.catch = new CatchBlock(component, this, scope.add(this.error, deps), info.catch);
} }
init( init(
@ -49,12 +49,12 @@ export default class AwaitBlock extends Node {
const child = this[status]; const child = this[status];
child.block = block.child({ child.block = block.child({
comment: createDebuggingComment(child, this.compiler), comment: createDebuggingComment(child, this.component),
name: this.compiler.getUniqueName(`create_${status}_block`) name: this.component.getUniqueName(`create_${status}_block`)
}); });
child.initChildren(child.block, stripWhitespace, nextSibling); child.initChildren(child.block, stripWhitespace, nextSibling);
this.compiler.target.blocks.push(child.block); this.component.target.blocks.push(child.block);
if (child.block.dependencies.size > 0) { if (child.block.dependencies.size > 0) {
isDynamic = true; isDynamic = true;
@ -77,7 +77,7 @@ export default class AwaitBlock extends Node {
this.then.block.hasOutroMethod = hasOutros; this.then.block.hasOutroMethod = hasOutros;
this.catch.block.hasOutroMethod = hasOutros; this.catch.block.hasOutroMethod = hasOutros;
if (hasOutros && this.compiler.options.nestedTransitions) block.addOutro(); if (hasOutros && this.component.options.nestedTransitions) block.addOutro();
} }
build( build(
@ -171,7 +171,7 @@ export default class AwaitBlock extends Node {
`); `);
} }
if (this.pending.block.hasOutroMethod && this.compiler.options.nestedTransitions) { if (this.pending.block.hasOutroMethod && this.component.options.nestedTransitions) {
const countdown = block.getUniqueName('countdown'); const countdown = block.getUniqueName('countdown');
block.builders.outro.addBlock(deindent` block.builders.outro.addBlock(deindent`
const ${countdown} = @callAfter(#outrocallback, 3); const ${countdown} = @callAfter(#outrocallback, 3);
@ -196,7 +196,7 @@ export default class AwaitBlock extends Node {
} }
ssr() { ssr() {
const target: SsrTarget = <SsrTarget>this.compiler.target; const target: SsrTarget = <SsrTarget>this.component.target;
const { snippet } = this.expression; const { snippet } = this.expression;
target.append('${(function(__value) { if(@isPromise(__value)) return `'); target.append('${(function(__value) { if(@isPromise(__value)) return `');

@ -3,7 +3,7 @@ import Element from './Element';
import getObject from '../../utils/getObject'; import getObject from '../../utils/getObject';
import getTailSnippet from '../../utils/getTailSnippet'; import getTailSnippet from '../../utils/getTailSnippet';
import flattenReference from '../../utils/flattenReference'; import flattenReference from '../../utils/flattenReference';
import Compiler from '../Compiler'; import Component from '../Component';
import Block from '../dom/Block'; import Block from '../dom/Block';
import Expression from './shared/Expression'; import Expression from './shared/Expression';
import { dimensions } from '../../utils/patterns'; import { dimensions } from '../../utils/patterns';
@ -26,11 +26,11 @@ export default class Binding extends Node {
obj: string; obj: string;
prop: string; prop: string;
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.name = info.name; this.name = info.name;
this.value = new Expression(compiler, this, scope, info.value); this.value = new Expression(component, this, scope, info.value);
let obj; let obj;
let prop; let prop;
@ -78,7 +78,7 @@ export default class Binding extends Node {
// TODO should this happen in preprocess? // TODO should this happen in preprocess?
const dependencies = new Set(this.value.dependencies); const dependencies = new Set(this.value.dependencies);
this.value.dependencies.forEach((prop: string) => { this.value.dependencies.forEach((prop: string) => {
const indirectDependencies = this.compiler.indirectDependencies.get(prop); const indirectDependencies = this.component.indirectDependencies.get(prop);
if (indirectDependencies) { if (indirectDependencies) {
indirectDependencies.forEach(indirectDependency => { indirectDependencies.forEach(indirectDependency => {
dependencies.add(indirectDependency); dependencies.add(indirectDependency);
@ -87,8 +87,8 @@ export default class Binding extends Node {
}); });
// view to model // view to model
const valueFromDom = getValueFromDom(this.compiler, node, this); const valueFromDom = getValueFromDom(this.component, node, this);
const handler = getEventHandler(this, this.compiler, block, name, snippet, dependencies, valueFromDom); const handler = getEventHandler(this, this.component, block, name, snippet, dependencies, valueFromDom);
// model to view // model to view
let updateDom = getDomUpdater(node, this, snippet); let updateDom = getDomUpdater(node, this, snippet);
@ -96,7 +96,7 @@ export default class Binding extends Node {
// special cases // special cases
if (this.name === 'group') { if (this.name === 'group') {
const bindingGroup = getBindingGroup(this.compiler, this.value.node); const bindingGroup = getBindingGroup(this.component, this.value.node);
block.builders.hydrate.addLine( block.builders.hydrate.addLine(
`#component._bindingGroups[${bindingGroup}].push(${node.var});` `#component._bindingGroups[${bindingGroup}].push(${node.var});`
@ -184,16 +184,16 @@ function getDomUpdater(
return `${node.var}.${binding.name} = ${snippet};`; return `${node.var}.${binding.name} = ${snippet};`;
} }
function getBindingGroup(compiler: Compiler, value: Node) { function getBindingGroup(component: Component, value: Node) {
const { parts } = flattenReference(value); // TODO handle cases involving computed member expressions const { parts } = flattenReference(value); // TODO handle cases involving computed member expressions
const keypath = parts.join('.'); const keypath = parts.join('.');
// TODO handle contextual bindings — `keypath` should include unique ID of // TODO handle contextual bindings — `keypath` should include unique ID of
// each block that provides context // each block that provides context
let index = compiler.bindingGroups.indexOf(keypath); let index = component.bindingGroups.indexOf(keypath);
if (index === -1) { if (index === -1) {
index = compiler.bindingGroups.length; index = component.bindingGroups.length;
compiler.bindingGroups.push(keypath); component.bindingGroups.push(keypath);
} }
return index; return index;
@ -201,7 +201,7 @@ function getBindingGroup(compiler: Compiler, value: Node) {
function getEventHandler( function getEventHandler(
binding: Binding, binding: Binding,
compiler: Compiler, component: Component,
block: Block, block: Block,
name: string, name: string,
snippet: string, snippet: string,
@ -235,9 +235,9 @@ function getEventHandler(
// Svelte tries to `set()` a computed property, which throws an // Svelte tries to `set()` a computed property, which throws an
// error in dev mode. a) it's possible that we should be // error in dev mode. a) it's possible that we should be
// replacing computations with *their* dependencies, and b) // replacing computations with *their* dependencies, and b)
// we should probably populate `compiler.target.readonly` sooner so // we should probably populate `component.target.readonly` sooner so
// that we don't have to do the `.some()` here // that we don't have to do the `.some()` here
dependencies = dependencies.filter(prop => !compiler.computations.some(computation => computation.key === prop)); dependencies = dependencies.filter(prop => !component.computations.some(computation => computation.key === prop));
return { return {
usesContext: false, usesContext: false,
@ -271,7 +271,7 @@ function getEventHandler(
} }
function getValueFromDom( function getValueFromDom(
compiler: Compiler, component: Component,
node: Element, node: Element,
binding: Node binding: Node
) { ) {
@ -286,7 +286,7 @@ function getValueFromDom(
// <input type='checkbox' bind:group='foo'> // <input type='checkbox' bind:group='foo'>
if (binding.name === 'group') { if (binding.name === 'group') {
const bindingGroup = getBindingGroup(compiler, binding.value.node); const bindingGroup = getBindingGroup(component, binding.value.node);
if (type === 'checkbox') { if (type === 'checkbox') {
return `@getBindingGroupValue(#component._bindingGroups[${bindingGroup}])`; return `@getBindingGroupValue(#component._bindingGroups[${bindingGroup}])`;
} }

@ -6,8 +6,8 @@ export default class CatchBlock extends Node {
block: Block; block: Block;
children: Node[]; children: Node[];
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.children = mapChildren(compiler, parent, scope, info.children); this.children = mapChildren(component, parent, scope, info.children);
} }
} }

@ -6,13 +6,13 @@ export default class Class extends Node {
name: string; name: string;
expression: Expression; expression: Expression;
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.name = info.name; this.name = info.name;
this.expression = info.expression this.expression = info.expression
? new Expression(compiler, this, scope, info.expression) ? new Expression(component, this, scope, info.expression)
: null; : null;
} }
} }

@ -4,15 +4,15 @@ export default class Comment extends Node {
type: 'Comment'; type: 'Comment';
data: string; data: string;
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.data = info.data; this.data = info.data;
} }
ssr() { ssr() {
// Allow option to preserve comments, otherwise ignore // Allow option to preserve comments, otherwise ignore
if (this.compiler.options.preserveComments) { if (this.component.options.preserveComments) {
this.compiler.target.append(`<!--${this.data}-->`); this.component.target.append(`<!--${this.data}-->`);
} }
} }
} }

@ -9,11 +9,11 @@ import { stringify } from '../../utils/stringify';
export default class DebugTag extends Node { export default class DebugTag extends Node {
expressions: Expression[]; expressions: Expression[];
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.expressions = info.identifiers.map(node => { this.expressions = info.identifiers.map(node => {
return new Expression(compiler, parent, scope, node); return new Expression(component, parent, scope, node);
}); });
} }
@ -22,9 +22,9 @@ export default class DebugTag extends Node {
parentNode: string, parentNode: string,
parentNodes: string, parentNodes: string,
) { ) {
if (!this.compiler.options.dev) return; if (!this.component.options.dev) return;
const { code } = this.compiler; const { code } = this.component;
if (this.expressions.length === 0) { if (this.expressions.length === 0) {
// Debug all // Debug all
@ -36,7 +36,7 @@ export default class DebugTag extends Node {
block.builders.create.addLine(statement); block.builders.create.addLine(statement);
block.builders.update.addLine(statement); block.builders.update.addLine(statement);
} else { } else {
const { code } = this.compiler; const { code } = this.component;
code.overwrite(this.start + 1, this.start + 7, 'log', { code.overwrite(this.start + 1, this.start + 7, 'log', {
storeName: true storeName: true
}); });
@ -70,10 +70,10 @@ export default class DebugTag extends Node {
} }
ssr() { ssr() {
if (!this.compiler.options.dev) return; if (!this.component.options.dev) return;
const filename = this.compiler.file || null; const filename = this.component.file || null;
const { line, column } = this.compiler.locate(this.start + 1); const { line, column } = this.component.locate(this.start + 1);
const obj = this.expressions.length === 0 const obj = this.expressions.length === 0
? `ctx` ? `ctx`
@ -84,6 +84,6 @@ export default class DebugTag extends Node {
const str = '${@debug(' + `${filename && stringify(filename)}, ${line}, ${column}, ${obj})}`; const str = '${@debug(' + `${filename && stringify(filename)}, ${line}, ${column}, ${obj})}`;
this.compiler.target.append(str); this.component.target.append(str);
} }
} }

@ -24,10 +24,10 @@ export default class EachBlock extends Node {
children: Node[]; children: Node[];
else?: ElseBlock; else?: ElseBlock;
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.expression = new Expression(compiler, this, scope, info.expression); this.expression = new Expression(component, this, scope, info.expression);
this.context = info.context.name || 'each'; // TODO this is used to facilitate binding; currently fails with destructuring this.context = info.context.name || 'each'; // TODO this is used to facilitate binding; currently fails with destructuring
this.index = info.index; this.index = info.index;
@ -41,7 +41,7 @@ export default class EachBlock extends Node {
}); });
this.key = info.key this.key = info.key
? new Expression(compiler, this, this.scope, info.key) ? new Expression(component, this, this.scope, info.key)
: null; : null;
if (this.index) { if (this.index) {
@ -50,10 +50,10 @@ export default class EachBlock extends Node {
this.scope.add(this.index, dependencies); this.scope.add(this.index, dependencies);
} }
this.children = mapChildren(compiler, this, this.scope, info.children); this.children = mapChildren(component, this, this.scope, info.children);
this.else = info.else this.else = info.else
? new ElseBlock(compiler, this, this.scope, info.else) ? new ElseBlock(component, this, this.scope, info.else)
: null; : null;
} }
@ -66,22 +66,22 @@ export default class EachBlock extends Node {
this.var = block.getUniqueName(`each`); this.var = block.getUniqueName(`each`);
this.iterations = block.getUniqueName(`${this.var}_blocks`); this.iterations = block.getUniqueName(`${this.var}_blocks`);
this.get_each_context = this.compiler.getUniqueName(`get_${this.var}_context`); this.get_each_context = this.component.getUniqueName(`get_${this.var}_context`);
const { dependencies } = this.expression; const { dependencies } = this.expression;
block.addDependencies(dependencies); block.addDependencies(dependencies);
this.block = block.child({ this.block = block.child({
comment: createDebuggingComment(this, this.compiler), comment: createDebuggingComment(this, this.component),
name: this.compiler.getUniqueName('create_each_block'), name: this.component.getUniqueName('create_each_block'),
key: this.key, key: this.key,
bindings: new Map(block.bindings) bindings: new Map(block.bindings)
}); });
this.each_block_value = this.compiler.getUniqueName('each_value'); this.each_block_value = this.component.getUniqueName('each_value');
const indexName = this.index || this.compiler.getUniqueName(`${this.context}_index`); const indexName = this.index || this.component.getUniqueName(`${this.context}_index`);
this.contexts.forEach(prop => { this.contexts.forEach(prop => {
this.block.bindings.set(prop.key.name, `ctx.${this.each_block_value}[ctx.${indexName}]${prop.tail}`); this.block.bindings.set(prop.key.name, `ctx.${this.each_block_value}[ctx.${indexName}]${prop.tail}`);
@ -99,18 +99,18 @@ export default class EachBlock extends Node {
`child_ctx.${indexName} = i;` `child_ctx.${indexName} = i;`
); );
this.compiler.target.blocks.push(this.block); this.component.target.blocks.push(this.block);
this.initChildren(this.block, stripWhitespace, nextSibling); this.initChildren(this.block, stripWhitespace, nextSibling);
block.addDependencies(this.block.dependencies); block.addDependencies(this.block.dependencies);
this.block.hasUpdateMethod = this.block.dependencies.size > 0; this.block.hasUpdateMethod = this.block.dependencies.size > 0;
if (this.else) { if (this.else) {
this.else.block = block.child({ this.else.block = block.child({
comment: createDebuggingComment(this.else, this.compiler), comment: createDebuggingComment(this.else, this.component),
name: this.compiler.getUniqueName(`${this.block.name}_else`), name: this.component.getUniqueName(`${this.block.name}_else`),
}); });
this.compiler.target.blocks.push(this.else.block); this.component.target.blocks.push(this.else.block);
this.else.initChildren( this.else.initChildren(
this.else.block, this.else.block,
stripWhitespace, stripWhitespace,
@ -131,7 +131,7 @@ export default class EachBlock extends Node {
) { ) {
if (this.children.length === 0) return; if (this.children.length === 0) return;
const { compiler } = this; const { component } = this;
const each = this.var; const each = this.var;
@ -146,8 +146,8 @@ export default class EachBlock extends Node {
// hack the sourcemap, so that if data is missing the bug // hack the sourcemap, so that if data is missing the bug
// is easy to find // is easy to find
let c = this.start + 2; let c = this.start + 2;
while (compiler.source[c] !== 'e') c += 1; while (component.source[c] !== 'e') c += 1;
compiler.code.overwrite(c, c + 4, 'length'); component.code.overwrite(c, c + 4, 'length');
const length = `[✂${c}-${c+4}✂]`; const length = `[✂${c}-${c+4}✂]`;
const mountOrIntro = (this.block.hasIntroMethod || this.block.hasOutroMethod) ? 'i' : 'm'; const mountOrIntro = (this.block.hasIntroMethod || this.block.hasOutroMethod) ? 'i' : 'm';
@ -164,7 +164,7 @@ export default class EachBlock extends Node {
block.builders.init.addLine(`var ${this.each_block_value} = ${snippet};`); block.builders.init.addLine(`var ${this.each_block_value} = ${snippet};`);
this.compiler.target.blocks.push(deindent` this.component.target.blocks.push(deindent`
function ${this.get_each_context}(ctx, list, i) { function ${this.get_each_context}(ctx, list, i) {
const child_ctx = Object.create(ctx); const child_ctx = Object.create(ctx);
${this.contextProps} ${this.contextProps}
@ -188,7 +188,7 @@ export default class EachBlock extends Node {
} }
if (this.else) { if (this.else) {
const each_block_else = compiler.getUniqueName(`${each}_else`); const each_block_else = component.getUniqueName(`${each}_else`);
const mountOrIntro = (this.else.block.hasIntroMethod || this.else.block.hasOutroMethod) ? 'i' : 'm'; const mountOrIntro = (this.else.block.hasIntroMethod || this.else.block.hasOutroMethod) ? 'i' : 'm';
block.builders.init.addLine(`var ${each_block_else} = null;`); block.builders.init.addLine(`var ${each_block_else} = null;`);
@ -331,7 +331,7 @@ export default class EachBlock extends Node {
${this.block.hasAnimation && `for (let #i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].a();`} ${this.block.hasAnimation && `for (let #i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].a();`}
`); `);
if (this.block.hasOutros && this.compiler.options.nestedTransitions) { if (this.block.hasOutros && this.component.options.nestedTransitions) {
const countdown = block.getUniqueName('countdown'); const countdown = block.getUniqueName('countdown');
block.builders.outro.addBlock(deindent` block.builders.outro.addBlock(deindent`
const ${countdown} = @callAfter(#outrocallback, ${blocks}.length); const ${countdown} = @callAfter(#outrocallback, ${blocks}.length);
@ -477,7 +477,7 @@ export default class EachBlock extends Node {
`); `);
} }
if (outroBlock && this.compiler.options.nestedTransitions) { if (outroBlock && this.component.options.nestedTransitions) {
const countdown = block.getUniqueName('countdown'); const countdown = block.getUniqueName('countdown');
block.builders.outro.addBlock(deindent` block.builders.outro.addBlock(deindent`
${iterations} = ${iterations}.filter(Boolean); ${iterations} = ${iterations}.filter(Boolean);
@ -495,7 +495,7 @@ export default class EachBlock extends Node {
} }
ssr() { ssr() {
const { compiler } = this; const { component } = this;
const { snippet } = this.expression; const { snippet } = this.expression;
const props = this.contexts.map(prop => `${prop.key.name}: item${prop.tail}`); const props = this.contexts.map(prop => `${prop.key.name}: item${prop.tail}`);
@ -505,23 +505,23 @@ export default class EachBlock extends Node {
: `item => Object.assign({}, ctx, { ${props.join(', ')} })`; : `item => Object.assign({}, ctx, { ${props.join(', ')} })`;
const open = `\${ ${this.else ? `${snippet}.length ? ` : ''}@each(${snippet}, ${getContext}, ctx => \``; const open = `\${ ${this.else ? `${snippet}.length ? ` : ''}@each(${snippet}, ${getContext}, ctx => \``;
compiler.target.append(open); component.target.append(open);
this.children.forEach((child: Node) => { this.children.forEach((child: Node) => {
child.ssr(); child.ssr();
}); });
const close = `\`)`; const close = `\`)`;
compiler.target.append(close); component.target.append(close);
if (this.else) { if (this.else) {
compiler.target.append(` : \``); component.target.append(` : \``);
this.else.children.forEach((child: Node) => { this.else.children.forEach((child: Node) => {
child.ssr(); child.ssr();
}); });
compiler.target.append(`\``); component.target.append(`\``);
} }
compiler.target.append('}'); component.target.append('}');
} }
} }

@ -6,7 +6,7 @@ import validCalleeObjects from '../../utils/validCalleeObjects';
import reservedNames from '../../utils/reservedNames'; import reservedNames from '../../utils/reservedNames';
import fixAttributeCasing from '../../utils/fixAttributeCasing'; import fixAttributeCasing from '../../utils/fixAttributeCasing';
import { quoteNameIfNecessary, quotePropIfNecessary } from '../../utils/quoteIfNecessary'; import { quoteNameIfNecessary, quotePropIfNecessary } from '../../utils/quoteIfNecessary';
import Compiler from '../Compiler'; import Component from '../Component';
import Node from './shared/Node'; import Node from './shared/Node';
import Block from '../dom/Block'; import Block from '../dom/Block';
import Attribute from './Attribute'; import Attribute from './Attribute';
@ -80,15 +80,15 @@ export default class Element extends Node {
ref: string; ref: string;
namespace: string; namespace: string;
constructor(compiler, parent, scope, info: any) { constructor(component, parent, scope, info: any) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.name = info.name; this.name = info.name;
this.scope = scope; this.scope = scope;
const parentElement = parent.findNearest(/^Element/); const parentElement = parent.findNearest(/^Element/);
this.namespace = this.name === 'svg' ? this.namespace = this.name === 'svg' ?
namespaces.svg : namespaces.svg :
parentElement ? parentElement.namespace : this.compiler.namespace; parentElement ? parentElement.namespace : this.component.namespace;
this.attributes = []; this.attributes = [];
this.actions = []; this.actions = [];
@ -134,7 +134,7 @@ export default class Element extends Node {
info.attributes.forEach(node => { info.attributes.forEach(node => {
switch (node.type) { switch (node.type) {
case 'Action': case 'Action':
this.actions.push(new Action(compiler, this, scope, node)); this.actions.push(new Action(component, this, scope, node));
break; break;
case 'Attribute': case 'Attribute':
@ -142,36 +142,36 @@ export default class Element extends Node {
// special case // special case
if (node.name === 'xmlns') this.namespace = node.value[0].data; if (node.name === 'xmlns') this.namespace = node.value[0].data;
this.attributes.push(new Attribute(compiler, this, scope, node)); this.attributes.push(new Attribute(component, this, scope, node));
break; break;
case 'Binding': case 'Binding':
this.bindings.push(new Binding(compiler, this, scope, node)); this.bindings.push(new Binding(component, this, scope, node));
break; break;
case 'Class': case 'Class':
this.classes.push(new Class(compiler, this, scope, node)); this.classes.push(new Class(component, this, scope, node));
break; break;
case 'EventHandler': case 'EventHandler':
this.handlers.push(new EventHandler(compiler, this, scope, node)); this.handlers.push(new EventHandler(component, this, scope, node));
break; break;
case 'Transition': case 'Transition':
const transition = new Transition(compiler, this, scope, node); const transition = new Transition(component, this, scope, node);
if (node.intro) this.intro = transition; if (node.intro) this.intro = transition;
if (node.outro) this.outro = transition; if (node.outro) this.outro = transition;
break; break;
case 'Animation': case 'Animation':
this.animation = new Animation(compiler, this, scope, node); this.animation = new Animation(component, this, scope, node);
break; break;
case 'Ref': case 'Ref':
// TODO catch this in validation // TODO catch this in validation
if (this.ref) throw new Error(`Duplicate refs`); if (this.ref) throw new Error(`Duplicate refs`);
compiler.usesRefs = true component.usesRefs = true
this.ref = node.name; this.ref = node.name;
break; break;
@ -180,9 +180,9 @@ export default class Element extends Node {
} }
}); });
this.children = mapChildren(compiler, this, scope, info.children); this.children = mapChildren(component, this, scope, info.children);
compiler.stylesheet.apply(this); component.stylesheet.apply(this);
} }
init( init(
@ -190,7 +190,7 @@ export default class Element extends Node {
stripWhitespace: boolean, stripWhitespace: boolean,
nextSibling: Node nextSibling: Node
) { ) {
if (this.name === 'slot' || this.name === 'option' || this.compiler.options.dev) { if (this.name === 'slot' || this.name === 'option' || this.component.options.dev) {
this.cannotUseInnerHTML(); this.cannotUseInnerHTML();
} }
@ -217,7 +217,7 @@ export default class Element extends Node {
if (select && select.selectBindingDependencies) { if (select && select.selectBindingDependencies) {
select.selectBindingDependencies.forEach(prop => { select.selectBindingDependencies.forEach(prop => {
attr.dependencies.forEach((dependency: string) => { attr.dependencies.forEach((dependency: string) => {
this.compiler.indirectDependencies.get(prop).add(dependency); this.component.indirectDependencies.get(prop).add(dependency);
}); });
}); });
} }
@ -276,7 +276,7 @@ export default class Element extends Node {
const dependencies = binding.value.dependencies; const dependencies = binding.value.dependencies;
this.selectBindingDependencies = dependencies; this.selectBindingDependencies = dependencies;
dependencies.forEach((prop: string) => { dependencies.forEach((prop: string) => {
this.compiler.indirectDependencies.set(prop, new Set()); this.component.indirectDependencies.set(prop, new Set());
}); });
} else { } else {
this.selectBindingDependencies = null; this.selectBindingDependencies = null;
@ -303,11 +303,11 @@ export default class Element extends Node {
parentNode: string, parentNode: string,
parentNodes: string parentNodes: string
) { ) {
const { compiler } = this; const { component } = this;
if (this.name === 'slot') { if (this.name === 'slot') {
const slotName = this.getStaticAttributeValue('name') || 'default'; const slotName = this.getStaticAttributeValue('name') || 'default';
this.compiler.slots.add(slotName); this.component.slots.add(slotName);
} }
if (this.name === 'noscript') return; if (this.name === 'noscript') return;
@ -327,10 +327,10 @@ export default class Element extends Node {
`${node} = ${renderStatement};` `${node} = ${renderStatement};`
); );
if (this.compiler.options.hydratable) { if (this.component.options.hydratable) {
if (parentNodes) { if (parentNodes) {
block.builders.claim.addBlock(deindent` block.builders.claim.addBlock(deindent`
${node} = ${getClaimStatement(compiler, this.namespace, parentNodes, this)}; ${node} = ${getClaimStatement(component, this.namespace, parentNodes, this)};
var ${nodes} = @children(${this.name === 'template' ? `${node}.content` : node}); var ${nodes} = @children(${this.name === 'template' ? `${node}.content` : node});
`); `);
} else { } else {
@ -453,10 +453,10 @@ export default class Element extends Node {
return `${open}>${node.children.map(toHTML).join('')}</${node.name}>`; return `${open}>${node.children.map(toHTML).join('')}</${node.name}>`;
} }
if (this.compiler.options.dev) { if (this.component.options.dev) {
const loc = this.compiler.locate(this.start); const loc = this.component.locate(this.start);
block.builders.hydrate.addLine( block.builders.hydrate.addLine(
`@addLoc(${this.var}, ${this.compiler.fileVar}, ${loc.line}, ${loc.column}, ${this.start});` `@addLoc(${this.var}, ${this.component.fileVar}, ${loc.line}, ${loc.column}, ${this.start});`
); );
} }
} }
@ -466,7 +466,7 @@ export default class Element extends Node {
) { ) {
if (this.bindings.length === 0) return; if (this.bindings.length === 0) return;
if (this.name === 'select' || this.isMediaNode()) this.compiler.target.hasComplexBindings = true; if (this.name === 'select' || this.isMediaNode()) this.component.target.hasComplexBindings = true;
const needsLock = this.name !== 'input' || !/radio|checkbox|range|color/.test(this.getStaticAttributeValue('type')); const needsLock = this.name !== 'input' || !/radio|checkbox|range|color/.test(this.getStaticAttributeValue('type'));
@ -575,7 +575,7 @@ export default class Element extends Node {
.join(' && '); .join(' && ');
if (this.name === 'select' || group.bindings.find(binding => binding.name === 'indeterminate' || binding.isReadOnlyMediaAttribute)) { if (this.name === 'select' || group.bindings.find(binding => binding.name === 'indeterminate' || binding.isReadOnlyMediaAttribute)) {
this.compiler.target.hasComplexBindings = true; this.component.target.hasComplexBindings = true;
block.builders.hydrate.addLine( block.builders.hydrate.addLine(
`if (!(${allInitialStateIsDefined})) #component.root._beforecreate.push(${handler});` `if (!(${allInitialStateIsDefined})) #component.root._beforecreate.push(${handler});`
@ -583,7 +583,7 @@ export default class Element extends Node {
} }
if (group.events[0] === 'resize') { if (group.events[0] === 'resize') {
this.compiler.target.hasComplexBindings = true; this.component.target.hasComplexBindings = true;
block.builders.hydrate.addLine( block.builders.hydrate.addLine(
`#component.root._beforecreate.push(${handler});` `#component.root._beforecreate.push(${handler});`
@ -659,24 +659,24 @@ export default class Element extends Node {
} }
addEventHandlers(block: Block) { addEventHandlers(block: Block) {
const { compiler } = this; const { component } = this;
this.handlers.forEach(handler => { this.handlers.forEach(handler => {
const isCustomEvent = compiler.events.has(handler.name); const isCustomEvent = component.events.has(handler.name);
if (handler.callee) { if (handler.callee) {
handler.render(this.compiler, block, handler.shouldHoist); handler.render(this.component, block, handler.shouldHoist);
} }
const target = handler.shouldHoist ? 'this' : this.var; const target = handler.shouldHoist ? 'this' : this.var;
// get a name for the event handler that is globally unique // get a name for the event handler that is globally unique
// if hoisted, locally unique otherwise // if hoisted, locally unique otherwise
const handlerName = (handler.shouldHoist ? compiler : block).getUniqueName( const handlerName = (handler.shouldHoist ? component : block).getUniqueName(
`${handler.name.replace(/[^a-zA-Z0-9_$]/g, '_')}_handler` `${handler.name.replace(/[^a-zA-Z0-9_$]/g, '_')}_handler`
); );
const component = block.alias('component'); // can't use #component, might be hoisted const component_name = block.alias('component'); // can't use #component, might be hoisted
// create the handler body // create the handler body
const handlerBody = deindent` const handlerBody = deindent`
@ -688,14 +688,14 @@ export default class Element extends Node {
${handler.snippet ? ${handler.snippet ?
handler.snippet : handler.snippet :
`${component}.fire("${handler.name}", event);`} `${component_name}.fire("${handler.name}", event);`}
`; `;
if (isCustomEvent) { if (isCustomEvent) {
block.addVariable(handlerName); block.addVariable(handlerName);
block.builders.hydrate.addBlock(deindent` block.builders.hydrate.addBlock(deindent`
${handlerName} = %events-${handler.name}.call(${component}, ${this.var}, function(event) { ${handlerName} = %events-${handler.name}.call(${component_name}, ${this.var}, function(event) {
${handlerBody} ${handlerBody}
}); });
`); `);
@ -711,7 +711,7 @@ export default class Element extends Node {
`; `;
if (handler.shouldHoist) { if (handler.shouldHoist) {
compiler.target.blocks.push(handlerFunction); component.target.blocks.push(handlerFunction);
} else { } else {
block.builders.init.addBlock(handlerFunction); block.builders.init.addBlock(handlerFunction);
} }
@ -946,14 +946,14 @@ export default class Element extends Node {
return `@append(${name}._slotted.default, ${this.var});`; return `@append(${name}._slotted.default, ${this.var});`;
} }
addCssClass(className = this.compiler.stylesheet.id) { addCssClass(className = this.component.stylesheet.id) {
const classAttribute = this.attributes.find(a => a.name === 'class'); const classAttribute = this.attributes.find(a => a.name === 'class');
if (classAttribute && !classAttribute.isTrue) { if (classAttribute && !classAttribute.isTrue) {
if (classAttribute.chunks.length === 1 && classAttribute.chunks[0].type === 'Text') { if (classAttribute.chunks.length === 1 && classAttribute.chunks[0].type === 'Text') {
(<Text>classAttribute.chunks[0]).data += ` ${className}`; (<Text>classAttribute.chunks[0]).data += ` ${className}`;
} else { } else {
(<Node[]>classAttribute.chunks).push( (<Node[]>classAttribute.chunks).push(
new Text(this.compiler, this, this.scope, { new Text(this.component, this, this.scope, {
type: 'Text', type: 'Text',
data: ` ${className}` data: ` ${className}`
}) })
@ -961,7 +961,7 @@ export default class Element extends Node {
} }
} else { } else {
this.attributes.push( this.attributes.push(
new Attribute(this.compiler, this, this.scope, { new Attribute(this.component, this, this.scope, {
type: 'Attribute', type: 'Attribute',
name: 'class', name: 'class',
value: [{ type: 'Text', data: className }] value: [{ type: 'Text', data: className }]
@ -971,7 +971,7 @@ export default class Element extends Node {
} }
ssr() { ssr() {
const { compiler } = this; const { component } = this;
let openingTag = `<${this.name}`; let openingTag = `<${this.name}`;
let textareaContents; // awkward special case let textareaContents; // awkward special case
@ -980,7 +980,7 @@ export default class Element extends Node {
if (slot && this.hasAncestor('InlineComponent')) { if (slot && this.hasAncestor('InlineComponent')) {
const slot = this.attributes.find((attribute: Node) => attribute.name === 'slot'); const slot = this.attributes.find((attribute: Node) => attribute.name === 'slot');
const slotName = slot.chunks[0].data; const slotName = slot.chunks[0].data;
const appendTarget = compiler.target.appendTargets[compiler.target.appendTargets.length - 1]; const appendTarget = component.target.appendTargets[component.target.appendTargets.length - 1];
appendTarget.slotStack.push(slotName); appendTarget.slotStack.push(slotName);
appendTarget.slots[slotName] = ''; appendTarget.slots[slotName] = '';
} }
@ -1048,10 +1048,10 @@ export default class Element extends Node {
openingTag += '>'; openingTag += '>';
compiler.target.append(openingTag); component.target.append(openingTag);
if (this.name === 'textarea' && textareaContents !== undefined) { if (this.name === 'textarea' && textareaContents !== undefined) {
compiler.target.append(textareaContents); component.target.append(textareaContents);
} else { } else {
this.children.forEach((child: Node) => { this.children.forEach((child: Node) => {
child.ssr(); child.ssr();
@ -1059,7 +1059,7 @@ export default class Element extends Node {
} }
if (!isVoidElementName(this.name)) { if (!isVoidElementName(this.name)) {
compiler.target.append(`</${this.name}>`); component.target.append(`</${this.name}>`);
} }
} }
} }
@ -1080,7 +1080,7 @@ function getRenderStatement(
} }
function getClaimStatement( function getClaimStatement(
compiler: Compiler, component: Component,
namespace: string, namespace: string,
nodes: string, nodes: string,
node: Node node: Node

@ -7,8 +7,8 @@ export default class ElseBlock extends Node {
children: Node[]; children: Node[];
block: Block; block: Block;
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.children = mapChildren(compiler, this, scope, info.children); this.children = mapChildren(component, this, scope, info.children);
} }
} }

@ -19,8 +19,8 @@ export default class EventHandler extends Node {
args: Expression[]; args: Expression[];
snippet: string; snippet: string;
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.name = info.name; this.name = info.name;
this.dependencies = new Set(); this.dependencies = new Set();
@ -33,7 +33,7 @@ export default class EventHandler extends Node {
this.usesContext = false; this.usesContext = false;
this.args = info.expression.arguments.map(param => { this.args = info.expression.arguments.map(param => {
const expression = new Expression(compiler, this, scope, param); const expression = new Expression(component, this, scope, param);
addToSet(this.dependencies, expression.dependencies); addToSet(this.dependencies, expression.dependencies);
if (expression.usesContext) this.usesContext = true; if (expression.usesContext) this.usesContext = true;
return expression; return expression;
@ -51,28 +51,28 @@ export default class EventHandler extends Node {
this.snippet = null; // TODO handle shorthand events here? this.snippet = null; // TODO handle shorthand events here?
} }
this.isCustomEvent = compiler.events.has(this.name); this.isCustomEvent = component.events.has(this.name);
this.shouldHoist = !this.isCustomEvent && parent.hasAncestor('EachBlock'); this.shouldHoist = !this.isCustomEvent && parent.hasAncestor('EachBlock');
} }
render(compiler, block, hoisted) { // TODO hoist more event handlers render(component, block, hoisted) { // TODO hoist more event handlers
if (this.insertionPoint === null) return; // TODO handle shorthand events here? if (this.insertionPoint === null) return; // TODO handle shorthand events here?
if (!validCalleeObjects.has(this.callee.name)) { if (!validCalleeObjects.has(this.callee.name)) {
const component = hoisted ? `component` : block.alias(`component`); const component_name = hoisted ? `component` : block.alias(`component`);
// allow event.stopPropagation(), this.select() etc // allow event.stopPropagation(), this.select() etc
// 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)
if (this.callee.name[0] === '$' && !compiler.methods.has(this.callee.name)) { if (this.callee.name[0] === '$' && !component.methods.has(this.callee.name)) {
compiler.code.overwrite( component.code.overwrite(
this.insertionPoint, this.insertionPoint,
this.insertionPoint + 1, this.insertionPoint + 1,
`${component}.store.` `${component_name}.store.`
); );
} else { } else {
compiler.code.prependRight( component.code.prependRight(
this.insertionPoint, this.insertionPoint,
`${component}.` `${component_name}.`
); );
} }
} }
@ -84,7 +84,7 @@ export default class EventHandler extends Node {
if (this.callee && this.callee.name === 'this') { if (this.callee && this.callee.name === 'this') {
const node = this.callee.nodes[0]; const node = this.callee.nodes[0];
compiler.code.overwrite(node.start, node.end, this.parent.var, { component.code.overwrite(node.start, node.end, this.parent.var, {
storeName: true, storeName: true,
contentOnly: true contentOnly: true
}); });

@ -1,5 +1,5 @@
import Node from './shared/Node'; import Node from './shared/Node';
import Compiler from '../Compiler'; import Component from '../Component';
import mapChildren from './shared/mapChildren'; import mapChildren from './shared/mapChildren';
import Block from '../dom/Block'; import Block from '../dom/Block';
import TemplateScope from './shared/TemplateScope'; import TemplateScope from './shared/TemplateScope';
@ -9,17 +9,17 @@ export default class Fragment extends Node {
children: Node[]; children: Node[];
scope: TemplateScope; scope: TemplateScope;
constructor(compiler: Compiler, info: any) { constructor(component: Component, info: any) {
const scope = new TemplateScope(); const scope = new TemplateScope();
super(compiler, null, scope, info); super(component, null, scope, info);
this.scope = scope; this.scope = scope;
this.children = mapChildren(compiler, this, scope, info.children); this.children = mapChildren(component, this, scope, info.children);
} }
init() { init() {
this.block = new Block({ this.block = new Block({
compiler: this.compiler, component: this.component,
name: '@create_main_fragment', name: '@create_main_fragment',
key: null, key: null,
@ -28,7 +28,7 @@ export default class Fragment extends Node {
dependencies: new Set(), dependencies: new Set(),
}); });
this.compiler.target.blocks.push(this.block); this.component.target.blocks.push(this.block);
this.initChildren(this.block, true, null); this.initChildren(this.block, true, null);
this.block.hasUpdateMethod = true; this.block.hasUpdateMethod = true;

@ -9,9 +9,9 @@ export default class Head extends Node {
type: 'Head'; type: 'Head';
children: any[]; // TODO children: any[]; // TODO
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.children = mapChildren(compiler, parent, scope, info.children.filter(child => { this.children = mapChildren(component, parent, scope, info.children.filter(child => {
return (child.type !== 'Text' || /\S/.test(child.data)); return (child.type !== 'Text' || /\S/.test(child.data));
})); }));
} }
@ -37,12 +37,12 @@ export default class Head extends Node {
} }
ssr() { ssr() {
this.compiler.target.append('${(__result.head += `'); this.component.target.append('${(__result.head += `');
this.children.forEach((child: Node) => { this.children.forEach((child: Node) => {
child.ssr(); child.ssr();
}); });
this.compiler.target.append('`, "")}'); this.component.target.append('`, "")}');
} }
} }

@ -1,7 +1,7 @@
import deindent from '../../utils/deindent'; import deindent from '../../utils/deindent';
import Node from './shared/Node'; import Node from './shared/Node';
import ElseBlock from './ElseBlock'; import ElseBlock from './ElseBlock';
import Compiler from '../Compiler'; import Component from '../Component';
import Block from '../dom/Block'; import Block from '../dom/Block';
import createDebuggingComment from '../../utils/createDebuggingComment'; import createDebuggingComment from '../../utils/createDebuggingComment';
import Expression from './shared/Expression'; import Expression from './shared/Expression';
@ -25,14 +25,14 @@ export default class IfBlock extends Node {
block: Block; block: Block;
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.expression = new Expression(compiler, this, scope, info.expression); this.expression = new Expression(component, this, scope, info.expression);
this.children = mapChildren(compiler, this, scope, info.children); this.children = mapChildren(component, this, scope, info.children);
this.else = info.else this.else = info.else
? new ElseBlock(compiler, this, scope, info.else) ? new ElseBlock(component, this, scope, info.else)
: null; : null;
} }
@ -41,7 +41,7 @@ export default class IfBlock extends Node {
stripWhitespace: boolean, stripWhitespace: boolean,
nextSibling: Node nextSibling: Node
) { ) {
const { compiler } = this; const { component } = this;
this.cannotUseInnerHTML(); this.cannotUseInnerHTML();
@ -56,8 +56,8 @@ export default class IfBlock extends Node {
block.addDependencies(node.expression.dependencies); block.addDependencies(node.expression.dependencies);
node.block = block.child({ node.block = block.child({
comment: createDebuggingComment(node, compiler), comment: createDebuggingComment(node, component),
name: compiler.getUniqueName(`create_if_block`), name: component.getUniqueName(`create_if_block`),
}); });
blocks.push(node.block); blocks.push(node.block);
@ -75,8 +75,8 @@ export default class IfBlock extends Node {
attachBlocks(node.else.children[0]); attachBlocks(node.else.children[0]);
} else if (node.else) { } else if (node.else) {
node.else.block = block.child({ node.else.block = block.child({
comment: createDebuggingComment(node.else, compiler), comment: createDebuggingComment(node.else, component),
name: compiler.getUniqueName(`create_if_block`), name: component.getUniqueName(`create_if_block`),
}); });
blocks.push(node.else.block); blocks.push(node.else.block);
@ -98,7 +98,7 @@ export default class IfBlock extends Node {
attachBlocks(this); attachBlocks(this);
if (compiler.options.nestedTransitions) { if (component.options.nestedTransitions) {
if (hasIntros) block.addIntro(); if (hasIntros) block.addIntro();
if (hasOutros) block.addOutro(); if (hasOutros) block.addOutro();
} }
@ -109,7 +109,7 @@ export default class IfBlock extends Node {
block.hasOutroMethod = hasOutros; block.hasOutroMethod = hasOutros;
}); });
compiler.target.blocks.push(...blocks); component.target.blocks.push(...blocks);
} }
build( build(
@ -138,7 +138,7 @@ export default class IfBlock extends Node {
if (hasOutros) { if (hasOutros) {
this.buildCompoundWithOutros(block, parentNode, parentNodes, branches, dynamic, vars); this.buildCompoundWithOutros(block, parentNode, parentNodes, branches, dynamic, vars);
if (this.compiler.options.nestedTransitions) { if (this.component.options.nestedTransitions) {
block.builders.outro.addBlock(deindent` block.builders.outro.addBlock(deindent`
if (${name}) ${name}.o(#outrocallback); if (${name}) ${name}.o(#outrocallback);
else #outrocallback(); else #outrocallback();
@ -150,7 +150,7 @@ export default class IfBlock extends Node {
} else { } else {
this.buildSimple(block, parentNode, parentNodes, branches[0], dynamic, vars); this.buildSimple(block, parentNode, parentNodes, branches[0], dynamic, vars);
if (hasOutros && this.compiler.options.nestedTransitions) { if (hasOutros && this.component.options.nestedTransitions) {
block.builders.outro.addBlock(deindent` block.builders.outro.addBlock(deindent`
if (${name}) ${name}.o(#outrocallback); if (${name}) ${name}.o(#outrocallback);
else #outrocallback(); else #outrocallback();
@ -184,7 +184,7 @@ export default class IfBlock extends Node {
dynamic, dynamic,
{ name, anchor, hasElse, if_name } { name, anchor, hasElse, if_name }
) { ) {
const select_block_type = this.compiler.getUniqueName(`select_block_type`); const select_block_type = this.component.getUniqueName(`select_block_type`);
const current_block_type = block.getUniqueName(`current_block_type`); const current_block_type = block.getUniqueName(`current_block_type`);
const current_block_type_and = hasElse ? '' : `${current_block_type} && `; const current_block_type_and = hasElse ? '' : `${current_block_type} && `;
@ -247,7 +247,7 @@ export default class IfBlock extends Node {
dynamic, dynamic,
{ name, anchor, hasElse } { name, anchor, hasElse }
) { ) {
const select_block_type = this.compiler.getUniqueName(`select_block_type`); const select_block_type = this.component.getUniqueName(`select_block_type`);
const current_block_type_index = block.getUniqueName(`current_block_type_index`); const current_block_type_index = block.getUniqueName(`current_block_type_index`);
const previous_block_index = block.getUniqueName(`previous_block_index`); const previous_block_index = block.getUniqueName(`previous_block_index`);
const if_block_creators = block.getUniqueName(`if_block_creators`); const if_block_creators = block.getUniqueName(`if_block_creators`);
@ -482,16 +482,16 @@ export default class IfBlock extends Node {
} }
ssr() { ssr() {
const { compiler } = this; const { component } = this;
const { snippet } = this.expression; const { snippet } = this.expression;
compiler.target.append('${ ' + snippet + ' ? `'); component.target.append('${ ' + snippet + ' ? `');
this.children.forEach((child: Node) => { this.children.forEach((child: Node) => {
child.ssr(); child.ssr();
}); });
compiler.target.append('` : `'); component.target.append('` : `');
if (this.else) { if (this.else) {
this.else.children.forEach((child: Node) => { this.else.children.forEach((child: Node) => {
@ -499,7 +499,7 @@ export default class IfBlock extends Node {
}); });
} }
compiler.target.append('` }'); component.target.append('` }');
} }
visitChildren(block: Block, node: Node) { visitChildren(block: Block, node: Node) {

@ -25,15 +25,15 @@ export default class InlineComponent extends Node {
children: Node[]; children: Node[];
ref: string; ref: string;
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
compiler.hasComponents = true; component.hasComponents = true;
this.name = info.name; this.name = info.name;
this.expression = this.name === 'svelte:component' this.expression = this.name === 'svelte:component'
? new Expression(compiler, this, scope, info.expression) ? new Expression(component, this, scope, info.expression)
: null; : null;
this.attributes = []; this.attributes = [];
@ -44,22 +44,22 @@ export default class InlineComponent extends Node {
switch (node.type) { switch (node.type) {
case 'Attribute': case 'Attribute':
case 'Spread': case 'Spread':
this.attributes.push(new Attribute(compiler, this, scope, node)); this.attributes.push(new Attribute(component, this, scope, node));
break; break;
case 'Binding': case 'Binding':
this.bindings.push(new Binding(compiler, this, scope, node)); this.bindings.push(new Binding(component, this, scope, node));
break; break;
case 'EventHandler': case 'EventHandler':
this.handlers.push(new EventHandler(compiler, this, scope, node)); this.handlers.push(new EventHandler(component, this, scope, node));
break; break;
case 'Ref': case 'Ref':
// TODO catch this in validation // TODO catch this in validation
if (this.ref) throw new Error(`Duplicate refs`); if (this.ref) throw new Error(`Duplicate refs`);
compiler.usesRefs = true component.usesRefs = true
this.ref = node.name; this.ref = node.name;
break; break;
@ -68,7 +68,7 @@ export default class InlineComponent extends Node {
} }
}); });
this.children = mapChildren(compiler, this, scope, info.children); this.children = mapChildren(component, this, scope, info.children);
} }
init( init(
@ -96,7 +96,7 @@ export default class InlineComponent extends Node {
this.var = block.getUniqueName( this.var = block.getUniqueName(
( (
this.name === 'svelte:self' ? this.compiler.name : this.name === 'svelte:self' ? this.component.name :
this.name === 'svelte:component' ? 'switch_instance' : this.name === 'svelte:component' ? 'switch_instance' :
this.name this.name
).toLowerCase() ).toLowerCase()
@ -110,7 +110,7 @@ export default class InlineComponent extends Node {
}); });
} }
if (this.compiler.options.nestedTransitions) { if (this.component.options.nestedTransitions) {
block.addOutro(); block.addOutro();
} }
} }
@ -120,7 +120,7 @@ export default class InlineComponent extends Node {
parentNode: string, parentNode: string,
parentNodes: string parentNodes: string
) { ) {
const { compiler } = this; const { component } = this;
const name = this.var; const name = this.var;
@ -228,7 +228,7 @@ export default class InlineComponent extends Node {
} }
if (this.bindings.length) { if (this.bindings.length) {
compiler.target.hasComplexBindings = true; component.target.hasComplexBindings = true;
name_updating = block.alias(`${name}_updating`); name_updating = block.alias(`${name}_updating`);
block.addVariable(name_updating, '{}'); block.addVariable(name_updating, '{}');
@ -337,7 +337,7 @@ export default class InlineComponent extends Node {
this.handlers.forEach(handler => { this.handlers.forEach(handler => {
handler.var = block.getUniqueName(`${this.var}_${handler.name}`); // TODO this is hacky handler.var = block.getUniqueName(`${this.var}_${handler.name}`); // TODO this is hacky
handler.render(compiler, block, false); // TODO hoist when possible handler.render(component, block, false); // TODO hoist when possible
if (handler.usesContext) block.maintainContext = true; // TODO is there a better place to put this? if (handler.usesContext) block.maintainContext = true; // TODO is there a better place to put this?
}); });
@ -403,7 +403,7 @@ export default class InlineComponent extends Node {
block.builders.update.addBlock(deindent` block.builders.update.addBlock(deindent`
if (${switch_value} !== (${switch_value} = ${snippet})) { if (${switch_value} !== (${switch_value} = ${snippet})) {
if (${name}) { if (${name}) {
${this.compiler.options.nestedTransitions ${this.component.options.nestedTransitions
? deindent` ? deindent`
@groupOutros(); @groupOutros();
const old_component = ${name}; const old_component = ${name};
@ -455,7 +455,7 @@ export default class InlineComponent extends Node {
block.builders.destroy.addLine(`if (${name}) ${name}.destroy(${parentNode ? '' : 'detach'});`); block.builders.destroy.addLine(`if (${name}) ${name}.destroy(${parentNode ? '' : 'detach'});`);
} else { } else {
const expression = this.name === 'svelte:self' const expression = this.name === 'svelte:self'
? compiler.name ? component.name
: `%components-${this.name}`; : `%components-${this.name}`;
block.builders.init.addBlock(deindent` block.builders.init.addBlock(deindent`
@ -503,7 +503,7 @@ export default class InlineComponent extends Node {
`); `);
} }
if (this.compiler.options.nestedTransitions) { if (this.component.options.nestedTransitions) {
block.builders.outro.addLine( block.builders.outro.addLine(
`if (${name}) ${name}._fragment.o(#outrocallback);` `if (${name}) ${name}._fragment.o(#outrocallback);`
); );
@ -570,7 +570,7 @@ export default class InlineComponent extends Node {
const expression = ( const expression = (
this.name === 'svelte:self' this.name === 'svelte:self'
? this.compiler.name ? this.component.name
: this.name === 'svelte:component' : this.name === 'svelte:component'
? `((${this.expression.snippet}) || @missingComponent)` ? `((${this.expression.snippet}) || @missingComponent)`
: `%components-${this.name}` : `%components-${this.name}`
@ -594,7 +594,7 @@ export default class InlineComponent extends Node {
const { name } = getObject(binding.value.node); const { name } = getObject(binding.value.node);
this.compiler.target.bindings.push(deindent` this.component.target.bindings.push(deindent`
if (${conditions.reverse().join('&&')}) { if (${conditions.reverse().join('&&')}) {
tmp = ${expression}.data(); tmp = ${expression}.data();
if ('${name}' in tmp) { if ('${name}' in tmp) {
@ -616,7 +616,7 @@ export default class InlineComponent extends Node {
slotStack: ['default'] slotStack: ['default']
}; };
this.compiler.target.appendTargets.push(appendTarget); this.component.target.appendTargets.push(appendTarget);
this.children.forEach((child: Node) => { this.children.forEach((child: Node) => {
child.ssr(); child.ssr();
@ -628,15 +628,15 @@ export default class InlineComponent extends Node {
options.push(`slotted: { ${slotted} }`); options.push(`slotted: { ${slotted} }`);
this.compiler.target.appendTargets.pop(); this.component.target.appendTargets.pop();
} }
if (options.length) { if (options.length) {
open += `, { ${options.join(', ')} }`; open += `, { ${options.join(', ')} }`;
} }
this.compiler.target.append(open); this.component.target.append(open);
this.compiler.target.append(')}'); this.component.target.append(')}');
} }
} }

@ -26,7 +26,7 @@ export default class MustacheTag extends Tag {
} }
ssr() { ssr() {
this.compiler.target.append( this.component.target.append(
this.parent && this.parent &&
this.parent.type === 'Element' && this.parent.type === 'Element' &&
this.parent.name === 'style' this.parent.name === 'style'

@ -6,8 +6,8 @@ export default class PendingBlock extends Node {
block: Block; block: Block;
children: Node[]; children: Node[];
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.children = mapChildren(compiler, parent, scope, info.children); this.children = mapChildren(component, parent, scope, info.children);
} }
} }

@ -95,6 +95,6 @@ export default class RawMustacheTag extends Tag {
} }
ssr() { ssr() {
this.compiler.target.append('${' + this.expression.snippet + '}'); this.component.target.append('${' + this.expression.snippet + '}');
} }
} }

@ -36,10 +36,10 @@ export default class Slot extends Element {
parentNode: string, parentNode: string,
parentNodes: string parentNodes: string
) { ) {
const { compiler } = this; const { component } = this;
const slotName = this.getStaticAttributeValue('name') || 'default'; const slotName = this.getStaticAttributeValue('name') || 'default';
compiler.slots.add(slotName); component.slots.add(slotName);
const content_name = block.getUniqueName(`slot_content_${sanitize(slotName)}`); const content_name = block.getUniqueName(`slot_content_${sanitize(slotName)}`);
const prop = quotePropIfNecessary(slotName); const prop = quotePropIfNecessary(slotName);
@ -160,12 +160,12 @@ export default class Slot extends Element {
const slotName = name && name.chunks[0].data || 'default'; const slotName = name && name.chunks[0].data || 'default';
const prop = quotePropIfNecessary(slotName); const prop = quotePropIfNecessary(slotName);
this.compiler.target.append(`\${options && options.slotted && options.slotted${prop} ? options.slotted${prop}() : \``); this.component.target.append(`\${options && options.slotted && options.slotted${prop} ? options.slotted${prop}() : \``);
this.children.forEach((child: Node) => { this.children.forEach((child: Node) => {
child.ssr(); child.ssr();
}); });
this.compiler.target.append(`\`}`); this.component.target.append(`\`}`);
} }
} }

@ -31,8 +31,8 @@ export default class Text extends Node {
data: string; data: string;
shouldSkip: boolean; shouldSkip: boolean;
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.data = info.data; this.data = info.data;
} }
@ -74,6 +74,6 @@ export default class Text extends Node {
// unless this Text node is inside a <script> or <style> element, escape &,<,> // unless this Text node is inside a <script> or <style> element, escape &,<,>
text = escapeHTML(text); text = escapeHTML(text);
} }
this.compiler.target.append(escape(escapeTemplate(text))); this.component.target.append(escape(escapeTemplate(text)));
} }
} }

@ -6,8 +6,8 @@ export default class ThenBlock extends Node {
block: Block; block: Block;
children: Node[]; children: Node[];
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.children = mapChildren(compiler, parent, scope, info.children); this.children = mapChildren(component, parent, scope, info.children);
} }
} }

@ -8,9 +8,9 @@ export default class Title extends Node {
children: any[]; // TODO children: any[]; // TODO
shouldCache: boolean; shouldCache: boolean;
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.children = mapChildren(compiler, parent, scope, info.children); this.children = mapChildren(component, parent, scope, info.children);
this.shouldCache = info.children.length === 1 this.shouldCache = info.children.length === 1
? ( ? (
@ -103,12 +103,12 @@ export default class Title extends Node {
} }
ssr() { ssr() {
this.compiler.target.append(`<title>`); this.component.target.append(`<title>`);
this.children.forEach((child: Node) => { this.children.forEach((child: Node) => {
child.ssr(); child.ssr();
}); });
this.compiler.target.append(`</title>`); this.component.target.append(`</title>`);
} }
} }

@ -6,13 +6,13 @@ export default class Transition extends Node {
name: string; name: string;
expression: Expression; expression: Expression;
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.name = info.name; this.name = info.name;
this.expression = info.expression this.expression = info.expression
? new Expression(compiler, this, scope, info.expression) ? new Expression(component, this, scope, info.expression)
: null; : null;
} }
} }

@ -38,17 +38,17 @@ export default class Window extends Node {
handlers: EventHandler[]; handlers: EventHandler[];
bindings: Binding[]; bindings: Binding[];
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.handlers = []; this.handlers = [];
this.bindings = []; this.bindings = [];
info.attributes.forEach(node => { info.attributes.forEach(node => {
if (node.type === 'EventHandler') { if (node.type === 'EventHandler') {
this.handlers.push(new EventHandler(compiler, this, scope, node)); this.handlers.push(new EventHandler(component, this, scope, node));
} else if (node.type === 'Binding') { } else if (node.type === 'Binding') {
this.bindings.push(new Binding(compiler, this, scope, node)); this.bindings.push(new Binding(component, this, scope, node));
} }
}); });
} }
@ -58,20 +58,20 @@ export default class Window extends Node {
parentNode: string, parentNode: string,
parentNodes: string parentNodes: string
) { ) {
const { compiler } = this; const { component } = this;
const events = {}; const events = {};
const bindings: Record<string, string> = {}; const bindings: Record<string, string> = {};
this.handlers.forEach(handler => { this.handlers.forEach(handler => {
// 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)
compiler.addSourcemapLocations(handler.expression); component.addSourcemapLocations(handler.expression);
const isCustomEvent = compiler.events.has(handler.name); const isCustomEvent = component.events.has(handler.name);
let usesState = handler.dependencies.size > 0; let usesState = handler.dependencies.size > 0;
handler.render(compiler, block, false); // TODO hoist? handler.render(component, block, false); // TODO hoist?
const handlerName = block.getUniqueName(`onwindow${handler.name}`); const handlerName = block.getUniqueName(`onwindow${handler.name}`);
const handlerBody = deindent` const handlerBody = deindent`
@ -109,7 +109,7 @@ export default class Window extends Node {
this.bindings.forEach(binding => { this.bindings.forEach(binding => {
// in dev mode, throw if read-only values are written to // in dev mode, throw if read-only values are written to
if (readonly.has(binding.name)) { if (readonly.has(binding.name)) {
compiler.target.readonly.add(binding.value.node.name); component.target.readonly.add(binding.value.node.name);
} }
bindings[binding.name] = binding.value.node.name; bindings[binding.name] = binding.value.node.name;
@ -126,7 +126,7 @@ export default class Window extends Node {
); );
// add initial value // add initial value
compiler.target.metaBindings.push( component.target.metaBindings.push(
`this._state.${binding.value.node.name} = window.${property};` `this._state.${binding.value.node.name} = window.${property};`
); );
}); });
@ -151,13 +151,13 @@ export default class Window extends Node {
if (${lock}) return; if (${lock}) return;
${lock} = true; ${lock} = true;
`} `}
${compiler.options.dev && `component._updatingReadonlyProperty = true;`} ${component.options.dev && `component._updatingReadonlyProperty = true;`}
#component.set({ #component.set({
${props} ${props}
}); });
${compiler.options.dev && `component._updatingReadonlyProperty = false;`} ${component.options.dev && `component._updatingReadonlyProperty = false;`}
${event === 'scroll' && `${lock} = false;`} ${event === 'scroll' && `${lock} = false;`}
`; `;
@ -200,16 +200,16 @@ export default class Window extends Node {
const handlerName = block.getUniqueName(`onlinestatuschanged`); const handlerName = block.getUniqueName(`onlinestatuschanged`);
block.builders.init.addBlock(deindent` block.builders.init.addBlock(deindent`
function ${handlerName}(event) { function ${handlerName}(event) {
${compiler.options.dev && `component._updatingReadonlyProperty = true;`} ${component.options.dev && `component._updatingReadonlyProperty = true;`}
#component.set({ ${bindings.online}: navigator.onLine }); #component.set({ ${bindings.online}: navigator.onLine });
${compiler.options.dev && `component._updatingReadonlyProperty = false;`} ${component.options.dev && `component._updatingReadonlyProperty = false;`}
} }
window.addEventListener("online", ${handlerName}); window.addEventListener("online", ${handlerName});
window.addEventListener("offline", ${handlerName}); window.addEventListener("offline", ${handlerName});
`); `);
// add initial value // add initial value
compiler.target.metaBindings.push( component.target.metaBindings.push(
`this._state.${bindings.online} = navigator.onLine;` `this._state.${bindings.online} = navigator.onLine;`
); );

@ -1,4 +1,4 @@
import Compiler from '../../Compiler'; import Component from '../../Component';
import { walk } from 'estree-walker'; import { walk } from 'estree-walker';
import isReference from 'is-reference'; import isReference from 'is-reference';
import flattenReference from '../../../utils/flattenReference'; import flattenReference from '../../../utils/flattenReference';
@ -54,7 +54,7 @@ const precedence: Record<string, (node?: Node) => number> = {
}; };
export default class Expression { export default class Expression {
compiler: Compiler; component: Component;
node: any; node: any;
snippet: string; snippet: string;
@ -64,11 +64,11 @@ export default class Expression {
thisReferences: Array<{ start: number, end: number }>; thisReferences: Array<{ start: number, end: number }>;
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
// TODO revert to direct property access in prod? // TODO revert to direct property access in prod?
Object.defineProperties(this, { Object.defineProperties(this, {
compiler: { component: {
value: compiler value: component
} }
}); });
@ -81,7 +81,7 @@ export default class Expression {
const dependencies = new Set(); const dependencies = new Set();
const { code, helpers } = compiler; const { code, helpers } = component;
let { map, scope: currentScope } = createScopes(info); let { map, scope: currentScope } = createScopes(info);
@ -111,11 +111,11 @@ export default class Expression {
if (currentScope.has(name) || (name === 'event' && isEventHandler)) return; if (currentScope.has(name) || (name === 'event' && isEventHandler)) return;
if (compiler.helpers.has(name)) { if (component.helpers.has(name)) {
let object = node; let object = node;
while (object.type === 'MemberExpression') object = object.object; while (object.type === 'MemberExpression') object = object.object;
const alias = compiler.templateVars.get(`helpers-${name}`); const alias = component.templateVars.get(`helpers-${name}`);
if (alias !== name) code.overwrite(object.start, object.end, alias); if (alias !== name) code.overwrite(object.start, object.end, alias);
return; return;
} }
@ -135,7 +135,7 @@ export default class Expression {
}); });
} else { } else {
dependencies.add(name); dependencies.add(name);
compiler.expectedProperties.add(name); component.expectedProperties.add(name);
} }
if (node.type === 'MemberExpression') { if (node.type === 'MemberExpression') {
@ -163,7 +163,7 @@ export default class Expression {
overwriteThis(name) { overwriteThis(name) {
this.thisReferences.forEach(ref => { this.thisReferences.forEach(ref => {
this.compiler.code.overwrite(ref.start, ref.end, name, { this.component.code.overwrite(ref.start, ref.end, name, {
storeName: true storeName: true
}); });
}); });

@ -1,11 +1,11 @@
import Compiler from './../../Compiler'; import Component from './../../Component';
import Block from '../../dom/Block'; import Block from '../../dom/Block';
import { trimStart, trimEnd } from '../../../utils/trim'; import { trimStart, trimEnd } from '../../../utils/trim';
export default class Node { export default class Node {
readonly start: number; readonly start: number;
readonly end: number; readonly end: number;
readonly compiler: Compiler; readonly component: Component;
readonly parent: Node; readonly parent: Node;
readonly type: string; readonly type: string;
@ -15,7 +15,7 @@ export default class Node {
canUseInnerHTML: boolean; canUseInnerHTML: boolean;
var: string; var: string;
constructor(compiler: Compiler, parent, scope, info: any) { constructor(component: Component, parent, scope, info: any) {
this.start = info.start; this.start = info.start;
this.end = info.end; this.end = info.end;
this.type = info.type; this.type = info.type;
@ -23,8 +23,8 @@ export default class Node {
// this makes properties non-enumerable, which makes logging // this makes properties non-enumerable, which makes logging
// bearable. might have a performance cost. TODO remove in prod? // bearable. might have a performance cost. TODO remove in prod?
Object.defineProperties(this, { Object.defineProperties(this, {
compiler: { component: {
value: compiler value: component
}, },
parent: { parent: {
value: parent value: parent
@ -86,7 +86,7 @@ export default class Node {
lastChild = null; lastChild = null;
cleaned.forEach((child: Node, i: number) => { cleaned.forEach((child: Node, i: number) => {
child.canUseInnerHTML = !this.compiler.options.hydratable; child.canUseInnerHTML = !this.component.options.hydratable;
child.init(block, stripWhitespace, cleaned[i + 1] || nextSibling); child.init(block, stripWhitespace, cleaned[i + 1] || nextSibling);

@ -6,9 +6,9 @@ export default class Tag extends Node {
expression: Expression; expression: Expression;
shouldCache: boolean; shouldCache: boolean;
constructor(compiler, parent, scope, info) { constructor(component, parent, scope, info) {
super(compiler, parent, scope, info); super(component, parent, scope, info);
this.expression = new Expression(compiler, this, scope, info.expression); this.expression = new Expression(component, this, scope, info.expression);
this.shouldCache = ( this.shouldCache = (
info.expression.type !== 'Identifier' || info.expression.type !== 'Identifier' ||

@ -34,11 +34,11 @@ function getConstructor(type): typeof Node {
} }
} }
export default function mapChildren(compiler, parent, scope, children: any[]) { export default function mapChildren(component, parent, scope, children: any[]) {
let last = null; let last = null;
return children.map(child => { return children.map(child => {
const constructor = getConstructor(child.type); const constructor = getConstructor(child.type);
const node = new constructor(compiler, parent, scope, child); const node = new constructor(component, parent, scope, child);
if (last) last.next = node; if (last) last.next = node;
node.prev = last; node.prev = last;

@ -1,5 +1,5 @@
import deindent from '../../utils/deindent'; import deindent from '../../utils/deindent';
import Compiler from '../Compiler'; import Component from '../Component';
import Stats from '../../Stats'; import Stats from '../../Stats';
import Stylesheet from '../../css/Stylesheet'; import Stylesheet from '../../css/Stylesheet';
import { removeNode, removeObjectKey } from '../../utils/removeNode'; import { removeNode, removeObjectKey } from '../../utils/removeNode';
@ -41,21 +41,21 @@ export default function ssr(
const format = options.format || 'cjs'; const format = options.format || 'cjs';
const target = new SsrTarget(); const target = new SsrTarget();
const compiler = new Compiler(ast, source, options.name || 'SvelteComponent', stylesheet, options, stats, false, target); const component = new Component(ast, source, options.name || 'SvelteComponent', stylesheet, options, stats, target);
const { computations, name, templateProperties } = compiler; const { computations, name, templateProperties } = component;
// create main render() function // create main render() function
trim(compiler.fragment.children).forEach((node: Node) => { trim(component.fragment.children).forEach((node: Node) => {
node.ssr(); node.ssr();
}); });
const css = compiler.customElement ? const css = component.customElement ?
{ code: null, map: null } : { code: null, map: null } :
compiler.stylesheet.render(options.filename, true); component.stylesheet.render(options.filename, true);
// generate initial state object // generate initial state object
const expectedProperties = Array.from(compiler.expectedProperties); const expectedProperties = Array.from(component.expectedProperties);
const globals = expectedProperties.filter(prop => globalWhitelist.has(prop)); const globals = expectedProperties.filter(prop => globalWhitelist.has(prop));
const storeProps = expectedProperties.filter(prop => prop[0] === '$'); const storeProps = expectedProperties.filter(prop => prop[0] === '$');
@ -81,7 +81,7 @@ export default function ssr(
// TODO concatenate CSS maps // TODO concatenate CSS maps
const result = deindent` const result = deindent`
${compiler.javascript} ${component.javascript}
var ${name} = {}; var ${name} = {};
@ -148,7 +148,7 @@ export default function ssr(
${templateProperties.preload && `${name}.preload = %preload;`} ${templateProperties.preload && `${name}.preload = %preload;`}
`; `;
return compiler.generate(result, options, { name, format }); return component.generate(result, options, { name, format });
} }
function trim(nodes) { function trim(nodes) {

@ -1,8 +1,11 @@
import Compiler from '../compile/Compiler'; import Component from '../compile/Component';
import { Node } from '../interfaces'; import { Node } from '../interfaces';
export default function createDebuggingComment(node: Node, compiler: Compiler) { export default function createDebuggingComment(
const { locate, source } = compiler; node: Node,
component: Component
) {
const { locate, source } = component;
let c = node.start; let c = node.start;
if (node.type === 'ElseBlock') { if (node.type === 'ElseBlock') {

Loading…
Cancel
Save