mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-09 17:44:56 +09:00
LibWeb: Implement Element::check_visibility
This commit is contained in:
parent
4a2d5bcf89
commit
5f154ba372
Notes:
github-actions[bot]
2024-07-20 08:15:46 +00:00
Author: https://github.com/EdwinHoksberg
Commit: 5f154ba372
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/717
Reviewed-by: https://github.com/tcl3 ✅
5 changed files with 148 additions and 1 deletions
|
@ -0,0 +1,8 @@
|
|||
display-none visible: false
|
||||
content-visibility-parent visible: true
|
||||
content-visibility-child visible: false
|
||||
opacity-hidden visible: false
|
||||
opacity-visible visible: true
|
||||
visibility-hidden visible: false
|
||||
visibility-visible visible: true
|
||||
content-visibility-auto-hidden visible: true
|
71
Tests/LibWeb/Text/input/HTML/Element-checkVisibility.html
Normal file
71
Tests/LibWeb/Text/input/HTML/Element-checkVisibility.html
Normal file
|
@ -0,0 +1,71 @@
|
|||
<!DOCTYPE html>
|
||||
<style>
|
||||
.display-none {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.content-visibility-parent {
|
||||
content-visibility: hidden;
|
||||
}
|
||||
|
||||
.opacity-hidden {
|
||||
opacity: 0;
|
||||
}
|
||||
.opacity-visible {
|
||||
opacity: 0.1;
|
||||
}
|
||||
|
||||
.visibility-hidden {
|
||||
visibility: hidden;
|
||||
}
|
||||
.visibility-visible {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.content-visibility-auto-hidden {
|
||||
content-visibility: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="display-none"></div>
|
||||
|
||||
<div class="content-visibility-parent">
|
||||
<div class="content-visibility-child"></div>
|
||||
</div>
|
||||
|
||||
<div class="opacity-hidden"></div>
|
||||
<div class="opacity-visible"></div>
|
||||
|
||||
<div class="visibility-hidden"></div>
|
||||
<div class="visibility-visible"></div>
|
||||
|
||||
<div class="content-visibility-auto-hidden"></div>
|
||||
|
||||
<script src="../include.js"></script>
|
||||
<script>
|
||||
test(() => {
|
||||
const displayNone = document.querySelector('.display-none');
|
||||
println("display-none visible: " + displayNone.checkVisibility());
|
||||
|
||||
const contentVisibilityParent = document.querySelector('.content-visibility-parent');
|
||||
println("content-visibility-parent visible: " + contentVisibilityParent.checkVisibility());
|
||||
|
||||
const contentVisibilityChild = document.querySelector('.content-visibility-child');
|
||||
println("content-visibility-child visible: " + contentVisibilityChild.checkVisibility());
|
||||
|
||||
const opacityHidden = document.querySelector('.opacity-hidden');
|
||||
println("opacity-hidden visible: " + opacityHidden.checkVisibility({opacityProperty: true}));
|
||||
|
||||
const opacityVisible = document.querySelector('.opacity-visible');
|
||||
println("opacity-visible visible: " + opacityVisible.checkVisibility({opacityProperty: true}));
|
||||
|
||||
const visibilityHidden = document.querySelector('.visibility-hidden');
|
||||
println("visibility-hidden visible: " + visibilityHidden.checkVisibility({visibilityProperty: true}));
|
||||
|
||||
const visibilityVisible = document.querySelector('.visibility-visible');
|
||||
println("visibility-visible visible: " + visibilityVisible.checkVisibility({visibilityProperty: true}));
|
||||
|
||||
const contentVisibilityAutoHidden = document.querySelector('.content-visibility-auto-hidden');
|
||||
println("content-visibility-auto-hidden visible: " + contentVisibilityAutoHidden.checkVisibility({contentVisibilityAuto: true}));
|
||||
});
|
||||
</script>
|
|
@ -2344,6 +2344,54 @@ void Element::scroll_by(HTML::ScrollToOptions options)
|
|||
scroll(options);
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view-1/#dom-element-checkvisibility
|
||||
bool Element::check_visibility(Optional<CheckVisibilityOptions> options)
|
||||
{
|
||||
// NOTE: Ensure that layout is up-to-date before looking at metrics.
|
||||
document().update_layout();
|
||||
|
||||
// 1. If this does not have an associated box, return false.
|
||||
if (!paintable_box())
|
||||
return false;
|
||||
|
||||
// 2. If an ancestor of this in the flat tree has content-visibility: hidden, return false.
|
||||
for (auto* element = parent_element(); element; element = element->parent_element()) {
|
||||
if (element->computed_css_values()->content_visibility() == CSS::ContentVisibility::Hidden)
|
||||
return false;
|
||||
}
|
||||
|
||||
// AD-HOC: Since the rest of the steps use the options, we can return early if we haven't been given any options.
|
||||
if (!options.has_value())
|
||||
return true;
|
||||
|
||||
// 3. If either the opacityProperty or the checkOpacity dictionary members of options are true, and this, or an ancestor of this in the flat tree, has a computed opacity value of 0, return false.
|
||||
if (options->opacity_property || options->check_opacity) {
|
||||
for (auto* element = this; element; element = element->parent_element()) {
|
||||
if (element->computed_css_values()->opacity() == 0.0f)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. If either the visibilityProperty or the checkVisibilityCSS dictionary members of options are true, and this is invisible, return false.
|
||||
if (options->visibility_property || options->check_visibility_css) {
|
||||
if (computed_css_values()->visibility() == CSS::Visibility::Hidden)
|
||||
return false;
|
||||
}
|
||||
|
||||
// 5. If the contentVisibilityAuto dictionary member of options is true and an ancestor of this in the flat tree skips its contents due to content-visibility: auto, return false.
|
||||
// FIXME: Currently we do not skip any content if content-visibility is auto: https://drafts.csswg.org/css-contain-2/#proximity-to-the-viewport
|
||||
auto const skipped_contents_due_to_content_visibility_auto = false;
|
||||
if (options->content_visibility_auto && skipped_contents_due_to_content_visibility_auto) {
|
||||
for (auto* element = this; element; element = element->parent_element()) {
|
||||
if (element->computed_css_values()->content_visibility() == CSS::ContentVisibility::Auto)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 6. Return true.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Element::id_reference_exists(String const& id_reference) const
|
||||
{
|
||||
return document().get_element_by_id(id_reference);
|
||||
|
|
|
@ -48,6 +48,15 @@ struct ScrollIntoViewOptions : public HTML::ScrollOptions {
|
|||
Bindings::ScrollLogicalPosition inline_ { Bindings::ScrollLogicalPosition::Nearest };
|
||||
};
|
||||
|
||||
// https://drafts.csswg.org/cssom-view-1/#dictdef-checkvisibilityoptions
|
||||
struct CheckVisibilityOptions {
|
||||
bool check_opacity = false;
|
||||
bool check_visibility_css = false;
|
||||
bool content_visibility_auto = false;
|
||||
bool opacity_property = false;
|
||||
bool visibility_property = false;
|
||||
};
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/custom-elements.html#upgrade-reaction
|
||||
// An upgrade reaction, which will upgrade the custom element and contains a custom element definition; or
|
||||
struct CustomElementUpgradeReaction {
|
||||
|
@ -354,6 +363,8 @@ public:
|
|||
void scroll_by(HTML::ScrollToOptions);
|
||||
void scroll_by(double x, double y);
|
||||
|
||||
bool check_visibility(Optional<CheckVisibilityOptions>);
|
||||
|
||||
void register_intersection_observer(Badge<IntersectionObserver::IntersectionObserver>, IntersectionObserver::IntersectionObserverRegistration);
|
||||
void unregister_intersection_observer(Badge<IntersectionObserver::IntersectionObserver>, JS::NonnullGCPtr<IntersectionObserver::IntersectionObserver>);
|
||||
IntersectionObserver::IntersectionObserverRegistration& get_intersection_observer_registration(Badge<DOM::Document>, IntersectionObserver::IntersectionObserver const&);
|
||||
|
|
|
@ -20,6 +20,15 @@ dictionary ScrollIntoViewOptions : ScrollOptions {
|
|||
ScrollLogicalPosition inline = "nearest";
|
||||
};
|
||||
|
||||
// https://drafts.csswg.org/cssom-view-1/#dictdef-checkvisibilityoptions
|
||||
dictionary CheckVisibilityOptions {
|
||||
boolean checkOpacity = false;
|
||||
boolean checkVisibilityCSS = false;
|
||||
boolean contentVisibilityAuto = false;
|
||||
boolean opacityProperty = false;
|
||||
boolean visibilityProperty = false;
|
||||
};
|
||||
|
||||
// https://dom.spec.whatwg.org/#element
|
||||
[Exposed=Window]
|
||||
interface Element : Node {
|
||||
|
@ -74,7 +83,7 @@ interface Element : Node {
|
|||
DOMRectList getClientRects();
|
||||
DOMRect getBoundingClientRect();
|
||||
|
||||
[FIXME] boolean checkVisibility(optional CheckVisibilityOptions options = {});
|
||||
boolean checkVisibility(optional CheckVisibilityOptions options = {});
|
||||
|
||||
undefined scrollIntoView(optional (boolean or ScrollIntoViewOptions) arg = {});
|
||||
undefined scroll(optional ScrollToOptions options = {});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue