LibWeb/SVG: Implement activation behavior for SVGAElement
This makes navigation work when clicking on SVG `<a>` elements.
This commit is contained in:
parent
ba7b0c60f0
commit
94fa08dcfe
5 changed files with 65 additions and 2 deletions
|
|
@ -267,7 +267,7 @@ bool Element::cannot_navigate() const
|
|||
return true;
|
||||
|
||||
// - element is not an a element and is not connected.
|
||||
return !is_html_anchor_element() && !is_connected();
|
||||
return !(is_html_anchor_element() || is_svg_a_element()) && !is_connected();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/links.html#following-hyperlinks-2
|
||||
|
|
@ -281,7 +281,7 @@ void Element::follow_the_hyperlink(Optional<String> hyperlink_suffix, HTML::User
|
|||
String target_attribute_value;
|
||||
|
||||
// 3. If subject is an a or area element, then set targetAttributeValue to the result of getting an element's target given subject.
|
||||
if (is_html_anchor_element() || is_html_area_element())
|
||||
if (is_html_anchor_element() || is_html_area_element() || is_svg_a_element())
|
||||
target_attribute_value = get_an_elements_target();
|
||||
|
||||
// 4. Let urlRecord be the result of encoding-parsing a URL given subject's href attribute value, relative to subject's node document.
|
||||
|
|
|
|||
|
|
@ -7,8 +7,11 @@
|
|||
|
||||
#include <LibWeb/Bindings/SVGAElementPrototype.h>
|
||||
#include <LibWeb/DOM/DOMTokenList.h>
|
||||
#include <LibWeb/HTML/UserNavigationInvolvement.h>
|
||||
#include <LibWeb/Layout/SVGGraphicsBox.h>
|
||||
#include <LibWeb/SVG/AttributeNames.h>
|
||||
#include <LibWeb/SVG/SVGAElement.h>
|
||||
#include <LibWeb/UIEvents/MouseEvent.h>
|
||||
|
||||
namespace Web::SVG {
|
||||
|
||||
|
|
@ -84,4 +87,39 @@ GC::Ptr<Layout::Node> SVGAElement::create_layout_node(GC::Ref<CSS::ComputedPrope
|
|||
return heap().allocate<Layout::SVGGraphicsBox>(document(), *this, move(style));
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/links.html#links-created-by-a-and-area-elements
|
||||
void SVGAElement::activation_behavior(DOM::Event const& event)
|
||||
{
|
||||
// The activation behavior of an a or area element element given an event event is:
|
||||
|
||||
// 1. If element has no href attribute, then return.
|
||||
if (href()->base_val().is_empty())
|
||||
return;
|
||||
|
||||
// AD-HOC: Do not activate the element for clicks with the ctrl/cmd modifier present. This lets
|
||||
// the browser process open the link in a new tab.
|
||||
if (is<UIEvents::MouseEvent>(event)) {
|
||||
auto const& mouse_event = static_cast<UIEvents::MouseEvent const&>(event);
|
||||
if (mouse_event.platform_ctrl_key())
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Let hyperlinkSuffix be null.
|
||||
Optional<String> hyperlink_suffix {};
|
||||
|
||||
// FIXME: 3. If element is an a element, and event's target is an img with an ismap attribute specified, then:
|
||||
|
||||
// 4. Let userInvolvement be event's user navigation involvement.
|
||||
auto user_involvement = HTML::user_navigation_involvement(event);
|
||||
|
||||
// FIXME: 5. If the user has expressed a preference to download the hyperlink, then set userInvolvement to "browser UI".
|
||||
|
||||
// FIXME: 6. If element has a download attribute, or if the user has expressed a preference to download the
|
||||
// hyperlink, then download the hyperlink created by element with hyperlinkSuffix set to hyperlinkSuffix and
|
||||
// userInvolvement set to userInvolvement.
|
||||
|
||||
// 7. Otherwise, follow the hyperlink created by element with hyperlinkSuffix set to hyperlinkSuffix and userInvolvement set to userInvolvement.
|
||||
follow_the_hyperlink(hyperlink_suffix, user_involvement);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ private:
|
|||
virtual void attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override;
|
||||
virtual i32 default_tab_index_value() const override;
|
||||
|
||||
virtual bool has_activation_behavior() const override { return true; }
|
||||
virtual void activation_behavior(DOM::Event const&) override;
|
||||
|
||||
GC::Ptr<DOM::DOMTokenList> m_rel_list;
|
||||
|
||||
GC::Ptr<SVGAnimatedString> m_target;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
basic link activated
|
||||
target link activated in iframe
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="include.js"></script>
|
||||
<iframe id="target-frame" name="target-frame"></iframe>
|
||||
<svg>
|
||||
<a id="basic-link" href="javascript:println('basic link activated')">
|
||||
<text y="20">Basic Link</text>
|
||||
</a>
|
||||
<a id="target-link" href="javascript:parent.println('target link activated in iframe')" target="target-frame">
|
||||
<text y="40">Target Link</text>
|
||||
</a>
|
||||
</svg>
|
||||
<script>
|
||||
promiseTest(async () => {
|
||||
document.getElementById("basic-link").dispatchEvent(new MouseEvent("click"));
|
||||
await animationFrame();
|
||||
|
||||
document.getElementById("target-link").dispatchEvent(new MouseEvent("click"));
|
||||
await animationFrame();
|
||||
});
|
||||
</script>
|
||||
Loading…
Reference in a new issue