mirror of
https://github.com/RGBCube/serenity
synced 2025-05-22 18:55:07 +00:00

The SVG <use> element is used to be able to reuse other SVG graphics without having to re-write the svg element. We now support this feature! :^)
92 lines
2.2 KiB
C++
92 lines
2.2 KiB
C++
/*
|
|
* Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org>
|
|
* Copyright (c) 2023, Preston Taylor <95388976+PrestonLTaylor@users.noreply.github.com>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <LibWeb/Bindings/ExceptionOrUtils.h>
|
|
#include <LibWeb/Bindings/Intrinsics.h>
|
|
#include <LibWeb/DOM/Document.h>
|
|
#include <LibWeb/HTML/DOMStringMap.h>
|
|
#include <LibWeb/SVG/SVGElement.h>
|
|
#include <LibWeb/SVG/SVGUseElement.h>
|
|
|
|
namespace Web::SVG {
|
|
|
|
SVGElement::SVGElement(DOM::Document& document, DOM::QualifiedName qualified_name)
|
|
: Element(document, move(qualified_name))
|
|
{
|
|
}
|
|
|
|
JS::ThrowCompletionOr<void> SVGElement::initialize(JS::Realm& realm)
|
|
{
|
|
MUST_OR_THROW_OOM(Base::initialize(realm));
|
|
set_prototype(&Bindings::ensure_web_prototype<Bindings::SVGElementPrototype>(realm, "SVGElement"));
|
|
|
|
m_dataset = TRY(Bindings::throw_dom_exception_if_needed(realm.vm(), [&]() {
|
|
return HTML::DOMStringMap::create(*this);
|
|
}));
|
|
|
|
return {};
|
|
}
|
|
|
|
void SVGElement::visit_edges(Cell::Visitor& visitor)
|
|
{
|
|
Base::visit_edges(visitor);
|
|
visitor.visit(m_dataset);
|
|
}
|
|
|
|
void SVGElement::parse_attribute(DeprecatedFlyString const& name, DeprecatedString const& value)
|
|
{
|
|
Base::parse_attribute(name, value);
|
|
|
|
update_use_elements_that_reference_this();
|
|
}
|
|
|
|
void SVGElement::inserted()
|
|
{
|
|
Base::inserted();
|
|
|
|
update_use_elements_that_reference_this();
|
|
}
|
|
|
|
void SVGElement::children_changed()
|
|
{
|
|
Base::children_changed();
|
|
|
|
update_use_elements_that_reference_this();
|
|
}
|
|
|
|
void SVGElement::update_use_elements_that_reference_this()
|
|
{
|
|
if (is<SVGUseElement>(this)) {
|
|
return;
|
|
}
|
|
|
|
document().for_each_in_subtree_of_type<SVGUseElement>([this](SVGUseElement& use_element) {
|
|
use_element.svg_element_changed(*this);
|
|
return IterationDecision::Continue;
|
|
});
|
|
}
|
|
|
|
void SVGElement::removed_from(Node* parent)
|
|
{
|
|
Base::removed_from(parent);
|
|
|
|
remove_from_use_element_that_reference_this();
|
|
}
|
|
|
|
void SVGElement::remove_from_use_element_that_reference_this()
|
|
{
|
|
if (is<SVGUseElement>(this)) {
|
|
return;
|
|
}
|
|
|
|
document().for_each_in_subtree_of_type<SVGUseElement>([this](SVGUseElement& use_element) {
|
|
use_element.svg_element_removed(*this);
|
|
return IterationDecision::Continue;
|
|
});
|
|
}
|
|
|
|
}
|