content/base/test/test_range_bounds.html

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:abe87cd3b758
1 <!DOCTYPE HTML>
2 <html>
3 <!--
4 https://bugzilla.mozilla.org/show_bug.cgi?id=421640
5 -->
6 <head>
7 <title>Test for Bug 396392</title>
8 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
9 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
10 <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
11 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
12 </head>
13 <body>
14 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=396392">Mozilla Bug Range getClientRects and getBoundingClientRect</a>
15 <div id="content" style="font-family:monospace;font-size:12px;width:100px">
16 <p>000000<span>0</span></p><div>00000<span>0</span></div><p>0000<span>0000</span>0000</p><div><span>000000000000 00000000000000 000000</span></div><div>000000000000 00000000000003 100305</div>
17 </div>
18 <div id="mixeddir" style="font-family:monospace;font-size:12px;width:100px"><span>english <bdo id="bdo" dir="rtl">rtl-overide english</bdo> word</span></div>
19 <div id="mixeddir2" style="font-family:monospace;font-size:12px"><span>english <bdo id="bdo2" dir="rtl">rtl-override english</bdo> word</span></div>
20 <pre id="test">
21 <script class="testbody" type="text/javascript">
22
23 var isLTR=true;
24 function isEmptyRect(rect, name) {
25 name = (isLTR ? 'isLTR ' : 'isRTL ') + name;
26 is(rect.left, 0, name+'empty rect should have left = 0');
27 is(rect.right, 0, name+'empty rect should have right = 0');
28 is(rect.top, 0, name+'empty rect should have top = 0');
29 is(rect.bottom, 0, name+'empty rect should have bottom = 0');
30 is(rect.width, 0, name+'empty rect should have width = 0');
31 is(rect.height, 0, name+'empty rect should have height = 0');
32 }
33
34 function isEmptyRectList(rectlist, name) {
35 name = (isLTR ? 'isLTR ' : 'isRTL ') + name;
36 is(rectlist.length, 0, name + 'empty rectlist should have zero rects');
37 }
38
39 // round coordinates to the nearest 1/256 of a pixel
40 function roundCoord(x) {
41 return Math.round(x * 256) / 256;
42 }
43
44 function _getRect(r) {
45 if (r.length) //array
46 return "{left:"+roundCoord(r[0])+",right:"+roundCoord(r[1])+
47 ",top:" +roundCoord(r[2])+",bottom:"+roundCoord(r[3])+
48 ",width:"+roundCoord(r[4])+",height:"+roundCoord(r[5])+"}";
49 else
50 return "{left:"+roundCoord(r.left)+",right:"+roundCoord(r.right)+
51 ",top:"+roundCoord(r.top)+",bottom:"+roundCoord(r.bottom)+
52 ",width:"+roundCoord(r.width)+",height:"+roundCoord(r.height)+"}";
53 }
54
55 function runATest(obj) {
56 var range = document.createRange();
57 try {
58 range.setStart(obj.range[0],obj.range[1]);
59 if (obj.range.length>2) {
60 range.setEnd(obj.range[2]||obj.range[0], obj.range[3]);
61 }
62 //test getBoundingClientRect()
63 var rect = range.getBoundingClientRect();
64 var testname = (isLTR ? 'isLTR ' : 'isRTL ') +
65 'range.getBoundingClientRect for ' + obj.name;
66 if (obj.rect) {
67 is(_getRect(rect),_getRect(obj.rect), testname);
68 } else {
69 isEmptyRect(rect,testname+": ");
70 }
71 //test getClientRects()
72 var rectlist = range.getClientRects();
73 testname = (isLTR ? 'isLTR ' : 'isRTL ') +
74 'range.getClientRects for '+obj.name;
75 if (!obj.rectList) {
76 //rectList is not specified, use obj.rect to figure out rectList
77 obj.rectList = obj.rect?[obj.rect]:[];
78 }
79 if (!obj.rectList.length) {
80 isEmptyRectList(rectlist, testname+": ");
81 } else {
82 is(rectlist.length, obj.rectList.length, testname+' should return '+obj.rectList.length+' rects.');
83 if(!obj.rectList.forEach){
84 //convert RectList to a real array
85 obj.rectList=Array.prototype.slice.call(obj.rectList, 0);
86 }
87 obj.rectList.forEach(function(rect,i) {
88 is(_getRect(rectlist[i]),_getRect(rect),testname+": item at "+i);
89 });
90 }
91 } finally {
92 range.detach();
93 }
94 }
95 /** Test for Bug 396392 **/
96 function doTest(){
97 var root = document.getElementById('content');
98 var firstP = root.firstElementChild, spanInFirstP = firstP.childNodes[1],
99 firstDiv = root.childNodes[2], spanInFirstDiv = firstDiv.childNodes[1],
100 secondP = root.childNodes[3], spanInSecondP = secondP.childNodes[1],
101 secondDiv = root.childNodes[4], spanInSecondDiv = secondDiv.firstChild,
102 thirdDiv = root.childNodes[5];
103 var firstPRect = firstP.getBoundingClientRect(),
104 spanInFirstPRect = spanInFirstP.getBoundingClientRect(),
105 firstDivRect = firstDiv.getBoundingClientRect(),
106 spanInFirstDivRect = spanInFirstDiv.getBoundingClientRect(),
107 secondPRect = secondP.getBoundingClientRect(),
108 secondDivRect = secondDiv.getBoundingClientRect(),
109 spanInSecondPRect = spanInSecondP.getBoundingClientRect(),
110 spanInSecondDivRect = spanInSecondDiv.getBoundingClientRect(),
111 spanInSecondDivRectList = spanInSecondDiv.getClientRects();
112 var widthPerchar = spanInSecondPRect.width / spanInSecondP.firstChild.length;
113 var testcases = [
114 {name:'nodesNotInDocument', range:[document.createTextNode('abc'), 1],
115 rect:null},
116 {name:'collapsedInBlockNode', range:[firstP, 2], rect:null},
117 {name:'collapsedAtBeginningOfTextNode', range:[firstP.firstChild, 0],
118 rect:[spanInFirstPRect.left - 6 * widthPerchar,
119 spanInFirstPRect.left - 6 * widthPerchar, spanInFirstPRect.top,
120 spanInFirstPRect.bottom, 0, spanInFirstPRect.height]},
121 {name:'collapsedWithinTextNode', range:[firstP.firstChild, 1],
122 rect:[spanInFirstPRect.left - 5 * widthPerchar,
123 spanInFirstPRect.left - 5 * widthPerchar,
124 spanInFirstPRect.top, spanInFirstPRect.bottom, 0, spanInFirstPRect.height]},
125 {name:'collapsedAtEndOfTextNode', range:[firstP.firstChild, 6],
126 rect:[spanInFirstPRect.left, spanInFirstPRect.left,
127 spanInFirstPRect.top, spanInFirstPRect.bottom, 0, spanInFirstPRect.height]},
128 {name:'singleBlockNode', range:[root, 1, root, 2], rect:firstPRect},
129 {name:'twoBlockNodes', range:[root, 1, root, 3],
130 rect:[firstPRect.left, firstPRect.right, firstPRect.top,
131 firstDivRect.bottom, firstPRect.width,
132 firstDivRect.bottom - firstPRect.top],
133 rectList:[firstPRect, firstDivRect]},
134 {name:'endOfTextNodeToEndOfAnotherTextNodeInAnotherBlock',
135 range:[spanInFirstP.firstChild, 1, firstDiv.firstChild, 5],
136 rect:[spanInFirstDivRect.left - 5*widthPerchar, spanInFirstDivRect.left,
137 spanInFirstDivRect.top, spanInFirstDivRect.bottom, 5 * widthPerchar,
138 spanInFirstDivRect.height]},
139 {name:'startOfTextNodeToStartOfAnotherTextNodeInAnotherBlock',
140 range:[spanInFirstP.firstChild, 0, firstDiv.firstChild, 0],
141 rect:[spanInFirstPRect.left, spanInFirstPRect.left + widthPerchar, spanInFirstPRect.top,
142 spanInFirstPRect.bottom, widthPerchar, spanInFirstPRect.height]},
143 {name:'endPortionOfATextNode', range:[firstP.firstChild, 3,
144 firstP.firstChild, 6],
145 rect:[spanInFirstPRect.left - 3*widthPerchar, spanInFirstPRect.left,
146 spanInFirstPRect.top, spanInFirstPRect.bottom, 3*widthPerchar, spanInFirstPRect.height]},
147 {name:'startPortionOfATextNode', range:[firstP.firstChild, 0,
148 firstP.firstChild, 3],
149 rect:[spanInFirstPRect.left - 6*widthPerchar,
150 spanInFirstPRect.left - 3*widthPerchar, spanInFirstPRect.top,
151 spanInFirstPRect.bottom, 3 * widthPerchar, spanInFirstPRect.height]},
152 {name:'spanTextNodes', range:[secondP.firstChild, 1, secondP.lastChild, 1],
153 rect:[spanInSecondPRect.left - 3*widthPerchar, spanInSecondPRect.right +
154 widthPerchar, spanInSecondPRect.top, spanInSecondPRect.bottom,
155 spanInSecondPRect.width + 4*widthPerchar, spanInSecondPRect.height],
156 rectList:[[spanInSecondPRect.left - 3*widthPerchar, spanInSecondPRect.left,
157 spanInSecondPRect.top, spanInSecondPRect.bottom, 3 * widthPerchar,
158 spanInSecondPRect.height],
159 spanInSecondPRect,
160 [spanInSecondPRect.right, spanInSecondPRect.right + widthPerchar,
161 spanInSecondPRect.top, spanInSecondPRect.bottom, widthPerchar,
162 spanInSecondPRect.height]]}
163 ];
164 testcases.forEach(runATest);
165
166 // testcases that have different ranges in LTR and RTL
167 var directionDependentTestcases;
168 if (isLTR) {
169 directionDependentTestcases = [
170 {name:'spanAcrossLines',range:[spanInSecondDiv.firstChild, 1, spanInSecondDiv.firstChild, 30],
171 rect: spanInSecondDivRect,
172 rectList:[[spanInSecondDivRectList[0].left+widthPerchar,
173 spanInSecondDivRectList[0].right, spanInSecondDivRectList[0].top,
174 spanInSecondDivRectList[0].bottom, spanInSecondDivRectList[0].width - widthPerchar,
175 spanInSecondDivRectList[0].height],
176 spanInSecondDivRectList[1],
177 [spanInSecondDivRectList[2].left,
178 spanInSecondDivRectList[2].right - 4 * widthPerchar, spanInSecondDivRectList[2].top,
179 spanInSecondDivRectList[2].bottom,
180 spanInSecondDivRectList[2].width - 4 * widthPerchar,
181 spanInSecondDivRectList[2].height]]},
182 {name:'textAcrossLines',range:[thirdDiv.firstChild, 13, thirdDiv.firstChild, 28],
183 rect: [spanInSecondDivRectList[1].left, spanInSecondDivRectList[1].right,
184 spanInSecondDivRectList[1].top + secondDivRect.height,
185 spanInSecondDivRectList[1].bottom + secondDivRect.height,
186 spanInSecondDivRectList[1].width, spanInSecondDivRectList[1].height]}
187 ];
188 } else {
189 directionDependentTestcases = [
190 {name:'spanAcrossLines',range:[spanInSecondDiv.firstChild, 1, spanInSecondDiv.firstChild, 30],
191 rect: spanInSecondDivRect,
192 rectList:[[spanInSecondDivRectList[0].left+widthPerchar,
193 spanInSecondDivRectList[0].right, spanInSecondDivRectList[0].top,
194 spanInSecondDivRectList[0].bottom, spanInSecondDivRectList[0].width - widthPerchar,
195 spanInSecondDivRectList[0].height],
196 spanInSecondDivRectList[1],
197 spanInSecondDivRectList[2],
198 spanInSecondDivRectList[3],
199 [spanInSecondDivRectList[4].left,
200 spanInSecondDivRectList[4].right - 4 * widthPerchar,
201 spanInSecondDivRectList[4].top,
202 spanInSecondDivRectList[4].bottom,
203 spanInSecondDivRectList[4].width - 4 * widthPerchar,
204 spanInSecondDivRectList[4].height]]},
205 {name:'textAcrossLines',range:[thirdDiv.firstChild, 13, thirdDiv.firstChild, 28],
206 rect: [spanInSecondDivRectList[2].left, spanInSecondDivRectList[2].right,
207 spanInSecondDivRectList[2].top + secondDivRect.height,
208 spanInSecondDivRectList[2].bottom + secondDivRect.height,
209 spanInSecondDivRectList[2].width, spanInSecondDivRectList[2].height],
210 rectList:[[spanInSecondDivRectList[2].left, spanInSecondDivRectList[2].right,
211 spanInSecondDivRectList[2].top + secondDivRect.height,
212 spanInSecondDivRectList[2].bottom + secondDivRect.height,
213 spanInSecondDivRectList[2].width, spanInSecondDivRectList[2].height],
214 [spanInSecondDivRectList[2].left, spanInSecondDivRectList[2].left,
215 spanInSecondDivRectList[2].top + secondDivRect.height,
216 spanInSecondDivRectList[2].bottom + secondDivRect.height,
217 0, spanInSecondDivRectList[2].height]]}
218 ];
219 }
220 directionDependentTestcases.forEach(runATest);
221 }
222 function testMixedDir(){
223 var root = document.getElementById('mixeddir');
224 var firstSpan = root.firstElementChild, firstSpanRect=firstSpan.getBoundingClientRect(),
225 firstSpanRectList = firstSpan.getClientRects();
226 runATest({name:'mixeddir',range:[firstSpan.firstChild,0,firstSpan.lastChild,firstSpan.lastChild.length],
227 rect: firstSpanRect, rectList:firstSpanRectList});
228
229 root = document.getElementById('mixeddir2');
230 firstSpan = root.firstElementChild;
231 firstSpanRect = firstSpan.getBoundingClientRect();
232 bdo = document.getElementById('bdo2');
233 bdoRect=bdo.getBoundingClientRect();
234 var widthPerChar = bdoRect.width / bdo.firstChild.length;
235 runATest({name:'mixeddirPartial', range:[firstSpan.firstChild, 3,
236 bdo.firstChild, 7],
237 rect: [firstSpanRect.left + 3*widthPerChar, bdoRect.right,
238 bdoRect.top, bdoRect.bottom,
239 (firstSpan.firstChild.length + bdo.firstChild.length - 3) *
240 widthPerChar,
241 bdoRect.height],
242 rectList:[[firstSpanRect.left + 3*widthPerChar,
243 bdoRect.left,
244 firstSpanRect.top, firstSpanRect.bottom,
245 (firstSpan.firstChild.length - 3) * widthPerChar,
246 firstSpanRect.height],
247 [bdoRect.right - 7 * widthPerChar, bdoRect.right,
248 bdoRect.top, bdoRect.bottom,
249 7*widthPerChar, bdoRect.height]]});
250 }
251 function test(){
252 //test ltr
253 doTest();
254 testMixedDir();
255
256 isLTR = false;
257 var root = document.getElementById('content');
258 root.dir = 'rtl';
259
260 //test rtl
261 doTest();
262 testMixedDir();
263
264 SimpleTest.finish();
265 }
266
267 window.onload = function() {
268 SimpleTest.waitForExplicitFinish();
269 setTimeout(test, 0);
270 };
271
272 </script>
273 </pre>
274 </body>
275 </html>

mercurial