refactor(compiler): allow to serialize and deserialize DirectiveMetadata

This commit is contained in:
Tobias Bosch
2015-09-11 13:35:46 -07:00
parent 67c79ba3f6
commit 71cbb49672
10 changed files with 443 additions and 157 deletions
@@ -15,89 +15,114 @@ export function main() {
var parser: HtmlParser;
beforeEach(() => { parser = new HtmlParser(); });
describe('text nodes', () => {
it('should parse root level text nodes', () => {
expect(humanizeDom(parser.parse('a', 'TestComp')))
.toEqual([[HtmlTextAst, 'a', 'TestComp > #text(a):nth-child(0)']]);
describe('parse', () => {
describe('text nodes', () => {
it('should parse root level text nodes', () => {
expect(humanizeDom(parser.parse('a', 'TestComp')))
.toEqual([[HtmlTextAst, 'a', 'TestComp > #text(a):nth-child(0)']]);
});
it('should parse text nodes inside regular elements', () => {
expect(humanizeDom(parser.parse('<div>a</div>', 'TestComp')))
.toEqual([
[HtmlElementAst, 'div', 'TestComp > div:nth-child(0)'],
[HtmlTextAst, 'a', 'TestComp > div:nth-child(0) > #text(a):nth-child(0)']
]);
});
it('should parse text nodes inside template elements', () => {
expect(humanizeDom(parser.parse('<template>a</template>', 'TestComp')))
.toEqual([
[HtmlElementAst, 'template', 'TestComp > template:nth-child(0)'],
[HtmlTextAst, 'a', 'TestComp > template:nth-child(0) > #text(a):nth-child(0)']
]);
});
});
it('should parse text nodes inside regular elements', () => {
expect(humanizeDom(parser.parse('<div>a</div>', 'TestComp')))
.toEqual([
[HtmlElementAst, 'div', 'TestComp > div:nth-child(0)'],
[HtmlTextAst, 'a', 'TestComp > div:nth-child(0) > #text(a):nth-child(0)']
]);
describe('elements', () => {
it('should parse root level elements', () => {
expect(humanizeDom(parser.parse('<div></div>', 'TestComp')))
.toEqual([[HtmlElementAst, 'div', 'TestComp > div:nth-child(0)']]);
});
it('should parse elements inside of regular elements', () => {
expect(humanizeDom(parser.parse('<div><span></span></div>', 'TestComp')))
.toEqual([
[HtmlElementAst, 'div', 'TestComp > div:nth-child(0)'],
[HtmlElementAst, 'span', 'TestComp > div:nth-child(0) > span:nth-child(0)']
]);
});
it('should parse elements inside of template elements', () => {
expect(humanizeDom(parser.parse('<template><span></span></template>', 'TestComp')))
.toEqual([
[HtmlElementAst, 'template', 'TestComp > template:nth-child(0)'],
[HtmlElementAst, 'span', 'TestComp > template:nth-child(0) > span:nth-child(0)']
]);
});
});
it('should parse text nodes inside template elements', () => {
expect(humanizeDom(parser.parse('<template>a</template>', 'TestComp')))
.toEqual([
[HtmlElementAst, 'template', 'TestComp > template:nth-child(0)'],
[HtmlTextAst, 'a', 'TestComp > template:nth-child(0) > #text(a):nth-child(0)']
]);
describe('attributes', () => {
it('should parse attributes on regular elements', () => {
expect(humanizeDom(parser.parse('<div k="v"></div>', 'TestComp')))
.toEqual([
[HtmlElementAst, 'div', 'TestComp > div:nth-child(0)'],
[HtmlAttrAst, 'k', 'v', 'TestComp > div:nth-child(0)[k=v]']
]);
});
it('should parse attributes on template elements', () => {
expect(humanizeDom(parser.parse('<template k="v"></template>', 'TestComp')))
.toEqual([
[HtmlElementAst, 'template', 'TestComp > template:nth-child(0)'],
[HtmlAttrAst, 'k', 'v', 'TestComp > template:nth-child(0)[k=v]']
]);
});
});
describe('ng-non-bindable', () => {
it('should ignore text nodes and elements inside of elements with ng-non-bindable', () => {
expect(humanizeDom(
parser.parse('<div ng-non-bindable>hello<span></span></div>', 'TestComp')))
.toEqual([
[HtmlElementAst, 'div', 'TestComp > div:nth-child(0)'],
[
HtmlAttrAst,
'ng-non-bindable',
'',
'TestComp > div:nth-child(0)[ng-non-bindable=]'
]
]);
});
});
});
describe('elements', () => {
it('should parse root level elements', () => {
expect(humanizeDom(parser.parse('<div></div>', 'TestComp')))
.toEqual([[HtmlElementAst, 'div', 'TestComp > div:nth-child(0)']]);
describe('unparse', () => {
it('should unparse text nodes',
() => { expect(parser.unparse(parser.parse('a', null))).toEqual('a'); });
it('should unparse elements',
() => { expect(parser.unparse(parser.parse('<a></a>', null))).toEqual('<a></a>'); });
it('should unparse attributes', () => {
expect(parser.unparse(parser.parse('<div a b="c"></div>', null)))
.toEqual('<div a="" b="c"></div>');
});
it('should parse elements inside of regular elements', () => {
expect(humanizeDom(parser.parse('<div><span></span></div>', 'TestComp')))
.toEqual([
[HtmlElementAst, 'div', 'TestComp > div:nth-child(0)'],
[HtmlElementAst, 'span', 'TestComp > div:nth-child(0) > span:nth-child(0)']
]);
it('should unparse nested elements', () => {
expect(parser.unparse(parser.parse('<div><a></a></div>', null)))
.toEqual('<div><a></a></div>');
});
it('should parse elements inside of template elements', () => {
expect(humanizeDom(parser.parse('<template><span></span></template>', 'TestComp')))
.toEqual([
[HtmlElementAst, 'template', 'TestComp > template:nth-child(0)'],
[HtmlElementAst, 'span', 'TestComp > template:nth-child(0) > span:nth-child(0)']
]);
});
});
describe('attributes', () => {
it('should parse attributes on regular elements', () => {
expect(humanizeDom(parser.parse('<div k="v"></div>', 'TestComp')))
.toEqual([
[HtmlElementAst, 'div', 'TestComp > div:nth-child(0)'],
[HtmlAttrAst, 'k', 'v', 'TestComp > div:nth-child(0)[k=v]']
]);
});
it('should parse attributes on template elements', () => {
expect(humanizeDom(parser.parse('<template k="v"></template>', 'TestComp')))
.toEqual([
[HtmlElementAst, 'template', 'TestComp > template:nth-child(0)'],
[HtmlAttrAst, 'k', 'v', 'TestComp > template:nth-child(0)[k=v]']
]);
});
});
describe('ng-non-bindable', () => {
it('should ignore text nodes and elements inside of elements with ng-non-bindable', () => {
expect(
humanizeDom(parser.parse('<div ng-non-bindable>hello<span></span></div>', 'TestComp')))
.toEqual([
[HtmlElementAst, 'div', 'TestComp > div:nth-child(0)'],
[
HtmlAttrAst,
'ng-non-bindable',
'',
'TestComp > div:nth-child(0)[ng-non-bindable=]'
]
]);
it('should unparse nested text nodes', () => {
expect(parser.unparse(parser.parse('<div>a</div>', null))).toEqual('<div>a</div>');
});
});
});
}
export function humanizeDom(asts: HtmlAst[]): any[] {
function humanizeDom(asts: HtmlAst[]): any[] {
var humanizer = new Humanizer();
htmlVisitAll(humanizer, asts);
return humanizer.result;
@@ -105,17 +130,17 @@ export function humanizeDom(asts: HtmlAst[]): any[] {
class Humanizer implements HtmlAstVisitor {
result: any[] = [];
visitElement(ast: HtmlElementAst): any {
visitElement(ast: HtmlElementAst, context: any): any {
this.result.push([HtmlElementAst, ast.name, ast.sourceInfo]);
htmlVisitAll(this, ast.attrs);
htmlVisitAll(this, ast.children);
return null;
}
visitAttr(ast: HtmlAttrAst): any {
visitAttr(ast: HtmlAttrAst, context: any): any {
this.result.push([HtmlAttrAst, ast.name, ast.value, ast.sourceInfo]);
return null;
}
visitText(ast: HtmlTextAst): any {
visitText(ast: HtmlTextAst, context: any): any {
this.result.push([HtmlTextAst, ast.value, ast.sourceInfo]);
return null;
}