diff options
Diffstat (limited to 'testing/web-platform/tests/resize-observer/devicepixel2.html')
-rw-r--r-- | testing/web-platform/tests/resize-observer/devicepixel2.html | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/testing/web-platform/tests/resize-observer/devicepixel2.html b/testing/web-platform/tests/resize-observer/devicepixel2.html new file mode 100644 index 0000000000..97b6255457 --- /dev/null +++ b/testing/web-platform/tests/resize-observer/devicepixel2.html @@ -0,0 +1,131 @@ +<!doctype html> +<link rel="match" href="devicepixel2-ref.html"> +<meta name="assert" content="Resize Observer's reported device pixel content box size should be consistent with the actual pixel-snapped painted box size"> +<style> + html, body { + margin: 0; + } + .line { + width: 100px; + display: flex; + } + .line>* { + flex: 1; + height: 20px; + } +</style> +<body> + <div></div> + <script type="module"> +import createPatternDataURL from './create-pattern-data-url.js'; + +const {patternSize, dataURL} = createPatternDataURL(); + +/** + * Set the pattern's size on this element so that it draws where + * 1 pixel in the pattern maps to 1 devicePixel and then set + * its position so it's aligned to the pattern of the body element. + */ +function setPattern(elem, x, y) { + const oneDevicePixel = 1 / devicePixelRatio; + const patternPixels = oneDevicePixel * patternSize; + elem.style.backgroundImage = `url("${dataURL}")`; + elem.style.backgroundSize = `${patternPixels}px ${patternPixels}px`; + elem.style.backgroundPosition = `${-x * oneDevicePixel}px ${-y * oneDevicePixel}px`; +} + +/* +This test creates elements like this + + <body> + <div> + <div class="line"><div></div><div></div></div> + <div class="line"><div></div><div></div><div></div></div> + <div class="line"><div></div><div></div><div></div><div></div></div> + ... + </div> + </body> + +It has the first `<div>` starting at the top left corner of the page, the +same as the body so they should both have a devicePixel position of 0,0 + +The devicePixelContentBoxSize of all the elements is queried with +a ResizeObserver. + +It then sets a repeating background-image, background-size and +background-position on the all of the innermost children elements so +they have a 4x4 checkerboard image at a size that should draw each pixel +of the 4x4 checkerboard pattern in single devicePixels and so they should +all align with the same pattern applied in a similar manner to the body. + +In other words + + <div class="line"> + <div></div><div></div><div></div> + </div> + +The first child will be displayed at left = 0 so its background-position is +set to 0px 0px. The second child should be displayed at + +secondChildLeft = entry(firstChild).devicePixelContentBoxSize[0].inlineSize. + +The 3rd child should be displayed at + +thirdChildLeft = entry(firstChild).devicePixelContentBoxSize[0].inlineSize + + entry(secondChild).devicePixelContentBoxSize[0].inlineSize + +Using the children's device-pixel positions (determined as described above), +we then set each child's background-position to the negated version of the +position that we computed for that child. This effectively makes its pattern's +origin match the document origin. + +If what devicePixelContentBox reports is correct the children's patterns +will align with the pattern in the body and the children will be invisible. +If what devicePixelContentBox reports is incorrect the patterns will not +align and it should be clearly visible. +*/ + +const wrapperElem = document.querySelector('div'); + +const elemToDevicePixelSize = new Map(); + +function setPatternsUsingSizeInfo(entries) { + setPattern(document.body, 0, 0); + + for (const entry of entries) { + elemToDevicePixelSize.set(entry.target, { + inlineSize: entry.devicePixelContentBoxSize[0].inlineSize, + blockSize: entry.devicePixelContentBoxSize[0].blockSize, + }); + } + + let devicePixelY = 0; + for (const lineElem of wrapperElem.children) { + let devicePixelX = 0; + for (const childElem of lineElem.children) { + setPattern(childElem, devicePixelX, devicePixelY); + const devicePixelSize = elemToDevicePixelSize.get(childElem); + devicePixelX += devicePixelSize.inlineSize; + } + + const lineEntry = elemToDevicePixelSize.get(lineElem); + const lineHeight = lineEntry.blockSize; + devicePixelY += lineHeight; + } +} + +const observer = new ResizeObserver(setPatternsUsingSizeInfo); +observer.observe(document.body); +for (let numFlexItems = 2; numFlexItems < 15; ++numFlexItems) { + const lineElem = document.createElement('div'); + lineElem.className = 'line'; + observer.observe(lineElem, {box:"device-pixel-content-box"}); + for (let j = 0; j < numFlexItems; ++j) { + const inner = document.createElement('div'); + lineElem.appendChild(inner); + observer.observe(inner, {box:"device-pixel-content-box"}); + } + wrapperElem.appendChild(lineElem); +} + </script> +</body> |