close #745, keep textarea text node clean

This commit is contained in:
Yanzhen Yu
2026-04-01 12:00:00 +08:00
parent ef28761aca
commit 849e60479b
2 changed files with 31 additions and 8 deletions

View File

@@ -321,18 +321,26 @@ export function buildNodeWithSN(
// close before open to make sure document was closed
doc.close();
doc.open();
if (n.compatMode === 'BackCompat' &&
(n.childNodes && n.childNodes[0].type !== NodeType.DocumentType) // there isn't one already defined
) {
if (
n.compatMode === 'BackCompat' &&
n.childNodes &&
n.childNodes[0].type !== NodeType.DocumentType // there isn't one already defined
) {
// Trigger compatMode in the iframe
// this is needed as document.createElement('iframe') otherwise inherits a CSS1Compat mode from the parent replayer environment
if (n.childNodes[0].type === NodeType.Element &&
'xmlns' in n.childNodes[0].attributes &&
n.childNodes[0].attributes.xmlns === 'http://www.w3.org/1999/xhtml') {
if (
n.childNodes[0].type === NodeType.Element &&
'xmlns' in n.childNodes[0].attributes &&
n.childNodes[0].attributes.xmlns === 'http://www.w3.org/1999/xhtml'
) {
// might as well use an xhtml doctype if we've got an xhtml namespace
doc.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">');
doc.write(
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">',
);
} else {
doc.write('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "">');
doc.write(
'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "">',
);
}
}
node = doc;

View File

@@ -1428,6 +1428,21 @@ export class Replayer {
return;
}
if (
'__sn' in parent &&
parent.__sn.type === NodeType.Element &&
parent.__sn.tagName === 'textarea' &&
mutation.node.type === NodeType.Text
) {
// https://github.com/rrweb-io/rrweb/issues/745
// parent is textarea, will only keep one child node as the value
for (const c of Array.from(parent.childNodes)) {
if (c.nodeType === parent.TEXT_NODE) {
parent.removeChild(c);
}
}
}
if (previous && previous.nextSibling && previous.nextSibling.parentNode) {
parent.insertBefore(target, previous.nextSibling);
} else if (next && next.parentNode) {