more typescript conversion

pull/573/head
Rich-Harris 8 years ago
parent b619d077a1
commit 7c3fca57cf

@ -1,8 +1,11 @@
import path from 'path';
import nodeResolve from 'rollup-plugin-node-resolve'; import nodeResolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs'; import commonjs from 'rollup-plugin-commonjs';
import json from 'rollup-plugin-json'; import json from 'rollup-plugin-json';
import typescript from 'rollup-plugin-typescript'; import typescript from 'rollup-plugin-typescript';
const src = path.resolve( 'src' );
export default { export default {
entry: 'src/index.ts', entry: 'src/index.ts',
moduleName: 'svelte', moduleName: 'svelte',
@ -10,6 +13,16 @@ export default {
{ dest: 'compiler/svelte.js', format: 'umd' } { dest: 'compiler/svelte.js', format: 'umd' }
], ],
plugins: [ plugins: [
{
resolveId ( importee, importer ) {
// bit of a hack — TypeScript only really works if it can resolve imports,
// but they misguidedly chose to reject imports with file extensions. This
// means we need to resolve them here
if ( importer && importer.startsWith( src ) && importee[0] === '.' && path.extname( importee ) === '' ) {
return path.resolve( path.dirname( importer ), `${importee}.ts` );
}
}
},
nodeResolve({ jsnext: true, module: true }), nodeResolve({ jsnext: true, module: true }),
commonjs(), commonjs(),
json(), json(),

@ -1,15 +1,15 @@
import MagicString, { Bundle } from 'magic-string'; import MagicString, { Bundle } from 'magic-string';
import { walk } from 'estree-walker'; import { walk } from 'estree-walker';
import isReference from '../utils/isReference.ts'; import isReference from '../utils/isReference';
import flattenReference from '../utils/flattenReference.ts'; import flattenReference from '../utils/flattenReference';
import globalWhitelist from '../utils/globalWhitelist.ts'; import globalWhitelist from '../utils/globalWhitelist';
import reservedNames from '../utils/reservedNames.ts'; import reservedNames from '../utils/reservedNames';
import namespaces from '../utils/namespaces.ts'; import namespaces from '../utils/namespaces';
import { removeNode, removeObjectKey } from '../utils/removeNode.ts'; import { removeNode, removeObjectKey } from '../utils/removeNode';
import getIntro from './shared/utils/getIntro.ts'; import getIntro from './shared/utils/getIntro';
import getOutro from './shared/utils/getOutro.ts'; import getOutro from './shared/utils/getOutro';
import processCss from './shared/processCss.ts'; import processCss from './shared/processCss';
import annotateWithScopes from '../utils/annotateWithScopes.ts'; import annotateWithScopes from '../utils/annotateWithScopes';
const test = typeof global !== 'undefined' && global.__svelte_test; const test = typeof global !== 'undefined' && global.__svelte_test;

@ -1,4 +1,4 @@
import CodeBuilder from '../../utils/CodeBuilder.ts'; import CodeBuilder from '../../utils/CodeBuilder';
import deindent from '../../utils/deindent.js'; import deindent from '../../utils/deindent.js';
export default class Block { export default class Block {

@ -1,14 +1,14 @@
import MagicString from 'magic-string'; import MagicString from 'magic-string';
import { parseExpressionAt } from 'acorn'; import { parseExpressionAt } from 'acorn';
import annotateWithScopes from '../../utils/annotateWithScopes.ts'; import annotateWithScopes from '../../utils/annotateWithScopes';
import isReference from '../../utils/isReference.ts'; import isReference from '../../utils/isReference';
import { walk } from 'estree-walker'; import { walk } from 'estree-walker';
import deindent from '../../utils/deindent.js'; import deindent from '../../utils/deindent.js';
import CodeBuilder from '../../utils/CodeBuilder.ts'; import CodeBuilder from '../../utils/CodeBuilder';
import visit from './visit.ts'; import visit from './visit';
import shared from './shared.ts'; import shared from './shared';
import Generator from '../Generator.ts'; import Generator from '../Generator';
import preprocess from './preprocess.ts'; import preprocess from './preprocess';
class DomGenerator extends Generator { class DomGenerator extends Generator {
constructor ( parsed, source, name, options ) { constructor ( parsed, source, name, options ) {

@ -1,5 +1,5 @@
import Block from './Block.ts'; import Block from './Block';
import { trimStart, trimEnd } from '../../utils/trim.ts'; import { trimStart, trimEnd } from '../../utils/trim';
import { assign } from '../../shared/index.js'; import { assign } from '../../shared/index.js';
function isElseIf ( node ) { function isElseIf ( node ) {

@ -1,4 +1,4 @@
import visitors from './visitors/index.ts'; import visitors from './visitors/index';
export default function visit ( generator, block, state, node ) { export default function visit ( generator, block, state, node ) {
const visitor = visitors[ node.type ]; const visitor = visitors[ node.type ];

@ -1,6 +1,6 @@
import deindent from '../../../../utils/deindent.js'; import deindent from '../../../../utils/deindent.js';
import flattenReference from '../../../../utils/flattenReference.ts'; import flattenReference from '../../../../utils/flattenReference';
import getSetter from '../shared/binding/getSetter.ts'; import getSetter from '../shared/binding/getSetter';
export default function visitBinding ( generator, block, state, node, attribute, local ) { export default function visitBinding ( generator, block, state, node, attribute, local ) {
const { name } = flattenReference( attribute.value ); const { name } = flattenReference( attribute.value );

@ -1,10 +1,10 @@
import deindent from '../../../../utils/deindent.js'; import deindent from '../../../../utils/deindent.js';
import CodeBuilder from '../../../../utils/CodeBuilder.ts'; import CodeBuilder from '../../../../utils/CodeBuilder';
import visit from '../../visit.ts'; import visit from '../../visit';
import visitAttribute from './Attribute.ts'; import visitAttribute from './Attribute';
import visitEventHandler from './EventHandler.ts'; import visitEventHandler from './EventHandler';
import visitBinding from './Binding.ts'; import visitBinding from './Binding';
import visitRef from './Ref.ts'; import visitRef from './Ref';
function stringifyProps ( props ) { function stringifyProps ( props ) {
if ( !props.length ) return '{}'; if ( !props.length ) return '{}';

@ -1,5 +1,5 @@
import deindent from '../../../utils/deindent.js'; import deindent from '../../../utils/deindent.js';
import visit from '../visit.ts'; import visit from '../visit';
export default function visitEachBlock ( generator, block, state, node ) { export default function visitEachBlock ( generator, block, state, node ) {
const each_block = generator.getUniqueName( `each_block` ); const each_block = generator.getUniqueName( `each_block` );

@ -1,6 +1,6 @@
import attributeLookup from './lookup.ts'; import attributeLookup from './lookup';
import deindent from '../../../../utils/deindent.js'; import deindent from '../../../../utils/deindent.js';
import getStaticAttributeValue from './getStaticAttributeValue.ts'; import getStaticAttributeValue from './getStaticAttributeValue';
export default function visitAttribute ( generator, block, state, node, attribute ) { export default function visitAttribute ( generator, block, state, node, attribute ) {
const name = attribute.name; const name = attribute.name;

@ -1,7 +1,7 @@
import deindent from '../../../../utils/deindent.js'; import deindent from '../../../../utils/deindent.js';
import flattenReference from '../../../../utils/flattenReference.ts'; import flattenReference from '../../../../utils/flattenReference';
import getSetter from '../shared/binding/getSetter.ts'; import getSetter from '../shared/binding/getSetter';
import getStaticAttributeValue from './getStaticAttributeValue.ts'; import getStaticAttributeValue from './getStaticAttributeValue';
export default function visitBinding ( generator, block, state, node, attribute ) { export default function visitBinding ( generator, block, state, node, attribute ) {
const { name, parts } = flattenReference( attribute.value ); const { name, parts } = flattenReference( attribute.value );

@ -1,12 +1,12 @@
import deindent from '../../../../utils/deindent.js'; import deindent from '../../../../utils/deindent.js';
import visit from '../../visit.ts'; import visit from '../../visit';
import visitComponent from '../Component/Component.ts'; import visitComponent from '../Component/Component';
import visitWindow from './meta/Window.ts'; import visitWindow from './meta/Window';
import visitAttribute from './Attribute.ts'; import visitAttribute from './Attribute';
import visitEventHandler from './EventHandler.ts'; import visitEventHandler from './EventHandler';
import visitBinding from './Binding.ts'; import visitBinding from './Binding';
import visitRef from './Ref.ts'; import visitRef from './Ref';
import addTransitions from './addTransitions.ts'; import addTransitions from './addTransitions';
const meta = { const meta = {
':Window': visitWindow ':Window': visitWindow

@ -1,5 +1,5 @@
import deindent from '../../../../utils/deindent.js'; import deindent from '../../../../utils/deindent.js';
import flattenReference from '../../../../utils/flattenReference.ts'; import flattenReference from '../../../../utils/flattenReference';
export default function visitEventHandler ( generator, block, state, node, attribute ) { export default function visitEventHandler ( generator, block, state, node, attribute ) {
const name = attribute.name; const name = attribute.name;

@ -1,4 +1,4 @@
import flattenReference from '../../../../../utils/flattenReference.ts'; import flattenReference from '../../../../../utils/flattenReference';
import deindent from '../../../../../utils/deindent.js'; import deindent from '../../../../../utils/deindent.js';
const associatedEvents = { const associatedEvents = {

@ -1,5 +1,5 @@
import deindent from '../../../utils/deindent.js'; import deindent from '../../../utils/deindent.js';
import visit from '../visit.ts'; import visit from '../visit';
function isElseIf ( node ) { function isElseIf ( node ) {
return node && node.children.length === 1 && node.children[0].type === 'IfBlock'; return node && node.children.length === 1 && node.children[0].type === 'IfBlock';

@ -1,10 +1,10 @@
import EachBlock from './EachBlock.ts'; import EachBlock from './EachBlock';
import Element from './Element/Element.ts'; import Element from './Element/Element';
import IfBlock from './IfBlock.ts'; import IfBlock from './IfBlock';
import MustacheTag from './MustacheTag.ts'; import MustacheTag from './MustacheTag';
import RawMustacheTag from './RawMustacheTag.ts'; import RawMustacheTag from './RawMustacheTag';
import Text from './Text.ts'; import Text from './Text';
import YieldTag from './YieldTag.ts'; import YieldTag from './YieldTag';
export default { export default {
EachBlock, EachBlock,

@ -1,5 +1,5 @@
import deindent from '../../utils/deindent.js'; import deindent from '../../utils/deindent.js';
import flattenReference from '../../utils/flattenReference.ts'; import flattenReference from '../../utils/flattenReference';
export default class Block { export default class Block {
constructor ( options ) { constructor ( options ) {

@ -1,7 +1,7 @@
import deindent from '../../utils/deindent.js'; import deindent from '../../utils/deindent.js';
import Generator from '../Generator.ts'; import Generator from '../Generator';
import Block from './Block.ts'; import Block from './Block';
import visit from './visit.ts'; import visit from './visit';
class SsrGenerator extends Generator { class SsrGenerator extends Generator {
constructor ( parsed, source, name, options ) { constructor ( parsed, source, name, options ) {

@ -1,4 +1,4 @@
import visitors from './visitors/index.ts'; import visitors from './visitors/index';
export default function visit ( generator, fragment, node ) { export default function visit ( generator, fragment, node ) {
const visitor = visitors[ node.type ]; const visitor = visitors[ node.type ];

@ -1,5 +1,5 @@
import flattenReference from '../../../utils/flattenReference.ts'; import flattenReference from '../../../utils/flattenReference';
import visit from '../visit.ts'; import visit from '../visit';
export default function visitComponent ( generator, block, node ) { export default function visitComponent ( generator, block, node ) {
function stringify ( chunk ) { function stringify ( chunk ) {

@ -1,4 +1,4 @@
import visit from '../visit.ts'; import visit from '../visit';
export default function visitEachBlock ( generator, block, node ) { export default function visitEachBlock ( generator, block, node ) {
const { dependencies, snippet } = block.contextualise( node.expression ); const { dependencies, snippet } = block.contextualise( node.expression );

@ -1,7 +1,7 @@
import visitComponent from './Component.ts'; import visitComponent from './Component';
import isVoidElementName from '../../../utils/isVoidElementName.ts'; import isVoidElementName from '../../../utils/isVoidElementName';
import visit from '../visit.ts'; import visit from '../visit';
import visitWindow from './meta/Window.ts'; import visitWindow from './meta/Window';
const meta = { const meta = {
':Window': visitWindow ':Window': visitWindow

@ -1,4 +1,4 @@
import visit from '../visit.ts'; import visit from '../visit';
export default function visitIfBlock ( generator, block, node ) { export default function visitIfBlock ( generator, block, node ) {
const { snippet } = block.contextualise( node.expression ); const { snippet } = block.contextualise( node.expression );

@ -1,11 +1,11 @@
import Comment from './Comment.ts'; import Comment from './Comment';
import EachBlock from './EachBlock.ts'; import EachBlock from './EachBlock';
import Element from './Element.ts'; import Element from './Element';
import IfBlock from './IfBlock.ts'; import IfBlock from './IfBlock';
import MustacheTag from './MustacheTag.ts'; import MustacheTag from './MustacheTag';
import RawMustacheTag from './RawMustacheTag.ts'; import RawMustacheTag from './RawMustacheTag';
import Text from './Text.ts'; import Text from './Text';
import YieldTag from './YieldTag.ts'; import YieldTag from './YieldTag';
export default { export default {
Comment, Comment,

@ -1,5 +1,5 @@
import deindent from '../../../utils/deindent.js'; import deindent from '../../../utils/deindent.js';
import getGlobals from './getGlobals.ts'; import getGlobals from './getGlobals';
export default function getIntro ( format: string, options, imports ) { export default function getIntro ( format: string, options, imports ) {
if ( format === 'es' ) return ''; if ( format === 'es' ) return '';

@ -1,4 +1,4 @@
import getGlobals from './getGlobals.ts'; import getGlobals from './getGlobals';
export default function getOutro ( format: string, name: string, options, imports ) { export default function getOutro ( format: string, name: string, options, imports ) {
if ( format === 'es' ) { if ( format === 'es' ) {

@ -1,7 +1,7 @@
import parse from './parse/index.ts'; import parse from './parse/index';
import validate from './validate/index.ts'; import validate from './validate/index';
import generate from './generators/dom/index.ts'; import generate from './generators/dom/index';
import generateSSR from './generators/server-side-rendering/index.ts'; import generateSSR from './generators/server-side-rendering/index';
import { assign } from './shared/index.js'; import { assign } from './shared/index.js';
import { version } from '../package.json'; import { version } from '../package.json';

@ -1,177 +1,204 @@
import { locate } from 'locate-character'; import { locate, Location } from 'locate-character';
import fragment from './state/fragment.ts'; import fragment from './state/fragment';
import { whitespace } from '../utils/patterns.ts'; import { whitespace } from '../utils/patterns';
import { trimStart, trimEnd } from '../utils/trim.ts'; import { trimStart, trimEnd } from '../utils/trim';
import getCodeFrame from '../utils/getCodeFrame.ts'; import getCodeFrame from '../utils/getCodeFrame';
import hash from './utils/hash.ts'; import hash from './utils/hash';
import { Node } from './interfaces';
function ParseError ( message, template, index, filename ) {
const { line, column } = locate( template, index ); class ParseError extends Error {
frame: string
this.name = 'ParseError'; loc: { line: number, column: number }
this.message = message; pos: number
this.frame = getCodeFrame( template, line, column ); filename: string
this.loc = { line: line + 1, column }; constructor ( message: string, template: string, index: number, filename: string ) {
this.pos = index; super( message );
this.filename = filename;
} const { line, column } = locate( template, index );
ParseError.prototype.toString = function () { this.name = 'ParseError';
return `${this.message} (${this.loc.line}:${this.loc.column})\n${this.frame}`; this.loc = { line: line + 1, column };
}; this.pos = index;
this.filename = filename;
this.frame = getCodeFrame( template, line, column );
}
export default function parse ( template, options = {} ) { toString () {
if ( typeof template !== 'string' ) { return `${this.message} (${this.loc.line}:${this.loc.column})\n${this.frame}`;
throw new TypeError( 'Template must be a string' );
} }
}
template = template.replace( /\s+$/, '' ); interface ParserOptions {
filename?: string
}
const parser = { export class Parser {
index: 0, readonly template: string;
template, readonly filename?: string;
stack: [],
metaTags: {},
current () { index: number;
return this.stack[ this.stack.length - 1 ]; stack: Array<Node>;
},
acornError ( err ) { html: Node;
parser.error( err.message.replace( / \(\d+:\d+\)$/, '' ), err.pos ); css: Node;
}, js: Node;
metaTags: {}
error ( message, index = this.index ) { constructor ( template: string, options: ParserOptions ) {
throw new ParseError( message, this.template, index, options.filename ); if ( typeof template !== 'string' ) {
}, throw new TypeError( 'Template must be a string' );
}
eat ( str, required ) { this.template = template.replace( /\s+$/, '' );
if ( this.match( str ) ) { this.filename = options.filename;
this.index += str.length;
return true;
}
if ( required ) { this.index = 0;
this.error( `Expected ${str}` ); this.stack = [];
} this.metaTags = {};
},
this.html = {
start: null,
end: null,
type: 'Fragment',
children: []
};
match ( str ) { this.css = null;
return this.template.slice( this.index, this.index + str.length ) === str; this.js = null;
},
allowWhitespace () { this.stack.push( this.html );
while ( this.index < this.template.length && whitespace.test( this.template[ this.index ] ) ) {
this.index++;
}
},
read ( pattern ) { let state = fragment;
const match = pattern.exec( this.template.slice( this.index ) );
if ( !match || match.index !== 0 ) return null;
parser.index += match[0].length; while ( this.index < this.template.length ) {
state = state( this ) || fragment;
}
return match[0]; if ( this.stack.length > 1 ) {
}, const current = this.current();
readUntil ( pattern ) { const type = current.type === 'Element' ? `<${current.name}>` : 'Block';
if ( this.index >= this.template.length ) parser.error( 'Unexpected end of input' ); this.error( `${type} was left open`, current.start );
}
const start = this.index; if ( state !== fragment ) {
const match = pattern.exec( this.template.slice( start ) ); this.error( 'Unexpected end of input' );
}
if ( match ) { // trim unnecessary whitespace
const start = this.index; while ( this.html.children.length ) {
this.index = start + match.index; const firstChild = this.html.children[0];
return this.template.slice( start, this.index ); this.html.start = firstChild.start;
}
this.index = this.template.length; if ( firstChild.type !== 'Text' ) break;
return this.template.slice( start );
},
remaining () { const length = firstChild.data.length;
return this.template.slice( this.index ); firstChild.data = trimStart( firstChild.data );
},
requireWhitespace () { if ( firstChild.data === '' ) {
if ( !whitespace.test( this.template[ this.index ] ) ) { this.html.children.shift();
this.error( `Expected whitespace` ); } else {
this.html.start += length - firstChild.data.length;
break;
} }
}
this.allowWhitespace(); while ( this.html.children.length ) {
}, const lastChild = this.html.children[ this.html.children.length - 1 ];
this.html.end = lastChild.end;
html: { if ( lastChild.type !== 'Text' ) break;
start: null,
end: null,
type: 'Fragment',
children: []
},
css: null, const length = lastChild.data.length;
lastChild.data = trimEnd( lastChild.data );
js: null if ( lastChild.data === '' ) {
}; this.html.children.pop();
} else {
this.html.end -= length - lastChild.data.length;
break;
}
}
}
parser.stack.push( parser.html ); current () {
return this.stack[ this.stack.length - 1 ];
}
let state = fragment; acornError ( err: Error ) {
this.error( err.message.replace( / \(\d+:\d+\)$/, '' ), err.pos );
}
while ( parser.index < parser.template.length ) { error ( message: string, index = this.index ) {
state = state( parser ) || fragment; throw new ParseError( message, this.template, index, this.filename );
} }
if ( parser.stack.length > 1 ) { eat ( str: string, required?: boolean ) {
const current = parser.current(); if ( this.match( str ) ) {
this.index += str.length;
return true;
}
const type = current.type === 'Element' ? `<${current.name}>` : 'Block'; if ( required ) {
parser.error( `${type} was left open`, current.start ); this.error( `Expected ${str}` );
}
} }
if ( state !== fragment ) { match ( str: string ) {
parser.error( 'Unexpected end of input' ); return this.template.slice( this.index, this.index + str.length ) === str;
} }
// trim unnecessary whitespace allowWhitespace () {
while ( parser.html.children.length ) { while ( this.index < this.template.length && whitespace.test( this.template[ this.index ] ) ) {
const firstChild = parser.html.children[0]; this.index++;
parser.html.start = firstChild.start; }
}
if ( firstChild.type !== 'Text' ) break; read ( pattern: RegExp ) {
const match = pattern.exec( this.template.slice( this.index ) );
if ( !match || match.index !== 0 ) return null;
const length = firstChild.data.length; this.index += match[0].length;
firstChild.data = trimStart( firstChild.data );
if ( firstChild.data === '' ) { return match[0];
parser.html.children.shift();
} else {
parser.html.start += length - firstChild.data.length;
break;
}
} }
while ( parser.html.children.length ) { readUntil ( pattern: RegExp ) {
const lastChild = parser.html.children[ parser.html.children.length - 1 ]; if ( this.index >= this.template.length ) this.error( 'Unexpected end of input' );
parser.html.end = lastChild.end;
const start = this.index;
const match = pattern.exec( this.template.slice( start ) );
if ( lastChild.type !== 'Text' ) break; if ( match ) {
const start = this.index;
this.index = start + match.index;
return this.template.slice( start, this.index );
}
const length = lastChild.data.length; this.index = this.template.length;
lastChild.data = trimEnd( lastChild.data ); return this.template.slice( start );
}
if ( lastChild.data === '' ) { remaining () {
parser.html.children.pop(); return this.template.slice( this.index );
} else { }
parser.html.end -= length - lastChild.data.length;
break; requireWhitespace () {
if ( !whitespace.test( this.template[ this.index ] ) ) {
this.error( `Expected whitespace` );
} }
this.allowWhitespace();
} }
}
export default function parse ( template: string, options: ParserOptions = {} ) {
const parser = new Parser( template, options );
return { return {
hash: hash( template ), hash: hash( parser.template ),
html: parser.html, html: parser.html,
css: parser.css, css: parser.css,
js: parser.js js: parser.js

@ -0,0 +1,19 @@
export interface Node {
start: number;
end: number;
type: string;
[propName: string]: any;
}
export interface Parser {
readonly template: string;
readonly filename?: string;
index: number;
stack: Array<Node>;
html: Node;
css: Node;
js: Node;
metaTags: {}
}

@ -1,7 +1,8 @@
import { parseExpressionAt } from 'acorn'; import { parseExpressionAt } from 'acorn';
import spaces from '../../utils/spaces.js'; import spaces from '../../utils/spaces.js';
import { Parser } from '../index';
function readExpression ( parser, start: number, quoteMark ) { function readExpression ( parser: Parser, start: number, quoteMark ) {
let str = ''; let str = '';
let escaped = false; let escaped = false;
@ -43,7 +44,7 @@ function readExpression ( parser, start: number, quoteMark ) {
return expression; return expression;
} }
export function readEventHandlerDirective ( parser, start: number, name: string ) { export function readEventHandlerDirective ( parser: Parser, start: number, name: string ) {
const quoteMark = ( const quoteMark = (
parser.eat( `'` ) ? `'` : parser.eat( `'` ) ? `'` :
parser.eat( `"` ) ? `"` : parser.eat( `"` ) ? `"` :
@ -67,7 +68,7 @@ export function readEventHandlerDirective ( parser, start: number, name: string
}; };
} }
export function readBindingDirective ( parser, start: number, name: string ) { export function readBindingDirective ( parser: Parser, start: number, name: string ) {
let value; let value;
if ( parser.eat( '=' ) ) { if ( parser.eat( '=' ) ) {
@ -130,7 +131,7 @@ export function readBindingDirective ( parser, start: number, name: string ) {
}; };
} }
export function readTransitionDirective ( parser, start: number, name: string, type: string ) { export function readTransitionDirective ( parser: Parser, start: number, name: string, type: string ) {
let expression = null; let expression = null;
if ( parser.eat( '=' ) ) { if ( parser.eat( '=' ) ) {

@ -1,4 +1,5 @@
import { parseExpressionAt } from 'acorn'; import { parseExpressionAt } from 'acorn';
import { Parser } from '../index';
const literals = new Map([ const literals = new Map([
[ 'true', true ], [ 'true', true ],
@ -6,7 +7,7 @@ const literals = new Map([
[ 'null', null ] [ 'null', null ]
]); ]);
export default function readExpression ( parser ) { export default function readExpression ( parser: Parser ) {
const start = parser.index; const start = parser.index;
const name = parser.readUntil( /\s*}}/ ); const name = parser.readUntil( /\s*}}/ );

@ -1,9 +1,10 @@
import { parse } from 'acorn'; import { parse } from 'acorn';
import spaces from '../../utils/spaces.js'; import spaces from '../../utils/spaces.js';
import { Parser } from '../index';
const scriptClosingTag = '<\/script>'; const scriptClosingTag = '<\/script>';
export default function readScript ( parser, start: number, attributes ) { export default function readScript ( parser: Parser, start: number, attributes ) {
const scriptStart = parser.index; const scriptStart = parser.index;
const scriptEnd = parser.template.indexOf( scriptClosingTag, scriptStart ); const scriptEnd = parser.template.indexOf( scriptClosingTag, scriptStart );

@ -1,7 +1,8 @@
import parse from 'css-tree/lib/parser/index.js'; import parse from 'css-tree/lib/parser/index.js';
import walk from 'css-tree/lib/utils/walk.js'; import walk from 'css-tree/lib/utils/walk.js';
import { Parser } from '../index';
export default function readStyle ( parser, start: number, attributes ) { export default function readStyle ( parser: Parser, start: number, attributes ) {
const contentStart = parser.index; const contentStart = parser.index;
const styles = parser.readUntil( /<\/style>/ ); const styles = parser.readUntil( /<\/style>/ );
const contentEnd = parser.index; const contentEnd = parser.index;

@ -1,8 +1,9 @@
import tag from './tag.ts'; import tag from './tag';
import mustache from './mustache.ts'; import mustache from './mustache';
import text from './text.ts'; import text from './text';
import { Parser } from '../index';
export default function fragment ( parser ) { export default function fragment ( parser: Parser ) {
if ( parser.match( '<' ) ) { if ( parser.match( '<' ) ) {
return tag; return tag;
} }

@ -1,6 +1,8 @@
import readExpression from '../read/expression.ts'; import readExpression from '../read/expression';
import { whitespace } from '../../utils/patterns.ts'; import { whitespace } from '../../utils/patterns';
import { trimStart, trimEnd } from '../../utils/trim.ts'; import { trimStart, trimEnd } from '../../utils/trim';
import { Parser } from '../index';
import { Node } from '../interfaces';
const validIdentifier = /[a-zA-Z_$][a-zA-Z0-9_$]*/; const validIdentifier = /[a-zA-Z_$][a-zA-Z0-9_$]*/;
@ -27,7 +29,7 @@ function trimWhitespace ( block, trimBefore, trimAfter ) {
} }
} }
export default function mustache ( parser ) { export default function mustache ( parser: Parser ) {
const start = parser.index; const start = parser.index;
parser.index += 2; parser.index += 2;
@ -145,7 +147,7 @@ export default function mustache ( parser ) {
const expression = readExpression( parser ); const expression = readExpression( parser );
const block = { const block: Node = {
start, start,
end: null, end: null,
type, type,

@ -1,10 +1,12 @@
import readExpression from '../read/expression.ts'; import readExpression from '../read/expression';
import readScript from '../read/script.ts'; import readScript from '../read/script';
import readStyle from '../read/style.ts'; import readStyle from '../read/style';
import { readEventHandlerDirective, readBindingDirective, readTransitionDirective } from '../read/directives.ts'; import { readEventHandlerDirective, readBindingDirective, readTransitionDirective } from '../read/directives';
import { trimStart, trimEnd } from '../../utils/trim.ts'; import { trimStart, trimEnd } from '../../utils/trim';
import { decodeCharacterReferences } from '../utils/html.ts'; import { decodeCharacterReferences } from '../utils/html';
import isVoidElementName from '../../utils/isVoidElementName.ts'; import isVoidElementName from '../../utils/isVoidElementName';
import { Parser } from '../index';
import { Node } from '../interfaces';
const validTagName = /^\!?[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/; const validTagName = /^\!?[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/;
const invalidUnquotedAttributeCharacters = /[\s"'=<>\/`]/; const invalidUnquotedAttributeCharacters = /[\s"'=<>\/`]/;
@ -61,7 +63,7 @@ function stripWhitespace ( element ) {
} }
} }
export default function tag ( parser ) { export default function tag ( parser: Parser ) {
const start = parser.index++; const start = parser.index++;
let parent = parser.current(); let parent = parser.current();
@ -162,7 +164,7 @@ export default function tag ( parser ) {
return; return;
} }
const element = { const element: Node = {
start, start,
end: null, // filled in later end: null, // filled in later
type: 'Element', type: 'Element',
@ -187,7 +189,7 @@ export default function tag ( parser ) {
return null; return null;
} }
function readTagName ( parser ) { function readTagName ( parser: Parser ) {
const start = parser.index; const start = parser.index;
if ( parser.eat( SELF ) ) { if ( parser.eat( SELF ) ) {
@ -222,7 +224,7 @@ function readTagName ( parser ) {
return name; return name;
} }
function readAttribute ( parser, uniqueNames ) { function readAttribute ( parser: Parser, uniqueNames ) {
const start = parser.index; const start = parser.index;
let name = parser.readUntil( /(\s|=|\/|>)/ ); let name = parser.readUntil( /(\s|=|\/|>)/ );
@ -277,13 +279,13 @@ function readAttribute ( parser, uniqueNames ) {
}; };
} }
function readAttributeValue ( parser ) { function readAttributeValue ( parser: Parser ) {
let quoteMark; let quoteMark;
if ( parser.eat( `'` ) ) quoteMark = `'`; if ( parser.eat( `'` ) ) quoteMark = `'`;
if ( parser.eat( `"` ) ) quoteMark = `"`; if ( parser.eat( `"` ) ) quoteMark = `"`;
let currentChunk = { let currentChunk: Node = {
start: parser.index, start: parser.index,
end: null, end: null,
type: 'Text', type: 'Text',
@ -347,7 +349,7 @@ function readAttributeValue ( parser ) {
parser.error( `Unexpected end of input` ); parser.error( `Unexpected end of input` );
} }
function getShorthandValue ( start, name ) { function getShorthandValue ( start: number, name: string ) {
const end = start + name.length; const end = start + name.length;
return [{ return [{

@ -1,6 +1,7 @@
import { decodeCharacterReferences } from '../utils/html.ts'; import { decodeCharacterReferences } from '../utils/html';
import { Parser } from '../index';
export default function text ( parser ) { export default function text ( parser: Parser ) {
const start = parser.index; const start = parser.index;
let data = ''; let data = '';

@ -1,5 +1,5 @@
// https://github.com/darkskyapp/string-hash/blob/master/index.js // https://github.com/darkskyapp/string-hash/blob/master/index.js
export default function hash ( str: string ) { export default function hash ( str: string ) :number {
let hash = 5381; let hash = 5381;
let i = str.length; let i = str.length;

@ -1,4 +1,4 @@
import htmlEntities from './entities.ts'; import htmlEntities from './entities';
const windows1252 = [ 8364, 129, 8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 352, 8249, 338, 141, 381, 143, 144, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8482, 353, 8250, 339, 157, 382, 376 ]; const windows1252 = [ 8364, 129, 8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 352, 8249, 338, 141, 381, 143, 144, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8482, 353, 8250, 339, 157, 382, 376 ];
const entityPattern = new RegExp( `&(#?(?:x[\\w\\d]+|\\d+|${Object.keys( htmlEntities ).join( '|' )}));?`, 'g' ); const entityPattern = new RegExp( `&(#?(?:x[\\w\\d]+|\\d+|${Object.keys( htmlEntities ).join( '|' )}));?`, 'g' );

@ -1,6 +1,6 @@
import * as assert from 'assert'; import * as assert from 'assert';
import deindent from './deindent.js'; import deindent from './deindent.js';
import CodeBuilder from './CodeBuilder.ts'; import CodeBuilder from './CodeBuilder';
describe( 'deindent', () => { describe( 'deindent', () => {
it( 'deindents a simple string', () => { it( 'deindents a simple string', () => {

@ -1,4 +1,4 @@
import { whitespace } from './patterns.ts'; import { whitespace } from './patterns';
export function trimStart ( str: string ) { export function trimStart ( str: string ) {
let i = 0; let i = 0;

@ -1,6 +1,6 @@
import * as namespaces from '../../utils/namespaces.ts'; import * as namespaces from '../../utils/namespaces';
import validateElement from './validateElement.ts'; import validateElement from './validateElement';
import validateWindow from './validateWindow.ts'; import validateWindow from './validateWindow';
const svg = /^(?:altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|animateMotion|animateTransform|circle|clipPath|color-profile|cursor|defs|desc|discard|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|foreignObject|g|glyph|glyphRef|hatch|hatchpath|hkern|image|line|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|metadata|missing-glyph|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|solidcolor|stop|switch|symbol|text|textPath|title|tref|tspan|unknown|use|view|vkern)$/; const svg = /^(?:altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|animateMotion|animateTransform|circle|clipPath|color-profile|cursor|defs|desc|discard|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|foreignObject|g|glyph|glyphRef|hatch|hatchpath|hkern|image|line|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|metadata|missing-glyph|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|solidcolor|stop|switch|symbol|text|textPath|title|tref|tspan|unknown|use|view|vkern)$/;

@ -1,4 +1,4 @@
import validateEventHandler from './validateEventHandler.ts'; import validateEventHandler from './validateEventHandler';
export default function validateElement ( validator, node ) { export default function validateElement ( validator, node ) {
const isComponent = node.name === ':Self' || validator.components.has( node.name ); const isComponent = node.name === ':Self' || validator.components.has( node.name );

@ -1,5 +1,5 @@
import flattenReference from '../../utils/flattenReference.ts'; import flattenReference from '../../utils/flattenReference';
import list from '../utils/list.ts'; import list from '../utils/list';
const validBuiltins = new Set([ const validBuiltins = new Set([
'set', 'set',

@ -1,7 +1,7 @@
import flattenReference from '../../utils/flattenReference.ts'; import flattenReference from '../../utils/flattenReference';
import fuzzymatch from '../utils/fuzzymatch.ts'; import fuzzymatch from '../utils/fuzzymatch';
import list from '../utils/list.ts'; import list from '../utils/list';
import validateEventHandler from './validateEventHandler.ts'; import validateEventHandler from './validateEventHandler';
const validBindings = [ const validBindings = [
'innerWidth', 'innerWidth',

@ -1,7 +1,7 @@
import validateJs from './js/index.ts'; import validateJs from './js/index';
import validateHtml from './html/index.ts'; import validateHtml from './html/index';
import { getLocator } from 'locate-character'; import { getLocator } from 'locate-character';
import getCodeFrame from '../utils/getCodeFrame.ts'; import getCodeFrame from '../utils/getCodeFrame';
export default function validate ( parsed, source, { onerror, onwarn, name, filename } ) { export default function validate ( parsed, source, { onerror, onwarn, name, filename } ) {
const locator = getLocator( source ); const locator = getLocator( source );

@ -1,8 +1,8 @@
import propValidators from './propValidators/index.ts'; import propValidators from './propValidators/index';
import fuzzymatch from '../utils/fuzzymatch.ts'; import fuzzymatch from '../utils/fuzzymatch';
import checkForDupes from './utils/checkForDupes.ts'; import checkForDupes from './utils/checkForDupes';
import checkForComputedKeys from './utils/checkForComputedKeys.ts'; import checkForComputedKeys from './utils/checkForComputedKeys';
import namespaces from '../../utils/namespaces.ts'; import namespaces from '../../utils/namespaces';
const validPropList = Object.keys( propValidators ); const validPropList = Object.keys( propValidators );

@ -1,5 +1,5 @@
import checkForDupes from '../utils/checkForDupes.ts'; import checkForDupes from '../utils/checkForDupes';
import checkForComputedKeys from '../utils/checkForComputedKeys.ts'; import checkForComputedKeys from '../utils/checkForComputedKeys';
export default function components ( validator, prop ) { export default function components ( validator, prop ) {
if ( prop.value.type !== 'ObjectExpression' ) { if ( prop.value.type !== 'ObjectExpression' ) {

@ -1,5 +1,5 @@
import checkForDupes from '../utils/checkForDupes.ts'; import checkForDupes from '../utils/checkForDupes';
import checkForComputedKeys from '../utils/checkForComputedKeys.ts'; import checkForComputedKeys from '../utils/checkForComputedKeys';
const isFunctionExpression = new Set( [ 'FunctionExpression', 'ArrowFunctionExpression' ] ); const isFunctionExpression = new Set( [ 'FunctionExpression', 'ArrowFunctionExpression' ] );

@ -1,5 +1,5 @@
import checkForDupes from '../utils/checkForDupes.ts'; import checkForDupes from '../utils/checkForDupes';
import checkForComputedKeys from '../utils/checkForComputedKeys.ts'; import checkForComputedKeys from '../utils/checkForComputedKeys';
export default function events ( validator, prop ) { export default function events ( validator, prop ) {
if ( prop.value.type !== 'ObjectExpression' ) { if ( prop.value.type !== 'ObjectExpression' ) {

@ -1,5 +1,5 @@
import checkForDupes from '../utils/checkForDupes.ts'; import checkForDupes from '../utils/checkForDupes';
import checkForComputedKeys from '../utils/checkForComputedKeys.ts'; import checkForComputedKeys from '../utils/checkForComputedKeys';
import { walk } from 'estree-walker'; import { walk } from 'estree-walker';
export default function helpers ( validator, prop ) { export default function helpers ( validator, prop ) {

@ -1,15 +1,15 @@
import data from './data.ts'; import data from './data';
import computed from './computed.ts'; import computed from './computed';
import oncreate from './oncreate.ts'; import oncreate from './oncreate';
import ondestroy from './ondestroy.ts'; import ondestroy from './ondestroy';
import onrender from './onrender.ts'; import onrender from './onrender';
import onteardown from './onteardown.ts'; import onteardown from './onteardown';
import helpers from './helpers.ts'; import helpers from './helpers';
import methods from './methods.ts'; import methods from './methods';
import components from './components.ts'; import components from './components';
import events from './events.ts'; import events from './events';
import namespace from './namespace.ts'; import namespace from './namespace';
import transitions from './transitions.ts'; import transitions from './transitions';
export default { export default {
data, data,

@ -1,7 +1,7 @@
import checkForAccessors from '../utils/checkForAccessors.ts'; import checkForAccessors from '../utils/checkForAccessors';
import checkForDupes from '../utils/checkForDupes.ts'; import checkForDupes from '../utils/checkForDupes';
import checkForComputedKeys from '../utils/checkForComputedKeys.ts'; import checkForComputedKeys from '../utils/checkForComputedKeys';
import usesThisOrArguments from '../utils/usesThisOrArguments.ts'; import usesThisOrArguments from '../utils/usesThisOrArguments';
const builtin = new Set( [ 'set', 'get', 'on', 'fire', 'observe', 'destroy' ] ); const builtin = new Set( [ 'set', 'get', 'on', 'fire', 'observe', 'destroy' ] );

@ -1,5 +1,5 @@
import * as namespaces from '../../../utils/namespaces.ts'; import * as namespaces from '../../../utils/namespaces';
import fuzzymatch from '../../utils/fuzzymatch.ts'; import fuzzymatch from '../../utils/fuzzymatch';
const valid = new Set( namespaces.validNamespaces ); const valid = new Set( namespaces.validNamespaces );

@ -1,4 +1,4 @@
import usesThisOrArguments from '../utils/usesThisOrArguments.ts'; import usesThisOrArguments from '../utils/usesThisOrArguments';
export default function oncreate ( validator, prop ) { export default function oncreate ( validator, prop ) {
if ( prop.value.type === 'ArrowFunctionExpression' ) { if ( prop.value.type === 'ArrowFunctionExpression' ) {

@ -1,4 +1,4 @@
import usesThisOrArguments from '../utils/usesThisOrArguments.ts'; import usesThisOrArguments from '../utils/usesThisOrArguments';
export default function ondestroy ( validator, prop ) { export default function ondestroy ( validator, prop ) {
if ( prop.value.type === 'ArrowFunctionExpression' ) { if ( prop.value.type === 'ArrowFunctionExpression' ) {

@ -1,4 +1,4 @@
import oncreate from './oncreate.ts'; import oncreate from './oncreate';
export default function onrender ( validator, prop ) { export default function onrender ( validator, prop ) {
validator.warn( `'onrender' has been deprecated in favour of 'oncreate', and will cause an error in Svelte 2.x`, prop.start ); validator.warn( `'onrender' has been deprecated in favour of 'oncreate', and will cause an error in Svelte 2.x`, prop.start );

@ -1,4 +1,4 @@
import ondestroy from './ondestroy.ts'; import ondestroy from './ondestroy';
export default function onteardown ( validator, prop ) { export default function onteardown ( validator, prop ) {
validator.warn( `'onteardown' has been deprecated in favour of 'ondestroy', and will cause an error in Svelte 2.x`, prop.start ); validator.warn( `'onteardown' has been deprecated in favour of 'ondestroy', and will cause an error in Svelte 2.x`, prop.start );

@ -1,5 +1,5 @@
import checkForDupes from '../utils/checkForDupes.ts'; import checkForDupes from '../utils/checkForDupes';
import checkForComputedKeys from '../utils/checkForComputedKeys.ts'; import checkForComputedKeys from '../utils/checkForComputedKeys';
export default function transitions ( validator, prop ) { export default function transitions ( validator, prop ) {
if ( prop.value.type !== 'ObjectExpression' ) { if ( prop.value.type !== 'ObjectExpression' ) {

@ -1,5 +1,5 @@
import { walk } from 'estree-walker'; import { walk } from 'estree-walker';
import isReference from '../../../utils/isReference.ts'; import isReference from '../../../utils/isReference';
export default function usesThisOrArguments ( node ) { export default function usesThisOrArguments ( node ) {
let result = false; let result = false;

@ -1,4 +1,4 @@
import FuzzySet from './FuzzySet.ts'; import FuzzySet from './FuzzySet';
export default function fuzzymatch ( name, names ) { export default function fuzzymatch ( name, names ) {
const set = new FuzzySet( names ); const set = new FuzzySet( names );

Loading…
Cancel
Save