mirror of https://github.com/gorhill/uBlock.git
Properly serialize CSS combinators according to position in selector
Related issue:
https://github.com/uBlockOrigin/uBlock-issues/issues/2778
Regression from:
bb41d9594f
The regression occurred because the modified code made the assumption
that a leading combinator would never be preceded by whitespace, while
the parser didn't prevent this.
The parser has been fixed to ensure there is never a leading
whitespace in a selector.
This commit is contained in:
parent
79cf5f574c
commit
fbc7a0e0ae
|
@ -3364,7 +3364,7 @@ class ExtSelectorCompiler {
|
||||||
out.push(`.${data.name}`);
|
out.push(`.${data.name}`);
|
||||||
break;
|
break;
|
||||||
case 'Combinator':
|
case 'Combinator':
|
||||||
out.push(data.name === ' ' ? ' ' : ` ${data.name} `);
|
out.push(data.name);
|
||||||
break;
|
break;
|
||||||
case 'Identifier':
|
case 'Identifier':
|
||||||
if ( this.reInvalidIdentifier.test(data.name) ) { return; }
|
if ( this.reInvalidIdentifier.test(data.name) ) { return; }
|
||||||
|
@ -3436,6 +3436,28 @@ class ExtSelectorCompiler {
|
||||||
return out.join('');
|
return out.join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
astAppendPart(part, out) {
|
||||||
|
const { data } = part;
|
||||||
|
switch ( data.type ) {
|
||||||
|
case 'Combinator': {
|
||||||
|
const s = this.astSerializePart(part);
|
||||||
|
if ( s === undefined ) { return false; }
|
||||||
|
if ( out.length === 0 ) {
|
||||||
|
if ( s !== ' ' ) {
|
||||||
|
out.push(s, ' ');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.push(' ');
|
||||||
|
if ( s !== ' ' ) {
|
||||||
|
out.push(s, ' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
astSerialize(parts, plainCSS = true) {
|
astSerialize(parts, plainCSS = true) {
|
||||||
const out = [];
|
const out = [];
|
||||||
for ( const part of parts ) {
|
for ( const part of parts ) {
|
||||||
|
@ -3443,7 +3465,6 @@ class ExtSelectorCompiler {
|
||||||
switch ( data.type ) {
|
switch ( data.type ) {
|
||||||
case 'AttributeSelector':
|
case 'AttributeSelector':
|
||||||
case 'ClassSelector':
|
case 'ClassSelector':
|
||||||
case 'Combinator':
|
|
||||||
case 'Identifier':
|
case 'Identifier':
|
||||||
case 'IdSelector':
|
case 'IdSelector':
|
||||||
case 'Nth':
|
case 'Nth':
|
||||||
|
@ -3455,6 +3476,9 @@ class ExtSelectorCompiler {
|
||||||
out.push(s);
|
out.push(s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'Combinator':
|
||||||
|
if ( this.astAppendPart(part, out) === false ) { return; }
|
||||||
|
break;
|
||||||
case 'Raw':
|
case 'Raw':
|
||||||
if ( plainCSS ) { return; }
|
if ( plainCSS ) { return; }
|
||||||
out.push(this.astSerializePart(part));
|
out.push(this.astSerializePart(part));
|
||||||
|
@ -3499,7 +3523,6 @@ class ExtSelectorCompiler {
|
||||||
}
|
}
|
||||||
case 'AttributeSelector':
|
case 'AttributeSelector':
|
||||||
case 'ClassSelector':
|
case 'ClassSelector':
|
||||||
case 'Combinator':
|
|
||||||
case 'IdSelector':
|
case 'IdSelector':
|
||||||
case 'PseudoClassSelector':
|
case 'PseudoClassSelector':
|
||||||
case 'PseudoElementSelector':
|
case 'PseudoElementSelector':
|
||||||
|
@ -3509,6 +3532,10 @@ class ExtSelectorCompiler {
|
||||||
prelude.push(component);
|
prelude.push(component);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'Combinator': {
|
||||||
|
if ( this.astAppendPart(part, prelude) === false ) { return; }
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'ProceduralSelector': {
|
case 'ProceduralSelector': {
|
||||||
if ( prelude.length !== 0 ) {
|
if ( prelude.length !== 0 ) {
|
||||||
let spath = prelude.join('');
|
let spath = prelude.join('');
|
||||||
|
|
Loading…
Reference in New Issue