dockview-core
Version:
Zero dependency layout manager supporting tabs, grids and splitviews
768 lines (767 loc) • 32.7 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Accreditation: This file is largly based upon the MIT licenced VSCode sourcecode found at:
* https://github.com/microsoft/vscode/tree/main/src/vs/base/browser/ui/splitview
*--------------------------------------------------------------------------------------------*/
import { removeClasses, addClasses, toggleClass, disableIframePointEvents, } from '../dom';
import { Emitter } from '../events';
import { pushToStart, pushToEnd, firstIndex } from '../array';
import { range, clamp } from '../math';
import { ViewItem } from './viewItem';
export var Orientation;
(function (Orientation) {
Orientation["HORIZONTAL"] = "HORIZONTAL";
Orientation["VERTICAL"] = "VERTICAL";
})(Orientation || (Orientation = {}));
export var SashState;
(function (SashState) {
SashState[SashState["MAXIMUM"] = 0] = "MAXIMUM";
SashState[SashState["MINIMUM"] = 1] = "MINIMUM";
SashState[SashState["DISABLED"] = 2] = "DISABLED";
SashState[SashState["ENABLED"] = 3] = "ENABLED";
})(SashState || (SashState = {}));
export var LayoutPriority;
(function (LayoutPriority) {
LayoutPriority["Low"] = "low";
LayoutPriority["High"] = "high";
LayoutPriority["Normal"] = "normal";
})(LayoutPriority || (LayoutPriority = {}));
export var Sizing;
(function (Sizing) {
Sizing.Distribute = { type: 'distribute' };
function Split(index) {
return { type: 'split', index };
}
Sizing.Split = Split;
function Invisible(cachedVisibleSize) {
return { type: 'invisible', cachedVisibleSize };
}
Sizing.Invisible = Invisible;
})(Sizing || (Sizing = {}));
export class Splitview {
get contentSize() {
return this._contentSize;
}
get size() {
return this._size;
}
set size(value) {
this._size = value;
}
get orthogonalSize() {
return this._orthogonalSize;
}
set orthogonalSize(value) {
this._orthogonalSize = value;
}
get length() {
return this.viewItems.length;
}
get proportions() {
return this._proportions ? [...this._proportions] : undefined;
}
get orientation() {
return this._orientation;
}
set orientation(value) {
this._orientation = value;
const tmp = this.size;
this.size = this.orthogonalSize;
this.orthogonalSize = tmp;
removeClasses(this.element, 'dv-horizontal', 'dv-vertical');
this.element.classList.add(this.orientation == Orientation.HORIZONTAL
? 'dv-horizontal'
: 'dv-vertical');
}
get minimumSize() {
return this.viewItems.reduce((r, item) => r + item.minimumSize, 0);
}
get maximumSize() {
return this.length === 0
? Number.POSITIVE_INFINITY
: this.viewItems.reduce((r, item) => r + item.maximumSize, 0);
}
get startSnappingEnabled() {
return this._startSnappingEnabled;
}
set startSnappingEnabled(startSnappingEnabled) {
if (this._startSnappingEnabled === startSnappingEnabled) {
return;
}
this._startSnappingEnabled = startSnappingEnabled;
this.updateSashEnablement();
}
get endSnappingEnabled() {
return this._endSnappingEnabled;
}
set endSnappingEnabled(endSnappingEnabled) {
if (this._endSnappingEnabled === endSnappingEnabled) {
return;
}
this._endSnappingEnabled = endSnappingEnabled;
this.updateSashEnablement();
}
get disabled() {
return this._disabled;
}
set disabled(value) {
this._disabled = value;
toggleClass(this.element, 'dv-splitview-disabled', value);
}
get margin() {
return this._margin;
}
set margin(value) {
this._margin = value;
toggleClass(this.element, 'dv-splitview-has-margin', value !== 0);
}
constructor(container, options) {
var _a, _b;
this.container = container;
this.viewItems = [];
this.sashes = [];
this._size = 0;
this._orthogonalSize = 0;
this._contentSize = 0;
this._proportions = undefined;
this._startSnappingEnabled = true;
this._endSnappingEnabled = true;
this._disabled = false;
this._margin = 0;
this._onDidSashEnd = new Emitter();
this.onDidSashEnd = this._onDidSashEnd.event;
this._onDidAddView = new Emitter();
this.onDidAddView = this._onDidAddView.event;
this._onDidRemoveView = new Emitter();
this.onDidRemoveView = this._onDidRemoveView.event;
this.resize = (index, delta, sizes = this.viewItems.map((x) => x.size), lowPriorityIndexes, highPriorityIndexes, overloadMinDelta = Number.NEGATIVE_INFINITY, overloadMaxDelta = Number.POSITIVE_INFINITY, snapBefore, snapAfter) => {
if (index < 0 || index > this.viewItems.length) {
return 0;
}
const upIndexes = range(index, -1);
const downIndexes = range(index + 1, this.viewItems.length);
//
if (highPriorityIndexes) {
for (const i of highPriorityIndexes) {
pushToStart(upIndexes, i);
pushToStart(downIndexes, i);
}
}
if (lowPriorityIndexes) {
for (const i of lowPriorityIndexes) {
pushToEnd(upIndexes, i);
pushToEnd(downIndexes, i);
}
}
//
const upItems = upIndexes.map((i) => this.viewItems[i]);
const upSizes = upIndexes.map((i) => sizes[i]);
//
const downItems = downIndexes.map((i) => this.viewItems[i]);
const downSizes = downIndexes.map((i) => sizes[i]);
//
const minDeltaUp = upIndexes.reduce((_, i) => _ + this.viewItems[i].minimumSize - sizes[i], 0);
const maxDeltaUp = upIndexes.reduce((_, i) => _ + this.viewItems[i].maximumSize - sizes[i], 0);
//
const maxDeltaDown = downIndexes.length === 0
? Number.POSITIVE_INFINITY
: downIndexes.reduce((_, i) => _ + sizes[i] - this.viewItems[i].minimumSize, 0);
const minDeltaDown = downIndexes.length === 0
? Number.NEGATIVE_INFINITY
: downIndexes.reduce((_, i) => _ + sizes[i] - this.viewItems[i].maximumSize, 0);
//
const minDelta = Math.max(minDeltaUp, minDeltaDown);
const maxDelta = Math.min(maxDeltaDown, maxDeltaUp);
//
let snapped = false;
if (snapBefore) {
const snapView = this.viewItems[snapBefore.index];
const visible = delta >= snapBefore.limitDelta;
snapped = visible !== snapView.visible;
snapView.setVisible(visible, snapBefore.size);
}
if (!snapped && snapAfter) {
const snapView = this.viewItems[snapAfter.index];
const visible = delta < snapAfter.limitDelta;
snapped = visible !== snapView.visible;
snapView.setVisible(visible, snapAfter.size);
}
if (snapped) {
return this.resize(index, delta, sizes, lowPriorityIndexes, highPriorityIndexes, overloadMinDelta, overloadMaxDelta);
}
//
const tentativeDelta = clamp(delta, minDelta, maxDelta);
let actualDelta = 0;
//
let deltaUp = tentativeDelta;
for (let i = 0; i < upItems.length; i++) {
const item = upItems[i];
const size = clamp(upSizes[i] + deltaUp, item.minimumSize, item.maximumSize);
const viewDelta = size - upSizes[i];
actualDelta += viewDelta;
deltaUp -= viewDelta;
item.size = size;
}
//
let deltaDown = actualDelta;
for (let i = 0; i < downItems.length; i++) {
const item = downItems[i];
const size = clamp(downSizes[i] - deltaDown, item.minimumSize, item.maximumSize);
const viewDelta = size - downSizes[i];
deltaDown += viewDelta;
item.size = size;
}
//
return delta;
};
this._orientation = (_a = options.orientation) !== null && _a !== void 0 ? _a : Orientation.VERTICAL;
this.element = this.createContainer();
this.margin = (_b = options.margin) !== null && _b !== void 0 ? _b : 0;
this.proportionalLayout =
options.proportionalLayout === undefined
? true
: !!options.proportionalLayout;
this.viewContainer = this.createViewContainer();
this.sashContainer = this.createSashContainer();
this.element.appendChild(this.sashContainer);
this.element.appendChild(this.viewContainer);
this.container.appendChild(this.element);
this.style(options.styles);
// We have an existing set of view, add them now
if (options.descriptor) {
this._size = options.descriptor.size;
options.descriptor.views.forEach((viewDescriptor, index) => {
const sizing = viewDescriptor.visible === undefined ||
viewDescriptor.visible
? viewDescriptor.size
: {
type: 'invisible',
cachedVisibleSize: viewDescriptor.size,
};
const view = viewDescriptor.view;
this.addView(view, sizing, index, true
// true skip layout
);
});
// Initialize content size and proportions for first layout
this._contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
this.saveProportions();
}
}
style(styles) {
if ((styles === null || styles === void 0 ? void 0 : styles.separatorBorder) === 'transparent') {
removeClasses(this.element, 'dv-separator-border');
this.element.style.removeProperty('--dv-separator-border');
}
else {
addClasses(this.element, 'dv-separator-border');
if (styles === null || styles === void 0 ? void 0 : styles.separatorBorder) {
this.element.style.setProperty('--dv-separator-border', styles.separatorBorder);
}
}
}
isViewVisible(index) {
if (index < 0 || index >= this.viewItems.length) {
throw new Error('Index out of bounds');
}
const viewItem = this.viewItems[index];
return viewItem.visible;
}
setViewVisible(index, visible) {
if (index < 0 || index >= this.viewItems.length) {
throw new Error('Index out of bounds');
}
const viewItem = this.viewItems[index];
viewItem.setVisible(visible, viewItem.size);
this.distributeEmptySpace(index);
this.layoutViews();
this.saveProportions();
}
getViewSize(index) {
if (index < 0 || index >= this.viewItems.length) {
return -1;
}
return this.viewItems[index].size;
}
resizeView(index, size) {
if (index < 0 || index >= this.viewItems.length) {
return;
}
const indexes = range(this.viewItems.length).filter((i) => i !== index);
const lowPriorityIndexes = [
...indexes.filter((i) => this.viewItems[i].priority === LayoutPriority.Low),
index,
];
const highPriorityIndexes = indexes.filter((i) => this.viewItems[i].priority === LayoutPriority.High);
const item = this.viewItems[index];
size = Math.round(size);
size = clamp(size, item.minimumSize, Math.min(item.maximumSize, this._size));
item.size = size;
this.relayout(lowPriorityIndexes, highPriorityIndexes);
}
getViews() {
return this.viewItems.map((x) => x.view);
}
onDidChange(item, size) {
const index = this.viewItems.indexOf(item);
if (index < 0 || index >= this.viewItems.length) {
return;
}
size = typeof size === 'number' ? size : item.size;
size = clamp(size, item.minimumSize, item.maximumSize);
item.size = size;
const indexes = range(this.viewItems.length).filter((i) => i !== index);
const lowPriorityIndexes = [
...indexes.filter((i) => this.viewItems[i].priority === LayoutPriority.Low),
index,
];
const highPriorityIndexes = indexes.filter((i) => this.viewItems[i].priority === LayoutPriority.High);
/**
* add this view we are changing to the low-index list since we have determined the size
* here and don't want it changed
*/
this.relayout([...lowPriorityIndexes, index], highPriorityIndexes);
}
addView(view, size = { type: 'distribute' }, index = this.viewItems.length, skipLayout) {
const container = document.createElement('div');
container.className = 'dv-view';
container.appendChild(view.element);
let viewSize;
if (typeof size === 'number') {
viewSize = size;
}
else if (size.type === 'split') {
viewSize = this.getViewSize(size.index) / 2;
}
else if (size.type === 'invisible') {
viewSize = { cachedVisibleSize: size.cachedVisibleSize };
}
else {
viewSize = view.minimumSize;
}
const disposable = view.onDidChange((newSize) => this.onDidChange(viewItem, newSize.size));
const viewItem = new ViewItem(container, view, viewSize, {
dispose: () => {
disposable.dispose();
this.viewContainer.removeChild(container);
},
});
if (index === this.viewItems.length) {
this.viewContainer.appendChild(container);
}
else {
this.viewContainer.insertBefore(container, this.viewContainer.children.item(index));
}
this.viewItems.splice(index, 0, viewItem);
if (this.viewItems.length > 1) {
//add sash
const sash = document.createElement('div');
sash.className = 'dv-sash';
const onPointerStart = (event) => {
for (const item of this.viewItems) {
item.enabled = false;
}
const iframes = disableIframePointEvents();
const start = this._orientation === Orientation.HORIZONTAL
? event.clientX
: event.clientY;
const sashIndex = firstIndex(this.sashes, (s) => s.container === sash);
//
const sizes = this.viewItems.map((x) => x.size);
//
let snapBefore;
let snapAfter;
const upIndexes = range(sashIndex, -1);
const downIndexes = range(sashIndex + 1, this.viewItems.length);
const minDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].minimumSize - sizes[i]), 0);
const maxDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].viewMaximumSize - sizes[i]), 0);
const maxDeltaDown = downIndexes.length === 0
? Number.POSITIVE_INFINITY
: downIndexes.reduce((r, i) => r +
(sizes[i] - this.viewItems[i].minimumSize), 0);
const minDeltaDown = downIndexes.length === 0
? Number.NEGATIVE_INFINITY
: downIndexes.reduce((r, i) => r +
(sizes[i] -
this.viewItems[i].viewMaximumSize), 0);
const minDelta = Math.max(minDeltaUp, minDeltaDown);
const maxDelta = Math.min(maxDeltaDown, maxDeltaUp);
const snapBeforeIndex = this.findFirstSnapIndex(upIndexes);
const snapAfterIndex = this.findFirstSnapIndex(downIndexes);
if (typeof snapBeforeIndex === 'number') {
const snappedViewItem = this.viewItems[snapBeforeIndex];
const halfSize = Math.floor(snappedViewItem.viewMinimumSize / 2);
snapBefore = {
index: snapBeforeIndex,
limitDelta: snappedViewItem.visible
? minDelta - halfSize
: minDelta + halfSize,
size: snappedViewItem.size,
};
}
if (typeof snapAfterIndex === 'number') {
const snappedViewItem = this.viewItems[snapAfterIndex];
const halfSize = Math.floor(snappedViewItem.viewMinimumSize / 2);
snapAfter = {
index: snapAfterIndex,
limitDelta: snappedViewItem.visible
? maxDelta + halfSize
: maxDelta - halfSize,
size: snappedViewItem.size,
};
}
const onPointerMove = (event) => {
const current = this._orientation === Orientation.HORIZONTAL
? event.clientX
: event.clientY;
const delta = current - start;
this.resize(sashIndex, delta, sizes, undefined, undefined, minDelta, maxDelta, snapBefore, snapAfter);
this.distributeEmptySpace();
this.layoutViews();
};
const end = () => {
for (const item of this.viewItems) {
item.enabled = true;
}
iframes.release();
this.saveProportions();
document.removeEventListener('pointermove', onPointerMove);
document.removeEventListener('pointerup', end);
document.removeEventListener('pointercancel', end);
this._onDidSashEnd.fire(undefined);
};
document.addEventListener('pointermove', onPointerMove);
document.addEventListener('pointerup', end);
document.addEventListener('pointercancel', end);
};
sash.addEventListener('pointerdown', onPointerStart);
const sashItem = {
container: sash,
disposable: () => {
sash.removeEventListener('pointerdown', onPointerStart);
this.sashContainer.removeChild(sash);
},
};
this.sashContainer.appendChild(sash);
this.sashes.push(sashItem);
}
if (!skipLayout) {
this.relayout([index]);
}
if (!skipLayout &&
typeof size !== 'number' &&
size.type === 'distribute') {
this.distributeViewSizes();
}
this._onDidAddView.fire(view);
}
distributeViewSizes() {
const flexibleViewItems = [];
let flexibleSize = 0;
for (const item of this.viewItems) {
if (item.maximumSize - item.minimumSize > 0) {
flexibleViewItems.push(item);
flexibleSize += item.size;
}
}
const size = Math.floor(flexibleSize / flexibleViewItems.length);
for (const item of flexibleViewItems) {
item.size = clamp(size, item.minimumSize, item.maximumSize);
}
const indexes = range(this.viewItems.length);
const lowPriorityIndexes = indexes.filter((i) => this.viewItems[i].priority === LayoutPriority.Low);
const highPriorityIndexes = indexes.filter((i) => this.viewItems[i].priority === LayoutPriority.High);
this.relayout(lowPriorityIndexes, highPriorityIndexes);
}
removeView(index, sizing, skipLayout = false) {
// Remove view
const viewItem = this.viewItems.splice(index, 1)[0];
viewItem.dispose();
// Remove sash
if (this.viewItems.length >= 1) {
const sashIndex = Math.max(index - 1, 0);
const sashItem = this.sashes.splice(sashIndex, 1)[0];
sashItem.disposable();
}
if (!skipLayout) {
this.relayout();
}
if (sizing && sizing.type === 'distribute') {
this.distributeViewSizes();
}
this._onDidRemoveView.fire(viewItem.view);
return viewItem.view;
}
getViewCachedVisibleSize(index) {
if (index < 0 || index >= this.viewItems.length) {
throw new Error('Index out of bounds');
}
const viewItem = this.viewItems[index];
return viewItem.cachedVisibleSize;
}
moveView(from, to) {
const cachedVisibleSize = this.getViewCachedVisibleSize(from);
const sizing = typeof cachedVisibleSize === 'undefined'
? this.getViewSize(from)
: Sizing.Invisible(cachedVisibleSize);
const view = this.removeView(from, undefined, true);
this.addView(view, sizing, to);
}
layout(size, orthogonalSize) {
const previousSize = Math.max(this.size, this._contentSize);
this.size = size;
this.orthogonalSize = orthogonalSize;
if (!this.proportions) {
const indexes = range(this.viewItems.length);
const lowPriorityIndexes = indexes.filter((i) => this.viewItems[i].priority === LayoutPriority.Low);
const highPriorityIndexes = indexes.filter((i) => this.viewItems[i].priority === LayoutPriority.High);
this.resize(this.viewItems.length - 1, size - previousSize, undefined, lowPriorityIndexes, highPriorityIndexes);
}
else {
let total = 0;
for (let i = 0; i < this.viewItems.length; i++) {
const item = this.viewItems[i];
const proportion = this.proportions[i];
if (typeof proportion === 'number') {
total += proportion;
}
else {
size -= item.size;
}
}
for (let i = 0; i < this.viewItems.length; i++) {
const item = this.viewItems[i];
const proportion = this.proportions[i];
if (typeof proportion === 'number' && total > 0) {
item.size = clamp(Math.round((proportion * size) / total), item.minimumSize, item.maximumSize);
}
}
}
this.distributeEmptySpace();
this.layoutViews();
}
relayout(lowPriorityIndexes, highPriorityIndexes) {
const contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
this.resize(this.viewItems.length - 1, this._size - contentSize, undefined, lowPriorityIndexes, highPriorityIndexes);
this.distributeEmptySpace();
this.layoutViews();
this.saveProportions();
}
distributeEmptySpace(lowPriorityIndex) {
const contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
let emptyDelta = this.size - contentSize;
const indexes = range(this.viewItems.length - 1, -1);
const lowPriorityIndexes = indexes.filter((i) => this.viewItems[i].priority === LayoutPriority.Low);
const highPriorityIndexes = indexes.filter((i) => this.viewItems[i].priority === LayoutPriority.High);
for (const index of highPriorityIndexes) {
pushToStart(indexes, index);
}
for (const index of lowPriorityIndexes) {
pushToEnd(indexes, index);
}
if (typeof lowPriorityIndex === 'number') {
pushToEnd(indexes, lowPriorityIndex);
}
for (let i = 0; emptyDelta !== 0 && i < indexes.length; i++) {
const item = this.viewItems[indexes[i]];
const size = clamp(item.size + emptyDelta, item.minimumSize, item.maximumSize);
const viewDelta = size - item.size;
emptyDelta -= viewDelta;
item.size = size;
}
}
saveProportions() {
if (this.proportionalLayout && this._contentSize > 0) {
this._proportions = this.viewItems.map((i) => i.visible ? i.size / this._contentSize : undefined);
}
}
/**
* Margin explain:
*
* For `n` views in a splitview there will be `n-1` margins `m`.
*
* To fit the margins each view must reduce in size by `(m * (n - 1)) / n`.
*
* For each view `i` the offet must be adjusted by `m * i/(n - 1)`.
*/
layoutViews() {
this._contentSize = this.viewItems.reduce((r, i) => r + i.size, 0);
this.updateSashEnablement();
if (this.viewItems.length === 0) {
return;
}
const visibleViewItems = this.viewItems.filter((i) => i.visible);
const sashCount = Math.max(0, visibleViewItems.length - 1);
const marginReducedSize = (this.margin * sashCount) / Math.max(1, visibleViewItems.length);
let totalLeftOffset = 0;
const viewLeftOffsets = [];
const sashWidth = 4; // hardcoded in css
const runningVisiblePanelCount = this.viewItems.reduce((arr, viewItem, i) => {
const flag = viewItem.visible ? 1 : 0;
if (i === 0) {
arr.push(flag);
}
else {
arr.push(arr[i - 1] + flag);
}
return arr;
}, []);
// calculate both view and cash positions
this.viewItems.forEach((view, i) => {
totalLeftOffset += this.viewItems[i].size;
viewLeftOffsets.push(totalLeftOffset);
const size = view.visible ? view.size - marginReducedSize : 0;
const visiblePanelsBeforeThisView = Math.max(0, runningVisiblePanelCount[i] - 1);
const offset = i === 0 || visiblePanelsBeforeThisView === 0
? 0
: viewLeftOffsets[i - 1] +
(visiblePanelsBeforeThisView / sashCount) *
marginReducedSize;
if (i < this.viewItems.length - 1) {
// calculate sash position
const newSize = view.visible
? offset + size - sashWidth / 2 + this.margin / 2
: offset;
if (this._orientation === Orientation.HORIZONTAL) {
this.sashes[i].container.style.left = `${newSize}px`;
this.sashes[i].container.style.top = `0px`;
}
if (this._orientation === Orientation.VERTICAL) {
this.sashes[i].container.style.left = `0px`;
this.sashes[i].container.style.top = `${newSize}px`;
}
}
// calculate view position
if (this._orientation === Orientation.HORIZONTAL) {
view.container.style.width = `${size}px`;
view.container.style.left = `${offset}px`;
view.container.style.top = '';
view.container.style.height = '';
}
if (this._orientation === Orientation.VERTICAL) {
view.container.style.height = `${size}px`;
view.container.style.top = `${offset}px`;
view.container.style.width = '';
view.container.style.left = '';
}
view.view.layout(view.size - marginReducedSize, this._orthogonalSize);
});
}
findFirstSnapIndex(indexes) {
// visible views first
for (const index of indexes) {
const viewItem = this.viewItems[index];
if (!viewItem.visible) {
continue;
}
if (viewItem.snap) {
return index;
}
}
// then, hidden views
for (const index of indexes) {
const viewItem = this.viewItems[index];
if (viewItem.visible &&
viewItem.maximumSize - viewItem.minimumSize > 0) {
return undefined;
}
if (!viewItem.visible && viewItem.snap) {
return index;
}
}
return undefined;
}
updateSashEnablement() {
let previous = false;
const collapsesDown = this.viewItems.map((i) => (previous = i.size - i.minimumSize > 0 || previous));
previous = false;
const expandsDown = this.viewItems.map((i) => (previous = i.maximumSize - i.size > 0 || previous));
const reverseViews = [...this.viewItems].reverse();
previous = false;
const collapsesUp = reverseViews
.map((i) => (previous = i.size - i.minimumSize > 0 || previous))
.reverse();
previous = false;
const expandsUp = reverseViews
.map((i) => (previous = i.maximumSize - i.size > 0 || previous))
.reverse();
let position = 0;
for (let index = 0; index < this.sashes.length; index++) {
const sash = this.sashes[index];
const viewItem = this.viewItems[index];
position += viewItem.size;
const min = !(collapsesDown[index] && expandsUp[index + 1]);
const max = !(expandsDown[index] && collapsesUp[index + 1]);
if (min && max) {
const upIndexes = range(index, -1);
const downIndexes = range(index + 1, this.viewItems.length);
const snapBeforeIndex = this.findFirstSnapIndex(upIndexes);
const snapAfterIndex = this.findFirstSnapIndex(downIndexes);
const snappedBefore = typeof snapBeforeIndex === 'number' &&
!this.viewItems[snapBeforeIndex].visible;
const snappedAfter = typeof snapAfterIndex === 'number' &&
!this.viewItems[snapAfterIndex].visible;
if (snappedBefore &&
collapsesUp[index] &&
(position > 0 || this.startSnappingEnabled)) {
this.updateSash(sash, SashState.MINIMUM);
}
else if (snappedAfter &&
collapsesDown[index] &&
(position < this._contentSize || this.endSnappingEnabled)) {
this.updateSash(sash, SashState.MAXIMUM);
}
else {
this.updateSash(sash, SashState.DISABLED);
}
}
else if (min && !max) {
this.updateSash(sash, SashState.MINIMUM);
}
else if (!min && max) {
this.updateSash(sash, SashState.MAXIMUM);
}
else {
this.updateSash(sash, SashState.ENABLED);
}
}
}
updateSash(sash, state) {
toggleClass(sash.container, 'dv-disabled', state === SashState.DISABLED);
toggleClass(sash.container, 'dv-enabled', state === SashState.ENABLED);
toggleClass(sash.container, 'dv-maximum', state === SashState.MAXIMUM);
toggleClass(sash.container, 'dv-minimum', state === SashState.MINIMUM);
}
createViewContainer() {
const element = document.createElement('div');
element.className = 'dv-view-container';
return element;
}
createSashContainer() {
const element = document.createElement('div');
element.className = 'dv-sash-container';
return element;
}
createContainer() {
const element = document.createElement('div');
const orientationClassname = this._orientation === Orientation.HORIZONTAL
? 'dv-horizontal'
: 'dv-vertical';
element.className = `dv-split-view-container ${orientationClassname}`;
return element;
}
dispose() {
this._onDidSashEnd.dispose();
this._onDidAddView.dispose();
this._onDidRemoveView.dispose();
for (let i = 0; i < this.element.children.length; i++) {
if (this.element.children.item(i) === this.element) {
this.element.removeChild(this.element);
break;
}
}
for (const viewItem of this.viewItems) {
viewItem.dispose();
}
this.element.remove();
}
}