You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
3.1 KiB
JavaScript
125 lines
3.1 KiB
JavaScript
'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();
|
|
}
|
|
})
|
|
}
|
|
}
|