-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtag.ts
66 lines (56 loc) · 1.54 KB
/
tag.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import { TagName } from './custom-types/tag-names';
import { AttrSet } from './attributes';
import { FindBy, TagMeta, ValidTagChild } from './custom-types/types';
import { TagBuilder } from './tag-builder';
/**
* Represents an html tag
*/
export class Tag {
tagName: TagName;
children: ValidTagChild[] = [];
attr: AttrSet = new AttrSet();
_meta: TagMeta = {
selfClosing: false,
storesChildren: false,
storage: false,
};
get className() {
return this.attr.className;
}
get tagId() {
return this.attr.id;
}
constructor(tagName: TagName, children: ValidTagChild[], attr: AttrSet, meta: TagMeta) {
this.tagName = tagName;
this.children = children;
this.attr = attr;
this._meta = meta;
}
/** Append children */
append(child: ValidTagChild) {
if (child instanceof TagBuilder) child = child.b();
this.children.push(child);
}
/** Find a child by tag name */
findByTagName(targetTagName: TagName): Tag | null {
return this.findOneBy((t) => t.tagName == targetTagName);
}
/** Find a child by custom test */
findOneBy(test: FindBy): Tag | null {
const stack: Tag[] = [];
stack.push(this);
while (stack.length > 0) {
let tag: Tag = stack.pop() as Tag;
if (test(tag)) {
return tag;
} else if (tag.children && tag.children.length) {
for (let ii = 0; ii < tag.children.length; ii += 1) {
if (this.children[ii] instanceof Tag) {
stack.push(tag.children[ii] as Tag);
}
}
}
}
return null;
}
}