dijit/_base/place.js

  • Provides:

    • dijit
  • dijit.getViewport

    • type
      Function
    • source: [view]
       return dojo.window.getBox();
    • summary
      Returns the dimensions and scroll position of the viewable area of a browser window
  • dijit.__Position

    • type
      Function
    • source: [view]
      define("dijit/_base/place", ["dojo", "dijit", "dojo/window", "dojo/AdapterRegistry"], function(dojo, dijit) {


      dijit.getViewport = function(){
       // summary:
       //  Returns the dimensions and scroll position of the viewable area of a browser window


       return dojo.window.getBox();
      };




      dijit.__Position = function(){
       // x: Integer
       //  horizontal coordinate in pixels, relative to document body
       // y: Integer
       //  vertical coordinate in pixels, relative to document body


       thix.x = x;
       this.y = y;
    • summary
  • dijit.__Position.y

    • summary
  • dijit.placeOnScreen

    • type
      Function
    • parameters:
      • node: (typeof DomNode)
      • pos: (typeof dijit.__Position)
        Object like {x: 10, y: 20}
      • corners: (typeof String[])
        Array of Strings representing order to try corners in, like ["TR", "BL"].
        Possible values are:
        * "BL" - bottom left
        * "BR" - bottom right
        * "TL" - top left
        * "TR" - top right
      • padding: (typeof dijit.__Position)
        set padding to put some buffer around the element you want to position.
    • source: [view]
       var choices = dojo.map(corners, function(corner){
        var c = { corner: corner, pos: {x:pos.x,y:pos.y} };
        if(padding){
         c.pos.x += corner.charAt(1) == 'L' ? padding.x : -padding.x;
         c.pos.y += corner.charAt(0) == 'T' ? padding.y : -padding.y;
        }
        return c;
       });


       return dijit._place(node, choices);
    • summary
      Positions one of the node's corners at specified position
      such that node is fully visible in viewport.
    • description
      NOTE: node is assumed to be absolutely or relatively positioned.
    • example
      Try to place node's top right corner at (10,20).
      If that makes node go (partially) off screen, then try placing
      bottom left corner at (10,20).
      
      	placeOnScreen(node, {x: 10, y: 20}, ["TR", "BL"])
  • dijit._place

    • type
      Function
    • parameters:
      • node: (typeof DomNode)
      • choices: (typeof 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: (typeof Function(node)
        aroundNodeCorner, nodeCorner, size)
        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.
        It also passes in the available size for the popup, which is useful for tooltips to
        tell them that their width is limited to a certain amount.   layoutNode() may return a value expressing
        how much the popup had to be modified to fit into the available space.   This is used to determine
        what the best placement is.
      • aroundNodeCoords: (typeof Object)
    • source: [view]
      define("dijit/_base/place", ["dojo", "dijit", "dojo/window", "dojo/AdapterRegistry"], function(dojo, dijit) {


      dijit.getViewport = function(){
       // summary:
       //  Returns the dimensions and scroll position of the viewable area of a browser window


       return dojo.window.getBox();
      };




      dijit.__Position = function(){
       // x: Integer
       //  horizontal coordinate in pixels, relative to document body
       // y: Integer
       //  vertical coordinate in pixels, relative to document body


       thix.x = x;
       this.y = y;
      }






      dijit.placeOnScreen = function(
       /* DomNode */   node,
       /* dijit.__Position */ pos,
       /* String[] */   corners,
       /* dijit.__Position? */ padding){
       // summary:
       //  Positions one of the node's corners at specified position
       //  such that node is fully visible in viewport.
       // description:
       //  NOTE: node is assumed to be absolutely or relatively positioned.
       // pos:
       //  Object like {x: 10, y: 20}
       // corners:
       //  Array of Strings representing order to try corners in, like ["TR", "BL"].
       //  Possible values are:
       //   * "BL" - bottom left
       //   * "BR" - bottom right
       //   * "TL" - top left
       //   * "TR" - top right
       // padding:
       //  set padding to put some buffer around the element you want to position.
       // example:
       //  Try to place node's top right corner at (10,20).
       //  If that makes node go (partially) off screen, then try placing
       //  bottom left corner at (10,20).
       // | placeOnScreen(node, {x: 10, y: 20}, ["TR", "BL"])


       var choices = dojo.map(corners, function(corner){
        var c = { corner: corner, pos: {x:pos.x,y:pos.y} };
        if(padding){
         c.pos.x += corner.charAt(1) == 'L' ? padding.x : -padding.x;
         c.pos.y += corner.charAt(0) == 'T' ? padding.y : -padding.y;
        }
        return c;
       });


       return dijit._place(node, choices);
      }


      dijit._place = function(/*DomNode*/ node, choices, layoutNode, /*Object*/ aroundNodeCoords){
       // 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, aroundNodeCorner, nodeCorner, size)
       //  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.
       //  It also passes in the available size for the popup, which is useful for tooltips to
       //  tell them that their width is limited to a certain amount. layoutNode() may return a value expressing
       //  how much the popup had to be modified to fit into the available space. This is used to determine
       //  what the best placement is.
       // aroundNodeCoords: Object
       //  Size of aroundNode, ex: {w: 200, h: 50}


       // get {x: 10, y: 10, w: 100, h:100} type obj representing position of
       // viewport over document
       var view = dojo.window.getBox();


       // This won't work if the node is inside a
      ,
       // so reattach it to dojo.doc.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;
       dojo.some(choices, function(choice){
        var corner = choice.corner;
        var pos = choice.pos;
        var overflow = 0;


        // calculate amount of space available given specified position of node
        var spaceAvailable = {
         w: corner.charAt(1) == 'L' ? (view.l + view.w) - pos.x : pos.x - view.l,
         h: corner.charAt(1) == 'T' ? (view.t + view.h) - pos.y : pos.y - view.t
        };


        // 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 tooltip's size changes based on position, due to triangle)
        if(layoutNode){
         var res = layoutNode(node, choice.aroundCorner, corner, spaceAvailable, aroundNodeCoords);
         overflow = typeof res == "undefined" ? 0 : res;
        }


        // get node's size
        var style = node.style;
        var oldDisplay = style.display;
        var oldVis = style.visibility;
        style.visibility = "hidden";
        style.display = "";
        var mb = dojo.marginBox(node);
        style.display = oldDisplay;
        style.visibility = oldVis;


        // coordinates and size of node with specified corner placed at pos,
        // and clipped by viewport
        var startX = Math.max(view.l, corner.charAt(1) == 'L' ? pos.x : (pos.x - mb.w)),
         startY = Math.max(view.t, corner.charAt(0) == 'T' ? pos.y : (pos.y - mb.h)),
         endX = Math.min(view.l + view.w, corner.charAt(1) == 'L' ? (startX + mb.w) : pos.x),
         endY = Math.min(view.t + view.h, corner.charAt(0) == 'T' ? (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: choice.aroundCorner,
          x: startX,
          y: startY,
          w: width,
          h: height,
          overflow: overflow,
          spaceAvailable: spaceAvailable
         };
        }

        
        return !overflow;
       });


       // In case the best position is not the last one we checked, need to call
       // layoutNode() again.
       if(best.overflow && layoutNode){
        layoutNode(node, best.aroundCorner, best.corner, best.spaceAvailable, aroundNodeCoords);
       }


       // And then position the node. Do this last, after the layoutNode() above
       // has sized the node, due to browser quirks when the viewport is scrolled
       // (specifically that a Tooltip will shrink to fit as though the window was
       // scrolled to the left).
       //
       // In RTL mode, set style.right rather than style.left so in the common case,
       // window resizes move the popup along with the aroundNode.
       var l = dojo._isBodyLtr(),
        s = node.style;
       s.top = best.y + "px";
       s[l ? "left" : "right"] = (l ? best.x : view.w - best.x - best.w) + "px";

       
       return best;
    • 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
  • dijit.placeOnScreenAroundNode

    • type
      Function
    • parameters:
      • node: (typeof DomNode)
      • aroundNode: (typeof DomNode)
      • aroundCorners: (typeof Object)
        Ordered list of pairs of corners to try matching up.
        Each pair of corners is represented as a key/value in the hash,
        where the key corresponds to the aroundNode's corner, and
        the value corresponds to the node's corner:
        
        	{ aroundNodeCorner1: nodeCorner1, aroundNodeCorner2: nodeCorner2, ...}
        
        The following strings are used to represent the four corners:
        * &quot;BL&quot; - bottom left
        * &quot;BR&quot; - bottom right
        * &quot;TL&quot; - top left
        * &quot;TR&quot; - top right
      • layoutNode: (typeof Function)
        Function(node, aroundNodeCorner, nodeCorner)
        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.
    • source: [view]
      define("dijit/_base/place", ["dojo", "dijit", "dojo/window", "dojo/AdapterRegistry"], function(dojo, dijit) {


      dijit.getViewport = function(){
       // summary:
       //  Returns the dimensions and scroll position of the viewable area of a browser window


       return dojo.window.getBox();
      };




      dijit.__Position = function(){
       // x: Integer
       //  horizontal coordinate in pixels, relative to document body
       // y: Integer
       //  vertical coordinate in pixels, relative to document body


       thix.x = x;
       this.y = y;
      }






      dijit.placeOnScreen = function(
       /* DomNode */   node,
       /* dijit.__Position */ pos,
       /* String[] */   corners,
       /* dijit.__Position? */ padding){
       // summary:
       //  Positions one of the node's corners at specified position
       //  such that node is fully visible in viewport.
       // description:
       //  NOTE: node is assumed to be absolutely or relatively positioned.
       // pos:
       //  Object like {x: 10, y: 20}
       // corners:
       //  Array of Strings representing order to try corners in, like ["TR", "BL"].
       //  Possible values are:
       //   * "BL" - bottom left
       //   * "BR" - bottom right
       //   * "TL" - top left
       //   * "TR" - top right
       // padding:
       //  set padding to put some buffer around the element you want to position.
       // example:
       //  Try to place node's top right corner at (10,20).
       //  If that makes node go (partially) off screen, then try placing
       //  bottom left corner at (10,20).
       // | placeOnScreen(node, {x: 10, y: 20}, ["TR", "BL"])


       var choices = dojo.map(corners, function(corner){
        var c = { corner: corner, pos: {x:pos.x,y:pos.y} };
        if(padding){
         c.pos.x += corner.charAt(1) == 'L' ? padding.x : -padding.x;
         c.pos.y += corner.charAt(0) == 'T' ? padding.y : -padding.y;
        }
        return c;
       });


       return dijit._place(node, choices);
      }


      dijit._place = function(/*DomNode*/ node, choices, layoutNode, /*Object*/ aroundNodeCoords){
       // 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, aroundNodeCorner, nodeCorner, size)
       //  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.
       //  It also passes in the available size for the popup, which is useful for tooltips to
       //  tell them that their width is limited to a certain amount. layoutNode() may return a value expressing
       //  how much the popup had to be modified to fit into the available space. This is used to determine
       //  what the best placement is.
       // aroundNodeCoords: Object
       //  Size of aroundNode, ex: {w: 200, h: 50}


       // get {x: 10, y: 10, w: 100, h:100} type obj representing position of
       // viewport over document
       var view = dojo.window.getBox();


       // This won't work if the node is inside a
      ,
       // so reattach it to dojo.doc.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;
       dojo.some(choices, function(choice){
        var corner = choice.corner;
        var pos = choice.pos;
        var overflow = 0;


        // calculate amount of space available given specified position of node
        var spaceAvailable = {
         w: corner.charAt(1) == 'L' ? (view.l + view.w) - pos.x : pos.x - view.l,
         h: corner.charAt(1) == 'T' ? (view.t + view.h) - pos.y : pos.y - view.t
        };


        // 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 tooltip's size changes based on position, due to triangle)
        if(layoutNode){
         var res = layoutNode(node, choice.aroundCorner, corner, spaceAvailable, aroundNodeCoords);
         overflow = typeof res == "undefined" ? 0 : res;
        }


        // get node's size
        var style = node.style;
        var oldDisplay = style.display;
        var oldVis = style.visibility;
        style.visibility = "hidden";
        style.display = "";
        var mb = dojo.marginBox(node);
        style.display = oldDisplay;
        style.visibility = oldVis;


        // coordinates and size of node with specified corner placed at pos,
        // and clipped by viewport
        var startX = Math.max(view.l, corner.charAt(1) == 'L' ? pos.x : (pos.x - mb.w)),
         startY = Math.max(view.t, corner.charAt(0) == 'T' ? pos.y : (pos.y - mb.h)),
         endX = Math.min(view.l + view.w, corner.charAt(1) == 'L' ? (startX + mb.w) : pos.x),
         endY = Math.min(view.t + view.h, corner.charAt(0) == 'T' ? (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: choice.aroundCorner,
          x: startX,
          y: startY,
          w: width,
          h: height,
          overflow: overflow,
          spaceAvailable: spaceAvailable
         };
        }

        
        return !overflow;
       });


       // In case the best position is not the last one we checked, need to call
       // layoutNode() again.
       if(best.overflow && layoutNode){
        layoutNode(node, best.aroundCorner, best.corner, best.spaceAvailable, aroundNodeCoords);
       }


       // And then position the node. Do this last, after the layoutNode() above
       // has sized the node, due to browser quirks when the viewport is scrolled
       // (specifically that a Tooltip will shrink to fit as though the window was
       // scrolled to the left).
       //
       // In RTL mode, set style.right rather than style.left so in the common case,
       // window resizes move the popup along with the aroundNode.
       var l = dojo._isBodyLtr(),
        s = node.style;
       s.top = best.y + "px";
       s[l ? "left" : "right"] = (l ? best.x : view.w - best.x - best.w) + "px";

       
       return best;
      }


      dijit.placeOnScreenAroundNode = function(
       /* DomNode */  node,
       /* DomNode */  aroundNode,
       /* Object */  aroundCorners,
       /* Function? */  layoutNode){


       // summary:
       //  Position node adjacent or kitty-corner to aroundNode
       //  such that it's fully visible in viewport.
       //
       // description:
       //  Place node such that corner of node touches a corner of
       //  aroundNode, and that node is fully visible.
       //
       // aroundCorners:
       //  Ordered list of pairs of corners to try matching up.
       //  Each pair of corners is represented as a key/value in the hash,
       //  where the key corresponds to the aroundNode's corner, and
       //  the value corresponds to the node's corner:
       //
       // | { aroundNodeCorner1: nodeCorner1, aroundNodeCorner2: nodeCorner2, ...}
       //
       //  The following strings are used to represent the four corners:
       //   * "BL" - bottom left
       //   * "BR" - bottom right
       //   * "TL" - top left
       //   * "TR" - top right
       //
       // layoutNode: Function(node, aroundNodeCorner, nodeCorner)
       //  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.
       //
       // example:
       // | dijit.placeOnScreenAroundNode(node, aroundNode, {'BL':'TL', 'TR':'BR'});
       //  This will try to position node such that node's top-left corner is at the same position
       //  as the bottom left corner of the aroundNode (ie, put node below
       //  aroundNode, with left edges aligned). If that fails it will try to put
       //   the bottom-right corner of node where the top right corner of aroundNode is
       //  (ie, put node above aroundNode, with right edges aligned)
       //


       // get coordinates of aroundNode
       aroundNode = dojo.byId(aroundNode);
       var aroundNodePos = dojo.position(aroundNode, true);


       // place the node around the calculated rectangle
       return dijit._placeOnScreenAroundRect(node,
        aroundNodePos.x, aroundNodePos.y, aroundNodePos.w, aroundNodePos.h, // rectangle
        aroundCorners, layoutNode);
    • summary
      Position node adjacent or kitty-corner to aroundNode
      such that it's fully visible in viewport.
    • description
      Place node such that corner of node touches a corner of
      aroundNode, and that node is fully visible.
  • dijit.__Rectangle

    • type
      Function
    • source: [view]
      define("dijit/_base/place", ["dojo", "dijit", "dojo/window", "dojo/AdapterRegistry"], function(dojo, dijit) {


      dijit.getViewport = function(){
       // summary:
       //  Returns the dimensions and scroll position of the viewable area of a browser window


       return dojo.window.getBox();
      };




      dijit.__Position = function(){
       // x: Integer
       //  horizontal coordinate in pixels, relative to document body
       // y: Integer
       //  vertical coordinate in pixels, relative to document body


       thix.x = x;
       this.y = y;
      }






      dijit.placeOnScreen = function(
       /* DomNode */   node,
       /* dijit.__Position */ pos,
       /* String[] */   corners,
       /* dijit.__Position? */ padding){
       // summary:
       //  Positions one of the node's corners at specified position
       //  such that node is fully visible in viewport.
       // description:
       //  NOTE: node is assumed to be absolutely or relatively positioned.
       // pos:
       //  Object like {x: 10, y: 20}
       // corners:
       //  Array of Strings representing order to try corners in, like ["TR", "BL"].
       //  Possible values are:
       //   * "BL" - bottom left
       //   * "BR" - bottom right
       //   * "TL" - top left
       //   * "TR" - top right
       // padding:
       //  set padding to put some buffer around the element you want to position.
       // example:
       //  Try to place node's top right corner at (10,20).
       //  If that makes node go (partially) off screen, then try placing
       //  bottom left corner at (10,20).
       // | placeOnScreen(node, {x: 10, y: 20}, ["TR", "BL"])


       var choices = dojo.map(corners, function(corner){
        var c = { corner: corner, pos: {x:pos.x,y:pos.y} };
        if(padding){
         c.pos.x += corner.charAt(1) == 'L' ? padding.x : -padding.x;
         c.pos.y += corner.charAt(0) == 'T' ? padding.y : -padding.y;
        }
        return c;
       });


       return dijit._place(node, choices);
      }


      dijit._place = function(/*DomNode*/ node, choices, layoutNode, /*Object*/ aroundNodeCoords){
       // 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, aroundNodeCorner, nodeCorner, size)
       //  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.
       //  It also passes in the available size for the popup, which is useful for tooltips to
       //  tell them that their width is limited to a certain amount. layoutNode() may return a value expressing
       //  how much the popup had to be modified to fit into the available space. This is used to determine
       //  what the best placement is.
       // aroundNodeCoords: Object
       //  Size of aroundNode, ex: {w: 200, h: 50}


       // get {x: 10, y: 10, w: 100, h:100} type obj representing position of
       // viewport over document
       var view = dojo.window.getBox();


       // This won't work if the node is inside a
      ,
       // so reattach it to dojo.doc.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;
       dojo.some(choices, function(choice){
        var corner = choice.corner;
        var pos = choice.pos;
        var overflow = 0;


        // calculate amount of space available given specified position of node
        var spaceAvailable = {
         w: corner.charAt(1) == 'L' ? (view.l + view.w) - pos.x : pos.x - view.l,
         h: corner.charAt(1) == 'T' ? (view.t + view.h) - pos.y : pos.y - view.t
        };


        // 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 tooltip's size changes based on position, due to triangle)
        if(layoutNode){
         var res = layoutNode(node, choice.aroundCorner, corner, spaceAvailable, aroundNodeCoords);
         overflow = typeof res == "undefined" ? 0 : res;
        }


        // get node's size
        var style = node.style;
        var oldDisplay = style.display;
        var oldVis = style.visibility;
        style.visibility = "hidden";
        style.display = "";
        var mb = dojo.marginBox(node);
        style.display = oldDisplay;
        style.visibility = oldVis;


        // coordinates and size of node with specified corner placed at pos,
        // and clipped by viewport
        var startX = Math.max(view.l, corner.charAt(1) == 'L' ? pos.x : (pos.x - mb.w)),
         startY = Math.max(view.t, corner.charAt(0) == 'T' ? pos.y : (pos.y - mb.h)),
         endX = Math.min(view.l + view.w, corner.charAt(1) == 'L' ? (startX + mb.w) : pos.x),
         endY = Math.min(view.t + view.h, corner.charAt(0) == 'T' ? (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: choice.aroundCorner,
          x: startX,
          y: startY,
          w: width,
          h: height,
          overflow: overflow,
          spaceAvailable: spaceAvailable
         };
        }

        
        return !overflow;
       });


       // In case the best position is not the last one we checked, need to call
       // layoutNode() again.
       if(best.overflow && layoutNode){
        layoutNode(node, best.aroundCorner, best.corner, best.spaceAvailable, aroundNodeCoords);
       }


       // And then position the node. Do this last, after the layoutNode() above
       // has sized the node, due to browser quirks when the viewport is scrolled
       // (specifically that a Tooltip will shrink to fit as though the window was
       // scrolled to the left).
       //
       // In RTL mode, set style.right rather than style.left so in the common case,
       // window resizes move the popup along with the aroundNode.
       var l = dojo._isBodyLtr(),
        s = node.style;
       s.top = best.y + "px";
       s[l ? "left" : "right"] = (l ? best.x : view.w - best.x - best.w) + "px";

       
       return best;
      }


      dijit.placeOnScreenAroundNode = function(
       /* DomNode */  node,
       /* DomNode */  aroundNode,
       /* Object */  aroundCorners,
       /* Function? */  layoutNode){


       // summary:
       //  Position node adjacent or kitty-corner to aroundNode
       //  such that it's fully visible in viewport.
       //
       // description:
       //  Place node such that corner of node touches a corner of
       //  aroundNode, and that node is fully visible.
       //
       // aroundCorners:
       //  Ordered list of pairs of corners to try matching up.
       //  Each pair of corners is represented as a key/value in the hash,
       //  where the key corresponds to the aroundNode's corner, and
       //  the value corresponds to the node's corner:
       //
       // | { aroundNodeCorner1: nodeCorner1, aroundNodeCorner2: nodeCorner2, ...}
       //
       //  The following strings are used to represent the four corners:
       //   * "BL" - bottom left
       //   * "BR" - bottom right
       //   * "TL" - top left
       //   * "TR" - top right
       //
       // layoutNode: Function(node, aroundNodeCorner, nodeCorner)
       //  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.
       //
       // example:
       // | dijit.placeOnScreenAroundNode(node, aroundNode, {'BL':'TL', 'TR':'BR'});
       //  This will try to position node such that node's top-left corner is at the same position
       //  as the bottom left corner of the aroundNode (ie, put node below
       //  aroundNode, with left edges aligned). If that fails it will try to put
       //   the bottom-right corner of node where the top right corner of aroundNode is
       //  (ie, put node above aroundNode, with right edges aligned)
       //


       // get coordinates of aroundNode
       aroundNode = dojo.byId(aroundNode);
       var aroundNodePos = dojo.position(aroundNode, true);


       // place the node around the calculated rectangle
       return dijit._placeOnScreenAroundRect(node,
        aroundNodePos.x, aroundNodePos.y, aroundNodePos.w, aroundNodePos.h, // rectangle
        aroundCorners, layoutNode);
      };




      dijit.__Rectangle = function(){
       // x: Integer
       //  horizontal offset in pixels, relative to document body
       // y: Integer
       //  vertical offset in pixels, relative to document body
       // width: Integer
       //  width in pixels
       // height: Integer
       //  height in pixels


       this.x = x;
       this.y = y;
       this.width = width;
       this.height = height;
    • summary
  • dijit.__Rectangle.x

    • type
      Integer
    • summary
      horizontal offset in pixels, relative to document body
  • dijit.__Rectangle.y

    • type
      Integer
    • summary
      vertical offset in pixels, relative to document body
  • dijit.__Rectangle.width

    • type
      Integer
    • summary
      width in pixels
  • dijit.__Rectangle.height

    • type
      Integer
    • summary
      height in pixels
  • dijit.placeOnScreenAroundRectangle

    • type
      Function
    • parameters:
      • node: (typeof DomNode)
      • aroundRect: (typeof dijit.__Rectangle)
      • aroundCorners: (typeof Object)
      • layoutNode: (typeof Function)
    • source: [view]
       return dijit._placeOnScreenAroundRect(node,
        aroundRect.x, aroundRect.y, aroundRect.width, aroundRect.height, // rectangle
        aroundCorners, layoutNode);
    • summary
      Like dijit.placeOnScreenAroundNode(), except that the &quot;around&quot;
      parameter is an arbitrary rectangle on the screen (x, y, width, height)
      instead of a dom node.
  • dijit._placeOnScreenAroundRect

    • type
      Function
    • parameters:
      • node: (typeof DomNode)
      • x: (typeof Number)
      • y: (typeof Number)
      • width: (typeof Number)
      • height: (typeof Number)
      • aroundCorners: (typeof Object)
      • layoutNode: (typeof Function)
    • source: [view]
      define("dijit/_base/place", ["dojo", "dijit", "dojo/window", "dojo/AdapterRegistry"], function(dojo, dijit) {


      dijit.getViewport = function(){
       // summary:
       //  Returns the dimensions and scroll position of the viewable area of a browser window


       return dojo.window.getBox();
      };




      dijit.__Position = function(){
       // x: Integer
       //  horizontal coordinate in pixels, relative to document body
       // y: Integer
       //  vertical coordinate in pixels, relative to document body


       thix.x = x;
       this.y = y;
      }






      dijit.placeOnScreen = function(
       /* DomNode */   node,
       /* dijit.__Position */ pos,
       /* String[] */   corners,
       /* dijit.__Position? */ padding){
       // summary:
       //  Positions one of the node's corners at specified position
       //  such that node is fully visible in viewport.
       // description:
       //  NOTE: node is assumed to be absolutely or relatively positioned.
       // pos:
       //  Object like {x: 10, y: 20}
       // corners:
       //  Array of Strings representing order to try corners in, like ["TR", "BL"].
       //  Possible values are:
       //   * "BL" - bottom left
       //   * "BR" - bottom right
       //   * "TL" - top left
       //   * "TR" - top right
       // padding:
       //  set padding to put some buffer around the element you want to position.
       // example:
       //  Try to place node's top right corner at (10,20).
       //  If that makes node go (partially) off screen, then try placing
       //  bottom left corner at (10,20).
       // | placeOnScreen(node, {x: 10, y: 20}, ["TR", "BL"])


       var choices = dojo.map(corners, function(corner){
        var c = { corner: corner, pos: {x:pos.x,y:pos.y} };
        if(padding){
         c.pos.x += corner.charAt(1) == 'L' ? padding.x : -padding.x;
         c.pos.y += corner.charAt(0) == 'T' ? padding.y : -padding.y;
        }
        return c;
       });


       return dijit._place(node, choices);
      }


      dijit._place = function(/*DomNode*/ node, choices, layoutNode, /*Object*/ aroundNodeCoords){
       // 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, aroundNodeCorner, nodeCorner, size)
       //  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.
       //  It also passes in the available size for the popup, which is useful for tooltips to
       //  tell them that their width is limited to a certain amount. layoutNode() may return a value expressing
       //  how much the popup had to be modified to fit into the available space. This is used to determine
       //  what the best placement is.
       // aroundNodeCoords: Object
       //  Size of aroundNode, ex: {w: 200, h: 50}


       // get {x: 10, y: 10, w: 100, h:100} type obj representing position of
       // viewport over document
       var view = dojo.window.getBox();


       // This won't work if the node is inside a
      ,
       // so reattach it to dojo.doc.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;
       dojo.some(choices, function(choice){
        var corner = choice.corner;
        var pos = choice.pos;
        var overflow = 0;


        // calculate amount of space available given specified position of node
        var spaceAvailable = {
         w: corner.charAt(1) == 'L' ? (view.l + view.w) - pos.x : pos.x - view.l,
         h: corner.charAt(1) == 'T' ? (view.t + view.h) - pos.y : pos.y - view.t
        };


        // 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 tooltip's size changes based on position, due to triangle)
        if(layoutNode){
         var res = layoutNode(node, choice.aroundCorner, corner, spaceAvailable, aroundNodeCoords);
         overflow = typeof res == "undefined" ? 0 : res;
        }


        // get node's size
        var style = node.style;
        var oldDisplay = style.display;
        var oldVis = style.visibility;
        style.visibility = "hidden";
        style.display = "";
        var mb = dojo.marginBox(node);
        style.display = oldDisplay;
        style.visibility = oldVis;


        // coordinates and size of node with specified corner placed at pos,
        // and clipped by viewport
        var startX = Math.max(view.l, corner.charAt(1) == 'L' ? pos.x : (pos.x - mb.w)),
         startY = Math.max(view.t, corner.charAt(0) == 'T' ? pos.y : (pos.y - mb.h)),
         endX = Math.min(view.l + view.w, corner.charAt(1) == 'L' ? (startX + mb.w) : pos.x),
         endY = Math.min(view.t + view.h, corner.charAt(0) == 'T' ? (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: choice.aroundCorner,
          x: startX,
          y: startY,
          w: width,
          h: height,
          overflow: overflow,
          spaceAvailable: spaceAvailable
         };
        }

        
        return !overflow;
       });


       // In case the best position is not the last one we checked, need to call
       // layoutNode() again.
       if(best.overflow && layoutNode){
        layoutNode(node, best.aroundCorner, best.corner, best.spaceAvailable, aroundNodeCoords);
       }


       // And then position the node. Do this last, after the layoutNode() above
       // has sized the node, due to browser quirks when the viewport is scrolled
       // (specifically that a Tooltip will shrink to fit as though the window was
       // scrolled to the left).
       //
       // In RTL mode, set style.right rather than style.left so in the common case,
       // window resizes move the popup along with the aroundNode.
       var l = dojo._isBodyLtr(),
        s = node.style;
       s.top = best.y + "px";
       s[l ? "left" : "right"] = (l ? best.x : view.w - best.x - best.w) + "px";

       
       return best;
      }


      dijit.placeOnScreenAroundNode = function(
       /* DomNode */  node,
       /* DomNode */  aroundNode,
       /* Object */  aroundCorners,
       /* Function? */  layoutNode){


       // summary:
       //  Position node adjacent or kitty-corner to aroundNode
       //  such that it's fully visible in viewport.
       //
       // description:
       //  Place node such that corner of node touches a corner of
       //  aroundNode, and that node is fully visible.
       //
       // aroundCorners:
       //  Ordered list of pairs of corners to try matching up.
       //  Each pair of corners is represented as a key/value in the hash,
       //  where the key corresponds to the aroundNode's corner, and
       //  the value corresponds to the node's corner:
       //
       // | { aroundNodeCorner1: nodeCorner1, aroundNodeCorner2: nodeCorner2, ...}
       //
       //  The following strings are used to represent the four corners:
       //   * "BL" - bottom left
       //   * "BR" - bottom right
       //   * "TL" - top left
       //   * "TR" - top right
       //
       // layoutNode: Function(node, aroundNodeCorner, nodeCorner)
       //  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.
       //
       // example:
       // | dijit.placeOnScreenAroundNode(node, aroundNode, {'BL':'TL', 'TR':'BR'});
       //  This will try to position node such that node's top-left corner is at the same position
       //  as the bottom left corner of the aroundNode (ie, put node below
       //  aroundNode, with left edges aligned). If that fails it will try to put
       //   the bottom-right corner of node where the top right corner of aroundNode is
       //  (ie, put node above aroundNode, with right edges aligned)
       //


       // get coordinates of aroundNode
       aroundNode = dojo.byId(aroundNode);
       var aroundNodePos = dojo.position(aroundNode, true);


       // place the node around the calculated rectangle
       return dijit._placeOnScreenAroundRect(node,
        aroundNodePos.x, aroundNodePos.y, aroundNodePos.w, aroundNodePos.h, // rectangle
        aroundCorners, layoutNode);
      };




      dijit.__Rectangle = function(){
       // x: Integer
       //  horizontal offset in pixels, relative to document body
       // y: Integer
       //  vertical offset in pixels, relative to document body
       // width: Integer
       //  width in pixels
       // height: Integer
       //  height in pixels


       this.x = x;
       this.y = y;
       this.width = width;
       this.height = height;
      }






      dijit.placeOnScreenAroundRectangle = function(
       /* DomNode */   node,
       /* dijit.__Rectangle */ aroundRect,
       /* Object */   aroundCorners,
       /* Function */   layoutNode){


       // summary:
       //  Like dijit.placeOnScreenAroundNode(), except that the "around"
       //  parameter is an arbitrary rectangle on the screen (x, y, width, height)
       //  instead of a dom node.


       return dijit._placeOnScreenAroundRect(node,
        aroundRect.x, aroundRect.y, aroundRect.width, aroundRect.height, // rectangle
        aroundCorners, layoutNode);
      };


      dijit._placeOnScreenAroundRect = function(
       /* DomNode */  node,
       /* Number */  x,
       /* Number */  y,
       /* Number */  width,
       /* Number */  height,
       /* Object */  aroundCorners,
       /* Function */  layoutNode){


       // summary:
       //  Like dijit.placeOnScreenAroundNode(), except it accepts coordinates
       //  of a rectangle to place node adjacent to.


       // TODO: combine with placeOnScreenAroundRectangle()


       // Generate list of possible positions for node
       var choices = [];
       for(var nodeCorner in aroundCorners){
        choices.push( {
         aroundCorner: nodeCorner,
         corner: aroundCorners[nodeCorner],
         pos: {
          x: x + (nodeCorner.charAt(1) == 'L' ? 0 : width),
          y: y + (nodeCorner.charAt(0) == 'T' ? 0 : height)
         }
        });
       }


       return dijit._place(node, choices, layoutNode, {w: width, h: height});
    • summary
  • dijit.placeOnScreenAroundElement

    • type
      Function
    • parameters:
      • node: (typeof DomNode)
      • aroundElement: (typeof Object)
      • aroundCorners: (typeof Object)
      • layoutNode: (typeof Function)
    • source: [view]
       return dijit.placementRegistry.match.apply(dijit.placementRegistry, arguments);
    • summary
      Like dijit.placeOnScreenAroundNode(), except it accepts an arbitrary object
      for the &quot;around&quot; argument and finds a proper processor to place a node.
    • chains:
      • dijit.placementRegistry.match: (call)
  • dijit.getPopupAroundAlignment

    • type
      Function
    • parameters:
      • position: (typeof Array)
        String[]
        This variable controls the position of the drop down.
        It's an array of strings with the following values:
        
        * before: places drop down to the left of the target node/widget, or to the right in
        the case of RTL scripts like Hebrew and Arabic
        * after: places drop down to the right of the target node/widget, or to the left in
        the case of RTL scripts like Hebrew and Arabic
        * above: drop down goes above target node
        * below: drop down goes below target node
        
        The list is positions is tried, in order, until a position is found where the drop down fits
        within the viewport.
      • leftToRight: (typeof Boolean)
        Whether the popup will be displaying in leftToRight mode.
    • source: [view]
       var align = {};
       dojo.forEach(position, function(pos){
        switch(pos){
         case "after":
          align[leftToRight ? "BR" : "BL"] = leftToRight ? "BL" : "BR";
          break;
         case "before":
          align[leftToRight ? "BL" : "BR"] = leftToRight ? "BR" : "BL";
          break;
         case "below-alt":
          leftToRight = !leftToRight;
          // fall through
         case "below":
          // first try to align left borders, next try to align right borders (or reverse for RTL mode)
          align[leftToRight ? "BL" : "BR"] = leftToRight ? "TL" : "TR";
          align[leftToRight ? "BR" : "BL"] = leftToRight ? "TR" : "TL";
          break;
         case "above-alt":
          leftToRight = !leftToRight;
          // fall through
         case "above":
         default:
          // first try to align left borders, next try to align right borders (or reverse for RTL mode)
          align[leftToRight ? "TL" : "TR"] = leftToRight ? "BL" : "BR";
          align[leftToRight ? "TR" : "TL"] = leftToRight ? "BR" : "BL";
          break;
        }
       });
       return align;
    • summary
      Transforms the passed array of preferred positions into a format suitable for passing as the aroundCorners argument to dijit.placeOnScreenAroundElement.
  • dijit.placementRegistry

    • summary
  • dijit

    • type
      Object
    • summary