[anchor-position] Support logical keywords (#37180)
This patch supports `start`, `end`, `self-start`, and
`self-end` keywords for the `anchor()` function[1].
[1] https://drafts.csswg.org/css-anchor-1/#anchor-pos
Bug: 1382524
Change-Id: Ie2a1e3bb3653475facac0454461327dd69e8ee89
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4060987
Auto-Submit: Koji Ishii <kojii@chromium.org>
Reviewed-by: Kent Tamura <tkent@chromium.org>
Commit-Queue: Kent Tamura <tkent@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1076083}
Co-authored-by: Koji Ishii <kojii@chromium.org>
diff --git a/css/css-anchor-position/anchor-position-writing-modes-002.html b/css/css-anchor-position/anchor-position-writing-modes-002.html
new file mode 100644
index 0000000..15a9a63
--- /dev/null
+++ b/css/css-anchor-position/anchor-position-writing-modes-002.html
@@ -0,0 +1,102 @@
+<!DOCTYPE html>
+<title>Tests logical `anchor` function for `writing-mode`/`direction`s</title>
+<link rel="help" href="https://drafts.csswg.org/css-anchor-1/#anchor-pos">
+<link rel="author" href="mailto:kojii@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script><style>
+<style>
+.htb-ltr { writing-mode: horizontal-tb; direction: ltr; }
+.htb-rtl { writing-mode: horizontal-tb; direction: rtl; }
+.vlr-ltr { writing-mode: vertical-lr; direction: ltr; }
+.vlr-rtl { writing-mode: vertical-lr; direction: rtl; }
+.vrl-ltr { writing-mode: vertical-rl; direction: ltr; }
+.vrl-rtl { writing-mode: vertical-rl; direction: rtl; }
+.relpos {
+ position: relative;
+ outline: blue 1px solid;
+}
+.spacer {
+ width: 10px;
+ height: 10px;
+ background: yellow;
+}
+.anchor {
+ anchor-name: --a1;
+ margin: 5px;
+ width: 30px;
+ height: 30px;
+ background: orange;
+}
+.target {
+ position: absolute;
+ outline: 5px solid lime;
+}
+</style>
+<body>
+ <template id="template">
+ <div class="relpos">
+ <div class="spacer"></div>
+ <div class="anchor"></div>
+ </div>
+ </template>
+<script>
+// Generate tests for all combinations.
+// The first two entries are the side `start` and `end` should match in x-axis.
+// The next two entries are the side `start` and `end` should match in y-axis.
+const writingDirs = {
+ 'htb-ltr':['l', 'r', 't', 'b'],
+ 'htb-rtl':['r', 'l', 't', 'b'],
+ 'vrl-ltr':['r', 'l', 't', 'b'],
+ 'vrl-rtl':['r', 'l', 'b', 't'],
+ 'vlr-ltr':['l', 'r', 't', 'b'],
+ 'vlr-rtl':['l', 'r', 'b', 't'],
+};
+const container = document.body;
+const cb_template = template.content.firstElementChild;
+for (const [writingDir, matches] of Object.entries(writingDirs)) {
+ const cb = cb_template.cloneNode(true);
+ cb.classList.add(writingDir);
+ createTarget(null, 'left: anchor(--a1 start)', matches[0], cb);
+ createTarget(null, 'left: anchor(--a1 end)', matches[1], cb);
+ createTarget(null, 'top: anchor(--a1 start)', matches[2], cb);
+ createTarget(null, 'top: anchor(--a1 end)', matches[3], cb);
+ createTarget(writingDir, 'left: anchor(--a1 self-start)', matches[0], cb);
+ createTarget(writingDir, 'left: anchor(--a1 self-end)', matches[1], cb);
+ createTarget(writingDir, 'top: anchor(--a1 self-start)', matches[2], cb);
+ createTarget(writingDir, 'top: anchor(--a1 self-end)', matches[3], cb);
+ container.appendChild(cb);
+}
+
+function createTarget(className, style, match, cb) {
+ const target = document.createElement('div');
+ target.classList.add('target');
+ if (className)
+ target.classList.add(className);
+ target.style = style;
+ target.dataset.match = match;
+ cb.appendChild(target);
+}
+
+// Test all `.target`s.
+for (const target of document.querySelectorAll('.target')) {
+ const cb = target.parentElement;
+ const anchor = cb.querySelector('.anchor');
+ test(() => {
+ switch (target.dataset.match) {
+ case 'l':
+ assert_equals(anchor.offsetLeft, target.offsetLeft);
+ break;
+ case 'r':
+ assert_equals(anchor.offsetLeft + anchor.offsetWidth, target.offsetLeft);
+ break;
+ case 't':
+ assert_equals(anchor.offsetTop, target.offsetTop);
+ break;
+ case 'b':
+ assert_equals(anchor.offsetTop + anchor.offsetHeight, target.offsetTop);
+ break;
+ }
+ }, `${cb.classList}/${target.classList}/${target.style.cssText}`);
+}
+</script>
+</body>