browser_html_tooltip_rtl.js (6895B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 /* import-globals-from helper_html_tooltip.js */ 4 "use strict"; 5 6 /** 7 * Test the HTMLTooltip anchor alignment changes with the anchor direction. 8 * - should be aligned to the right of RTL anchors 9 * - should be aligned to the left of LTR anchors 10 */ 11 12 const HTML_NS = "http://www.w3.org/1999/xhtml"; 13 const TEST_URI = CHROME_URL_ROOT + "doc_html_tooltip_rtl.xhtml"; 14 15 const { 16 HTMLTooltip, 17 } = require("resource://devtools/client/shared/widgets/tooltip/HTMLTooltip.js"); 18 loadHelperScript("helper_html_tooltip.js"); 19 20 const TOOLBOX_WIDTH = 500; 21 const TOOLTIP_WIDTH = 150; 22 const TOOLTIP_HEIGHT = 30; 23 24 add_task(async function () { 25 await pushPref("devtools.toolbox.sidebar.width", TOOLBOX_WIDTH); 26 27 const { doc } = await createHost("right", TEST_URI); 28 29 info("Test the positioning of tooltips in RTL and LTR directions"); 30 31 const tooltip = new HTMLTooltip(doc, { useXulWrapper: false }); 32 const div = doc.createElementNS(HTML_NS, "div"); 33 div.textContent = "tooltip"; 34 div.style.cssText = "box-sizing: border-box; border: 1px solid black"; 35 tooltip.panel.appendChild(div); 36 tooltip.setContentSize({ width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT }); 37 38 await testRtlAnchors(doc, tooltip); 39 await testLtrAnchors(doc, tooltip); 40 await hideTooltip(tooltip); 41 42 tooltip.destroy(); 43 44 await testRtlArrow(doc); 45 }); 46 47 async function testRtlAnchors(doc, tooltip) { 48 /* 49 * The layout of the test page is as follows: 50 * _______________________________ 51 * | toolbox | 52 * | _____ _____ _____ _____ | 53 * || | | | | | | || 54 * || box1| | box2| | box3| | box4|| 55 * ||_____| |_____| |_____| |_____|| 56 * |_______________________________| 57 * 58 * - box1 is aligned with the left edge of the toolbox 59 * - box2 is displayed right after box1 60 * - total toolbox width is 500px so each box is 125px wide 61 */ 62 63 const box1 = doc.getElementById("box1"); 64 const box2 = doc.getElementById("box2"); 65 66 info("Display the tooltip on box1."); 67 await showTooltip(tooltip, box1, { position: "bottom" }); 68 69 let panelRect = tooltip.container.getBoundingClientRect(); 70 let anchorRect = box1.getBoundingClientRect(); 71 72 // box1 uses RTL direction, so the tooltip should be aligned with the right edge of the 73 // anchor, but it is shifted to the right to fit in the toolbox. 74 is(panelRect.left, 0, "Tooltip is aligned with left edge of the toolbox"); 75 is( 76 panelRect.top, 77 anchorRect.bottom, 78 "Tooltip aligned with the anchor bottom edge" 79 ); 80 is( 81 panelRect.height, 82 TOOLTIP_HEIGHT, 83 "Tooltip height is at 100px as expected" 84 ); 85 86 info("Display the tooltip on box2."); 87 await showTooltip(tooltip, box2, { position: "bottom" }); 88 89 panelRect = tooltip.container.getBoundingClientRect(); 90 anchorRect = box2.getBoundingClientRect(); 91 92 // box2 uses RTL direction, so the tooltip is aligned with the right edge of the anchor 93 is( 94 Math.round(panelRect.right), 95 Math.round(anchorRect.right), 96 "Tooltip is aligned with right edge of anchor" 97 ); 98 is( 99 panelRect.top, 100 anchorRect.bottom, 101 "Tooltip aligned with the anchor bottom edge" 102 ); 103 is( 104 panelRect.height, 105 TOOLTIP_HEIGHT, 106 "Tooltip height is at 100px as expected" 107 ); 108 } 109 110 async function testLtrAnchors(doc, tooltip) { 111 /* 112 * The layout of the test page is as follows: 113 * _______________________________ 114 * | toolbox | 115 * | _____ _____ _____ _____ | 116 * || | | | | | | || 117 * || box1| | box2| | box3| | box4|| 118 * ||_____| |_____| |_____| |_____|| 119 * |_______________________________| 120 * 121 * - box3 is is displayed right after box2 122 * - box4 is aligned with the right edge of the toolbox 123 * - total toolbox width is 500px so each box is 125px wide 124 */ 125 126 const box3 = doc.getElementById("box3"); 127 const box4 = doc.getElementById("box4"); 128 129 info("Display the tooltip on box3."); 130 await showTooltip(tooltip, box3, { position: "bottom" }); 131 132 let panelRect = tooltip.container.getBoundingClientRect(); 133 let anchorRect = box3.getBoundingClientRect(); 134 135 // box3 uses LTR direction, so the tooltip is aligned with the left edge of the anchor. 136 is( 137 Math.round(panelRect.left), 138 Math.round(anchorRect.left), 139 "Tooltip is aligned with left edge of anchor" 140 ); 141 is( 142 panelRect.top, 143 anchorRect.bottom, 144 "Tooltip aligned with the anchor bottom edge" 145 ); 146 is( 147 panelRect.height, 148 TOOLTIP_HEIGHT, 149 "Tooltip height is at 100px as expected" 150 ); 151 152 info("Display the tooltip on box4."); 153 await showTooltip(tooltip, box4, { position: "bottom" }); 154 155 panelRect = tooltip.container.getBoundingClientRect(); 156 anchorRect = box4.getBoundingClientRect(); 157 158 // box4 uses LTR direction, so the tooltip should be aligned with the left edge of the 159 // anchor, but it is shifted to the left to fit in the toolbox. 160 is( 161 panelRect.right, 162 TOOLBOX_WIDTH, 163 "Tooltip is aligned with right edge of toolbox" 164 ); 165 is( 166 panelRect.top, 167 anchorRect.bottom, 168 "Tooltip aligned with the anchor bottom edge" 169 ); 170 is( 171 panelRect.height, 172 TOOLTIP_HEIGHT, 173 "Tooltip height is at 100px as expected" 174 ); 175 } 176 177 async function testRtlArrow(doc) { 178 // Set up the arrow-style tooltip 179 const arrowTooltip = new HTMLTooltip(doc, { 180 type: "arrow", 181 useXulWrapper: false, 182 }); 183 const div = doc.createElementNS(HTML_NS, "div"); 184 div.textContent = "tooltip"; 185 div.style.cssText = "box-sizing: border-box; border: 1px solid black"; 186 arrowTooltip.panel.appendChild(div); 187 arrowTooltip.setContentSize({ 188 width: TOOLTIP_WIDTH, 189 height: TOOLTIP_HEIGHT, 190 }); 191 192 // box2 uses RTL direction and is far enough from the edge that the arrow 193 // should not be squashed in the wrong direction. 194 const box2 = doc.getElementById("box2"); 195 196 info("Display the arrow tooltip on box2."); 197 await showTooltip(arrowTooltip, box2, { position: "top" }); 198 199 const arrow = arrowTooltip.arrow; 200 ok(arrow, "Tooltip has an arrow"); 201 202 const panelRect = arrowTooltip.container.getBoundingClientRect(); 203 const arrowRect = arrow.getBoundingClientRect(); 204 205 // The arrow should be offset from the right edge, but still closer to the 206 // right edge than the left edge. 207 Assert.less( 208 arrowRect.right, 209 panelRect.right, 210 "Right edge of the arrow " + 211 `(${arrowRect.right}) is less than the right edge of the panel ` + 212 `(${panelRect.right})` 213 ); 214 const rightMargin = panelRect.right - arrowRect.right; 215 const leftMargin = arrowRect.left - panelRect.right; 216 Assert.greater( 217 rightMargin, 218 leftMargin, 219 "Arrow should be closer to the right side of " + 220 ` the panel (margin: ${rightMargin}) than the left side ` + 221 ` (margin: ${leftMargin})` 222 ); 223 224 await hideTooltip(arrowTooltip); 225 arrowTooltip.destroy(); 226 }