Skip to content
This repository has been archived by the owner on Aug 29, 2023. It is now read-only.

Commit

Permalink
fix(panel): take offsets into account when checking if element is on …
Browse files Browse the repository at this point in the history
…screen (#9662)

Accounts for the computed offsets of the panel element when determining whether it is on screen.

Fixes #9628.
  • Loading branch information
crisbeto authored and hansl committed Sep 26, 2016
1 parent 62df3c8 commit 761493d
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 3 deletions.
37 changes: 34 additions & 3 deletions src/components/panel/panel.js
Expand Up @@ -2471,11 +2471,15 @@ MdPanelPosition.prototype.getTransform = function() {
MdPanelPosition.prototype._isOnscreen = function(panelEl) {
// this works because we always use fixed positioning for the panel,
// which is relative to the viewport.
// TODO(gmoothart): take into account _translateX and _translateY to the
// extent feasible.

var left = parseInt(this.getLeft());
var top = parseInt(this.getTop());

if (this._translateX.length || this._translateY.length) {
var offsets = getComputedTranslations(panelEl);
left += offsets.x;
top += offsets.y;
}

var right = left + panelEl[0].offsetWidth;
var bottom = top + panelEl[0].offsetHeight;

Expand Down Expand Up @@ -2982,3 +2986,30 @@ function getElement(el) {
document.querySelector(el) : el;
return angular.element(queryResult);
}

/**
* Gets the computed values for an element's translateX and translateY in px.
* @param {!angular.JQLite|!Element} el
* @return {{x: number, y: number}}
*/
function getComputedTranslations(el) {
// The transform being returned by `getComputedStyle` is in the format:
// `matrix(a, b, c, d, translateX, translateY)` if defined and `none`
// if the element doesn't have a transform.
var transform = getComputedStyle(el[0] || el).transform;
var openIndex = transform.indexOf('(');
var closeIndex = transform.lastIndexOf(')');
var output = { x: 0, y: 0 };

if (openIndex > -1 && closeIndex > -1) {
var parsedValues = transform
.substring(openIndex + 1, closeIndex)
.split(', ')
.slice(-2);

output.x = parseInt(parsedValues[0]);
output.y = parseInt(parsedValues[1]);
}

return output;
}
34 changes: 34 additions & 0 deletions src/components/panel/panel.spec.js
Expand Up @@ -2025,6 +2025,40 @@ describe('$mdPanel', function() {
});
});

it('takes the x offset into account', function() {
var position = mdPanelPosition
.relativeTo(myButton)
.withOffsetX(window.innerWidth + 'px')
.addPanelPosition(xPosition.ALIGN_START, yPosition.ALIGN_TOPS)
.addPanelPosition(xPosition.ALIGN_END, yPosition.ALIGN_TOPS);

config['position'] = position;

openPanel(config);

expect(position.getActualPosition()).toEqual({
x: xPosition.ALIGN_END,
y: yPosition.ALIGN_TOPS
});
});

it('takes the y offset into account', function() {
var position = mdPanelPosition
.relativeTo(myButton)
.withOffsetY(window.innerHeight + 'px')
.addPanelPosition(xPosition.ALIGN_START, yPosition.ALIGN_BOTTOMS)
.addPanelPosition(xPosition.ALIGN_START, yPosition.ALIGN_TOPS);

config['position'] = position;

openPanel(config);

expect(position.getActualPosition()).toEqual({
x: xPosition.ALIGN_START,
y: yPosition.ALIGN_TOPS
});
});

it('should choose last position if none are on-screen', function() {
var position = mdPanelPosition
.relativeTo(myButton)
Expand Down

0 comments on commit 761493d

Please sign in to comment.