fix: Ensure attributes are lowercased when checking (#1183)
* fix: Ensure attributes are lowercased when checking * add changeset * fix to lower case * Apply formatting changes --------- Co-authored-by: mydea <mydea@users.noreply.github.com>
This commit is contained in:
6
.changeset/lovely-students-boil.md
Normal file
6
.changeset/lovely-students-boil.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
'rrweb-snapshot': patch
|
||||||
|
'rrweb': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: Ensure attributes are lowercased when checking
|
||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
isNativeShadowDom,
|
isNativeShadowDom,
|
||||||
getCssRulesString,
|
getCssRulesString,
|
||||||
getInputType,
|
getInputType,
|
||||||
|
toLowerCase,
|
||||||
} from './utils';
|
} from './utils';
|
||||||
|
|
||||||
let _id = 1;
|
let _id = 1;
|
||||||
@@ -32,12 +33,12 @@ export function genId(): number {
|
|||||||
return _id++;
|
return _id++;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getValidTagName(element: HTMLElement): string {
|
function getValidTagName(element: HTMLElement): Lowercase<string> {
|
||||||
if (element instanceof HTMLFormElement) {
|
if (element instanceof HTMLFormElement) {
|
||||||
return 'form';
|
return 'form';
|
||||||
}
|
}
|
||||||
|
|
||||||
const processedTagName = element.tagName.toLowerCase().trim();
|
const processedTagName = toLowerCase(element.tagName);
|
||||||
|
|
||||||
if (tagNameRegex.test(processedTagName)) {
|
if (tagNameRegex.test(processedTagName)) {
|
||||||
// if the tag name is odd and we cannot extract
|
// if the tag name is odd and we cannot extract
|
||||||
@@ -222,8 +223,8 @@ function getHref() {
|
|||||||
|
|
||||||
export function transformAttribute(
|
export function transformAttribute(
|
||||||
doc: Document,
|
doc: Document,
|
||||||
tagName: string,
|
tagName: Lowercase<string>,
|
||||||
name: string,
|
name: Lowercase<string>,
|
||||||
value: string | null,
|
value: string | null,
|
||||||
): string | null {
|
): string | null {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
@@ -638,7 +639,7 @@ function serializeElementNode(
|
|||||||
attributes[attr.name] = transformAttribute(
|
attributes[attr.name] = transformAttribute(
|
||||||
doc,
|
doc,
|
||||||
tagName,
|
tagName,
|
||||||
attr.name,
|
toLowerCase(attr.name),
|
||||||
attr.value,
|
attr.value,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ export function maskInputValue({
|
|||||||
maskInputFn?: MaskInputFn;
|
maskInputFn?: MaskInputFn;
|
||||||
}): string {
|
}): string {
|
||||||
let text = value || '';
|
let text = value || '';
|
||||||
const actualType = type && type.toLowerCase();
|
const actualType = type && toLowerCase(type);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
maskInputOptions[tagName.toLowerCase() as keyof MaskInputOptions] ||
|
maskInputOptions[tagName.toLowerCase() as keyof MaskInputOptions] ||
|
||||||
@@ -184,6 +184,10 @@ export function maskInputValue({
|
|||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function toLowerCase<T extends string>(str: T): Lowercase<T> {
|
||||||
|
return str.toLowerCase() as unknown as Lowercase<T>;
|
||||||
|
}
|
||||||
|
|
||||||
const ORIGINAL_ATTRIBUTE_NAME = '__rrweb_original__';
|
const ORIGINAL_ATTRIBUTE_NAME = '__rrweb_original__';
|
||||||
type PatchedGetImageData = {
|
type PatchedGetImageData = {
|
||||||
[ORIGINAL_ATTRIBUTE_NAME]: CanvasImageData['getImageData'];
|
[ORIGINAL_ATTRIBUTE_NAME]: CanvasImageData['getImageData'];
|
||||||
@@ -265,6 +269,6 @@ export function getInputType(element: HTMLElement): Lowercase<string> | null {
|
|||||||
? 'password'
|
? 'password'
|
||||||
: type
|
: type
|
||||||
? // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
? // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
(type.toLowerCase() as Lowercase<string>)
|
toLowerCase(type)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
Mirror,
|
Mirror,
|
||||||
isNativeShadowDom,
|
isNativeShadowDom,
|
||||||
getInputType,
|
getInputType,
|
||||||
|
toLowerCase,
|
||||||
} from 'rrweb-snapshot';
|
} from 'rrweb-snapshot';
|
||||||
import type { observerParam, MutationBufferParam } from '../types';
|
import type { observerParam, MutationBufferParam } from '../types';
|
||||||
import type {
|
import type {
|
||||||
@@ -597,8 +598,8 @@ export default class MutationBuffer {
|
|||||||
// overwrite attribute if the mutations was triggered in same time
|
// overwrite attribute if the mutations was triggered in same time
|
||||||
item.attributes[attributeName] = transformAttribute(
|
item.attributes[attributeName] = transformAttribute(
|
||||||
this.doc,
|
this.doc,
|
||||||
target.tagName,
|
toLowerCase(target.tagName),
|
||||||
attributeName,
|
toLowerCase(attributeName),
|
||||||
value,
|
value,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
maskInputValue,
|
maskInputValue,
|
||||||
Mirror,
|
Mirror,
|
||||||
getInputType,
|
getInputType,
|
||||||
|
toLowerCase,
|
||||||
} from 'rrweb-snapshot';
|
} from 'rrweb-snapshot';
|
||||||
import type { FontFaceSet } from 'css-font-loading-module';
|
import type { FontFaceSet } from 'css-font-loading-module';
|
||||||
import {
|
import {
|
||||||
@@ -309,13 +310,16 @@ function initMouseInteractionObserver({
|
|||||||
disableMap[key] !== false,
|
disableMap[key] !== false,
|
||||||
)
|
)
|
||||||
.forEach((eventKey: keyof typeof MouseInteractions) => {
|
.forEach((eventKey: keyof typeof MouseInteractions) => {
|
||||||
let eventName = eventKey.toLowerCase();
|
let eventName = toLowerCase(eventKey);
|
||||||
const handler = getHandler(eventKey);
|
const handler = getHandler(eventKey);
|
||||||
if (window.PointerEvent) {
|
if (window.PointerEvent) {
|
||||||
switch (MouseInteractions[eventKey]) {
|
switch (MouseInteractions[eventKey]) {
|
||||||
case MouseInteractions.MouseDown:
|
case MouseInteractions.MouseDown:
|
||||||
case MouseInteractions.MouseUp:
|
case MouseInteractions.MouseUp:
|
||||||
eventName = eventName.replace('mouse', 'pointer');
|
eventName = eventName.replace(
|
||||||
|
'mouse',
|
||||||
|
'pointer',
|
||||||
|
) as unknown as typeof eventName;
|
||||||
break;
|
break;
|
||||||
case MouseInteractions.TouchStart:
|
case MouseInteractions.TouchStart:
|
||||||
case MouseInteractions.TouchEnd:
|
case MouseInteractions.TouchEnd:
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
createMirror,
|
createMirror,
|
||||||
attributes,
|
attributes,
|
||||||
serializedElementNodeWithId,
|
serializedElementNodeWithId,
|
||||||
|
toLowerCase,
|
||||||
} from 'rrweb-snapshot';
|
} from 'rrweb-snapshot';
|
||||||
import {
|
import {
|
||||||
RRDocument,
|
RRDocument,
|
||||||
@@ -1120,7 +1121,7 @@ export class Replayer {
|
|||||||
if (d.id === -1) {
|
if (d.id === -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const event = new Event(MouseInteractions[d.type].toLowerCase());
|
const event = new Event(toLowerCase(MouseInteractions[d.type]));
|
||||||
const target = this.mirror.getNode(d.id);
|
const target = this.mirror.getNode(d.id);
|
||||||
if (!target) {
|
if (!target) {
|
||||||
return this.debugNodeNotFound(d, d.id);
|
return this.debugNodeNotFound(d, d.id);
|
||||||
|
|||||||
Reference in New Issue
Block a user