Support media query range comparisons for responsive navigation

This commit is contained in:
wuggy 2026-09-25 04:12:50 -07:00
commit 8bc41fe3ea
2 changed files with 38 additions and 4 deletions

View file

@ -4168,10 +4168,35 @@ CSSParserImpl::ParseMediaQueryExpression(nsMediaQuery* aQuery)
} }
if (!mToken.IsSymbol(':')) { if (!mToken.IsSymbol(':')) {
REPORT_UNEXPECTED_TOKEN(PEMQExpectedFeatureNameEnd); // Media Queries Level 4 permits range features in a comparison context,
UngetToken(); // e.g. (width >= 1012px), in addition to min-width/max-width.
SkipUntil(')'); if (expr->mRange != nsMediaExpression::eEqual ||
return false; feature->mRangeType != nsMediaFeature::eMinMaxAllowed ||
!(mToken.IsSymbol('<') || mToken.IsSymbol('>') ||
mToken.IsSymbol('='))) {
REPORT_UNEXPECTED_TOKEN(PEMQExpectedFeatureNameEnd);
UngetToken();
SkipUntil(')');
return false;
}
if (mToken.IsSymbol('=')) {
expr->mRange = nsMediaExpression::eEqual;
} else {
bool greater = mToken.IsSymbol('>');
// Use GetToken(false) so whitespace between the two characters of
// an inclusive comparison is not accepted as part of the operator.
bool gotToken = GetToken(false);
bool inclusive = gotToken && mToken.IsSymbol('=');
if (gotToken && !inclusive) {
UngetToken();
}
expr->mRange = greater
? (inclusive ? nsMediaExpression::eMin
: nsMediaExpression::eMinExclusive)
: (inclusive ? nsMediaExpression::eMax
: nsMediaExpression::eMaxExclusive);
}
} }
bool rv = false; bool rv = false;

View file

@ -321,6 +321,15 @@ function run() {
(Math.floor(value/em_size) - 1) + "rem)"); (Math.floor(value/em_size) - 1) + "rem)");
} }
// GitHub's navigation uses range queries without whitespace around the
// comparison operator. Check both sides of its desktop breakpoint.
should_apply("(width>=117px)");
should_not_apply("(width<=116.98px)");
should_apply("(width=117px)");
expression_should_not_be_parseable("width > = 117px");
expression_should_not_be_parseable("min-width >= 117px");
expression_should_not_be_parseable("orientation >= landscape");
change_state(function() { change_state(function() {
iframe_style.width = "100px"; iframe_style.width = "100px";
iframe_style.height = "10px"; iframe_style.height = "10px";