Skip to content

Commit

Permalink
Simplify the hover replacement function (#1535)
Browse files Browse the repository at this point in the history
Simplify the hover replacement function, which has been borrowed from postcss-pseudo-classes

Note: 'parses nested commas in selectors correctly' was failing after this PR, however I don't think that the previous behaviour was desirable, so have added a new test to formalize this expectation
  • Loading branch information
eoghanmurray authored Sep 13, 2024
1 parent 5fbb904 commit 04ee6ed
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 53 deletions.
6 changes: 6 additions & 0 deletions .changeset/simplifify-hover-replacement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"rrweb-snapshot": patch
"rrweb": patch
---

Slight simplification to how we replace :hover after #1458
55 changes: 3 additions & 52 deletions packages/rrweb-snapshot/src/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const mediaSelectorPlugin: AcceptedPlugin = {
},
};

// Adapted from https://github.com/giuseppeg/postcss-pseudo-classes/blob/master/index.js
// Simplified from https://github.com/giuseppeg/postcss-pseudo-classes/blob/master/index.js
const pseudoClassPlugin: AcceptedPlugin = {
postcssPlugin: 'postcss-hover-classes',
prepare: function () {
Expand All @@ -28,58 +28,9 @@ const pseudoClassPlugin: AcceptedPlugin = {
return;
}
fixed.push(rule);

rule.selectors.forEach(function (selector) {
if (!selector.includes(':')) {
return;
}

const selectorParts = selector.replace(/\n/g, ' ').split(' ');
const pseudoedSelectorParts: string[] = [];

selectorParts.forEach(function (selectorPart) {
const pseudos = selectorPart.match(/::?([^:]+)/g);

if (!pseudos) {
pseudoedSelectorParts.push(selectorPart);
return;
}

const baseSelector = selectorPart.substr(
0,
selectorPart.length - pseudos.join('').length,
);

const classPseudos = pseudos.map(function (pseudo) {
const pseudoToCheck = pseudo.replace(/\(.*/g, '');
if (pseudoToCheck !== ':hover') {
return pseudo;
}

// Ignore pseudo-elements!
if (pseudo.match(/^::/)) {
return pseudo;
}

// Kill the colon
pseudo = pseudo.substr(1);

// Replace left and right parens
pseudo = pseudo.replace(/\(/g, '\\(');
pseudo = pseudo.replace(/\)/g, '\\)');

return '.' + '\\:' + pseudo;
});

pseudoedSelectorParts.push(baseSelector + classPseudos.join(''));
});

addSelector(pseudoedSelectorParts.join(' '));

function addSelector(newSelector: string) {
if (newSelector && newSelector !== selector) {
rule.selector += ',\n' + newSelector;
}
if (selector.includes(':hover')) {
rule.selector += ',\n' + selector.replace(/:hover/g, '.\\:hover');
}
});
},
Expand Down
10 changes: 9 additions & 1 deletion packages/rrweb-snapshot/test/css.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,18 @@ describe('css parser', () => {
describe('pseudoClassPlugin', () => {
it('parses nested commas in selectors correctly', () => {
const cssText =
'body > ul :is(li:not(:first-of-type) a:hover, li:not(:first-of-type).active a) {background: red;}';
'body > ul :is(li:not(:first-of-type) a.current, li:not(:first-of-type).active a) {background: red;}';
expect(parse(pseudoClassPlugin, cssText)).toEqual(cssText);
});

it("doesn't ignore :hover within :is brackets", () => {
const cssText =
'body > ul :is(li:not(:first-of-type) a:hover, li:not(:first-of-type).active a) {background: red;}';
expect(parse(pseudoClassPlugin, cssText))
.toEqual(`body > ul :is(li:not(:first-of-type) a:hover, li:not(:first-of-type).active a),
body > ul :is(li:not(:first-of-type) a.\\:hover, li:not(:first-of-type).active a) {background: red;}`);
});

it('should parse selector with comma nested inside ()', () => {
const cssText =
'[_nghost-ng-c4172599085]:not(.fit-content).aim-select:hover:not(:disabled, [_nghost-ng-c4172599085]:not(.fit-content).aim-select--disabled, [_nghost-ng-c4172599085]:not(.fit-content).aim-select--invalid, [_nghost-ng-c4172599085]:not(.fit-content).aim-select--active) { border-color: rgb(84, 84, 84); }';
Expand Down

0 comments on commit 04ee6ed

Please sign in to comment.