Bug 1448555 - Make devtools flexible so that it doesn't stretch the window. r?jryans
MozReview-Commit-ID: 74EdTp9EvAf
--- a/devtools/client/framework/toolbox-hosts.js
+++ b/devtools/client/framework/toolbox-hosts.js
@@ -16,16 +16,52 @@ loader.lazyRequireGetter(this, "AppConst
loader.lazyRequireGetter(this, "gDevToolsBrowser", "devtools/client/framework/devtools-browser", true);
/* A host should always allow this much space for the page to be displayed.
* There is also a min-height on the browser, but we still don't want to set
* frame.height to be larger than that, since it can cause problems with
* resizing the toolbox and panel layout. */
const MIN_PAGE_SIZE = 25;
+function capitalize(s) {
+ return s[0].toUpperCase() + s.substring(1);
+}
+
+/**
+ * Size the frame before appending it into the container.
+ *
+ * This also explicitly sizes previous flex siblings in the container
+ * to prevent frame from being expanded after appended.
+ */
+function sizeFrameBeforeAppend(container, frame, prop, pref) {
+ frame.setAttribute("flex", "1");
+ frame[prop] = Math.min(
+ Services.prefs.getIntPref(pref),
+ container["client" + capitalize(prop)] - MIN_PAGE_SIZE
+ );
+ // Size previous flex siblings explicitly so that when we insert the
+ // frame with flex, its size wouldn't be expanded unexpectedly. Among
+ // the previous flex siblings, the last one would be resized to to
+ // reserve room for the frame.
+ let foundLastFlex = false;
+ for (let child = container.lastElementChild; child;
+ child = child.previousElementSibling) {
+ if (child.getClientRects().length > 0 &&
+ parseInt(child.getAttribute("flex"), 10) > 0) {
+ let childRect = child.getBoundingClientRect();
+ if (!foundLastFlex) {
+ foundLastFlex = true;
+ child[prop] = childRect[prop] - frame[prop];
+ } else {
+ child[prop] = childRect[prop];
+ }
+ }
+ }
+}
+
/**
* A toolbox host represents an object that contains a toolbox (e.g. the
* sidebar or a separate window). Any host object should implement the
* following functions:
*
* create() - create the UI and emit a 'ready' event when the UI is ready to use
* destroy() - destroy the host's UI
*/
@@ -63,20 +99,17 @@ BottomHost.prototype = {
this._splitter = ownerDocument.createElement("splitter");
this._splitter.setAttribute("class", "devtools-horizontal-splitter");
// Avoid resizing notification containers
this._splitter.setAttribute("resizebefore", "flex");
this.frame = ownerDocument.createElement("iframe");
this.frame.className = "devtools-toolbox-bottom-iframe";
- this.frame.height = Math.min(
- Services.prefs.getIntPref(this.heightPref),
- this._nbox.clientHeight - MIN_PAGE_SIZE
- );
+ sizeFrameBeforeAppend(this._nbox, this.frame, "height", this.heightPref);
this._nbox.appendChild(this._splitter);
this._nbox.appendChild(this.frame);
this.frame.tooltip = "aHTMLTooltip";
// we have to load something so we can switch documents if we have to
this.frame.setAttribute("src", "about:blank");
@@ -207,21 +240,17 @@ SidebarHost.prototype = {
let ownerDocument = gBrowser.ownerDocument;
this._sidebar = gBrowser.getSidebarContainer(this.hostTab.linkedBrowser);
this._splitter = ownerDocument.createElement("splitter");
this._splitter.setAttribute("class", "devtools-side-splitter");
this.frame = ownerDocument.createElement("iframe");
this.frame.className = "devtools-toolbox-side-iframe";
-
- this.frame.width = Math.min(
- Services.prefs.getIntPref(this.widthPref),
- this._sidebar.clientWidth - MIN_PAGE_SIZE
- );
+ sizeFrameBeforeAppend(this._sidebar, this.frame, "width", this.widthPref);
this._sidebar.appendChild(this._splitter);
this._sidebar.appendChild(this.frame);
this.frame.tooltip = "aHTMLTooltip";
this.frame.setAttribute("src", "about:blank");
let frame = await new Promise(resolve => {