panel-container-element.js
1 'use strict'; 2 3 const focusTrap = require('focus-trap'); 4 const { CompositeDisposable } = require('event-kit'); 5 6 class PanelContainerElement extends HTMLElement { 7 createdCallback() { 8 this.subscriptions = new CompositeDisposable(); 9 } 10 11 attachedCallback() { 12 if (this.model.dock) { 13 this.model.dock.elementAttached(); 14 } 15 } 16 17 initialize(model, viewRegistry) { 18 this.model = model; 19 this.viewRegistry = viewRegistry; 20 21 this.subscriptions.add( 22 this.model.onDidAddPanel(this.panelAdded.bind(this)) 23 ); 24 this.subscriptions.add(this.model.onDidDestroy(this.destroyed.bind(this))); 25 this.classList.add(this.model.getLocation()); 26 27 // Add the dock. 28 if (this.model.dock != null) { 29 this.appendChild(this.model.dock.getElement()); 30 } 31 32 return this; 33 } 34 35 getModel() { 36 return this.model; 37 } 38 39 panelAdded({ panel, index }) { 40 const panelElement = panel.getElement(); 41 panelElement.classList.add(this.model.getLocation()); 42 if (this.model.isModal()) { 43 panelElement.classList.add('overlay', 'from-top'); 44 } else { 45 panelElement.classList.add( 46 'tool-panel', 47 `panel-${this.model.getLocation()}` 48 ); 49 } 50 51 if (index >= this.childNodes.length) { 52 this.appendChild(panelElement); 53 } else { 54 const referenceItem = this.childNodes[index]; 55 this.insertBefore(panelElement, referenceItem); 56 } 57 58 if (this.model.isModal()) { 59 this.hideAllPanelsExcept(panel); 60 this.subscriptions.add( 61 panel.onDidChangeVisible(visible => { 62 if (visible) { 63 this.hideAllPanelsExcept(panel); 64 } 65 }) 66 ); 67 68 if (panel.autoFocus) { 69 const focusOptions = { 70 // focus-trap will attempt to give focus to the first tabbable element 71 // on activation. If there aren't any tabbable elements, 72 // give focus to the panel element itself 73 fallbackFocus: panelElement, 74 // closing is handled by core Atom commands and this already deactivates 75 // on visibility changes 76 escapeDeactivates: false 77 }; 78 79 if (panel.autoFocus !== true) { 80 focusOptions.initialFocus = panel.autoFocus; 81 } 82 const modalFocusTrap = focusTrap(panelElement, focusOptions); 83 84 this.subscriptions.add( 85 panel.onDidChangeVisible(visible => { 86 if (visible) { 87 modalFocusTrap.activate(); 88 } else { 89 modalFocusTrap.deactivate(); 90 } 91 }) 92 ); 93 } 94 } 95 } 96 97 destroyed() { 98 this.subscriptions.dispose(); 99 if (this.parentNode != null) { 100 this.parentNode.removeChild(this); 101 } 102 } 103 104 hideAllPanelsExcept(excludedPanel) { 105 for (let panel of this.model.getPanels()) { 106 if (panel !== excludedPanel) { 107 panel.hide(); 108 } 109 } 110 } 111 } 112 113 module.exports = document.registerElement('atom-panel-container', { 114 prototype: PanelContainerElement.prototype 115 });