mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 13:38:11 +00:00
LibWeb: Add a parser for the HTML "dimension value" microsyntax
This commit is contained in:
parent
2e6f5fddef
commit
075bdfdef8
2 changed files with 90 additions and 0 deletions
|
@ -5153,4 +5153,93 @@ RefPtr<CSS::StyleValue> parse_html_length(DOM::Document const& document, StringV
|
|||
return parse_css_value(CSS::ParsingContext(document), string);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#current-dimension-value
|
||||
static RefPtr<CSS::StyleValue> parse_current_dimension_value(float value, Utf8View input, Utf8View::Iterator position)
|
||||
{
|
||||
// 1. If position is past the end of input, then return value as a length.
|
||||
if (position == input.end())
|
||||
return CSS::LengthStyleValue::create(CSS::Length::make_px(value));
|
||||
|
||||
// 2. If the code point at position within input is U+0025 (%), then return value as a percentage.
|
||||
if (*position == '%')
|
||||
return CSS::PercentageStyleValue::create(CSS::Percentage(value));
|
||||
|
||||
// 3. Return value as a length.
|
||||
return CSS::LengthStyleValue::create(CSS::Length::make_px(value));
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#rules-for-parsing-dimension-values
|
||||
RefPtr<CSS::StyleValue> parse_dimension_value(StringView string)
|
||||
{
|
||||
// 1. Let input be the string being parsed.
|
||||
auto input = Utf8View(string);
|
||||
if (!input.validate())
|
||||
return nullptr;
|
||||
|
||||
// 2. Let position be a position variable for input, initially pointing at the start of input.
|
||||
auto position = input.begin();
|
||||
|
||||
// 3. Skip ASCII whitespace within input given position.
|
||||
while (position != input.end() && is_ascii_space(*position))
|
||||
++position;
|
||||
|
||||
// 4. If position is past the end of input or the code point at position within input is not an ASCII digit,
|
||||
// then return failure.
|
||||
if (position == input.end() || !is_ascii_digit(*position))
|
||||
return nullptr;
|
||||
|
||||
// 5. Collect a sequence of code points that are ASCII digits from input given position,
|
||||
// and interpret the resulting sequence as a base-ten integer. Let value be that number.
|
||||
StringBuilder number_string;
|
||||
while (position != input.end() && is_ascii_digit(*position)) {
|
||||
number_string.append(*position);
|
||||
++position;
|
||||
}
|
||||
auto integer_value = number_string.string_view().to_int();
|
||||
|
||||
// 6. If position is past the end of input, then return value as a length.
|
||||
if (position == input.end())
|
||||
return CSS::LengthStyleValue::create(CSS::Length::make_px(*integer_value));
|
||||
|
||||
float value = *integer_value;
|
||||
|
||||
// 7. If the code point at position within input is U+002E (.), then:
|
||||
if (*position == '.') {
|
||||
// 1. Advance position by 1.
|
||||
++position;
|
||||
|
||||
// 2. If position is past the end of input or the code point at position within input is not an ASCII digit,
|
||||
// then return the current dimension value with value, input, and position.
|
||||
if (position == input.end() || !is_ascii_digit(*position))
|
||||
return parse_current_dimension_value(value, input, position);
|
||||
|
||||
// 3. Let divisor have the value 1.
|
||||
float divisor = 1;
|
||||
|
||||
// 4. While true:
|
||||
while (true) {
|
||||
// 1. Multiply divisor by ten.
|
||||
divisor *= 10;
|
||||
|
||||
// 2. Add the value of the code point at position within input,
|
||||
// interpreted as a base-ten digit (0..9) and divided by divisor, to value.
|
||||
value += (*position - '0') / divisor;
|
||||
|
||||
// 3. Advance position by 1.
|
||||
++position;
|
||||
|
||||
// 4. If position is past the end of input, then return value as a length.
|
||||
if (position == input.end())
|
||||
return CSS::LengthStyleValue::create(CSS::Length::make_px(value));
|
||||
|
||||
// 5. If the code point at position within input is not an ASCII digit, then break.
|
||||
if (!is_ascii_digit(*position))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 8. Return the current dimension value with value, input, and position.
|
||||
return parse_current_dimension_value(value, input, position);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue