mirror of https://github.com/sveltejs/svelte
				
				
				
			
							parent
							
								
									85b731c1bc
								
							
						
					
					
						commit
						f45e2b70fd
					
				@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					export {
 | 
				
			||||||
 | 
						onMount,
 | 
				
			||||||
 | 
						onDestroy,
 | 
				
			||||||
 | 
						beforeUpdate,
 | 
				
			||||||
 | 
						afterUpdate,
 | 
				
			||||||
 | 
						createEventDispatcher
 | 
				
			||||||
 | 
					} from './internal.js';
 | 
				
			||||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								@ -1,9 +0,0 @@
 | 
				
			|||||||
export default {
 | 
					 | 
				
			||||||
	input: 'store.js',
 | 
					 | 
				
			||||||
	output: {
 | 
					 | 
				
			||||||
		file: 'store.umd.js',
 | 
					 | 
				
			||||||
		format: 'umd',
 | 
					 | 
				
			||||||
		name: 'svelte',
 | 
					 | 
				
			||||||
		extend: true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								@ -1,27 +1,24 @@
 | 
				
			|||||||
import Node from './shared/Node';
 | 
					import Node from './shared/Node';
 | 
				
			||||||
import Expression from './shared/Expression';
 | 
					import Expression from './shared/Expression';
 | 
				
			||||||
 | 
					import Component from '../Component';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class Action extends Node {
 | 
					export default class Action extends Node {
 | 
				
			||||||
	type: 'Action';
 | 
						type: 'Action';
 | 
				
			||||||
	name: string;
 | 
						name: string;
 | 
				
			||||||
	expression: Expression;
 | 
						expression: Expression;
 | 
				
			||||||
 | 
						usesContext: boolean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	constructor(component, parent, scope, info) {
 | 
						constructor(component: Component, parent, scope, info) {
 | 
				
			||||||
		super(component, parent, scope, info);
 | 
							super(component, parent, scope, info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this.name = info.name;
 | 
							component.warn_if_undefined(info, scope);
 | 
				
			||||||
 | 
					 | 
				
			||||||
		component.used.actions.add(this.name);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!component.actions.has(this.name)) {
 | 
							this.name = info.name;
 | 
				
			||||||
			component.error(this, {
 | 
					 | 
				
			||||||
				code: `missing-action`,
 | 
					 | 
				
			||||||
				message: `Missing action '${this.name}'`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this.expression = info.expression
 | 
							this.expression = info.expression
 | 
				
			||||||
			? new Expression(component, this, scope, info.expression)
 | 
								? new Expression(component, this, scope, info.expression)
 | 
				
			||||||
			: null;
 | 
								: null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this.usesContext = this.expression && this.expression.usesContext;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1,14 +1,19 @@
 | 
				
			|||||||
import Node from './shared/Node';
 | 
					import Node from './shared/Node';
 | 
				
			||||||
import Block from '../render-dom/Block';
 | 
					import Block from '../render-dom/Block';
 | 
				
			||||||
import mapChildren from './shared/mapChildren';
 | 
					import mapChildren from './shared/mapChildren';
 | 
				
			||||||
 | 
					import TemplateScope from './shared/TemplateScope';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class CatchBlock extends Node {
 | 
					export default class CatchBlock extends Node {
 | 
				
			||||||
	block: Block;
 | 
						block: Block;
 | 
				
			||||||
 | 
						scope: TemplateScope;
 | 
				
			||||||
	children: Node[];
 | 
						children: Node[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	constructor(component, parent, scope, info) {
 | 
						constructor(component, parent, scope, info) {
 | 
				
			||||||
		super(component, parent, scope, info);
 | 
							super(component, parent, scope, info);
 | 
				
			||||||
		this.children = mapChildren(component, parent, scope, info.children);
 | 
					
 | 
				
			||||||
 | 
							this.scope = scope.child();
 | 
				
			||||||
 | 
							this.scope.add(parent.error, parent.expression.dependencies);
 | 
				
			||||||
 | 
							this.children = mapChildren(component, parent, this.scope, info.children);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this.warnIfEmptyBlock();
 | 
							this.warnIfEmptyBlock();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,164 +1,42 @@
 | 
				
			|||||||
import Node from './shared/Node';
 | 
					import Node from './shared/Node';
 | 
				
			||||||
import Expression from './shared/Expression';
 | 
					import Expression from './shared/Expression';
 | 
				
			||||||
import addToSet from '../../utils/addToSet';
 | 
					import Component from '../Component';
 | 
				
			||||||
import flattenReference from '../../utils/flattenReference';
 | 
					import deindent from '../../utils/deindent';
 | 
				
			||||||
import validCalleeObjects from '../../utils/validCalleeObjects';
 | 
					 | 
				
			||||||
import list from '../../utils/list';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const validBuiltins = new Set(['set', 'fire', 'destroy']);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class EventHandler extends Node {
 | 
					export default class EventHandler extends Node {
 | 
				
			||||||
	name: string;
 | 
						name: string;
 | 
				
			||||||
	modifiers: Set<string>;
 | 
						modifiers: Set<string>;
 | 
				
			||||||
	dependencies: Set<string>;
 | 
						expression: Expression;
 | 
				
			||||||
	expression: Node;
 | 
						handler_name: string;
 | 
				
			||||||
	callee: any; // TODO
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	usesComponent: boolean;
 | 
					 | 
				
			||||||
	usesContext: boolean;
 | 
						usesContext: boolean;
 | 
				
			||||||
	usesEventObject: boolean;
 | 
					 | 
				
			||||||
	isCustomEvent: boolean;
 | 
					 | 
				
			||||||
	shouldHoist: boolean;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	insertionPoint: number;
 | 
					 | 
				
			||||||
	args: Expression[];
 | 
					 | 
				
			||||||
	snippet: string;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	constructor(component, parent, scope, info) {
 | 
						constructor(component: Component, parent, template_scope, info) {
 | 
				
			||||||
		super(component, parent, scope, info);
 | 
							super(component, parent, template_scope, info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this.name = info.name;
 | 
							this.name = info.name;
 | 
				
			||||||
		this.modifiers = new Set(info.modifiers);
 | 
							this.modifiers = new Set(info.modifiers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		component.used.events.add(this.name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		this.dependencies = new Set();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (info.expression) {
 | 
							if (info.expression) {
 | 
				
			||||||
			this.validateExpression(info.expression);
 | 
								this.expression = new Expression(component, this, template_scope, info.expression);
 | 
				
			||||||
 | 
								this.usesContext = this.expression.usesContext;
 | 
				
			||||||
			this.callee = flattenReference(info.expression.callee);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			this.insertionPoint = info.expression.start;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			this.usesComponent = !validCalleeObjects.has(this.callee.name);
 | 
					 | 
				
			||||||
			this.usesContext = false;
 | 
					 | 
				
			||||||
			this.usesEventObject = this.callee.name === 'event';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			this.args = info.expression.arguments.map(param => {
 | 
					 | 
				
			||||||
				const expression = new Expression(component, this, scope, param);
 | 
					 | 
				
			||||||
				addToSet(this.dependencies, expression.dependencies);
 | 
					 | 
				
			||||||
				if (expression.usesContext) this.usesContext = true;
 | 
					 | 
				
			||||||
				if (expression.usesEvent) this.usesEventObject = true;
 | 
					 | 
				
			||||||
				return expression;
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			this.snippet = `[✂${info.expression.start}-${info.expression.end}✂];`;
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			this.callee = null;
 | 
					 | 
				
			||||||
			this.insertionPoint = null;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			this.args = null;
 | 
					 | 
				
			||||||
			this.usesComponent = true;
 | 
					 | 
				
			||||||
			this.usesContext = false;
 | 
					 | 
				
			||||||
			this.usesEventObject = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			this.snippet = null; // TODO handle shorthand events here?
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		this.isCustomEvent = component.events.has(this.name);
 | 
					 | 
				
			||||||
		this.shouldHoist = !this.isCustomEvent && parent.hasAncestor('EachBlock');
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	render(component, block, context, hoisted) { // TODO hoist more event handlers
 | 
					 | 
				
			||||||
		if (this.insertionPoint === null) return; // TODO handle shorthand events here?
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (!validCalleeObjects.has(this.callee.name)) {
 | 
					 | 
				
			||||||
			const component_name = hoisted ? `component` : block.alias(`component`);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			// allow event.stopPropagation(), this.select() etc
 | 
					 | 
				
			||||||
			// TODO verify that it's a valid callee (i.e. built-in or declared method)
 | 
					 | 
				
			||||||
			if (this.callee.name[0] === '$' && !component.methods.has(this.callee.name)) {
 | 
					 | 
				
			||||||
				component.code.overwrite(
 | 
					 | 
				
			||||||
					this.insertionPoint,
 | 
					 | 
				
			||||||
					this.insertionPoint + 1,
 | 
					 | 
				
			||||||
					`${component_name}.store.`
 | 
					 | 
				
			||||||
				);
 | 
					 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
				component.code.prependRight(
 | 
								const name = component.getUniqueName(`${this.name}_handler`);
 | 
				
			||||||
					this.insertionPoint,
 | 
								component.declarations.push(name);
 | 
				
			||||||
					`${component_name}.`
 | 
					 | 
				
			||||||
				);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (this.isCustomEvent) {
 | 
					 | 
				
			||||||
			this.args.forEach(arg => {
 | 
					 | 
				
			||||||
				arg.overwriteThis(context);
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (this.callee && this.callee.name === 'this') {
 | 
								component.partly_hoisted.push(deindent`
 | 
				
			||||||
				const node = this.callee.nodes[0];
 | 
									function ${name}(event) {
 | 
				
			||||||
				component.code.overwrite(node.start, node.end, context, {
 | 
										@bubble($$self, event);
 | 
				
			||||||
					storeName: true,
 | 
					 | 
				
			||||||
					contentOnly: true
 | 
					 | 
				
			||||||
				});
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
								`);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	validateExpression(expression) {
 | 
								this.handler_name = name;
 | 
				
			||||||
		const { callee, type } = expression;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (type !== 'CallExpression') {
 | 
					 | 
				
			||||||
			this.component.error(expression, {
 | 
					 | 
				
			||||||
				code: `invalid-event-handler`,
 | 
					 | 
				
			||||||
				message: `Expected a call expression`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		const { component } = this;
 | 
					 | 
				
			||||||
		const { name } = flattenReference(callee);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (validCalleeObjects.has(name) || name === 'options') return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (name === 'refs') {
 | 
					 | 
				
			||||||
			this.component.refCallees.push(callee);
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (
 | 
						render() {
 | 
				
			||||||
			(callee.type === 'Identifier' && validBuiltins.has(name)) ||
 | 
							if (this.expression) return this.expression.render();
 | 
				
			||||||
			this.component.methods.has(name)
 | 
					 | 
				
			||||||
		) {
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (name[0] === '$') {
 | 
					 | 
				
			||||||
			// assume it's a store method
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		const validCallees = ['this.*', 'refs.*', 'event.*', 'options.*', 'console.*'].concat(
 | 
					 | 
				
			||||||
			Array.from(validBuiltins),
 | 
					 | 
				
			||||||
			Array.from(this.component.methods.keys())
 | 
					 | 
				
			||||||
		);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		let message = `'${component.source.slice(callee.start, callee.end)}' is an invalid callee ` ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (name === 'store') {
 | 
					 | 
				
			||||||
			message += `(did you mean '$${component.source.slice(callee.start + 6, callee.end)}(...)'?)`;
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			message += `(should be one of ${list(validCallees)})`;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (callee.type === 'Identifier' && component.helpers.has(callee.name)) {
 | 
					 | 
				
			||||||
				message += `. '${callee.name}' exists on 'helpers', did you put it in the wrong place?`;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		component.warn(expression, {
 | 
							this.component.template_references.add(this.handler_name);
 | 
				
			||||||
			code: `invalid-callee`,
 | 
							return `ctx.${this.handler_name}`;
 | 
				
			||||||
			message
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					import Node from './shared/Node';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default class Meta extends Node {
 | 
				
			||||||
 | 
						type: 'Meta';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,14 +1,19 @@
 | 
				
			|||||||
import Node from './shared/Node';
 | 
					import Node from './shared/Node';
 | 
				
			||||||
import Block from '../render-dom/Block';
 | 
					import Block from '../render-dom/Block';
 | 
				
			||||||
import mapChildren from './shared/mapChildren';
 | 
					import mapChildren from './shared/mapChildren';
 | 
				
			||||||
 | 
					import TemplateScope from './shared/TemplateScope';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class ThenBlock extends Node {
 | 
					export default class ThenBlock extends Node {
 | 
				
			||||||
	block: Block;
 | 
						block: Block;
 | 
				
			||||||
 | 
						scope: TemplateScope;
 | 
				
			||||||
	children: Node[];
 | 
						children: Node[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	constructor(component, parent, scope, info) {
 | 
						constructor(component, parent, scope, info) {
 | 
				
			||||||
		super(component, parent, scope, info);
 | 
							super(component, parent, scope, info);
 | 
				
			||||||
		this.children = mapChildren(component, parent, scope, info.children);
 | 
					
 | 
				
			||||||
 | 
							this.scope = scope.child();
 | 
				
			||||||
 | 
							this.scope.add(parent.value, parent.expression.dependencies);
 | 
				
			||||||
 | 
							this.children = mapChildren(component, parent, this.scope, info.children);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this.warnIfEmptyBlock();
 | 
							this.warnIfEmptyBlock();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					import Renderer from '../../Renderer';
 | 
				
			||||||
 | 
					import Block from '../../Block';
 | 
				
			||||||
 | 
					import Action from '../../../nodes/Action';
 | 
				
			||||||
 | 
					import Component from '../../../Component';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default function addActions(
 | 
				
			||||||
 | 
						component: Component,
 | 
				
			||||||
 | 
						block: Block,
 | 
				
			||||||
 | 
						target: string,
 | 
				
			||||||
 | 
						actions: Action[]
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
						actions.forEach(action => {
 | 
				
			||||||
 | 
							const { expression } = action;
 | 
				
			||||||
 | 
							let snippet, dependencies;
 | 
				
			||||||
 | 
							if (expression) {
 | 
				
			||||||
 | 
								snippet = expression.render();
 | 
				
			||||||
 | 
								dependencies = expression.dynamic_dependencies;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								expression.declarations.forEach(declaration => {
 | 
				
			||||||
 | 
									block.builders.init.addBlock(declaration);
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const name = block.getUniqueName(
 | 
				
			||||||
 | 
								`${action.name.replace(/[^a-zA-Z0-9_$]/g, '_')}_action`
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							block.addVariable(name);
 | 
				
			||||||
 | 
							const fn = component.imported_declarations.has(action.name) || component.hoistable_names.has(action.name)
 | 
				
			||||||
 | 
								? action.name
 | 
				
			||||||
 | 
								: `ctx.${action.name}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							component.template_references.add(action.name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							block.builders.mount.addLine(
 | 
				
			||||||
 | 
								`${name} = ${fn}.call(null, ${target}${snippet ? `, ${snippet}` : ''}) || {};`
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (dependencies && dependencies.size > 0) {
 | 
				
			||||||
 | 
								let conditional = `typeof ${name}.update === 'function' && `;
 | 
				
			||||||
 | 
								const deps = [...dependencies].map(dependency => `changed.${dependency}`).join(' || ');
 | 
				
			||||||
 | 
								conditional += dependencies.size > 1 ? `(${deps})` : deps;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								block.builders.update.addConditional(
 | 
				
			||||||
 | 
									conditional,
 | 
				
			||||||
 | 
									`${name}.update.call(null, ${snippet});`
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							block.builders.destroy.addLine(
 | 
				
			||||||
 | 
								`if (${name} && typeof ${name}.destroy === 'function') ${name}.destroy();`
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					import Block from '../../Block';
 | 
				
			||||||
 | 
					import EventHandler from '../../../nodes/EventHandler';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default function addEventHandlers(
 | 
				
			||||||
 | 
						block: Block,
 | 
				
			||||||
 | 
						target: string,
 | 
				
			||||||
 | 
						handlers: EventHandler[]
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
						handlers.forEach(handler => {
 | 
				
			||||||
 | 
							let snippet = handler.render();
 | 
				
			||||||
 | 
							if (handler.modifiers.has('preventDefault')) snippet = `@preventDefault(${snippet})`;
 | 
				
			||||||
 | 
							if (handler.modifiers.has('stopPropagation')) snippet = `@stopPropagation(${snippet})`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const opts = ['passive', 'once', 'capture'].filter(mod => handler.modifiers.has(mod));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (opts.length) {
 | 
				
			||||||
 | 
								const optString = (opts.length === 1 && opts[0] === 'capture')
 | 
				
			||||||
 | 
									? 'true'
 | 
				
			||||||
 | 
									: `{ ${opts.map(opt => `${opt}: true`).join(', ')} }`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								block.event_listeners.push(
 | 
				
			||||||
 | 
									`@addListener(${target}, "${handler.name}", ${snippet}, ${optString})`
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								block.event_listeners.push(
 | 
				
			||||||
 | 
									`@addListener(${target}, "${handler.name}", ${snippet})`
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (handler.expression) {
 | 
				
			||||||
 | 
								handler.expression.declarations.forEach(declaration => {
 | 
				
			||||||
 | 
									block.builders.init.addBlock(declaration);
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,16 +1,16 @@
 | 
				
			|||||||
import Renderer from '../Renderer';
 | 
					import Renderer from '../Renderer';
 | 
				
			||||||
import { CompileOptions } from '../../../interfaces';
 | 
					import { CompileOptions } from '../../../interfaces';
 | 
				
			||||||
 | 
					import { snip } from '../utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function(node, renderer: Renderer, options: CompileOptions) {
 | 
					export default function(node, renderer: Renderer, options: CompileOptions) {
 | 
				
			||||||
	const { snippet } = node.expression;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	renderer.append('${(function(__value) { if(@isPromise(__value)) return `');
 | 
						renderer.append('${(function(__value) { if(@isPromise(__value)) return `');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	renderer.render(node.pending.children, options);
 | 
						renderer.render(node.pending.children, options);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	renderer.append('`; return function(ctx) { return `');
 | 
						renderer.append('`; return function(' + (node.value || '') + ') { return `');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	renderer.render(node.then.children, options);
 | 
						renderer.render(node.then.children, options);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	renderer.append(`\`;}(Object.assign({}, ctx, { ${node.value}: __value }));}(${snippet})) }`);
 | 
						const snippet = snip(node.expression);
 | 
				
			||||||
 | 
						renderer.append(`\`;}(__value);}(${snippet})) }`);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					import { snip } from '../utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function(node, renderer, options) {
 | 
					export default function(node, renderer, options) {
 | 
				
			||||||
	renderer.append('${' + node.expression.snippet + '}');
 | 
						renderer.append('${' + snip(node.expression) + '}');
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1,9 +1,13 @@
 | 
				
			|||||||
 | 
					import { snip } from '../utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default function(node, renderer, options) {
 | 
					export default function(node, renderer, options) {
 | 
				
			||||||
 | 
						const snippet = snip(node.expression);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	renderer.append(
 | 
						renderer.append(
 | 
				
			||||||
		node.parent &&
 | 
							node.parent &&
 | 
				
			||||||
		node.parent.type === 'Element' &&
 | 
							node.parent.type === 'Element' &&
 | 
				
			||||||
		node.parent.name === 'style'
 | 
							node.parent.name === 'style'
 | 
				
			||||||
			? '${' + node.expression.snippet + '}'
 | 
								? '${' + snippet + '}'
 | 
				
			||||||
			: '${@escape(' + node.expression.snippet + ')}'
 | 
								: '${@escape(' + snippet + ')}'
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					export function snip(expression) {
 | 
				
			||||||
 | 
						return `[✂${expression.node.start}-${expression.node.end}✂]`;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,16 +0,0 @@
 | 
				
			|||||||
import checkForDupes from '../utils/checkForDupes';
 | 
					 | 
				
			||||||
import checkForComputedKeys from '../utils/checkForComputedKeys';
 | 
					 | 
				
			||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function actions(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	if (prop.value.type !== 'ObjectExpression') {
 | 
					 | 
				
			||||||
		component.error(prop, {
 | 
					 | 
				
			||||||
			code: `invalid-actions`,
 | 
					 | 
				
			||||||
			message: `The 'actions' property must be an object literal`
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	checkForDupes(component, prop.value.properties);
 | 
					 | 
				
			||||||
	checkForComputedKeys(component, prop.value.properties);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,21 +0,0 @@
 | 
				
			|||||||
import checkForDupes from '../utils/checkForDupes';
 | 
					 | 
				
			||||||
import checkForComputedKeys from '../utils/checkForComputedKeys';
 | 
					 | 
				
			||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function transitions(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	if (prop.value.type !== 'ObjectExpression') {
 | 
					 | 
				
			||||||
		component.error(prop, {
 | 
					 | 
				
			||||||
			code: `invalid-transitions-property`,
 | 
					 | 
				
			||||||
			message: `The 'transitions' property must be an object literal`
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	checkForDupes(component, prop.value.properties);
 | 
					 | 
				
			||||||
	checkForComputedKeys(component, prop.value.properties);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	prop.value.properties.forEach(() => {
 | 
					 | 
				
			||||||
		// TODO probably some validation that can happen here...
 | 
					 | 
				
			||||||
		// checking for use of `this` etc?
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,36 +0,0 @@
 | 
				
			|||||||
import checkForDupes from '../utils/checkForDupes';
 | 
					 | 
				
			||||||
import checkForComputedKeys from '../utils/checkForComputedKeys';
 | 
					 | 
				
			||||||
import getName from '../../../../utils/getName';
 | 
					 | 
				
			||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function components(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	if (prop.value.type !== 'ObjectExpression') {
 | 
					 | 
				
			||||||
		component.error(prop, {
 | 
					 | 
				
			||||||
			code: `invalid-components-property`,
 | 
					 | 
				
			||||||
			message: `The 'components' property must be an object literal`
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	checkForDupes(component, prop.value.properties);
 | 
					 | 
				
			||||||
	checkForComputedKeys(component, prop.value.properties);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	prop.value.properties.forEach((node: Node) => {
 | 
					 | 
				
			||||||
		const name = getName(node.key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (name === 'state') {
 | 
					 | 
				
			||||||
			// TODO is this still true?
 | 
					 | 
				
			||||||
			component.error(node, {
 | 
					 | 
				
			||||||
				code: `invalid-name`,
 | 
					 | 
				
			||||||
				message: `Component constructors cannot be called 'state' due to technical limitations`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (!/^[A-Z]/.test(name)) {
 | 
					 | 
				
			||||||
			component.error(node, {
 | 
					 | 
				
			||||||
				code: `component-lowercase`,
 | 
					 | 
				
			||||||
				message: `Component names must be capitalised`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,84 +0,0 @@
 | 
				
			|||||||
import checkForDupes from '../utils/checkForDupes';
 | 
					 | 
				
			||||||
import checkForComputedKeys from '../utils/checkForComputedKeys';
 | 
					 | 
				
			||||||
import getName from '../../../../utils/getName';
 | 
					 | 
				
			||||||
import isValidIdentifier from '../../../../utils/isValidIdentifier';
 | 
					 | 
				
			||||||
import reservedNames from '../../../../utils/reservedNames';
 | 
					 | 
				
			||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import walkThroughTopFunctionScope from '../../../../utils/walkThroughTopFunctionScope';
 | 
					 | 
				
			||||||
import isThisGetCallExpression from '../../../../utils/isThisGetCallExpression';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const isFunctionExpression = new Set([
 | 
					 | 
				
			||||||
	'FunctionExpression',
 | 
					 | 
				
			||||||
	'ArrowFunctionExpression',
 | 
					 | 
				
			||||||
]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function computed(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	if (prop.value.type !== 'ObjectExpression') {
 | 
					 | 
				
			||||||
		component.error(prop, {
 | 
					 | 
				
			||||||
			code: `invalid-computed-property`,
 | 
					 | 
				
			||||||
			message: `The 'computed' property must be an object literal`
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	checkForDupes(component, prop.value.properties);
 | 
					 | 
				
			||||||
	checkForComputedKeys(component, prop.value.properties);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	prop.value.properties.forEach((computation: Node) => {
 | 
					 | 
				
			||||||
		const name = getName(computation.key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (!isValidIdentifier(name)) {
 | 
					 | 
				
			||||||
			const suggestion = name.replace(/[^_$a-z0-9]/ig, '_').replace(/^\d/, '_$&');
 | 
					 | 
				
			||||||
			component.error(computation.key, {
 | 
					 | 
				
			||||||
				code: `invalid-computed-name`,
 | 
					 | 
				
			||||||
				message: `Computed property name '${name}' is invalid — must be a valid identifier such as ${suggestion}`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (reservedNames.has(name)) {
 | 
					 | 
				
			||||||
			component.error(computation.key, {
 | 
					 | 
				
			||||||
				code: `invalid-computed-name`,
 | 
					 | 
				
			||||||
				message: `Computed property name '${name}' is invalid — cannot be a JavaScript reserved word`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (!isFunctionExpression.has(computation.value.type)) {
 | 
					 | 
				
			||||||
			component.error(computation.value, {
 | 
					 | 
				
			||||||
				code: `invalid-computed-value`,
 | 
					 | 
				
			||||||
				message: `Computed properties can be function expressions or arrow function expressions`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		const { body, params } = computation.value;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		walkThroughTopFunctionScope(body, (node: Node) => {
 | 
					 | 
				
			||||||
			if (isThisGetCallExpression(node) && !node.callee.property.computed) {
 | 
					 | 
				
			||||||
				component.error(node, {
 | 
					 | 
				
			||||||
					code: `impure-computed`,
 | 
					 | 
				
			||||||
					message: `Cannot use this.get(...) — values must be passed into the function as arguments`
 | 
					 | 
				
			||||||
				});
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (node.type === 'ThisExpression') {
 | 
					 | 
				
			||||||
				component.error(node, {
 | 
					 | 
				
			||||||
					code: `impure-computed`,
 | 
					 | 
				
			||||||
					message: `Computed properties should be pure functions — they do not have access to the component instance and cannot use 'this'. Did you mean to put this in 'methods'?`
 | 
					 | 
				
			||||||
				});
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (params.length === 0) {
 | 
					 | 
				
			||||||
			component.error(computation.value, {
 | 
					 | 
				
			||||||
				code: `impure-computed`,
 | 
					 | 
				
			||||||
				message: `A computed value must depend on at least one property`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (params.length > 1) {
 | 
					 | 
				
			||||||
			component.error(computation.value, {
 | 
					 | 
				
			||||||
				code: `invalid-computed-arguments`,
 | 
					 | 
				
			||||||
				message: `Computed properties must take a single argument`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,15 +0,0 @@
 | 
				
			|||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const disallowed = new Set(['Literal', 'ObjectExpression', 'ArrayExpression']);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function data(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	while (prop.type === 'ParenthesizedExpression') prop = prop.expression;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (disallowed.has(prop.value.type)) {
 | 
					 | 
				
			||||||
		component.error(prop.value, {
 | 
					 | 
				
			||||||
			code: `invalid-data-property`,
 | 
					 | 
				
			||||||
			message: `'data' must be a function`
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,16 +0,0 @@
 | 
				
			|||||||
import checkForDupes from '../utils/checkForDupes';
 | 
					 | 
				
			||||||
import checkForComputedKeys from '../utils/checkForComputedKeys';
 | 
					 | 
				
			||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function events(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	if (prop.value.type !== 'ObjectExpression') {
 | 
					 | 
				
			||||||
		component.error(prop, {
 | 
					 | 
				
			||||||
			code: `invalid-events-property`,
 | 
					 | 
				
			||||||
			message: `The 'events' property must be an object literal`
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	checkForDupes(component, prop.value.properties);
 | 
					 | 
				
			||||||
	checkForComputedKeys(component, prop.value.properties);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,49 +0,0 @@
 | 
				
			|||||||
import checkForDupes from '../utils/checkForDupes';
 | 
					 | 
				
			||||||
import checkForComputedKeys from '../utils/checkForComputedKeys';
 | 
					 | 
				
			||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import walkThroughTopFunctionScope from '../../../../utils/walkThroughTopFunctionScope';
 | 
					 | 
				
			||||||
import isThisGetCallExpression from '../../../../utils/isThisGetCallExpression';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function helpers(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	if (prop.value.type !== 'ObjectExpression') {
 | 
					 | 
				
			||||||
		component.error(prop, {
 | 
					 | 
				
			||||||
			code: `invalid-helpers-property`,
 | 
					 | 
				
			||||||
			message: `The 'helpers' property must be an object literal`
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	checkForDupes(component, prop.value.properties);
 | 
					 | 
				
			||||||
	checkForComputedKeys(component, prop.value.properties);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	prop.value.properties.forEach((prop: Node) => {
 | 
					 | 
				
			||||||
		if (!/FunctionExpression/.test(prop.value.type)) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		let usesArguments = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		walkThroughTopFunctionScope(prop.value.body, (node: Node) => {
 | 
					 | 
				
			||||||
			if (isThisGetCallExpression(node) && !node.callee.property.computed) {
 | 
					 | 
				
			||||||
				component.error(node, {
 | 
					 | 
				
			||||||
					code: `impure-helper`,
 | 
					 | 
				
			||||||
					message: `Cannot use this.get(...) — values must be passed into the helper function as arguments`
 | 
					 | 
				
			||||||
				});
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (node.type === 'ThisExpression') {
 | 
					 | 
				
			||||||
				component.error(node, {
 | 
					 | 
				
			||||||
					code: `impure-helper`,
 | 
					 | 
				
			||||||
					message: `Helpers should be pure functions — they do not have access to the component instance and cannot use 'this'. Did you mean to put this in 'methods'?`
 | 
					 | 
				
			||||||
				});
 | 
					 | 
				
			||||||
			} else if (node.type === 'Identifier' && node.name === 'arguments') {
 | 
					 | 
				
			||||||
				usesArguments = true;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (prop.value.params.length === 0 && !usesArguments) {
 | 
					 | 
				
			||||||
			component.warn(prop, {
 | 
					 | 
				
			||||||
				code: `impure-helper`,
 | 
					 | 
				
			||||||
				message: `Helpers should be pure functions, with at least one argument`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,11 +0,0 @@
 | 
				
			|||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function immutable(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	if (prop.value.type !== 'Literal' || typeof prop.value.value !== 'boolean') {
 | 
					 | 
				
			||||||
		component.error(prop.value, {
 | 
					 | 
				
			||||||
			code: `invalid-immutable-property`,
 | 
					 | 
				
			||||||
			message: `'immutable' must be a boolean literal`
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,47 +0,0 @@
 | 
				
			|||||||
import data from './data';
 | 
					 | 
				
			||||||
import actions from './actions';
 | 
					 | 
				
			||||||
import animations from './animations';
 | 
					 | 
				
			||||||
import computed from './computed';
 | 
					 | 
				
			||||||
import oncreate from './oncreate';
 | 
					 | 
				
			||||||
import ondestroy from './ondestroy';
 | 
					 | 
				
			||||||
import onstate from './onstate';
 | 
					 | 
				
			||||||
import onupdate from './onupdate';
 | 
					 | 
				
			||||||
import onrender from './onrender';
 | 
					 | 
				
			||||||
import onteardown from './onteardown';
 | 
					 | 
				
			||||||
import helpers from './helpers';
 | 
					 | 
				
			||||||
import methods from './methods';
 | 
					 | 
				
			||||||
import components from './components';
 | 
					 | 
				
			||||||
import events from './events';
 | 
					 | 
				
			||||||
import namespace from './namespace';
 | 
					 | 
				
			||||||
import preload from './preload';
 | 
					 | 
				
			||||||
import props from './props';
 | 
					 | 
				
			||||||
import tag from './tag';
 | 
					 | 
				
			||||||
import transitions from './transitions';
 | 
					 | 
				
			||||||
import setup from './setup';
 | 
					 | 
				
			||||||
import store from './store';
 | 
					 | 
				
			||||||
import immutable from './immutable';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default {
 | 
					 | 
				
			||||||
	data,
 | 
					 | 
				
			||||||
	actions,
 | 
					 | 
				
			||||||
	animations,
 | 
					 | 
				
			||||||
	computed,
 | 
					 | 
				
			||||||
	oncreate,
 | 
					 | 
				
			||||||
	ondestroy,
 | 
					 | 
				
			||||||
	onstate,
 | 
					 | 
				
			||||||
	onupdate,
 | 
					 | 
				
			||||||
	onrender,
 | 
					 | 
				
			||||||
	onteardown,
 | 
					 | 
				
			||||||
	helpers,
 | 
					 | 
				
			||||||
	methods,
 | 
					 | 
				
			||||||
	components,
 | 
					 | 
				
			||||||
	events,
 | 
					 | 
				
			||||||
	namespace,
 | 
					 | 
				
			||||||
	preload,
 | 
					 | 
				
			||||||
	props,
 | 
					 | 
				
			||||||
	tag,
 | 
					 | 
				
			||||||
	transitions,
 | 
					 | 
				
			||||||
	setup,
 | 
					 | 
				
			||||||
	store,
 | 
					 | 
				
			||||||
	immutable,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@ -1,42 +0,0 @@
 | 
				
			|||||||
import checkForAccessors from '../utils/checkForAccessors';
 | 
					 | 
				
			||||||
import checkForDupes from '../utils/checkForDupes';
 | 
					 | 
				
			||||||
import checkForComputedKeys from '../utils/checkForComputedKeys';
 | 
					 | 
				
			||||||
import usesThisOrArguments from '../utils/usesThisOrArguments';
 | 
					 | 
				
			||||||
import getName from '../../../../utils/getName';
 | 
					 | 
				
			||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const builtin = new Set(['set', 'get', 'on', 'fire', 'destroy']);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function methods(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	if (prop.value.type !== 'ObjectExpression') {
 | 
					 | 
				
			||||||
		component.error(prop, {
 | 
					 | 
				
			||||||
			code: `invalid-methods-property`,
 | 
					 | 
				
			||||||
			message: `The 'methods' property must be an object literal`
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	checkForAccessors(component, prop.value.properties, 'Methods');
 | 
					 | 
				
			||||||
	checkForDupes(component, prop.value.properties);
 | 
					 | 
				
			||||||
	checkForComputedKeys(component, prop.value.properties);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	prop.value.properties.forEach((prop: Node) => {
 | 
					 | 
				
			||||||
		const name = getName(prop.key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (builtin.has(name)) {
 | 
					 | 
				
			||||||
			component.error(prop, {
 | 
					 | 
				
			||||||
				code: `invalid-method-name`,
 | 
					 | 
				
			||||||
				message: `Cannot overwrite built-in method '${name}'`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (prop.value.type === 'ArrowFunctionExpression') {
 | 
					 | 
				
			||||||
			if (usesThisOrArguments(prop.value.body)) {
 | 
					 | 
				
			||||||
				component.error(prop, {
 | 
					 | 
				
			||||||
					code: `invalid-method-value`,
 | 
					 | 
				
			||||||
					message: `Method '${prop.key.name}' should be a function expression, not an arrow function expression`
 | 
					 | 
				
			||||||
				});
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,33 +0,0 @@
 | 
				
			|||||||
import * as namespaces from '../../../../utils/namespaces';
 | 
					 | 
				
			||||||
import nodeToString from '../../../../utils/nodeToString'
 | 
					 | 
				
			||||||
import fuzzymatch from '../../utils/fuzzymatch';
 | 
					 | 
				
			||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const valid = new Set(namespaces.validNamespaces);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function namespace(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	const ns = nodeToString(prop.value);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (typeof ns !== 'string') {
 | 
					 | 
				
			||||||
		component.error(prop, {
 | 
					 | 
				
			||||||
			code: `invalid-namespace-property`,
 | 
					 | 
				
			||||||
			message: `The 'namespace' property must be a string literal representing a valid namespace`
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!valid.has(ns)) {
 | 
					 | 
				
			||||||
		const match = fuzzymatch(ns, namespaces.validNamespaces);
 | 
					 | 
				
			||||||
		if (match) {
 | 
					 | 
				
			||||||
			component.error(prop, {
 | 
					 | 
				
			||||||
				code: `invalid-namespace-property`,
 | 
					 | 
				
			||||||
				message: `Invalid namespace '${ns}' (did you mean '${match}'?)`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			component.error(prop, {
 | 
					 | 
				
			||||||
				code: `invalid-namespace-property`,
 | 
					 | 
				
			||||||
				message: `Invalid namespace '${ns}'`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,14 +0,0 @@
 | 
				
			|||||||
import usesThisOrArguments from '../utils/usesThisOrArguments';
 | 
					 | 
				
			||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function oncreate(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	if (prop.value.type === 'ArrowFunctionExpression') {
 | 
					 | 
				
			||||||
		if (usesThisOrArguments(prop.value.body)) {
 | 
					 | 
				
			||||||
			component.error(prop, {
 | 
					 | 
				
			||||||
				code: `invalid-oncreate-property`,
 | 
					 | 
				
			||||||
				message: `'oncreate' should be a function expression, not an arrow function expression`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,14 +0,0 @@
 | 
				
			|||||||
import usesThisOrArguments from '../utils/usesThisOrArguments';
 | 
					 | 
				
			||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function ondestroy(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	if (prop.value.type === 'ArrowFunctionExpression') {
 | 
					 | 
				
			||||||
		if (usesThisOrArguments(prop.value.body)) {
 | 
					 | 
				
			||||||
			component.error(prop, {
 | 
					 | 
				
			||||||
				code: `invalid-ondestroy-property`,
 | 
					 | 
				
			||||||
				message: `'ondestroy' should be a function expression, not an arrow function expression`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,12 +0,0 @@
 | 
				
			|||||||
import oncreate from './oncreate';
 | 
					 | 
				
			||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function onrender(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	component.warn(prop, {
 | 
					 | 
				
			||||||
		code: `deprecated-onrender`,
 | 
					 | 
				
			||||||
		message: `'onrender' has been deprecated in favour of 'oncreate', and will cause an error in Svelte 2.x`
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	oncreate(component, prop);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,14 +0,0 @@
 | 
				
			|||||||
import usesThisOrArguments from '../utils/usesThisOrArguments';
 | 
					 | 
				
			||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function onstate(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	if (prop.value.type === 'ArrowFunctionExpression') {
 | 
					 | 
				
			||||||
		if (usesThisOrArguments(prop.value.body)) {
 | 
					 | 
				
			||||||
			component.error(prop, {
 | 
					 | 
				
			||||||
				code: `invalid-onstate-property`,
 | 
					 | 
				
			||||||
				message: `'onstate' should be a function expression, not an arrow function expression`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,12 +0,0 @@
 | 
				
			|||||||
import ondestroy from './ondestroy';
 | 
					 | 
				
			||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function onteardown(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	component.warn(prop, {
 | 
					 | 
				
			||||||
		code: `deprecated-onteardown`,
 | 
					 | 
				
			||||||
		message: `'onteardown' has been deprecated in favour of 'ondestroy', and will cause an error in Svelte 2.x`
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ondestroy(component, prop);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,14 +0,0 @@
 | 
				
			|||||||
import usesThisOrArguments from '../utils/usesThisOrArguments';
 | 
					 | 
				
			||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function onupdate(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	if (prop.value.type === 'ArrowFunctionExpression') {
 | 
					 | 
				
			||||||
		if (usesThisOrArguments(prop.value.body)) {
 | 
					 | 
				
			||||||
			component.error(prop, {
 | 
					 | 
				
			||||||
				code: `invalid-onupdate-property`,
 | 
					 | 
				
			||||||
				message: `'onupdate' should be a function expression, not an arrow function expression`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,6 +0,0 @@
 | 
				
			|||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function preload(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	// not sure there's anything we need to check here...
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,21 +0,0 @@
 | 
				
			|||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import nodeToString from '../../../../utils/nodeToString';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function props(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	if (prop.value.type !== 'ArrayExpression') {
 | 
					 | 
				
			||||||
		component.error(prop.value, {
 | 
					 | 
				
			||||||
			code: `invalid-props-property`,
 | 
					 | 
				
			||||||
			message: `'props' must be an array expression, if specified`
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	prop.value.elements.forEach((element: Node) => {
 | 
					 | 
				
			||||||
		if (typeof nodeToString(element) !== 'string') {
 | 
					 | 
				
			||||||
			component.error(element, {
 | 
					 | 
				
			||||||
				code: `invalid-props-property`,
 | 
					 | 
				
			||||||
				message: `'props' must be an array of string literals`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,15 +0,0 @@
 | 
				
			|||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const disallowed = new Set(['Literal', 'ObjectExpression', 'ArrayExpression']);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function setup(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	while (prop.type === 'ParenthesizedExpression') prop = prop.expression;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (disallowed.has(prop.value.type)) {
 | 
					 | 
				
			||||||
		component.error(prop.value, {
 | 
					 | 
				
			||||||
			code: `invalid-setup-property`,
 | 
					 | 
				
			||||||
			message: `'setup' must be a function`
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,6 +0,0 @@
 | 
				
			|||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function store(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	// not sure there's anything we need to check here...
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,20 +0,0 @@
 | 
				
			|||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import nodeToString from '../../../../utils/nodeToString';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function tag(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	const tag = nodeToString(prop.value);
 | 
					 | 
				
			||||||
	if (typeof tag !== 'string') {
 | 
					 | 
				
			||||||
		component.error(prop.value, {
 | 
					 | 
				
			||||||
			code: `invalid-tag-property`,
 | 
					 | 
				
			||||||
			message: `'tag' must be a string literal`
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!/^[a-zA-Z][a-zA-Z0-9]*-[a-zA-Z0-9-]+$/.test(tag)) {
 | 
					 | 
				
			||||||
		component.error(prop.value, {
 | 
					 | 
				
			||||||
			code: `invalid-tag-property`,
 | 
					 | 
				
			||||||
			message: `tag name must be two or more words joined by the '-' character`
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,21 +0,0 @@
 | 
				
			|||||||
import checkForDupes from '../utils/checkForDupes';
 | 
					 | 
				
			||||||
import checkForComputedKeys from '../utils/checkForComputedKeys';
 | 
					 | 
				
			||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function transitions(component: Component, prop: Node) {
 | 
					 | 
				
			||||||
	if (prop.value.type !== 'ObjectExpression') {
 | 
					 | 
				
			||||||
		component.error(prop, {
 | 
					 | 
				
			||||||
			code: `invalid-transitions-property`,
 | 
					 | 
				
			||||||
			message: `The 'transitions' property must be an object literal`
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	checkForDupes(component, prop.value.properties);
 | 
					 | 
				
			||||||
	checkForComputedKeys(component, prop.value.properties);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	prop.value.properties.forEach(() => {
 | 
					 | 
				
			||||||
		// TODO probably some validation that can happen here...
 | 
					 | 
				
			||||||
		// checking for use of `this` etc?
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,17 +0,0 @@
 | 
				
			|||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function checkForAccessors(
 | 
					 | 
				
			||||||
	component: Component,
 | 
					 | 
				
			||||||
	properties: Node[],
 | 
					 | 
				
			||||||
	label: string
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
	properties.forEach(prop => {
 | 
					 | 
				
			||||||
		if (prop.kind !== 'init') {
 | 
					 | 
				
			||||||
			component.error(prop, {
 | 
					 | 
				
			||||||
				code: `illegal-accessor`,
 | 
					 | 
				
			||||||
				message: `${label} cannot use getters and setters`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,16 +0,0 @@
 | 
				
			|||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function checkForComputedKeys(
 | 
					 | 
				
			||||||
	component: Component,
 | 
					 | 
				
			||||||
	properties: Node[]
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
	properties.forEach(prop => {
 | 
					 | 
				
			||||||
		if (prop.key.computed) {
 | 
					 | 
				
			||||||
			component.error(prop, {
 | 
					 | 
				
			||||||
				code: `computed-key`,
 | 
					 | 
				
			||||||
				message: `Cannot use computed keys`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,23 +0,0 @@
 | 
				
			|||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
import getName from '../../../../utils/getName';
 | 
					 | 
				
			||||||
import Component from '../../../Component';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function checkForDupes(
 | 
					 | 
				
			||||||
	component: Component,
 | 
					 | 
				
			||||||
	properties: Node[]
 | 
					 | 
				
			||||||
) {
 | 
					 | 
				
			||||||
	const seen = new Set();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	properties.forEach(prop => {
 | 
					 | 
				
			||||||
		const name = getName(prop.key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (seen.has(name)) {
 | 
					 | 
				
			||||||
			component.error(prop, {
 | 
					 | 
				
			||||||
				code: `duplicate-property`,
 | 
					 | 
				
			||||||
				message: `Duplicate property '${name}'`
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		seen.add(name);
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,33 +0,0 @@
 | 
				
			|||||||
import { walk } from 'estree-walker';
 | 
					 | 
				
			||||||
import isReference from 'is-reference';
 | 
					 | 
				
			||||||
import { Node } from '../../../../interfaces';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function usesThisOrArguments(node: Node) {
 | 
					 | 
				
			||||||
	let result = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	walk(node, {
 | 
					 | 
				
			||||||
		enter(node: Node, parent: Node) {
 | 
					 | 
				
			||||||
			if (
 | 
					 | 
				
			||||||
				result ||
 | 
					 | 
				
			||||||
				node.type === 'FunctionExpression' ||
 | 
					 | 
				
			||||||
				node.type === 'FunctionDeclaration'
 | 
					 | 
				
			||||||
			) {
 | 
					 | 
				
			||||||
				return this.skip();
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (node.type === 'ThisExpression') {
 | 
					 | 
				
			||||||
				result = true;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (
 | 
					 | 
				
			||||||
				node.type === 'Identifier' &&
 | 
					 | 
				
			||||||
				isReference(node, parent) &&
 | 
					 | 
				
			||||||
				node.name === 'arguments'
 | 
					 | 
				
			||||||
			) {
 | 
					 | 
				
			||||||
				result = true;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,8 +0,0 @@
 | 
				
			|||||||
import FuzzySet from './FuzzySet';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default function fuzzymatch(name: string, names: string[]) {
 | 
					 | 
				
			||||||
	const set = new FuzzySet(names);
 | 
					 | 
				
			||||||
	const matches = set.get(name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return matches && matches[0] && matches[0][0] > 0.7 ? matches[0][1] : null;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,34 +1,4 @@
 | 
				
			|||||||
import compile from './compile/index';
 | 
					 | 
				
			||||||
import { CompileOptions } from './interfaces';
 | 
					 | 
				
			||||||
import deprecate from './utils/deprecate';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function create(source: string, options: CompileOptions = {}) {
 | 
					 | 
				
			||||||
	const onerror = options.onerror || (err => {
 | 
					 | 
				
			||||||
		throw err;
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (options.onerror) {
 | 
					 | 
				
			||||||
		// TODO remove in v3
 | 
					 | 
				
			||||||
		deprecate(`Instead of using options.onerror, wrap svelte.create in a try-catch block`);
 | 
					 | 
				
			||||||
		delete options.onerror;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	options.format = 'eval';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	try {
 | 
					 | 
				
			||||||
		const compiled = compile(source, options);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (!compiled || !compiled.js.code) {
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return (new Function(`return ${compiled.js.code}`))();
 | 
					 | 
				
			||||||
	} catch (err) {
 | 
					 | 
				
			||||||
		onerror(err);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export { default as compile } from './compile/index';
 | 
					export { default as compile } from './compile/index';
 | 
				
			||||||
export { default as parse } from './parse/index';
 | 
					 | 
				
			||||||
export { default as preprocess } from './preprocess/index';
 | 
					export { default as preprocess } from './preprocess/index';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const VERSION = '__VERSION__';
 | 
					export const VERSION = '__VERSION__';
 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show More
					Loading…
					
					
				
		Reference in new issue