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,
|
||||
transformAttribute,
|
||||
ignoreAttribute,
|
||||
slimDOMDefaults,
|
||||
visitSnapshot,
|
||||
cleanupSnapshot,
|
||||
needMaskingText,
|
||||
@@ -26,6 +27,7 @@ export {
|
||||
createCache,
|
||||
transformAttribute,
|
||||
ignoreAttribute,
|
||||
slimDOMDefaults,
|
||||
visitSnapshot,
|
||||
cleanupSnapshot,
|
||||
needMaskingText,
|
||||
|
||||
@@ -190,10 +190,7 @@ export function transformAttribute(
|
||||
} else if (name === 'xlink:href' && value[0] !== '#') {
|
||||
// xlink:href starts with # is an id pointer
|
||||
return absoluteToDoc(doc, value);
|
||||
} else if (
|
||||
name === 'background' &&
|
||||
(tagName === 'table' || tagName === 'td' || tagName === 'th')
|
||||
) {
|
||||
} else if (name === 'background' && ['table', 'td', 'th'].includes(tagName)) {
|
||||
return absoluteToDoc(doc, value);
|
||||
} else if (name === 'srcset') {
|
||||
return getAbsoluteSrcsetString(doc, value);
|
||||
@@ -212,7 +209,7 @@ export function ignoreAttribute(
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
_value: unknown,
|
||||
): boolean {
|
||||
return (tagName === 'video' || tagName === 'audio') && name === 'autoplay';
|
||||
return ['video', 'audio'].includes(tagName) && name === 'autoplay';
|
||||
}
|
||||
|
||||
export function _isBlockedElement(
|
||||
@@ -616,7 +613,7 @@ function serializeElementNode(
|
||||
}
|
||||
}
|
||||
// form fields
|
||||
if (tagName === 'input' || tagName === 'textarea' || tagName === 'select') {
|
||||
if (['input', 'textarea', 'select'].includes(tagName)) {
|
||||
const value = (n as HTMLInputElement | HTMLTextAreaElement).value;
|
||||
const checked = (n as HTMLInputElement).checked;
|
||||
if (
|
||||
@@ -733,7 +730,7 @@ function serializeElementNode(
|
||||
else image.addEventListener('load', recordInlineImage);
|
||||
}
|
||||
// media elements
|
||||
if (tagName === 'audio' || tagName === 'video') {
|
||||
if (['audio', 'video'].includes(tagName)) {
|
||||
const mediaAttributes = attributes as mediaAttributes;
|
||||
mediaAttributes.rr_mediaState = (n as HTMLMediaElement).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(
|
||||
sn: serializedNode,
|
||||
slimDOMOptions: SlimDOMOptions,
|
||||
@@ -1289,24 +1312,8 @@ function snapshot(
|
||||
password: true,
|
||||
}
|
||||
: maskAllInputs;
|
||||
const slimDOMOptions: SlimDOMOptions =
|
||||
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;
|
||||
const slimDOMOptions = slimDOMDefaults(slimDOM);
|
||||
|
||||
return serializeNodeWithId(n, {
|
||||
doc: n,
|
||||
mirror,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
snapshot,
|
||||
slimDOMDefaults,
|
||||
type MaskInputOptions,
|
||||
type SlimDOMOptions,
|
||||
createMirror,
|
||||
} from 'rrweb-snapshot';
|
||||
import { initObservers, mutationBuffers } from './observer';
|
||||
@@ -160,26 +160,7 @@ function record<T = eventWithTime>(
|
||||
? _maskInputOptions
|
||||
: { password: true };
|
||||
|
||||
const slimDOMOptions: 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
|
||||
: {};
|
||||
const slimDOMOptions = slimDOMDefaults(_slimDOMOptions);
|
||||
|
||||
polyfill();
|
||||
|
||||
@@ -587,10 +568,7 @@ function record<T = eventWithTime>(
|
||||
handlers.push(observe(document));
|
||||
recording = true;
|
||||
};
|
||||
if (
|
||||
document.readyState === 'interactive' ||
|
||||
document.readyState === 'complete'
|
||||
) {
|
||||
if (['interactive', 'complete'].includes(document.readyState)) {
|
||||
init();
|
||||
} else {
|
||||
handlers.push(
|
||||
|
||||
Reference in New Issue
Block a user