layout/base/tests/test_getBoxQuads_convertPointRectQuad.html

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 <!DOCTYPE HTML>
michael@0 2 <html>
michael@0 3 <head>
michael@0 4 <meta charset="utf-8">
michael@0 5 <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
michael@0 6 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
michael@0 7 </head>
michael@0 8 <body onload="startTest()">
michael@0 9 <p id="display"></p>
michael@0 10 <script>
michael@0 11 // Global variables we want eval() to be able to reference from anywhere
michael@0 12 var f1d;
michael@0 13 var text;
michael@0 14 var suppressedText;
michael@0 15 var suppressedText2;
michael@0 16 var comment;
michael@0 17 var fragment;
michael@0 18 var openedWindow;
michael@0 19 var zeroPoint = new DOMPoint(0,0);
michael@0 20 var zeroRect = new DOMRect(0,0,0,0);
michael@0 21 var zeroQuad = new DOMQuad(zeroRect);
michael@0 22 var notInDocument = document.createElement('div');
michael@0 23
michael@0 24 function isEval(expr, b) {
michael@0 25 is(eval(expr), b, expr);
michael@0 26 }
michael@0 27
michael@0 28 function isApprox(a, b, msg, options) {
michael@0 29 if (a != b && 'tolerance' in options &&
michael@0 30 Math.abs(a - b) < options.tolerance) {
michael@0 31 ok(true, msg + "(" + a + " within " + options.tolerance + " of " + b + ")");
michael@0 32 return;
michael@0 33 }
michael@0 34 is(a, b, msg);
michael@0 35 }
michael@0 36
michael@0 37 function makeQuadsExpr(fromStr, options) {
michael@0 38 var getBoxQuadsOptionParts = [];
michael@0 39 if ('box' in options) {
michael@0 40 getBoxQuadsOptionParts.push("box:'" + options.box + "'");
michael@0 41 }
michael@0 42 if ('toStr' in options) {
michael@0 43 getBoxQuadsOptionParts.push("relativeTo:" + options.toStr);
michael@0 44 }
michael@0 45 return fromStr + ".getBoxQuads({" + getBoxQuadsOptionParts.join(',') + "})";
michael@0 46 }
michael@0 47
michael@0 48 function makePointExpr(fromStr, options, x, y) {
michael@0 49 var convertPointOptionParts = [];
michael@0 50 if ('box' in options) {
michael@0 51 convertPointOptionParts.push("fromBox:'" + options.box + "'");
michael@0 52 }
michael@0 53 if ('toBox' in options) {
michael@0 54 convertPointOptionParts.push("toBox:'" + options.toBox + "'");
michael@0 55 }
michael@0 56 return ('toStr' in options ? options.toStr : "document") +
michael@0 57 ".convertPointFromNode(new DOMPoint(" + x + "," + y + ")," + fromStr + ",{" +
michael@0 58 convertPointOptionParts.join(",") + "})";
michael@0 59 }
michael@0 60
michael@0 61 function checkConvertPoints(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4) {
michael@0 62 var selfQuads = eval(fromStr).getBoxQuads(
michael@0 63 {box:options.box == "" ? "border" : options.box,
michael@0 64 relativeTo:eval(fromStr)});
michael@0 65 var boxWidth = selfQuads[0].bounds.width;
michael@0 66 var boxHeight = selfQuads[0].bounds.height;
michael@0 67
michael@0 68 var convertTopLeftPointExpr = makePointExpr(fromStr, options, 0, 0);
michael@0 69 var topLeft = eval(convertTopLeftPointExpr);
michael@0 70 isApprox(topLeft.x, x1, convertTopLeftPointExpr + ".x", options);
michael@0 71 isApprox(topLeft.y, y1, convertTopLeftPointExpr + ".y", options);
michael@0 72
michael@0 73 var convertTopRightPointExpr = makePointExpr(fromStr, options, boxWidth, 0);
michael@0 74 var topRight = eval(convertTopRightPointExpr);
michael@0 75 isApprox(topRight.x, x2, convertTopRightPointExpr + ".x", options);
michael@0 76 isApprox(topRight.y, y2, convertTopRightPointExpr + ".y", options);
michael@0 77
michael@0 78 var convertBottomRightPointExpr = makePointExpr(fromStr, options, boxWidth, boxHeight);
michael@0 79 var bottomRight = eval(convertBottomRightPointExpr);
michael@0 80 isApprox(bottomRight.x, x3, convertBottomRightPointExpr + ".x", options);
michael@0 81 isApprox(bottomRight.y, y3, convertBottomRightPointExpr + ".y", options);
michael@0 82
michael@0 83 var convertBottomLeftPointExpr = makePointExpr(fromStr, options, 0, boxHeight);
michael@0 84 var bottomLeft = eval(convertBottomLeftPointExpr);
michael@0 85 isApprox(bottomLeft.x, x4, convertBottomLeftPointExpr + ".x", options);
michael@0 86 isApprox(bottomLeft.y, y4, convertBottomLeftPointExpr + ".y", options);
michael@0 87 }
michael@0 88
michael@0 89 function checkConvertRect(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4) {
michael@0 90 var selfQuads = eval(fromStr).getBoxQuads(
michael@0 91 {box:options.box == "" ? "border" : options.box,
michael@0 92 relativeTo:eval(fromStr)});
michael@0 93 var boxWidth = selfQuads[0].bounds.width;
michael@0 94 var boxHeight = selfQuads[0].bounds.height;
michael@0 95
michael@0 96 var convertPointOptionParts = [];
michael@0 97 if ('box' in options) {
michael@0 98 convertPointOptionParts.push("fromBox:'" + options.box + "'");
michael@0 99 }
michael@0 100 if ('toBox' in options) {
michael@0 101 convertPointOptionParts.push("toBox:'" + options.toBox + "'");
michael@0 102 }
michael@0 103
michael@0 104 var convertRectExpr = ('toStr' in options ? options.toStr : "document") +
michael@0 105 ".convertRectFromNode(new DOMRect(0,0," + boxWidth + "," + boxHeight + ")," +
michael@0 106 fromStr + ",{" + convertPointOptionParts.join(",") + "})";
michael@0 107 var quad = eval(convertRectExpr);
michael@0 108 isApprox(quad.p1.x, x1, convertRectExpr + ".p1.x", options);
michael@0 109 isApprox(quad.p1.y, y1, convertRectExpr + ".p1.y", options);
michael@0 110 isApprox(quad.p2.x, x2, convertRectExpr + ".p2.x", options);
michael@0 111 isApprox(quad.p2.y, y2, convertRectExpr + ".p2.y", options);
michael@0 112 isApprox(quad.p3.x, x3, convertRectExpr + ".p3.x", options);
michael@0 113 isApprox(quad.p3.y, y3, convertRectExpr + ".p3.y", options);
michael@0 114 isApprox(quad.p4.x, x4, convertRectExpr + ".p4.x", options);
michael@0 115 isApprox(quad.p4.y, y4, convertRectExpr + ".p4.y", options);
michael@0 116 }
michael@0 117
michael@0 118 function checkConvertQuad(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4) {
michael@0 119 var selfQuads = eval(fromStr).getBoxQuads(
michael@0 120 {box:options.box == "" ? "border" : options.box,
michael@0 121 relativeTo:eval(fromStr)});
michael@0 122 var boxWidth = selfQuads[0].bounds.width;
michael@0 123 var boxHeight = selfQuads[0].bounds.height;
michael@0 124
michael@0 125 var convertPointOptionParts = [];
michael@0 126 if ('box' in options) {
michael@0 127 convertPointOptionParts.push("fromBox:'" + options.box + "'");
michael@0 128 }
michael@0 129 if ('toBox' in options) {
michael@0 130 convertPointOptionParts.push("toBox:'" + options.toBox + "'");
michael@0 131 }
michael@0 132
michael@0 133 var convertQuadExpr = ('toStr' in options ? options.toStr : "document") +
michael@0 134 ".convertQuadFromNode(new DOMQuad(new DOMRect(0,0," + boxWidth + "," + boxHeight + "))," +
michael@0 135 fromStr + ",{" + convertPointOptionParts.join(",") + "})";
michael@0 136 var quad = eval(convertQuadExpr);
michael@0 137 isApprox(quad.p1.x, x1, convertQuadExpr + ".p1.x", options);
michael@0 138 isApprox(quad.p1.y, y1, convertQuadExpr + ".p1.y", options);
michael@0 139 isApprox(quad.p2.x, x2, convertQuadExpr + ".p2.x", options);
michael@0 140 isApprox(quad.p2.y, y2, convertQuadExpr + ".p2.y", options);
michael@0 141 isApprox(quad.p3.x, x3, convertQuadExpr + ".p3.x", options);
michael@0 142 isApprox(quad.p3.y, y3, convertQuadExpr + ".p3.y", options);
michael@0 143 isApprox(quad.p4.x, x4, convertQuadExpr + ".p4.x", options);
michael@0 144 isApprox(quad.p4.y, y4, convertQuadExpr + ".p4.y", options);
michael@0 145 }
michael@0 146
michael@0 147 function checkQuadIsRect(fromStr, options, x, y, w, h) {
michael@0 148 var quadsExpr = makeQuadsExpr(fromStr, options);
michael@0 149 var quads = eval(quadsExpr);
michael@0 150 is(quads.length, 1, quadsExpr + " checking quad count");
michael@0 151 var q = quads[0];
michael@0 152 isApprox(q.p1.x, x, quadsExpr + " checking quad.p1.x", options);
michael@0 153 isApprox(q.p1.y, y, quadsExpr + " checking quad.p1.y", options);
michael@0 154 isApprox(q.p2.x, x + w, quadsExpr + " checking quad.p2.x", options);
michael@0 155 isApprox(q.p2.y, y, quadsExpr + " checking quad.p2.y", options);
michael@0 156 isApprox(q.p3.x, x + w, quadsExpr + " checking quad.p3.x", options);
michael@0 157 isApprox(q.p3.y, y + h, quadsExpr + " checking quad.p3.y", options);
michael@0 158 isApprox(q.p4.x, x, quadsExpr + " checking quad.p4.x", options);
michael@0 159 isApprox(q.p4.y, y + h, quadsExpr + " checking quad.p4.y", options);
michael@0 160
michael@0 161 isApprox(q.bounds.left, x, quadsExpr + " checking quad.bounds.left", options);
michael@0 162 isApprox(q.bounds.top, y, quadsExpr + " checking quad.bounds.top", options);
michael@0 163 isApprox(q.bounds.width, w, quadsExpr + " checking quad.bounds.width", options);
michael@0 164 isApprox(q.bounds.height, h, quadsExpr + " checking quad.bounds.height", options);
michael@0 165
michael@0 166 checkConvertPoints(fromStr, options, x, y, x + w, y, x + w, y + h, x, y + h);
michael@0 167 checkConvertRect(fromStr, options, x, y, x + w, y, x + w, y + h, x, y + h);
michael@0 168 checkConvertQuad(fromStr, options, x, y, x + w, y, x + w, y + h, x, y + h);
michael@0 169 }
michael@0 170
michael@0 171 function checkQuadIsQuad(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4) {
michael@0 172 var quadsExpr = makeQuadsExpr(fromStr, options);
michael@0 173 var quads = eval(quadsExpr);
michael@0 174 is(quads.length, 1, quadsExpr + " checking quad count");
michael@0 175 var q = quads[0];
michael@0 176 isApprox(q.p1.x, x1, quadsExpr + " checking quad.p1.x", options);
michael@0 177 isApprox(q.p1.y, y1, quadsExpr + " checking quad.p1.y", options);
michael@0 178 isApprox(q.p2.x, x2, quadsExpr + " checking quad.p2.x", options);
michael@0 179 isApprox(q.p2.y, y2, quadsExpr + " checking quad.p2.y", options);
michael@0 180 isApprox(q.p3.x, x3, quadsExpr + " checking quad.p3.x", options);
michael@0 181 isApprox(q.p3.y, y3, quadsExpr + " checking quad.p3.y", options);
michael@0 182 isApprox(q.p4.x, x4, quadsExpr + " checking quad.p4.x", options);
michael@0 183 isApprox(q.p4.y, y4, quadsExpr + " checking quad.p4.y", options);
michael@0 184
michael@0 185 isApprox(q.bounds.left, Math.min(x1,x2,x3,x4), quadsExpr + " checking quad.bounds.left", options);
michael@0 186 isApprox(q.bounds.top, Math.min(y1,y2,y3,y4), quadsExpr + " checking quad.bounds.top", options);
michael@0 187 isApprox(q.bounds.right, Math.max(x1,x2,x3,x4), quadsExpr + " checking quad.bounds.right", options);
michael@0 188 isApprox(q.bounds.bottom, Math.max(y1,y2,y3,y4), quadsExpr + " checking quad.bounds.bottom", options);
michael@0 189
michael@0 190 checkConvertPoints(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4);
michael@0 191 checkConvertRect(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4);
michael@0 192 checkConvertQuad(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4);
michael@0 193 }
michael@0 194
michael@0 195 function checkException(expr, name) {
michael@0 196 try {
michael@0 197 eval(expr);
michael@0 198 ok(false, "Exception should have been thrown for " + expr);
michael@0 199 } catch (ex) {
michael@0 200 is(ex.name, name, "Checking exception type for " + expr);
michael@0 201 }
michael@0 202 }
michael@0 203
michael@0 204 function checkNotFound(fromStr, toStr, x1, y1, x2, y2) {
michael@0 205 var convertPointExpr = toStr + ".convertPointFromNode(new DOMPoint(" + x1 +
michael@0 206 "," + y1 + ")," + fromStr + ")";
michael@0 207 checkException(convertPointExpr, "NotFoundError");
michael@0 208
michael@0 209 var convertRectExpr = toStr + ".convertRectFromNode(new DOMRect(" + x1 +
michael@0 210 "," + y1 + "," + x2 + "," + y2 + ")," + fromStr + ")";
michael@0 211 checkException(convertRectExpr, "NotFoundError");
michael@0 212
michael@0 213 var convertQuadExpr = toStr + ".convertQuadFromNode(new DOMQuad(new DOMRect(" + x1 +
michael@0 214 "," + y1 + "," + x2 + "," + y2 + "))," + fromStr + ")";
michael@0 215 checkException(convertQuadExpr, "NotFoundError");
michael@0 216 }
michael@0 217 </script>
michael@0 218 <style>
michael@0 219 em {
michael@0 220 display:inline-block; height:10px; background:gray;
michael@0 221 }
michael@0 222 </style>
michael@0 223 <div id="dContainer"
michael@0 224 style="padding:13px 14px 15px 16px;
michael@0 225 border-width:17px 18px 19px 20px; border-style:solid; border-color:yellow;
michael@0 226 margin:21px 22px 23px 24px;">
michael@0 227 <div id="d"
michael@0 228 style="width:120px; height:90px; padding:1px 2px 3px 4px;
michael@0 229 border-width:5px 6px 7px 8px; border-style:solid; border-color:yellow;
michael@0 230 margin:9px 10px 11px 12px; background:blue;">
michael@0 231 </div>
michael@0 232 </div>
michael@0 233
michael@0 234 <div id="dUnrelated" style="width:50px; height:50px;"></div>
michael@0 235
michael@0 236 <iframe id="f1" style="width:50px; height:50px; border:0; background:lime;"
michael@0 237 src="data:text/html,<!DOCTYPE HTML><html style='padding:25px'><div id='f1d' style='position:absolute; left:14px; top:15px; width:16px; height:17px; background:pink'></div>">
michael@0 238 </iframe>
michael@0 239 <!--
michael@0 240 It matters that the first part of this span is on the same line as the above <iframe>!
michael@0 241 That ensures the first quad's X position is not equal to the anonymous block's X position.
michael@0 242 -->
michael@0 243 <span id="ibSplit"
michael@0 244 ><em id="ibSplitPart1" style="width:100px;"></em
michael@0 245 ><div style="width:110px; height:20px; background:black"></div
michael@0 246 ><em style="width:130px;"></em></span>
michael@0 247
michael@0 248 <table cellspacing="0" id="table" style="border:0; margin:0; padding:0; background:orange">
michael@0 249 <tbody style="padding:0; margin:0; border:0; background:blue">
michael@0 250 <tr style="height:50px; padding:0; margin:0; border:0">
michael@0 251 <td style="border:0; margin:0; padding:0">Cell</td>
michael@0 252 </tr>
michael@0 253 </tbody>
michael@0 254 <caption style="height:40px; background:yellow">Caption</caption>
michael@0 255 </table>
michael@0 256
michael@0 257 <div style="height:80px; -moz-column-count:2; -moz-column-fill:auto; border:2px solid black;">
michael@0 258 <div style="height:20px;"></div>
michael@0 259 <div id="colSplit" style="height:80px; background:blue; border:10px solid red; border-bottom-width:15px"></div>
michael@0 260 </div>
michael@0 261
michael@0 262 <div style="width:200px; border:2px solid black;"
michael@0 263 ><em style="width:150px;"></em
michael@0 264 ><span id="inlineSplit" style="background:pink; border:10px solid red; border-right-width:15px"
michael@0 265 ><em style="width:20px; background:green"></em><em style="width:60px"></em
michael@0 266 ></span
michael@0 267 ></div>
michael@0 268
michael@0 269 <div style="width:200px; border:2px solid black;"
michael@0 270 ><em style="width:150px;"></em
michael@0 271 ><span id="textContainer">T
michael@0 272 TextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextText</span
michael@0 273 ></div>
michael@0 274
michael@0 275 <div id="suppressedTextContainer"> </div>
michael@0 276 <div id="suppressedTextContainer2"> </div>
michael@0 277
michael@0 278 <div id="commentContainer"><!-- COMMENT --></div>
michael@0 279
michael@0 280 <div id="displayNone" style="display:none"></div>
michael@0 281
michael@0 282 <div id="overflowHidden"
michael@0 283 style="overflow:hidden; width:120px; height:90px; padding:1px 2px 3px 4px;
michael@0 284 border-width:5px 6px 7px 8px; border-style:solid; border-color:yellow;
michael@0 285 margin:9px 10px 11px 12px; background:blue;">
michael@0 286 <div style="height:400px; background:lime;"></div>
michael@0 287 </div>
michael@0 288
michael@0 289 <div id="overflowScroll"
michael@0 290 style="overflow:scroll; width:120px; height:90px; padding:1px 2px 3px 4px;
michael@0 291 border-width:5px 6px 7px 8px; border-style:solid; border-color:yellow;
michael@0 292 margin:9px 10px 11px 12px; background:blue; background-clip:content-box;">
michael@0 293 <div id="overflowScrollChild" style="height:400px;"></div>
michael@0 294 </div>
michael@0 295
michael@0 296 <div id="scaleTransformContainer" style="width:200px; height:200px;">
michael@0 297 <div id="scaleTransform"
michael@0 298 style="transform:scale(2); transform-origin:top left; width:70px; height:80px; background:yellow"></div>
michael@0 299 </div>
michael@0 300
michael@0 301 <div id="translateTransformContainer" style="width:200px; height:200px;">
michael@0 302 <div id="translateTransform"
michael@0 303 style="transform:translate(30px,40px); width:70px; height:80px; background:yellow"></div>
michael@0 304 </div>
michael@0 305
michael@0 306 <div id="rotateTransformContainer" style="width:200px; height:200px;">
michael@0 307 <div id="rotateTransform"
michael@0 308 style="transform:rotate(90deg); width:70px; height:80px; background:yellow"></div>
michael@0 309 </div>
michael@0 310
michael@0 311 <div id="flipTransformContainer" style="width:200px; height:200px;">
michael@0 312 <div id="flipTransform"
michael@0 313 style="transform:scaleY(-1); width:70px; height:80px; background:yellow"></div>
michael@0 314 </div>
michael@0 315
michael@0 316 <div id="rot45TransformContainer" style="width:200px; height:200px;">
michael@0 317 <div id="rot45Transform"
michael@0 318 style="transform:rotate(45deg); width:100px; height:100px; background:yellow"></div>
michael@0 319 </div>
michael@0 320
michael@0 321 <div id="singularTransform" style="transform:scale(0); width:200px; height:200px;">
michael@0 322 <div id="singularTransformChild1" style="height:50px;"></div>
michael@0 323 <div id="singularTransformChild2" style="height:50px;"></div>
michael@0 324 </div>
michael@0 325
michael@0 326 <div id="threeDTransformContainer" style="perspective:600px; width:200px; height:200px">
michael@0 327 <div id="threeDTransform" style="transform:rotateY(70deg); background:yellow; height:100px; perspective:600px">
michael@0 328 <div id="threeDTransformChild" style="transform:rotateY(-70deg); background:blue; height:50px;"></div>
michael@0 329 </div>
michael@0 330 </div>
michael@0 331
michael@0 332 <div id="preserve3DTransformContainer" style="perspective:600px; width:200px; height:200px">
michael@0 333 <div id="preserve3DTransform" style="transform:rotateY(70deg); transform-style:preserve-3d; background:yellow; height:100px;">
michael@0 334 <div id="preserve3DTransformChild" style="transform:rotateY(-70deg); background:blue; height:50px;"></div>
michael@0 335 </div>
michael@0 336 </div>
michael@0 337
michael@0 338 <div id="svgContainer">
michael@0 339 <svg id="svg" style="width:200px; height:200px; background:lightgray;">
michael@0 340 <circle id="circle" cx="50" cy="50" r="20" fill="red" style="margin:20px; padding:10px; border:15px solid black"></circle>
michael@0 341 <g transform="scale(2)">
michael@0 342 <foreignObject x="50" y="20">
michael@0 343 <div id="foreign" style="width:100px; height:60px; background:purple"></div>
michael@0 344 </foreignObject>
michael@0 345 </g>
michael@0 346 </svg>
michael@0 347 </div>
michael@0 348
michael@0 349 <script>
michael@0 350 SimpleTest.waitForExplicitFinish();
michael@0 351
michael@0 352 window.scrollTo(0,0);
michael@0 353
michael@0 354 function startTest() {
michael@0 355 SpecialPowers.pushPrefEnv({"set": [["layout.css.DOMPoint.enabled", true],
michael@0 356 ["layout.css.DOMQuad.enabled", true],
michael@0 357 ["layout.css.getBoxQuads.enabled", true],
michael@0 358 ["layout.css.convertFromNode.enabled", true]]}, runTest);
michael@0 359 }
michael@0 360
michael@0 361 function runTest() {
michael@0 362 // Setup globals
michael@0 363 f1d = f1.contentWindow.f1d;
michael@0 364 text = textContainer.firstChild;
michael@0 365 suppressedText = suppressedTextContainer.firstChild;
michael@0 366 suppressedText2 = suppressedTextContainer2.firstChild;
michael@0 367 comment = commentContainer.firstChild;
michael@0 368 fragment = document.createDocumentFragment();
michael@0 369
michael@0 370 // Test basic BoxQuadOptions.box.
michael@0 371 var dX = d.getBoundingClientRect().left;
michael@0 372 var dY = d.getBoundingClientRect().top;
michael@0 373 var dW = d.getBoundingClientRect().width;
michael@0 374 var dH = d.getBoundingClientRect().height;
michael@0 375
michael@0 376 checkQuadIsRect("d", {box:"content"},
michael@0 377 dX + 4 + 8, dY + 1 + 5, 120, 90);
michael@0 378 checkQuadIsRect("d", {box:"padding"},
michael@0 379 dX + 8, dY + 5, 120 + 2 + 4, 90 + 1 + 3);
michael@0 380 checkQuadIsRect("d", {box:"border"},
michael@0 381 dX, dY, dW, dH);
michael@0 382 checkQuadIsRect("d", {},
michael@0 383 dX, dY, 120 + 2 + 4 + 6 + 8, 90 + 1 + 3 + 5 + 7);
michael@0 384 checkQuadIsRect("d", {box:"margin"},
michael@0 385 dX - 12, dY - 9, 120 + 2 + 4 + 6 + 8 + 10 + 12, 90 + 1 + 3 + 5 + 7 + 9 + 11);
michael@0 386
michael@0 387 // Test basic BoxQuadOptions.relativeTo
michael@0 388 checkQuadIsRect("d", {toStr:"dContainer"},
michael@0 389 12 + 16 + 20, 9 + 13 + 17, dW, dH);
michael@0 390
michael@0 391 // Test BoxQuadOptions.relativeTo relative to this document
michael@0 392 checkQuadIsRect("d", {toStr:"document"},
michael@0 393 dX, dY, dW, dH);
michael@0 394 // Test BoxQuadOptions.relativeTo relative to a non-ancestor.
michael@0 395 var dUnrelatedX = dUnrelated.getBoundingClientRect().left;
michael@0 396 var dUnrelatedY = dUnrelated.getBoundingClientRect().top;
michael@0 397 checkQuadIsRect("d", {toStr:"dUnrelated"},
michael@0 398 dX - dUnrelatedX, dY - dUnrelatedY, dW, dH);
michael@0 399 // Test BoxQuadOptions.relativeTo relative to an element in a different document (and the document)
michael@0 400 var f1X = f1.getBoundingClientRect().left;
michael@0 401 var f1Y = f1.getBoundingClientRect().top;
michael@0 402 checkQuadIsRect("d", {toStr:"f1.contentWindow.f1d"},
michael@0 403 dX - (f1X + 14), dY - (f1Y + 15), dW, dH);
michael@0 404 checkQuadIsRect("d", {toStr:"f1.contentDocument"},
michael@0 405 dX - f1X, dY - f1Y, dW, dH);
michael@0 406 // Test one document relative to another
michael@0 407 checkQuadIsRect("f1.contentDocument", {toStr:"document"},
michael@0 408 f1X, f1Y, 50, 50);
michael@0 409 // The box type is irrelevant for a document
michael@0 410 checkQuadIsRect("f1.contentDocument", {toStr:"document",box:"content"},
michael@0 411 f1X, f1Y, 50, 50);
michael@0 412 checkQuadIsRect("f1.contentDocument", {toStr:"document",box:"margin"},
michael@0 413 f1X, f1Y, 50, 50);
michael@0 414 checkQuadIsRect("f1.contentDocument", {toStr:"document",box:"padding"},
michael@0 415 f1X, f1Y, 50, 50);
michael@0 416
michael@0 417 // Test that anonymous boxes are correctly ignored when building quads.
michael@0 418 var ibSplitPart1X = ibSplitPart1.getBoundingClientRect().left;
michael@0 419 var ibSplitY = ibSplit.getBoundingClientRect().top;
michael@0 420 isEval("ibSplit.getBoxQuads().length", 3);
michael@0 421 isEval("ibSplit.getBoxQuads()[0].bounds.left", ibSplitPart1X);
michael@0 422 isEval("ibSplit.getBoxQuads()[0].bounds.width", 100);
michael@0 423 isEval("ibSplit.getBoxQuads()[1].bounds.width", 110);
michael@0 424 isEval("ibSplit.getBoxQuads()[2].bounds.width", 130);
michael@0 425 isEval("table.getBoxQuads().length", 2);
michael@0 426 isEval("table.getBoxQuads()[0].bounds.height", 50);
michael@0 427 isEval("table.getBoxQuads()[1].bounds.height", 40);
michael@0 428
michael@0 429 // Test that we skip anonymous boxes when finding the right box to be relative to.
michael@0 430 checkQuadIsRect("d", {toStr:"ibSplit"},
michael@0 431 dX - ibSplitPart1X, dY - ibSplitY, dW, dH);
michael@0 432 var tableX = table.getClientRects()[0].left;
michael@0 433 var tableY = table.getClientRects()[0].top;
michael@0 434 checkQuadIsRect("d", {toStr:"table"},
michael@0 435 dX - tableX, dY - tableY, dW, dH);
michael@0 436 isEval("ibSplit.convertPointFromNode(zeroPoint,d).x", dX - ibSplitPart1X);
michael@0 437 isEval("table.convertPointFromNode(zeroPoint,d).x", dX - table.getClientRects()[0].left);
michael@0 438
michael@0 439 // Test boxes generated by block splitting. Check for borders being placed correctly.
michael@0 440 var colSplitY = colSplit.getClientRects()[0].top;
michael@0 441 isEval("colSplit.getBoxQuads().length", 2);
michael@0 442 isEval("colSplit.getBoxQuads()[0].bounds.top", colSplitY);
michael@0 443 isEval("colSplit.getBoxQuads()[0].bounds.height", 60);
michael@0 444 isEval("colSplit.getBoxQuads()[1].bounds.top", colSplitY - 20);
michael@0 445 isEval("colSplit.getBoxQuads()[1].bounds.height", 45);
michael@0 446 isEval("colSplit.getBoxQuads({box:'content'}).length", 2);
michael@0 447 // The first box for the block has the top border; the second box has the bottom border.
michael@0 448 isEval("colSplit.getBoxQuads({box:'content'})[0].bounds.top", colSplitY + 10);
michael@0 449 isEval("colSplit.getBoxQuads({box:'content'})[0].bounds.height", 50);
michael@0 450 isEval("colSplit.getBoxQuads({box:'content'})[1].bounds.top", colSplitY - 20);
michael@0 451 isEval("colSplit.getBoxQuads({box:'content'})[1].bounds.height", 30);
michael@0 452
michael@0 453 var inlineSplitX = inlineSplit.getClientRects()[0].left;
michael@0 454 isEval("inlineSplit.getBoxQuads().length", 2);
michael@0 455 isEval("inlineSplit.getBoxQuads()[0].bounds.left", inlineSplitX);
michael@0 456 isEval("inlineSplit.getBoxQuads()[0].bounds.width", 30);
michael@0 457 isEval("inlineSplit.getBoxQuads()[1].bounds.left", inlineSplitX - 150);
michael@0 458 isEval("inlineSplit.getBoxQuads()[1].bounds.width", 75);
michael@0 459 isEval("inlineSplit.getBoxQuads({box:'content'}).length", 2);
michael@0 460 // The first box for the inline has the left border; the second box has the right border.
michael@0 461 isEval("inlineSplit.getBoxQuads({box:'content'})[0].bounds.left", inlineSplitX + 10);
michael@0 462 isEval("inlineSplit.getBoxQuads({box:'content'})[0].bounds.width", 20);
michael@0 463 isEval("inlineSplit.getBoxQuads({box:'content'})[1].bounds.left", inlineSplitX - 150);
michael@0 464 isEval("inlineSplit.getBoxQuads({box:'content'})[1].bounds.width", 60);
michael@0 465
michael@0 466 var textX = textContainer.getClientRects()[0].left;
michael@0 467 isEval("text.getBoxQuads().length", 2);
michael@0 468 isEval("text.getBoxQuads()[0].bounds.left", textX);
michael@0 469 isEval("text.getBoxQuads()[1].bounds.left", textX - 150);
michael@0 470 // Box types are irrelevant for text
michael@0 471 isEval("text.getBoxQuads({box:'content'}).length", 2);
michael@0 472 isEval("text.getBoxQuads({box:'content'})[0].bounds.left", textX);
michael@0 473 isEval("text.getBoxQuads({box:'content'})[1].bounds.left", textX - 150);
michael@0 474 isEval("text.getBoxQuads({box:'padding'}).length", 2);
michael@0 475 isEval("text.getBoxQuads({box:'padding'})[0].bounds.left", textX);
michael@0 476 isEval("text.getBoxQuads({box:'padding'})[1].bounds.left", textX - 150);
michael@0 477 isEval("text.getBoxQuads({box:'margin'}).length", 2);
michael@0 478 isEval("text.getBoxQuads({box:'margin'})[0].bounds.left", textX);
michael@0 479 isEval("text.getBoxQuads({box:'margin'})[1].bounds.left", textX - 150);
michael@0 480
michael@0 481 // Check that a text node whose layout might have been optimized away gives
michael@0 482 // correct results.
michael@0 483 var suppressedTextContainerX = suppressedTextContainer.getBoundingClientRect().left;
michael@0 484 isEval("suppressedText.getBoxQuads().length", 1);
michael@0 485 isEval("suppressedText.getBoxQuads()[0].bounds.left", suppressedTextContainerX);
michael@0 486 isEval("suppressedText.getBoxQuads()[0].bounds.width", 0);
michael@0 487
michael@0 488 var suppressedTextContainer2X = suppressedTextContainer2.getBoundingClientRect().left;
michael@0 489 isEval("document.convertPointFromNode(zeroPoint,suppressedText2).x",
michael@0 490 suppressedTextContainer2X);
michael@0 491
michael@0 492 checkException("comment.getBoxQuads()", "TypeError");
michael@0 493 checkException("d.getBoxQuads({relativeTo:comment})", "TypeError");
michael@0 494 checkException("comment.convertPointFromNode(zeroPoint,document)", "TypeError");
michael@0 495 checkException("document.convertPointFromNode(zeroPoint,comment)", "TypeError");
michael@0 496 checkException("comment.convertRectFromNode(zeroRect,document)", "TypeError");
michael@0 497 checkException("document.convertRectFromNode(zeroRect,comment)", "TypeError");
michael@0 498 checkException("comment.convertQuadFromNode(zeroQuad,document)", "TypeError");
michael@0 499 checkException("document.convertQuadFromNode(zeroQuad,comment)", "TypeError");
michael@0 500
michael@0 501 checkException("fragment.getBoxQuads()", "TypeError");
michael@0 502 checkException("d.getBoxQuads({relativeTo:fragment})", "TypeError");
michael@0 503 checkException("fragment.convertPointFromNode(zeroPoint,document)", "TypeError");
michael@0 504 checkException("document.convertPointFromNode(zeroPoint,fragment)", "TypeError");
michael@0 505 checkException("fragment.convertRectFromNode(zeroRect,document)", "TypeError");
michael@0 506 checkException("document.convertRectFromNode(zeroRect,fragment)", "TypeError");
michael@0 507 checkException("fragment.convertQuadFromNode(zeroQuad,document)", "TypeError");
michael@0 508 checkException("document.convertQuadFromNode(zeroQuad,fragment)", "TypeError");
michael@0 509
michael@0 510 isEval("displayNone.getBoxQuads().length", 0);
michael@0 511 isEval("notInDocument.getBoxQuads().length", 0);
michael@0 512 checkNotFound("displayNone", "document", 1, 2, 3, 4);
michael@0 513 checkNotFound("notInDocument", "document", 1, 2, 3, 4);
michael@0 514 checkNotFound("document", "displayNone", 1, 2, 3, 4);
michael@0 515 checkNotFound("document", "notInDocument", 1, 2, 3, 4);
michael@0 516
michael@0 517 // Test an overflow:hidden version of d. overflow:hidden should not affect
michael@0 518 // the quads, basically.
michael@0 519 var oHX = overflowHidden.getBoundingClientRect().left;
michael@0 520 var oHY = overflowHidden.getBoundingClientRect().top;
michael@0 521 checkQuadIsRect("overflowHidden", {box:"content"},
michael@0 522 oHX + 4 + 8, oHY + 1 + 5, 120, 90);
michael@0 523 checkQuadIsRect("overflowHidden", {box:"padding"},
michael@0 524 oHX + 8, oHY + 5, 120 + 2 + 4, 90 + 1 + 3);
michael@0 525 checkQuadIsRect("overflowHidden", {box:"border"},
michael@0 526 oHX, oHY, 120 + 2 + 4 + 6 + 8, 90 + 1 + 3 + 5 + 7);
michael@0 527 checkQuadIsRect("overflowHidden", {},
michael@0 528 oHX, oHY, 120 + 2 + 4 + 6 + 8, 90 + 1 + 3 + 5 + 7);
michael@0 529 checkQuadIsRect("overflowHidden", {box:"margin"},
michael@0 530 oHX - 12, oHY - 9, 120 + 2 + 4 + 6 + 8 + 10 + 12, 90 + 1 + 3 + 5 + 7 + 9 + 11);
michael@0 531
michael@0 532 // Test an overflow:scroll version of d. I assume that boxes aren't affected
michael@0 533 // by the scrollbar although it's not clear that this is correct.
michael@0 534 var oSX = overflowScroll.getBoundingClientRect().left;
michael@0 535 var oSY = overflowScroll.getBoundingClientRect().top;
michael@0 536 checkQuadIsRect("overflowScroll", {box:"content"},
michael@0 537 oSX + 4 + 8, oSY + 1 + 5, 120, 90);
michael@0 538 checkQuadIsRect("overflowScroll", {box:"padding"},
michael@0 539 oSX + 8, oSY + 5, 120 + 2 + 4, 90 + 1 + 3);
michael@0 540 checkQuadIsRect("overflowScroll", {box:"border"},
michael@0 541 oSX, oSY, 120 + 2 + 4 + 6 + 8, 90 + 1 + 3 + 5 + 7);
michael@0 542 checkQuadIsRect("overflowScroll", {},
michael@0 543 oSX, oSY, 120 + 2 + 4 + 6 + 8, 90 + 1 + 3 + 5 + 7);
michael@0 544 checkQuadIsRect("overflowScroll", {box:"margin"},
michael@0 545 oSX - 12, oSY - 9, 120 + 2 + 4 + 6 + 8 + 10 + 12, 90 + 1 + 3 + 5 + 7 + 9 + 11);
michael@0 546
michael@0 547 // Test simple 2D transforms.
michael@0 548 var stcX = scaleTransformContainer.getBoundingClientRect().left;
michael@0 549 var stcY = scaleTransformContainer.getBoundingClientRect().top;
michael@0 550 checkQuadIsRect("scaleTransform", {},
michael@0 551 stcX, stcY, 140, 160);
michael@0 552 var ttcX = translateTransformContainer.getBoundingClientRect().left;
michael@0 553 var ttcY = translateTransformContainer.getBoundingClientRect().top;
michael@0 554 checkQuadIsRect("translateTransform", {},
michael@0 555 ttcX + 30, ttcY + 40, 70, 80);
michael@0 556 // Test mapping into a transformed element.
michael@0 557 checkQuadIsRect("scaleTransform", {toStr:"translateTransform"},
michael@0 558 stcX - (ttcX + 30), stcY - (ttcY + 40), 140, 160);
michael@0 559 // Test 90 degree rotation.
michael@0 560 var rotatetcX = rotateTransformContainer.getBoundingClientRect().left;
michael@0 561 var rotatetcY = rotateTransformContainer.getBoundingClientRect().top;
michael@0 562 checkQuadIsQuad("rotateTransform", {},
michael@0 563 rotatetcX + 75, rotatetcY + 5,
michael@0 564 rotatetcX + 75, rotatetcY + 75,
michael@0 565 rotatetcX - 5, rotatetcY + 75,
michael@0 566 rotatetcX - 5, rotatetcY + 5);
michael@0 567 // Test vertical flip.
michael@0 568 var fliptcX = flipTransformContainer.getBoundingClientRect().left;
michael@0 569 var fliptcY = flipTransformContainer.getBoundingClientRect().top;
michael@0 570 checkQuadIsQuad("flipTransform", {},
michael@0 571 fliptcX, fliptcY + 80,
michael@0 572 fliptcX + 70, fliptcY + 80,
michael@0 573 fliptcX + 70, fliptcY,
michael@0 574 fliptcX, fliptcY);
michael@0 575 // Test non-90deg rotation.
michael@0 576 var rot45tcX = rot45TransformContainer.getBoundingClientRect().left;
michael@0 577 var rot45tcY = rot45TransformContainer.getBoundingClientRect().top;
michael@0 578 var halfDiagonal = 100/Math.sqrt(2);
michael@0 579 checkQuadIsQuad("rot45Transform", {tolerance:0.01},
michael@0 580 rot45tcX + 50, rot45tcY + 50 - halfDiagonal,
michael@0 581 rot45tcX + 50 + halfDiagonal, rot45tcY + 50,
michael@0 582 rot45tcX + 50, rot45tcY + 50 + halfDiagonal,
michael@0 583 rot45tcX + 50 - halfDiagonal, rot45tcY + 50);
michael@0 584
michael@0 585 // Test singular transforms.
michael@0 586 var singularTransformX = singularTransform.getBoundingClientRect().left;
michael@0 587 var singularTransformY = singularTransform.getBoundingClientRect().top;
michael@0 588 // They map everything to a point.
michael@0 589 checkQuadIsRect("singularTransform", {},
michael@0 590 singularTransformX, singularTransformY, 0, 0);
michael@0 591 checkQuadIsRect("singularTransformChild2", {},
michael@0 592 singularTransformX, singularTransformY, 0, 0);
michael@0 593 // Mapping into an element with a singular transform from outside sets
michael@0 594 // everything to zero.
michael@0 595 checkQuadIsRect("d", {toStr:"singularTransform"},
michael@0 596 0, 0, 0, 0);
michael@0 597 // But mappings within a subtree of an element with a singular transform work.
michael@0 598 checkQuadIsRect("singularTransformChild2", {toStr:"singularTransformChild1"},
michael@0 599 0, 50, 200, 50);
michael@0 600
michael@0 601 // Test 3D transforms.
michael@0 602 var t3tcX = threeDTransformContainer.getBoundingClientRect().left;
michael@0 603 var t3tcY = threeDTransformContainer.getBoundingClientRect().top;
michael@0 604 checkQuadIsQuad("threeDTransform", {tolerance:0.01},
michael@0 605 t3tcX + 59.446714, t3tcY - 18.569847,
michael@0 606 t3tcX + 129.570778, t3tcY + 13.540874,
michael@0 607 t3tcX + 129.570778, t3tcY + 100,
michael@0 608 t3tcX + 59.446714, t3tcY + 100);
michael@0 609 // Test nested 3D transforms (without preserve-3d).
michael@0 610 checkQuadIsQuad("threeDTransformChild", {tolerance:0.01},
michael@0 611 t3tcX + 89.395061, t3tcY + 2.243033,
michael@0 612 t3tcX + 113.041727, t3tcY - 2.758530,
michael@0 613 t3tcX + 113.041727, t3tcY + 52.985921,
michael@0 614 t3tcX + 89.395061, t3tcY + 47.571899);
michael@0 615 // Test preserve-3D.
michael@0 616 var p3dtcX = preserve3DTransformContainer.getBoundingClientRect().left;
michael@0 617 var p3dtcY = preserve3DTransformContainer.getBoundingClientRect().top;
michael@0 618 checkQuadIsRect("preserve3DTransformChild", {tolerance:0.01},
michael@0 619 p3dtcX, p3dtcY, 200, 50,
michael@0 620 {tolerance:0.0001});
michael@0 621 // Test mapping back into preserve-3D.
michael@0 622 checkQuadIsRect("d", {toStr:"preserve3DTransformChild",tolerance:0.01},
michael@0 623 dX - p3dtcX, dY - p3dtcY, dW, dH);
michael@0 624
michael@0 625 // Test SVG.
michael@0 626 var svgContainerX = svgContainer.getBoundingClientRect().left;
michael@0 627 var svgContainerY = svgContainer.getBoundingClientRect().top;
michael@0 628 checkQuadIsRect("circle", {},
michael@0 629 svgContainerX + 30, svgContainerY + 30, 40, 40);
michael@0 630 // Box types are ignored for SVG elements.
michael@0 631 checkQuadIsRect("circle", {box:"content"},
michael@0 632 svgContainerX + 30, svgContainerY + 30, 40, 40);
michael@0 633 checkQuadIsRect("circle", {box:"padding"},
michael@0 634 svgContainerX + 30, svgContainerY + 30, 40, 40);
michael@0 635 checkQuadIsRect("circle", {box:"margin"},
michael@0 636 svgContainerX + 30, svgContainerY + 30, 40, 40);
michael@0 637 checkQuadIsRect("d", {toStr:"circle"},
michael@0 638 dX - (svgContainerX + 30), dY - (svgContainerY + 30), dW, dH);
michael@0 639 // Test foreignObject inside an SVG transform.
michael@0 640 checkQuadIsRect("foreign", {},
michael@0 641 svgContainerX + 100, svgContainerY + 40, 200, 120);
michael@0 642
michael@0 643 // XXX Test SVG text (probably broken; unclear what the best way is to handle it)
michael@0 644
michael@0 645 // Test that converting between nodes in different toplevel browsing contexts
michael@0 646 // throws an exception.
michael@0 647 try {
michael@0 648 openedWindow = window.open("data:text/html,<div id='d'>","");
michael@0 649 } catch (ex) {
michael@0 650 // in some cases we can't open the window.
michael@0 651 openedWindow = null;
michael@0 652 }
michael@0 653 if (openedWindow) {
michael@0 654 openedWindow.addEventListener("load", function() {
michael@0 655 checkException("openedWindow.d.getBoxQuads({relativeTo:document})", "NotFoundError");
michael@0 656 checkException("document.getBoxQuads({relativeTo:openedWindow.d})", "NotFoundError");
michael@0 657 checkException("openedWindow.d.convertPointFromNode(zeroPoint,document)", "NotFoundError");
michael@0 658 checkException("document.convertPointFromNode(zeroPoint,openedWindow.d)", "NotFoundError");
michael@0 659 checkException("openedWindow.d.convertRectFromNode(zeroRect,document)", "NotFoundError");
michael@0 660 checkException("document.convertRectFromNode(zeroRect,openedWindow.d)", "NotFoundError");
michael@0 661 checkException("openedWindow.d.convertQuadFromNode(zeroQuad,document)", "NotFoundError");
michael@0 662 checkException("document.convertQuadFromNode(zeroQuad,openedWindow.d)", "NotFoundError");
michael@0 663 openedWindow.close();
michael@0 664 SimpleTest.finish();
michael@0 665 });
michael@0 666 } else {
michael@0 667 SimpleTest.finish();
michael@0 668 }
michael@0 669 }
michael@0 670 </script>
michael@0 671 </body>
michael@0 672 </html>

mercurial