1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" |
---|
2 | "http://www.w3.org/TR/html4/strict.dtd"> |
---|
3 | <html style="overflow-y:scroll;border:0px none;padding:0;margin:0;"> |
---|
4 | <head> |
---|
5 | <title>dojo.window.scrollIntoView Test</title> |
---|
6 | |
---|
7 | <style type="text/css"> |
---|
8 | @import "../../resources/dojo.css"; |
---|
9 | FIELDSET { border:2px groove black; display:inline; padding:2px; } |
---|
10 | FIELDSET IFRAME { width:100px; height:100px; } |
---|
11 | </style> |
---|
12 | <script type="text/javascript" src="../../dojo.js" |
---|
13 | data-dojo-config="isDebug: true"></script> |
---|
14 | |
---|
15 | <script type="text/javascript"> |
---|
16 | // Global methods accessed by iframes |
---|
17 | var count, loading; |
---|
18 | function initIframeMethods(iframeWin, parentWin){ |
---|
19 | iframeWin.frameElement.findInput = function(){ return parentWin._findInput(iframeWin); }; |
---|
20 | iframeWin.frameElement.scrollMin = function(n){ parentWin._scroll(iframeWin,true,n); }; |
---|
21 | iframeWin.frameElement.scrollMax = function(n){ parentWin._scroll(iframeWin,false,n); }; |
---|
22 | iframeWin.frameElement.getBoundingRect = function(n){ return parentWin._getBoundingRect(iframeWin, n); }; |
---|
23 | iframeWin.frameElement.getVisibleSize = function(n){ return parentWin._getVisibleSize(iframeWin, n); }; |
---|
24 | iframeWin.frameElement.scrollIntoView = function(x,y,w,h){ parentWin._scrollIntoView(iframeWin,x,y,w,h); }; |
---|
25 | iframeWin.frameElement.onClick = function(e){ parentWin._onClick(iframeWin);return false; }; |
---|
26 | } |
---|
27 | |
---|
28 | function _findInput(win){ |
---|
29 | return win.document.getElementById('it'); |
---|
30 | } |
---|
31 | |
---|
32 | function _getBoundingRect(win, n){ |
---|
33 | var r = n.getBoundingClientRect(); |
---|
34 | return { left: r.left, right: r.right, top: r.top, bottom: r.bottom, w: Math.round(r.right - r.left), h: Math.round(r.bottom - r.top) }; |
---|
35 | } |
---|
36 | |
---|
37 | function _scroll(win,isMin,n){ |
---|
38 | while(n && n.tagName){ |
---|
39 | n.scrollTop = isMin ? -9999 : 9999; |
---|
40 | n.scrollLeft = isMin ? -9999 : 9999; |
---|
41 | if(n.tagName == "BODY" && (n.scrollLeft || n.scrollTop)){ |
---|
42 | break; // skip HTML |
---|
43 | } |
---|
44 | n = n.parentNode; |
---|
45 | } |
---|
46 | } |
---|
47 | |
---|
48 | var loaded = {}; |
---|
49 | function iframeLoaded(id){ |
---|
50 | if(!loaded[id]){ // ignore duplicate notifications |
---|
51 | loaded[id] = true; |
---|
52 | if(--count == 0){ loading.callback(true); } |
---|
53 | } |
---|
54 | } |
---|
55 | |
---|
56 | require([ |
---|
57 | "doh", |
---|
58 | "dojo/dom", "dojo/dom-attr", "dojo/dom-geometry", "dojo/dom-style", |
---|
59 | "dojo/query", "dojo/sniff", "dojo/_base/window", "dojo/window", "dojo/_base/array", "dojo/domReady!" |
---|
60 | ], function(doh, dom, domAttr, domGeom, domStyle, query, has, baseWin, winUtils, array) { |
---|
61 | |
---|
62 | // More global methods accessed by iframes |
---|
63 | _scrollIntoView = function(win,x,y,w,h){ |
---|
64 | var n = _findInput(win); |
---|
65 | var pos; |
---|
66 | if(typeof x == "number" && typeof y == "number"){ |
---|
67 | var p = baseWin.withGlobal(win, 'position', domGeom, [ n ]); |
---|
68 | pos = { x: p.x + x, y: p.y + y, w: isNaN(w) ? 1 : w, h: isNaN(h) ? 1 : h }; |
---|
69 | } |
---|
70 | baseWin.withGlobal(win, 'scrollIntoView', winUtils, [ n, pos ]); |
---|
71 | }; |
---|
72 | _onClick = function(win){ |
---|
73 | _scrollIntoView(win); |
---|
74 | }; |
---|
75 | |
---|
76 | _getVisibleSize = function(win,n){ |
---|
77 | var html = win.document.documentElement, |
---|
78 | body = win.document.body, |
---|
79 | rect = n.getBoundingClientRect(), |
---|
80 | width = Math.min(body.clientWidth || html.clientWidth, html.clientWidth || body.clientWidth), |
---|
81 | height = Math.min(body.clientHeight || html.clientHeight, html.clientHeight || body.clientHeight), |
---|
82 | pos = baseWin.withGlobal(win, 'position', domGeom, [ n ]); |
---|
83 | // adjust width and height for IE nonsense |
---|
84 | width += Math.round(rect.left - pos.x); |
---|
85 | height += Math.round(rect.top - pos.y); |
---|
86 | if(has('ie')){ width += outerScrollBarSize; } // IE10 bug |
---|
87 | for(y = 0; y < height; y++){ |
---|
88 | for(x = 0; x < width; x++){ |
---|
89 | var pointElement = win.document.elementFromPoint(x,y); |
---|
90 | if(pointElement == n){ |
---|
91 | // work around browser bugs |
---|
92 | // Opera 12.12 says the element is showing beyond the browser edge |
---|
93 | // IE 10 says` |
---|
94 | for(var w = 1; (x+w) < width && win.document.elementFromPoint(x+w,y) == n; w++); |
---|
95 | for(var h = 1; (y+h) < height && win.document.elementFromPoint(x,y+h) == n; h++); |
---|
96 | return { w: w, h: h }; |
---|
97 | } |
---|
98 | } |
---|
99 | } |
---|
100 | return { w: 0, h: 0 }; |
---|
101 | }; |
---|
102 | |
---|
103 | |
---|
104 | // Below is the magic code that creates the iframes from the given template. |
---|
105 | // This should be generalized for other files to include. |
---|
106 | |
---|
107 | function getIframeSrc(id, content, doctype, rtl){ |
---|
108 | content = content.replace(/"/g/*balance"*/,"'").replace(/iframe.javascript/g,"text/javascript").replace(/<input\b/ig,"<INPUT disabled "); |
---|
109 | var iframeSrc = 'javascript:"'; |
---|
110 | // find browser specific CSS attributes |
---|
111 | if(has("ie")){ |
---|
112 | content = content.replace(/IE([A-Z]_)/g, "$1"); |
---|
113 | }else if(has("webkit")){ |
---|
114 | content = content.replace(/WK([A-Z]_)/g, "$1"); |
---|
115 | }else if(has("mozilla")){ |
---|
116 | content = content.replace(/MZ([A-Z]_)/g, "$1"); |
---|
117 | }else if(has("opera")){ |
---|
118 | content = content.replace(/OP([A-Z]_)/g, "$1"); |
---|
119 | } |
---|
120 | // find DOCTYPE specific CSS attributes |
---|
121 | if(doctype=="strict"){ |
---|
122 | iframeSrc += "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>\n"; |
---|
123 | content = content.replace(/[A-Z0-9_]*(\b|_)[SZ]_[A-Z0-9_]*/g, ""); |
---|
124 | }else if(doctype=="loose"){ |
---|
125 | iframeSrc += "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>\n"; |
---|
126 | content = content.replace(/[A-Z0-9_]*(\b|_)[TZ]_[A-Z0-9_]*/g, ""); |
---|
127 | }else{ |
---|
128 | if(has("webkit")){ |
---|
129 | iframeSrc += "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>\n"; // quirks: needed for WebKit's javascript: protocol |
---|
130 | } |
---|
131 | content = content.replace(/[A-Z0-9_]*(\b|_)[QZ]_[A-Z0-9_]*/g, ""); |
---|
132 | } |
---|
133 | if(rtl){ |
---|
134 | content = content.replace(/[A-Z0-9_]*(\b|_)R_[A-Z0-9_]*/g, ""); |
---|
135 | }else{ |
---|
136 | content = content.replace(/[A-Z0-9_]*(\b|_)L_[A-Z0-9_]*/g, ""); |
---|
137 | } |
---|
138 | content = content.replace(/\s*<(\/?)iframestyle>\s*/ig,"<$1"+"STYLE>"); |
---|
139 | var i = content.indexOf('<STYLE>'); |
---|
140 | var style = ''; |
---|
141 | if(i >= 0){ |
---|
142 | var j = content.indexOf('</STYLE>'); |
---|
143 | if(j >= 0){ |
---|
144 | style = content.substring(i+7, j); |
---|
145 | content = content.substr(j+8); |
---|
146 | } |
---|
147 | } |
---|
148 | iframeSrc += |
---|
149 | '<HTML dir='+(rtl?'rtl':'ltr')+'>'+ |
---|
150 | '<HEAD>'+ |
---|
151 | '<STYLE>'+ |
---|
152 | '* { border:0px solid white;padding:0px;margin:0px;font-style:normal;font-family:monospace;font-size:0px;line-height:normal; }\n'+ |
---|
153 | 'INPUT { display:block;background-color:red;font-size:0px;line-height:0px;overflow:hidden;width:20px;height:20px; }\n'+ |
---|
154 | 'UL { list-style-type: none;line-height:0px;width:45px;overflow:auto; }\n'+ |
---|
155 | 'LI { list-style-type: none;line-height:20px;overflow:visible;max-width:20px;max-height:20px;height:20px;width:20px;float:left; }\n'+ |
---|
156 | 'HR { width:120px;height:1px;visibility:hidden;display:block; }\n'+ |
---|
157 | style+ |
---|
158 | '<\/STYLE>'+ |
---|
159 | '<\/HEAD>'+ |
---|
160 | '<BODY BGCOLOR=#ffffff>'+ |
---|
161 | content+ |
---|
162 | '<SCRIPT type=text/javascript>'+ |
---|
163 | 'win=frameElement.ownerDocument.defaultView||frameElement.document.parentWindow;'+ |
---|
164 | 'win.initIframeMethods(window, win);'+ |
---|
165 | 'win.iframeLoaded(\'' + id + "-" + doctype + "-" + (rtl ?'rtl':'ltr') + '\');'+ |
---|
166 | 'document.body.onclick=frameElement.onClick;'+ |
---|
167 | '<\/SCRIPT>'+ |
---|
168 | '<\/BODY>'+ |
---|
169 | '<\/HTML>"'; |
---|
170 | return iframeSrc; |
---|
171 | } |
---|
172 | |
---|
173 | function makeIframe(id, className, style, content, doctype, rtl, srcNode){ |
---|
174 | var iframeSrc = getIframeSrc(id, content, doctype, rtl); |
---|
175 | var container = document.createElement('fieldset'); |
---|
176 | var text = (doctype=="strict"? 'strict': (doctype=="loose"? 'loose' : 'quirks')) + (rtl? ' RTL' : ''); |
---|
177 | var color = (rtl? 'medium': '') + (doctype=="strict"? 'SpringGreen': (doctype=="loose"? 'Turquoise' : 'Aquamarine')); |
---|
178 | var idSuffix = (doctype=="strict"? '_strict': (doctype=="loose"? '_loose': '_quirks')) + (rtl? '_rtl' : ''); |
---|
179 | domStyle.set(container, "cssText", "display:inline;border:1px ridge gray;padding:0px;margin:0px;background-color:"+color+";text-align:"+(rtl?"right;":"left;")); |
---|
180 | container.appendChild(document.createTextNode(text)); |
---|
181 | var iframe = document.createElement('iframe'); |
---|
182 | iframe.setAttribute('src', iframeSrc); |
---|
183 | iframe.setAttribute('frameBorder', "0"); |
---|
184 | iframe.setAttribute('scrolling', "auto"); |
---|
185 | iframe.setAttribute('allowTransparency', "true"); |
---|
186 | iframe.setAttribute('id', id + idSuffix); |
---|
187 | iframe.setAttribute('name', id + idSuffix); |
---|
188 | iframe.className = className; |
---|
189 | domStyle.set(iframe, "cssText", "visibility:hidden;display:block;border:2px solid "+color+";background-color:transparent;margin:0px;padding:3px;"+style); |
---|
190 | container.appendChild(iframe); |
---|
191 | srcNode.appendChild(container); |
---|
192 | var src = iframe.getAttribute("src"); |
---|
193 | if(!src || src.indexOf("javascript") == -1){ |
---|
194 | // set it again if it didn't stick the first time: esp. older Opera and WebKit |
---|
195 | setTimeout(function(){ iframe.setAttribute('src', iframeSrc); }, 0); |
---|
196 | } |
---|
197 | } |
---|
198 | |
---|
199 | var innerScrollBarSize = Math.ceil(dom.byId("nonscroll").clientWidth - dom.byId("withscroll").clientWidth); |
---|
200 | console.debug('inner scrollbar size = ' + innerScrollBarSize); |
---|
201 | var outerScrollBarSize = Math.ceil((has("ie") >= 9) ? ((domGeom.position(document.documentElement).w - document.documentElement.clientWidth) || innerScrollBarSize) : innerScrollBarSize); |
---|
202 | console.debug('outer scrollbar size = ' + outerScrollBarSize); |
---|
203 | |
---|
204 | doh.register("dojo.window.scroll",[ |
---|
205 | { |
---|
206 | name: "create iframes and wait for them to load", |
---|
207 | timeout: 20000, |
---|
208 | runTest: function(){ |
---|
209 | loading = new doh.Deferred(); |
---|
210 | var testIframes = query('DIV[type="testIframe"]'); |
---|
211 | count = testIframes.length * 4; |
---|
212 | console.log("count is " + count); |
---|
213 | // have to do all the iframes at once so the iPad doesn't resize and cause problems |
---|
214 | for(var i=0; i < testIframes.length; i++){ |
---|
215 | var srcNode = testIframes[i]; |
---|
216 | var content = srcNode.innerHTML || ''; |
---|
217 | var id = srcNode.id || ""; |
---|
218 | var style = srcNode.getAttribute('style') || ""; |
---|
219 | var className = srcNode.getAttribute('class') || srcNode.className || ""; |
---|
220 | if(typeof style == "object"){ |
---|
221 | style = style.cssText || ""; |
---|
222 | } |
---|
223 | srcNode.innerHTML = ""; |
---|
224 | srcNode.removeAttribute('style'); |
---|
225 | srcNode.className = ""; |
---|
226 | |
---|
227 | makeIframe(id, className, style, content, "strict", false, srcNode); |
---|
228 | makeIframe(id, className, style, content, "quirks", false, srcNode); |
---|
229 | makeIframe(id, className, style, content, "loose", true, srcNode); |
---|
230 | makeIframe(id, className, style, content, "quirks", true, srcNode); |
---|
231 | } |
---|
232 | return loading; |
---|
233 | } |
---|
234 | }, |
---|
235 | function checkAttrs(){ |
---|
236 | var body = baseWin.body(); |
---|
237 | winUtils.scrollIntoView(body); |
---|
238 | doh.f(domAttr.has(body,'_offsetParent')); |
---|
239 | doh.f(domAttr.has(body,'_parent')); |
---|
240 | } |
---|
241 | ]); |
---|
242 | array.forEach([ '8249', |
---|
243 | '8284', |
---|
244 | 'absContent', |
---|
245 | 'fixedNode', |
---|
246 | 'fixedScrollable', |
---|
247 | '7036_8665', |
---|
248 | 'innerNoScrollBars', |
---|
249 | 'noScrollBars', |
---|
250 | 'table', |
---|
251 | 'innerScrollbars', |
---|
252 | '8542', |
---|
253 | 'tooBig', |
---|
254 | 'htmlPadding' ], |
---|
255 | function(test){ |
---|
256 | array.forEach([ "_strict", "_quirks", "_loose_rtl", "_quirks_rtl" ], |
---|
257 | function(mode){ |
---|
258 | var id = test+mode, |
---|
259 | n, maxWidth, maxHeight, nodeWidth, nodeHeight, rAfterScroll, vAfterScroll, rBeforeScroll, vBeforeScroll; |
---|
260 | doh.register(id, [ |
---|
261 | { |
---|
262 | timeout: 4000, |
---|
263 | name: "compare to native", |
---|
264 | runTest: function(){ with(dom.byId(id)){ |
---|
265 | n = findInput(); |
---|
266 | scrollMin(n); |
---|
267 | var d = new doh.Deferred(); |
---|
268 | setTimeout(function(){ |
---|
269 | rBeforeScroll = getBoundingRect(n); |
---|
270 | vBeforeScroll = getVisibleSize(n); |
---|
271 | nodeWidth = rBeforeScroll.w; |
---|
272 | nodeHeight = rBeforeScroll.h; |
---|
273 | dom.byId(id).style.visibility = 'visible'; |
---|
274 | n.scrollIntoView(true); |
---|
275 | setTimeout(function(){ |
---|
276 | var vAfterNativeScroll = getVisibleSize(n); |
---|
277 | scrollIntoView(); |
---|
278 | setTimeout(d.getTestCallback(function(){ |
---|
279 | vAfterScroll = getVisibleSize(n); |
---|
280 | doh.t(vAfterScroll.w > 0, "min width " + vAfterScroll.w); |
---|
281 | doh.t(vAfterScroll.h > 0, "min height " + vAfterScroll.h); |
---|
282 | doh.t(vAfterScroll.w >= vAfterNativeScroll.w, "width compare " + vAfterNativeScroll.w + " to " + vAfterScroll.w); |
---|
283 | doh.t(vAfterScroll.h >= vAfterNativeScroll.h, "height compare " + vAfterNativeScroll.h + " to " + vAfterScroll.h); |
---|
284 | maxWidth = Math.max(vAfterNativeScroll.w, vAfterScroll.w); |
---|
285 | maxHeight = Math.max(vAfterNativeScroll.h, vAfterScroll.h); |
---|
286 | }), 0); |
---|
287 | }, 0); |
---|
288 | }, 0); |
---|
289 | return d; |
---|
290 | }} |
---|
291 | }, |
---|
292 | { |
---|
293 | timeout: 4000, |
---|
294 | name: "min start horizontal", |
---|
295 | runTest: function(){ with(dom.byId(id)){ |
---|
296 | scrollMin(n); |
---|
297 | var d = new doh.Deferred(); |
---|
298 | setTimeout(function(){ |
---|
299 | scrollIntoView(1,0); |
---|
300 | setTimeout(function(){ |
---|
301 | rAfterScroll = getBoundingRect(n); |
---|
302 | vAfterScroll = getVisibleSize(n); |
---|
303 | if(rAfterScroll.left > rBeforeScroll.left){ // shifted right so all but leftmost pixel on first row is showing |
---|
304 | scrollIntoView(0,0); |
---|
305 | setTimeout(d.getTestCallback(function(){ |
---|
306 | doh.is(nodeWidth > maxWidth ? maxWidth : (maxWidth-1), vAfterScroll.w, "min: start: shift right partial width"); |
---|
307 | vAfterScroll = getVisibleSize(n); |
---|
308 | doh.is(vAfterScroll.w, maxWidth, "min: start: shift right full width"); |
---|
309 | }), 0); |
---|
310 | }else if(rAfterScroll.left < rBeforeScroll.left){ // shifted left so only 2 leftmost pixels on first row are showing |
---|
311 | scrollIntoView(nodeWidth-1,0); |
---|
312 | setTimeout(d.getTestCallback(function(){ |
---|
313 | doh.is(2, vAfterScroll.w, "min: start: shift left width"); |
---|
314 | vAfterScroll = getVisibleSize(n); |
---|
315 | doh.is(vAfterScroll.w, maxWidth, "min: start: shift left full width"); |
---|
316 | }), 0); |
---|
317 | }else{ // no horizontal scrolling |
---|
318 | scrollIntoView(0,0,nodeWidth); |
---|
319 | setTimeout(d.getTestCallback(function(){ |
---|
320 | vAfterScroll = getVisibleSize(n); |
---|
321 | doh.is(maxWidth, vAfterScroll.w, "min: start: no shift full width"); |
---|
322 | }), 0); |
---|
323 | } |
---|
324 | }, 0); |
---|
325 | }, 0); |
---|
326 | return d; |
---|
327 | }} |
---|
328 | }, |
---|
329 | { |
---|
330 | timeout: 2000, |
---|
331 | name: "min start vertical", |
---|
332 | runTest: function(){ with(dom.byId(id)){ |
---|
333 | var d = new doh.Deferred(); |
---|
334 | if(rAfterScroll.top > rBeforeScroll.top){ // shifted down so all rows are showing |
---|
335 | scrollIntoView(1,nodeHeight-1); |
---|
336 | setTimeout(d.getTestCallback(function(){ |
---|
337 | doh.is(vAfterScroll.h, maxHeight, "min: start: shift down height"); |
---|
338 | vAfterScroll = getVisibleSize(n); |
---|
339 | doh.is(vAfterScroll.h, maxHeight, "min: start: shift down full height"); |
---|
340 | }), 0); |
---|
341 | }else if(rAfterScroll.top < rBeforeScroll.top){ // shifted up so only the first row is showing |
---|
342 | scrollIntoView(0,nodeHeight-1); |
---|
343 | setTimeout(d.getTestCallback(function(){ |
---|
344 | doh.is(1, vAfterScroll.h, "min: start: shift up height"); |
---|
345 | vAfterScroll = getVisibleSize(n); |
---|
346 | doh.is(vAfterScroll.h, maxHeight, "min: start: shift up full height"); |
---|
347 | }), 0); |
---|
348 | }else{ // no vertical scrolling |
---|
349 | scrollIntoView(0,nodeHeight-1); |
---|
350 | setTimeout(d.getTestCallback(function(){ |
---|
351 | vAfterScroll = getVisibleSize(n); |
---|
352 | doh.is(vAfterScroll.h, maxHeight, "min: start: no shift full height"); |
---|
353 | }), 0); |
---|
354 | } |
---|
355 | return d; |
---|
356 | }} |
---|
357 | }, |
---|
358 | { |
---|
359 | timeout: 4000, |
---|
360 | name: "min end horizontal", |
---|
361 | runTest: function(){ with(dom.byId(id)){ |
---|
362 | scrollMin(n); |
---|
363 | var d = new doh.Deferred(); |
---|
364 | setTimeout(function(){ |
---|
365 | scrollIntoView(nodeWidth-2,nodeHeight-1); |
---|
366 | setTimeout(function(){ |
---|
367 | rAfterScroll = getBoundingRect(n); |
---|
368 | vAfterScroll = getVisibleSize(n); |
---|
369 | if(rAfterScroll.left < rBeforeScroll.left){ // shifted left so all but rightmost pixel on first row is showing |
---|
370 | scrollIntoView(nodeWidth-1,nodeHeight-1); |
---|
371 | setTimeout(d.getTestCallback(function(){ |
---|
372 | doh.is(nodeWidth > maxWidth ? maxWidth : (maxWidth-1), vAfterScroll.w, "min: end: shift left partial width"); |
---|
373 | vAfterScroll = getVisibleSize(n); |
---|
374 | doh.is(vAfterScroll.w, maxWidth, "min: end: shift left full width"); |
---|
375 | }), 0); |
---|
376 | }else if(rAfterScroll.left > rBeforeScroll.left){ // shifted right so only 2 rightmost pixels on first row are showing |
---|
377 | scrollIntoView(0,nodeHeight-1); |
---|
378 | setTimeout(d.getTestCallback(function(){ |
---|
379 | doh.is(2, vAfterScroll.w, "min: end: shift right width"); |
---|
380 | vAfterScroll = getVisibleSize(n); |
---|
381 | doh.is(vAfterScroll.w, maxWidth, "min: end: shift right full width"); |
---|
382 | }), 0); |
---|
383 | }else{ // no horizontal scrolling |
---|
384 | scrollIntoView(0,nodeHeight-1,nodeWidth); |
---|
385 | setTimeout(d.getTestCallback(function(){ |
---|
386 | vAfterScroll = getVisibleSize(n); |
---|
387 | doh.is(vAfterScroll.w, maxWidth, "min: end: no shift full width"); |
---|
388 | }), 0); |
---|
389 | } |
---|
390 | }, 0); |
---|
391 | }, 0); |
---|
392 | return d; |
---|
393 | }} |
---|
394 | }, |
---|
395 | { |
---|
396 | timeout: 2000, |
---|
397 | name: "min end vertical", |
---|
398 | runTest: function(){ with(dom.byId(id)){ |
---|
399 | var d = new doh.Deferred(); |
---|
400 | if(rAfterScroll.top < rBeforeScroll.top){ // shifted up so all rows are showing |
---|
401 | scrollIntoView(nodeWidth-1,0); |
---|
402 | setTimeout(d.getTestCallback(function(){ |
---|
403 | doh.is(vAfterScroll.h, maxHeight, "min: end: shift up height"); |
---|
404 | vAfterScroll = getVisibleSize(n); |
---|
405 | doh.is(vAfterScroll.h, maxHeight, "min: end: shift up full height"); |
---|
406 | }), 0); |
---|
407 | }else if(rAfterScroll.top > rBeforeScroll.top){ // shifted down so only the last row is showing |
---|
408 | scrollIntoView(0,0); |
---|
409 | setTimeout(d.getTestCallback(function(){ |
---|
410 | doh.is(1, vAfterScroll.h, "min: end: shift down height"); |
---|
411 | vAfterScroll = getVisibleSize(n); |
---|
412 | doh.is(vAfterScroll.h, maxHeight, "min: end: shift down full height"); |
---|
413 | }), 0); |
---|
414 | }else{ // no vertical scrolling |
---|
415 | scrollIntoView(0,nodeHeight-1); |
---|
416 | setTimeout(d.getTestCallback(function(){ |
---|
417 | vAfterScroll = getVisibleSize(n); |
---|
418 | doh.is(vAfterScroll.h, maxHeight, "min: end: no shift full height"); |
---|
419 | }), 0); |
---|
420 | } |
---|
421 | return d; |
---|
422 | }} |
---|
423 | }, |
---|
424 | { |
---|
425 | timeout: 4000, |
---|
426 | name: "max start horizontal", |
---|
427 | runTest: function(){ with(dom.byId(id)){ |
---|
428 | scrollMax(n); |
---|
429 | var d = new doh.Deferred(); |
---|
430 | setTimeout(function(){ |
---|
431 | rBeforeScroll = getBoundingRect(n); |
---|
432 | vBeforeScroll = getVisibleSize(n); |
---|
433 | scrollIntoView(1,0); |
---|
434 | setTimeout(function(){ |
---|
435 | rAfterScroll = getBoundingRect(n); |
---|
436 | vAfterScroll = getVisibleSize(n); |
---|
437 | if(rAfterScroll.left > rBeforeScroll.left){ // shifted right so all but leftmost pixel on first row is showing |
---|
438 | scrollIntoView(0,0); |
---|
439 | setTimeout(d.getTestCallback(function(){ |
---|
440 | doh.is(nodeWidth > maxWidth ? maxWidth : (maxWidth-1), vAfterScroll.w, "max: start: shift right partial width"); |
---|
441 | vAfterScroll = getVisibleSize(n); |
---|
442 | doh.is(vAfterScroll.w, maxWidth, "max: start: shift right full width"); |
---|
443 | }), 0); |
---|
444 | }else if(rAfterScroll.left < rBeforeScroll.left){ // shifted left so only 2 leftmost pixels on first row are showing |
---|
445 | scrollIntoView(nodeWidth-1,0); |
---|
446 | setTimeout(d.getTestCallback(function(){ |
---|
447 | doh.is(2, vAfterScroll.w, "max: start: shift left width"); |
---|
448 | vAfterScroll = getVisibleSize(n); |
---|
449 | doh.is(vAfterScroll.w, maxWidth, "max: start: shift left full width"); |
---|
450 | }), 0); |
---|
451 | }else{ // no horizontal scrolling |
---|
452 | scrollIntoView(0,0,nodeWidth); |
---|
453 | setTimeout(d.getTestCallback(function(){ |
---|
454 | vAfterScroll = getVisibleSize(n); |
---|
455 | doh.is(vAfterScroll.w, maxWidth, "max: start: no shift full width"); |
---|
456 | }), 0); |
---|
457 | } |
---|
458 | }, 0); |
---|
459 | }, 0); |
---|
460 | return d; |
---|
461 | }} |
---|
462 | }, |
---|
463 | { |
---|
464 | timeout: 2000, |
---|
465 | name: "max start vertical", |
---|
466 | runTest: function(){ with(dom.byId(id)){ |
---|
467 | var d = new doh.Deferred(); |
---|
468 | if(rAfterScroll.top > rBeforeScroll.top){ // shifted down so all rows are showing |
---|
469 | scrollIntoView(1,nodeHeight-1); |
---|
470 | setTimeout(d.getTestCallback(function(){ |
---|
471 | doh.is(vAfterScroll.h, maxHeight, "max: start: shift down height"); |
---|
472 | vAfterScroll = getVisibleSize(n); |
---|
473 | doh.is(vAfterScroll.h, maxHeight, "max: start: shift down full height"); |
---|
474 | }), 0); |
---|
475 | }else if(rAfterScroll.top < rBeforeScroll.top){ // shifted up so only the first row is showing |
---|
476 | scrollIntoView(0,nodeHeight-1); |
---|
477 | setTimeout(d.getTestCallback(function(){ |
---|
478 | doh.is(1, vAfterScroll.h, "max: start: shift up height"); |
---|
479 | vAfterScroll = getVisibleSize(n); |
---|
480 | doh.is(vAfterScroll.h, maxHeight, "max: start: shift up full height"); |
---|
481 | }), 0); |
---|
482 | }else{ // no vertical scrolling |
---|
483 | scrollIntoView(0,nodeHeight-1); |
---|
484 | setTimeout(d.getTestCallback(function(){ |
---|
485 | vAfterScroll = getVisibleSize(n); |
---|
486 | doh.is(vAfterScroll.h, maxHeight, "max: start: no shift full height"); |
---|
487 | }), 0); |
---|
488 | } |
---|
489 | return d; |
---|
490 | }} |
---|
491 | }, |
---|
492 | { |
---|
493 | timeout: 4000, |
---|
494 | name: "max end horizontal", |
---|
495 | runTest: function(){ with(dom.byId(id)){ |
---|
496 | scrollMax(n); |
---|
497 | var d = new doh.Deferred(); |
---|
498 | setTimeout(function(){ |
---|
499 | scrollIntoView(nodeWidth-2,nodeHeight-1); |
---|
500 | setTimeout(function(){ |
---|
501 | rAfterScroll = getBoundingRect(n); |
---|
502 | vAfterScroll = getVisibleSize(n); |
---|
503 | if(rAfterScroll.left < rBeforeScroll.left){ // shifted left so all but rightmost pixel on first row is showing |
---|
504 | scrollIntoView(nodeWidth-1,nodeHeight-1); |
---|
505 | setTimeout(d.getTestCallback(function(){ |
---|
506 | doh.is(nodeWidth > maxWidth ? maxWidth : (maxWidth-1), vAfterScroll.w, "max: end: shift left partial width"); |
---|
507 | vAfterScroll = getVisibleSize(n); |
---|
508 | doh.is(vAfterScroll.w, maxWidth, "max: end: shift left full width"); |
---|
509 | }), 0); |
---|
510 | }else if(rAfterScroll.left > rBeforeScroll.left){ // shifted right so only 2 rightmost pixels on first row are showing |
---|
511 | scrollIntoView(0,nodeHeight-1); |
---|
512 | setTimeout(d.getTestCallback(function(){ |
---|
513 | doh.is(2, vAfterScroll.w, "max: end: shift right width"); |
---|
514 | vAfterScroll = getVisibleSize(n); |
---|
515 | doh.is(vAfterScroll.w, maxWidth, "max: end: shift right full width"); |
---|
516 | }), 0); |
---|
517 | }else{ // no horizontal scrolling |
---|
518 | scrollIntoView(0,nodeHeight-1,nodeWidth); |
---|
519 | setTimeout(d.getTestCallback(function(){ |
---|
520 | vAfterScroll = getVisibleSize(n); |
---|
521 | doh.is(vAfterScroll.w, maxWidth, "max: end: no shift full width"); |
---|
522 | }), 0); |
---|
523 | } |
---|
524 | }, 0); |
---|
525 | }, 0); |
---|
526 | return d; |
---|
527 | }} |
---|
528 | }, |
---|
529 | { |
---|
530 | timeout: 2000, |
---|
531 | name: "max end vertical", |
---|
532 | runTest: function(){ with(dom.byId(id)){ |
---|
533 | var d = new doh.Deferred(); |
---|
534 | if(rAfterScroll.top < rBeforeScroll.top){ // shifted up so all rows are showing |
---|
535 | scrollIntoView(nodeWidth-1,0); |
---|
536 | setTimeout(d.getTestCallback(function(){ |
---|
537 | doh.is(vAfterScroll.h, maxHeight, "max: end: shift up height"); |
---|
538 | vAfterScroll = getVisibleSize(n); |
---|
539 | doh.is(vAfterScroll.h, maxHeight, "max: end: shift up full height"); |
---|
540 | }), 0); |
---|
541 | }else if(rAfterScroll.top > rBeforeScroll.top){ // shifted down so only the last row is showing |
---|
542 | scrollIntoView(0,0); |
---|
543 | setTimeout(d.getTestCallback(function(){ |
---|
544 | doh.is(1, vAfterScroll.h, "max: end: shift down height"); |
---|
545 | vAfterScroll = getVisibleSize(n); |
---|
546 | doh.is(vAfterScroll.h, maxHeight, "max: end: shift down full height"); |
---|
547 | }), 0); |
---|
548 | }else{ // no vertical scrolling |
---|
549 | scrollIntoView(0,0); |
---|
550 | setTimeout(d.getTestCallback(function(){ |
---|
551 | vAfterScroll = getVisibleSize(n); |
---|
552 | doh.is(vAfterScroll.h, maxHeight, "max: end: no shift full height"); |
---|
553 | }), 0); |
---|
554 | } |
---|
555 | return d; |
---|
556 | }} |
---|
557 | }]); |
---|
558 | } |
---|
559 | ); |
---|
560 | } |
---|
561 | ); |
---|
562 | |
---|
563 | doh.run(); |
---|
564 | }); |
---|
565 | </script> |
---|
566 | </head> |
---|
567 | <body> |
---|
568 | <h1>Automated scrollIntoView tests with 3 different DOCTYPEs as well as right-to-left</h1> |
---|
569 | <!-- compute scrollbar size for test result computations --> |
---|
570 | <table style="visibility:hidden;table-layout:fixed;"> |
---|
571 | <tr><td><div id="nonscroll" style="width:100px;overflow:hidden;border:1px solid blue;"> </div></td></tr> |
---|
572 | <tr><td><div id="withscroll" style="width:100px;overflow-x:hidden;overflow-y:scroll;border:1px solid red;"> </div></td></tr> |
---|
573 | </table> |
---|
574 | <!-- The test templates are below --> |
---|
575 | <fieldset> |
---|
576 | <label for="8249">Scrollable parent != offsetParent:</label> |
---|
577 | <div type="testIframe" id="8249"> |
---|
578 | <iframestyle>INPUT { float:left; } |
---|
579 | HTML, BODY { overflow: hidden; } |
---|
580 | </iframestyle> |
---|
581 | <div style="height:61px;width:50px;overflow-y:scroll;margin:11px 20px" |
---|
582 | ><p style="display:inline;" |
---|
583 | ><li><input style="visibility:hidden;"></li |
---|
584 | ><li><input style="visibility:hidden;"></li |
---|
585 | ><li><input style="visibility:hidden;"></li |
---|
586 | ><li><input id=it></li |
---|
587 | ><li><input style="visibility:hidden;"></li |
---|
588 | ><li><input style="visibility:hidden;"></li |
---|
589 | ><li><input style="visibility:hidden;"></li |
---|
590 | ></p |
---|
591 | ></div> |
---|
592 | </div> |
---|
593 | </fieldset> |
---|
594 | <fieldset> |
---|
595 | <label for="8284">Absolute positioned overflow container:</label> |
---|
596 | <div type="testIframe" id="8284"> |
---|
597 | <iframestyle>HTML { overflow-x:hidden !important; /*IE6*/ }</iframestyle> |
---|
598 | <hr style="height:200px;width:20px;"/> |
---|
599 | <div style="position:absolute;top:0px;left:0px;height:200px;width:20px;"> |
---|
600 | <input id=it style="margin:90px 0px;"> |
---|
601 | </div> |
---|
602 | </div> |
---|
603 | </fieldset> |
---|
604 | <fieldset> |
---|
605 | <label for="absContent">Absolute-positioned content:</label> |
---|
606 | <div type="testIframe" id="absContent"> |
---|
607 | <iframestyle>HTML { overflow-x:hidden !important; /*IE6*/ }</iframestyle> |
---|
608 | <div style="height:200px;width:20px;"></div> |
---|
609 | <input id=it style="position:absolute;left:10px;top:90px;"> |
---|
610 | </div> |
---|
611 | </fieldset> |
---|
612 | <fieldset> |
---|
613 | <label for="fixedNode">Fixed-positioned node:</label> |
---|
614 | <div type="testIframe" id="fixedNode"> |
---|
615 | <hr style="height:50px;float:left;"/> |
---|
616 | <hr style="height:50px;float:right;"/> |
---|
617 | <input id=it style="position:fixed;top:75px;left:-5px;"> |
---|
618 | </div> |
---|
619 | </fieldset> |
---|
620 | <fieldset> |
---|
621 | <label for="fixedScrollable">Fixed-positioned scrollable content:</label> |
---|
622 | <div type="testIframe" id="fixedScrollable"> |
---|
623 | <iframestyle>HTML { overflow:hidden !important; /*IE6*/ } |
---|
624 | INPUT { height:20px; width:20px; }</iframestyle> |
---|
625 | <div style="height:100px;width:70px;overflow-y:scroll;position:fixed;top:0px;left:0;"> |
---|
626 | <input id=it style="margin:120px 0px;"> |
---|
627 | <hr style="width:10px;"> |
---|
628 | </div> |
---|
629 | <hr style="height:200px;width:20px;"/> |
---|
630 | </div> |
---|
631 | </fieldset> |
---|
632 | <fieldset> |
---|
633 | <label for="7036_8665">Double scrollbars with absolute positioned content:</label> |
---|
634 | <div type="testIframe" id="7036_8665"> |
---|
635 | <iframestyle>INPUT { height:28px; width:28px; }</iframestyle> |
---|
636 | <div style="height:70px;width:70px;overflow-y:scroll;position:absolute;top:26px;left:5px;" |
---|
637 | ><input id=it style="margin:80px 0px 80px 0px;" |
---|
638 | ><hr style="width:10px;" |
---|
639 | ></div> |
---|
640 | <div style="height:26px;width:10px;position:absolute;top:96px;left:10px;"></div> |
---|
641 | </div> |
---|
642 | </fieldset> |
---|
643 | <fieldset> |
---|
644 | <label for="innerNoScrollBars">Complex scrollable inner content, no scrollbars:</label> |
---|
645 | <div type="testIframe" id="innerNoScrollBars"> |
---|
646 | <iframestyle>BODY { overflow:hidden !important; /*IE9*/ }</iframestyle> |
---|
647 | <fieldset style="overflow:hidden; margin:10px;border:1px solid red;border-width:1px 2px 3px 4px;display:inline;" |
---|
648 | ><div style="overflow:hidden; width:20px;height:20px;" |
---|
649 | ><fieldset style="width:59px;overflow:visible;" |
---|
650 | ><input style="background-color:green;height:15px;float:left;" |
---|
651 | ><nobr style="margin:7px;padding:3px;border:5px solid black;overflow:visible;display:block;width:90px;float:left;" |
---|
652 | ><input style="background-color:black;display:inline;width:24px;height:24px;float:left;" |
---|
653 | ><input id=it style="display:inline;float:left;" |
---|
654 | ><input style="background-color:blue;display:inline;width:16px;height:16px;float:left;" |
---|
655 | ></nobr |
---|
656 | ><input style="background-color:cyan;height:10px;float:left;" |
---|
657 | ></fieldset |
---|
658 | ></div |
---|
659 | ></fieldset> |
---|
660 | </div> |
---|
661 | </fieldset> |
---|
662 | <fieldset> |
---|
663 | <label for="noScrollBars">Nothing to do:</label> |
---|
664 | <div type="testIframe" id="noScrollBars"> |
---|
665 | <iframestyle> |
---|
666 | HTML { overflow:hidden !important; /*IE6*/ } |
---|
667 | BODY { overflow:hidden !important; /*IE9*/ } |
---|
668 | </iframestyle> |
---|
669 | <input id=it style="margin:25px;"> |
---|
670 | </div> |
---|
671 | </fieldset> |
---|
672 | <fieldset> |
---|
673 | <label for="table">Table:</label> |
---|
674 | <div type="testIframe" id="table"> |
---|
675 | <iframestyle>HTML { overflow-x:hidden !important; /*IE6*/ }</iframestyle> |
---|
676 | <table style="border-width:75px 5px 75px 5px;float:left;" cellspacing="0" cellpadding="0" rules="none"> |
---|
677 | <tr><td><input id=it style="height:40px;width:40px;float:left;"></td></tr> |
---|
678 | </table> |
---|
679 | </div> |
---|
680 | </fieldset> |
---|
681 | <fieldset> |
---|
682 | <label for="innerScrollbars">Inner scrollable content with scrollbars:</label> |
---|
683 | <div type="testIframe" id="innerScrollbars"> |
---|
684 | <iframestyle> |
---|
685 | HTML { overflow:hidden !important; /*IE6*/ } |
---|
686 | BODY { padding:10px; } |
---|
687 | TABLE { OPR_float:left; } |
---|
688 | </iframestyle> |
---|
689 | <div style="overflow:scroll;height:80px;width:80px;" |
---|
690 | ><fieldset style="visibility:hidden;" |
---|
691 | ><table cellspacing="65" cellpadding="0" border="0" |
---|
692 | ><tr><td><input id=it style="width:50px;height:50px;clear:both;float:left;visibility:visible;"></td></tr |
---|
693 | ></table |
---|
694 | ></fieldset |
---|
695 | ></div> |
---|
696 | </div> |
---|
697 | </fieldset> |
---|
698 | <fieldset> |
---|
699 | <label for="8542">position:absolute TD content:</label> |
---|
700 | <div type="testIframe" id="8542"> |
---|
701 | <div style="position:absolute;padding:100px 20px;left:5px;"> |
---|
702 | <table style="width:10px;height:10px;max-height:10px;table-layout:fixed;" cellspacing="0" cellpadding="0"> |
---|
703 | <tr><td><div style="position:relative;height:10px;width:10px;"><input id=it style="position:absolute;"></div></td></tr> |
---|
704 | </table> |
---|
705 | </div> |
---|
706 | </div> |
---|
707 | </fieldset> |
---|
708 | <fieldset> |
---|
709 | <label for="tooBig">Oversized content:</label> |
---|
710 | <div type="testIframe" id="tooBig"> |
---|
711 | <iframestyle> |
---|
712 | HTML { IEZ_overflow:scroll !important; /*IE6*/ } |
---|
713 | BODY { OPT_overflow:scroll !important; } |
---|
714 | </iframestyle> |
---|
715 | <input id=it style="position:absolute;margin:-10px 0px 0px 0px;left:-20px;width:130px;height:130px;"> |
---|
716 | <hr style="height:100px;width:200px;float:left;"/> |
---|
717 | <hr style="height:100px;width:200px;float:right;"/> |
---|
718 | </div> |
---|
719 | </fieldset> |
---|
720 | <fieldset> |
---|
721 | <label for="htmlPadding">HTML/BODY padding:</label> |
---|
722 | <div type="testIframe" id="htmlPadding"> |
---|
723 | <iframestyle>HTML, BODY { padding:50px 9px; } |
---|
724 | HTML { overflow-x:hidden !important; /*IE6*/ }</iframestyle> |
---|
725 | <hr style="height:50px;width:20px;"/> |
---|
726 | <input id=it style="display:block;clear:both;float:left;"> |
---|
727 | <hr style="clear:both;height:50px;width:20px;"/> |
---|
728 | </div> |
---|
729 | </fieldset> |
---|
730 | <br> |
---|
731 | </body> |
---|
732 | </html> |
---|