'use strict'; const elementSize = require("element-size"); const sortDockable = require("./util/sort-dockables"); function px(pixels) { return `${pixels}px`; } module.exports = { init: function() { let dockableAPI = { isActive: () => { return (this.opts.dockableContainer != null); }, stack: [], fillElement: null, recalculateLayout: () => { dockableAPI.stack.forEach((item, i) => { item.stackIndex = i; }); let orderedStack = dockableAPI.stack.slice().sort(sortDockable); let reservedLeft = 0; let reservedRight = 0; let reservedTop = 0; let reservedBottom = 0; orderedStack.forEach((item) => { let element = item.tag.root; /* We set the positioning to absolute *before* attempting * to obtain the element size - this way, we can be sure * that the element won't try to stretch to its container. * Instead, it'll be auto-sized, which is exactly what we * want. */ element.style.position = "absolute"; let [width, height] = elementSize(element); if (item.heightHint != null) { height = item.heightHint; } if (item.widthHint != null) { width = item.widthHint; } // FIXME: Should the following really be errors? if ((item.side === "left" || item.side === "right") && width === 0) { throw new Error("Cannot horizontally dock an element without a width; you may need to specify a dock-width"); } else if ((item.side === "top" || item.side === "bottom") && height === 0) { throw new Error("Cannot vertically dock an element without a height; you may need to specify a dock-height"); } if (item.side === "left") { Object.assign(element.style, { left: px(reservedLeft), top: px(reservedTop), bottom: px(reservedBottom) }); delete element.style.right; reservedLeft += width; } else if (item.side === "right") { Object.assign(element.style, { right: px(reservedRight), top: px(reservedTop), bottom: px(reservedBottom) }); delete element.style.left; reservedRight += width; } else if (item.side === "top") { Object.assign(element.style, { left: px(reservedLeft), right: px(reservedRight), top: px(reservedTop) }); delete element.style.bottom; reservedTop += height; } else if (item.side === "bottom") { Object.assign(element.style, { left: px(reservedLeft), right: px(reservedRight), bottom: px(reservedBottom) }); delete element.style.top; reservedBottom += height; } }) let item = dockableAPI.fillElement; if (item != null) { let element = item.root; Object.assign(element.style, { position: "absolute", left: px(reservedLeft), right: px(reservedRight), top: px(reservedTop), bottom: px(reservedBottom) }); } } } this._uikitDockableContainer = dockableAPI; this.on("mount", () => { if (dockableAPI.isActive()) { dockableAPI.recalculateLayout(); } }) } }