Skip to content

Commit fc7e6e6

Browse files
committed
initial commit
0 parents  commit fc7e6e6

File tree

7 files changed

+206
-0
lines changed

7 files changed

+206
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.DS_Store
2+
node_modules

compiler/generate/index.js

Whitespace-only changes.

compiler/index.js

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

compiler/parse/__test__.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import * as assert from 'assert';
2+
import parse from './index.js';
3+
4+
describe( 'parse', () => {
5+
it( 'is a function', () => {
6+
assert.equal( typeof parse, 'function' );
7+
});
8+
9+
it( 'parses a single element', () => {
10+
const template = `<span>test</span>`;
11+
12+
assert.deepEqual( parse( template ), {
13+
start: 0,
14+
end: 17,
15+
type: 'Fragment',
16+
children: [
17+
{
18+
start: 0,
19+
end: 17,
20+
type: 'Element',
21+
name: 'span',
22+
attributes: {},
23+
children: [
24+
{
25+
start: 6,
26+
end: 10,
27+
type: 'Text',
28+
data: 'test'
29+
}
30+
]
31+
}
32+
]
33+
});
34+
});
35+
});

compiler/parse/index.js

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import { locate } from 'locate-character';
2+
3+
const validNameChar = /[a-zA-Z0-9_$]/;
4+
5+
export default function parse ( template ) {
6+
let i = 0;
7+
8+
const root = {
9+
start: 0,
10+
end: template.length,
11+
type: 'Fragment',
12+
children: []
13+
};
14+
15+
const stack = [ root ];
16+
let current = root;
17+
18+
function error ( message ) {
19+
const { line, column } = locate( template, i );
20+
throw new Error( `${message} (${line}:${column})` );
21+
}
22+
23+
function match ( str ) {
24+
return template.slice( i, i + str.length ) === str;
25+
}
26+
27+
function fragment () {
28+
const char = template[i];
29+
30+
while ( char === ' ' ) {
31+
i += 1;
32+
}
33+
34+
if ( char === '<' ) {
35+
return tag;
36+
}
37+
38+
if ( match( '{{' ) ) {
39+
return mustache;
40+
}
41+
42+
return text;
43+
}
44+
45+
function tag () {
46+
const start = i++;
47+
let char = template[ i ];
48+
49+
const isClosingTag = char === '/';
50+
51+
if ( isClosingTag ) {
52+
// this is a closing tag
53+
i += 1;
54+
char = template[ i ];
55+
}
56+
57+
// TODO handle cases like <li>one<li>two
58+
59+
let name = '';
60+
61+
while ( validNameChar.test( char ) ) {
62+
name += char;
63+
i += 1;
64+
char = template[i];
65+
}
66+
67+
if ( isClosingTag ) {
68+
if ( char !== '>' ) error( `Expected '>'` );
69+
70+
i += 1;
71+
current.end = i;
72+
stack.pop();
73+
current = stack[ stack.length - 1 ];
74+
75+
return fragment;
76+
}
77+
78+
const element = {
79+
start,
80+
end: null, // filled in later
81+
type: 'Element',
82+
name,
83+
attributes: {},
84+
children: []
85+
};
86+
87+
current.children.push( element );
88+
stack.push( element );
89+
90+
current = element;
91+
92+
if ( char === '>' ) {
93+
i += 1;
94+
return fragment;
95+
}
96+
97+
return attributes;
98+
}
99+
100+
function text () {
101+
const start = i;
102+
103+
let data = '';
104+
105+
while ( i < template.length && template[i] !== '<' && !match( '{{' ) ) {
106+
data += template[ i++ ];
107+
}
108+
109+
current.children.push({
110+
start,
111+
end: i,
112+
type: 'Text',
113+
data
114+
});
115+
116+
return fragment;
117+
}
118+
119+
function attributes () {
120+
const char = template[i];
121+
if ( char === '>' ) {
122+
i += 1;
123+
return fragment;
124+
}
125+
}
126+
127+
let state = fragment;
128+
129+
while ( i < template.length ) {
130+
state = state();
131+
}
132+
133+
return root;
134+
}

mocha.opts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--require reify

package.json

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"name": "svelte",
3+
"version": "1.0.0",
4+
"description": "The frameworkless UI framework",
5+
"main": "dist/svelte-compiler.js",
6+
"scripts": {
7+
"test": "mocha --opts mocha.opts --recursive ./**/__test__.js"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://gitlab.com/Rich-Harris/svelte.git"
12+
},
13+
"keywords": [
14+
"UI",
15+
"framework",
16+
"templates",
17+
"templating"
18+
],
19+
"author": "Rich Harris",
20+
"license": "MIT",
21+
"bugs": {
22+
"url": "https://gitlab.com/Rich-Harris/svelte/issues"
23+
},
24+
"homepage": "https://gitlab.com/Rich-Harris/svelte#README",
25+
"devDependencies": {
26+
"mocha": "^3.1.2",
27+
"reify": "^0.4.0"
28+
},
29+
"dependencies": {
30+
"locate-character": "^2.0.0"
31+
}
32+
}

0 commit comments

Comments
 (0)