dom/tests/mochitest/general/test_offsets.js

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

mercurial