• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import type { TAG_ID } from './html.js';
2
3export enum TokenType {
4    CHARACTER,
5    NULL_CHARACTER,
6    WHITESPACE_CHARACTER,
7    START_TAG,
8    END_TAG,
9    COMMENT,
10    DOCTYPE,
11    EOF,
12    HIBERNATION,
13}
14
15export interface Location {
16    /** One-based line index of the first character. */
17    startLine: number;
18    /** One-based column index of the first character. */
19    startCol: number;
20    /** Zero-based first character index. */
21    startOffset: number;
22    /** One-based line index of the last character. */
23    endLine: number;
24    /** One-based column index of the last character. Points directly *after* the last character. */
25    endCol: number;
26    /** Zero-based last character index. Points directly *after* the last character. */
27    endOffset: number;
28}
29
30export interface LocationWithAttributes extends Location {
31    /** Start tag attributes' location info. */
32    attrs?: Record<string, Location>;
33    line?: number;
34    col?: number;
35}
36
37export interface ElementLocation extends LocationWithAttributes {
38    /** Element's start tag location info. */
39    startTag?: Location;
40    /**
41     * Element's end tag location info.
42     * This property is undefined, if the element has no closing tag.
43     */
44    endTag?: Location;
45}
46
47interface TokenBase {
48    readonly type: TokenType;
49    location: Location | null;
50}
51
52export interface DoctypeToken extends TokenBase {
53    readonly type: TokenType.DOCTYPE;
54    name: string | null;
55    forceQuirks: boolean;
56    publicId: string | null;
57    systemId: string | null;
58}
59
60export interface Attribute {
61    /** The name of the attribute. */
62    name: string;
63    /** The namespace of the attribute. */
64    namespace?: string;
65    /** The namespace-related prefix of the attribute. */
66    prefix?: string;
67    /** The value of the attribute. */
68    value: string;
69}
70
71export interface TagToken extends TokenBase {
72    readonly type: TokenType.START_TAG | TokenType.END_TAG;
73    tagName: string;
74    /** Used to cache the ID of the tag name. */
75    tagID: TAG_ID;
76    selfClosing: boolean;
77    ackSelfClosing: boolean;
78    attrs: Attribute[];
79    location: LocationWithAttributes | null;
80}
81
82export function getTokenAttr(token: TagToken, attrName: string): string | null {
83    for (let i = token.attrs.length - 1; i >= 0; i--) {
84        if (token.attrs[i].name === attrName) {
85            return token.attrs[i].value;
86        }
87    }
88
89    return null;
90}
91
92export interface CommentToken extends TokenBase {
93    readonly type: TokenType.COMMENT;
94    data: string;
95}
96
97export interface EOFToken extends TokenBase {
98    readonly type: TokenType.EOF;
99}
100
101export interface CharacterToken extends TokenBase {
102    type: TokenType.CHARACTER | TokenType.NULL_CHARACTER | TokenType.WHITESPACE_CHARACTER;
103    chars: string;
104}
105
106export type Token = DoctypeToken | TagToken | CommentToken | EOFToken | CharacterToken;
107