Skip to content

Commit

Permalink
fix: Ensure CSS support is checked more robustly (#1106)
Browse files Browse the repository at this point in the history
* fix: Ensure CSS support is checked more robustly

* Apply formatting changes

* apply eslint changes

* Update packages/rrweb/src/record/observer.ts

Co-authored-by: Justin Halsall <Juice10@users.noreply.github.com>

* fix: do not use window in module scope

---------

Co-authored-by: mydea <mydea@users.noreply.github.com>
Co-authored-by: Justin Halsall <Juice10@users.noreply.github.com>
  • Loading branch information
3 people authored Feb 9, 2023
1 parent 25a4f5a commit cb15800
Showing 1 changed file with 29 additions and 13 deletions.
42 changes: 29 additions & 13 deletions packages/rrweb/src/record/observer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,6 @@ type WindowWithAngularZone = IWindow & {
export const mutationBuffers: MutationBuffer[] = [];
export const processedNodeManager = new ProcessedNodeManager();

const isCSSGroupingRuleSupported = typeof CSSGroupingRule !== 'undefined';
const isCSSMediaRuleSupported = typeof CSSMediaRule !== 'undefined';
const isCSSSupportsRuleSupported = typeof CSSSupportsRule !== 'undefined';
const isCSSConditionRuleSupported = typeof CSSConditionRule !== 'undefined';

// Event.path is non-standard and used in some older browsers
type NonStandardEvent = Omit<Event, 'composedPath'> & {
path: EventTarget[];
Expand Down Expand Up @@ -488,13 +483,13 @@ function getNestedCSSRulePositions(rule: CSSRule): number[] {
const positions: number[] = [];
function recurse(childRule: CSSRule, pos: number[]) {
if (
(isCSSGroupingRuleSupported &&
(hasNestedCSSRule('CSSGroupingRule') &&
childRule.parentRule instanceof CSSGroupingRule) ||
(isCSSMediaRuleSupported &&
(hasNestedCSSRule('CSSMediaRule') &&
childRule.parentRule instanceof CSSMediaRule) ||
(isCSSSupportsRuleSupported &&
(hasNestedCSSRule('CSSSupportsRule') &&
childRule.parentRule instanceof CSSSupportsRule) ||
(isCSSConditionRuleSupported &&
(hasNestedCSSRule('CSSConditionRule') &&
childRule.parentRule instanceof CSSConditionRule)
) {
const rules = Array.from(
Expand Down Expand Up @@ -643,20 +638,20 @@ function initStyleSheetObserver(
const supportedNestedCSSRuleTypes: {
[key: string]: GroupingCSSRuleTypes;
} = {};
if (isCSSGroupingRuleSupported) {
if (canMonkeyPatchNestedCSSRule('CSSGroupingRule')) {
supportedNestedCSSRuleTypes.CSSGroupingRule = win.CSSGroupingRule;
} else {
// Some browsers (Safari) don't support CSSGroupingRule
// https://caniuse.com/?search=cssgroupingrule
// fall back to monkey patching classes that would have inherited from CSSGroupingRule

if (isCSSMediaRuleSupported) {
if (canMonkeyPatchNestedCSSRule('CSSMediaRule')) {
supportedNestedCSSRuleTypes.CSSMediaRule = win.CSSMediaRule;
}
if (isCSSConditionRuleSupported) {
if (canMonkeyPatchNestedCSSRule('CSSConditionRule')) {
supportedNestedCSSRuleTypes.CSSConditionRule = win.CSSConditionRule;
}
if (isCSSSupportsRuleSupported) {
if (canMonkeyPatchNestedCSSRule('CSSSupportsRule')) {
supportedNestedCSSRuleTypes.CSSSupportsRule = win.CSSSupportsRule;
}
}
Expand Down Expand Up @@ -1168,3 +1163,24 @@ export function initObservers(
pluginHandlers.forEach((h) => h());
};
}

type CSSGroupingProp =
| 'CSSGroupingRule'
| 'CSSMediaRule'
| 'CSSSupportsRule'
| 'CSSConditionRule';

function hasNestedCSSRule(prop: CSSGroupingProp): boolean {
return typeof window[prop] !== 'undefined';
}

function canMonkeyPatchNestedCSSRule(prop: CSSGroupingProp): boolean {
return Boolean(
typeof window[prop] !== 'undefined' &&
// Note: Generally, this check _shouldn't_ be necessary
// However, in some scenarios (e.g. jsdom) this can sometimes fail, so we check for it here
window[prop].prototype &&
'insertRule' in window[prop].prototype &&
'deleteRule' in window[prop].prototype,
);
}

0 comments on commit cb15800

Please sign in to comment.