mirror of
https://github.com/RGBCube/serenity
synced 2025-05-16 13:55:00 +00:00

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.
71 lines
2.9 KiB
C++
71 lines
2.9 KiB
C++
/*
|
||
* 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));
|
||
}
|
||
|
||
}
|