@@ -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