Slim dom defaults refactor (#1758)
* Prefer `includes` formulation for brevity and as it composes better (easier to understand) in longer boolean expressions with && * Noticed two different interpretations of `headMetaAuthorship` under slimDOMOptions; take the opportunity to cleanup and merge code
This commit is contained in:
2
.changeset/slimdom-defaults-refactor.md
Normal file
2
.changeset/slimdom-defaults-refactor.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
---
|
||||||
@@ -2,6 +2,7 @@ import snapshot, {
|
|||||||
serializeNodeWithId,
|
serializeNodeWithId,
|
||||||
transformAttribute,
|
transformAttribute,
|
||||||
ignoreAttribute,
|
ignoreAttribute,
|
||||||
|
slimDOMDefaults,
|
||||||
visitSnapshot,
|
visitSnapshot,
|
||||||
cleanupSnapshot,
|
cleanupSnapshot,
|
||||||
needMaskingText,
|
needMaskingText,
|
||||||
@@ -26,6 +27,7 @@ export {
|
|||||||
createCache,
|
createCache,
|
||||||
transformAttribute,
|
transformAttribute,
|
||||||
ignoreAttribute,
|
ignoreAttribute,
|
||||||
|
slimDOMDefaults,
|
||||||
visitSnapshot,
|
visitSnapshot,
|
||||||
cleanupSnapshot,
|
cleanupSnapshot,
|
||||||
needMaskingText,
|
needMaskingText,
|
||||||
|
|||||||
@@ -190,10 +190,7 @@ export function transformAttribute(
|
|||||||
} else if (name === 'xlink:href' && value[0] !== '#') {
|
} else if (name === 'xlink:href' && value[0] !== '#') {
|
||||||
// xlink:href starts with # is an id pointer
|
// xlink:href starts with # is an id pointer
|
||||||
return absoluteToDoc(doc, value);
|
return absoluteToDoc(doc, value);
|
||||||
} else if (
|
} else if (name === 'background' && ['table', 'td', 'th'].includes(tagName)) {
|
||||||
name === 'background' &&
|
|
||||||
(tagName === 'table' || tagName === 'td' || tagName === 'th')
|
|
||||||
) {
|
|
||||||
return absoluteToDoc(doc, value);
|
return absoluteToDoc(doc, value);
|
||||||
} else if (name === 'srcset') {
|
} else if (name === 'srcset') {
|
||||||
return getAbsoluteSrcsetString(doc, value);
|
return getAbsoluteSrcsetString(doc, value);
|
||||||
@@ -212,7 +209,7 @@ export function ignoreAttribute(
|
|||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
_value: unknown,
|
_value: unknown,
|
||||||
): boolean {
|
): boolean {
|
||||||
return (tagName === 'video' || tagName === 'audio') && name === 'autoplay';
|
return ['video', 'audio'].includes(tagName) && name === 'autoplay';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function _isBlockedElement(
|
export function _isBlockedElement(
|
||||||
@@ -616,7 +613,7 @@ function serializeElementNode(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// form fields
|
// form fields
|
||||||
if (tagName === 'input' || tagName === 'textarea' || tagName === 'select') {
|
if (['input', 'textarea', 'select'].includes(tagName)) {
|
||||||
const value = (n as HTMLInputElement | HTMLTextAreaElement).value;
|
const value = (n as HTMLInputElement | HTMLTextAreaElement).value;
|
||||||
const checked = (n as HTMLInputElement).checked;
|
const checked = (n as HTMLInputElement).checked;
|
||||||
if (
|
if (
|
||||||
@@ -733,7 +730,7 @@ function serializeElementNode(
|
|||||||
else image.addEventListener('load', recordInlineImage);
|
else image.addEventListener('load', recordInlineImage);
|
||||||
}
|
}
|
||||||
// media elements
|
// media elements
|
||||||
if (tagName === 'audio' || tagName === 'video') {
|
if (['audio', 'video'].includes(tagName)) {
|
||||||
const mediaAttributes = attributes as mediaAttributes;
|
const mediaAttributes = attributes as mediaAttributes;
|
||||||
mediaAttributes.rr_mediaState = (n as HTMLMediaElement).paused
|
mediaAttributes.rr_mediaState = (n as HTMLMediaElement).paused
|
||||||
? 'paused'
|
? 'paused'
|
||||||
@@ -805,6 +802,32 @@ function lowerIfExists(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function slimDOMDefaults(
|
||||||
|
_slimDOMOptions: SlimDOMOptions | 'all' | true | false | undefined,
|
||||||
|
) {
|
||||||
|
if (_slimDOMOptions === true || _slimDOMOptions === 'all') {
|
||||||
|
// if true: set of sensible options that should not throw away any information
|
||||||
|
return {
|
||||||
|
script: true,
|
||||||
|
comment: true,
|
||||||
|
headFavicon: true,
|
||||||
|
headWhitespace: true,
|
||||||
|
headMetaSocial: true,
|
||||||
|
headMetaRobots: true,
|
||||||
|
headMetaHttpEquiv: true,
|
||||||
|
headMetaVerification: true,
|
||||||
|
// the following are off for slimDOMOptions === true,
|
||||||
|
// as they destroy some (hidden) info:
|
||||||
|
headMetaAuthorship: _slimDOMOptions === 'all',
|
||||||
|
headMetaDescKeywords: _slimDOMOptions === 'all',
|
||||||
|
headTitleMutations: _slimDOMOptions === 'all',
|
||||||
|
};
|
||||||
|
} else if (_slimDOMOptions) {
|
||||||
|
return _slimDOMOptions;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
function slimDOMExcluded(
|
function slimDOMExcluded(
|
||||||
sn: serializedNode,
|
sn: serializedNode,
|
||||||
slimDOMOptions: SlimDOMOptions,
|
slimDOMOptions: SlimDOMOptions,
|
||||||
@@ -1289,24 +1312,8 @@ function snapshot(
|
|||||||
password: true,
|
password: true,
|
||||||
}
|
}
|
||||||
: maskAllInputs;
|
: maskAllInputs;
|
||||||
const slimDOMOptions: SlimDOMOptions =
|
const slimDOMOptions = slimDOMDefaults(slimDOM);
|
||||||
slimDOM === true || slimDOM === 'all'
|
|
||||||
? // if true: set of sensible options that should not throw away any information
|
|
||||||
{
|
|
||||||
script: true,
|
|
||||||
comment: true,
|
|
||||||
headFavicon: true,
|
|
||||||
headWhitespace: true,
|
|
||||||
headMetaDescKeywords: slimDOM === 'all', // destructive
|
|
||||||
headMetaSocial: true,
|
|
||||||
headMetaRobots: true,
|
|
||||||
headMetaHttpEquiv: true,
|
|
||||||
headMetaAuthorship: true,
|
|
||||||
headMetaVerification: true,
|
|
||||||
}
|
|
||||||
: slimDOM === false
|
|
||||||
? {}
|
|
||||||
: slimDOM;
|
|
||||||
return serializeNodeWithId(n, {
|
return serializeNodeWithId(n, {
|
||||||
doc: n,
|
doc: n,
|
||||||
mirror,
|
mirror,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
snapshot,
|
snapshot,
|
||||||
|
slimDOMDefaults,
|
||||||
type MaskInputOptions,
|
type MaskInputOptions,
|
||||||
type SlimDOMOptions,
|
|
||||||
createMirror,
|
createMirror,
|
||||||
} from 'rrweb-snapshot';
|
} from 'rrweb-snapshot';
|
||||||
import { initObservers, mutationBuffers } from './observer';
|
import { initObservers, mutationBuffers } from './observer';
|
||||||
@@ -160,26 +160,7 @@ function record<T = eventWithTime>(
|
|||||||
? _maskInputOptions
|
? _maskInputOptions
|
||||||
: { password: true };
|
: { password: true };
|
||||||
|
|
||||||
const slimDOMOptions: SlimDOMOptions =
|
const slimDOMOptions = slimDOMDefaults(_slimDOMOptions);
|
||||||
_slimDOMOptions === true || _slimDOMOptions === 'all'
|
|
||||||
? {
|
|
||||||
script: true,
|
|
||||||
comment: true,
|
|
||||||
headFavicon: true,
|
|
||||||
headWhitespace: true,
|
|
||||||
headMetaSocial: true,
|
|
||||||
headMetaRobots: true,
|
|
||||||
headMetaHttpEquiv: true,
|
|
||||||
headMetaVerification: true,
|
|
||||||
// the following are off for slimDOMOptions === true,
|
|
||||||
// as they destroy some (hidden) info:
|
|
||||||
headMetaAuthorship: _slimDOMOptions === 'all',
|
|
||||||
headMetaDescKeywords: _slimDOMOptions === 'all',
|
|
||||||
headTitleMutations: _slimDOMOptions === 'all',
|
|
||||||
}
|
|
||||||
: _slimDOMOptions
|
|
||||||
? _slimDOMOptions
|
|
||||||
: {};
|
|
||||||
|
|
||||||
polyfill();
|
polyfill();
|
||||||
|
|
||||||
@@ -587,10 +568,7 @@ function record<T = eventWithTime>(
|
|||||||
handlers.push(observe(document));
|
handlers.push(observe(document));
|
||||||
recording = true;
|
recording = true;
|
||||||
};
|
};
|
||||||
if (
|
if (['interactive', 'complete'].includes(document.readyState)) {
|
||||||
document.readyState === 'interactive' ||
|
|
||||||
document.readyState === 'complete'
|
|
||||||
) {
|
|
||||||
init();
|
init();
|
||||||
} else {
|
} else {
|
||||||
handlers.push(
|
handlers.push(
|
||||||
|
|||||||
Reference in New Issue
Block a user