You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
2.8 KiB
87 lines
2.8 KiB
define([ |
|
"dojo/Evented", |
|
"dojo/on", |
|
"dojo/domReady", |
|
"dojo/sniff", // has("ie"), has("ios") |
|
"dojo/window" // getBox() |
|
], function(Evented, on, domReady, has, winUtils){ |
|
|
|
// module: |
|
// dijit/Viewport |
|
|
|
/*===== |
|
return { |
|
// summary: |
|
// Utility singleton to watch for viewport resizes, avoiding duplicate notifications |
|
// which can lead to infinite loops. |
|
// description: |
|
// Usage: Viewport.on("resize", myCallback). |
|
// |
|
// myCallback() is called without arguments in case it's _WidgetBase.resize(), |
|
// which would interpret the argument as the size to make the widget. |
|
}; |
|
=====*/ |
|
|
|
var Viewport = new Evented(); |
|
|
|
var focusedNode; |
|
|
|
domReady(function(){ |
|
var oldBox = winUtils.getBox(); |
|
Viewport._rlh = on(window, "resize", function(){ |
|
var newBox = winUtils.getBox(); |
|
if(oldBox.h == newBox.h && oldBox.w == newBox.w){ return; } |
|
oldBox = newBox; |
|
Viewport.emit("resize"); |
|
}); |
|
|
|
// Also catch zoom changes on IE8, since they don't naturally generate resize events |
|
if(has("ie") == 8){ |
|
var deviceXDPI = screen.deviceXDPI; |
|
setInterval(function(){ |
|
if(screen.deviceXDPI != deviceXDPI){ |
|
deviceXDPI = screen.deviceXDPI; |
|
Viewport.emit("resize"); |
|
} |
|
}, 500); |
|
} |
|
|
|
// On iOS, keep track of the focused node so we can guess when the keyboard is/isn't being displayed. |
|
if(has("ios")){ |
|
on(document, "focusin", function(evt){ |
|
focusedNode = evt.target; |
|
}); |
|
on(document, "focusout", function(evt){ |
|
focusedNode = null; |
|
}); |
|
} |
|
}); |
|
|
|
Viewport.getEffectiveBox = function(/*Document*/ doc){ |
|
// summary: |
|
// Get the size of the viewport, or on mobile devices, the part of the viewport not obscured by the |
|
// virtual keyboard. |
|
|
|
var box = winUtils.getBox(doc); |
|
|
|
// Account for iOS virtual keyboard, if it's being shown. Unfortunately no direct way to check or measure. |
|
var tag = focusedNode && focusedNode.tagName && focusedNode.tagName.toLowerCase(); |
|
if(has("ios") && focusedNode && !focusedNode.readOnly && (tag == "textarea" || (tag == "input" && |
|
/^(color|email|number|password|search|tel|text|url)$/.test(focusedNode.type)))){ |
|
|
|
// Box represents the size of the viewport. Some of the viewport is likely covered by the keyboard. |
|
// Estimate height of visible viewport assuming viewport goes to bottom of screen, but is covered by keyboard. |
|
box.h *= (orientation == 0 || orientation == 180 ? 0.66 : 0.40); |
|
|
|
// Above measurement will be inaccurate if viewport was scrolled up so far that it ends before the bottom |
|
// of the screen. In this case, keyboard isn't covering as much of the viewport as we thought. |
|
// We know the visible size is at least the distance from the top of the viewport to the focused node. |
|
var rect = focusedNode.getBoundingClientRect(); |
|
box.h = Math.max(box.h, rect.top + rect.height); |
|
} |
|
|
|
return box; |
|
}; |
|
|
|
return Viewport; |
|
});
|
|
|