1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-16 13:55:00 +00:00
serenity/Userland/Libraries/LibWeb/SVG/SVGSymbolElement.cpp
Andreas Kling 1e0ea45fe5 LibWeb: Make sure that SVG use and symbol elements get paintables
I'm about to make StackingContext traverse the paintable tree instead of
actually traversing the layout tree, and it turns out we were not
creating paintables for these SVG elements.

Also switch them to Layout::Box instead of the default InlineNode to
make the trees look a bit less weird. Ultimately, we should do something
specialized for these subtrees, but for now this'll do.
2023-08-20 05:02:59 +02:00

71 lines
2.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2023, Preston Taylor <95388976+PrestonLTaylor@users.noreply.github.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/CSS/StyleProperties.h>
#include <LibWeb/CSS/StyleValues/DisplayStyleValue.h>
#include <LibWeb/CSS/StyleValues/IdentifierStyleValue.h>
#include <LibWeb/CSS/StyleValues/OverflowStyleValue.h>
#include <LibWeb/DOM/ShadowRoot.h>
#include <LibWeb/Layout/Box.h>
#include <LibWeb/SVG/AttributeNames.h>
#include <LibWeb/SVG/SVGSymbolElement.h>
#include <LibWeb/SVG/SVGUseElement.h>
namespace Web::SVG {
SVGSymbolElement::SVGSymbolElement(DOM::Document& document, DOM::QualifiedName qualified_name)
: SVGGraphicsElement(document, qualified_name)
{
}
void SVGSymbolElement::initialize(JS::Realm& realm)
{
Base::initialize(realm);
set_prototype(&Bindings::ensure_web_prototype<Bindings::SVGSymbolElementPrototype>(realm, "SVGSymbolElement"));
}
// https://svgwg.org/svg2-draft/struct.html#SymbolNotes
void SVGSymbolElement::apply_presentational_hints(CSS::StyleProperties& style) const
{
// The user agent style sheet sets the overflow property for symbol elements to hidden.
auto hidden = CSS::IdentifierStyleValue::create(CSS::ValueID::Hidden);
style.set_property(CSS::PropertyID::Overflow, CSS::OverflowStyleValue::create(hidden, hidden));
if (is_direct_child_of_use_shadow_tree()) {
// The generated instance of a symbol that is the direct referenced element of a use element must always have a computed value of inline for the display property.
style.set_property(CSS::PropertyID::Display, CSS::DisplayStyleValue::create(CSS::Display::from_short(CSS::Display::Short::Inline)));
} else {
// FIXME: When we have a DefaultSVG.css then use https://svgwg.org/svg2-draft/styling.html#UAStyleSheet instead.
// The user agent must set the display property on the symbol element to none, as part of the user agent style sheet,
// and this declaration must have importance over any other CSS rule or presentation attribute.
style.set_property(CSS::PropertyID::Display, CSS::DisplayStyleValue::create(CSS::Display::from_short(CSS::Display::Short::None)));
}
}
void SVGSymbolElement::attribute_changed(DeprecatedFlyString const& name, DeprecatedString const& value)
{
if (name.equals_ignoring_ascii_case(SVG::AttributeNames::viewBox))
m_view_box = try_parse_view_box(value);
}
bool SVGSymbolElement::is_direct_child_of_use_shadow_tree() const
{
auto maybe_shadow_root = parent();
if (!is<DOM::ShadowRoot>(maybe_shadow_root)) {
return false;
}
auto host = static_cast<const DOM::ShadowRoot&>(*maybe_shadow_root).host();
return is<SVGUseElement>(host);
}
JS::GCPtr<Layout::Node> SVGSymbolElement::create_layout_node(NonnullRefPtr<CSS::StyleProperties> style)
{
return heap().allocate_without_realm<Layout::Box>(document(), this, move(style));
}
}