mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-09 09:34:57 +09:00
LibWeb: Make a elements honor base element's target
This commit is contained in:
parent
79d6d5a7fa
commit
f839f1b44b
Notes:
github-actions[bot]
2025-02-16 08:22:46 +00:00
Author: https://github.com/Psychpsyo
Commit: f839f1b44b
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3576
8 changed files with 50 additions and 8 deletions
|
@ -536,6 +536,7 @@ void Document::visit_edges(Cell::Visitor& visitor)
|
|||
visitor.visit(m_fonts);
|
||||
visitor.visit(m_selection);
|
||||
visitor.visit(m_first_base_element_with_href_in_tree_order);
|
||||
visitor.visit(m_first_base_element_with_target_in_tree_order);
|
||||
visitor.visit(m_parser);
|
||||
visitor.visit(m_lazy_load_intersection_observer);
|
||||
visitor.visit(m_visual_viewport);
|
||||
|
@ -1075,18 +1076,26 @@ Vector<CSS::BackgroundLayerData> const* Document::background_layers() const
|
|||
|
||||
void Document::update_base_element(Badge<HTML::HTMLBaseElement>)
|
||||
{
|
||||
GC::Ptr<HTML::HTMLBaseElement const> base_element;
|
||||
GC::Ptr<HTML::HTMLBaseElement const> base_element_with_href = nullptr;
|
||||
GC::Ptr<HTML::HTMLBaseElement const> base_element_with_target = nullptr;
|
||||
|
||||
for_each_in_subtree_of_type<HTML::HTMLBaseElement>([&base_element](HTML::HTMLBaseElement const& base_element_in_tree) {
|
||||
if (base_element_in_tree.has_attribute(HTML::AttributeNames::href)) {
|
||||
base_element = &base_element_in_tree;
|
||||
for_each_in_subtree_of_type<HTML::HTMLBaseElement>([&base_element_with_href, &base_element_with_target](HTML::HTMLBaseElement const& base_element_in_tree) {
|
||||
if (!base_element_with_href && base_element_in_tree.has_attribute(HTML::AttributeNames::href)) {
|
||||
base_element_with_href = &base_element_in_tree;
|
||||
if (base_element_with_target)
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
if (!base_element_with_target && base_element_in_tree.has_attribute(HTML::AttributeNames::target)) {
|
||||
base_element_with_target = &base_element_in_tree;
|
||||
if (base_element_with_href)
|
||||
return TraversalDecision::Break;
|
||||
}
|
||||
|
||||
return TraversalDecision::Continue;
|
||||
});
|
||||
|
||||
m_first_base_element_with_href_in_tree_order = base_element;
|
||||
m_first_base_element_with_href_in_tree_order = base_element_with_href;
|
||||
m_first_base_element_with_target_in_tree_order = base_element_with_target;
|
||||
}
|
||||
|
||||
GC::Ptr<HTML::HTMLBaseElement const> Document::first_base_element_with_href_in_tree_order() const
|
||||
|
@ -1094,6 +1103,11 @@ GC::Ptr<HTML::HTMLBaseElement const> Document::first_base_element_with_href_in_t
|
|||
return m_first_base_element_with_href_in_tree_order;
|
||||
}
|
||||
|
||||
GC::Ptr<HTML::HTMLBaseElement const> Document::first_base_element_with_target_in_tree_order() const
|
||||
{
|
||||
return m_first_base_element_with_target_in_tree_order;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/urls-and-fetching.html#fallback-base-url
|
||||
URL::URL Document::fallback_base_url() const
|
||||
{
|
||||
|
|
|
@ -152,6 +152,7 @@ public:
|
|||
|
||||
void update_base_element(Badge<HTML::HTMLBaseElement>);
|
||||
GC::Ptr<HTML::HTMLBaseElement const> first_base_element_with_href_in_tree_order() const;
|
||||
GC::Ptr<HTML::HTMLBaseElement const> first_base_element_with_target_in_tree_order() const;
|
||||
|
||||
String url_string() const { return m_url.to_string(); }
|
||||
String document_uri() const { return url_string(); }
|
||||
|
@ -1022,8 +1023,9 @@ private:
|
|||
// https://w3c.github.io/selection-api/#dfn-selection
|
||||
GC::Ptr<Selection::Selection> m_selection;
|
||||
|
||||
// NOTE: This is a cache to make finding the first <base href> element O(1).
|
||||
// NOTE: This is a cache to make finding the first <base href> or <base target> element O(1).
|
||||
GC::Ptr<HTML::HTMLBaseElement const> m_first_base_element_with_href_in_tree_order;
|
||||
GC::Ptr<HTML::HTMLBaseElement const> m_first_base_element_with_target_in_tree_order;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/images.html#list-of-available-images
|
||||
GC::Ptr<HTML::ListOfAvailableImages> m_list_of_available_images;
|
||||
|
|
|
@ -948,8 +948,10 @@ String HTMLElement::get_an_elements_target(Optional<String> target) const
|
|||
if (auto maybe_target = attribute(AttributeNames::target); maybe_target.has_value()) {
|
||||
target = maybe_target.release_value();
|
||||
}
|
||||
// FIXME: 2. Otherwise, if element's node document contains a base element with a target attribute,
|
||||
// 2. Otherwise, if element's node document contains a base element with a target attribute,
|
||||
// set target to the value of the target attribute of the first such base element.
|
||||
if (auto base_element = document().first_base_element_with_target_in_tree_order())
|
||||
target = base_element->attribute(AttributeNames::target);
|
||||
}
|
||||
|
||||
// 2. If target is not null, and contains an ASCII tab or newline and a U+003C (<), then set target to "_blank".
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
<!DOCTYPE html>
|
||||
SUCCESS!
|
|
@ -0,0 +1,3 @@
|
|||
<!DOCTYPE html>
|
||||
<base target="_parent">
|
||||
<a id="a" href="a-element-target-sub-alt.html">Click me!</a>
|
2
Tests/LibWeb/Text/data/base/a-element-target-sub.html
Normal file
2
Tests/LibWeb/Text/data/base/a-element-target-sub.html
Normal file
|
@ -0,0 +1,2 @@
|
|||
<!DOCTYPE html>
|
||||
<iframe id="frame" src="a-element-target-sub-sub.html"></iframe>
|
1
Tests/LibWeb/Text/expected/base/a-element-target.txt
Normal file
1
Tests/LibWeb/Text/expected/base/a-element-target.txt
Normal file
|
@ -0,0 +1 @@
|
|||
Parent frame navigated successfully!
|
16
Tests/LibWeb/Text/input/base/a-element-target.html
Normal file
16
Tests/LibWeb/Text/input/base/a-element-target.html
Normal file
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../include.js"></script>
|
||||
<iframe id="frame" src="../../data/base/a-element-target-sub.html"></iframe>
|
||||
<script>
|
||||
asyncTest(done => {
|
||||
window.onload = () => {
|
||||
frame.onload = () => {
|
||||
frame.onload = () => {
|
||||
println(frame.contentDocument.location.href.includes("a-element-target-sub-alt.html")? "Parent frame navigated successfully!" : "Parent frame incorrectly navigated to " + frame.contentDocument.location.href);
|
||||
done();
|
||||
}
|
||||
}
|
||||
frame.contentDocument.getElementById("frame").contentDocument.getElementById("a").click();
|
||||
};
|
||||
});
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue