dockview
Version:
Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support
1,032 lines (1,010 loc) • 274 kB
JavaScript
/**
* dockview
* @version 1.0.0
* @link https://github.com/mathuo/dockview
* @license MIT
*/
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
var ReactDOM = require('react-dom');
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n["default"] = e;
return Object.freeze(n);
}
var React__namespace = /*#__PURE__*/_interopNamespace(React);
var ReactDOM__namespace = /*#__PURE__*/_interopNamespace(ReactDOM);
function styleInject(css, ref) {
if ( ref === void 0 ) ref = {};
var insertAt = ref.insertAt;
if (!css || typeof document === 'undefined') { return; }
var head = document.head || document.getElementsByTagName('head')[0];
var style = document.createElement('style');
style.type = 'text/css';
if (insertAt === 'top') {
if (head.firstChild) {
head.insertBefore(style, head.firstChild);
} else {
head.appendChild(style);
}
} else {
head.appendChild(style);
}
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
}
var css_248z = ".dockview-theme-dark {\n --dv-paneview-active-outline-color: dodgerblue;\n --dv-tabs-and-actions-container-font-size: 13px;\n --dv-tabs-and-actions-container-height: 35px;\n --dv-tab-close-icon: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"/></svg>');\n --dv-tab-dirty-icon: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z\"/></svg>');\n --dv-drag-over-background-color: rgba(83, 89, 93, 0.5);\n --dv-drag-over-border-color: white;\n --dv-tabs-container-scrollbar-color: #888;\n --dv-group-view-background-color: #1e1e1e;\n --dv-tabs-and-actions-container-background-color: #252526;\n --dv-activegroup-visiblepanel-tab-background-color: #1e1e1e;\n --dv-activegroup-hiddenpanel-tab-background-color: #2d2d2d;\n --dv-inactivegroup-visiblepanel-tab-background-color: #1e1e1e;\n --dv-inactivegroup-hiddenpanel-tab-background-color: #2d2d2d;\n --dv-tab-divider-color: #1e1e1e;\n --dv-activegroup-visiblepanel-tab-color: white;\n --dv-activegroup-hiddenpanel-tab-color: #969696;\n --dv-inactivegroup-visiblepanel-tab-color: #8f8f8f;\n --dv-inactivegroup-hiddenpanel-tab-color: #626262;\n --dv-separator-border: rgb(68, 68, 68);\n --dv-paneview-header-border-color: rgba(204, 204, 204, 0.2);\n}\n\n.dockview-theme-light {\n --dv-paneview-active-outline-color: dodgerblue;\n --dv-tabs-and-actions-container-font-size: 13px;\n --dv-tabs-and-actions-container-height: 35px;\n --dv-tab-close-icon: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"/></svg>');\n --dv-tab-dirty-icon: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z\"/></svg>');\n --dv-drag-over-background-color: rgba(83, 89, 93, 0.5);\n --dv-drag-over-border-color: white;\n --dv-tabs-container-scrollbar-color: #888;\n --dv-group-view-background-color: white;\n --dv-tabs-and-actions-container-background-color: #f3f3f3;\n --dv-activegroup-visiblepanel-tab-background-color: white;\n --dv-activegroup-hiddenpanel-tab-background-color: #ececec;\n --dv-inactivegroup-visiblepanel-tab-background-color: white;\n --dv-inactivegroup-hiddenpanel-tab-background-color: #ececec;\n --dv-tab-divider-color: white;\n --dv-activegroup-visiblepanel-tab-color: rgb(51, 51, 51);\n --dv-activegroup-hiddenpanel-tab-color: rgba(51, 51, 51, 0.7);\n --dv-inactivegroup-visiblepanel-tab-color: rgba(51, 51, 51, 0.7);\n --dv-inactivegroup-hiddenpanel-tab-color: rgba(51, 51, 51, 0.35);\n --dv-separator-border: rgba(128, 128, 128, 0.35);\n --dv-paneview-header-border-color: rgb(51, 51, 51);\n}\n\n.dockview-theme-vs {\n --dv-paneview-active-outline-color: dodgerblue;\n --dv-tabs-and-actions-container-font-size: 13px;\n --dv-tabs-and-actions-container-height: 35px;\n --dv-tab-close-icon: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"/></svg>');\n --dv-tab-dirty-icon: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24\" viewBox=\"0 0 24 24\" width=\"24\"><path d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z\"/></svg>');\n --dv-drag-over-background-color: rgba(83, 89, 93, 0.5);\n --dv-drag-over-border-color: white;\n --dv-tabs-container-scrollbar-color: #888;\n --dv-group-view-background-color: #1e1e1e;\n --dv-tabs-and-actions-container-background-color: #252526;\n --dv-activegroup-visiblepanel-tab-background-color: #1e1e1e;\n --dv-activegroup-hiddenpanel-tab-background-color: #2d2d2d;\n --dv-inactivegroup-visiblepanel-tab-background-color: #1e1e1e;\n --dv-inactivegroup-hiddenpanel-tab-background-color: #2d2d2d;\n --dv-tab-divider-color: #1e1e1e;\n --dv-activegroup-visiblepanel-tab-color: white;\n --dv-activegroup-hiddenpanel-tab-color: #969696;\n --dv-inactivegroup-visiblepanel-tab-color: #8f8f8f;\n --dv-inactivegroup-hiddenpanel-tab-color: #626262;\n --dv-separator-border: rgb(68, 68, 68);\n --dv-paneview-header-border-color: rgba(204, 204, 204, 0.2);\n --dv-activegroup-visiblepanel-tab-background-color: dodgerblue;\n --dv-tabs-and-actions-container-height: 18px;\n --dv-tabs-and-actions-container-font-size: 11px;\n}\n.dockview-theme-vs .groupview.active-group > .tabs-and-actions-container {\n border-bottom: 2px solid var(--dv-activegroup-visiblepanel-tab-background-color);\n}\n.dockview-theme-vs .groupview.inactive-group > .tabs-and-actions-container {\n border-bottom: 2px solid var(--dv-inactivegroup-visiblepanel-tab-background-color);\n}\n.actions-bar {\n text-align: right;\n width: 28px;\n display: flex;\n align-items: center;\n flex-shrink: 0;\n}\n.actions-bar .actions-container {\n display: flex;\n padding: 0px;\n margin: 0px;\n justify-content: flex-end;\n}\n.actions-bar .actions-container a:active {\n -webkit-mask-size: 100% 100% !important;\n mask-size: 100% 100% !important;\n}\n.actions-bar .actions-container .close-action {\n background-color: white;\n height: 16px;\n width: 16px;\n display: block;\n -webkit-mask: var(--dv-tab-close-icon) 50% 50%/90% 90% no-repeat;\n mask: var(--dv-tab-close-icon) 50% 50%/90% 90% no-repeat;\n margin-right: \"0.5em\";\n cursor: pointer;\n}\n.drop-target {\n position: relative;\n}\n.drop-target > .drop-target-dropzone {\n position: absolute;\n left: 0px;\n top: 0px;\n height: 100%;\n width: 100%;\n z-index: 10000;\n}\n.drop-target > .drop-target-dropzone > .drop-target-selection {\n position: relative;\n pointer-events: none;\n box-sizing: border-box;\n height: 100%;\n width: 100%;\n background-color: var(--dv-drag-over-background-color);\n transition-duration: 0.15s;\n transition-timing-function: ease-out;\n}\n.drop-target > .drop-target-dropzone > .drop-target-selection.left, .drop-target > .drop-target-dropzone > .drop-target-selection.right {\n width: 50%;\n}\n.drop-target > .drop-target-dropzone > .drop-target-selection.right {\n transform: translate(100%, 0%);\n}\n.drop-target > .drop-target-dropzone > .drop-target-selection.bottom {\n transform: translate(0%, 100%);\n}\n.drop-target > .drop-target-dropzone > .drop-target-selection.top, .drop-target > .drop-target-dropzone > .drop-target-selection.bottom {\n height: 50%;\n}\n.drop-target > .drop-target-dropzone > .drop-target-selection.small-top {\n border-top: 1px solid var(--dv-drag-over-border-color);\n}\n.drop-target > .drop-target-dropzone > .drop-target-selection.small-bottom {\n border-bottom: 1px solid var(--dv-drag-over-border-color);\n}\n.drop-target > .drop-target-dropzone > .drop-target-selection.small-left {\n border-left: 1px solid var(--dv-drag-over-border-color);\n}\n.drop-target > .drop-target-dropzone > .drop-target-selection.small-right {\n border-right: 1px solid var(--dv-drag-over-border-color);\n}\n.custom-dragging {\n height: 24px;\n line-height: 24px;\n font-size: 11px;\n width: 100px;\n background-color: dodgerblue;\n color: ghostwhite;\n border-radius: 11px;\n position: absolute;\n padding-left: 10px;\n}\n\n.groupview.active-group > .tabs-and-actions-container > .tabs-container > .tab.active-tab {\n background-color: var(--dv-activegroup-visiblepanel-tab-background-color);\n color: var(--dv-activegroup-visiblepanel-tab-color);\n}\n.groupview.active-group > .tabs-and-actions-container > .tabs-container > .tab.active-tab .tab-action {\n background-color: var(--dv-activegroup-visiblepanel-tab-color);\n}\n.groupview.active-group > .tabs-and-actions-container > .tabs-container > .tab.inactive-tab {\n background-color: var(--dv-activegroup-hiddenpanel-tab-background-color);\n color: var(--dv-activegroup-hiddenpanel-tab-color);\n}\n.groupview.active-group > .tabs-and-actions-container > .tabs-container > .tab.inactive-tab .tab-action {\n background-color: var(--dv-activegroup-hiddenpanel-tab-color);\n}\n.groupview.inactive-group > .tabs-and-actions-container > .tabs-container > .tab.active-tab {\n background-color: var(--dv-inactivegroup-visiblepanel-tab-background-color);\n color: var(--dv-inactivegroup-visiblepanel-tab-color);\n}\n.groupview.inactive-group > .tabs-and-actions-container > .tabs-container > .tab.active-tab .tab-action {\n background-color: var(--dv-inactivegroup-visiblepanel-tab-color);\n}\n.groupview.inactive-group > .tabs-and-actions-container > .tabs-container > .tab.inactive-tab {\n background-color: var(--dv-inactivegroup-hiddenpanel-tab-background-color);\n color: var(--dv-inactivegroup-hiddenpanel-tab-color);\n}\n.groupview.inactive-group > .tabs-and-actions-container > .tabs-container > .tab.inactive-tab .tab-action {\n background-color: var(--dv-inactivegroup-hiddenpanel-tab-color);\n}\n\n/**\n * when a tab is dragged we lose the above stylings because they are conditional on parent elements\n * therefore we also set some stylings for the dragging event\n **/\n.tab.dragging {\n background-color: var(--dv-activegroup-visiblepanel-tab-background-color);\n color: var(--dv-activegroup-visiblepanel-tab-color);\n}\n.grid-view,\n.branch-node {\n height: 100%;\n width: 100%;\n}\n.groupview {\n display: flex;\n flex-direction: column;\n height: 100%;\n background-color: var(--dv-group-view-background-color);\n overflow: hidden;\n}\n.groupview:focus {\n outline: none;\n}\n.groupview.empty > .tabs-and-actions-container {\n display: none;\n}\n.groupview > .content-container {\n flex-grow: 1;\n overflow: hidden;\n outline: none;\n}\n.pane-container {\n height: 100%;\n width: 100%;\n}\n.pane-container.animated .view {\n transition-duration: 0.15s;\n transition-timing-function: ease-out;\n}\n.pane-container .view {\n overflow: hidden;\n display: flex;\n flex-direction: column;\n padding: 0px !important;\n}\n.pane-container .view:not(:first-child)::before {\n background-color: transparent !important;\n}\n.pane-container .view:not(:first-child) .pane > .pane-header {\n border-top: 1px solid var(--dv-paneview-header-border-color);\n}\n.pane-container .view .default-header {\n background-color: var(--dv-group-view-background-color);\n color: var(--dv-activegroup-visiblepanel-tab-color);\n display: flex;\n padding: 0px 8px;\n}\n.pane-container .view .default-header > span {\n flex-grow: 1;\n}\n.pane-container:first-of-type > .pane > .pane-header {\n border-top: none !important;\n}\n.pane-container .pane {\n display: flex;\n flex-direction: column;\n overflow: hidden;\n height: 100%;\n}\n.pane-container .pane .pane-header {\n box-sizing: border-box;\n user-select: none;\n position: relative;\n outline: none;\n}\n.pane-container .pane .pane-header.pane-draggable {\n cursor: pointer;\n}\n.pane-container .pane .pane-header:focus:before, .pane-container .pane .pane-header:focus-within:before {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 5;\n content: \"\";\n pointer-events: none;\n outline: 1px solid;\n outline-width: -1px;\n outline-style: solid;\n outline-offset: -1px;\n outline-color: var(--dv-paneview-active-outline-color);\n}\n.pane-container .pane .pane-body {\n overflow-y: auto;\n overflow-x: hidden;\n flex-grow: 1;\n position: relative;\n outline: none;\n}\n.pane-container .pane .pane-body:focus:before, .pane-container .pane .pane-body:focus-within:before {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 5;\n content: \"\";\n pointer-events: none;\n outline: 1px solid;\n outline-width: -1px;\n outline-style: solid;\n outline-offset: -1px;\n outline-color: var(--dv-paneview-active-outline-color);\n}\n.tabs-and-actions-container {\n display: flex;\n background-color: var(--dv-tabs-and-actions-container-background-color);\n flex-shrink: 0;\n box-sizing: border-box;\n height: var(--dv-tabs-and-actions-container-height);\n font-size: var(--dv-tabs-and-actions-container-font-size);\n}\n.tabs-and-actions-container.hidden {\n display: none;\n}\n.tabs-and-actions-container .void-container {\n display: flex;\n flex-grow: 1;\n}\n.tabs-and-actions-container .tabs-container {\n display: flex;\n overflow-x: overlay;\n overflow-y: hidden;\n scrollbar-width: thin;\n /* Track */\n /* Handle */\n}\n.tabs-and-actions-container .tabs-container::-webkit-scrollbar {\n height: 3px;\n}\n.tabs-and-actions-container .tabs-container::-webkit-scrollbar-track {\n background: transparent;\n}\n.tabs-and-actions-container .tabs-container::-webkit-scrollbar-thumb {\n background: var(--dv-tabs-container-scrollbar-color);\n}\n.tabs-and-actions-container .tabs-container .tab {\n -webkit-user-drag: element;\n outline: none;\n min-width: 75px;\n cursor: pointer;\n position: relative;\n box-sizing: border-box;\n}\n.tabs-and-actions-container .tabs-container .tab:not(:first-child)::before {\n content: \" \";\n position: absolute;\n top: 0;\n left: 0;\n z-index: 5;\n pointer-events: none;\n background-color: var(--dv-tab-divider-color);\n width: 1px;\n height: 100%;\n}\n.split-view-container {\n position: relative;\n overflow: hidden;\n height: 100%;\n width: 100%;\n}\n.split-view-container.animation .view,\n.split-view-container.animation .sash {\n transition-duration: 0.15s;\n transition-timing-function: ease-out;\n}\n.split-view-container.horizontal {\n height: 100%;\n}\n.split-view-container.horizontal > .sash-container > .sash {\n height: 100%;\n width: 4px;\n}\n.split-view-container.horizontal > .sash-container > .sash.enabled {\n cursor: ew-resize;\n}\n.split-view-container.horizontal > .sash-container > .sash.disabled {\n cursor: default;\n}\n.split-view-container.horizontal > .sash-container > .sash.maximum {\n cursor: w-resize;\n}\n.split-view-container.horizontal > .sash-container > .sash.minimum {\n cursor: e-resize;\n}\n.split-view-container.horizontal > .view-container > .view:not(:first-child)::before {\n height: 100%;\n width: 1px;\n}\n.split-view-container.vertical {\n width: 100%;\n}\n.split-view-container.vertical > .sash-container > .sash {\n width: 100%;\n height: 4px;\n}\n.split-view-container.vertical > .sash-container > .sash.enabled {\n cursor: ns-resize;\n}\n.split-view-container.vertical > .sash-container > .sash.disabled {\n cursor: default;\n}\n.split-view-container.vertical > .sash-container > .sash.maximum {\n cursor: n-resize;\n}\n.split-view-container.vertical > .sash-container > .sash.minimum {\n cursor: s-resize;\n}\n.split-view-container.vertical > .view-container > .view {\n width: 100%;\n}\n.split-view-container.vertical > .view-container > .view:not(:first-child)::before {\n height: 1px;\n width: 100%;\n}\n.split-view-container .sash-container {\n height: 100%;\n width: 100%;\n position: absolute;\n}\n.split-view-container .sash-container .sash {\n position: absolute;\n z-index: 99;\n outline: none;\n}\n.split-view-container .sash-container .sash:active {\n transition: background-color 0.1s ease-in-out;\n background-color: var(--dv-active-sash-color, transparent);\n}\n.split-view-container .sash-container .sash:hover {\n background-color: var(--dv-active-sash-color, transparent);\n transition: background-color 0.1s ease-in-out;\n transition-delay: 0.5s;\n}\n.split-view-container .view-container {\n position: relative;\n height: 100%;\n width: 100%;\n}\n.split-view-container .view-container .view {\n height: 100%;\n box-sizing: border-box;\n overflow: auto;\n position: absolute;\n}\n.split-view-container.separator-border .view:not(:first-child)::before {\n content: \" \";\n position: absolute;\n top: 0;\n left: 0;\n z-index: 5;\n pointer-events: none;\n background-color: var(--dv-separator-border);\n}\n.dragged {\n transform: translate3d(0px, 0px, 0px);\n /* forces tab to be drawn on a separate layer (see https://github.com/microsoft/vscode/issues/18733) */\n}\n\n.tab {\n flex-shrink: 0;\n}\n.tab.dragging .tab-action {\n background-color: var(--dv-activegroup-visiblepanel-tab-color);\n}\n.tab.active-tab > .default-tab .tab-action {\n visibility: visible;\n}\n.tab.inactive-tab > .default-tab .tab-action:not(.dirty) {\n visibility: hidden;\n}\n.tab.inactive-tab > .default-tab:hover .tab-action {\n visibility: visible;\n}\n.tab .default-tab {\n position: relative;\n height: 100%;\n display: flex;\n min-width: 80px;\n align-items: center;\n padding-left: 10px;\n white-space: nowrap;\n text-overflow: elipsis;\n}\n.tab .default-tab .tab-content {\n flex-grow: 1;\n}\n.tab .default-tab .action-container {\n text-align: right;\n width: 28px;\n display: flex;\n}\n.tab .default-tab .action-container .tab-list {\n display: flex;\n padding: 0px;\n margin: 0px;\n justify-content: flex-end;\n}\n.tab .default-tab .action-container .tab-list a:active:hover {\n -webkit-mask-size: 100% 100% !important;\n mask-size: 100% 100% !important;\n}\n.tab .default-tab .action-container .tab-list .tab-action {\n height: 16px;\n width: 16px;\n display: block;\n -webkit-mask: var(--dv-tab-close-icon) 50% 50%/90% 90% no-repeat;\n mask: var(--dv-tab-close-icon) 50% 50%/90% 90% no-repeat;\n margin-right: \"0.5em\";\n}\n.tab .default-tab .action-container .tab-list .tab-action.disable-close {\n display: none;\n}\n.tab .default-tab .action-container .tab-list .tab-action.dirty:not(:hover) {\n display: block;\n -webkit-mask: var(--dv-tab-dirty-icon) 50% 50%/60% 60% no-repeat;\n mask: var(--dv-tab-dirty-icon) 50% 50%/60% 60% no-repeat;\n}\n.watermark {\n display: flex;\n width: 100%;\n}\n.watermark.has-actions .watermark-title .actions-bar {\n display: none;\n}\n.watermark .watermark-title {\n height: 35px;\n width: 100%;\n display: flex;\n}\n.watermark .watermark-content {\n flex-grow: 1;\n}";
styleInject(css_248z);
function runFootnote() {
var _a, _b;
const DOCKVIEW_SUPPRESS_WATERMARK = 'DOCKVIEW_WATERMARK_SUPPRESSED';
const isTest = ((_b = (_a = window.process) === null || _a === void 0 ? void 0 : _a.env) === null || _b === void 0 ? void 0 : _b.NODE_ENV) === 'test';
if (isTest) {
return; // don't spam people tests
}
const isSuppressed = !!window[DOCKVIEW_SUPPRESS_WATERMARK];
if (!isSuppressed) {
console.log([
'dockview: https://github.com/mathuo/dockview for examples and documentation',
'dockview: https://www.npmjs.com/package/dockview',
`dockview: To suppress this message set window.${DOCKVIEW_SUPPRESS_WATERMARK}=1 before importing the dockview package`,
'',
].join('\n'));
}
}
runFootnote();
exports.Event = void 0;
(function (Event) {
Event.any = (...children) => {
return (listener) => {
const disposables = children.map((child) => child(listener));
return {
dispose: () => {
disposables.forEach((d) => {
d.dispose();
});
},
};
};
};
})(exports.Event || (exports.Event = {}));
// dumb event emitter with better typings than nodes event emitter
// https://github.com/microsoft/vscode/blob/master/src/vs/base/common/event.ts
class Emitter {
constructor(options) {
this.options = options;
this._listeners = [];
this._disposed = false;
}
get event() {
if (!this._event) {
this._event = (listener) => {
var _a;
if (((_a = this.options) === null || _a === void 0 ? void 0 : _a.replay) && this._last !== undefined) {
listener(this._last);
}
this._listeners.length === 0;
this._listeners.push(listener);
return {
dispose: () => {
const index = this._listeners.indexOf(listener);
if (index > -1) {
this._listeners.splice(index, 1);
}
},
};
};
}
return this._event;
}
fire(e) {
this._last = e;
this._listeners.forEach((listener) => {
listener(e);
});
}
dispose() {
this._listeners = [];
this._disposed = true;
}
}
function addDisposableWindowListener(element, type, listener, options) {
element.addEventListener(type, listener, options);
return {
dispose: () => {
element.removeEventListener(type, listener);
},
};
}
function addDisposableListener(element, type, listener, options) {
element.addEventListener(type, listener, options);
return {
dispose: () => {
element.removeEventListener(type, listener);
},
};
}
exports.Disposable = void 0;
(function (Disposable) {
Disposable.NONE = {
dispose: () => {
// noop
},
};
})(exports.Disposable || (exports.Disposable = {}));
class CompositeDisposable {
constructor(...args) {
this.disposables = args;
}
static from(...args) {
return new CompositeDisposable(...args);
}
addDisposables(...args) {
args === null || args === void 0 ? void 0 : args.forEach((arg) => this.disposables.push(arg));
}
dispose() {
this.disposables.forEach((arg) => arg.dispose());
}
}
class MutableDisposable {
constructor() {
this._disposable = exports.Disposable.NONE;
}
set value(disposable) {
if (this._disposable) {
this._disposable.dispose();
}
this._disposable = disposable;
}
dispose() {
if (this._disposable) {
this._disposable.dispose();
}
}
}
function tryParseJSON(text, reviver) {
try {
return JSON.parse(text, reviver);
}
catch (err) {
console.warn('failed to parse JSON');
return undefined;
}
}
class TransferObject {
constructor() {
//
}
}
class PanelTransfer extends TransferObject {
constructor(viewId, groupId, panelId) {
super();
this.viewId = viewId;
this.groupId = groupId;
this.panelId = panelId;
}
}
class PaneTransfer extends TransferObject {
constructor(viewId, paneId) {
super();
this.viewId = viewId;
this.paneId = paneId;
}
}
const DATA_KEY = 'splitview/transfer';
const isPanelTransferEvent = (event) => {
if (!event.dataTransfer) {
return false;
}
return event.dataTransfer.types.includes(DATA_KEY);
};
exports.DragType = void 0;
(function (DragType) {
DragType["DOCKVIEW_TAB"] = "dockview_tab";
DragType["EXTERNAL"] = "external_group_drag";
})(exports.DragType || (exports.DragType = {}));
/**
* Determine whether this data belong to that of an event that was started by
* dragging a tab component
*/
const isTabDragEvent = (data) => {
return data.type === exports.DragType.DOCKVIEW_TAB;
};
/**
* Determine whether this data belong to that of an event that was started by
* a custom drag-enable component
*/
const isCustomDragEvent = (data) => {
return data.type === exports.DragType.EXTERNAL;
};
const extractData = (event) => {
if (!event.dataTransfer) {
return null;
}
const data = tryParseJSON(event.dataTransfer.getData(DATA_KEY));
if (!data) {
console.warn(`[dragEvent] ${DATA_KEY} data is missing`);
}
if (typeof data.type !== 'string') {
console.warn(`[dragEvent] invalid type ${data.type}`);
}
return data;
};
/**
* A singleton to store transfer data during drag & drop operations that are only valid within the application.
*/
class LocalSelectionTransfer {
constructor() {
// protect against external instantiation
}
static getInstance() {
return LocalSelectionTransfer.INSTANCE;
}
hasData(proto) {
return proto && proto === this.proto;
}
clearData(proto) {
if (this.hasData(proto)) {
this.proto = undefined;
this.data = undefined;
}
}
getData(proto) {
if (this.hasData(proto)) {
return this.data;
}
return undefined;
}
setData(data, proto) {
if (proto) {
this.data = data;
this.proto = proto;
}
}
}
LocalSelectionTransfer.INSTANCE = new LocalSelectionTransfer();
function getPanelData() {
const panelTransfer = LocalSelectionTransfer.getInstance();
const isPanelEvent = panelTransfer.hasData(PanelTransfer.prototype);
if (!isPanelEvent) {
return undefined;
}
return panelTransfer.getData(PanelTransfer.prototype)[0];
}
function getPaneData() {
const paneTransfer = LocalSelectionTransfer.getInstance();
const isPanelEvent = paneTransfer.hasData(PaneTransfer.prototype);
if (!isPanelEvent) {
return undefined;
}
return paneTransfer.getData(PaneTransfer.prototype)[0];
}
class SplitviewApi {
constructor(component) {
this.component = component;
}
get minimumSize() {
return this.component.minimumSize;
}
get maximumSize() {
return this.component.maximumSize;
}
get height() {
return this.component.height;
}
get width() {
return this.component.width;
}
get length() {
return this.component.length;
}
get onDidLayoutChange() {
return this.component.onDidLayoutChange;
}
get orientation() {
return this.component.orientation;
}
updateOptions(options) {
this.component.updateOptions(options);
}
removePanel(panel, sizing) {
this.component.removePanel(panel, sizing);
}
setVisible(panel, isVisible) {
this.component.setVisible(panel, isVisible);
}
getPanels() {
return this.component.getPanels();
}
focus() {
this.component.focus();
}
getPanel(id) {
return this.component.getPanel(id);
}
setActive(panel) {
this.component.setActive(panel);
}
layout(width, height) {
return this.component.layout(width, height);
}
addPanel(options) {
this.component.addPanel(options);
}
resizeToFit() {
this.component.resizeToFit();
}
movePanel(from, to) {
this.component.movePanel(from, to);
}
fromJSON(data, deferComponentLayout) {
this.component.fromJSON(data, deferComponentLayout);
}
toJSON() {
return this.component.toJSON();
}
}
class PaneviewApi {
constructor(component) {
this.component = component;
}
get width() {
return this.component.width;
}
get height() {
return this.component.height;
}
get minimumSize() {
return this.component.minimumSize;
}
get maximumSize() {
return this.component.maximumSize;
}
get onDidLayoutChange() {
return this.component.onDidLayoutChange;
}
getPanels() {
return this.component.getPanels();
}
removePanel(panel) {
this.component.removePanel(panel);
}
getPanel(id) {
return this.component.getPanel(id);
}
movePanel(from, to) {
this.component.movePanel(from, to);
}
focus() {
this.component.focus();
}
layout(width, height) {
this.component.layout(width, height);
}
addPanel(options) {
return this.component.addPanel(options);
}
resizeToFit() {
this.component.resizeToFit();
}
fromJSON(data, deferComponentLayout) {
this.component.fromJSON(data, deferComponentLayout);
}
toJSON() {
return this.component.toJSON();
}
}
class GridviewApi {
constructor(component) {
this.component = component;
}
get width() {
return this.component.width;
}
get height() {
return this.component.height;
}
get minimumHeight() {
return this.component.minimumHeight;
}
get maximumHeight() {
return this.component.maximumHeight;
}
get minimumWidth() {
return this.component.minimumWidth;
}
get maximumWidth() {
return this.component.maximumWidth;
}
get onGridEvent() {
return this.component.onGridEvent;
}
get onDidLayoutChange() {
return this.component.onDidLayoutChange;
}
get panels() {
return this.component.groups;
}
get orientation() {
return this.component.orientation;
}
set orientation(value) {
this.component.updateOptions({ orientation: value });
}
focus() {
this.component.focus();
}
layout(width, height, force = false) {
this.component.layout(width, height, force);
}
addPanel(options) {
this.component.addPanel(options);
}
removePanel(panel, sizing) {
this.component.removePanel(panel, sizing);
}
movePanel(panel, options) {
this.component.movePanel(panel, options);
}
resizeToFit() {
this.component.resizeToFit();
}
getPanel(id) {
return this.component.getPanel(id);
}
toggleVisibility(panel) {
this.component.toggleVisibility(panel);
}
setVisible(panel, visible) {
this.component.setVisible(panel, visible);
}
setActive(panel) {
this.component.setActive(panel);
}
fromJSON(data, deferComponentLayout) {
return this.component.fromJSON(data, deferComponentLayout);
}
toJSON() {
return this.component.toJSON();
}
}
class DockviewApi {
constructor(component) {
this.component = component;
}
get width() {
return this.component.width;
}
get height() {
return this.component.height;
}
get minimumHeight() {
return this.component.minimumHeight;
}
get maximumHeight() {
return this.component.maximumHeight;
}
get minimumWidth() {
return this.component.minimumWidth;
}
get maximumWidth() {
return this.component.maximumWidth;
}
get size() {
return this.component.size;
}
get totalPanels() {
return this.component.totalPanels;
}
get onGridEvent() {
return this.component.onGridEvent;
}
get onDidLayoutChange() {
return this.component.onDidLayoutChange;
}
get panels() {
return this.component.panels;
}
get groups() {
return this.component.groups;
}
get activePanel() {
return this.component.activePanel;
}
get activeGroup() {
return this.component.activeGroup;
}
getTabHeight() {
return this.component.tabHeight;
}
setTabHeight(height) {
this.component.tabHeight = height;
}
focus() {
this.component.focus();
}
getPanel(id) {
return this.component.getGroupPanel(id);
}
setActivePanel(panel) {
this.component.setActivePanel(panel);
}
layout(width, height, force = false) {
this.component.layout(width, height, force);
}
addPanel(options) {
return this.component.addPanel(options);
}
removePanel(panel) {
this.component.removePanel(panel);
}
addEmptyGroup(options) {
this.component.addEmptyGroup(options);
}
moveToNext(options) {
this.component.moveToNext(options);
}
moveToPrevious(options) {
this.component.moveToPrevious(options);
}
closeAllGroups() {
return this.component.closeAllGroups();
}
removeGroup(group) {
this.component.removeGroup(group);
}
resizeToFit() {
return this.component.resizeToFit();
}
getGroup(id) {
return this.component.getPanel(id);
}
fromJSON(data) {
this.component.fromJSON(data);
}
toJSON() {
return this.component.toJSON();
}
}
function watchElementResize(element, cb) {
const observer = new ResizeObserver((entires) => {
const firstEntry = entires[0];
cb(firstEntry);
});
observer.observe(element);
return {
dispose: () => {
observer.unobserve(element);
observer.disconnect();
},
};
}
const removeClasses = (element, ...classes) => {
for (const classname of classes) {
if (element.classList.contains(classname)) {
element.classList.remove(classname);
}
}
};
const addClasses = (element, ...classes) => {
for (const classname of classes) {
if (!element.classList.contains(classname)) {
element.classList.add(classname);
}
}
};
const toggleClass = (element, className, isToggled) => {
const hasClass = element.classList.contains(className);
if (isToggled && !hasClass) {
element.classList.add(className);
}
if (!isToggled && hasClass) {
element.classList.remove(className);
}
};
function isAncestor(testChild, testAncestor) {
while (testChild) {
if (testChild === testAncestor) {
return true;
}
testChild = testChild.parentNode;
}
return false;
}
function getElementsByTagName(tag) {
return Array.prototype.slice.call(document.getElementsByTagName(tag), 0);
}
function trackFocus(element) {
return new FocusTracker(element);
}
/**
* Track focus on an element. Ensure tabIndex is set when an HTMLElement is not focusable by default
*/
class FocusTracker extends CompositeDisposable {
constructor(element) {
super();
this._onDidFocus = new Emitter();
this.onDidFocus = this._onDidFocus.event;
this._onDidBlur = new Emitter();
this.onDidBlur = this._onDidBlur.event;
let hasFocus = isAncestor(document.activeElement, element);
let loosingFocus = false;
const onFocus = () => {
loosingFocus = false;
if (!hasFocus) {
hasFocus = true;
this._onDidFocus.fire();
}
};
const onBlur = () => {
if (hasFocus) {
loosingFocus = true;
window.setTimeout(() => {
if (loosingFocus) {
loosingFocus = false;
hasFocus = false;
this._onDidBlur.fire();
}
}, 0);
}
};
this._refreshStateHandler = () => {
const currentNodeHasFocus = isAncestor(document.activeElement, element);
if (currentNodeHasFocus !== hasFocus) {
if (hasFocus) {
onBlur();
}
else {
onFocus();
}
}
};
if (element instanceof HTMLElement) {
this.addDisposables(addDisposableListener(element, 'focus', onFocus, true));
this.addDisposables(addDisposableListener(element, 'blur', onBlur, true));
}
else {
this.addDisposables(addDisposableWindowListener(element, 'focus', onFocus, true));
this.addDisposables(addDisposableWindowListener(element, 'blur', onBlur, true));
}
}
refreshState() {
this._refreshStateHandler();
}
dispose() {
super.dispose();
this._onDidBlur.dispose();
this._onDidFocus.dispose();
}
}
const clamp = (value, min, max) => {
if (min > max) {
throw new Error(`${min} > ${max} is an invalid condition`);
}
return Math.min(max, Math.max(value, min));
};
const sequentialNumberGenerator = () => {
let value = 1;
return { next: () => (value++).toString() };
};
function tail(arr) {
if (arr.length === 0) {
throw new Error('Invalid tail call');
}
return [arr.slice(0, arr.length - 1), arr[arr.length - 1]];
}
function last(arr) {
return arr.length > 0 ? arr[arr.length - 1] : undefined;
}
function sequenceEquals(arr1, arr2) {
if (arr1.length !== arr2.length) {
return false;
}
for (let i = 0; i < arr1.length; i++) {
if (arr1[i] !== arr2[i]) {
return false;
}
}
return true;
}
/**
* Pushes an element to the start of the array, if found.
*/
function pushToStart(arr, value) {
const index = arr.indexOf(value);
if (index > -1) {
arr.splice(index, 1);
arr.unshift(value);
}
}
/**
* Pushes an element to the end of the array, if found.
*/
function pushToEnd(arr, value) {
const index = arr.indexOf(value);
if (index > -1) {
arr.splice(index, 1);
arr.push(value);
}
}
const range = (from, to) => {
const result = [];
if (typeof to !== 'number') {
to = from;
from = 0;
}
if (from <= to) {
for (let i = from; i < to; i++) {
result.push(i);
}
}
else {
for (let i = from; i > to; i--) {
result.push(i);
}
}
return result;
};
function firstIndex(array, fn) {
for (let i = 0; i < array.length; i++) {
const element = array[i];
if (fn(element)) {
return i;
}
}
return -1;
}
class ViewItem {
constructor(container, view, size, disposable) {
this.container = container;
this.view = view;
this.disposable = disposable;
this._cachedVisibleSize = undefined;
if (typeof size === 'number') {
this._size = size;
this._cachedVisibleSize = undefined;
container.classList.add('visible');
}
else {
this._size = 0;
this._cachedVisibleSize = size.cachedVisibleSize;
}
}
set size(size) {
this._size = size;
}
get size() {
return this._size;
}
get cachedVisibleSize() {
return this._cachedVisibleSize;
}
get visible() {
return typeof this._cachedVisibleSize === 'undefined';
}
setVisible(visible, size) {
var _a;
if (visible === this.visible) {
return;
}
if (visible) {
this.size = clamp((_a = this._cachedVisibleSize) !== null && _a !== void 0 ? _a : 0, this.viewMinimumSize, this.viewMaximumSize);
this._cachedVisibleSize = undefined;
}
else {
this._cachedVisibleSize =
typeof size === 'number' ? size : this.size;
this.size = 0;
}
this.container.classList.toggle('visible', visible);
if (this.view.setVisible) {
this.view.setVisible(visible);
}
}
get minimumSize() {
return this.visible ? this.view.minimumSize : 0;
}
get viewMinimumSize() {
return this.view.minimumSize;
}
get maximumSize() {
return this.visible ? this.view.maximumSize : 0;
}
get viewMaximumSize() {
return this.view.maximumSize;
}
get priority() {
return this.view.priority;
}
get snap() {
return !!this.view.snap;
}
set enabled(enabled) {
this.container.style.pointerEvents = enabled ? '' : 'none';
}
// layout(offset: number, layoutContext: TLayoutContext | undefined): void {
// this.layoutContainer(offset);
// this.view.layout(this.size, offset, layoutContext);
// }
// abstract layoutContainer(offset: number): void;
dispose() {
this.disposable.dispose();
return this.view;
}
}
/*---------------------------------------------------------------------------------------------
* 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
*--------------------------------------------------------------------------------------------*/
exports.Orientation = void 0;
(function (Orientation) {
Orientation["HORIZONTAL"] = "HORIZONTAL";
Orientation["VERTICAL"] = "VERTICAL";
})(exports.Orientation || (exports.Orientation = {}));
exports.SashState = void 0;
(function (SashState) {
SashState[SashState["MAXIMUM"] = 0] = "MAXIMUM";
SashState[SashState["MINIMUM"] = 1] = "MINIMUM";
SashState[SashState["DISABLED"] = 2] = "DISABLED";
SashState[SashState["ENABLED"] = 3] = "ENABLED";
})(exports.SashState || (exports.SashState = {}));
exports.LayoutPriority = void 0;
(function (LayoutPriority) {
LayoutPriority["Low"] = "low";
LayoutPriority["High"] = "high";
LayoutPriority["Normal"] = "normal";
})(exports.LayoutPriority || (exports.LayoutPriority = {}));
exports.Sizing = void 0;
(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;
})(exports.Sizing || (exports.Sizing = {}));
class Splitview {
constructor(container, options) {
this.container = container;
this.views = [];
this.sashes = [];
this._size = 0;
this._orthogonalSize = 0;
this.contentSize = 0;
this._proportions = undefined;
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._onDidAddView.event;
this._startSnappingEnabled = true;
this._endSnappingEnabled = true;
this.resize = (index, delta, sizes = this.views.map((x) => x.size), lowPriorityIndexes, highPriorityIndexes, overloadMinDelta = Number.NEGATIVE_INFINITY, overloadMaxDelta = Number.POSITIVE_INFINITY, snapBefore, snapAfter) => {
if (index < 0 || index > this.views.length) {
return 0;
}
const upIndexes = range(index, -1);
const downIndexes = range(index + 1, this.views.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.views[i]);
const upSizes = upIndexes.map((i) => sizes[i]);
//
const downItems = downIndexes.map((i) => this.views[i]);
const downSizes = downIndexes.map((i) => sizes[i]);
//
const minDeltaUp = upIndexes.reduce((_, i) => _ + this.views[i].minimumSize - sizes[i], 0);
const maxDeltaUp = upIndexes.reduce((_, i) => _ + this.views[i].maximumSize - sizes[i], 0);
//
const maxDeltaDown = downIndexes.length === 0
? Number.POSITIVE_INFINITY
: downIndexes.reduce((_, i) => _ + sizes[i] - this.views[i].minimumSize, 0);
const minDeltaDown = downIndexes.length === 0
? Number.NEGATIVE_INFINITY
: downIndexes.reduce((_, i) => _ + sizes[i] - this.views[i].maximumSize, 0);
//
const minDelta = Math.max(minDeltaUp, minDeltaDown);
const maxDelta = Math.min(maxDeltaDown, maxDeltaUp);
//
let snapped = false;
if (snapBefore) {
const snapView = this.views[snapBefore.index];
const visible = delta >= snapBefore.limitDelta;
snapped = visible !== snapView.visible;
snapView.setVisible(visible, snapBefore.size);
}
if (!snapped && snapAfter) {
const snapView = this.views[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 = options.orientation;
this.element = this.createContainer();
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