Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE HTML>
<html>
<!-- Basic tests for the GridElementWidthResizer component. -->
<head>
<meta charset="utf-8">
<title>Tree component test</title>
<link href="chrome://mochikit/content/tests/SimpleTest/test.css" rel="stylesheet" type="text/css"/>
<link href="chrome://devtools/skin/splitters.css" rel="stylesheet" type="text/css"/>
<link href="chrome://devtools/content/shared/components/splitter/GridElementResizer.css" rel="stylesheet" type="text/css"/>
<style>
* {
box-sizing: border-box;
}
html {
--theme-splitter-color: red;
}
main {
display: grid;
grid-template-columns: auto 1fr auto;
grid-template-rows: 20px 20px 20px;
grid-gap: 10px;
direction: rtl;
}
.a,
.b,
.c,
.d {
border: 1px solid green;
}
header {
grid-column: 1 / -1;
}
.a {
grid-column: 1 / 2;
grid-row: 2 / -1;
min-width: 100px;
}
.b {
grid-column: 2 / 3;
grid-row: 2 / -1;
}
.c {
grid-column: 3 / 4;
grid-row: 2 / 3;
}
.d {
grid-column: 3 / 4;
grid-row: 3 / 4;
min-width: 150px;
}
.resizer-a {
grid-column: 1 / 2;
grid-row: 2 / -1;
}
.resizer-d {
grid-column: 3 / 4;
grid-row: 2 / -1;
}
</style>
</head>
<body>
<main></main>
<pre id="test">
<script src="head.js" type="application/javascript"></script>
<script type="application/javascript">
'use strict'
const FUDGE_FACTOR = .5;
function aboutEq(a, b) {
dumpn(`Checking ${a} ~= ${b}`);
return Math.abs(a - b) < FUDGE_FACTOR;
}
window.onload = async function () {
try {
const React = browserRequire("devtools/client/shared/vendor/react");
const ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const GridElementWidthResizer = React.createFactory(browserRequire("devtools/client/shared/components/splitter/GridElementWidthResizer"));
ok(GridElementWidthResizer, "Should get GridElementWidthResizer");
const resizedA = [];
const resizedD = [];
ReactDOM.render([
dom.header({}, "header"),
dom.aside({className: "a"}, "A"),
GridElementWidthResizer({
getControlledElementNode: () => a,
enabled: true,
position: "end",
className: "resizer-a",
onResizeEnd: width => resizedA.push(width),
}),
dom.section({className: "b"}, "B"),
GridElementWidthResizer({
getControlledElementNode: () => window.document.querySelector(".b"),
enabled: false,
position: "start",
className: "resizer-disabled",
}),
dom.aside({className: "c"}, "C"),
dom.aside({className: "d"}, "D"),
GridElementWidthResizer({
getControlledElementNode: () => d,
enabled: true,
position: "start",
className: "resizer-d",
onResizeEnd: width => resizedD.push(width),
}),
], window.document.querySelector("main"));
// wait for a bit as we may not have everything setup yet.
await new Promise(res => setTimeout(res, 10));
const a = window.document.querySelector(".a");
const d = window.document.querySelector(".d");
// Test that we properly rendered our two resizers, and not the disabled one.
const resizers = window.document.querySelectorAll(".grid-element-width-resizer");
is(resizers.length, 2, "The 2 enabled resizers are rendered");
const [resizerA, resizerD] = resizers;
ok(resizerA.classList.contains("resizer-a")
&& resizerA.classList.contains("end"), "resizerA has expected classes");
ok(resizerD.classList.contains("resizer-d")
&& resizerD.classList.contains("start"), "resizerD has expected classes");
const aBoundingRect = a.getBoundingClientRect();
const aOriginalWidth = aBoundingRect.width;
info("Resize element A");
await resize(resizerA, aBoundingRect.left - 20);
is(resizedA.length, 1, "onResizeEnd was called once");
is(resizedD.length, 0, "resizerD was not impacted");
let aWidth = a.getBoundingClientRect().width;
is(resizedA[0], aWidth, "onResizeEnd gives the width of the controlled element");
ok(aboutEq(aWidth, aOriginalWidth + 20),
"controlled element was resized to the expected size");
info("Resize element A below its min width");
await resize(resizerA, [aBoundingRect.right - 10]);
aWidth = a.getBoundingClientRect().width;
ok(aboutEq(aWidth, 100), "controlled element was resized to its min width");
info("Resize element D below its min width");
const dBoundingRect = d.getBoundingClientRect();
const dOriginalWidth = dBoundingRect.width;
await resize(resizerD, dBoundingRect.right - 100);
is(resizedD.length, 1, "onResizeEnd was called once for d");
is(resizedA.length, 2, "onResizeEnd wasn't called for a");
let dWidth = d.getBoundingClientRect().width;
is(resizedD[0], dWidth, "onResizeEnd gives the width of the controlled element");
ok(aboutEq(dWidth, 150), "controlled element wasn't resized below its min-width");
info("Resize element D");
await resize(resizerD, dBoundingRect.right + 15);
dWidth = d.getBoundingClientRect().width;
is(resizedD[1], dWidth, "onResizeEnd gives the width of the controlled element");
ok(aboutEq(dWidth, dOriginalWidth + 15), "element was resized");
} catch(e) {
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
} finally {
SimpleTest.finish();
}
async function resize(resizer, clientX) {
info("Mouse down to start dragging");
synthesizeMouseAtCenter(resizer, { button: 0, type: "mousedown" }, window);
await SimpleTest.promiseWaitForCondition(
() => document.firstElementChild.classList.contains("dragging"),
"dragging class is never set on the root element"
);
ok(true, "The dragging class is set on the root element");
const event = new MouseEvent("mousemove", { clientX });
resizer.dispatchEvent(event);
info("Mouse up to stop resizing");
synthesizeMouseAtCenter(document.body, { button: 0, type: "mouseup" }, window);
await SimpleTest.promiseWaitForCondition(
() => !document.firstElementChild.classList.contains("dragging"),
"dragging class is never removed from the root element"
);
ok(true, "The dragging class is removed from the root element");
}
};
</script>
</pre>
</body>
</html>