angular-html-parser
Version:
A HTML parser extracted from Angular with some modifications
208 lines (207 loc) • 6.62 kB
JavaScript
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
// Expansion|ExpansionCase -- not used by angular-html-parser, should be removed on publish
export class NodeWithI18n {
constructor(sourceSpan, i18n) {
this.sourceSpan = sourceSpan;
this.i18n = i18n;
}
}
export class Text extends NodeWithI18n {
constructor(value, sourceSpan, tokens, i18n) {
super(sourceSpan, i18n);
this.value = value;
this.tokens = tokens;
this.type = 'text';
}
visit(visitor, context) {
return visitor.visitText(this, context);
}
}
export class CDATA extends NodeWithI18n {
constructor(value, sourceSpan, tokens, i18n) {
super(sourceSpan, i18n);
this.value = value;
this.tokens = tokens;
this.type = 'cdata';
}
visit(visitor, context) {
return visitor.visitCdata(this, context);
}
}
export class Expansion extends NodeWithI18n {
constructor(switchValue, type, cases, sourceSpan, switchValueSourceSpan, i18n) {
super(sourceSpan, i18n);
this.switchValue = switchValue;
this.type = type;
this.cases = cases;
this.switchValueSourceSpan = switchValueSourceSpan;
}
visit(visitor, context) {
return visitor.visitExpansion(this, context);
}
}
export class ExpansionCase {
constructor(value, expression, sourceSpan, valueSourceSpan, expSourceSpan) {
this.value = value;
this.expression = expression;
this.sourceSpan = sourceSpan;
this.valueSourceSpan = valueSourceSpan;
this.expSourceSpan = expSourceSpan;
this.type = 'expansionCase';
}
visit(visitor, context) {
return visitor.visitExpansionCase(this, context);
}
}
export class Attribute extends NodeWithI18n {
constructor(name, value, sourceSpan, keySpan, valueSpan, valueTokens, i18n) {
super(sourceSpan, i18n);
this.name = name;
this.value = value;
this.keySpan = keySpan;
this.valueSpan = valueSpan;
this.valueTokens = valueTokens;
this.type = 'attribute';
}
visit(visitor, context) {
return visitor.visitAttribute(this, context);
}
// angular-html-parser: backwards compatibility for Prettier
get nameSpan() {
return this.keySpan;
}
}
export class Element extends NodeWithI18n {
constructor(name, attrs, children, sourceSpan, startSourceSpan, endSourceSpan = null, nameSpan = null, i18n) {
super(sourceSpan, i18n);
this.name = name;
this.attrs = attrs;
this.children = children;
this.startSourceSpan = startSourceSpan;
this.endSourceSpan = endSourceSpan;
this.nameSpan = nameSpan;
this.type = 'element';
}
visit(visitor, context) {
return visitor.visitElement(this, context);
}
}
export class Comment {
constructor(value, sourceSpan) {
this.value = value;
this.sourceSpan = sourceSpan;
this.type = 'comment';
}
visit(visitor, context) {
return visitor.visitComment(this, context);
}
}
export class DocType {
constructor(value, sourceSpan) {
this.value = value;
this.sourceSpan = sourceSpan;
this.type = 'docType';
}
visit(visitor, context) {
return visitor.visitDocType(this, context);
}
}
export class Block extends NodeWithI18n {
constructor(name, parameters, children, sourceSpan, nameSpan, startSourceSpan, endSourceSpan = null, i18n) {
super(sourceSpan, i18n);
this.name = name;
this.parameters = parameters;
this.children = children;
this.nameSpan = nameSpan;
this.startSourceSpan = startSourceSpan;
this.endSourceSpan = endSourceSpan;
this.type = 'block';
}
visit(visitor, context) {
return visitor.visitBlock(this, context);
}
}
export class BlockParameter {
constructor(expression, sourceSpan) {
this.expression = expression;
this.sourceSpan = sourceSpan;
this.type = 'blockParameter';
this.startSourceSpan = null;
this.endSourceSpan = null;
}
visit(visitor, context) {
return visitor.visitBlockParameter(this, context);
}
}
export class LetDeclaration {
constructor(name, value, sourceSpan, nameSpan, valueSpan) {
this.name = name;
this.value = value;
this.sourceSpan = sourceSpan;
this.nameSpan = nameSpan;
this.valueSpan = valueSpan;
this.type = 'letDeclaration';
this.startSourceSpan = null;
this.endSourceSpan = null;
}
visit(visitor, context) {
return visitor.visitLetDeclaration(this, context);
}
}
export function visitAll(visitor, nodes, context = null) {
const result = [];
const visit = visitor.visit
? (ast) => visitor.visit(ast, context) || ast.visit(visitor, context)
: (ast) => ast.visit(visitor, context);
nodes.forEach((ast) => {
const astResult = visit(ast);
if (astResult) {
result.push(astResult);
}
});
return result;
}
export class RecursiveVisitor {
constructor() { }
visitElement(ast, context) {
this.visitChildren(context, (visit) => {
visit(ast.attrs);
visit(ast.children);
});
}
visitAttribute(ast, context) { }
visitText(ast, context) { }
visitCdata(ast, context) { }
visitComment(ast, context) { }
visitDocType(ast, context) { }
visitExpansion(ast, context) {
return this.visitChildren(context, (visit) => {
visit(ast.cases);
});
}
visitExpansionCase(ast, context) { }
visitBlock(block, context) {
this.visitChildren(context, (visit) => {
visit(block.parameters);
visit(block.children);
});
}
visitBlockParameter(ast, context) { }
visitLetDeclaration(decl, context) { }
visitChildren(context, cb) {
let results = [];
let t = this;
function visit(children) {
if (children)
results.push(visitAll(t, children, context));
}
cb(visit);
return Array.prototype.concat.apply([], results);
}
}