initial commit

pull/31/head
Rich Harris 8 years ago
commit fc7e6e6827

2
.gitignore vendored

@ -0,0 +1,2 @@
.DS_Store
node_modules

@ -0,0 +1,2 @@
export { default as parse } from './parse/index.js';
export { default as generate } from './generate/index.js';

@ -0,0 +1,35 @@
import * as assert from 'assert';
import parse from './index.js';
describe( 'parse', () => {
it( 'is a function', () => {
assert.equal( typeof parse, 'function' );
});
it( 'parses a single element', () => {
const template = `<span>test</span>`;
assert.deepEqual( parse( template ), {
start: 0,
end: 17,
type: 'Fragment',
children: [
{
start: 0,
end: 17,
type: 'Element',
name: 'span',
attributes: {},
children: [
{
start: 6,
end: 10,
type: 'Text',
data: 'test'
}
]
}
]
});
});
});

@ -0,0 +1,134 @@
import { locate } from 'locate-character';
const validNameChar = /[a-zA-Z0-9_$]/;
export default function parse ( template ) {
let i = 0;
const root = {
start: 0,
end: template.length,
type: 'Fragment',
children: []
};
const stack = [ root ];
let current = root;
function error ( message ) {
const { line, column } = locate( template, i );
throw new Error( `${message} (${line}:${column})` );
}
function match ( str ) {
return template.slice( i, i + str.length ) === str;
}
function fragment () {
const char = template[i];
while ( char === ' ' ) {
i += 1;
}
if ( char === '<' ) {
return tag;
}
if ( match( '{{' ) ) {
return mustache;
}
return text;
}
function tag () {
const start = i++;
let char = template[ i ];
const isClosingTag = char === '/';
if ( isClosingTag ) {
// this is a closing tag
i += 1;
char = template[ i ];
}
// TODO handle cases like <li>one<li>two
let name = '';
while ( validNameChar.test( char ) ) {
name += char;
i += 1;
char = template[i];
}
if ( isClosingTag ) {
if ( char !== '>' ) error( `Expected '>'` );
i += 1;
current.end = i;
stack.pop();
current = stack[ stack.length - 1 ];
return fragment;
}
const element = {
start,
end: null, // filled in later
type: 'Element',
name,
attributes: {},
children: []
};
current.children.push( element );
stack.push( element );
current = element;
if ( char === '>' ) {
i += 1;
return fragment;
}
return attributes;
}
function text () {
const start = i;
let data = '';
while ( i < template.length && template[i] !== '<' && !match( '{{' ) ) {
data += template[ i++ ];
}
current.children.push({
start,
end: i,
type: 'Text',
data
});
return fragment;
}
function attributes () {
const char = template[i];
if ( char === '>' ) {
i += 1;
return fragment;
}
}
let state = fragment;
while ( i < template.length ) {
state = state();
}
return root;
}

@ -0,0 +1 @@
--require reify

@ -0,0 +1,32 @@
{
"name": "svelte",
"version": "1.0.0",
"description": "The frameworkless UI framework",
"main": "dist/svelte-compiler.js",
"scripts": {
"test": "mocha --opts mocha.opts --recursive ./**/__test__.js"
},
"repository": {
"type": "git",
"url": "git+https://gitlab.com/Rich-Harris/svelte.git"
},
"keywords": [
"UI",
"framework",
"templates",
"templating"
],
"author": "Rich Harris",
"license": "MIT",
"bugs": {
"url": "https://gitlab.com/Rich-Harris/svelte/issues"
},
"homepage": "https://gitlab.com/Rich-Harris/svelte#README",
"devDependencies": {
"mocha": "^3.1.2",
"reify": "^0.4.0"
},
"dependencies": {
"locate-character": "^2.0.0"
}
}
Loading…
Cancel
Save