Bug 1348919 - forced grid cell infobar and area infobar position; r=gl

The infobars needs to be not hidden when the `moveInfobar` function is called,
otherwise the computed style won't work as expected; therefore I switched the
functions' call related to that.
I added an optional `options` argument to the `moveInfobar` function in order
to support forced position and make the infobar hide if offscreen.

MozReview-Commit-ID: 81dxkMGt7vT

--HG--
extra : rebase_source : 5f64ea62368a85b020b4ad964e749c74fa337d9c
This commit is contained in:
Matteo Ferretti 2017-05-15 13:54:42 +02:00
Родитель 4caa12c2c1
Коммит 28d99ffe94
2 изменённых файлов: 34 добавлений и 16 удалений

Просмотреть файл

@ -807,7 +807,10 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
this.getElement("area-infobar-dimensions").setTextContent(dim);
let container = this.getElement("area-infobar-container");
this._moveInfobar(container, x1, x2, y1, y2);
this._moveInfobar(container, x1, x2, y1, y2, {
position: "bottom",
hideIfOffscreen: true
});
},
_updateGridCellInfobar(rowNumber, columnNumber, x1, x2, y1, y2) {
@ -822,7 +825,10 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
this.getElement("cell-infobar-dimensions").setTextContent(dim);
let container = this.getElement("cell-infobar-container");
this._moveInfobar(container, x1, x2, y1, y2);
this._moveInfobar(container, x1, x2, y1, y2, {
position: "top",
hideIfOffscreen: true
});
},
/**
@ -857,7 +863,7 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
* @param {Number} y2
* The second y-coordinate of the grid rectangle.
*/
_moveInfobar(container, x1, x2, y1, y2) {
_moveInfobar(container, x1, x2, y1, y2, options) {
let bounds = {
bottom: y2,
height: y2 - y1,
@ -869,7 +875,7 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
y: y1,
};
moveInfobar(container, bounds, this.win);
moveInfobar(container, bounds, this.win, options);
},
/**
@ -1380,8 +1386,8 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
// Update and show the info bar when only displaying a single grid area.
if (areaName) {
this._updateGridAreaInfobar(area, x1, x2, y1, y2);
this._showGridAreaInfoBar();
this._updateGridAreaInfobar(area, x1, x2, y1, y2);
}
}
}
@ -1430,8 +1436,8 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
let cells = this.getElement("cells");
cells.setAttribute("d", path);
this._updateGridCellInfobar(rowNumber, columnNumber, x1, x2, y1, y2);
this._showGridCellInfoBar();
this._updateGridCellInfobar(rowNumber, columnNumber, x1, x2, y1, y2);
},
/**
@ -1479,8 +1485,8 @@ CssGridHighlighter.prototype = extend(AutoRefreshHighlighter.prototype, {
? linePos.start + (bounds.top / currentZoom)
: rowYPosition.start + (bounds.top / currentZoom);
this._updateGridLineInfobar(names.join(", "), lineNumber, x, y);
this._showGridLineInfoBar();
this._updateGridLineInfobar(names.join(", "), lineNumber, x, y);
},
/**

Просмотреть файл

@ -563,15 +563,23 @@ exports.CanvasFrameAnonymousContentHelper = CanvasFrameAnonymousContentHelper;
* The content bounds of the container element.
* @param {Window} win
* The window object.
* @param {Object} [options={}]
* Advanced options for the infobar.
* @param {String} options.position
* Force the infobar to be displayed either on "top" or "bottom". Any other value
* will be ingnored.
* @param {Boolean} options.hideIfOffscreen
* If set to `true`, hides the infobar if it's offscreen, instead of automatically
* reposition it.
*/
function moveInfobar(container, bounds, win) {
function moveInfobar(container, bounds, win, options = {}) {
let zoom = getCurrentZoom(win);
let viewport = getViewportDimensions(win);
let { computedStyle } = container;
// To simplify, we use the same arrow's size value as margin's value for all four sides.
let margin = parseFloat(computedStyle
let margin = 2;
let arrowSize = parseFloat(computedStyle
.getPropertyValue("--highlighter-bubble-arrow-size"));
let containerHeight = parseFloat(computedStyle.getPropertyValue("height"));
let containerWidth = parseFloat(computedStyle.getPropertyValue("width"));
@ -583,17 +591,16 @@ function moveInfobar(container, bounds, win) {
pageYOffset *= zoom;
pageXOffset *= zoom;
containerHeight += margin;
// Defines the boundaries for the infobar.
let topBoundary = margin;
let bottomBoundary = viewportHeight - containerHeight;
let bottomBoundary = viewportHeight - containerHeight - margin - 1;
let leftBoundary = containerHalfWidth + margin;
let rightBoundary = viewportWidth - containerHalfWidth - margin;
// Set the default values.
let top = bounds.y - containerHeight;
let bottom = bounds.bottom + margin;
let top = bounds.y - containerHeight - arrowSize;
let bottom = bounds.bottom + margin + arrowSize;
let left = bounds.x + bounds.width / 2;
let isOverlapTheNode = false;
let positionAttribute = "top";
@ -608,8 +615,10 @@ function moveInfobar(container, bounds, win) {
// It's a sort of "position: sticky" (but positioned as absolute instead of relative).
let canBePlacedOnTop = top >= pageYOffset;
let canBePlacedOnBottom = bottomBoundary + pageYOffset - bottom > 0;
let forcedOnTop = options.position === "top";
let forcedOnBottom = options.position === "bottom";
if (!canBePlacedOnTop && canBePlacedOnBottom) {
if ((!canBePlacedOnTop && canBePlacedOnBottom && !forcedOnTop) || forcedOnBottom) {
top = bottom;
positionAttribute = "bottom";
}
@ -630,7 +639,10 @@ function moveInfobar(container, bounds, win) {
top -= pageYOffset;
}
if (isOverlapTheNode) {
if (isOverlapTheNode && options.hideIfOffscreen) {
container.setAttribute("hidden", "true");
return;
} else if (isOverlapTheNode) {
left = Math.min(Math.max(leftBoundary, left - pageXOffset), rightBoundary);
position = "fixed";