Fix a code path where masking could be skipped on textareas (#1599)
* Fixes #1596
This commit is contained in:
5
.changeset/textarea-inner-html.md
Normal file
5
.changeset/textarea-inner-html.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"rrweb": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
#1596 Add masking for innerText mutations on textarea elements
|
||||||
@@ -533,10 +533,18 @@ export default class MutationBuffer {
|
|||||||
this.attributes.push(item);
|
this.attributes.push(item);
|
||||||
this.attributeMap.set(textarea, item);
|
this.attributeMap.set(textarea, item);
|
||||||
}
|
}
|
||||||
item.attributes.value = Array.from(
|
const value = Array.from(
|
||||||
dom.childNodes(textarea),
|
dom.childNodes(textarea),
|
||||||
(cn) => dom.textContent(cn) || '',
|
(cn) => dom.textContent(cn) || '',
|
||||||
).join('');
|
).join('');
|
||||||
|
item.attributes.value = maskInputValue({
|
||||||
|
element: textarea,
|
||||||
|
maskInputOptions: this.maskInputOptions,
|
||||||
|
tagName: textarea.tagName,
|
||||||
|
type: getInputType(textarea),
|
||||||
|
value,
|
||||||
|
maskInputFn: this.maskInputFn,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
private processMutation = (m: mutationRecord) => {
|
private processMutation = (m: mutationRecord) => {
|
||||||
|
|||||||
@@ -9964,6 +9964,21 @@ exports[`record integration tests > should not record input values if dynamicall
|
|||||||
{
|
{
|
||||||
\\"parentId\\": 14,
|
\\"parentId\\": 14,
|
||||||
\\"nextId\\": 16,
|
\\"nextId\\": 16,
|
||||||
|
\\"node\\": {
|
||||||
|
\\"type\\": 2,
|
||||||
|
\\"tagName\\": \\"textarea\\",
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"id\\": \\"textarea\\",
|
||||||
|
\\"size\\": \\"50\\",
|
||||||
|
\\"value\\": \\"*************************\\"
|
||||||
|
},
|
||||||
|
\\"childNodes\\": [],
|
||||||
|
\\"id\\": 21
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"parentId\\": 14,
|
||||||
|
\\"nextId\\": 21,
|
||||||
\\"node\\": {
|
\\"node\\": {
|
||||||
\\"type\\": 2,
|
\\"type\\": 2,
|
||||||
\\"tagName\\": \\"input\\",
|
\\"tagName\\": \\"input\\",
|
||||||
@@ -9973,7 +9988,7 @@ exports[`record integration tests > should not record input values if dynamicall
|
|||||||
\\"value\\": \\"**********************\\"
|
\\"value\\": \\"**********************\\"
|
||||||
},
|
},
|
||||||
\\"childNodes\\": [],
|
\\"childNodes\\": [],
|
||||||
\\"id\\": 21
|
\\"id\\": 22
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -9985,9 +10000,61 @@ exports[`record integration tests > should not record input values if dynamicall
|
|||||||
\\"source\\": 5,
|
\\"source\\": 5,
|
||||||
\\"text\\": \\"**********************\\",
|
\\"text\\": \\"**********************\\",
|
||||||
\\"isChecked\\": false,
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 22
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"*************************\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
\\"id\\": 21
|
\\"id\\": 21
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 2,
|
||||||
|
\\"type\\": 5,
|
||||||
|
\\"id\\": 22
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"***********************\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 22
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"************************\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 22
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"*************************\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 22
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 2,
|
||||||
|
\\"type\\": 6,
|
||||||
|
\\"id\\": 22
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
\\"type\\": 3,
|
\\"type\\": 3,
|
||||||
\\"data\\": {
|
\\"data\\": {
|
||||||
@@ -10000,7 +10067,7 @@ exports[`record integration tests > should not record input values if dynamicall
|
|||||||
\\"type\\": 3,
|
\\"type\\": 3,
|
||||||
\\"data\\": {
|
\\"data\\": {
|
||||||
\\"source\\": 5,
|
\\"source\\": 5,
|
||||||
\\"text\\": \\"***********************\\",
|
\\"text\\": \\"**************************\\",
|
||||||
\\"isChecked\\": false,
|
\\"isChecked\\": false,
|
||||||
\\"id\\": 21
|
\\"id\\": 21
|
||||||
}
|
}
|
||||||
@@ -10009,7 +10076,7 @@ exports[`record integration tests > should not record input values if dynamicall
|
|||||||
\\"type\\": 3,
|
\\"type\\": 3,
|
||||||
\\"data\\": {
|
\\"data\\": {
|
||||||
\\"source\\": 5,
|
\\"source\\": 5,
|
||||||
\\"text\\": \\"************************\\",
|
\\"text\\": \\"***************************\\",
|
||||||
\\"isChecked\\": false,
|
\\"isChecked\\": false,
|
||||||
\\"id\\": 21
|
\\"id\\": 21
|
||||||
}
|
}
|
||||||
@@ -10018,10 +10085,68 @@ exports[`record integration tests > should not record input values if dynamicall
|
|||||||
\\"type\\": 3,
|
\\"type\\": 3,
|
||||||
\\"data\\": {
|
\\"data\\": {
|
||||||
\\"source\\": 5,
|
\\"source\\": 5,
|
||||||
\\"text\\": \\"*************************\\",
|
\\"text\\": \\"****************************\\",
|
||||||
\\"isChecked\\": false,
|
\\"isChecked\\": false,
|
||||||
\\"id\\": 21
|
\\"id\\": 21
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"**********************************************\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 22
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 5,
|
||||||
|
\\"text\\": \\"*************************************************\\",
|
||||||
|
\\"isChecked\\": false,
|
||||||
|
\\"id\\": 21
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 0,
|
||||||
|
\\"texts\\": [],
|
||||||
|
\\"attributes\\": [
|
||||||
|
{
|
||||||
|
\\"id\\": 22,
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"value\\": \\"**********************************************************************************************\\"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"id\\": 21,
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"value\\": \\"*************************************************************************************************\\"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"removes\\": [],
|
||||||
|
\\"adds\\": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
\\"type\\": 3,
|
||||||
|
\\"data\\": {
|
||||||
|
\\"source\\": 0,
|
||||||
|
\\"texts\\": [],
|
||||||
|
\\"attributes\\": [
|
||||||
|
{
|
||||||
|
\\"id\\": 21,
|
||||||
|
\\"attributes\\": {
|
||||||
|
\\"value\\": \\"****************************************************************\\"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
\\"removes\\": [],
|
||||||
|
\\"adds\\": []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]"
|
]"
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -783,9 +783,46 @@ describe('record integration tests', function (this: ISuite) {
|
|||||||
|
|
||||||
const nextElement = document.querySelector('#one')!;
|
const nextElement = document.querySelector('#one')!;
|
||||||
nextElement.parentNode!.insertBefore(el, nextElement);
|
nextElement.parentNode!.insertBefore(el, nextElement);
|
||||||
|
|
||||||
|
const ta = document.createElement('textarea');
|
||||||
|
ta.size = 50;
|
||||||
|
ta.id = 'textarea';
|
||||||
|
ta.setAttribute('size', '50');
|
||||||
|
ta.value = 'textarea should be masked';
|
||||||
|
|
||||||
|
nextElement.parentNode!.insertBefore(ta, nextElement);
|
||||||
});
|
});
|
||||||
|
|
||||||
await page.type('#input', 'moo');
|
await page.type('#input', 'moo');
|
||||||
|
await page.type('#textarea', 'boo');
|
||||||
|
|
||||||
|
await page.evaluate(() => {
|
||||||
|
const el = document.querySelector('input');
|
||||||
|
el.value = 'input attribute mutation should also be masked';
|
||||||
|
|
||||||
|
const ta = document.querySelector('textarea');
|
||||||
|
ta.value = 'textarea attribute mutation should also be masked';
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.evaluate(() => {
|
||||||
|
const el = document.querySelector('input');
|
||||||
|
el.setAttribute(
|
||||||
|
'value',
|
||||||
|
"input attribute mutation should also be masked (even though the new value doesn't take effect)",
|
||||||
|
);
|
||||||
|
|
||||||
|
const ta = document.querySelector('textarea');
|
||||||
|
ta.setAttribute(
|
||||||
|
'value',
|
||||||
|
"textarea attribute mutation should also be masked (even though the new value doesn't take effect)",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.evaluate(() => {
|
||||||
|
const ta = document.querySelector('textarea');
|
||||||
|
ta.innerText =
|
||||||
|
'textarea attribute mutation via innerText should also be masked ';
|
||||||
|
});
|
||||||
|
|
||||||
await assertSnapshot(page);
|
await assertSnapshot(page);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user