@@ -13,6 +13,8 @@ describe('$mdPanel', function() {
1313  var  DEFAULT_CONFIG  =  {  template : DEFAULT_TEMPLATE  } ; 
1414  var  PANEL_ID_PREFIX  =  'panel_' ; 
1515  var  SCROLL_MASK_CLASS  =  '.md-scroll-mask' ; 
16+   var  ADJUSTED_CLASS  =  '_md-panel-position-adjusted' ; 
17+   var  VIEWPORT_MARGIN  =  8 ; 
1618
1719  /** 
1820   * @param  {!angular.$injector } $injector 
@@ -1261,6 +1263,7 @@ describe('$mdPanel', function() {
12611263        myButton  =  '<button>myButton</button>' ; 
12621264        attachToBody ( myButton ) ; 
12631265        myButton  =  angular . element ( document . querySelector ( 'button' ) ) ; 
1266+         myButton . css ( 'margin' ,  '100px' ) ; 
12641267        myButtonRect  =  myButton [ 0 ] . getBoundingClientRect ( ) ; 
12651268      } ) ; 
12661269
@@ -1310,6 +1313,7 @@ describe('$mdPanel', function() {
13101313        expect ( panelRect . top ) . toBeApproximately ( myButtonRect . top ) ; 
13111314        expect ( panelRect . left ) . toBeApproximately ( myButtonRect . left ) ; 
13121315
1316+ 
13131317        var  newPosition  =  $mdPanel . newPanelPosition ( ) 
13141318            . relativeTo ( myButton ) 
13151319            . addPanelPosition ( null ,  yPosition . ABOVE ) ; 
@@ -1725,6 +1729,7 @@ describe('$mdPanel', function() {
17251729        myButton  =  '<button>myButton</button>' ; 
17261730        attachToBody ( myButton ) ; 
17271731        myButton  =  angular . element ( document . querySelector ( 'button' ) ) ; 
1732+         myButton . css ( 'margin' ,  '100px' ) ; 
17281733        myButtonRect  =  myButton [ 0 ] . getBoundingClientRect ( ) ; 
17291734
17301735        xPosition  =  $mdPanel . xPosition ; 
@@ -1773,100 +1778,108 @@ describe('$mdPanel', function() {
17731778        expect ( panelCss . top ) . toBeApproximately ( myButtonRect . top ) ; 
17741779      } ) ; 
17751780
1776-       it ( 'rejects offscreen position left of target element ',  function ( )  { 
1777-         var   position   =   mdPanelPosition 
1778-              . relativeTo ( myButton ) 
1779-              . addPanelPosition ( xPosition . OFFSET_START ,   yPosition . ALIGN_TOPS ) 
1780-              . addPanelPosition ( xPosition . ALIGN_START ,   yPosition . ALIGN_TOPS ) ; 
1781+       describe ( 'fallback positions ',  function ( )  { 
1782+         beforeEach ( function ( )   { 
1783+           myButton . css ( 'margin' ,   0 ) ; 
1784+           myButtonRect   =   myButton [ 0 ] . getBoundingClientRect ( ) ; 
1785+         } ) ; 
17811786
1782-         config [ 'position' ]  =  position ; 
1787+         it ( 'rejects offscreen position left of target element' ,  function ( )  { 
1788+           var  position  =  mdPanelPosition 
1789+               . relativeTo ( myButton ) 
1790+               . addPanelPosition ( xPosition . OFFSET_START ,  yPosition . ALIGN_TOPS ) 
1791+               . addPanelPosition ( xPosition . ALIGN_START ,  yPosition . ALIGN_TOPS ) ; 
17831792
1784-         openPanel ( config ) ; 
1793+           config [ 'position' ]  =  position ; 
1794+ 
1795+           openPanel ( config ) ; 
1796+ 
1797+           expect ( position . getActualPosition ( ) ) . toEqual ( { 
1798+             x : xPosition . ALIGN_START , 
1799+             y : yPosition . ALIGN_TOPS , 
1800+           } ) ; 
17851801
1786-         expect ( position . getActualPosition ( ) ) . toEqual ( { 
1787-           x :  xPosition . ALIGN_START , 
1788-           y :  yPosition . ALIGN_TOPS , 
1802+            var   panelCss   =   document . querySelector ( PANEL_EL ) . style ; 
1803+           expect ( panelCss . left ) . toBeApproximately ( myButtonRect . left ) ; 
1804+           expect ( panelCss . top ) . toBeApproximately ( myButtonRect . top ) ; 
17891805        } ) ; 
1790-         var  panelCss  =  document . querySelector ( PANEL_EL ) . style ; 
1791-         expect ( panelCss . left ) . toBeApproximately ( myButtonRect . left ) ; 
1792-         expect ( panelCss . top ) . toBeApproximately ( myButtonRect . top ) ; 
1793-       } ) ; 
17941806
1795-       it ( 'rejects offscreen position above target element' ,  function ( )  { 
1796-         var  position  =  mdPanelPosition 
1797-             . relativeTo ( myButton ) 
1798-             . addPanelPosition ( xPosition . ALIGN_START ,  yPosition . ABOVE ) 
1799-             . addPanelPosition ( xPosition . ALIGN_START ,  yPosition . ALIGN_TOPS ) ; 
1807+          it ( 'rejects offscreen position above target element' ,  function ( )  { 
1808+            var  position  =  mdPanelPosition 
1809+                . relativeTo ( myButton ) 
1810+                . addPanelPosition ( xPosition . ALIGN_START ,  yPosition . ABOVE ) 
1811+                . addPanelPosition ( xPosition . ALIGN_START ,  yPosition . ALIGN_TOPS ) ; 
18001812
1801-         config [ 'position' ]  =  position ; 
1813+            config [ 'position' ]  =  position ; 
18021814
1803-         openPanel ( config ) ; 
1815+            openPanel ( config ) ; 
18041816
1805-         expect ( position . getActualPosition ( ) ) . toEqual ( { 
1806-           x : xPosition . ALIGN_START , 
1807-           y : yPosition . ALIGN_TOPS , 
1817+           expect ( position . getActualPosition ( ) ) . toEqual ( { 
1818+             x : xPosition . ALIGN_START , 
1819+             y : yPosition . ALIGN_TOPS , 
1820+           } ) ; 
18081821        } ) ; 
1809-       } ) ; 
18101822
1811-       it ( 'rejects offscreen position below target element' ,  function ( )  { 
1812-         // reposition button at the bottom of the screen 
1813-         $rootEl [ 0 ] . style . height  =  "100%" ; 
1814-         myButton [ 0 ] . style . position  =  'absolute' ; 
1815-         myButton [ 0 ] . style . bottom  =  '0px' ; 
1816-         myButtonRect  =  myButton [ 0 ] . getBoundingClientRect ( ) ; 
1823+          it ( 'rejects offscreen position below target element' ,  function ( )  { 
1824+            // reposition button at the bottom of the screen 
1825+            $rootEl [ 0 ] . style . height  =  "100%" ; 
1826+            myButton [ 0 ] . style . position  =  'absolute' ; 
1827+            myButton [ 0 ] . style . bottom  =  '0px' ; 
1828+            myButtonRect  =  myButton [ 0 ] . getBoundingClientRect ( ) ; 
18171829
1818-         var  position  =  mdPanelPosition 
1819-             . relativeTo ( myButton ) 
1820-             . addPanelPosition ( xPosition . ALIGN_START ,  yPosition . BELOW ) 
1821-             . addPanelPosition ( xPosition . ALIGN_START ,  yPosition . ALIGN_TOPS ) ; 
1830+            var  position  =  mdPanelPosition 
1831+                . relativeTo ( myButton ) 
1832+                . addPanelPosition ( xPosition . ALIGN_START ,  yPosition . BELOW ) 
1833+                . addPanelPosition ( xPosition . ALIGN_START ,  yPosition . ALIGN_TOPS ) ; 
18221834
1823-         config [ 'position' ]  =  position ; 
1835+            config [ 'position' ]  =  position ; 
18241836
1825-         openPanel ( config ) ; 
1837+            openPanel ( config ) ; 
18261838
1827-         expect ( position . getActualPosition ( ) ) . toEqual ( { 
1828-           x : xPosition . ALIGN_START , 
1829-           y : yPosition . ALIGN_TOPS , 
1839+           expect ( position . getActualPosition ( ) ) . toEqual ( { 
1840+             x : xPosition . ALIGN_START , 
1841+             y : yPosition . ALIGN_TOPS , 
1842+           } ) ; 
18301843        } ) ; 
1831-       } ) ; 
18321844
1833-       it ( 'rejects offscreen position right of target element' ,  function ( )  { 
1834-         // reposition button at the bottom of the screen 
1835-         $rootEl [ 0 ] . style . width  =  "100%" ; 
1836-         myButton [ 0 ] . style . position  =  'absolute' ; 
1837-         myButton [ 0 ] . style . right  =  '0px' ; 
1838-         myButtonRect  =  myButton [ 0 ] . getBoundingClientRect ( ) ; 
1845+          it ( 'rejects offscreen position right of target element' ,  function ( )  { 
1846+            // reposition button at the bottom of the screen 
1847+            $rootEl [ 0 ] . style . width  =  "100%" ; 
1848+            myButton [ 0 ] . style . position  =  'absolute' ; 
1849+            myButton [ 0 ] . style . right  =  '0px' ; 
1850+            myButtonRect  =  myButton [ 0 ] . getBoundingClientRect ( ) ; 
18391851
1840-         var  position  =  mdPanelPosition 
1841-             . relativeTo ( myButton ) 
1842-             . addPanelPosition ( xPosition . OFFSET_END ,  yPosition . ALIGN_TOPS ) 
1843-             . addPanelPosition ( xPosition . ALIGN_START ,  yPosition . ALIGN_TOPS ) ; 
1852+            var  position  =  mdPanelPosition 
1853+                . relativeTo ( myButton ) 
1854+                . addPanelPosition ( xPosition . OFFSET_END ,  yPosition . ALIGN_TOPS ) 
1855+                . addPanelPosition ( xPosition . ALIGN_START ,  yPosition . ALIGN_TOPS ) ; 
18441856
1845-         config [ 'position' ]  =  position ; 
1857+            config [ 'position' ]  =  position ; 
18461858
1847-         openPanel ( config ) ; 
1859+            openPanel ( config ) ; 
18481860
1849-         expect ( position . getActualPosition ( ) ) . toEqual ( { 
1850-           x : xPosition . ALIGN_START , 
1851-           y : yPosition . ALIGN_TOPS , 
1861+           expect ( position . getActualPosition ( ) ) . toEqual ( { 
1862+             x : xPosition . ALIGN_START , 
1863+             y : yPosition . ALIGN_TOPS , 
1864+           } ) ; 
18521865        } ) ; 
1853-       } ) ; 
18541866
1855-       it ( 'should choose last position if none are on-screen' ,  function ( )  { 
1856-         var  position  =  mdPanelPosition 
1857-             . relativeTo ( myButton ) 
1858-             // off-screen to the left 
1859-             . addPanelPosition ( xPosition . OFFSET_START ,  yPosition . ALIGN_TOPS ) 
1860-             // off-screen at the top 
1861-             . addPanelPosition ( xPosition . ALIGN_START ,  yPosition . ALIGN_TOPS ) ; 
1867+          it ( 'should choose last position if none are on-screen' ,  function ( )  { 
1868+            var  position  =  mdPanelPosition 
1869+                . relativeTo ( myButton ) 
1870+                // off-screen to the left 
1871+                . addPanelPosition ( xPosition . OFFSET_START ,  yPosition . ALIGN_TOPS ) 
1872+                // off-screen at the top 
1873+                . addPanelPosition ( xPosition . ALIGN_START ,  yPosition . ALIGN_TOPS ) ; 
18621874
1863-         config [ 'position' ]  =  position ; 
1875+            config [ 'position' ]  =  position ; 
18641876
1865-         openPanel ( config ) ; 
1877+            openPanel ( config ) ; 
18661878
1867-         expect ( position . getActualPosition ( ) ) . toEqual ( { 
1868-           x : xPosition . ALIGN_START , 
1869-           y : yPosition . ALIGN_TOPS , 
1879+           expect ( position . getActualPosition ( ) ) . toEqual ( { 
1880+             x : xPosition . ALIGN_START , 
1881+             y : yPosition . ALIGN_TOPS , 
1882+           } ) ; 
18701883        } ) ; 
18711884      } ) ; 
18721885
@@ -1943,6 +1956,49 @@ describe('$mdPanel', function() {
19431956              . getBoundingClientRect ( ) ; 
19441957          expect ( panelRect . top ) . toBeApproximately ( myButtonRect . bottom ) ; 
19451958        } ) ; 
1959+ 
1960+         it ( 'element outside the left boundry of the viewport' ,  function ( )  { 
1961+           var  position  =  mdPanelPosition 
1962+               . relativeTo ( myButton ) 
1963+               . addPanelPosition ( xPosition . ALIGN_END ,  yPosition . ALIGN_TOPS ) ; 
1964+ 
1965+           config [ 'position' ]  =  position ; 
1966+ 
1967+           myButton . css ( { 
1968+             position : 'absolute' , 
1969+             left : '-100px' , 
1970+             margin : 0 
1971+           } ) ; 
1972+ 
1973+           openPanel ( config ) ; 
1974+ 
1975+           var  panel  =  document . querySelector ( PANEL_EL ) ; 
1976+ 
1977+           expect ( panel . offsetLeft ) . toBe ( VIEWPORT_MARGIN ) ; 
1978+           expect ( panel ) . toHaveClass ( ADJUSTED_CLASS ) ; 
1979+         } ) ; 
1980+ 
1981+         it ( 'element outside the right boundry of the viewport' ,  function ( )  { 
1982+           var  position  =  mdPanelPosition 
1983+               . relativeTo ( myButton ) 
1984+               . addPanelPosition ( xPosition . ALIGN_START ,  yPosition . ALIGN_TOPS ) ; 
1985+ 
1986+           config [ 'position' ]  =  position ; 
1987+ 
1988+           myButton . css ( { 
1989+             position : 'absolute' , 
1990+             right : '-100px' , 
1991+             margin : 0 
1992+           } ) ; 
1993+ 
1994+           openPanel ( config ) ; 
1995+ 
1996+           var  panel  =  document . querySelector ( PANEL_EL ) ; 
1997+           var  panelRect  =  panel . getBoundingClientRect ( ) ; 
1998+ 
1999+           expect ( panelRect . left  +  panelRect . width ) . toBeLessThan ( window . innerWidth ) ; 
2000+           expect ( panel ) . toHaveClass ( ADJUSTED_CLASS ) ; 
2001+         } ) ; 
19462002      } ) ; 
19472003
19482004      describe ( 'horizontally' ,  function ( )  { 
@@ -2019,6 +2075,49 @@ describe('$mdPanel', function() {
20192075          expect ( panelRect . left ) . toBeApproximately ( myButtonRect . right ) ; 
20202076        } ) ; 
20212077
2078+         it ( 'element outside the top boundry of the viewport' ,  function ( )  { 
2079+           var  position  =  mdPanelPosition 
2080+               . relativeTo ( myButton ) 
2081+               . addPanelPosition ( xPosition . ALIGN_START ,  yPosition . ABOVE ) ; 
2082+ 
2083+           config [ 'position' ]  =  position ; 
2084+ 
2085+           myButton . css ( { 
2086+             position : 'absolute' , 
2087+             top : 0 , 
2088+             margin : 0 
2089+           } ) ; 
2090+ 
2091+           openPanel ( config ) ; 
2092+ 
2093+           var  panel  =  document . querySelector ( PANEL_EL ) ; 
2094+ 
2095+           expect ( panel . offsetTop ) . toBe ( VIEWPORT_MARGIN ) ; 
2096+           expect ( panel ) . toHaveClass ( ADJUSTED_CLASS ) ; 
2097+         } ) ; 
2098+ 
2099+         it ( 'element outside the bottom boundry of the viewport' ,  function ( )  { 
2100+           var  position  =  mdPanelPosition 
2101+               . relativeTo ( myButton ) 
2102+               . addPanelPosition ( xPosition . ALIGN_START ,  yPosition . BELOW ) ; 
2103+ 
2104+           config [ 'position' ]  =  position ; 
2105+ 
2106+           myButton . css ( { 
2107+             position : 'absolute' , 
2108+             bottom : 0 , 
2109+             margin : 0 
2110+           } ) ; 
2111+ 
2112+           openPanel ( config ) ; 
2113+ 
2114+           var  panel  =  document . querySelector ( PANEL_EL ) ; 
2115+           var  panelRect  =  panel . getBoundingClientRect ( ) ; 
2116+ 
2117+           expect ( panelRect . top  +  panelRect . height ) . toBeLessThan ( window . innerHeight ) ; 
2118+           expect ( panel ) . toHaveClass ( ADJUSTED_CLASS ) ; 
2119+         } ) ; 
2120+ 
20222121        describe ( 'rtl' ,  function  ( )  { 
20232122          beforeEach ( function  ( )  { 
20242123            setRTL ( ) ; 
0 commit comments