test_GridElementWidthResizer.html (6987B)
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 <!DOCTYPE HTML> 5 <html> 6 <!-- Basic tests for the GridElementWidthResizer component. --> 7 <head> 8 <meta charset="utf-8"> 9 <title>Tree component test</title> 10 <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> 11 <script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> 12 <link href="chrome://mochikit/content/tests/SimpleTest/test.css" rel="stylesheet" type="text/css"/> 13 <link href="chrome://devtools/skin/splitters.css" rel="stylesheet" type="text/css"/> 14 <link href="chrome://devtools/content/shared/components/splitter/GridElementResizer.css" rel="stylesheet" type="text/css"/> 15 <style> 16 * { 17 box-sizing: border-box; 18 } 19 20 html { 21 --theme-splitter-color: red; 22 } 23 24 main { 25 display: grid; 26 grid-template-columns: auto 1fr auto; 27 grid-template-rows: 20px 20px 20px; 28 grid-gap: 10px; 29 } 30 31 .a, 32 .b, 33 .c, 34 .d { 35 border: 1px solid green; 36 } 37 38 header { 39 grid-column: 1 / -1; 40 } 41 .a { 42 grid-column: 1 / 2; 43 grid-row: 2 / -1; 44 min-width: 100px; 45 } 46 .b { 47 grid-column: 2 / 3; 48 grid-row: 2 / -1; 49 } 50 51 .c { 52 grid-column: 3 / 4; 53 grid-row: 2 / 3; 54 } 55 56 .d { 57 grid-column: 3 / 4; 58 grid-row: 3 / 4; 59 min-width: 150px; 60 } 61 62 .resizer-a { 63 grid-column: 1 / 2; 64 grid-row: 2 / -1; 65 } 66 67 .resizer-d { 68 grid-column: 3 / 4; 69 grid-row: 2 / -1; 70 } 71 </style> 72 </head> 73 <body> 74 <main></main> 75 <pre id="test"> 76 <script src="head.js" type="application/javascript"></script> 77 <script type="application/javascript"> 78 79 'use strict' 80 81 const FUDGE_FACTOR = .5; 82 function aboutEq(a, b) { 83 dumpn(`Checking ${a} ~= ${b}`); 84 return Math.abs(a - b) < FUDGE_FACTOR; 85 } 86 87 window.onload = async function () { 88 try { 89 const React = browserRequire("devtools/client/shared/vendor/react"); 90 const ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom"); 91 const dom = require("devtools/client/shared/vendor/react-dom-factories"); 92 93 const GridElementWidthResizer = React.createFactory(browserRequire("devtools/client/shared/components/splitter/GridElementWidthResizer")); 94 ok(GridElementWidthResizer, "Should get GridElementWidthResizer"); 95 96 const resizedA = []; 97 const resizedD = []; 98 99 ReactDOM.render([ 100 dom.header({}, "header"), 101 dom.aside({className: "a"}, "A"), 102 GridElementWidthResizer({ 103 getControlledElementNode: () => a, 104 enabled: true, 105 position: "end", 106 className: "resizer-a", 107 onResizeEnd: width => resizedA.push(width), 108 }), 109 dom.section({className: "b"}, "B"), 110 GridElementWidthResizer({ 111 getControlledElementNode: () => window.document.querySelector(".b"), 112 enabled: false, 113 position: "start", 114 className: "resizer-disabled", 115 }), 116 dom.aside({className: "c"}, "C"), 117 dom.aside({className: "d"}, "D"), 118 GridElementWidthResizer({ 119 getControlledElementNode: () => d, 120 enabled: true, 121 position: "start", 122 className: "resizer-d", 123 onResizeEnd: width => resizedD.push(width), 124 }), 125 ], window.document.querySelector("main")); 126 127 // wait for a bit as we may not have everything setup yet. 128 await new Promise(res => setTimeout(res, 10)); 129 130 const a = window.document.querySelector(".a"); 131 const d = window.document.querySelector(".d"); 132 133 // Test that we properly rendered our two resizers, and not the disabled one. 134 const resizers = window.document.querySelectorAll(".grid-element-width-resizer"); 135 is(resizers.length, 2, "The 2 enabled resizers are rendered"); 136 137 const [resizerA, resizerD] = resizers; 138 139 ok(resizerA.classList.contains("resizer-a") 140 && resizerA.classList.contains("end"), "resizerA has expected classes"); 141 ok(resizerD.classList.contains("resizer-d") 142 && resizerD.classList.contains("start"), "resizerD has expected classes"); 143 144 const aBoundingRect = a.getBoundingClientRect(); 145 const aOriginalWidth = aBoundingRect.width; 146 147 info("Resize element A"); 148 await resize(resizerA, aBoundingRect.right + 20); 149 150 is(resizedA.length, 1, "onResizeEnd was called once"); 151 is(resizedD.length, 0, "resizerD was not impacted"); 152 let aWidth = a.getBoundingClientRect().width; 153 is(resizedA[0], aWidth, "onResizeEnd gives the width of the controlled element"); 154 ok(aboutEq(aWidth, aOriginalWidth + 20), 155 "controlled element was resized to the expected size"); 156 157 info("Resize element A below its min width"); 158 await resize(resizerA, [aBoundingRect.left + 10]); 159 aWidth = a.getBoundingClientRect().width; 160 ok(aboutEq(aWidth, 100), "controlled element was resized to its min width"); 161 162 info("Resize element D below its min width"); 163 const dBoundingRect = d.getBoundingClientRect(); 164 const dOriginalWidth = dBoundingRect.width; 165 166 await resize(resizerD, dBoundingRect.left + 100); 167 is(resizedD.length, 1, "onResizeEnd was called once for d"); 168 is(resizedA.length, 2, "onResizeEnd wasn't called for a"); 169 let dWidth = d.getBoundingClientRect().width; 170 is(resizedD[0], dWidth, "onResizeEnd gives the width of the controlled element"); 171 ok(aboutEq(dWidth, 150), "controlled element wasn't resized below its min-width"); 172 173 info("Resize element D"); 174 await resize(resizerD, dBoundingRect.left - 15); 175 dWidth = d.getBoundingClientRect().width; 176 is(resizedD[1], dWidth, "onResizeEnd gives the width of the controlled element"); 177 ok(aboutEq(dWidth, dOriginalWidth + 15), "element was resized"); 178 } catch(e) { 179 ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e)); 180 } finally { 181 SimpleTest.finish(); 182 } 183 184 async function resize(resizer, clientX) { 185 info("Mouse down to start dragging"); 186 synthesizeMouseAtCenter(resizer, { button: 0, type: "mousedown" }, window); 187 await SimpleTest.promiseWaitForCondition( 188 () => document.firstElementChild.classList.contains("dragging"), 189 "dragging class is never set on the root element" 190 ); 191 ok(true, "The dragging class is set on the root element"); 192 193 const event = new MouseEvent("mousemove", { clientX }); 194 resizer.dispatchEvent(event); 195 196 info("Mouse up to stop resizing"); 197 synthesizeMouseAtCenter(document.body, { button: 0, type: "mouseup" }, window); 198 199 await SimpleTest.promiseWaitForCondition( 200 () => !document.firstElementChild.classList.contains("dragging"), 201 "dragging class is never removed from the root element" 202 ); 203 ok(true, "The dragging class is removed from the root element"); 204 } 205 }; 206 </script> 207 </pre> 208 </body> 209 </html>