UNPKG

golden-layout

Version:

A multi-screen javascript Layout manager

874 lines 38.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Stack = void 0; const config_1 = require("../config/config"); const resolved_config_1 = require("../config/resolved-config"); const header_1 = require("../controls/header"); const internal_error_1 = require("../errors/internal-error"); const event_emitter_1 = require("../utils/event-emitter"); const jquery_legacy_1 = require("../utils/jquery-legacy"); const types_1 = require("../utils/types"); const utils_1 = require("../utils/utils"); const component_item_1 = require("./component-item"); const component_parentable_item_1 = require("./component-parentable-item"); const content_item_1 = require("./content-item"); /** @public */ class Stack extends component_parentable_item_1.ComponentParentableItem { /** @internal */ constructor(layoutManager, config, /** @internal */ _stackParent) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x; super(layoutManager, config, _stackParent, Stack.createElement(document)); this._stackParent = _stackParent; /** @internal */ this._headerSideChanged = false; /** @internal */ this._elementMouseEnterEventListener = () => this.onElementMouseEnter(); /** @internal */ this._elementMouseLeaveEventListener = () => this.onElementMouseLeave(); /** @internal */ this._resizeListener = () => this.handleResize(); /** @internal */ this._maximisedListener = () => this.handleMaximised(); /** @internal */ this._minimisedListener = () => this.handleMinimised(); this._headerConfig = config.header; const layoutHeaderConfig = layoutManager.layoutConfig.header; const configContent = config.content; // If stack has only one component, then we can also check this for header settings let componentHeaderConfig; if (configContent.length !== 1) { componentHeaderConfig = undefined; } else { const firstChildItemConfig = configContent[0]; componentHeaderConfig = firstChildItemConfig.header; // will be undefined if not component (and wont be stack) } this._initialWantMaximise = config.maximised; this._initialActiveItemIndex = (_a = config.activeItemIndex) !== null && _a !== void 0 ? _a : 0; // make sure defined // check for defined value for each item in order of Stack (this Item), Component (first child), Manager. const show = (_d = (_c = (_b = this._headerConfig) === null || _b === void 0 ? void 0 : _b.show) !== null && _c !== void 0 ? _c : componentHeaderConfig === null || componentHeaderConfig === void 0 ? void 0 : componentHeaderConfig.show) !== null && _d !== void 0 ? _d : layoutHeaderConfig.show; const popout = (_g = (_f = (_e = this._headerConfig) === null || _e === void 0 ? void 0 : _e.popout) !== null && _f !== void 0 ? _f : componentHeaderConfig === null || componentHeaderConfig === void 0 ? void 0 : componentHeaderConfig.popout) !== null && _g !== void 0 ? _g : layoutHeaderConfig.popout; const dock = (_k = (_j = (_h = this._headerConfig) === null || _h === void 0 ? void 0 : _h.dock) !== null && _j !== void 0 ? _j : componentHeaderConfig === null || componentHeaderConfig === void 0 ? void 0 : componentHeaderConfig.dock) !== null && _k !== void 0 ? _k : layoutHeaderConfig.dock; const maximise = (_o = (_m = (_l = this._headerConfig) === null || _l === void 0 ? void 0 : _l.maximise) !== null && _m !== void 0 ? _m : componentHeaderConfig === null || componentHeaderConfig === void 0 ? void 0 : componentHeaderConfig.maximise) !== null && _o !== void 0 ? _o : layoutHeaderConfig.maximise; const close = (_r = (_q = (_p = this._headerConfig) === null || _p === void 0 ? void 0 : _p.close) !== null && _q !== void 0 ? _q : componentHeaderConfig === null || componentHeaderConfig === void 0 ? void 0 : componentHeaderConfig.close) !== null && _r !== void 0 ? _r : layoutHeaderConfig.close; const minimise = (_u = (_t = (_s = this._headerConfig) === null || _s === void 0 ? void 0 : _s.minimise) !== null && _t !== void 0 ? _t : componentHeaderConfig === null || componentHeaderConfig === void 0 ? void 0 : componentHeaderConfig.minimise) !== null && _u !== void 0 ? _u : layoutHeaderConfig.minimise; const tabDropdown = (_x = (_w = (_v = this._headerConfig) === null || _v === void 0 ? void 0 : _v.tabDropdown) !== null && _w !== void 0 ? _w : componentHeaderConfig === null || componentHeaderConfig === void 0 ? void 0 : componentHeaderConfig.tabDropdown) !== null && _x !== void 0 ? _x : layoutHeaderConfig.tabDropdown; this._maximisedEnabled = maximise !== false; const headerSettings = { show: show !== false, side: show === false ? types_1.Side.top : show, popoutEnabled: popout !== false, popoutLabel: popout === false ? '' : popout, dockEnabled: dock !== false, dockLabel: dock === false ? '' : dock, maximiseEnabled: this._maximisedEnabled, maximiseLabel: maximise === false ? '' : maximise, closeEnabled: close !== false, closeLabel: close === false ? '' : close, minimiseEnabled: true, minimiseLabel: minimise, tabDropdownEnabled: tabDropdown !== false, tabDropdownLabel: tabDropdown === false ? '' : tabDropdown, }; this._header = new header_1.Header(layoutManager, this, headerSettings, config.isClosable && close !== false, () => this.getActiveComponentItem(), () => this.remove(), () => this.handleDockEvent(), () => this.handlePopoutEvent(), () => this.toggleMaximise(), (ev) => this.handleHeaderClickEvent(ev), (ev) => this.handleHeaderTouchStartEvent(ev), (item) => this.handleHeaderComponentRemoveEvent(item), (item) => this.handleHeaderComponentFocusEvent(item), (x, y, dragListener, item) => this.handleHeaderComponentStartDragEvent(x, y, dragListener, item)); // this._dropZones = {}; this.isStack = true; this._childElementContainer = document.createElement('section'); this._childElementContainer.classList.add("lm_items" /* Items */); this.on('resize', this._resizeListener); if (this._maximisedEnabled) { this.on('maximised', this._maximisedListener); this.on('minimised', this._minimisedListener); } this.element.addEventListener('mouseenter', this._elementMouseEnterEventListener, { passive: true }); this.element.addEventListener('mouseleave', this._elementMouseLeaveEventListener, { passive: true }); this.element.appendChild(this._header.element); this.element.appendChild(this._childElementContainer); this.setUndocked(); this.setupHeaderPosition(); this._header.updateClosability(); } get childElementContainer() { return this._childElementContainer; } get headerShow() { return this._header.show; } get headerSide() { return this._header.side; } get headerLeftRightSided() { return this._header.leftRightSided; } get dockEnabled() { return this._header.dockEnabled; } /** @internal */ get docker() { return this._docker; } /** @internal */ get contentAreaDimensions() { return this._contentAreaDimensions; } /** @internal */ get initialWantMaximise() { return this._initialWantMaximise; } get isMaximised() { return this === this.layoutManager.maximisedStack; } /** @internal */ dock(mode) { if (this._header.dockEnabled) if (this._stackParent.isColumn || this._stackParent.isColumn) { this._stackParent.dock(this, mode); } } updateSize() { this.updateNodeSize(); this.updateContentItemsSize(); } /** @internal */ init() { if (this.isInitialised === true) return; this.updateNodeSize(); for (let i = 0; i < this.contentItems.length; i++) { this._childElementContainer.appendChild(this.contentItems[i].element); } super.init(); const contentItems = this.contentItems; const contentItemCount = contentItems.length; if (contentItemCount > 0) { // contentItemCount will be 0 on drag drop if (this._initialActiveItemIndex < 0 || this._initialActiveItemIndex >= contentItemCount) { throw new Error(`ActiveItemIndex out of range: ${this._initialActiveItemIndex} id: ${this.id}`); } else { for (let i = 0; i < contentItemCount; i++) { const contentItem = contentItems[i]; if (!(contentItem instanceof component_item_1.ComponentItem)) { throw new Error(`Stack Content Item is not of type ComponentItem: ${i} id: ${this.id}`); } else { this._header.createTab(contentItem, i); contentItem.hide(); } } this.setActiveComponentItem(contentItems[this._initialActiveItemIndex], false); this._header.updateTabSizes(); } } this._header.updateClosability(); if (this._stackParent.isRow || this._stackParent.isColumn) { this._stackParent.validateDocking(); } this.initContentItems(); } /** @deprecated Use {@link (Stack:class).setActiveComponentItem} */ setActiveContentItem(item) { if (!content_item_1.ContentItem.isComponentItem(item)) { throw new Error('Stack.setActiveContentItem: item is not a ComponentItem'); } else { this.setActiveComponentItem(item, false); } } setActiveComponentItem(componentItem, focus, suppressFocusEvent = false) { if (this._activeComponentItem !== componentItem) { if (this.contentItems.indexOf(componentItem) === -1) { throw new Error('componentItem is not a child of this stack'); } else { if (this._activeComponentItem !== undefined) { this._activeComponentItem.hide(); } this._activeComponentItem = componentItem; this._header.processActiveComponentChanged(componentItem); componentItem.show(); this.emit('activeContentItemChanged', componentItem); this.layoutManager.emit('activeContentItemChanged', componentItem); this.emitStateChangedEvent(); } } if (this.focused || focus) { this.layoutManager.setFocusedComponentItem(componentItem, suppressFocusEvent); } } /** @deprecated Use {@link (Stack:class).getActiveComponentItem} */ getActiveContentItem() { let result; result = this.getActiveComponentItem(); if (result === undefined) { result = null; } return result; } getActiveComponentItem() { return this._activeComponentItem; } /** @internal */ focusActiveContentItem() { this._activeComponentItem.focus(); } /** @internal */ setFocusedValue(value) { this._header.applyFocusedValue(value); super.setFocusedValue(value); } /** @internal */ setDocked(value) { if (!value.docked) { throw new internal_error_1.AssertError('SSD3396'); } else { this._docker = value; } } /** @internal */ setUndocked() { this._docker = { docked: false, dimension: 'width', size: 0, realSize: 0, // value ignored }; } /** @internal */ setDockable(value) { this._header.setDockable(value); } /** @internal */ setRowColumnClosable(value) { this._header.setRowColumnClosable(value); } newComponent(componentType, componentState, title, index) { const itemConfig = { type: 'component', componentType, componentState, title, }; return this.newItem(itemConfig, index); } addComponent(componentType, componentState, title, index) { const itemConfig = { type: 'component', componentType, componentState, title, }; return this.addItem(itemConfig, index); } newItem(itemConfig, index) { index = this.addItem(itemConfig, index); return this.contentItems[index]; } addItem(itemConfig, index) { this.layoutManager.checkMinimiseMaximisedStack(); const resolvedItemConfig = config_1.ItemConfig.resolve(itemConfig); const contentItem = this.layoutManager.createAndInitContentItem(resolvedItemConfig, this); return this.addChild(contentItem, index); } addChild(contentItem, index, focus = false) { if (index !== undefined && index > this.contentItems.length) { /* * UGLY PATCH: PR #428, commit a4e84ec5 fixed a bug appearing on touchscreens during the drag of a panel. * The bug was caused by the physical removal of the element on drag: partial documentation is at issue #425. * The fix introduced the function undisplayChild() (called 'undisplay' to differentiate it from jQuery.hide), * which doesn't remove the element but only hides it: that's why when a tab is dragged & dropped into its * original container (at the end), the index here could be off by one. */ /* Better workarounds now exists * https://stackoverflow.com/questions/33298828/touch-move-event-dont-fire-after-touch-start-target-is-removed */ index -= 1; throw new internal_error_1.AssertError('SAC99728'); // undisplayChild() removed so this condition should no longer occur } if (!(contentItem instanceof component_item_1.ComponentItem)) { throw new internal_error_1.AssertError('SACC88532'); // Stacks can only have Component children } else { index = super.addChild(contentItem, index); this._childElementContainer.appendChild(contentItem.element); this._header.createTab(contentItem, index); this.setActiveComponentItem(contentItem, focus); this._header.updateTabSizes(); this.updateSize(); this._header.updateClosability(); if (this._stackParent.isRow || this._stackParent.isColumn) { this._stackParent.validateDocking(); } this.emitStateChangedEvent(); return index; } } removeChild(contentItem, keepChild) { const componentItem = contentItem; const index = this.contentItems.indexOf(componentItem); const stackWillBeDeleted = this.contentItems.length === 1; if (this._activeComponentItem === componentItem) { if (componentItem.focused) { componentItem.blur(); } if (!stackWillBeDeleted) { // At this point we're already sure we have at least one content item left *after* // removing contentItem, so we can safely assume index 1 is a valid one if // the index of contentItem is 0, otherwise we just use the previous content item. const newActiveComponentIdx = index === 0 ? 1 : index - 1; this.setActiveComponentItem(this.contentItems[newActiveComponentIdx], false); } } this._header.removeTab(componentItem); super.removeChild(componentItem, keepChild); if (!stackWillBeDeleted) { this._header.updateClosability(); if (this._stackParent.isRow || this._stackParent.isColumn) { this._stackParent.validateDocking(); } } this.emitStateChangedEvent(); } /** * Maximises the Item or minimises it if it is already maximised */ toggleMaximise() { if (this.isMaximised) { this.minimise(); } else { this.maximise(); } } maximise() { if (!this.isMaximised) { this.dock(false); this.layoutManager.setMaximisedStack(this); this.emitStateChangedEvent(); } } minimise() { if (this.isMaximised) { this.layoutManager.setMaximisedStack(undefined); this.emitStateChangedEvent(); } } /** @internal */ destroy() { if (this._activeComponentItem.focused) { this._activeComponentItem.blur(); } super.destroy(); this.off('resize', this._resizeListener); if (this._maximisedEnabled) { this.off('maximised', this._maximisedListener); this.off('minimised', this._minimisedListener); } this.element.removeEventListener('mouseenter', this._elementMouseEnterEventListener); this.element.removeEventListener('mouseleave', this._elementMouseLeaveEventListener); this._header.destroy(); } toConfig() { const activeItemIndex = this.contentItems.indexOf(this._activeComponentItem); if (activeItemIndex < 0) { throw new internal_error_1.AssertError('STC69221'); } else { const result = { type: 'stack', content: this.calculateConfigContent(), width: this.width, minWidth: this.minWidth, height: this.height, minHeight: this.minHeight, id: this.id, isClosable: this.isClosable, maximised: this.isMaximised, header: this.createHeaderConfig(), activeItemIndex, }; return result; } } /** * Ok, this one is going to be the tricky one: The user has dropped a {@link (ContentItem:class)} onto this stack. * * It was dropped on either the stacks header or the top, right, bottom or left bit of the content area * (which one of those is stored in this._dropSegment). Now, if the user has dropped on the header the case * is relatively clear: We add the item to the existing stack... job done (might be good to have * tab reordering at some point, but lets not sweat it right now) * * If the item was dropped on the content part things are a bit more complicated. If it was dropped on either the * top or bottom region we need to create a new column and place the items accordingly. * Unless, of course if the stack is already within a column... in which case we want * to add the newly created item to the existing column... * either prepend or append it, depending on wether its top or bottom. * * Same thing for rows and left / right drop segments... so in total there are 9 things that can potentially happen * (left, top, right, bottom) * is child of the right parent (row, column) + header drop * * @internal */ // eslint-disable-next-line @typescript-eslint/no-unused-vars onDrop(contentItem, area) { /* * The item was dropped on the header area. Just add it as a child of this stack and * get the hell out of this logic */ if (this._dropSegment === "header" /* Header */) { this.resetHeaderDropZone(); if (this._dropIndex === undefined) { throw new internal_error_1.UnexpectedUndefinedError('SODDI68990'); } else { this.addChild(contentItem, this._dropIndex); return; } } /* * The stack is empty. Let's just add the element. */ if (this._dropSegment === "body" /* Body */) { this.addChild(contentItem, 0, true); return; } /* * The item was dropped on the top-, left-, bottom- or right- part of the content. Let's * aggregate some conditions to make the if statements later on more readable */ const isVertical = this._dropSegment === "top" /* Top */ || this._dropSegment === "bottom" /* Bottom */; const isHorizontal = this._dropSegment === "left" /* Left */ || this._dropSegment === "right" /* Right */; const insertBefore = this._dropSegment === "top" /* Top */ || this._dropSegment === "left" /* Left */; const hasCorrectParent = (isVertical && this._stackParent.isColumn) || (isHorizontal && this._stackParent.isRow); const dimension = isVertical ? 'height' : 'width'; /* * The content item can be either a component or a stack. If it is a component, wrap it into a stack */ if (contentItem.isComponent) { const itemConfig = resolved_config_1.ResolvedStackItemConfig.createDefault(); itemConfig.header = this.createHeaderConfig(); const stack = this.layoutManager.createAndInitContentItem(itemConfig, this); stack.addChild(contentItem); contentItem = stack; } /* * If the contentItem that's being dropped is not dropped on a Stack (cases which just passed above and * which would wrap the contentItem in a Stack) we need to check whether contentItem is a RowOrColumn. * If it is, we need to re-wrap it in a Stack like it was when it was dragged by its Tab (it was dragged!). */ if (contentItem.type === types_1.ItemType.row || contentItem.type === types_1.ItemType.column) { const itemConfig = resolved_config_1.ResolvedStackItemConfig.createDefault(); itemConfig.header = this.createHeaderConfig(); const stack = this.layoutManager.createContentItem(itemConfig, this); stack.addChild(contentItem); contentItem = stack; } /* * If the item is dropped on top or bottom of a column or left and right of a row, it's already * layd out in the correct way. Just add it as a child */ if (hasCorrectParent) { const index = this._stackParent.contentItems.indexOf(this); this._stackParent.addChild(contentItem, insertBefore ? index : index + 1, true); this[dimension] *= 0.5; contentItem[dimension] = this[dimension]; this._stackParent.updateSize(); /* * This handles items that are dropped on top or bottom of a row or left / right of a column. We need * to create the appropriate contentItem for them to live in */ } else { const type = isVertical ? types_1.ItemType.column : types_1.ItemType.row; const itemConfig = resolved_config_1.ResolvedItemConfig.createDefault(type); const rowOrColumn = this.layoutManager.createContentItem(itemConfig, this); this._stackParent.replaceChild(this, rowOrColumn); rowOrColumn.addChild(contentItem, insertBefore ? 0 : undefined, true); rowOrColumn.addChild(this, insertBefore ? undefined : 0, true); this[dimension] = 50; contentItem[dimension] = 50; rowOrColumn.updateSize(); } this._stackParent.validateDocking(); } /** * If the user hovers above the header part of the stack, indicate drop positions for tabs. * otherwise indicate which segment of the body the dragged item would be dropped on * * @param x - Absolute Screen X * @param y - Absolute Screen Y * @internal */ highlightDropZone(x, y) { for (const key in this._contentAreaDimensions) { const segment = key; const area = this._contentAreaDimensions[segment].hoverArea; if (area.x1 < x && area.x2 > x && area.y1 < y && area.y2 > y) { if (segment === "header" /* Header */) { this._dropSegment = "header" /* Header */; this.highlightHeaderDropZone(this._header.leftRightSided ? y : x); } else { this.resetHeaderDropZone(); this.highlightBodyDropZone(segment); } return; } } } /** @internal */ getArea() { if (this.element.style.display === 'none') { return null; } const headerArea = super.getElementArea(this._header.element); const contentArea = super.getElementArea(this._childElementContainer); if (headerArea === null || contentArea === null) { throw new internal_error_1.UnexpectedNullError('SGAHC13086'); } const contentWidth = contentArea.x2 - contentArea.x1; const contentHeight = contentArea.y2 - contentArea.y1; this._contentAreaDimensions = { header: { hoverArea: { x1: headerArea.x1, y1: headerArea.y1, x2: headerArea.x2, y2: headerArea.y2 }, highlightArea: { x1: headerArea.x1, y1: headerArea.y1, x2: headerArea.x2, y2: headerArea.y2 } } }; /** * Highlight the entire body if the stack is empty */ if (this.contentItems.length === 0) { this._contentAreaDimensions.body = { hoverArea: { x1: contentArea.x1, y1: contentArea.y1, x2: contentArea.x2, y2: contentArea.y2 }, highlightArea: { x1: contentArea.x1, y1: contentArea.y1, x2: contentArea.x2, y2: contentArea.y2 } }; return super.getElementArea(this.element); } else { this._contentAreaDimensions.left = { hoverArea: { x1: contentArea.x1, y1: contentArea.y1, x2: contentArea.x1 + contentWidth * 0.25, y2: contentArea.y2 }, highlightArea: { x1: contentArea.x1, y1: contentArea.y1, x2: contentArea.x1 + contentWidth * 0.5, y2: contentArea.y2 } }; this._contentAreaDimensions.top = { hoverArea: { x1: contentArea.x1 + contentWidth * 0.25, y1: contentArea.y1, x2: contentArea.x1 + contentWidth * 0.75, y2: contentArea.y1 + contentHeight * 0.5 }, highlightArea: { x1: contentArea.x1, y1: contentArea.y1, x2: contentArea.x2, y2: contentArea.y1 + contentHeight * 0.5 } }; this._contentAreaDimensions.right = { hoverArea: { x1: contentArea.x1 + contentWidth * 0.75, y1: contentArea.y1, x2: contentArea.x2, y2: contentArea.y2 }, highlightArea: { x1: contentArea.x1 + contentWidth * 0.5, y1: contentArea.y1, x2: contentArea.x2, y2: contentArea.y2 } }; this._contentAreaDimensions.bottom = { hoverArea: { x1: contentArea.x1 + contentWidth * 0.25, y1: contentArea.y1 + contentHeight * 0.5, x2: contentArea.x1 + contentWidth * 0.75, y2: contentArea.y2 }, highlightArea: { x1: contentArea.x1, y1: contentArea.y1 + contentHeight * 0.5, x2: contentArea.x2, y2: contentArea.y2 } }; return super.getElementArea(this.element); } } /** * Programmatically operate with header position. * * @param position - * * @returns previous header position * @internal */ positionHeader(position) { if (this._docker.docked) { throw new Error('Can\'t change header position in docked stack'); } if (this._header.side !== position) { this._header.setSide(position); this._headerSideChanged = true; this.setupHeaderPosition(); } } /** @internal */ setParent(parent) { this._stackParent = parent; super.setParent(parent); } /** @internal */ updateNodeSize() { if (this.element.style.display !== 'none') { const isDocked = this._docker.docked; const content = utils_1.getElementWidthAndHeight(this.element); if (this._header.show) { const dimension = this._header.leftRightSided ? types_1.WidthOrHeightPropertyName.width : types_1.WidthOrHeightPropertyName.height; content[dimension] -= this.layoutManager.layoutConfig.dimensions.headerHeight; } if (isDocked) { content[this._docker.dimension] = this._docker.realSize; } if (!isDocked || this._docker.dimension === types_1.WidthOrHeightPropertyName.height) { this._childElementContainer.style.width = utils_1.numberToPixels(content.width); } if (!isDocked || this._docker.dimension === types_1.WidthOrHeightPropertyName.width) { this._childElementContainer.style.height = utils_1.numberToPixels(content.height); } for (let i = 0; i < this.contentItems.length; i++) { this.contentItems[i].element.style.width = utils_1.numberToPixels(content.width); this.contentItems[i].element.style.height = utils_1.numberToPixels(content.height); } this.emit('resize'); this.emitStateChangedEvent(); } } /** @internal */ highlightHeaderDropZone(x) { const tabsLength = this._header.tabs.length; const dropTargetIndicator = this.layoutManager.dropTargetIndicator; if (dropTargetIndicator === null) { throw new internal_error_1.UnexpectedNullError('SHHDZDTI97110'); } let area; // Empty stack if (tabsLength === 0) { const headerOffset = jquery_legacy_1.getJQueryOffset(this._header.element); const elementHeight = utils_1.getElementHeight(this._header.element); area = { x1: headerOffset.left, x2: headerOffset.left + 100, y1: headerOffset.top + elementHeight - 20, y2: headerOffset.top + elementHeight, }; } else { let tabIndex = 0; let isAboveTab = false; let tabTop; let tabLeft; let tabWidth; let tabElement; do { tabElement = this._header.tabs[tabIndex].element; const offset = jquery_legacy_1.getJQueryOffset(tabElement); if (this._header.leftRightSided) { tabLeft = offset.top; tabTop = offset.left; tabWidth = utils_1.getElementHeight(tabElement); } else { tabLeft = offset.left; tabTop = offset.top; tabWidth = utils_1.getElementWidth(tabElement); } if (x > tabLeft && x < tabLeft + tabWidth) { isAboveTab = true; } else { tabIndex++; } } while (tabIndex < tabsLength && !isAboveTab); if (isAboveTab === false && x < tabLeft) { return; } const halfX = tabLeft + tabWidth / 2; if (x < halfX) { this._dropIndex = tabIndex; tabElement.insertAdjacentElement('beforebegin', this.layoutManager.tabDropPlaceholder); } else { this._dropIndex = Math.min(tabIndex + 1, tabsLength); tabElement.insertAdjacentElement('afterend', this.layoutManager.tabDropPlaceholder); } const tabDropPlaceholderOffset = jquery_legacy_1.getJQueryOffset(this.layoutManager.tabDropPlaceholder); const tabDropPlaceholderWidth = utils_1.getElementWidth(this.layoutManager.tabDropPlaceholder); if (this._header.leftRightSided) { const placeHolderTop = tabDropPlaceholderOffset.top; area = { x1: tabTop, x2: tabTop + tabElement.clientHeight, y1: placeHolderTop, y2: placeHolderTop + tabDropPlaceholderWidth, }; } else { const placeHolderLeft = tabDropPlaceholderOffset.left; area = { x1: placeHolderLeft, x2: placeHolderLeft + tabDropPlaceholderWidth, y1: tabTop, y2: tabTop + tabElement.clientHeight, }; } } dropTargetIndicator.highlightArea(area); return; } /** @internal */ resetHeaderDropZone() { this.layoutManager.tabDropPlaceholder.remove(); } /** @internal */ setupHeaderPosition() { utils_1.setElementDisplayVisibility(this._header.element, this._header.show); this.element.classList.remove("lm_left" /* Left */, "lm_right" /* Right */, "lm_bottom" /* Bottom */); if (this._header.leftRightSided) { this.element.classList.add('lm_' + this._header.side); } //if ([Side.right, Side.bottom].includes(this._header.side)) { // // move the header behind the content. // this.element.appendChild(this._header.element); //} this.updateSize(); } /** @internal */ highlightBodyDropZone(segment) { if (this._contentAreaDimensions === undefined) { throw new internal_error_1.UnexpectedUndefinedError('SHBDZC82265'); } else { const highlightArea = this._contentAreaDimensions[segment].highlightArea; const dropTargetIndicator = this.layoutManager.dropTargetIndicator; if (dropTargetIndicator === null) { throw new internal_error_1.UnexpectedNullError('SHBDZD96110'); } else { dropTargetIndicator.highlightArea(highlightArea); this._dropSegment = segment; } } } /** @internal */ handleResize() { this._header.updateTabSizes(); } /** @internal */ handleMaximised() { this._header.processMaximised(); } /** @internal */ handleMinimised() { this._header.processMinimised(); } /** @internal */ onElementMouseEnter() { if (this._docker.docked) { this._childElementContainer.style[this._docker.dimension] = utils_1.numberToPixels(this._docker.realSize); } } /** @internal */ onElementMouseLeave() { if (this._docker.docked) { this._childElementContainer.style[this._docker.dimension] = utils_1.numberToPixels(0); } } /** @internal */ handleDockEvent() { this.dock(); } /** @internal */ handlePopoutEvent() { this.popout(); } /** @internal */ handleHeaderClickEvent(ev) { const eventName = event_emitter_1.EventEmitter.headerClickEventName; const bubblingEvent = new event_emitter_1.EventEmitter.ClickBubblingEvent(eventName, this, ev); this.emit(eventName, bubblingEvent); } /** @internal */ handleHeaderTouchStartEvent(ev) { const eventName = event_emitter_1.EventEmitter.headerTouchStartEventName; const bubblingEvent = new event_emitter_1.EventEmitter.TouchStartBubblingEvent(eventName, this, ev); this.emit(eventName, bubblingEvent); } /** @internal */ handleHeaderComponentRemoveEvent(item) { this.removeChild(item, false); } /** @internal */ handleHeaderComponentFocusEvent(item) { this.setActiveComponentItem(item, true); } /** @internal */ handleHeaderComponentStartDragEvent(x, y, dragListener, componentItem) { if (this.isMaximised === true) { this.toggleMaximise(); } this.layoutManager.startComponentDrag(x, y, dragListener, componentItem, this); } /** @internal */ createHeaderConfig() { if (!this._headerSideChanged) { return resolved_config_1.ResolvedHeaderedItemConfig.Header.createCopy(this._headerConfig); } else { const show = this._header.show ? this._header.side : false; let result = resolved_config_1.ResolvedHeaderedItemConfig.Header.createCopy(this._headerConfig, show); if (result === undefined) { result = { show, popout: undefined, dock: undefined, maximise: undefined, close: undefined, minimise: undefined, tabDropdown: undefined, }; } return result; } } /** @internal */ emitStateChangedEvent() { this.emitBaseBubblingEvent('stateChanged'); } } exports.Stack = Stack; /** @public */ (function (Stack) { /** @internal */ function createElement(document) { const element = document.createElement('div'); element.classList.add("lm_item" /* Item */); element.classList.add("lm_stack" /* Stack */); return element; } Stack.createElement = createElement; })(Stack = exports.Stack || (exports.Stack = {})); //# sourceMappingURL=stack.js.map