@@ -236,7 +236,7 @@ angular
236236 * - `locals` - `{Object=}`: An object containing key/value pairs. The keys
237237 * will be used as names of values to inject into the controller. For
238238 * example, `locals: {three: 3}` would inject `three` into the controller,
239- * with the value 3. 'mdPanelRef' is a reserved key, and will always
239+ * with the value 3. 'mdPanelRef' is a reserved key, and will always
240240 * be set to the created MdPanelRef instance.
241241 * - `resolve` - `{Object=}`: Similar to locals, except it takes promises as
242242 * values. The panel will not open until all of the promises resolve.
@@ -1296,10 +1296,10 @@ MdPanelService.prototype._closeFirstOpenedPanel = function(groupName) {
12961296
12971297
12981298/**
1299- * Wraps the users template in two elements, md-panel-outer-wrapper, which
1300- * covers the entire attachTo element, and md-panel, which contains only the
1301- * template. This allows the panel control over positioning, animations,
1302- * and similar properties .
1299+ * Wraps the user's template in three elements:
1300+ * - md-panel-outer-wrapper - covers the entire ` attachTo` element.
1301+ * - md- panel-inner-wrapper - handles the positioning.
1302+ * - md-panel - contains the user's content and deals with the animations .
13031303 * @param {string} origTemplate The original template.
13041304 * @returns {string} The wrapped template.
13051305 * @private
@@ -1311,26 +1311,32 @@ MdPanelService.prototype._wrapTemplate = function(origTemplate) {
13111311 // height and width for positioning.
13121312 return '' +
13131313 '<div class="md-panel-outer-wrapper">' +
1314- ' <div class="md-panel _md-panel-offscreen">' + template + '</div>' +
1314+ '<div class="md-panel-inner-wrapper" style="left: -9999px;">' +
1315+ '<div class="md-panel _md-panel-offscreen">' + template + '</div>' +
1316+ '</div>' +
13151317 '</div>';
13161318};
13171319
13181320
13191321/**
1320- * Wraps a content element in a md-panel-outer wrapper and
1321- * positions it off-screen. Allows for proper control over positoning
1322- * and animations.
1322+ * Wraps a content element in a ` md-panel-outer- wrapper`, as well as
1323+ * a `md-panel-inner-wrapper`, and positions it off-screen. Allows for
1324+ * proper control over positoning and animations.
13231325 * @param {!angular.JQLite} contentElement Element to be wrapped.
13241326 * @return {!angular.JQLite} Wrapper element.
13251327 * @private
13261328 */
13271329MdPanelService.prototype._wrapContentElement = function(contentElement) {
1328- var wrapper = angular.element('<div class="md-panel-outer-wrapper">');
1330+ var outerWrapper = angular.element(
1331+ '<div class="md-panel-outer-wrapper">' +
1332+ '<div class="md-panel-inner-wrapper" style="left: -9999px;"></div>' +
1333+ '</div>'
1334+ );
13291335
13301336 contentElement.addClass('md-panel _md-panel-offscreen');
1331- wrapper .append(contentElement);
1337+ outerWrapper.children().eq(0) .append(contentElement);
13321338
1333- return wrapper ;
1339+ return outerWrapper ;
13341340};
13351341
13361342
@@ -1397,6 +1403,9 @@ function MdPanelRef(config, $injector) {
13971403 /** @type {!angular.JQLite|undefined} */
13981404 this.panelEl;
13991405
1406+ /** @type {!angular.JQLite|undefined} */
1407+ this.innerWrapper;
1408+
14001409 /**
14011410 * Whether the panel is attached. This is synchronous. When attach is called,
14021411 * isAttached is set to true. When detach is called, isAttached is set to
@@ -1839,6 +1848,11 @@ MdPanelRef.prototype._compile = function() {
18391848 );
18401849 }
18411850
1851+ // Save a reference to the inner wrapper.
1852+ self.innerWrapper = angular.element(
1853+ self.panelContainer[0].querySelector('.md-panel-inner-wrapper')
1854+ );
1855+
18421856 // Save a reference to the cleanup function from the compiler.
18431857 self._compilerCleanup = compileData.cleanup;
18441858
@@ -1915,14 +1929,17 @@ MdPanelRef.prototype._addStyles = function() {
19151929 var self = this;
19161930 return this._$q(function(resolve) {
19171931 self.panelContainer.css('z-index', self.config['zIndex']);
1918- self.panelEl .css('z-index', self.config['zIndex'] + 1);
1932+ self.innerWrapper .css('z-index', self.config['zIndex'] + 1);
19191933
19201934 var hideAndResolve = function() {
19211935 // Theme the element and container.
19221936 self._setTheming();
19231937
19241938 // Remove offscreen class and add hidden class.
19251939 self.panelEl.removeClass('_md-panel-offscreen');
1940+
1941+ // Remove left: -9999px and add hidden class.
1942+ self.innerWrapper.css('left', '');
19261943 self.panelContainer.addClass(MD_PANEL_HIDDEN);
19271944
19281945 resolve(self);
@@ -1989,27 +2006,27 @@ MdPanelRef.prototype._updatePosition = function(init) {
19892006 var positionConfig = this.config['position'];
19902007
19912008 if (positionConfig) {
1992- positionConfig._setPanelPosition(this.panelEl );
2009+ positionConfig._setPanelPosition(this.innerWrapper );
19932010
19942011 // Hide the panel now that position is known.
19952012 if (init) {
19962013 this.panelEl.removeClass('_md-panel-offscreen');
19972014 this.panelContainer.addClass(MD_PANEL_HIDDEN);
19982015 }
19992016
2000- this.panelEl .css(
2017+ this.innerWrapper .css(
20012018 MdPanelPosition.absPosition.TOP,
20022019 positionConfig.getTop()
20032020 );
2004- this.panelEl .css(
2021+ this.innerWrapper .css(
20052022 MdPanelPosition.absPosition.BOTTOM,
20062023 positionConfig.getBottom()
20072024 );
2008- this.panelEl .css(
2025+ this.innerWrapper .css(
20092026 MdPanelPosition.absPosition.LEFT,
20102027 positionConfig.getLeft()
20112028 );
2012- this.panelEl .css(
2029+ this.innerWrapper .css(
20132030 MdPanelPosition.absPosition.RIGHT,
20142031 positionConfig.getRight()
20152032 );
@@ -2916,38 +2933,38 @@ MdPanelPosition.prototype.getTransform = function() {
29162933
29172934
29182935/**
2919- * Sets the `transform` value for a panel element.
2920- * @param {!angular.JQLite} panelEl
2936+ * Sets the `transform` value for an element.
2937+ * @param {!angular.JQLite} el
29212938 * @returns {!angular.JQLite}
29222939 * @private
29232940 */
2924- MdPanelPosition.prototype._setTransform = function(panelEl ) {
2925- return panelEl .css(this._$mdConstant.CSS.TRANSFORM, this.getTransform());
2941+ MdPanelPosition.prototype._setTransform = function(el ) {
2942+ return el .css(this._$mdConstant.CSS.TRANSFORM, this.getTransform());
29262943};
29272944
29282945
29292946/**
29302947 * True if the panel is completely on-screen with this positioning; false
29312948 * otherwise.
2932- * @param {!angular.JQLite} panelEl
2949+ * @param {!angular.JQLite} el
29332950 * @return {boolean}
29342951 * @private
29352952 */
2936- MdPanelPosition.prototype._isOnscreen = function(panelEl ) {
2953+ MdPanelPosition.prototype._isOnscreen = function(el ) {
29372954 // this works because we always use fixed positioning for the panel,
29382955 // which is relative to the viewport.
29392956 var left = parseInt(this.getLeft());
29402957 var top = parseInt(this.getTop());
29412958
29422959 if (this._translateX.length || this._translateY.length) {
29432960 var prefixedTransform = this._$mdConstant.CSS.TRANSFORM;
2944- var offsets = getComputedTranslations(panelEl , prefixedTransform);
2961+ var offsets = getComputedTranslations(el , prefixedTransform);
29452962 left += offsets.x;
29462963 top += offsets.y;
29472964 }
29482965
2949- var right = left + panelEl [0].offsetWidth;
2950- var bottom = top + panelEl [0].offsetHeight;
2966+ var right = left + el [0].offsetWidth;
2967+ var bottom = top + el [0].offsetHeight;
29512968
29522969 return (left >= 0) &&
29532970 (top >= 0) &&
@@ -2987,53 +3004,53 @@ MdPanelPosition.prototype._reduceTranslateValues =
29873004/**
29883005 * Sets the panel position based on the created panel element and best x/y
29893006 * positioning.
2990- * @param {!angular.JQLite} panelEl
3007+ * @param {!angular.JQLite} el
29913008 * @private
29923009 */
2993- MdPanelPosition.prototype._setPanelPosition = function(panelEl ) {
2994- // Remove the "position adjusted" class in case it has been added before.
2995- panelEl .removeClass('_md-panel-position-adjusted');
3010+ MdPanelPosition.prototype._setPanelPosition = function(el ) {
3011+ // Remove the class in case it has been added before.
3012+ el .removeClass('_md-panel-position-adjusted');
29963013
29973014 // Only calculate the position if necessary.
29983015 if (this._absolute) {
2999- this._setTransform(panelEl );
3016+ this._setTransform(el );
30003017 return;
30013018 }
30023019
30033020 if (this._actualPosition) {
3004- this._calculatePanelPosition(panelEl , this._actualPosition);
3005- this._setTransform(panelEl );
3006- this._constrainToViewport(panelEl );
3021+ this._calculatePanelPosition(el , this._actualPosition);
3022+ this._setTransform(el );
3023+ this._constrainToViewport(el );
30073024 return;
30083025 }
30093026
30103027 for (var i = 0; i < this._positions.length; i++) {
30113028 this._actualPosition = this._positions[i];
3012- this._calculatePanelPosition(panelEl , this._actualPosition);
3013- this._setTransform(panelEl );
3029+ this._calculatePanelPosition(el , this._actualPosition);
3030+ this._setTransform(el );
30143031
3015- if (this._isOnscreen(panelEl )) {
3032+ if (this._isOnscreen(el )) {
30163033 return;
30173034 }
30183035 }
30193036
3020- this._constrainToViewport(panelEl );
3037+ this._constrainToViewport(el );
30213038};
30223039
30233040
30243041/**
30253042 * Constrains a panel's position to the viewport.
3026- * @param {!angular.JQLite} panelEl
3043+ * @param {!angular.JQLite} el
30273044 * @private
30283045 */
3029- MdPanelPosition.prototype._constrainToViewport = function(panelEl ) {
3046+ MdPanelPosition.prototype._constrainToViewport = function(el ) {
30303047 var margin = MdPanelPosition.viewportMargin;
30313048 var initialTop = this._top;
30323049 var initialLeft = this._left;
30333050
30343051 if (this.getTop()) {
30353052 var top = parseInt(this.getTop());
3036- var bottom = panelEl [0].offsetHeight + top;
3053+ var bottom = el [0].offsetHeight + top;
30373054 var viewportHeight = this._$window.innerHeight;
30383055
30393056 if (top < margin) {
@@ -3045,7 +3062,7 @@ MdPanelPosition.prototype._constrainToViewport = function(panelEl) {
30453062
30463063 if (this.getLeft()) {
30473064 var left = parseInt(this.getLeft());
3048- var right = panelEl [0].offsetWidth + left;
3065+ var right = el [0].offsetWidth + left;
30493066 var viewportWidth = this._$window.innerWidth;
30503067
30513068 if (left < margin) {
@@ -3056,7 +3073,7 @@ MdPanelPosition.prototype._constrainToViewport = function(panelEl) {
30563073 }
30573074
30583075 // Class that can be used to re-style the panel if it was repositioned.
3059- panelEl .toggleClass(
3076+ el .toggleClass(
30603077 '_md-panel-position-adjusted',
30613078 this._top !== initialTop || this._left !== initialLeft
30623079 );
@@ -3095,13 +3112,13 @@ MdPanelPosition.prototype._bidi = function(position) {
30953112/**
30963113 * Calculates the panel position based on the created panel element and the
30973114 * provided positioning.
3098- * @param {!angular.JQLite} panelEl
3115+ * @param {!angular.JQLite} el
30993116 * @param {!{x:string, y:string}} position
31003117 * @private
31013118 */
3102- MdPanelPosition.prototype._calculatePanelPosition = function(panelEl , position) {
3119+ MdPanelPosition.prototype._calculatePanelPosition = function(el , position) {
31033120
3104- var panelBounds = panelEl [0].getBoundingClientRect();
3121+ var panelBounds = el [0].getBoundingClientRect();
31053122 var panelWidth = panelBounds.width;
31063123 var panelHeight = panelBounds.height;
31073124
0 commit comments