Skip to content

Commit

Permalink
Pass raw tokens in unknown functional pseudo selectors through unmodi…
Browse files Browse the repository at this point in the history
…fied

#495
  • Loading branch information
devongovett committed May 24, 2023
1 parent 99e1a2e commit 6a2adb6
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 4 deletions.
16 changes: 16 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6686,6 +6686,22 @@ mod tests {
".foo ::unknown:only-child {width: 20px}",
".foo ::unknown:only-child{width:20px}",
);
minify_test(
".foo ::unknown(.foo) .bar {width: 20px}",
".foo ::unknown(.foo) .bar{width:20px}",
);
minify_test(
".foo ::unknown(.foo .bar / .baz) .bar {width: 20px}",
".foo ::unknown(.foo .bar / .baz) .bar{width:20px}",
);
minify_test(
".foo ::unknown(something(foo)) .bar {width: 20px}",
".foo ::unknown(something(foo)) .bar{width:20px}",
);
minify_test(
".foo ::unknown([abc]) .bar {width: 20px}",
".foo ::unknown([abc]) .bar{width:20px}",
);

let deep_options = ParserOptions {
flags: ParserFlags::DEEP_SELECTOR_COMBINATOR,
Expand Down
69 changes: 69 additions & 0 deletions src/properties/custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,54 @@ impl<'i> TokenList<'i> {
return Ok(TokenList(tokens));
}

pub(crate) fn parse_raw<'t>(
input: &mut Parser<'i, 't>,
tokens: &mut Vec<TokenOrValue<'i>>,
options: &ParserOptions<'_, 'i>,
depth: usize,
) -> Result<(), ParseError<'i, ParserError<'i>>> {
if depth > 500 {
return Err(input.new_custom_error(ParserError::MaximumNestingDepth));
}

loop {
let state = input.state();
match input.next_including_whitespace_and_comments() {
Ok(token @ &cssparser::Token::ParenthesisBlock)
| Ok(token @ &cssparser::Token::SquareBracketBlock)
| Ok(token @ &cssparser::Token::CurlyBracketBlock) => {
tokens.push(Token::from(token).into());
let closing_delimiter = match token {
cssparser::Token::ParenthesisBlock => Token::CloseParenthesis,
cssparser::Token::SquareBracketBlock => Token::CloseSquareBracket,
cssparser::Token::CurlyBracketBlock => Token::CloseCurlyBracket,
_ => unreachable!(),
};

input.parse_nested_block(|input| TokenList::parse_raw(input, tokens, options, depth + 1))?;
tokens.push(closing_delimiter.into());
}
Ok(token @ &cssparser::Token::Function(_)) => {
tokens.push(Token::from(token).into());
input.parse_nested_block(|input| TokenList::parse_raw(input, tokens, options, depth + 1))?;
tokens.push(Token::CloseParenthesis.into());
}
Ok(token) if token.is_parse_error() => {
return Err(ParseError {
kind: ParseErrorKind::Basic(BasicParseErrorKind::UnexpectedToken(token.clone())),
location: state.source_location(),
})
}
Ok(token) => {
tokens.push(Token::from(token).into());
}
Err(_) => break,
}
}

Ok(())
}

fn parse_into<'t>(
input: &mut Parser<'i, 't>,
tokens: &mut Vec<TokenOrValue<'i>>,
Expand Down Expand Up @@ -584,6 +632,27 @@ impl<'i> TokenList<'i> {
Ok(())
}

pub(crate) fn to_css_raw<W>(&self, dest: &mut Printer<W>) -> Result<(), PrinterError>
where
W: std::fmt::Write,
{
for token_or_value in &self.0 {
match token_or_value {
TokenOrValue::Token(token) => {
token.to_css(dest)?;
}
_ => {
return Err(PrinterError {
kind: PrinterErrorKind::FmtError,
loc: None,
})
}
}
}

Ok(())
}

#[inline]
fn write_whitespace_if_needed<W>(&self, i: usize, dest: &mut Printer<W>) -> Result<bool, PrinterError>
where
Expand Down
12 changes: 8 additions & 4 deletions src/selector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,11 @@ impl<'a, 'o, 'i> parcel_selectors::parser::Parser<'i> for SelectorParser<'a, 'o,
if !name.starts_with('-') {
self.options.warn(parser.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone())));
}
let mut args = Vec::new();
TokenList::parse_raw(parser, &mut args, &self.options, 0)?;
CustomFunction {
name: name.into(),
arguments: TokenList::parse(parser, &self.options, 0)?
arguments: TokenList(args)
}
},
};
Expand Down Expand Up @@ -277,7 +279,9 @@ impl<'a, 'o, 'i> parcel_selectors::parser::Parser<'i> for SelectorParser<'a, 'o,
if !name.starts_with('-') {
self.options.warn(arguments.new_custom_error(SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name.clone())));
}
CustomFunction { name: name.into(), arguments: TokenList::parse(arguments, &self.options, 0)? }
let mut args = Vec::new();
TokenList::parse_raw(arguments, &mut args, &self.options, 0)?;
CustomFunction { name: name.into(), arguments: TokenList(args) }
}
};

Expand Down Expand Up @@ -734,7 +738,7 @@ where
dest.write_char(':')?;
dest.write_str(name)?;
dest.write_char('(')?;
args.to_css(dest, false)?;
args.to_css_raw(dest)?;
dest.write_char(')')
}
}
Expand Down Expand Up @@ -1095,7 +1099,7 @@ where
dest.write_str("::")?;
dest.write_str(name)?;
dest.write_char('(')?;
args.to_css(dest, false)?;
args.to_css_raw(dest)?;
dest.write_char(')')
}
}
Expand Down

0 comments on commit 6a2adb6

Please sign in to comment.