| <!DOCTYPE html> |
| <html> |
| <meta charset="utf-8"> |
| <title>View timeline with fieldset as source</title> |
| <link rel="help" href="https://www.w3.org/TR/scroll-animations-1/#dom-viewtimeline-viewtimeline"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="/web-animations/testcommon.js"></script> |
| <style> |
| @keyframes colorize { |
| from { background-color: #ccf; } |
| to { background-color: white; } |
| } |
| |
| .input { |
| background-color: white; |
| view-timeline: --timeline; |
| animation: colorize; |
| animation-timeline: --timeline; |
| margin-top: 0px; |
| margin-bottom: 3px; |
| margin-left: 8px; |
| height: 20px; |
| width: 150px; |
| } |
| |
| .input:last-child { |
| margin-bottom: 0px; |
| } |
| |
| fieldset { |
| display: inline-block; |
| overflow-x: hidden; |
| overflow-y: scroll; |
| height: 80px; |
| } |
| |
| div { |
| display: flex; |
| justify-content: flex-end; |
| align-items: center; |
| } |
| </style> |
| <body> |
| <fieldset id="fieldset"> |
| <legend id="legend">Reservation Details</legend> |
| <div> |
| <label for="name">Name: </label> |
| <input type="text" class="input" id="input1" value="Jane Doe" /> |
| </div> |
| <div> |
| <label for="date">Date: </label> |
| <input type="date" class="input" id="input2" value="2024-01-16"/> |
| </div> |
| <div> |
| <label for="time">Time: </label> |
| <input type="time" class="input" id="input3" value="18:30"/> |
| </div> |
| <div> |
| <label for="name">Number of guests: </label> |
| <input type="number" class="input" id="input4" value="5" /> |
| </div> |
| <div> |
| <label for="name">Contact info: </label> |
| <input type="text" class="input" id="input5" value="(555) 555-5555" /> |
| </div> |
| </fieldset> |
| </body> |
| <script> |
| async function runTest() { |
| promise_test(async t => { |
| const anims = document.getAnimations(); |
| assert_equals(anims.length, 5); |
| await Promise.all(anims.map(anim => anim.ready)); |
| |
| // The bottom of the legend aligns with the top of the fieldset's |
| // scrollable area. |
| const fieldset = document.getElementById('fieldset'); |
| const legend = document.getElementById('legend'); |
| const fieldsetContentTop = |
| legend.getBoundingClientRect().bottom; |
| |
| // The bottom of the scroll container aligns with the bottom of the |
| // fieldset's content box. |
| const fieldsetContentBottom = |
| fieldset.getBoundingClientRect().bottom - |
| parseFloat(getComputedStyle(fieldset).borderBottom); |
| |
| // Validate the start and end offsets for each view timeline. |
| for (let anim of anims) { |
| assert_equals(anim.timeline.source.id, 'fieldset'); |
| assert_equals(anim.timeline.subject.tagName, 'INPUT'); |
| const bounds = anim.effect.target.getBoundingClientRect(); |
| |
| const expectedStartOffset = bounds.top - fieldsetContentBottom; |
| const expectedEndOffset = bounds.bottom - fieldsetContentTop; |
| assert_approx_equals( |
| parseFloat(anim.timeline.startOffset), |
| expectedStartOffset, 0.5, |
| `Unexpected start offset for ${anim.effect.target.id}`); |
| assert_approx_equals( |
| parseFloat(anim.timeline.endOffset), |
| expectedEndOffset, 0.5, |
| `Unexpected end offset for ${anim.effect.target.id}`); |
| }; |
| }, 'Fieldset is a valid source for a view timeline'); |
| } |
| |
| window.onload = runTest(); |
| </script> |
| </html> |