Skip to content

Commit

Permalink
[popover][anchor-position] Implement implicit anchoring (2/2)
Browse files Browse the repository at this point in the history
- https://drafts.csswg.org/css-anchor-1/#implicit-anchor-element
- josepharhar/html#2

This is the 2/2 patch implementing implicit anchoring for popovers,
focusing on layout-level changes.

With the info of which elements are used as implicit anchors, this
patch adds the implicit anchors into NG*AnchorQuery with LayoutObject
as keys, so that implicit anchor queries can be evaluated without an
anchor name.

At a more detailed level, now all the NG*AnchorQuery classes need to
maintain two hashmaps: one keyed by names for the named anchors, and
the other keyed by LayoutObjects for the implicit anchors. To reduce
code verbosity, the common structure of these classes is abstracted
into a base class NGAnchorQueryBase.

Bug: 1307772, 1380112
Change-Id: I9bdec5e3c08f9b9b20442503dedf32995643f037
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4053342
Reviewed-by: Ian Kilpatrick <ikilpatrick@chromium.org>
Reviewed-by: Koji Ishii <kojii@chromium.org>
Commit-Queue: Xiaocheng Hu <xiaochengh@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1078270}
  • Loading branch information
xiaochengh authored and chromium-wpt-export-bot committed Dec 1, 2022
1 parent af36093 commit 5779697
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<meta charset="utf-8">

<p>There should be a green box attached to the right side of each orange box.</p>
<div class=ex><div class=anchor></div><div class=popover></div></div>
<div class=ex><div class=anchor></div><div class=popover></div></div>

<style>
.ex {
margin: 25px;
font-size: 0;
}
.ex div {
display:inline-block;
width: 100px;
height: 100px;
}
.anchor {
background: orange;
}
.popover {
background: lime;
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<!DOCTYPE html>
<meta charset="utf-8">
<link rel=author href="mailto:xiaochengh@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<link rel=match href="popover-anchor-change-display-ref.tentative.html">
<script src="resources/popover-utils.js"></script>

<p>There should be a green box attached to the right side of each orange box.</p>

<div class=ex>
<div class=anchor id=anchor1></div>
<div id=popover1 popover=manual defaultopen></div>
</div>

<div class=ex>
<div class=anchor id=will-be-anchor2></div>
<div id=popover2 popover=manual anchor=anchor2 defaultopen></div>
</div>

<script>
showDefaultopenPopoversOnLoad();

function runTest() {
document.body.offsetLeft; // Force layout

document.getElementById('popover1').setAttribute('anchor', 'anchor1');
document.getElementById('will-be-anchor2').setAttribute('id', 'anchor2');
}
window.addEventListener('load', runTest);
</script>

<style>
.ex {
margin: 25px;
}
.ex div {
width: 100px;
height: 100px;
}
.anchor {
background: orange;
}
[popover] {
background: lime;
padding:0;
border:0;
left: anchor(right);
top: anchor(top);
}
</style>
33 changes: 33 additions & 0 deletions html/semantics/popovers/popover-anchor-display-none.tentative.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Tests that a popover can be anchored to an unrendered element.</title>
<link rel=author href="mailto:xiaochengh@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>

<div id=popover popover anchor=anchor></div>
<div id=anchor></div>

<style>
#anchor {
display: none;
}
[popover] {
background: lime;
padding: 0;
border: 0;
width: 100px;
height: 100px;
top: anchor(top, 100px);
left: anchor(left, 100px);
}
</style>

<script>
test(() => {
popover.showPopover();
assert_equals(popover.offsetLeft, 100);
assert_equals(popover.offsetTop, 100);
});
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<div class=ex id=ex1><div class=anchor></div><div class=popover></div></div>
<div class=ex id=ex2><div class=anchor></div><div class=popover></div></div>
<div class=ex id=ex3><div class=anchor></div><div class=popover></div></div>
<div class=ex id=ex3><div class=anchor></div><div class=popover></div></div>

<style>
.ex {
Expand Down
19 changes: 18 additions & 1 deletion html/semantics/popovers/popover-anchor-display.tentative.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
<link rel=author href="mailto:masonf@chromium.org">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<link rel=match href="popover-anchor-display-ref.tentative.html">
<link rel=stylesheet href="/fonts/ahem.css">
<script src="resources/popover-utils.js"></script>

<p>There should be a green box attached to the right side of each orange box.</p>

<!-- Example using the `anchor` implicit reference element -->
<div class=ex>
<div class=anchor id=anchor1></div>
<div popover=manual anchor=anchor1 defaultopen></div>
<div id=popover1 popover=manual anchor=anchor1 defaultopen></div>
</div>

<!-- Example with `anchor` attribute but not using it for anchor pos -->
Expand All @@ -25,6 +26,13 @@
<div id=popover3 popover=manual defaultopen></div>
</div>

<!-- Example using implicit anchor reference and inline anchor element -->
<div class=ex>
<span id=anchor4>X</span>
<div id=popover4 popover=manual anchor=anchor4 defaultopen></div>
</div>


<script>
showDefaultopenPopoversOnLoad();
</script>
Expand Down Expand Up @@ -64,4 +72,13 @@
left: anchor(--anchor3 right);
top: anchor(--anchor3 top);
}
#anchor4 {
font-family: Ahem;
font-size: 100px;
color: orange;
}
#popover4 {
left: anchor(right);
top: anchor(top);
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<!DOCTYPE html>
<title>Tests popovers with implicit anchors in out-of-flow boxes</title>
<link rel="help" href="https://drafts.csswg.org/css-anchor-1/#determining">
<link rel="help" href="https://drafts.csswg.org/css-anchor-1/#propdef-anchor-name">
<link rel="help" href="https://drafts.csswg.org/css-anchor-1/#anchor-size">
<link rel="author" href="mailto:xiaochengh@chromium.org">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>

<style>
.relpos {
position: relative;
}
.columns {
column-count: 2;
column-fill: auto;
column-gap: 10px;
column-width: 100px;
width: 210px;
height: 50px;
}
#anchor1 {
position: absolute;
width: 10px;
height: 30px;
background: orange;
}
.target {
/*
* We need a popover to use implicit anchors, and force showing it with CSS
* so that it's not in the top layer.
*/
display: block;
position: absolute;
margin: 0;
border: 0;
padding: 0;
width: anchor-size(width);
height: anchor-size(height);
background: lime;
}
</style>
<body onload="checkLayout('.target')">
<div class="spacer" style="height: 10px"></div>
<div class="relpos">
<div class="columns">
<div class="spacer" style="height: 10px"></div>
<div class="relpos">
<div class="spacer" style="height: 10px"></div>
<div class="relpos">
<div class="spacer" style="height: 10px"></div>
<div id="anchor1"></div>
</div>
<div class="target" popover anchor="anchor1"
data-expected-height=50></div>
</div>
</div>
</div>

</body>

0 comments on commit 5779697

Please sign in to comment.