dom/tests/mochitest/general/test_offsets.js

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 var scrollbarWidth = 17, scrollbarHeight = 17;
michael@0 2
michael@0 3 function testElements(baseid, callback)
michael@0 4 {
michael@0 5 scrollbarWidth = scrollbarHeight = gcs($("scrollbox-test"), "width");
michael@0 6
michael@0 7 var elements = $(baseid).getElementsByTagName("*");
michael@0 8 for (var t = 0; t < elements.length; t++) {
michael@0 9 var element = elements[t];
michael@0 10 testElement(element);
michael@0 11 }
michael@0 12
michael@0 13 var nonappended = document.createElement("div");
michael@0 14 nonappended.id = "nonappended";
michael@0 15 nonappended.setAttribute("_offsetParent", "null");
michael@0 16 testElement(nonappended);
michael@0 17
michael@0 18 checkScrolledElement($("scrollbox"), $("scrollchild"));
michael@0 19
michael@0 20 var div = $("noscroll");
michael@0 21 div.scrollLeft = 10;
michael@0 22 div.scrollTop = 10;
michael@0 23 is(element.scrollLeft, 0, element.id + " scrollLeft after nonscroll");
michael@0 24 is(element.scrollTop, 0, element.id + " scrollTop after nonscroll");
michael@0 25
michael@0 26 callback();
michael@0 27 }
michael@0 28
michael@0 29 function toNearestAppunit(v)
michael@0 30 {
michael@0 31 // 60 appunits per CSS pixel; round result to the nearest appunit
michael@0 32 return Math.round(v*60)/60;
michael@0 33 }
michael@0 34
michael@0 35 function isEqualAppunits(a, b, msg)
michael@0 36 {
michael@0 37 is(toNearestAppunit(a), toNearestAppunit(b), msg);
michael@0 38 }
michael@0 39
michael@0 40 function testElement(element)
michael@0 41 {
michael@0 42 var offsetParent = element.getAttribute("_offsetParent");
michael@0 43 offsetParent = $(offsetParent == "null" ? null: (offsetParent ? offsetParent : "body"));
michael@0 44
michael@0 45 var borderLeft = gcs(element, "borderLeftWidth");
michael@0 46 var borderTop = gcs(element, "borderTopWidth");
michael@0 47 var borderRight = gcs(element, "borderRightWidth");
michael@0 48 var borderBottom = gcs(element, "borderBottomWidth");
michael@0 49 var paddingLeft = gcs(element, "paddingLeft");
michael@0 50 var paddingTop = gcs(element, "paddingTop");
michael@0 51 var paddingRight = gcs(element, "paddingRight");
michael@0 52 var paddingBottom = gcs(element, "paddingBottom");
michael@0 53 var width = gcs(element, "width");
michael@0 54 var height = gcs(element, "height");
michael@0 55
michael@0 56 if (element instanceof HTMLElement)
michael@0 57 checkOffsetState(element, -10000, -10000,
michael@0 58 borderLeft + paddingLeft + width + paddingRight + borderRight,
michael@0 59 borderTop + paddingTop + height + paddingBottom + borderBottom,
michael@0 60 offsetParent, element.id);
michael@0 61
michael@0 62 var scrollWidth, scrollHeight, clientWidth, clientHeight;
michael@0 63 var doScrollCheck = true;
michael@0 64 if (element.id == "scrollbox") {
michael@0 65 var lastchild = $("lastline");
michael@0 66 scrollWidth = lastchild.getBoundingClientRect().width + paddingLeft + paddingRight;
michael@0 67 var top = element.firstChild.getBoundingClientRect().top;
michael@0 68 var bottom = element.lastChild.getBoundingClientRect().bottom;
michael@0 69 var contentsHeight = bottom - top;
michael@0 70 scrollHeight = contentsHeight + paddingTop + paddingBottom;
michael@0 71 clientWidth = paddingLeft + width + paddingRight - scrollbarWidth;
michael@0 72 clientHeight = paddingTop + height + paddingBottom - scrollbarHeight;
michael@0 73 } else {
michael@0 74 clientWidth = paddingLeft + width + paddingRight;
michael@0 75 clientHeight = paddingTop + height + paddingBottom;
michael@0 76 if (element.id == "overflow-visible") {
michael@0 77 scrollWidth = 200;
michael@0 78 scrollHeight = 201;
michael@0 79 } else if (element.scrollWidth > clientWidth ||
michael@0 80 element.scrollHeight > clientHeight) {
michael@0 81 // The element overflows. Don't check scrollWidth/scrollHeight since the
michael@0 82 // above calculation is not correct.
michael@0 83 doScrollCheck = false;
michael@0 84 } else {
michael@0 85 scrollWidth = clientWidth;
michael@0 86 scrollHeight = clientHeight;
michael@0 87 }
michael@0 88 }
michael@0 89
michael@0 90 if (doScrollCheck) {
michael@0 91 if (element instanceof SVGElement)
michael@0 92 checkScrollState(element, 0, 0, 0, 0, element.id);
michael@0 93 else
michael@0 94 checkScrollState(element, 0, 0, scrollWidth, scrollHeight, element.id);
michael@0 95 }
michael@0 96
michael@0 97 if (element instanceof SVGElement)
michael@0 98 checkClientState(element, 0, 0, 0, 0, element.id);
michael@0 99 else
michael@0 100 checkClientState(element, borderLeft, borderTop, clientWidth, clientHeight, element.id);
michael@0 101
michael@0 102 var boundingrect = element.getBoundingClientRect();
michael@0 103 isEqualAppunits(boundingrect.width, borderLeft + paddingLeft + width + paddingRight + borderRight,
michael@0 104 element.id + " bounding rect width");
michael@0 105 isEqualAppunits(boundingrect.height, borderTop + paddingTop + height + paddingBottom + borderBottom,
michael@0 106 element.id + " bounding rect height");
michael@0 107 isEqualAppunits(boundingrect.right - boundingrect.left, boundingrect.width,
michael@0 108 element.id + " bounding rect right");
michael@0 109 isEqualAppunits(boundingrect.bottom - boundingrect.top, boundingrect.height,
michael@0 110 element.id + " bounding rect bottom");
michael@0 111
michael@0 112 var rects = element.getClientRects();
michael@0 113 if (element.id == "div-displaynone" || element.id == "nonappended") {
michael@0 114 is(rects.length, 0, element.id + " getClientRects empty");
michael@0 115 }
michael@0 116 else {
michael@0 117 is(rects[0].left, boundingrect.left, element.id + " getClientRects left");
michael@0 118 is(rects[0].top, boundingrect.top, element.id + " getClientRects top");
michael@0 119 is(rects[0].right, boundingrect.right, element.id + " getClientRects right");
michael@0 120 is(rects[0].bottom, boundingrect.bottom, element.id + " getClientRects bottom");
michael@0 121 }
michael@0 122 }
michael@0 123
michael@0 124 function checkScrolledElement(element, child)
michael@0 125 {
michael@0 126 var elemrect = element.getBoundingClientRect();
michael@0 127 var childrect = child.getBoundingClientRect();
michael@0 128
michael@0 129 var topdiff = childrect.top - elemrect.top;
michael@0 130
michael@0 131 element.scrollTop = 20;
michael@0 132 is(element.scrollLeft, 0, element.id + " scrollLeft after vertical scroll");
michael@0 133 is(element.scrollTop, 20, element.id + " scrollTop after vertical scroll");
michael@0 134 // If the viewport has been transformed, then we might have scrolled to a subpixel value
michael@0 135 // that's slightly different from what we requested. After rounding, however, it should
michael@0 136 // be the same.
michael@0 137 is(Math.round(childrect.top - child.getBoundingClientRect().top), 20, "child position after vertical scroll");
michael@0 138
michael@0 139 element.scrollTop = 0;
michael@0 140 is(element.scrollLeft, 0, element.id + " scrollLeft after vertical scroll reset");
michael@0 141 is(element.scrollTop, 0, element.id + " scrollTop after vertical scroll reset");
michael@0 142 // Scrolling back to the top should work precisely.
michael@0 143 is(child.getBoundingClientRect().top, childrect.top, "child position after vertical scroll reset");
michael@0 144
michael@0 145 element.scrollTop = 10;
michael@0 146 element.scrollTop = -30;
michael@0 147 is(element.scrollLeft, 0, element.id + " scrollLeft after vertical scroll negative");
michael@0 148 is(element.scrollTop, 0, element.id + " scrollTop after vertical scroll negative");
michael@0 149 is(child.getBoundingClientRect().top, childrect.top, "child position after vertical scroll negative");
michael@0 150
michael@0 151 element.scrollLeft = 18;
michael@0 152 is(element.scrollLeft, 18, element.id + " scrollLeft after horizontal scroll");
michael@0 153 is(element.scrollTop, 0, element.id + " scrollTop after horizontal scroll");
michael@0 154 is(Math.round(childrect.left - child.getBoundingClientRect().left), 18, "child position after horizontal scroll");
michael@0 155
michael@0 156 element.scrollLeft = -30;
michael@0 157 is(element.scrollLeft, 0, element.id + " scrollLeft after horizontal scroll reset");
michael@0 158 is(element.scrollTop, 0, element.id + " scrollTop after horizontal scroll reset");
michael@0 159 is(child.getBoundingClientRect().left, childrect.left, "child position after horizontal scroll reset");
michael@0 160 }
michael@0 161
michael@0 162 function checkOffsetState(element, left, top, width, height, parent, testname)
michael@0 163 {
michael@0 164 checkCoords(element, "offset", left, top, width, height, testname);
michael@0 165 is(element.offsetParent, parent, testname + " offsetParent");
michael@0 166 }
michael@0 167
michael@0 168 function checkScrollState(element, left, top, width, height, testname)
michael@0 169 {
michael@0 170 checkCoords(element, "scroll", left, top, width, height, testname);
michael@0 171 }
michael@0 172
michael@0 173 function checkClientState(element, left, top, width, height, testname)
michael@0 174 {
michael@0 175 checkCoords(element, "client", left, top, width, height, testname);
michael@0 176 }
michael@0 177
michael@0 178 function checkCoord(element, type, val, testname)
michael@0 179 {
michael@0 180 if (val != -10000)
michael@0 181 is(element[type], Math.round(val), testname + " " + type);
michael@0 182 }
michael@0 183
michael@0 184 function checkCoords(element, type, left, top, width, height, testname)
michael@0 185 {
michael@0 186 checkCoord(element, type + "Left", left, testname);
michael@0 187 checkCoord(element, type + "Top", top, testname);
michael@0 188 checkCoord(element, type + "Width", width, testname);
michael@0 189 checkCoord(element, type + "Height", height, testname);
michael@0 190
michael@0 191 if (element instanceof SVGElement)
michael@0 192 return;
michael@0 193
michael@0 194 if (element.id == "outerpopup" && !element.parentNode.open) // closed popup
michael@0 195 return;
michael@0 196
michael@0 197 if (element.id == "div-displaynone" || element.id == "nonappended") // hidden elements
michael@0 198 ok(element[type + "Width"] == 0 && element[type + "Height"] == 0,
michael@0 199 element.id + " has zero " + type + " width and height");
michael@0 200 }
michael@0 201
michael@0 202 function gcs(element, prop)
michael@0 203 {
michael@0 204 var propVal = (element instanceof SVGElement && (prop == "width" || prop == "height")) ?
michael@0 205 element.getAttribute(prop) : getComputedStyle(element, "")[prop];
michael@0 206 if (propVal == "auto")
michael@0 207 return 0;
michael@0 208 return parseFloat(propVal);
michael@0 209 }

mercurial