browser_inspector_highlighter-cssshape_offset-path.js (6237B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 // Test the creation of the CSS shapes highlighter for offset-path. 8 9 const TEST_URL = `data:text/html,<meta charset=utf8>${encodeURIComponent(` 10 <style> 11 html, body {margin: 0; padding: 0; } 12 13 .wrapper { 14 width: 100px; 15 height: 100px; 16 background: tomato; 17 } 18 19 .target { 20 width: 20px; 21 height: 20px; 22 display: block; 23 background: gold; 24 offset-path: inset(10% 20%); 25 } 26 27 #abs { 28 position: absolute; 29 background: cyan; 30 offset-path: inset(10% 20%); 31 } 32 </style> 33 <div class=wrapper> 34 <span id=regular class=target></span> 35 <span id=abs class=target></span> 36 </div>`)}`; 37 38 const { TYPES } = ChromeUtils.importESModule( 39 "resource://devtools/shared/highlighters.mjs" 40 ); 41 const HIGHLIGHTER_TYPE = TYPES.SHAPES; 42 43 add_task(async function () { 44 const env = await openInspectorForURL(TEST_URL); 45 const { highlighterTestFront, inspector } = env; 46 const view = selectRuleView(inspector); 47 48 await selectNode("#regular", inspector); 49 50 info(`Show offset-path shape highlighter for regular case`); 51 await toggleShapesHighlighter(view, ".target", "offset-path", true); 52 53 info( 54 "Check that highlighter is drawn relatively to the selected node parent node" 55 ); 56 57 const wrapperQuads = 58 await getAllAdjustedQuadsForContentPageElement(".wrapper"); 59 const { 60 width: wrapperWidth, 61 height: wrapperHeight, 62 x: wrapperX, 63 y: wrapperY, 64 } = wrapperQuads.content[0].bounds; 65 66 const rect = await getShapeHighlighterRect(highlighterTestFront, inspector); 67 // SVG stroke seems to impact boundingClientRect differently depending on platform/hardware. 68 // Let's assert that the delta is okay, and use it for the different assertions. 69 const delta = wrapperX + wrapperWidth * 0.2 - rect.x; 70 Assert.lessOrEqual(Math.abs(delta), 1, `delta is <=1 (${Math.abs(delta)})`); 71 72 // Coming from inset(10% 20%) 73 let inlineOffset = 0.2 * wrapperWidth - delta; 74 let blockOffset = 0.1 * wrapperHeight - delta; 75 76 is(rect.x, wrapperX + inlineOffset, "Rect has expected x"); 77 is(rect.y, wrapperY + blockOffset, "Rect has expected y"); 78 is(rect.width, wrapperWidth - inlineOffset * 2, "Rect has expected width"); 79 is(rect.height, wrapperHeight - blockOffset * 2, "Rect has expected height"); 80 81 const x = parseFloat( 82 await highlighterTestFront.getHighlighterNodeAttribute( 83 "shapes-rect", 84 "x", 85 inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE) 86 ) 87 ); 88 const y = parseFloat( 89 await highlighterTestFront.getHighlighterNodeAttribute( 90 "shapes-rect", 91 "y", 92 inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE) 93 ) 94 ); 95 const width = parseFloat( 96 await highlighterTestFront.getHighlighterNodeAttribute( 97 "shapes-rect", 98 "width", 99 inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE) 100 ) 101 ); 102 103 const left = (wrapperWidth * x) / 100; 104 const top = (wrapperHeight * y) / 100; 105 const right = left + (wrapperWidth * width) / 100; 106 const xCenter = (left + right) / 2; 107 const dy = wrapperHeight / 10; 108 109 const helper = await getHighlighterHelperFor(HIGHLIGHTER_TYPE)(env); 110 const { mouse } = helper; 111 112 info("Moving inset top"); 113 const onShapeChangeApplied = view.highlighters.once( 114 "shapes-highlighter-changes-applied" 115 ); 116 await mouse.down(xCenter, top, ".wrapper"); 117 await mouse.move(xCenter, top + dy, ".wrapper"); 118 await mouse.up(xCenter, top + dy, ".wrapper"); 119 await reflowContentPage(); 120 await onShapeChangeApplied; 121 122 const offsetPathAfterUpdate = await SpecialPowers.spawn( 123 gBrowser.selectedBrowser, 124 [], 125 () => 126 content.getComputedStyle(content.document.getElementById("regular")) 127 .offsetPath 128 ); 129 130 is( 131 offsetPathAfterUpdate, 132 `inset(${top + dy}% 20% 10%)`, 133 "Inset edges successfully moved" 134 ); 135 136 info(`Hide offset-path shape highlighter`); 137 await toggleShapesHighlighter(view, ".target", "offset-path", false); 138 139 info(`Show offset-path shape highlighter for absolutely positioned element`); 140 await selectNode("#abs", inspector); 141 await toggleShapesHighlighter(view, ".target", "offset-path", true); 142 143 const viewportClientRect = await SpecialPowers.spawn( 144 gBrowser.selectedBrowser, 145 [], 146 () => { 147 const [quad] = content.document.getBoxQuads(); 148 return { 149 x: quad.p1.x, 150 y: quad.p1.y, 151 width: quad.p2.x - quad.p1.x, 152 height: quad.p3.y - quad.p2.y, 153 }; 154 } 155 ); 156 157 const absRect = await getShapeHighlighterRect( 158 highlighterTestFront, 159 inspector 160 ); 161 162 inlineOffset = 0.2 * viewportClientRect.width - delta; 163 blockOffset = 0.1 * viewportClientRect.height - delta; 164 165 Assert.less( 166 Math.abs(absRect.x - (viewportClientRect.x + inlineOffset)), 167 1, 168 `Rect approximately has expected x (got ${absRect.x}, expected ${ 169 viewportClientRect.x + inlineOffset 170 })` 171 ); 172 Assert.less( 173 Math.abs(absRect.y - (viewportClientRect.y + blockOffset)), 174 1, 175 `Rect approximately has expected y (got ${absRect.y}, expected ${ 176 viewportClientRect.y + blockOffset 177 })` 178 ); 179 Assert.less( 180 Math.abs(absRect.width - (viewportClientRect.width - inlineOffset * 2)), 181 1, 182 `Rect approximately has expected width (got ${absRect.width}, expected ${ 183 viewportClientRect.width - inlineOffset * 2 184 })` 185 ); 186 Assert.less( 187 Math.abs(absRect.height - (viewportClientRect.height - blockOffset * 2)), 188 1, 189 `Rect approximately has expected height (got ${absRect.height}, expected ${ 190 viewportClientRect.height - blockOffset * 2 191 })` 192 ); 193 194 info(`Hide offset-path shape highlighter for absolutely positioned element`); 195 await toggleShapesHighlighter(view, ".target", "offset-path", false); 196 }); 197 198 async function getShapeHighlighterRect(highlighterTestFront, inspector) { 199 const highlighterFront = 200 inspector.inspectorFront.getKnownHighlighter(HIGHLIGHTER_TYPE); 201 return highlighterTestFront.getHighlighterBoundingClientRect( 202 "shapes-rect", 203 highlighterFront.actorID 204 ); 205 }