diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp index dbbde107db..8e86a8fcf7 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp @@ -5132,115 +5132,4 @@ RefPtr parse_css_supports(CSS::ParsingContext const& context, Str return parser.parse_as_supports(); } -// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#current-dimension-value -static RefPtr 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 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); -} - -// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#rules-for-parsing-non-zero-dimension-values -RefPtr parse_nonzero_dimension_value(StringView string) -{ - // 1. Let input be the string being parsed. - // 2. Let value be the result of parsing input using the rules for parsing dimension values. - auto value = parse_dimension_value(string); - - // 3. If value is an error, return an error. - if (!value) - return nullptr; - - // 4. If value is zero, return an error. - if (value->is_length() && value->as_length().length().raw_value() == 0) - return nullptr; - if (value->is_percentage() && value->as_percentage().percentage().value() == 0) - return nullptr; - - // 5. If value is a percentage, return value as a percentage. - // 6. Return value as a length. - return value; -} - } diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h index 5d1cca99be..3ba2ff010c 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h @@ -358,7 +358,4 @@ RefPtr parse_media_query(CSS::ParsingContext const&, StringView NonnullRefPtrVector parse_media_query_list(CSS::ParsingContext const&, StringView); RefPtr parse_css_supports(CSS::ParsingContext const&, StringView); -RefPtr parse_dimension_value(StringView); -RefPtr parse_nonzero_dimension_value(StringView); - } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp index 4a4a2e30e5..bf05d8983e 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLImageElement.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTableCellElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLTableCellElement.cpp index 763c512dae..b71aad7073 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLTableCellElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLTableCellElement.cpp @@ -1,11 +1,12 @@ /* - * Copyright (c) 2020, Andreas Kling + * Copyright (c) 2020-2022, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #include #include +#include namespace Web::HTML { diff --git a/Userland/Libraries/LibWeb/HTML/HTMLTableElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLTableElement.cpp index 755ce18e51..447005b95d 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLTableElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLTableElement.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include namespace Web::HTML { diff --git a/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp b/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp index c0da3e8b60..7422037db2 100644 --- a/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp +++ b/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp @@ -3642,4 +3642,115 @@ String HTMLParser::serialize_html_fragment(DOM::Node const& node) return builder.to_string(); } +// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#current-dimension-value +static RefPtr 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 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); +} + +// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#rules-for-parsing-non-zero-dimension-values +RefPtr parse_nonzero_dimension_value(StringView string) +{ + // 1. Let input be the string being parsed. + // 2. Let value be the result of parsing input using the rules for parsing dimension values. + auto value = parse_dimension_value(string); + + // 3. If value is an error, return an error. + if (!value) + return nullptr; + + // 4. If value is zero, return an error. + if (value->is_length() && value->as_length().length().raw_value() == 0) + return nullptr; + if (value->is_percentage() && value->as_percentage().percentage().value() == 0) + return nullptr; + + // 5. If value is a percentage, return value as a percentage. + // 6. Return value as a length. + return value; +} + } diff --git a/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.h b/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.h index 78137adf24..7fbfb363d6 100644 --- a/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.h +++ b/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.h @@ -186,4 +186,7 @@ private: StringBuilder m_character_insertion_builder; }; +RefPtr parse_dimension_value(StringView); +RefPtr parse_nonzero_dimension_value(StringView); + } diff --git a/Userland/Libraries/LibWeb/SVG/SVGSVGElement.cpp b/Userland/Libraries/LibWeb/SVG/SVGSVGElement.cpp index d0264c5ff4..35f592d977 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGSVGElement.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGSVGElement.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -28,14 +29,14 @@ RefPtr SVGSVGElement::create_layout_node(NonnullRefPtr