123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- if (!dojo._hasResource["dijit._base.place"]) { // _hasResource checks added by
- // build. Do not use
- // _hasResource directly in your
- // code.
- dojo._hasResource["dijit._base.place"] = true;
- dojo.provide("dijit._base.place");
- // ported from dojo.html.util
- dijit.getViewport = function() {
- // summary
- // Returns the dimensions and scroll position of the viewable area of a
- // browser window
- var _window = dojo.global;
- var _document = dojo.doc;
- // get viewport size
- var w = 0, h = 0;
- if (dojo.isMozilla) {
- // mozilla
- // _window.innerHeight includes the height taken by the scroll bar
- // clientHeight is ideal but has DTD issues:
- // #4539: FF reverses the roles of body.clientHeight/Width and
- // documentElement.clientHeight/Width based on the DTD!
- // check DTD to see whether body or documentElement returns the
- // viewport dimensions using this algorithm:
- var minw, minh, maxw, maxh;
- if (_document.body.clientWidth > _document.documentElement.clientWidth) {
- minw = _document.documentElement.clientWidth;
- maxw = _document.body.clientWidth;
- } else {
- maxw = _document.documentElement.clientWidth;
- minw = _document.body.clientWidth;
- }
- if (_document.body.clientHeight > _document.documentElement.clientHeight) {
- minh = _document.documentElement.clientHeight;
- maxh = _document.body.clientHeight;
- } else {
- maxh = _document.documentElement.clientHeight;
- minh = _document.body.clientHeight;
- }
- w = (maxw > _window.innerWidth) ? minw : maxw;
- h = (maxh > _window.innerHeight) ? minh : maxh;
- } else if (!dojo.isOpera && _window.innerWidth) {
- // in opera9, dojo.body().clientWidth should be used, instead
- // of window.innerWidth/document.documentElement.clientWidth
- // so we have to check whether it is opera
- w = _window.innerWidth;
- h = _window.innerHeight;
- } else if (dojo.isIE && _document.documentElement
- && _document.documentElement.clientHeight) {
- w = _document.documentElement.clientWidth;
- h = _document.documentElement.clientHeight;
- } else if (dojo.body().clientWidth) {
- // IE5, Opera
- w = dojo.body().clientWidth;
- h = dojo.body().clientHeight;
- }
- // get scroll position
- var scroll = dojo._docScroll();
- return {
- w : w,
- h : h,
- l : scroll.x,
- t : scroll.y
- }; // object
- };
- dijit.placeOnScreen = function(
- /* DomNode */node,
- /* Object */pos,
- /* Object */corners,
- /* boolean? */tryOnly) {
- // summary:
- // Keeps 'node' in the visible area of the screen while trying to
- // place closest to pos.x, pos.y. The input coordinates are
- // expected to be the desired document position.
- //
- // Set which corner(s) you want to bind to, such as
- //
- // placeOnScreen(node, {x: 10, y: 20}, ["TR", "BL"])
- //
- // The desired x/y will be treated as the topleft(TL)/topright(TR) or
- // BottomLeft(BL)/BottomRight(BR) corner of the node. Each corner is
- // tested
- // and if a perfect match is found, it will be used. Otherwise, it goes
- // through
- // all of the specified corners, and choose the most appropriate one.
- //
- // NOTE: node is assumed to be absolutely or relatively positioned.
- var choices = dojo.map(corners, function(corner) {
- return {
- corner : corner,
- pos : pos
- };
- });
- return dijit._place(node, choices);
- }
- dijit._place = function(/* DomNode */node, /* Array */choices, /* Function */
- layoutNode) {
- // summary:
- // Given a list of spots to put node, put it at the first spot where it
- // fits,
- // of if it doesn't fit anywhere then the place with the least overflow
- // choices: Array
- // Array of elements like: {corner: 'TL', pos: {x: 10, y: 20} }
- // Above example says to put the top-left corner of the node at (10,20)
- // layoutNode: Function(node, orient)
- // for things like tooltip, they are displayed differently (and have
- // different dimensions)
- // based on their orientation relative to the parent. This adjusts the
- // popup based on orientation.
- // get {x: 10, y: 10, w: 100, h:100} type obj representing position of
- // viewport over document
- var view = dijit.getViewport();
- // This won't work if the node is inside a <div style="position:
- // relative">,
- // so reattach it to document.body. (Otherwise, the positioning will be
- // wrong
- // and also it might get cutoff)
- if (!node.parentNode
- || String(node.parentNode.tagName).toLowerCase() != "body") {
- dojo.body().appendChild(node);
- }
- var best = null;
- for (var i = 0; i < choices.length; i++) {
- var corner = choices[i].corner;
- var pos = choices[i].pos;
- // configure node to be displayed in given position relative to
- // button
- // (need to do this in order to get an accurate size for the node,
- // because
- // a tooltips size changes based on position, due to triangle)
- if (layoutNode) {
- layoutNode(corner);
- }
- // get node's size
- var oldDisplay = node.style.display;
- var oldVis = node.style.visibility;
- node.style.visibility = "hidden";
- node.style.display = "";
- var mb = dojo.marginBox(node);
- node.style.display = oldDisplay;
- node.style.visibility = oldVis;
- // coordinates and size of node with specified corner placed at pos,
- // and clipped by viewport
- var startX = (corner.charAt(1) == 'L' ? pos.x : Math.max(view.l,
- pos.x - mb.w)), startY = (corner.charAt(0) == 'T'
- ? pos.y
- : Math.max(view.t, pos.y - mb.h)), endX = (corner.charAt(1) == 'L'
- ? Math.min(view.l + view.w, startX + mb.w)
- : pos.x), endY = (corner.charAt(0) == 'T' ? Math.min(view.t
- + view.h, startY + mb.h) : pos.y), width = endX
- - startX, height = endY - startY, overflow = (mb.w - width)
- + (mb.h - height);
- if (best == null || overflow < best.overflow) {
- best = {
- corner : corner,
- aroundCorner : choices[i].aroundCorner,
- x : startX,
- y : startY,
- w : width,
- h : height,
- overflow : overflow
- };
- }
- if (overflow == 0) {
- break;
- }
- }
- node.style.left = best.x + "px";
- node.style.top = best.y + "px";
- return best;
- }
- dijit.placeOnScreenAroundElement = function(
- /* DomNode */node,
- /* DomNode */aroundNode,
- /* Object */aroundCorners,
- /* Function */layoutNode) {
- // summary
- // Like placeOnScreen, except it accepts aroundNode instead of x,y
- // and attempts to place node around it. Uses margin box dimensions.
- //
- // aroundCorners
- // specify Which corner of aroundNode should be
- // used to place the node => which corner(s) of node to use (see the
- // corners parameter in dijit.placeOnScreen)
- // e.g. {'TL': 'BL', 'BL': 'TL'}
- //
- // layoutNode: Function(node, orient)
- // for things like tooltip, they are displayed differently (and have
- // different dimensions)
- // based on their orientation relative to the parent. This adjusts the
- // popup based on orientation.
- // get coordinates of aroundNode
- aroundNode = dojo.byId(aroundNode);
- var oldDisplay = aroundNode.style.display;
- aroundNode.style.display = "";
- // #3172: use the slightly tighter border box instead of marginBox
- var aroundNodeW = aroundNode.offsetWidth; // mb.w;
- var aroundNodeH = aroundNode.offsetHeight; // mb.h;
- var aroundNodePos = dojo.coords(aroundNode, true);
- aroundNode.style.display = oldDisplay;
- // Generate list of possible positions for node
- var choices = [];
- for (var nodeCorner in aroundCorners) {
- choices.push({
- aroundCorner : nodeCorner,
- corner : aroundCorners[nodeCorner],
- pos : {
- x : aroundNodePos.x
- + (nodeCorner.charAt(1) == 'L'
- ? 0
- : aroundNodeW),
- y : aroundNodePos.y
- + (nodeCorner.charAt(0) == 'T'
- ? 0
- : aroundNodeH)
- }
- });
- }
- return dijit._place(node, choices, layoutNode);
- }
- }
|