diff --git a/.changeset/sour-feet-smile.md b/.changeset/sour-feet-smile.md new file mode 100644 index 0000000000..a7633222fa --- /dev/null +++ b/.changeset/sour-feet-smile.md @@ -0,0 +1,6 @@ +--- +"rrweb-snapshot": minor +"rrdom": minor +--- + +improve tagName resolution diff --git a/packages/rrdom/src/index.ts b/packages/rrdom/src/index.ts index 577811766b..c705402a7e 100644 --- a/packages/rrdom/src/index.ts +++ b/packages/rrdom/src/index.ts @@ -208,7 +208,7 @@ function getValidTagName(element: HTMLElement): string { if (element instanceof HTMLFormElement) { return 'FORM'; } - return element.tagName.toUpperCase(); + return element.tagName; } /** diff --git a/packages/rrweb-snapshot/src/snapshot.ts b/packages/rrweb-snapshot/src/snapshot.ts index cd3d7189b7..7e7a4adbf2 100644 --- a/packages/rrweb-snapshot/src/snapshot.ts +++ b/packages/rrweb-snapshot/src/snapshot.ts @@ -41,6 +41,12 @@ export function genId(): number { } function getValidTagName(element: HTMLElement): Lowercase { + const commonTagName = HTML_TAGNAMES[element.tagName]; + if (commonTagName) { + return commonTagName; + } + + // https://github.com/rrweb-io/rrweb-snapshot/issues/56 if (element instanceof HTMLFormElement) { return 'form'; } @@ -57,6 +63,158 @@ function getValidTagName(element: HTMLElement): Lowercase { return processedTagName; } +const HTML_TAGNAMES: Record> = { + A: 'a', + ABBR: 'abbr', + ACRONYM: 'acronym', + ADDRESS: 'address', + APPLET: 'applet', + AREA: 'area', + ARTICLE: 'article', + ASIDE: 'aside', + AUDIO: 'audio', + B: 'b', + BASE: 'base', + BASEFONT: 'basefont', + BDI: 'bdi', + BDO: 'bdo', + BGSOUND: 'bgsound', + BIG: 'big', + BLINK: 'blink', + BLOCKQUOTE: 'blockquote', + BODY: 'body', + BR: 'br', + BUTTON: 'button', + CANVAS: 'canvas', + CAPTION: 'caption', + CENTER: 'center', + CITE: 'cite', + CODE: 'code', + COL: 'col', + COLGROUP: 'colgroup', + COMMAND: 'command', + CONTENT: 'content', + DATA: 'data', + DATALIST: 'datalist', + DD: 'dd', + DEL: 'del', + DETAILS: 'details', + DFN: 'dfn', + DIALOG: 'dialog', + DIR: 'dir', + DIV: 'div', + DL: 'dl', + DT: 'dt', + ELEMENT: 'element', + EM: 'em', + EMBED: 'embed', + FIELDSET: 'fieldset', + FIGCAPTION: 'figcaption', + FIGURE: 'figure', + FONT: 'font', + FOOTER: 'footer', + FORM: 'form', + FRAME: 'frame', + FRAMESET: 'frameset', + H1: 'h1', + H2: 'h2', + H3: 'h3', + H4: 'h4', + H5: 'h5', + H6: 'h6', + HEAD: 'head', + HEADER: 'header', + HGROUP: 'hgroup', + HR: 'hr', + HTML: 'html', + I: 'i', + IFRAME: 'iframe', + IMAGE: 'image', + IMG: 'img', + INPUT: 'input', + INS: 'ins', + ISINDEX: 'isindex', + KBD: 'kbd', + KEYGEN: 'keygen', + LABEL: 'label', + LEGEND: 'legend', + LI: 'li', + LINK: 'link', + LISTING: 'listing', + MAIN: 'main', + MAP: 'map', + MARK: 'mark', + MARQUEE: 'marquee', + MATH: 'math', + MENU: 'menu', + MENUITEM: 'menuitem', + META: 'meta', + METER: 'meter', + MULTICOL: 'multicol', + NAV: 'nav', + NEXTID: 'nextid', + NOBR: 'nobr', + NOEMBED: 'noembed', + NOFRAMES: 'noframes', + NOSCRIPT: 'noscript', + OBJECT: 'object', + OL: 'ol', + OPTGROUP: 'optgroup', + OPTION: 'option', + OUTPUT: 'output', + P: 'p', + PARAM: 'param', + PICTURE: 'picture', + PLAINTEXT: 'plaintext', + PRE: 'pre', + PROGRESS: 'progress', + Q: 'q', + RB: 'rb', + RBC: 'rbc', + RP: 'rp', + RT: 'rt', + RTC: 'rtc', + RUBY: 'ruby', + S: 's', + SAMP: 'samp', + SCRIPT: 'script', + SEARCH: 'search', + SECTION: 'section', + SELECT: 'select', + SHADOW: 'shadow', + SLOT: 'slot', + SMALL: 'small', + SOURCE: 'source', + SPACER: 'spacer', + SPAN: 'span', + STRIKE: 'strike', + STRONG: 'strong', + STYLE: 'style', + SUB: 'sub', + SUMMARY: 'summary', + SUP: 'sup', + SVG: 'svg', + TABLE: 'table', + TBODY: 'tbody', + TD: 'td', + TEMPLATE: 'template', + TEXTAREA: 'textarea', + TFOOT: 'tfoot', + TH: 'th', + THEAD: 'thead', + TIME: 'time', + TITLE: 'title', + TR: 'tr', + TRACK: 'track', + TT: 'tt', + U: 'u', + UL: 'ul', + VAR: 'var', + VIDEO: 'video', + WBR: 'wbr', + XMP: 'xmp', +}; + let canvasService: HTMLCanvasElement | null; let canvasCtx: CanvasRenderingContext2D | null;