UNPKG

dockview

Version:

Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support

1,032 lines (1,010 loc) 274 kB
/** * 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