1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,672 @@ 1.4 +<!DOCTYPE HTML> 1.5 +<html> 1.6 +<head> 1.7 +<meta charset="utf-8"> 1.8 +<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> 1.9 +<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 1.10 +</head> 1.11 +<body onload="startTest()"> 1.12 +<p id="display"></p> 1.13 +<script> 1.14 +// Global variables we want eval() to be able to reference from anywhere 1.15 +var f1d; 1.16 +var text; 1.17 +var suppressedText; 1.18 +var suppressedText2; 1.19 +var comment; 1.20 +var fragment; 1.21 +var openedWindow; 1.22 +var zeroPoint = new DOMPoint(0,0); 1.23 +var zeroRect = new DOMRect(0,0,0,0); 1.24 +var zeroQuad = new DOMQuad(zeroRect); 1.25 +var notInDocument = document.createElement('div'); 1.26 + 1.27 +function isEval(expr, b) { 1.28 + is(eval(expr), b, expr); 1.29 +} 1.30 + 1.31 +function isApprox(a, b, msg, options) { 1.32 + if (a != b && 'tolerance' in options && 1.33 + Math.abs(a - b) < options.tolerance) { 1.34 + ok(true, msg + "(" + a + " within " + options.tolerance + " of " + b + ")"); 1.35 + return; 1.36 + } 1.37 + is(a, b, msg); 1.38 +} 1.39 + 1.40 +function makeQuadsExpr(fromStr, options) { 1.41 + var getBoxQuadsOptionParts = []; 1.42 + if ('box' in options) { 1.43 + getBoxQuadsOptionParts.push("box:'" + options.box + "'"); 1.44 + } 1.45 + if ('toStr' in options) { 1.46 + getBoxQuadsOptionParts.push("relativeTo:" + options.toStr); 1.47 + } 1.48 + return fromStr + ".getBoxQuads({" + getBoxQuadsOptionParts.join(',') + "})"; 1.49 +} 1.50 + 1.51 +function makePointExpr(fromStr, options, x, y) { 1.52 + var convertPointOptionParts = []; 1.53 + if ('box' in options) { 1.54 + convertPointOptionParts.push("fromBox:'" + options.box + "'"); 1.55 + } 1.56 + if ('toBox' in options) { 1.57 + convertPointOptionParts.push("toBox:'" + options.toBox + "'"); 1.58 + } 1.59 + return ('toStr' in options ? options.toStr : "document") + 1.60 + ".convertPointFromNode(new DOMPoint(" + x + "," + y + ")," + fromStr + ",{" + 1.61 + convertPointOptionParts.join(",") + "})"; 1.62 +} 1.63 + 1.64 +function checkConvertPoints(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4) { 1.65 + var selfQuads = eval(fromStr).getBoxQuads( 1.66 + {box:options.box == "" ? "border" : options.box, 1.67 + relativeTo:eval(fromStr)}); 1.68 + var boxWidth = selfQuads[0].bounds.width; 1.69 + var boxHeight = selfQuads[0].bounds.height; 1.70 + 1.71 + var convertTopLeftPointExpr = makePointExpr(fromStr, options, 0, 0); 1.72 + var topLeft = eval(convertTopLeftPointExpr); 1.73 + isApprox(topLeft.x, x1, convertTopLeftPointExpr + ".x", options); 1.74 + isApprox(topLeft.y, y1, convertTopLeftPointExpr + ".y", options); 1.75 + 1.76 + var convertTopRightPointExpr = makePointExpr(fromStr, options, boxWidth, 0); 1.77 + var topRight = eval(convertTopRightPointExpr); 1.78 + isApprox(topRight.x, x2, convertTopRightPointExpr + ".x", options); 1.79 + isApprox(topRight.y, y2, convertTopRightPointExpr + ".y", options); 1.80 + 1.81 + var convertBottomRightPointExpr = makePointExpr(fromStr, options, boxWidth, boxHeight); 1.82 + var bottomRight = eval(convertBottomRightPointExpr); 1.83 + isApprox(bottomRight.x, x3, convertBottomRightPointExpr + ".x", options); 1.84 + isApprox(bottomRight.y, y3, convertBottomRightPointExpr + ".y", options); 1.85 + 1.86 + var convertBottomLeftPointExpr = makePointExpr(fromStr, options, 0, boxHeight); 1.87 + var bottomLeft = eval(convertBottomLeftPointExpr); 1.88 + isApprox(bottomLeft.x, x4, convertBottomLeftPointExpr + ".x", options); 1.89 + isApprox(bottomLeft.y, y4, convertBottomLeftPointExpr + ".y", options); 1.90 +} 1.91 + 1.92 +function checkConvertRect(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4) { 1.93 + var selfQuads = eval(fromStr).getBoxQuads( 1.94 + {box:options.box == "" ? "border" : options.box, 1.95 + relativeTo:eval(fromStr)}); 1.96 + var boxWidth = selfQuads[0].bounds.width; 1.97 + var boxHeight = selfQuads[0].bounds.height; 1.98 + 1.99 + var convertPointOptionParts = []; 1.100 + if ('box' in options) { 1.101 + convertPointOptionParts.push("fromBox:'" + options.box + "'"); 1.102 + } 1.103 + if ('toBox' in options) { 1.104 + convertPointOptionParts.push("toBox:'" + options.toBox + "'"); 1.105 + } 1.106 + 1.107 + var convertRectExpr = ('toStr' in options ? options.toStr : "document") + 1.108 + ".convertRectFromNode(new DOMRect(0,0," + boxWidth + "," + boxHeight + ")," + 1.109 + fromStr + ",{" + convertPointOptionParts.join(",") + "})"; 1.110 + var quad = eval(convertRectExpr); 1.111 + isApprox(quad.p1.x, x1, convertRectExpr + ".p1.x", options); 1.112 + isApprox(quad.p1.y, y1, convertRectExpr + ".p1.y", options); 1.113 + isApprox(quad.p2.x, x2, convertRectExpr + ".p2.x", options); 1.114 + isApprox(quad.p2.y, y2, convertRectExpr + ".p2.y", options); 1.115 + isApprox(quad.p3.x, x3, convertRectExpr + ".p3.x", options); 1.116 + isApprox(quad.p3.y, y3, convertRectExpr + ".p3.y", options); 1.117 + isApprox(quad.p4.x, x4, convertRectExpr + ".p4.x", options); 1.118 + isApprox(quad.p4.y, y4, convertRectExpr + ".p4.y", options); 1.119 +} 1.120 + 1.121 +function checkConvertQuad(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4) { 1.122 + var selfQuads = eval(fromStr).getBoxQuads( 1.123 + {box:options.box == "" ? "border" : options.box, 1.124 + relativeTo:eval(fromStr)}); 1.125 + var boxWidth = selfQuads[0].bounds.width; 1.126 + var boxHeight = selfQuads[0].bounds.height; 1.127 + 1.128 + var convertPointOptionParts = []; 1.129 + if ('box' in options) { 1.130 + convertPointOptionParts.push("fromBox:'" + options.box + "'"); 1.131 + } 1.132 + if ('toBox' in options) { 1.133 + convertPointOptionParts.push("toBox:'" + options.toBox + "'"); 1.134 + } 1.135 + 1.136 + var convertQuadExpr = ('toStr' in options ? options.toStr : "document") + 1.137 + ".convertQuadFromNode(new DOMQuad(new DOMRect(0,0," + boxWidth + "," + boxHeight + "))," + 1.138 + fromStr + ",{" + convertPointOptionParts.join(",") + "})"; 1.139 + var quad = eval(convertQuadExpr); 1.140 + isApprox(quad.p1.x, x1, convertQuadExpr + ".p1.x", options); 1.141 + isApprox(quad.p1.y, y1, convertQuadExpr + ".p1.y", options); 1.142 + isApprox(quad.p2.x, x2, convertQuadExpr + ".p2.x", options); 1.143 + isApprox(quad.p2.y, y2, convertQuadExpr + ".p2.y", options); 1.144 + isApprox(quad.p3.x, x3, convertQuadExpr + ".p3.x", options); 1.145 + isApprox(quad.p3.y, y3, convertQuadExpr + ".p3.y", options); 1.146 + isApprox(quad.p4.x, x4, convertQuadExpr + ".p4.x", options); 1.147 + isApprox(quad.p4.y, y4, convertQuadExpr + ".p4.y", options); 1.148 +} 1.149 + 1.150 +function checkQuadIsRect(fromStr, options, x, y, w, h) { 1.151 + var quadsExpr = makeQuadsExpr(fromStr, options); 1.152 + var quads = eval(quadsExpr); 1.153 + is(quads.length, 1, quadsExpr + " checking quad count"); 1.154 + var q = quads[0]; 1.155 + isApprox(q.p1.x, x, quadsExpr + " checking quad.p1.x", options); 1.156 + isApprox(q.p1.y, y, quadsExpr + " checking quad.p1.y", options); 1.157 + isApprox(q.p2.x, x + w, quadsExpr + " checking quad.p2.x", options); 1.158 + isApprox(q.p2.y, y, quadsExpr + " checking quad.p2.y", options); 1.159 + isApprox(q.p3.x, x + w, quadsExpr + " checking quad.p3.x", options); 1.160 + isApprox(q.p3.y, y + h, quadsExpr + " checking quad.p3.y", options); 1.161 + isApprox(q.p4.x, x, quadsExpr + " checking quad.p4.x", options); 1.162 + isApprox(q.p4.y, y + h, quadsExpr + " checking quad.p4.y", options); 1.163 + 1.164 + isApprox(q.bounds.left, x, quadsExpr + " checking quad.bounds.left", options); 1.165 + isApprox(q.bounds.top, y, quadsExpr + " checking quad.bounds.top", options); 1.166 + isApprox(q.bounds.width, w, quadsExpr + " checking quad.bounds.width", options); 1.167 + isApprox(q.bounds.height, h, quadsExpr + " checking quad.bounds.height", options); 1.168 + 1.169 + checkConvertPoints(fromStr, options, x, y, x + w, y, x + w, y + h, x, y + h); 1.170 + checkConvertRect(fromStr, options, x, y, x + w, y, x + w, y + h, x, y + h); 1.171 + checkConvertQuad(fromStr, options, x, y, x + w, y, x + w, y + h, x, y + h); 1.172 +} 1.173 + 1.174 +function checkQuadIsQuad(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4) { 1.175 + var quadsExpr = makeQuadsExpr(fromStr, options); 1.176 + var quads = eval(quadsExpr); 1.177 + is(quads.length, 1, quadsExpr + " checking quad count"); 1.178 + var q = quads[0]; 1.179 + isApprox(q.p1.x, x1, quadsExpr + " checking quad.p1.x", options); 1.180 + isApprox(q.p1.y, y1, quadsExpr + " checking quad.p1.y", options); 1.181 + isApprox(q.p2.x, x2, quadsExpr + " checking quad.p2.x", options); 1.182 + isApprox(q.p2.y, y2, quadsExpr + " checking quad.p2.y", options); 1.183 + isApprox(q.p3.x, x3, quadsExpr + " checking quad.p3.x", options); 1.184 + isApprox(q.p3.y, y3, quadsExpr + " checking quad.p3.y", options); 1.185 + isApprox(q.p4.x, x4, quadsExpr + " checking quad.p4.x", options); 1.186 + isApprox(q.p4.y, y4, quadsExpr + " checking quad.p4.y", options); 1.187 + 1.188 + isApprox(q.bounds.left, Math.min(x1,x2,x3,x4), quadsExpr + " checking quad.bounds.left", options); 1.189 + isApprox(q.bounds.top, Math.min(y1,y2,y3,y4), quadsExpr + " checking quad.bounds.top", options); 1.190 + isApprox(q.bounds.right, Math.max(x1,x2,x3,x4), quadsExpr + " checking quad.bounds.right", options); 1.191 + isApprox(q.bounds.bottom, Math.max(y1,y2,y3,y4), quadsExpr + " checking quad.bounds.bottom", options); 1.192 + 1.193 + checkConvertPoints(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4); 1.194 + checkConvertRect(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4); 1.195 + checkConvertQuad(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4); 1.196 +} 1.197 + 1.198 +function checkException(expr, name) { 1.199 + try { 1.200 + eval(expr); 1.201 + ok(false, "Exception should have been thrown for " + expr); 1.202 + } catch (ex) { 1.203 + is(ex.name, name, "Checking exception type for " + expr); 1.204 + } 1.205 +} 1.206 + 1.207 +function checkNotFound(fromStr, toStr, x1, y1, x2, y2) { 1.208 + var convertPointExpr = toStr + ".convertPointFromNode(new DOMPoint(" + x1 + 1.209 + "," + y1 + ")," + fromStr + ")"; 1.210 + checkException(convertPointExpr, "NotFoundError"); 1.211 + 1.212 + var convertRectExpr = toStr + ".convertRectFromNode(new DOMRect(" + x1 + 1.213 + "," + y1 + "," + x2 + "," + y2 + ")," + fromStr + ")"; 1.214 + checkException(convertRectExpr, "NotFoundError"); 1.215 + 1.216 + var convertQuadExpr = toStr + ".convertQuadFromNode(new DOMQuad(new DOMRect(" + x1 + 1.217 + "," + y1 + "," + x2 + "," + y2 + "))," + fromStr + ")"; 1.218 + checkException(convertQuadExpr, "NotFoundError"); 1.219 +} 1.220 +</script> 1.221 +<style> 1.222 +em { 1.223 + display:inline-block; height:10px; background:gray; 1.224 +} 1.225 +</style> 1.226 +<div id="dContainer" 1.227 + style="padding:13px 14px 15px 16px; 1.228 + border-width:17px 18px 19px 20px; border-style:solid; border-color:yellow; 1.229 + margin:21px 22px 23px 24px;"> 1.230 + <div id="d" 1.231 + style="width:120px; height:90px; padding:1px 2px 3px 4px; 1.232 + border-width:5px 6px 7px 8px; border-style:solid; border-color:yellow; 1.233 + margin:9px 10px 11px 12px; background:blue;"> 1.234 + </div> 1.235 +</div> 1.236 + 1.237 +<div id="dUnrelated" style="width:50px; height:50px;"></div> 1.238 + 1.239 +<iframe id="f1" style="width:50px; height:50px; border:0; background:lime;" 1.240 + 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>"> 1.241 +</iframe> 1.242 +<!-- 1.243 +It matters that the first part of this span is on the same line as the above <iframe>! 1.244 +That ensures the first quad's X position is not equal to the anonymous block's X position. 1.245 +--> 1.246 +<span id="ibSplit" 1.247 + ><em id="ibSplitPart1" style="width:100px;"></em 1.248 + ><div style="width:110px; height:20px; background:black"></div 1.249 + ><em style="width:130px;"></em></span> 1.250 + 1.251 +<table cellspacing="0" id="table" style="border:0; margin:0; padding:0; background:orange"> 1.252 + <tbody style="padding:0; margin:0; border:0; background:blue"> 1.253 + <tr style="height:50px; padding:0; margin:0; border:0"> 1.254 + <td style="border:0; margin:0; padding:0">Cell</td> 1.255 + </tr> 1.256 + </tbody> 1.257 + <caption style="height:40px; background:yellow">Caption</caption> 1.258 +</table> 1.259 + 1.260 +<div style="height:80px; -moz-column-count:2; -moz-column-fill:auto; border:2px solid black;"> 1.261 + <div style="height:20px;"></div> 1.262 + <div id="colSplit" style="height:80px; background:blue; border:10px solid red; border-bottom-width:15px"></div> 1.263 +</div> 1.264 + 1.265 +<div style="width:200px; border:2px solid black;" 1.266 + ><em style="width:150px;"></em 1.267 + ><span id="inlineSplit" style="background:pink; border:10px solid red; border-right-width:15px" 1.268 + ><em style="width:20px; background:green"></em><em style="width:60px"></em 1.269 + ></span 1.270 +></div> 1.271 + 1.272 +<div style="width:200px; border:2px solid black;" 1.273 + ><em style="width:150px;"></em 1.274 + ><span id="textContainer">T 1.275 +TextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextText</span 1.276 +></div> 1.277 + 1.278 +<div id="suppressedTextContainer"> </div> 1.279 +<div id="suppressedTextContainer2"> </div> 1.280 + 1.281 +<div id="commentContainer"><!-- COMMENT --></div> 1.282 + 1.283 +<div id="displayNone" style="display:none"></div> 1.284 + 1.285 +<div id="overflowHidden" 1.286 + style="overflow:hidden; width:120px; height:90px; padding:1px 2px 3px 4px; 1.287 + border-width:5px 6px 7px 8px; border-style:solid; border-color:yellow; 1.288 + margin:9px 10px 11px 12px; background:blue;"> 1.289 + <div style="height:400px; background:lime;"></div> 1.290 +</div> 1.291 + 1.292 +<div id="overflowScroll" 1.293 + style="overflow:scroll; width:120px; height:90px; padding:1px 2px 3px 4px; 1.294 + border-width:5px 6px 7px 8px; border-style:solid; border-color:yellow; 1.295 + margin:9px 10px 11px 12px; background:blue; background-clip:content-box;"> 1.296 + <div id="overflowScrollChild" style="height:400px;"></div> 1.297 +</div> 1.298 + 1.299 +<div id="scaleTransformContainer" style="width:200px; height:200px;"> 1.300 + <div id="scaleTransform" 1.301 + style="transform:scale(2); transform-origin:top left; width:70px; height:80px; background:yellow"></div> 1.302 +</div> 1.303 + 1.304 +<div id="translateTransformContainer" style="width:200px; height:200px;"> 1.305 + <div id="translateTransform" 1.306 + style="transform:translate(30px,40px); width:70px; height:80px; background:yellow"></div> 1.307 +</div> 1.308 + 1.309 +<div id="rotateTransformContainer" style="width:200px; height:200px;"> 1.310 + <div id="rotateTransform" 1.311 + style="transform:rotate(90deg); width:70px; height:80px; background:yellow"></div> 1.312 +</div> 1.313 + 1.314 +<div id="flipTransformContainer" style="width:200px; height:200px;"> 1.315 + <div id="flipTransform" 1.316 + style="transform:scaleY(-1); width:70px; height:80px; background:yellow"></div> 1.317 +</div> 1.318 + 1.319 +<div id="rot45TransformContainer" style="width:200px; height:200px;"> 1.320 + <div id="rot45Transform" 1.321 + style="transform:rotate(45deg); width:100px; height:100px; background:yellow"></div> 1.322 +</div> 1.323 + 1.324 +<div id="singularTransform" style="transform:scale(0); width:200px; height:200px;"> 1.325 + <div id="singularTransformChild1" style="height:50px;"></div> 1.326 + <div id="singularTransformChild2" style="height:50px;"></div> 1.327 +</div> 1.328 + 1.329 +<div id="threeDTransformContainer" style="perspective:600px; width:200px; height:200px"> 1.330 + <div id="threeDTransform" style="transform:rotateY(70deg); background:yellow; height:100px; perspective:600px"> 1.331 + <div id="threeDTransformChild" style="transform:rotateY(-70deg); background:blue; height:50px;"></div> 1.332 + </div> 1.333 +</div> 1.334 + 1.335 +<div id="preserve3DTransformContainer" style="perspective:600px; width:200px; height:200px"> 1.336 + <div id="preserve3DTransform" style="transform:rotateY(70deg); transform-style:preserve-3d; background:yellow; height:100px;"> 1.337 + <div id="preserve3DTransformChild" style="transform:rotateY(-70deg); background:blue; height:50px;"></div> 1.338 + </div> 1.339 +</div> 1.340 + 1.341 +<div id="svgContainer"> 1.342 + <svg id="svg" style="width:200px; height:200px; background:lightgray;"> 1.343 + <circle id="circle" cx="50" cy="50" r="20" fill="red" style="margin:20px; padding:10px; border:15px solid black"></circle> 1.344 + <g transform="scale(2)"> 1.345 + <foreignObject x="50" y="20"> 1.346 + <div id="foreign" style="width:100px; height:60px; background:purple"></div> 1.347 + </foreignObject> 1.348 + </g> 1.349 + </svg> 1.350 +</div> 1.351 + 1.352 +<script> 1.353 +SimpleTest.waitForExplicitFinish(); 1.354 + 1.355 +window.scrollTo(0,0); 1.356 + 1.357 +function startTest() { 1.358 + SpecialPowers.pushPrefEnv({"set": [["layout.css.DOMPoint.enabled", true], 1.359 + ["layout.css.DOMQuad.enabled", true], 1.360 + ["layout.css.getBoxQuads.enabled", true], 1.361 + ["layout.css.convertFromNode.enabled", true]]}, runTest); 1.362 +} 1.363 + 1.364 +function runTest() { 1.365 + // Setup globals 1.366 + f1d = f1.contentWindow.f1d; 1.367 + text = textContainer.firstChild; 1.368 + suppressedText = suppressedTextContainer.firstChild; 1.369 + suppressedText2 = suppressedTextContainer2.firstChild; 1.370 + comment = commentContainer.firstChild; 1.371 + fragment = document.createDocumentFragment(); 1.372 + 1.373 + // Test basic BoxQuadOptions.box. 1.374 + var dX = d.getBoundingClientRect().left; 1.375 + var dY = d.getBoundingClientRect().top; 1.376 + var dW = d.getBoundingClientRect().width; 1.377 + var dH = d.getBoundingClientRect().height; 1.378 + 1.379 + checkQuadIsRect("d", {box:"content"}, 1.380 + dX + 4 + 8, dY + 1 + 5, 120, 90); 1.381 + checkQuadIsRect("d", {box:"padding"}, 1.382 + dX + 8, dY + 5, 120 + 2 + 4, 90 + 1 + 3); 1.383 + checkQuadIsRect("d", {box:"border"}, 1.384 + dX, dY, dW, dH); 1.385 + checkQuadIsRect("d", {}, 1.386 + dX, dY, 120 + 2 + 4 + 6 + 8, 90 + 1 + 3 + 5 + 7); 1.387 + checkQuadIsRect("d", {box:"margin"}, 1.388 + dX - 12, dY - 9, 120 + 2 + 4 + 6 + 8 + 10 + 12, 90 + 1 + 3 + 5 + 7 + 9 + 11); 1.389 + 1.390 + // Test basic BoxQuadOptions.relativeTo 1.391 + checkQuadIsRect("d", {toStr:"dContainer"}, 1.392 + 12 + 16 + 20, 9 + 13 + 17, dW, dH); 1.393 + 1.394 + // Test BoxQuadOptions.relativeTo relative to this document 1.395 + checkQuadIsRect("d", {toStr:"document"}, 1.396 + dX, dY, dW, dH); 1.397 + // Test BoxQuadOptions.relativeTo relative to a non-ancestor. 1.398 + var dUnrelatedX = dUnrelated.getBoundingClientRect().left; 1.399 + var dUnrelatedY = dUnrelated.getBoundingClientRect().top; 1.400 + checkQuadIsRect("d", {toStr:"dUnrelated"}, 1.401 + dX - dUnrelatedX, dY - dUnrelatedY, dW, dH); 1.402 + // Test BoxQuadOptions.relativeTo relative to an element in a different document (and the document) 1.403 + var f1X = f1.getBoundingClientRect().left; 1.404 + var f1Y = f1.getBoundingClientRect().top; 1.405 + checkQuadIsRect("d", {toStr:"f1.contentWindow.f1d"}, 1.406 + dX - (f1X + 14), dY - (f1Y + 15), dW, dH); 1.407 + checkQuadIsRect("d", {toStr:"f1.contentDocument"}, 1.408 + dX - f1X, dY - f1Y, dW, dH); 1.409 + // Test one document relative to another 1.410 + checkQuadIsRect("f1.contentDocument", {toStr:"document"}, 1.411 + f1X, f1Y, 50, 50); 1.412 + // The box type is irrelevant for a document 1.413 + checkQuadIsRect("f1.contentDocument", {toStr:"document",box:"content"}, 1.414 + f1X, f1Y, 50, 50); 1.415 + checkQuadIsRect("f1.contentDocument", {toStr:"document",box:"margin"}, 1.416 + f1X, f1Y, 50, 50); 1.417 + checkQuadIsRect("f1.contentDocument", {toStr:"document",box:"padding"}, 1.418 + f1X, f1Y, 50, 50); 1.419 + 1.420 + // Test that anonymous boxes are correctly ignored when building quads. 1.421 + var ibSplitPart1X = ibSplitPart1.getBoundingClientRect().left; 1.422 + var ibSplitY = ibSplit.getBoundingClientRect().top; 1.423 + isEval("ibSplit.getBoxQuads().length", 3); 1.424 + isEval("ibSplit.getBoxQuads()[0].bounds.left", ibSplitPart1X); 1.425 + isEval("ibSplit.getBoxQuads()[0].bounds.width", 100); 1.426 + isEval("ibSplit.getBoxQuads()[1].bounds.width", 110); 1.427 + isEval("ibSplit.getBoxQuads()[2].bounds.width", 130); 1.428 + isEval("table.getBoxQuads().length", 2); 1.429 + isEval("table.getBoxQuads()[0].bounds.height", 50); 1.430 + isEval("table.getBoxQuads()[1].bounds.height", 40); 1.431 + 1.432 + // Test that we skip anonymous boxes when finding the right box to be relative to. 1.433 + checkQuadIsRect("d", {toStr:"ibSplit"}, 1.434 + dX - ibSplitPart1X, dY - ibSplitY, dW, dH); 1.435 + var tableX = table.getClientRects()[0].left; 1.436 + var tableY = table.getClientRects()[0].top; 1.437 + checkQuadIsRect("d", {toStr:"table"}, 1.438 + dX - tableX, dY - tableY, dW, dH); 1.439 + isEval("ibSplit.convertPointFromNode(zeroPoint,d).x", dX - ibSplitPart1X); 1.440 + isEval("table.convertPointFromNode(zeroPoint,d).x", dX - table.getClientRects()[0].left); 1.441 + 1.442 + // Test boxes generated by block splitting. Check for borders being placed correctly. 1.443 + var colSplitY = colSplit.getClientRects()[0].top; 1.444 + isEval("colSplit.getBoxQuads().length", 2); 1.445 + isEval("colSplit.getBoxQuads()[0].bounds.top", colSplitY); 1.446 + isEval("colSplit.getBoxQuads()[0].bounds.height", 60); 1.447 + isEval("colSplit.getBoxQuads()[1].bounds.top", colSplitY - 20); 1.448 + isEval("colSplit.getBoxQuads()[1].bounds.height", 45); 1.449 + isEval("colSplit.getBoxQuads({box:'content'}).length", 2); 1.450 + // The first box for the block has the top border; the second box has the bottom border. 1.451 + isEval("colSplit.getBoxQuads({box:'content'})[0].bounds.top", colSplitY + 10); 1.452 + isEval("colSplit.getBoxQuads({box:'content'})[0].bounds.height", 50); 1.453 + isEval("colSplit.getBoxQuads({box:'content'})[1].bounds.top", colSplitY - 20); 1.454 + isEval("colSplit.getBoxQuads({box:'content'})[1].bounds.height", 30); 1.455 + 1.456 + var inlineSplitX = inlineSplit.getClientRects()[0].left; 1.457 + isEval("inlineSplit.getBoxQuads().length", 2); 1.458 + isEval("inlineSplit.getBoxQuads()[0].bounds.left", inlineSplitX); 1.459 + isEval("inlineSplit.getBoxQuads()[0].bounds.width", 30); 1.460 + isEval("inlineSplit.getBoxQuads()[1].bounds.left", inlineSplitX - 150); 1.461 + isEval("inlineSplit.getBoxQuads()[1].bounds.width", 75); 1.462 + isEval("inlineSplit.getBoxQuads({box:'content'}).length", 2); 1.463 + // The first box for the inline has the left border; the second box has the right border. 1.464 + isEval("inlineSplit.getBoxQuads({box:'content'})[0].bounds.left", inlineSplitX + 10); 1.465 + isEval("inlineSplit.getBoxQuads({box:'content'})[0].bounds.width", 20); 1.466 + isEval("inlineSplit.getBoxQuads({box:'content'})[1].bounds.left", inlineSplitX - 150); 1.467 + isEval("inlineSplit.getBoxQuads({box:'content'})[1].bounds.width", 60); 1.468 + 1.469 + var textX = textContainer.getClientRects()[0].left; 1.470 + isEval("text.getBoxQuads().length", 2); 1.471 + isEval("text.getBoxQuads()[0].bounds.left", textX); 1.472 + isEval("text.getBoxQuads()[1].bounds.left", textX - 150); 1.473 + // Box types are irrelevant for text 1.474 + isEval("text.getBoxQuads({box:'content'}).length", 2); 1.475 + isEval("text.getBoxQuads({box:'content'})[0].bounds.left", textX); 1.476 + isEval("text.getBoxQuads({box:'content'})[1].bounds.left", textX - 150); 1.477 + isEval("text.getBoxQuads({box:'padding'}).length", 2); 1.478 + isEval("text.getBoxQuads({box:'padding'})[0].bounds.left", textX); 1.479 + isEval("text.getBoxQuads({box:'padding'})[1].bounds.left", textX - 150); 1.480 + isEval("text.getBoxQuads({box:'margin'}).length", 2); 1.481 + isEval("text.getBoxQuads({box:'margin'})[0].bounds.left", textX); 1.482 + isEval("text.getBoxQuads({box:'margin'})[1].bounds.left", textX - 150); 1.483 + 1.484 + // Check that a text node whose layout might have been optimized away gives 1.485 + // correct results. 1.486 + var suppressedTextContainerX = suppressedTextContainer.getBoundingClientRect().left; 1.487 + isEval("suppressedText.getBoxQuads().length", 1); 1.488 + isEval("suppressedText.getBoxQuads()[0].bounds.left", suppressedTextContainerX); 1.489 + isEval("suppressedText.getBoxQuads()[0].bounds.width", 0); 1.490 + 1.491 + var suppressedTextContainer2X = suppressedTextContainer2.getBoundingClientRect().left; 1.492 + isEval("document.convertPointFromNode(zeroPoint,suppressedText2).x", 1.493 + suppressedTextContainer2X); 1.494 + 1.495 + checkException("comment.getBoxQuads()", "TypeError"); 1.496 + checkException("d.getBoxQuads({relativeTo:comment})", "TypeError"); 1.497 + checkException("comment.convertPointFromNode(zeroPoint,document)", "TypeError"); 1.498 + checkException("document.convertPointFromNode(zeroPoint,comment)", "TypeError"); 1.499 + checkException("comment.convertRectFromNode(zeroRect,document)", "TypeError"); 1.500 + checkException("document.convertRectFromNode(zeroRect,comment)", "TypeError"); 1.501 + checkException("comment.convertQuadFromNode(zeroQuad,document)", "TypeError"); 1.502 + checkException("document.convertQuadFromNode(zeroQuad,comment)", "TypeError"); 1.503 + 1.504 + checkException("fragment.getBoxQuads()", "TypeError"); 1.505 + checkException("d.getBoxQuads({relativeTo:fragment})", "TypeError"); 1.506 + checkException("fragment.convertPointFromNode(zeroPoint,document)", "TypeError"); 1.507 + checkException("document.convertPointFromNode(zeroPoint,fragment)", "TypeError"); 1.508 + checkException("fragment.convertRectFromNode(zeroRect,document)", "TypeError"); 1.509 + checkException("document.convertRectFromNode(zeroRect,fragment)", "TypeError"); 1.510 + checkException("fragment.convertQuadFromNode(zeroQuad,document)", "TypeError"); 1.511 + checkException("document.convertQuadFromNode(zeroQuad,fragment)", "TypeError"); 1.512 + 1.513 + isEval("displayNone.getBoxQuads().length", 0); 1.514 + isEval("notInDocument.getBoxQuads().length", 0); 1.515 + checkNotFound("displayNone", "document", 1, 2, 3, 4); 1.516 + checkNotFound("notInDocument", "document", 1, 2, 3, 4); 1.517 + checkNotFound("document", "displayNone", 1, 2, 3, 4); 1.518 + checkNotFound("document", "notInDocument", 1, 2, 3, 4); 1.519 + 1.520 + // Test an overflow:hidden version of d. overflow:hidden should not affect 1.521 + // the quads, basically. 1.522 + var oHX = overflowHidden.getBoundingClientRect().left; 1.523 + var oHY = overflowHidden.getBoundingClientRect().top; 1.524 + checkQuadIsRect("overflowHidden", {box:"content"}, 1.525 + oHX + 4 + 8, oHY + 1 + 5, 120, 90); 1.526 + checkQuadIsRect("overflowHidden", {box:"padding"}, 1.527 + oHX + 8, oHY + 5, 120 + 2 + 4, 90 + 1 + 3); 1.528 + checkQuadIsRect("overflowHidden", {box:"border"}, 1.529 + oHX, oHY, 120 + 2 + 4 + 6 + 8, 90 + 1 + 3 + 5 + 7); 1.530 + checkQuadIsRect("overflowHidden", {}, 1.531 + oHX, oHY, 120 + 2 + 4 + 6 + 8, 90 + 1 + 3 + 5 + 7); 1.532 + checkQuadIsRect("overflowHidden", {box:"margin"}, 1.533 + oHX - 12, oHY - 9, 120 + 2 + 4 + 6 + 8 + 10 + 12, 90 + 1 + 3 + 5 + 7 + 9 + 11); 1.534 + 1.535 + // Test an overflow:scroll version of d. I assume that boxes aren't affected 1.536 + // by the scrollbar although it's not clear that this is correct. 1.537 + var oSX = overflowScroll.getBoundingClientRect().left; 1.538 + var oSY = overflowScroll.getBoundingClientRect().top; 1.539 + checkQuadIsRect("overflowScroll", {box:"content"}, 1.540 + oSX + 4 + 8, oSY + 1 + 5, 120, 90); 1.541 + checkQuadIsRect("overflowScroll", {box:"padding"}, 1.542 + oSX + 8, oSY + 5, 120 + 2 + 4, 90 + 1 + 3); 1.543 + checkQuadIsRect("overflowScroll", {box:"border"}, 1.544 + oSX, oSY, 120 + 2 + 4 + 6 + 8, 90 + 1 + 3 + 5 + 7); 1.545 + checkQuadIsRect("overflowScroll", {}, 1.546 + oSX, oSY, 120 + 2 + 4 + 6 + 8, 90 + 1 + 3 + 5 + 7); 1.547 + checkQuadIsRect("overflowScroll", {box:"margin"}, 1.548 + oSX - 12, oSY - 9, 120 + 2 + 4 + 6 + 8 + 10 + 12, 90 + 1 + 3 + 5 + 7 + 9 + 11); 1.549 + 1.550 + // Test simple 2D transforms. 1.551 + var stcX = scaleTransformContainer.getBoundingClientRect().left; 1.552 + var stcY = scaleTransformContainer.getBoundingClientRect().top; 1.553 + checkQuadIsRect("scaleTransform", {}, 1.554 + stcX, stcY, 140, 160); 1.555 + var ttcX = translateTransformContainer.getBoundingClientRect().left; 1.556 + var ttcY = translateTransformContainer.getBoundingClientRect().top; 1.557 + checkQuadIsRect("translateTransform", {}, 1.558 + ttcX + 30, ttcY + 40, 70, 80); 1.559 + // Test mapping into a transformed element. 1.560 + checkQuadIsRect("scaleTransform", {toStr:"translateTransform"}, 1.561 + stcX - (ttcX + 30), stcY - (ttcY + 40), 140, 160); 1.562 + // Test 90 degree rotation. 1.563 + var rotatetcX = rotateTransformContainer.getBoundingClientRect().left; 1.564 + var rotatetcY = rotateTransformContainer.getBoundingClientRect().top; 1.565 + checkQuadIsQuad("rotateTransform", {}, 1.566 + rotatetcX + 75, rotatetcY + 5, 1.567 + rotatetcX + 75, rotatetcY + 75, 1.568 + rotatetcX - 5, rotatetcY + 75, 1.569 + rotatetcX - 5, rotatetcY + 5); 1.570 + // Test vertical flip. 1.571 + var fliptcX = flipTransformContainer.getBoundingClientRect().left; 1.572 + var fliptcY = flipTransformContainer.getBoundingClientRect().top; 1.573 + checkQuadIsQuad("flipTransform", {}, 1.574 + fliptcX, fliptcY + 80, 1.575 + fliptcX + 70, fliptcY + 80, 1.576 + fliptcX + 70, fliptcY, 1.577 + fliptcX, fliptcY); 1.578 + // Test non-90deg rotation. 1.579 + var rot45tcX = rot45TransformContainer.getBoundingClientRect().left; 1.580 + var rot45tcY = rot45TransformContainer.getBoundingClientRect().top; 1.581 + var halfDiagonal = 100/Math.sqrt(2); 1.582 + checkQuadIsQuad("rot45Transform", {tolerance:0.01}, 1.583 + rot45tcX + 50, rot45tcY + 50 - halfDiagonal, 1.584 + rot45tcX + 50 + halfDiagonal, rot45tcY + 50, 1.585 + rot45tcX + 50, rot45tcY + 50 + halfDiagonal, 1.586 + rot45tcX + 50 - halfDiagonal, rot45tcY + 50); 1.587 + 1.588 + // Test singular transforms. 1.589 + var singularTransformX = singularTransform.getBoundingClientRect().left; 1.590 + var singularTransformY = singularTransform.getBoundingClientRect().top; 1.591 + // They map everything to a point. 1.592 + checkQuadIsRect("singularTransform", {}, 1.593 + singularTransformX, singularTransformY, 0, 0); 1.594 + checkQuadIsRect("singularTransformChild2", {}, 1.595 + singularTransformX, singularTransformY, 0, 0); 1.596 + // Mapping into an element with a singular transform from outside sets 1.597 + // everything to zero. 1.598 + checkQuadIsRect("d", {toStr:"singularTransform"}, 1.599 + 0, 0, 0, 0); 1.600 + // But mappings within a subtree of an element with a singular transform work. 1.601 + checkQuadIsRect("singularTransformChild2", {toStr:"singularTransformChild1"}, 1.602 + 0, 50, 200, 50); 1.603 + 1.604 + // Test 3D transforms. 1.605 + var t3tcX = threeDTransformContainer.getBoundingClientRect().left; 1.606 + var t3tcY = threeDTransformContainer.getBoundingClientRect().top; 1.607 + checkQuadIsQuad("threeDTransform", {tolerance:0.01}, 1.608 + t3tcX + 59.446714, t3tcY - 18.569847, 1.609 + t3tcX + 129.570778, t3tcY + 13.540874, 1.610 + t3tcX + 129.570778, t3tcY + 100, 1.611 + t3tcX + 59.446714, t3tcY + 100); 1.612 + // Test nested 3D transforms (without preserve-3d). 1.613 + checkQuadIsQuad("threeDTransformChild", {tolerance:0.01}, 1.614 + t3tcX + 89.395061, t3tcY + 2.243033, 1.615 + t3tcX + 113.041727, t3tcY - 2.758530, 1.616 + t3tcX + 113.041727, t3tcY + 52.985921, 1.617 + t3tcX + 89.395061, t3tcY + 47.571899); 1.618 + // Test preserve-3D. 1.619 + var p3dtcX = preserve3DTransformContainer.getBoundingClientRect().left; 1.620 + var p3dtcY = preserve3DTransformContainer.getBoundingClientRect().top; 1.621 + checkQuadIsRect("preserve3DTransformChild", {tolerance:0.01}, 1.622 + p3dtcX, p3dtcY, 200, 50, 1.623 + {tolerance:0.0001}); 1.624 + // Test mapping back into preserve-3D. 1.625 + checkQuadIsRect("d", {toStr:"preserve3DTransformChild",tolerance:0.01}, 1.626 + dX - p3dtcX, dY - p3dtcY, dW, dH); 1.627 + 1.628 + // Test SVG. 1.629 + var svgContainerX = svgContainer.getBoundingClientRect().left; 1.630 + var svgContainerY = svgContainer.getBoundingClientRect().top; 1.631 + checkQuadIsRect("circle", {}, 1.632 + svgContainerX + 30, svgContainerY + 30, 40, 40); 1.633 + // Box types are ignored for SVG elements. 1.634 + checkQuadIsRect("circle", {box:"content"}, 1.635 + svgContainerX + 30, svgContainerY + 30, 40, 40); 1.636 + checkQuadIsRect("circle", {box:"padding"}, 1.637 + svgContainerX + 30, svgContainerY + 30, 40, 40); 1.638 + checkQuadIsRect("circle", {box:"margin"}, 1.639 + svgContainerX + 30, svgContainerY + 30, 40, 40); 1.640 + checkQuadIsRect("d", {toStr:"circle"}, 1.641 + dX - (svgContainerX + 30), dY - (svgContainerY + 30), dW, dH); 1.642 + // Test foreignObject inside an SVG transform. 1.643 + checkQuadIsRect("foreign", {}, 1.644 + svgContainerX + 100, svgContainerY + 40, 200, 120); 1.645 + 1.646 + // XXX Test SVG text (probably broken; unclear what the best way is to handle it) 1.647 + 1.648 + // Test that converting between nodes in different toplevel browsing contexts 1.649 + // throws an exception. 1.650 + try { 1.651 + openedWindow = window.open("data:text/html,<div id='d'>",""); 1.652 + } catch (ex) { 1.653 + // in some cases we can't open the window. 1.654 + openedWindow = null; 1.655 + } 1.656 + if (openedWindow) { 1.657 + openedWindow.addEventListener("load", function() { 1.658 + checkException("openedWindow.d.getBoxQuads({relativeTo:document})", "NotFoundError"); 1.659 + checkException("document.getBoxQuads({relativeTo:openedWindow.d})", "NotFoundError"); 1.660 + checkException("openedWindow.d.convertPointFromNode(zeroPoint,document)", "NotFoundError"); 1.661 + checkException("document.convertPointFromNode(zeroPoint,openedWindow.d)", "NotFoundError"); 1.662 + checkException("openedWindow.d.convertRectFromNode(zeroRect,document)", "NotFoundError"); 1.663 + checkException("document.convertRectFromNode(zeroRect,openedWindow.d)", "NotFoundError"); 1.664 + checkException("openedWindow.d.convertQuadFromNode(zeroQuad,document)", "NotFoundError"); 1.665 + checkException("document.convertQuadFromNode(zeroQuad,openedWindow.d)", "NotFoundError"); 1.666 + openedWindow.close(); 1.667 + SimpleTest.finish(); 1.668 + }); 1.669 + } else { 1.670 + SimpleTest.finish(); 1.671 + } 1.672 +} 1.673 +</script> 1.674 +</body> 1.675 +</html>