Coverage Report

Created: 2026-02-14 08:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibWeb/HTML/HTMLMetaElement.cpp
Line
Count
Source
1
/*
2
 * Copyright (c) 2020, the SerenityOS developers.
3
 * Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
4
 *
5
 * SPDX-License-Identifier: BSD-2-Clause
6
 */
7
8
#include <LibWeb/Bindings/HTMLMetaElementPrototype.h>
9
#include <LibWeb/Bindings/Intrinsics.h>
10
#include <LibWeb/CSS/Parser/Parser.h>
11
#include <LibWeb/CSS/Parser/ParsingContext.h>
12
#include <LibWeb/CSS/PropertyID.h>
13
#include <LibWeb/CSS/StyleValues/CSSColorValue.h>
14
#include <LibWeb/DOM/Document.h>
15
#include <LibWeb/HTML/HTMLMetaElement.h>
16
#include <LibWeb/Infra/CharacterTypes.h>
17
#include <LibWeb/Page/Page.h>
18
19
namespace Web::HTML {
20
21
JS_DEFINE_ALLOCATOR(HTMLMetaElement);
22
23
HTMLMetaElement::HTMLMetaElement(DOM::Document& document, DOM::QualifiedName qualified_name)
24
0
    : HTMLElement(document, move(qualified_name))
25
0
{
26
0
}
27
28
0
HTMLMetaElement::~HTMLMetaElement() = default;
29
30
void HTMLMetaElement::initialize(JS::Realm& realm)
31
0
{
32
0
    Base::initialize(realm);
33
0
    WEB_SET_PROTOTYPE_FOR_INTERFACE(HTMLMetaElement);
34
0
}
35
36
Optional<HTMLMetaElement::HttpEquivAttributeState> HTMLMetaElement::http_equiv_state() const
37
0
{
38
0
    auto value = get_attribute_value(HTML::AttributeNames::http_equiv);
39
40
0
#define __ENUMERATE_HTML_META_HTTP_EQUIV_ATTRIBUTE(keyword, state) \
41
0
    if (value.equals_ignoring_ascii_case(keyword##sv))             \
42
0
        return HTMLMetaElement::HttpEquivAttributeState::state;
43
0
    ENUMERATE_HTML_META_HTTP_EQUIV_ATTRIBUTES
44
0
#undef __ENUMERATE_HTML_META_HTTP_EQUIV_ATTRIBUTE
45
46
0
    return OptionalNone {};
47
0
}
48
49
void HTMLMetaElement::inserted()
50
0
{
51
0
    Base::inserted();
52
53
    // https://html.spec.whatwg.org/multipage/semantics.html#meta-theme-color
54
    // 1. To obtain a page's theme color, user agents must run the following steps:
55
    //     * The element is in a document tree
56
    //     * The element has a name attribute, whose value is an ASCII case-insensitive match for theme-color
57
    //     * The element has a content attribute
58
0
    auto content = attribute(AttributeNames::content);
59
0
    if (name().has_value() && name()->equals_ignoring_ascii_case("theme-color"sv) && content.has_value()) {
60
0
        auto context = CSS::Parser::ParsingContext { document() };
61
62
        // 2. For each element in candidate elements:
63
64
        // 1. If element has a media attribute and the value of element's media attribute does not match the environment, then continue.
65
0
        auto media = attribute(AttributeNames::media);
66
0
        if (media.has_value()) {
67
0
            auto query = parse_media_query(context, media.value());
68
0
            if (document().window() && !query->evaluate(*document().window()))
69
0
                return;
70
0
        }
71
72
        // 2. Let value be the result of stripping leading and trailing ASCII whitespace from the value of element's content attribute.
73
0
        auto value = content->bytes_as_string_view().trim(Infra::ASCII_WHITESPACE);
74
75
        // 3. Let color be the result of parsing value.
76
0
        auto css_value = parse_css_value(context, value, CSS::PropertyID::Color);
77
0
        if (css_value.is_null() || !css_value->is_color())
78
0
            return;
79
0
        auto color = css_value->to_color({}); // TODO: Pass a layout node?
80
81
        // 4. If color is not failure, then return color.
82
0
        document().page().client().page_did_change_theme_color(color);
83
0
        return;
84
0
    }
85
86
    // https://html.spec.whatwg.org/multipage/semantics.html#pragma-directives
87
    // When a meta element is inserted into the document, if its http-equiv attribute is present and represents one of
88
    // the above states, then the user agent must run the algorithm appropriate for that state, as described in the
89
    // following list:
90
0
    auto http_equiv = http_equiv_state();
91
0
    if (http_equiv.has_value()) {
92
0
        switch (http_equiv.value()) {
93
0
        case HttpEquivAttributeState::EncodingDeclaration:
94
            // https://html.spec.whatwg.org/multipage/semantics.html#attr-meta-http-equiv-content-type
95
            // The Encoding declaration state is just an alternative form of setting the charset attribute: it is a character encoding declaration.
96
            // This state's user agent requirements are all handled by the parsing section of the specification.
97
0
            break;
98
0
        case HttpEquivAttributeState::Refresh: {
99
            // https://html.spec.whatwg.org/multipage/semantics.html#attr-meta-http-equiv-refresh
100
            // 1. If the meta element has no content attribute, or if that attribute's value is the empty string, then return.
101
            // 2. Let input be the value of the element's content attribute.
102
0
            if (!has_attribute(AttributeNames::content))
103
0
                break;
104
105
0
            auto input = get_attribute_value(AttributeNames::content);
106
0
            if (input.is_empty())
107
0
                break;
108
109
            // 3. Run the shared declarative refresh steps with the meta element's node document, input, and the meta element.
110
0
            document().shared_declarative_refresh_steps(input, this);
111
0
            break;
112
0
        }
113
0
        case HttpEquivAttributeState::SetCookie:
114
            // https://html.spec.whatwg.org/multipage/semantics.html#attr-meta-http-equiv-set-cookie
115
            // This pragma is non-conforming and has no effect.
116
            // User agents are required to ignore this pragma.
117
0
            break;
118
0
        case HttpEquivAttributeState::XUACompatible:
119
            // https://html.spec.whatwg.org/multipage/semantics.html#attr-meta-http-equiv-x-ua-compatible
120
            // In practice, this pragma encourages Internet Explorer to more closely follow the specifications.
121
            // For meta elements with an http-equiv attribute in the X-UA-Compatible state, the content attribute must have a value that is an ASCII case-insensitive match for the string "IE=edge".
122
            // User agents are required to ignore this pragma.
123
0
            break;
124
0
        default:
125
0
            dbgln("FIXME: Implement '{}' http-equiv state", get_attribute_value(AttributeNames::http_equiv));
126
0
            break;
127
0
        }
128
0
    }
129
0
}
130
131
}