Bug 1043612 - Persist the size of resizable in-content subdialogs. r=gijs

This commit is contained in:
Jared Wein 2015-04-09 11:23:32 -04:00
Родитель 244a94800e
Коммит 2baf6f0589
1 изменённых файлов: 41 добавлений и 4 удалений

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

@ -16,6 +16,7 @@ let gSubDialog = {
"chrome://global/skin/in-content/common.css",
"chrome://browser/skin/preferences/in-content/preferences.css",
"chrome://browser/skin/preferences/in-content/dialog.css"],
_resizeObserver: null,
init: function() {
this._frame = document.getElementById("dialogFrame");
@ -181,8 +182,12 @@ let gSubDialog = {
let groupBoxBody = document.getAnonymousElementByAttribute(this._box, "class", "groupbox-body");
let boxVerticalPadding = 2 * parseFloat(getComputedStyle(groupBoxBody).paddingTop);
let boxHorizontalPadding = 2 * parseFloat(getComputedStyle(groupBoxBody).paddingLeft);
let frameWidth = docEl.style.width || docEl.scrollWidth + "px";
let frameHeight = docEl.style.height || docEl.scrollHeight + "px";
let frameMinWidth = docEl.scrollWidth + "px";
let frameWidth = docEl.getAttribute("width") ? docEl.getAttribute("width") + "px" :
frameMinWidth;
let frameMinHeight = docEl.scrollHeight + "px";
let frameHeight = docEl.getAttribute("height") ? docEl.getAttribute("height") + "px" :
frameMinHeight;
let boxVerticalBorder = 2 * parseFloat(getComputedStyle(this._box).borderTopWidth);
let boxHorizontalBorder = 2 * parseFloat(getComputedStyle(this._box).borderLeftWidth);
@ -206,17 +211,45 @@ let gSubDialog = {
this._frame.style.height = frameHeight;
this._box.style.minHeight = "calc(" +
(boxVerticalBorder + groupBoxTitleHeight + boxVerticalPadding) +
"px + " + frameHeight + ")";
"px + " + frameMinHeight + ")";
this._box.style.minWidth = "calc(" +
(boxHorizontalBorder + boxHorizontalPadding) +
"px + " + frameWidth + ")";
"px + " + frameMinWidth + ")";
this._overlay.style.visibility = "visible";
this._overlay.style.opacity = ""; // XXX: focus hack continued from _onContentLoaded
this._resizeObserver = new MutationObserver(this._onResize);
this._resizeObserver.observe(this._box, {attributes: true});
this._trapFocus();
},
_onResize: function(mutations) {
let frame = gSubDialog._frame;
// The width and height styles are needed for the initial
// layout of the frame, but afterward they need to be removed
// or their presence will restrict the contents of the <browser>
// from resizing to a smaller size.
frame.style.removeProperty("width");
frame.style.removeProperty("height");
let docEl = frame.contentDocument.documentElement;
let persistedAttributes = docEl.getAttribute("persist");
if (!persistedAttributes.contains("width") &&
!persistedAttributes.contains("height")) {
return;
}
for (let mutation of mutations) {
if (mutation.attributeName == "width") {
docEl.setAttribute("width", docEl.scrollWidth);
} else if (mutation.attributeName == "height") {
docEl.setAttribute("height", docEl.scrollHeight);
}
}
},
_onDialogClosing: function(aEvent) {
this._frame.contentWindow.removeEventListener("dialogclosing", this);
this._closingEvent = aEvent;
@ -301,6 +334,10 @@ let gSubDialog = {
this._frame.removeEventListener("load", this);
this._frame.contentWindow.removeEventListener("dialogclosing", this);
window.removeEventListener("keydown", this, true);
if (this._resizeObserver) {
this._resizeObserver.disconnect();
this._resizeObserver = null;
}
this._untrapFocus();
},