UNPKG

dockview-core

Version:

Zero dependency layout manager supporting tabs, grids and splitviews

1,050 lines 94.4 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DockviewComponent = void 0; var gridview_1 = require("../gridview/gridview"); var droptarget_1 = require("../dnd/droptarget"); var array_1 = require("../array"); var dockviewPanel_1 = require("./dockviewPanel"); var lifecycle_1 = require("../lifecycle"); var events_1 = require("../events"); var watermark_1 = require("./components/watermark/watermark"); var math_1 = require("../math"); var deserializer_1 = require("./deserializer"); var options_1 = require("./options"); var baseComponentGridview_1 = require("../gridview/baseComponentGridview"); var component_api_1 = require("../api/component.api"); var splitview_1 = require("../splitview/splitview"); var dockviewGroupPanelModel_1 = require("./dockviewGroupPanelModel"); var dockviewGroupPanel_1 = require("./dockviewGroupPanel"); var dockviewPanelModel_1 = require("./dockviewPanelModel"); var dataTransfer_1 = require("../dnd/dataTransfer"); var overlay_1 = require("../overlay/overlay"); var dom_1 = require("../dom"); var dockviewFloatingGroupPanel_1 = require("./dockviewFloatingGroupPanel"); var constants_1 = require("../constants"); var overlayRenderContainer_1 = require("../overlay/overlayRenderContainer"); var popoutWindow_1 = require("../popoutWindow"); var strictEventsSequencing_1 = require("./strictEventsSequencing"); var popupService_1 = require("./components/popupService"); var dropTargetAnchorContainer_1 = require("../dnd/dropTargetAnchorContainer"); var theme_1 = require("./theme"); var DEFAULT_ROOT_OVERLAY_MODEL = { activationSize: { type: 'pixels', value: 10 }, size: { type: 'pixels', value: 20 }, }; function moveGroupWithoutDestroying(options) { var activePanel = options.from.activePanel; var panels = __spreadArray([], __read(options.from.panels), false).map(function (panel) { var removedPanel = options.from.model.removePanel(panel); options.from.model.renderContainer.detatch(panel); return removedPanel; }); panels.forEach(function (panel) { options.to.model.openPanel(panel, { skipSetActive: activePanel !== panel, skipSetGroupActive: true, }); }); } var DockviewComponent = /** @class */ (function (_super) { __extends(DockviewComponent, _super); function DockviewComponent(container, options) { var _a, _b, _c; var _this = _super.call(this, container, { proportionalLayout: true, orientation: splitview_1.Orientation.HORIZONTAL, styles: options.hideBorders ? { separatorBorder: 'transparent' } : undefined, disableAutoResizing: options.disableAutoResizing, locked: options.locked, margin: (_b = (_a = options.theme) === null || _a === void 0 ? void 0 : _a.gap) !== null && _b !== void 0 ? _b : 0, className: options.className, }) || this; _this.nextGroupId = (0, math_1.sequentialNumberGenerator)(); _this._deserializer = new deserializer_1.DefaultDockviewDeserialzier(_this); _this._watermark = null; _this._onWillDragPanel = new events_1.Emitter(); _this.onWillDragPanel = _this._onWillDragPanel.event; _this._onWillDragGroup = new events_1.Emitter(); _this.onWillDragGroup = _this._onWillDragGroup.event; _this._onDidDrop = new events_1.Emitter(); _this.onDidDrop = _this._onDidDrop.event; _this._onWillDrop = new events_1.Emitter(); _this.onWillDrop = _this._onWillDrop.event; _this._onWillShowOverlay = new events_1.Emitter(); _this.onWillShowOverlay = _this._onWillShowOverlay.event; _this._onUnhandledDragOverEvent = new events_1.Emitter(); _this.onUnhandledDragOverEvent = _this._onUnhandledDragOverEvent.event; _this._onDidRemovePanel = new events_1.Emitter(); _this.onDidRemovePanel = _this._onDidRemovePanel.event; _this._onDidAddPanel = new events_1.Emitter(); _this.onDidAddPanel = _this._onDidAddPanel.event; _this._onDidPopoutGroupSizeChange = new events_1.Emitter(); _this.onDidPopoutGroupSizeChange = _this._onDidPopoutGroupSizeChange.event; _this._onDidPopoutGroupPositionChange = new events_1.Emitter(); _this.onDidPopoutGroupPositionChange = _this._onDidPopoutGroupPositionChange.event; _this._onDidLayoutFromJSON = new events_1.Emitter(); _this.onDidLayoutFromJSON = _this._onDidLayoutFromJSON.event; _this._onDidActivePanelChange = new events_1.Emitter(); _this.onDidActivePanelChange = _this._onDidActivePanelChange.event; _this._onDidMovePanel = new events_1.Emitter(); _this.onDidMovePanel = _this._onDidMovePanel.event; _this._onDidMaximizedGroupChange = new events_1.Emitter(); _this.onDidMaximizedGroupChange = _this._onDidMaximizedGroupChange.event; _this._floatingGroups = []; _this._popoutGroups = []; _this._onDidRemoveGroup = new events_1.Emitter(); _this.onDidRemoveGroup = _this._onDidRemoveGroup.event; _this._onDidAddGroup = new events_1.Emitter(); _this.onDidAddGroup = _this._onDidAddGroup.event; _this._onDidOptionsChange = new events_1.Emitter(); _this.onDidOptionsChange = _this._onDidOptionsChange.event; _this._onDidActiveGroupChange = new events_1.Emitter(); _this.onDidActiveGroupChange = _this._onDidActiveGroupChange.event; _this._moving = false; _this._options = options; _this.popupService = new popupService_1.PopupService(_this.element); _this._themeClassnames = new dom_1.Classnames(_this.element); _this._api = new component_api_1.DockviewApi(_this); _this.rootDropTargetContainer = new dropTargetAnchorContainer_1.DropTargetAnchorContainer(_this.element, { disabled: true }); _this.overlayRenderContainer = new overlayRenderContainer_1.OverlayRenderContainer(_this.gridview.element, _this); _this._rootDropTarget = new droptarget_1.Droptarget(_this.element, { className: 'dv-drop-target-edge', canDisplayOverlay: function (event, position) { var data = (0, dataTransfer_1.getPanelData)(); if (data) { if (data.viewId !== _this.id) { return false; } if (position === 'center') { // center drop target is only allowed if there are no panels in the grid // floating panels are allowed return _this.gridview.length === 0; } return true; } if (position === 'center' && _this.gridview.length !== 0) { /** * for external events only show the four-corner drag overlays, disable * the center position so that external drag events can fall through to the group * and panel drop target handlers */ return false; } var firedEvent = new options_1.DockviewUnhandledDragOverEvent(event, 'edge', position, dataTransfer_1.getPanelData); _this._onUnhandledDragOverEvent.fire(firedEvent); return firedEvent.isAccepted; }, acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'], overlayModel: (_c = options.rootOverlayModel) !== null && _c !== void 0 ? _c : DEFAULT_ROOT_OVERLAY_MODEL, getOverrideTarget: function () { var _a; return (_a = _this.rootDropTargetContainer) === null || _a === void 0 ? void 0 : _a.model; }, }); _this.updateDropTargetModel(options); (0, dom_1.toggleClass)(_this.gridview.element, 'dv-dockview', true); (0, dom_1.toggleClass)(_this.element, 'dv-debug', !!options.debug); _this.updateTheme(); _this.updateWatermark(); if (options.debug) { _this.addDisposables(new strictEventsSequencing_1.StrictEventsSequencing(_this)); } _this.addDisposables(_this.rootDropTargetContainer, _this.overlayRenderContainer, _this._onWillDragPanel, _this._onWillDragGroup, _this._onWillShowOverlay, _this._onDidActivePanelChange, _this._onDidAddPanel, _this._onDidRemovePanel, _this._onDidLayoutFromJSON, _this._onDidDrop, _this._onWillDrop, _this._onDidMovePanel, _this._onDidAddGroup, _this._onDidRemoveGroup, _this._onDidActiveGroupChange, _this._onUnhandledDragOverEvent, _this._onDidMaximizedGroupChange, _this._onDidOptionsChange, _this._onDidPopoutGroupSizeChange, _this._onDidPopoutGroupPositionChange, _this.onDidViewVisibilityChangeMicroTaskQueue(function () { _this.updateWatermark(); }), _this.onDidAdd(function (event) { if (!_this._moving) { _this._onDidAddGroup.fire(event); } }), _this.onDidRemove(function (event) { if (!_this._moving) { _this._onDidRemoveGroup.fire(event); } }), _this.onDidActiveChange(function (event) { if (!_this._moving) { _this._onDidActiveGroupChange.fire(event); } }), _this.onDidMaximizedChange(function (event) { _this._onDidMaximizedGroupChange.fire({ group: event.panel, isMaximized: event.isMaximized, }); }), events_1.Event.any(_this.onDidAdd, _this.onDidRemove)(function () { _this.updateWatermark(); }), events_1.Event.any(_this.onDidAddPanel, _this.onDidRemovePanel, _this.onDidAddGroup, _this.onDidRemove, _this.onDidMovePanel, _this.onDidActivePanelChange, _this.onDidPopoutGroupPositionChange, _this.onDidPopoutGroupSizeChange)(function () { _this._bufferOnDidLayoutChange.fire(); }), lifecycle_1.Disposable.from(function () { var e_1, _a, e_2, _b; try { // iterate over a copy of the array since .dispose() mutates the original array for (var _c = __values(__spreadArray([], __read(_this._floatingGroups), false)), _d = _c.next(); !_d.done; _d = _c.next()) { var group = _d.value; group.dispose(); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_d && !_d.done && (_a = _c.return)) _a.call(_c); } finally { if (e_1) throw e_1.error; } } try { // iterate over a copy of the array since .dispose() mutates the original array for (var _e = __values(__spreadArray([], __read(_this._popoutGroups), false)), _f = _e.next(); !_f.done; _f = _e.next()) { var group = _f.value; group.disposable.dispose(); } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (_f && !_f.done && (_b = _e.return)) _b.call(_e); } finally { if (e_2) throw e_2.error; } } }), _this._rootDropTarget, _this._rootDropTarget.onWillShowOverlay(function (event) { if (_this.gridview.length > 0 && event.position === 'center') { // option only available when no panels in primary grid return; } _this._onWillShowOverlay.fire(new dockviewGroupPanelModel_1.WillShowOverlayLocationEvent(event, { kind: 'edge', panel: undefined, api: _this._api, group: undefined, getData: dataTransfer_1.getPanelData, })); }), _this._rootDropTarget.onDrop(function (event) { var _a; var willDropEvent = new dockviewGroupPanelModel_1.DockviewWillDropEvent({ nativeEvent: event.nativeEvent, position: event.position, panel: undefined, api: _this._api, group: undefined, getData: dataTransfer_1.getPanelData, kind: 'edge', }); _this._onWillDrop.fire(willDropEvent); if (willDropEvent.defaultPrevented) { return; } var data = (0, dataTransfer_1.getPanelData)(); if (data) { _this.moveGroupOrPanel({ from: { groupId: data.groupId, panelId: (_a = data.panelId) !== null && _a !== void 0 ? _a : undefined, }, to: { group: _this.orthogonalize(event.position), position: 'center', }, }); } else { _this._onDidDrop.fire(new dockviewGroupPanelModel_1.DockviewDidDropEvent({ nativeEvent: event.nativeEvent, position: event.position, panel: undefined, api: _this._api, group: undefined, getData: dataTransfer_1.getPanelData, })); } }), _this._rootDropTarget); return _this; } Object.defineProperty(DockviewComponent.prototype, "orientation", { get: function () { return this.gridview.orientation; }, enumerable: false, configurable: true }); Object.defineProperty(DockviewComponent.prototype, "totalPanels", { get: function () { return this.panels.length; }, enumerable: false, configurable: true }); Object.defineProperty(DockviewComponent.prototype, "panels", { get: function () { return this.groups.flatMap(function (group) { return group.panels; }); }, enumerable: false, configurable: true }); Object.defineProperty(DockviewComponent.prototype, "options", { get: function () { return this._options; }, enumerable: false, configurable: true }); Object.defineProperty(DockviewComponent.prototype, "activePanel", { get: function () { var activeGroup = this.activeGroup; if (!activeGroup) { return undefined; } return activeGroup.activePanel; }, enumerable: false, configurable: true }); Object.defineProperty(DockviewComponent.prototype, "renderer", { get: function () { var _a; return (_a = this.options.defaultRenderer) !== null && _a !== void 0 ? _a : 'onlyWhenVisible'; }, enumerable: false, configurable: true }); Object.defineProperty(DockviewComponent.prototype, "api", { get: function () { return this._api; }, enumerable: false, configurable: true }); Object.defineProperty(DockviewComponent.prototype, "floatingGroups", { get: function () { return this._floatingGroups; }, enumerable: false, configurable: true }); DockviewComponent.prototype.setVisible = function (panel, visible) { switch (panel.api.location.type) { case 'grid': _super.prototype.setVisible.call(this, panel, visible); break; case 'floating': { var item = this.floatingGroups.find(function (floatingGroup) { return floatingGroup.group === panel; }); if (item) { item.overlay.setVisible(visible); panel.api._onDidVisibilityChange.fire({ isVisible: visible, }); } break; } case 'popout': console.warn('dockview: You cannot hide a group that is in a popout window'); break; } }; DockviewComponent.prototype.addPopoutGroup = function (itemToPopout, options) { var _this = this; var _a, _b, _c, _d, _e; if (itemToPopout instanceof dockviewPanel_1.DockviewPanel && itemToPopout.group.size === 1) { return this.addPopoutGroup(itemToPopout.group, options); } var theme = (0, dom_1.getDockviewTheme)(this.gridview.element); var element = this.element; function getBox() { if (options === null || options === void 0 ? void 0 : options.position) { return options.position; } if (itemToPopout instanceof dockviewGroupPanel_1.DockviewGroupPanel) { return itemToPopout.element.getBoundingClientRect(); } if (itemToPopout.group) { return itemToPopout.group.element.getBoundingClientRect(); } return element.getBoundingClientRect(); } var box = getBox(); var groupId = (_b = (_a = options === null || options === void 0 ? void 0 : options.overridePopoutGroup) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : this.getNextGroupId(); var _window = new popoutWindow_1.PopoutWindow("".concat(this.id, "-").concat(groupId), // unique id theme !== null && theme !== void 0 ? theme : '', { url: (_e = (_c = options === null || options === void 0 ? void 0 : options.popoutUrl) !== null && _c !== void 0 ? _c : (_d = this.options) === null || _d === void 0 ? void 0 : _d.popoutUrl) !== null && _e !== void 0 ? _e : '/popout.html', left: window.screenX + box.left, top: window.screenY + box.top, width: box.width, height: box.height, onDidOpen: options === null || options === void 0 ? void 0 : options.onDidOpen, onWillClose: options === null || options === void 0 ? void 0 : options.onWillClose, }); var popoutWindowDisposable = new lifecycle_1.CompositeDisposable(_window, _window.onDidClose(function () { popoutWindowDisposable.dispose(); })); return _window .open() .then(function (popoutContainer) { var _a; if (_window.isDisposed) { return false; } if (popoutContainer === null) { popoutWindowDisposable.dispose(); return false; } var gready = document.createElement('div'); gready.className = 'dv-overlay-render-container'; var overlayRenderContainer = new overlayRenderContainer_1.OverlayRenderContainer(gready, _this); var referenceGroup = itemToPopout instanceof dockviewPanel_1.DockviewPanel ? itemToPopout.group : itemToPopout; var referenceLocation = itemToPopout.api.location.type; /** * The group that is being added doesn't already exist within the DOM, the most likely occurance * of this case is when being called from the `fromJSON(...)` method */ var isGroupAddedToDom = referenceGroup.element.parentElement !== null; var group; if (!isGroupAddedToDom) { group = referenceGroup; } else if (options === null || options === void 0 ? void 0 : options.overridePopoutGroup) { group = options.overridePopoutGroup; } else { group = _this.createGroup({ id: groupId }); _this._onDidAddGroup.fire(group); } group.model.renderContainer = overlayRenderContainer; group.layout(_window.window.innerWidth, _window.window.innerHeight); var floatingBox; if (!(options === null || options === void 0 ? void 0 : options.overridePopoutGroup) && isGroupAddedToDom) { if (itemToPopout instanceof dockviewPanel_1.DockviewPanel) { _this.movingLock(function () { var panel = referenceGroup.model.removePanel(itemToPopout); group.model.openPanel(panel); }); } else { _this.movingLock(function () { return moveGroupWithoutDestroying({ from: referenceGroup, to: group, }); }); switch (referenceLocation) { case 'grid': referenceGroup.api.setVisible(false); break; case 'floating': case 'popout': floatingBox = (_a = _this._floatingGroups .find(function (value) { return value.group.api.id === itemToPopout.api.id; })) === null || _a === void 0 ? void 0 : _a.overlay.toJSON(); _this.removeGroup(referenceGroup); break; } } } popoutContainer.classList.add('dv-dockview'); popoutContainer.style.overflow = 'hidden'; popoutContainer.appendChild(gready); popoutContainer.appendChild(group.element); var anchor = document.createElement('div'); var dropTargetContainer = new dropTargetAnchorContainer_1.DropTargetAnchorContainer(anchor, { disabled: _this.rootDropTargetContainer.disabled }); popoutContainer.appendChild(anchor); group.model.dropTargetContainer = dropTargetContainer; group.model.location = { type: 'popout', getWindow: function () { return _window.window; }, popoutUrl: options === null || options === void 0 ? void 0 : options.popoutUrl, }; if (isGroupAddedToDom && itemToPopout.api.location.type === 'grid') { itemToPopout.api.setVisible(false); } _this.doSetGroupAndPanelActive(group); popoutWindowDisposable.addDisposables(group.api.onDidActiveChange(function (event) { var _a; if (event.isActive) { (_a = _window.window) === null || _a === void 0 ? void 0 : _a.focus(); } }), group.api.onWillFocus(function () { var _a; (_a = _window.window) === null || _a === void 0 ? void 0 : _a.focus(); })); var returnedGroup; var isValidReferenceGroup = isGroupAddedToDom && referenceGroup && _this.getPanel(referenceGroup.id); var value = { window: _window, popoutGroup: group, referenceGroup: isValidReferenceGroup ? referenceGroup.id : undefined, disposable: { dispose: function () { popoutWindowDisposable.dispose(); return returnedGroup; }, }, }; var _onDidWindowPositionChange = (0, dom_1.onDidWindowMoveEnd)(_window.window); popoutWindowDisposable.addDisposables(_onDidWindowPositionChange, (0, dom_1.onDidWindowResizeEnd)(_window.window, function () { _this._onDidPopoutGroupSizeChange.fire({ width: _window.window.innerWidth, height: _window.window.innerHeight, group: group, }); }), _onDidWindowPositionChange.event(function () { _this._onDidPopoutGroupPositionChange.fire({ screenX: _window.window.screenX, screenY: _window.window.screenX, group: group, }); }), /** * ResizeObserver seems slow here, I do not know why but we don't need it * since we can reply on the window resize event as we will occupy the full * window dimensions */ (0, events_1.addDisposableListener)(_window.window, 'resize', function () { group.layout(_window.window.innerWidth, _window.window.innerHeight); }), overlayRenderContainer, lifecycle_1.Disposable.from(function () { if (_this.isDisposed) { return; // cleanup may run after instance is disposed } if (isGroupAddedToDom && _this.getPanel(referenceGroup.id)) { _this.movingLock(function () { return moveGroupWithoutDestroying({ from: group, to: referenceGroup, }); }); if (!referenceGroup.api.isVisible) { referenceGroup.api.setVisible(true); } if (_this.getPanel(group.id)) { _this.doRemoveGroup(group, { skipPopoutAssociated: true, }); } } else if (_this.getPanel(group.id)) { group.model.renderContainer = _this.overlayRenderContainer; group.model.dropTargetContainer = _this.rootDropTargetContainer; returnedGroup = group; var alreadyRemoved = !_this._popoutGroups.find(function (p) { return p.popoutGroup === group; }); if (alreadyRemoved) { /** * If this popout group was explicitly removed then we shouldn't run the additional * steps. To tell if the running of this disposable is the result of this popout group * being explicitly removed we can check if this popout group is still referenced in * the `this._popoutGroups` list. */ return; } if (floatingBox) { _this.addFloatingGroup(group, { height: floatingBox.height, width: floatingBox.width, position: floatingBox, }); } else { _this.doRemoveGroup(group, { skipDispose: true, skipActive: true, skipPopoutReturn: true, }); group.model.location = { type: 'grid' }; _this.movingLock(function () { // suppress group add events since the group already exists _this.doAddGroup(group, [0]); }); } _this.doSetGroupAndPanelActive(group); } })); _this._popoutGroups.push(value); _this.updateWatermark(); return true; }) .catch(function (err) { console.error('dockview: failed to create popout window', err); return false; }); }; DockviewComponent.prototype.addFloatingGroup = function (item, options) { var _this = this; var _a, _b, _c, _d, _e; var group; if (item instanceof dockviewPanel_1.DockviewPanel) { group = this.createGroup(); this._onDidAddGroup.fire(group); this.movingLock(function () { return _this.removePanel(item, { removeEmptyGroup: true, skipDispose: true, skipSetActiveGroup: true, }); }); this.movingLock(function () { return group.model.openPanel(item, { skipSetGroupActive: true }); }); } else { group = item; var popoutReferenceGroupId = (_a = this._popoutGroups.find(function (_) { return _.popoutGroup === group; })) === null || _a === void 0 ? void 0 : _a.referenceGroup; var popoutReferenceGroup_1 = popoutReferenceGroupId ? this.getPanel(popoutReferenceGroupId) : undefined; var skip = typeof (options === null || options === void 0 ? void 0 : options.skipRemoveGroup) === 'boolean' && options.skipRemoveGroup; if (!skip) { if (popoutReferenceGroup_1) { this.movingLock(function () { return moveGroupWithoutDestroying({ from: item, to: popoutReferenceGroup_1, }); }); this.doRemoveGroup(item, { skipPopoutReturn: true, skipPopoutAssociated: true, }); this.doRemoveGroup(popoutReferenceGroup_1, { skipDispose: true, }); group = popoutReferenceGroup_1; } else { this.doRemoveGroup(item, { skipDispose: true, skipPopoutReturn: true, skipPopoutAssociated: false, }); } } } function getAnchoredBox() { if (options === null || options === void 0 ? void 0 : options.position) { var result = {}; if ('left' in options.position) { result.left = Math.max(options.position.left, 0); } else if ('right' in options.position) { result.right = Math.max(options.position.right, 0); } else { result.left = constants_1.DEFAULT_FLOATING_GROUP_POSITION.left; } if ('top' in options.position) { result.top = Math.max(options.position.top, 0); } else if ('bottom' in options.position) { result.bottom = Math.max(options.position.bottom, 0); } else { result.top = constants_1.DEFAULT_FLOATING_GROUP_POSITION.top; } if (typeof options.width === 'number') { result.width = Math.max(options.width, 0); } else { result.width = constants_1.DEFAULT_FLOATING_GROUP_POSITION.width; } if (typeof options.height === 'number') { result.height = Math.max(options.height, 0); } else { result.height = constants_1.DEFAULT_FLOATING_GROUP_POSITION.height; } return result; } return { left: typeof (options === null || options === void 0 ? void 0 : options.x) === 'number' ? Math.max(options.x, 0) : constants_1.DEFAULT_FLOATING_GROUP_POSITION.left, top: typeof (options === null || options === void 0 ? void 0 : options.y) === 'number' ? Math.max(options.y, 0) : constants_1.DEFAULT_FLOATING_GROUP_POSITION.top, width: typeof (options === null || options === void 0 ? void 0 : options.width) === 'number' ? Math.max(options.width, 0) : constants_1.DEFAULT_FLOATING_GROUP_POSITION.width, height: typeof (options === null || options === void 0 ? void 0 : options.height) === 'number' ? Math.max(options.height, 0) : constants_1.DEFAULT_FLOATING_GROUP_POSITION.height, }; } var anchoredBox = getAnchoredBox(); var overlay = new overlay_1.Overlay(__assign(__assign({ container: this.gridview.element, content: group.element }, anchoredBox), { minimumInViewportWidth: this.options.floatingGroupBounds === 'boundedWithinViewport' ? undefined : (_c = (_b = this.options.floatingGroupBounds) === null || _b === void 0 ? void 0 : _b.minimumWidthWithinViewport) !== null && _c !== void 0 ? _c : constants_1.DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE, minimumInViewportHeight: this.options.floatingGroupBounds === 'boundedWithinViewport' ? undefined : (_e = (_d = this.options.floatingGroupBounds) === null || _d === void 0 ? void 0 : _d.minimumHeightWithinViewport) !== null && _e !== void 0 ? _e : constants_1.DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE })); var el = group.element.querySelector('.dv-void-container'); if (!el) { throw new Error('failed to find drag handle'); } overlay.setupDrag(el, { inDragMode: typeof (options === null || options === void 0 ? void 0 : options.inDragMode) === 'boolean' ? options.inDragMode : false, }); var floatingGroupPanel = new dockviewFloatingGroupPanel_1.DockviewFloatingGroupPanel(group, overlay); var disposable = new lifecycle_1.CompositeDisposable(group.api.onDidActiveChange(function (event) { if (event.isActive) { overlay.bringToFront(); } }), (0, dom_1.watchElementResize)(group.element, function (entry) { var _a = entry.contentRect, width = _a.width, height = _a.height; group.layout(width, height); // let the group know it's size is changing so it can fire events to the panel })); floatingGroupPanel.addDisposables(overlay.onDidChange(function () { // this is either a resize or a move // to inform the panels .layout(...) the group with it's current size // don't care about resize since the above watcher handles that group.layout(group.width, group.height); }), overlay.onDidChangeEnd(function () { _this._bufferOnDidLayoutChange.fire(); }), group.onDidChange(function (event) { overlay.setBounds({ height: event === null || event === void 0 ? void 0 : event.height, width: event === null || event === void 0 ? void 0 : event.width, }); }), { dispose: function () { disposable.dispose(); (0, array_1.remove)(_this._floatingGroups, floatingGroupPanel); group.model.location = { type: 'grid' }; _this.updateWatermark(); }, }); this._floatingGroups.push(floatingGroupPanel); group.model.location = { type: 'floating' }; if (!(options === null || options === void 0 ? void 0 : options.skipActiveGroup)) { this.doSetGroupAndPanelActive(group); } this.updateWatermark(); }; DockviewComponent.prototype.orthogonalize = function (position, options) { switch (position) { case 'top': case 'bottom': if (this.gridview.orientation === splitview_1.Orientation.HORIZONTAL) { // we need to add to a vertical splitview but the current root is a horizontal splitview. // insert a vertical splitview at the root level and add the existing view as a child this.gridview.insertOrthogonalSplitviewAtRoot(); } break; case 'left': case 'right': if (this.gridview.orientation === splitview_1.Orientation.VERTICAL) { // we need to add to a horizontal splitview but the current root is a vertical splitview. // insert a horiziontal splitview at the root level and add the existing view as a child this.gridview.insertOrthogonalSplitviewAtRoot(); } break; default: break; } switch (position) { case 'top': case 'left': case 'center': return this.createGroupAtLocation([0], undefined, options); // insert into first position case 'bottom': case 'right': return this.createGroupAtLocation([this.gridview.length], undefined, options); // insert into last position default: throw new Error("unsupported position ".concat(position)); } }; DockviewComponent.prototype.updateOptions = function (options) { var e_3, _a; var _b, _c; _super.prototype.updateOptions.call(this, options); if ('floatingGroupBounds' in options) { try { for (var _d = __values(this._floatingGroups), _e = _d.next(); !_e.done; _e = _d.next()) { var group = _e.value; switch (options.floatingGroupBounds) { case 'boundedWithinViewport': group.overlay.minimumInViewportHeight = undefined; group.overlay.minimumInViewportWidth = undefined; break; case undefined: group.overlay.minimumInViewportHeight = constants_1.DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE; group.overlay.minimumInViewportWidth = constants_1.DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE; break; default: group.overlay.minimumInViewportHeight = (_b = options.floatingGroupBounds) === null || _b === void 0 ? void 0 : _b.minimumHeightWithinViewport; group.overlay.minimumInViewportWidth = (_c = options.floatingGroupBounds) === null || _c === void 0 ? void 0 : _c.minimumWidthWithinViewport; } group.overlay.setBounds(); } } catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (_e && !_e.done && (_a = _d.return)) _a.call(_d); } finally { if (e_3) throw e_3.error; } } } this.updateDropTargetModel(options); this._options = __assign(__assign({}, this.options), options); if ('theme' in options) { this.updateTheme(); } this.layout(this.gridview.width, this.gridview.height, true); }; DockviewComponent.prototype.layout = function (width, height, forceResize) { var e_4, _a; _super.prototype.layout.call(this, width, height, forceResize); if (this._floatingGroups) { try { for (var _b = __values(this._floatingGroups), _c = _b.next(); !_c.done; _c = _b.next()) { var floating = _c.value; // ensure floting groups stay within visible boundaries floating.overlay.setBounds(); } } catch (e_4_1) { e_4 = { error: e_4_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_4) throw e_4.error; } } } }; DockviewComponent.prototype.focus = function () { var _a; (_a = this.activeGroup) === null || _a === void 0 ? void 0 : _a.focus(); }; DockviewComponent.prototype.getGroupPanel = function (id) { return this.panels.find(function (panel) { return panel.id === id; }); }; DockviewComponent.prototype.setActivePanel = function (panel) { panel.group.model.openPanel(panel); this.doSetGroupAndPanelActive(panel.group); }; DockviewComponent.prototype.moveToNext = function (options) { var _a; if (options === void 0) { options = {}; } if (!options.group) { if (!this.activeGroup) { return; } options.group = this.activeGroup; } if (options.includePanel && options.group) { if (options.group.activePanel !== options.group.panels[options.group.panels.length - 1]) { options.group.model.moveToNext({ suppressRoll: true }); return; } } var location = (0, gridview_1.getGridLocation)(options.group.element); var next = (_a = this.gridview.next(location)) === null || _a === void 0 ? void 0 : _a.view; this.doSetGroupAndPanelActive(next); }; DockviewComponent.prototype.moveToPrevious = function (options) { var _a; if (options === void 0) { options = {}; } if (!options.group) { if (!this.activeGroup) { return; } options.group = this.activeGroup; } if (options.includePanel && options.group) { if (options.group.activePanel !== options.group.panels[0]) { options.group.model.moveToPrevious({ suppressRoll: true }); return; } } var location = (0, gridview_1.getGridLocation)(options.group.element); var next = (_a = this.gridview.previous(location)) === null || _a === void 0 ? void 0 : _a.view; if (next) { this.doSetGroupAndPanelActive(next); } }; /** * Serialize the current state of the layout * * @returns A JSON respresentation of the layout */ DockviewComponent.prototype.toJSON = function () { var _a; var data = this.gridview.serialize(); var panels = this.panels.reduce(function (collection, panel) { collection[panel.id] = panel.toJSON(); return collection; }, {}); var floats = this._floatingGroups.map(function (group) { return { data: group.group.toJSON(), position: group.overlay.toJSON(), }; }); var popoutGroups = this._popoutGroups.map(function (group) { return { data: group.popoutGroup.toJSON(), gridReferenceGroup: group.referenceGroup, position: group.window.dimensions(), url: group.popoutGroup.api.location.type === 'popout' ? group.popoutGroup.api.location.popoutUrl : undefined, }; }); var result = { grid: data, panels: panels, activeGroup: (_a = this.activeGroup) === null || _a === void 0 ? void 0 : _a.id, }; if (floats.length > 0) { result.floatingGroups = floats; } if (popoutGroups.length > 0) { result.popoutGroups = popoutGroups; } return result; }; DockviewComponent.prototype.fromJSON = function (data) { var e_5, _a, e_6, _b, e_7, _c, e_8, _d, e_9, _e, e_10, _f, e_11, _g; var _this = this; var _h, _j, _k; this.clear(); if (typeof data !== 'object' || data === null) { throw new Error('serialized layout must be a non-null object'); } var grid = data.grid, panels = data.panels, activeGroup = data.activeGroup; if (grid.root.type !== 'branch' || !Array.isArray(grid.root.data)) { throw new Error('root must be of type branch'); } try { // take note of the existing dimensions var width = this.width; var height = this.height; var createGroupFromSerializedState_1 = function (data) { var e_12, _a; var id = data.id, locked = data.locked, hideHeader = data.hideHeader, views = data.views, activeView = data.activeView; if (typeof id !== 'string') { throw new Error('group id must be of type string'); } var group = _this.createGroup({ id: id, locked: !!locked, hideHeader: !!hideHeader, }); _this._onDidAddGroup.fire(group); var createdPanels = []; try { for (var views_1 = __values(views), views_1_1 = views_1.next(); !views_1_1.done; views_1_1 = views_1.next()) { var child = views_1_1.value; /** * Run the deserializer step seperately since this may fail to due corrupted external state. * In running this section first we avoid firing lots of 'add' events in the event of a failure * due to a corruption of input data. */ var panel = _this._deserializer.fromJSON(panels[child], group); createdPanels.push(panel); } } catch (e_12_1) { e_12 = { error: e_12_1 }; } finally { try { if (views_1_1 && !views_1_1.done && (_a = views_1.return)) _a.call(views_1); } finally { if (e_12) throw e_12.error; } } for (var i = 0; i < views.length; i++) { var panel = createdPanels[i]; var isActive = typeof activeView === 'string' && activeView === panel.id; group.model.openPanel(panel, { skipSetActive: !isActive, skipSetGroupActive: true, }); } if (!group.activePanel && group.panels.length > 0) { group.model.openPanel(group.panels[group.panels.length - 1], { skipSetGroupActive: true, }); } return group; }; this.gridview.deserialize(grid, { fromJSON: function (node) { return createGroupFromSerializedState_1(node.data); }, }); this.layout(width, height, true); var serializedFloatingGroups = (_h = data.floatingGroups) !== null && _h !== void 0 ? _h : []; try { for (var serializedFloatingGroups_1 = __values(serializedFloatingGroups), serializedFloatingGroups_1_1 = serializedFloatingGroups_1.next()