From fcb79af4f74091b6c94cba6643d5f21ed3665ee8 Mon Sep 17 00:00:00 2001 From: JonasBa Date: Sat, 20 Jul 2024 13:34:19 -0400 Subject: [PATCH 1/5] ref: comptime lookup for tagName --- packages/rrdom/src/index.ts | 2 +- packages/rrweb-snapshot/src/snapshot.ts | 158 ++++++++++++++++++++++++ packages/rrweb/src/record/mutation.ts | 2 +- 3 files changed, 160 insertions(+), 2 deletions(-) diff --git a/packages/rrdom/src/index.ts b/packages/rrdom/src/index.ts index 65ae197de8..8e838f6778 100644 --- a/packages/rrdom/src/index.ts +++ b/packages/rrdom/src/index.ts @@ -202,7 +202,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 88b6c8b0ae..e31c9813be 100644 --- a/packages/rrweb-snapshot/src/snapshot.ts +++ b/packages/rrweb-snapshot/src/snapshot.ts @@ -37,6 +37,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'; } @@ -53,6 +59,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', +} + function extractOrigin(url: string): string { let origin = ''; if (url.indexOf('//') > -1) { diff --git a/packages/rrweb/src/record/mutation.ts b/packages/rrweb/src/record/mutation.ts index a798441969..578ef1c99b 100644 --- a/packages/rrweb/src/record/mutation.ts +++ b/packages/rrweb/src/record/mutation.ts @@ -739,7 +739,7 @@ export default class MutationBuffer { /** * Make sure you check if `n`'s parent is blocked before calling this function * */ - private genAdds = (n: Node, target?: Node) => { + private genAdds(n: Node, target?: Node){ // this node was already recorded in other buffer, ignore it if (this.processedNodeManager.inOtherBuffer(n, this)) return; From c64cac0d5e3798f9e5b4f08109bff70e12ea5079 Mon Sep 17 00:00:00 2001 From: JonasBa Date: Sat, 20 Jul 2024 13:34:37 -0400 Subject: [PATCH 2/5] format --- packages/rrweb-snapshot/src/snapshot.ts | 300 ++++++++++++------------ packages/rrweb/src/record/mutation.ts | 4 +- 2 files changed, 152 insertions(+), 152 deletions(-) diff --git a/packages/rrweb-snapshot/src/snapshot.ts b/packages/rrweb-snapshot/src/snapshot.ts index e31c9813be..debc3301ae 100644 --- a/packages/rrweb-snapshot/src/snapshot.ts +++ b/packages/rrweb-snapshot/src/snapshot.ts @@ -60,156 +60,156 @@ function getValidTagName(element: HTMLElement): Lowercase { } 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', -} + 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', +}; function extractOrigin(url: string): string { let origin = ''; diff --git a/packages/rrweb/src/record/mutation.ts b/packages/rrweb/src/record/mutation.ts index 578ef1c99b..02a8867a64 100644 --- a/packages/rrweb/src/record/mutation.ts +++ b/packages/rrweb/src/record/mutation.ts @@ -739,7 +739,7 @@ export default class MutationBuffer { /** * Make sure you check if `n`'s parent is blocked before calling this function * */ - private genAdds(n: Node, target?: Node){ + private genAdds(n: Node, target?: Node) { // this node was already recorded in other buffer, ignore it if (this.processedNodeManager.inOtherBuffer(n, this)) return; @@ -774,7 +774,7 @@ export default class MutationBuffer { }); } } - }; + } } /** From 2a966f42ea92e12c1c934fac4adb0f197a83837d Mon Sep 17 00:00:00 2001 From: JonasBa Date: Sat, 20 Jul 2024 13:39:09 -0400 Subject: [PATCH 3/5] revert mutation change --- packages/rrweb/src/record/mutation.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rrweb/src/record/mutation.ts b/packages/rrweb/src/record/mutation.ts index 02a8867a64..a798441969 100644 --- a/packages/rrweb/src/record/mutation.ts +++ b/packages/rrweb/src/record/mutation.ts @@ -739,7 +739,7 @@ export default class MutationBuffer { /** * Make sure you check if `n`'s parent is blocked before calling this function * */ - private genAdds(n: Node, target?: Node) { + private genAdds = (n: Node, target?: Node) => { // this node was already recorded in other buffer, ignore it if (this.processedNodeManager.inOtherBuffer(n, this)) return; @@ -774,7 +774,7 @@ export default class MutationBuffer { }); } } - } + }; } /** From de5d5f810727e7322d9f6b1150a7bc8c0bf9f2c7 Mon Sep 17 00:00:00 2001 From: JonasBa Date: Sat, 20 Jul 2024 13:40:53 -0400 Subject: [PATCH 4/5] add changeset --- .changeset/sour-feet-smile.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/sour-feet-smile.md 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 From de28f51b239c1b5175cb30160e675ff423af7dac Mon Sep 17 00:00:00 2001 From: JonasBa Date: Thu, 19 Sep 2024 11:07:19 -0400 Subject: [PATCH 5/5] remove unused fn --- packages/rrweb-snapshot/src/snapshot.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/packages/rrweb-snapshot/src/snapshot.ts b/packages/rrweb-snapshot/src/snapshot.ts index f5af134a86..7e7a4adbf2 100644 --- a/packages/rrweb-snapshot/src/snapshot.ts +++ b/packages/rrweb-snapshot/src/snapshot.ts @@ -215,17 +215,6 @@ const HTML_TAGNAMES: Record> = { XMP: 'xmp', }; -function extractOrigin(url: string): string { - let origin = ''; - if (url.indexOf('//') > -1) { - origin = url.split('/').slice(0, 3).join('/'); - } else { - origin = url.split('/')[0]; - } - origin = origin.split('?')[0]; - return origin; -} - let canvasService: HTMLCanvasElement | null; let canvasCtx: CanvasRenderingContext2D | null;