Current Path : /var/www/www-root/data/www/monolith-realty.ru/bitrix/js/ui/entity-selector/src/dialog/ |
Current File : /var/www/www-root/data/www/monolith-realty.ru/bitrix/js/ui/entity-selector/src/dialog/navigation.js |
import { Event } from 'main.core'; import type ItemNode from '../item/item-node'; import type Tab from './tabs/tab'; import type Dialog from './dialog'; export default class Navigation { dialog: Dialog = null; lockedTab: Tab = null; enabled: boolean = false; // IE/Edge compatible event names static keyMap: Object<string, string> = { 'Down': 'ArrowDown', 'Up': 'ArrowUp', 'Left': 'ArrowLeft', 'Right': 'ArrowRight', 'Spacebar': 'Space', ' ': 'Space' // For all browsers }; constructor(dialog: Dialog) { this.dialog = dialog; this.dialog.subscribe('onShow', this.handleDialogShow.bind(this)); this.dialog.subscribe('onHide', this.handleDialogHide.bind(this)); this.dialog.subscribe('onDestroy', this.handleDialogDestroy.bind(this)); this.handleDocumentKeyDown = this.handleDocumentKeyDown.bind(this); this.handleDocumentMouseMove = this.handleDocumentMouseMove.bind(this); } getDialog(): Dialog { return this.dialog; } enable(): void { if (!this.isEnabled()) { this.bindEvents(); } this.enabled = true; } disable(): void { if (this.isEnabled()) { this.unbindEvents(); this.unlockTab(); } this.enabled = false; } isEnabled(): boolean { return this.enabled; } bindEvents(): void { Event.bind(document, 'keydown', this.handleDocumentKeyDown); } unbindEvents(): void { Event.unbind(document, 'keydown', this.handleDocumentKeyDown); } getNextNode(): ?ItemNode { if (!this.getActiveNode()) { return null; } let nextNode = null; let currentNode = this.getActiveNode(); if (currentNode.hasChildren() && currentNode.isOpen()) { nextNode = currentNode.getFirstChild(); } while (nextNode === null && currentNode !== null) { nextNode = currentNode.getNextSibling(); if (nextNode) { break; } currentNode = currentNode.getParentNode(); } return nextNode; } getPreviousNode(): ?ItemNode { if (!this.getActiveNode()) { return null; } let previousNode = this.getActiveNode().getPreviousSibling(); if (previousNode) { while (previousNode.hasChildren() && previousNode.isOpen()) { const lastChild = previousNode.getLastChild(); if (lastChild === null) { break; } previousNode = lastChild; } } else { if (this.getActiveNode().getParentNode() && !this.getActiveNode().getParentNode().isRoot()) { previousNode = this.getActiveNode().getParentNode(); } } return previousNode; } getFirstNode(): ?ItemNode { const tab = this.getDialog().getActiveTab(); return tab && tab.getRootNode().getFirstChild(); } getLastNode(): ?ItemNode { const tab = this.getDialog().getActiveTab(); if (!tab) { return null; } let lastNode = tab.getRootNode().getLastChild(); if (lastNode !== null) { while (lastNode.hasChildren() && lastNode.isOpen()) { const lastChild = lastNode.getLastChild(); if (lastChild === null) { break; } lastNode = lastChild; } } return lastNode; } getActiveNode(): ?ItemNode { return this.getDialog().getFocusedNode(); } focusOnNode(node: ItemNode): void { if (node) { node.focus(); node.scrollIntoView(); } } lockTab(): void { const activeTab = this.getDialog().getActiveTab(); if (this.lockedTab === activeTab) { return; } else if (this.lockedTab !== null) { this.unlockTab(); } this.lockedTab = activeTab; this.lockedTab.lock(); Event.bind(document, 'mousemove', this.handleDocumentMouseMove); } unlockTab(): void { if (this.lockedTab === null) { return; } this.lockedTab.unlock(); this.lockedTab = null; Event.unbind(document, 'mousemove', this.handleDocumentMouseMove); } handleDialogShow(): void { this.enable(); } handleDialogHide(): void { this.disable(); } handleDialogDestroy(): void { this.disable(); } handleDocumentMouseMove(): void { this.unlockTab(); } handleDocumentKeyDown(event: KeyboardEvent): void { if (!this.getDialog().isOpen()) { this.unbindEvents(); return; } if (event.metaKey || event.ctrlKey || event.altKey) { return; } const activeTab = this.getDialog().getActiveTab(); if (!activeTab) { return; } const keyName = this.constructor.keyMap[event.key] || event.key; if (activeTab === this.getDialog().getSearchTab() && ['ArrowLeft', 'ArrowRight'].includes(keyName)) { return; } const handler: ?Function = this[`handle${keyName}Press`]; if (handler) { handler.call(this, event); this.lockTab(activeTab); event.preventDefault(); } } handleArrowDownPress(): void { if (!this.getActiveNode()) { const firstNode = this.getFirstNode(); this.focusOnNode(firstNode); } else { const nextNode = this.getNextNode(); if (nextNode) { this.focusOnNode(nextNode); } else { const firstNode = this.getFirstNode(); this.focusOnNode(firstNode); } } } handleArrowUpPress(): void { if (!this.getActiveNode()) { const lastNode = this.getLastNode(); this.focusOnNode(lastNode); } else { const previousNode = this.getPreviousNode(); if (previousNode) { this.focusOnNode(previousNode); } else { const lastNode = this.getLastNode(); this.focusOnNode(lastNode); } } } handleArrowRightPress(): void { if (this.getActiveNode()) { this.getActiveNode().expand(); } } handleArrowLeftPress(): void { if (!this.getActiveNode()) { return; } if (this.getActiveNode().isOpen()) { this.getActiveNode().collapse(); } else { const parentNode = this.getActiveNode().getParentNode(); if (parentNode && !parentNode.isRoot()) { this.focusOnNode(parentNode); } } } handleEnterPress(): void { if (this.getActiveNode()) { this.getActiveNode().click(); } } /*handleSpacePress(event: KeyboardEvent): void { const searchQuery = this.getDialog().getTagSelector() && this.getDialog().getTagSelector().getTextBoxValue(); if (this.getActiveNode() && !Type.isStringFilled(searchQuery)) { this.getActiveNode().click(); event.preventDefault(); } }*/ handleTabPress(event: KeyboardEvent): void { const activeTab = this.getDialog().getActiveTab(); if (!activeTab) { this.getDialog().selectFirstTab(); return; } if (event.shiftKey) { const previousTab = this.getDialog().getPreviousTab(); if (previousTab) { this.getDialog().selectTab(previousTab.getId()); } else { this.getDialog().selectLastTab(); } } else { const nextTab = this.getDialog().getNextTab(); if (nextTab) { this.getDialog().selectTab(nextTab.getId()); } else { this.getDialog().selectFirstTab(); } } } }