Simplify the hover replacement function (#1535)
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
This commit is contained in:
6
.changeset/simplifify-hover-replacement.md
Normal file
6
.changeset/simplifify-hover-replacement.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
"rrweb-snapshot": patch
|
||||||
|
"rrweb": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Slight simplification to how we replace :hover after #1458
|
||||||
@@ -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 = {
|
const pseudoClassPlugin: AcceptedPlugin = {
|
||||||
postcssPlugin: 'postcss-hover-classes',
|
postcssPlugin: 'postcss-hover-classes',
|
||||||
prepare: function () {
|
prepare: function () {
|
||||||
@@ -28,58 +28,9 @@ const pseudoClassPlugin: AcceptedPlugin = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fixed.push(rule);
|
fixed.push(rule);
|
||||||
|
|
||||||
rule.selectors.forEach(function (selector) {
|
rule.selectors.forEach(function (selector) {
|
||||||
if (!selector.includes(':')) {
|
if (selector.includes(':hover')) {
|
||||||
return;
|
rule.selector += ',\n' + selector.replace(/:hover/g, '.\\:hover');
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -50,10 +50,18 @@ describe('css parser', () => {
|
|||||||
describe('pseudoClassPlugin', () => {
|
describe('pseudoClassPlugin', () => {
|
||||||
it('parses nested commas in selectors correctly', () => {
|
it('parses nested commas in selectors correctly', () => {
|
||||||
const cssText =
|
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);
|
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 ()', () => {
|
it('should parse selector with comma nested inside ()', () => {
|
||||||
const cssText =
|
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); }';
|
'[_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); }';
|
||||||
|
|||||||
Reference in New Issue
Block a user