mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 11:18:11 +00:00
LibWeb: Support size
attribute on font
elements
This commit is contained in:
parent
5df52a5082
commit
468b2a5ace
3 changed files with 107 additions and 0 deletions
14
Tests/LibWeb/Layout/expected/font-size-legacy.txt
Normal file
14
Tests/LibWeb/Layout/expected/font-size-legacy.txt
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||||
|
BlockContainer <html> at (0,0) content-size 800x33.46875 [BFC] children: not-inline
|
||||||
|
BlockContainer <body> at (8,8) content-size 784x17.46875 children: inline
|
||||||
|
line 0 width: 24.109375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
|
||||||
|
frag 0 from TextNode start: 0, length: 4, rect: [8,11 24.109375x13.09375]
|
||||||
|
"text"
|
||||||
|
InlineNode <font>
|
||||||
|
TextNode <#text>
|
||||||
|
|
||||||
|
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||||
|
PaintableWithLines (BlockContainer<HTML>) [0,0 800x33.46875]
|
||||||
|
PaintableWithLines (BlockContainer<BODY>) [8,8 784x17.46875]
|
||||||
|
InlinePaintable (InlineNode<FONT>)
|
||||||
|
TextPaintable (TextNode<#text>)
|
1
Tests/LibWeb/Layout/input/font-size-legacy.html
Normal file
1
Tests/LibWeb/Layout/input/font-size-legacy.html
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<!doctype html><font size="-2">text
|
|
@ -4,16 +4,100 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <AK/GenericLexer.h>
|
||||||
#include <LibWeb/Bindings/Intrinsics.h>
|
#include <LibWeb/Bindings/Intrinsics.h>
|
||||||
|
#include <LibWeb/CSS/Parser/Parser.h>
|
||||||
|
#include <LibWeb/CSS/Parser/ParsingContext.h>
|
||||||
#include <LibWeb/CSS/StyleProperties.h>
|
#include <LibWeb/CSS/StyleProperties.h>
|
||||||
#include <LibWeb/CSS/StyleValues/ColorStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/ColorStyleValue.h>
|
||||||
#include <LibWeb/HTML/HTMLFontElement.h>
|
#include <LibWeb/HTML/HTMLFontElement.h>
|
||||||
#include <LibWeb/HTML/Parser/HTMLParser.h>
|
#include <LibWeb/HTML/Parser/HTMLParser.h>
|
||||||
|
#include <LibWeb/Infra/CharacterTypes.h>
|
||||||
|
|
||||||
namespace Web::HTML {
|
namespace Web::HTML {
|
||||||
|
|
||||||
JS_DEFINE_ALLOCATOR(HTMLFontElement);
|
JS_DEFINE_ALLOCATOR(HTMLFontElement);
|
||||||
|
|
||||||
|
enum class Mode {
|
||||||
|
RelativePlus,
|
||||||
|
RelativeMinus,
|
||||||
|
Absolute,
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/rendering.html#rules-for-parsing-a-legacy-font-size
|
||||||
|
static Optional<CSS::ValueID> parse_legacy_font_size(StringView string)
|
||||||
|
{
|
||||||
|
// 1. Let input be the attribute's value.
|
||||||
|
// 2. Let position be a pointer into input, initially pointing at the start of the string.
|
||||||
|
GenericLexer lexer { string };
|
||||||
|
|
||||||
|
// 3. Skip ASCII whitespace within input given position.
|
||||||
|
lexer.ignore_while(Web::Infra::is_ascii_whitespace);
|
||||||
|
|
||||||
|
// 4. If position is past the end of input, there is no presentational hint. Return.
|
||||||
|
if (lexer.is_eof())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
// 5. If the character at position is a U+002B PLUS SIGN character (+), then let mode be relative-plus, and advance position to the next character. Otherwise, if the character at position is a U+002D HYPHEN-MINUS character (-), then let mode be relative-minus, and advance position to the next character. Otherwise, let mode be absolute.
|
||||||
|
Mode mode { Mode::Absolute };
|
||||||
|
|
||||||
|
if (lexer.peek() == '+') {
|
||||||
|
mode = Mode::RelativePlus;
|
||||||
|
lexer.consume();
|
||||||
|
} else if (lexer.peek() == '-') {
|
||||||
|
mode = Mode::RelativeMinus;
|
||||||
|
lexer.consume();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. Collect a sequence of code points that are ASCII digits from input given position, and let the resulting sequence be digits.
|
||||||
|
size_t start_index = lexer.tell();
|
||||||
|
lexer.consume_while(is_ascii_digit);
|
||||||
|
size_t end_index = lexer.tell();
|
||||||
|
auto digits = lexer.input().substring_view(start_index, end_index - start_index);
|
||||||
|
auto value_or_empty = AK::StringUtils::convert_to_int<i32>(digits);
|
||||||
|
|
||||||
|
// 7. If digits is the empty string, there is no presentational hint. Return.
|
||||||
|
if (!value_or_empty.has_value())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
// 8. Interpret digits as a base-ten integer. Let value be the resulting number.
|
||||||
|
auto value = value_or_empty.release_value();
|
||||||
|
|
||||||
|
// 9. If mode is relative-plus, then increment value by 3. If mode is relative-minus, then let value be the result of subtracting value from 3.
|
||||||
|
if (mode == Mode::RelativePlus)
|
||||||
|
value += 3;
|
||||||
|
else if (mode == Mode::RelativeMinus)
|
||||||
|
value = 3 - value;
|
||||||
|
|
||||||
|
// 10. If value is greater than 7, let it be 7.
|
||||||
|
if (value > 7)
|
||||||
|
value = 7;
|
||||||
|
|
||||||
|
// 11. If value is less than 1, let it be 1.
|
||||||
|
if (value < 1)
|
||||||
|
value = 1;
|
||||||
|
|
||||||
|
// 12. Set 'font-size' to the keyword corresponding to the value of value according to the following table:
|
||||||
|
switch (value) {
|
||||||
|
case 1:
|
||||||
|
return CSS::ValueID::XSmall;
|
||||||
|
case 2:
|
||||||
|
return CSS::ValueID::Small;
|
||||||
|
case 3:
|
||||||
|
return CSS::ValueID::Medium;
|
||||||
|
case 4:
|
||||||
|
return CSS::ValueID::Large;
|
||||||
|
case 5:
|
||||||
|
return CSS::ValueID::XLarge;
|
||||||
|
case 6:
|
||||||
|
return CSS::ValueID::XxLarge;
|
||||||
|
case 7:
|
||||||
|
return CSS::ValueID::XxxLarge;
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HTMLFontElement::HTMLFontElement(DOM::Document& document, DOM::QualifiedName qualified_name)
|
HTMLFontElement::HTMLFontElement(DOM::Document& document, DOM::QualifiedName qualified_name)
|
||||||
: HTMLElement(document, move(qualified_name))
|
: HTMLElement(document, move(qualified_name))
|
||||||
{
|
{
|
||||||
|
@ -35,6 +119,14 @@ void HTMLFontElement::apply_presentational_hints(CSS::StyleProperties& style) co
|
||||||
auto color = parse_legacy_color_value(value);
|
auto color = parse_legacy_color_value(value);
|
||||||
if (color.has_value())
|
if (color.has_value())
|
||||||
style.set_property(CSS::PropertyID::Color, CSS::ColorStyleValue::create(color.value()));
|
style.set_property(CSS::PropertyID::Color, CSS::ColorStyleValue::create(color.value()));
|
||||||
|
} else if (name.equals_ignoring_ascii_case("size"sv)) {
|
||||||
|
// When a font element has a size attribute, the user agent is expected to use the following steps, known as the rules for parsing a legacy font size, to treat the attribute as a presentational hint setting the element's 'font-size' property:
|
||||||
|
auto font_size_or_empty = parse_legacy_font_size(value);
|
||||||
|
if (font_size_or_empty.has_value()) {
|
||||||
|
auto font_size = string_from_value_id(font_size_or_empty.release_value());
|
||||||
|
if (auto parsed_value = parse_css_value(CSS::Parser::ParsingContext { document() }, font_size, CSS::PropertyID::FontSize))
|
||||||
|
style.set_property(CSS::PropertyID::FontSize, parsed_value.release_nonnull());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue