mirror of
https://github.com/atom/atom.git
synced 2026-01-23 22:08:08 -05:00
219 lines
5.6 KiB
JavaScript
219 lines
5.6 KiB
JavaScript
const path = require('path')
|
|
const {CompositeDisposable} = require('event-kit')
|
|
|
|
class PaneElement extends HTMLElement {
|
|
createdCallback () {
|
|
this.attached = false
|
|
this.subscriptions = new CompositeDisposable()
|
|
this.inlineDisplayStyles = new WeakMap()
|
|
this.initializeContent()
|
|
this.subscribeToDOMEvents()
|
|
}
|
|
|
|
attachedCallback () {
|
|
this.attached = true
|
|
if (this.model.isFocused()) {
|
|
this.focus()
|
|
}
|
|
}
|
|
|
|
detachedCallback () {
|
|
this.attached = false
|
|
}
|
|
|
|
initializeContent () {
|
|
this.setAttribute('class', 'pane')
|
|
this.setAttribute('tabindex', -1)
|
|
this.itemViews = document.createElement('div')
|
|
this.appendChild(this.itemViews)
|
|
this.itemViews.setAttribute('class', 'item-views')
|
|
}
|
|
|
|
subscribeToDOMEvents () {
|
|
const handleFocus = event => {
|
|
if (
|
|
!(
|
|
this.isActivating ||
|
|
this.model.isDestroyed() ||
|
|
this.contains(event.relatedTarget)
|
|
)
|
|
) {
|
|
this.model.focus()
|
|
}
|
|
if (event.target !== this) return
|
|
const view = this.getActiveView()
|
|
if (view) {
|
|
view.focus()
|
|
event.stopPropagation()
|
|
}
|
|
}
|
|
const handleBlur = event => {
|
|
if (!this.contains(event.relatedTarget)) {
|
|
this.model.blur()
|
|
}
|
|
}
|
|
const handleDragOver = event => {
|
|
event.preventDefault()
|
|
event.stopPropagation()
|
|
}
|
|
const handleDrop = event => {
|
|
event.preventDefault()
|
|
event.stopPropagation()
|
|
this.getModel().activate()
|
|
const pathsToOpen = [...event.dataTransfer.files].map(file => file.path)
|
|
if (pathsToOpen.length > 0) {
|
|
this.applicationDelegate.open({pathsToOpen})
|
|
}
|
|
}
|
|
this.addEventListener('focus', handleFocus, true)
|
|
this.addEventListener('blur', handleBlur, true)
|
|
this.addEventListener('dragover', handleDragOver)
|
|
this.addEventListener('drop', handleDrop)
|
|
}
|
|
|
|
initialize (model, {views, applicationDelegate}) {
|
|
this.model = model
|
|
this.views = views
|
|
this.applicationDelegate = applicationDelegate
|
|
if (this.views == null) {
|
|
throw new Error(
|
|
'Must pass a views parameter when initializing PaneElements'
|
|
)
|
|
}
|
|
if (this.applicationDelegate == null) {
|
|
throw new Error(
|
|
'Must pass an applicationDelegate parameter when initializing PaneElements'
|
|
)
|
|
}
|
|
this.subscriptions.add(this.model.onDidActivate(this.activated.bind(this)))
|
|
this.subscriptions.add(
|
|
this.model.observeActive(this.activeStatusChanged.bind(this))
|
|
)
|
|
this.subscriptions.add(
|
|
this.model.observeActiveItem(this.activeItemChanged.bind(this))
|
|
)
|
|
this.subscriptions.add(
|
|
this.model.onDidRemoveItem(this.itemRemoved.bind(this))
|
|
)
|
|
this.subscriptions.add(
|
|
this.model.onDidDestroy(this.paneDestroyed.bind(this))
|
|
)
|
|
this.subscriptions.add(
|
|
this.model.observeFlexScale(this.flexScaleChanged.bind(this))
|
|
)
|
|
return this
|
|
}
|
|
|
|
getModel () {
|
|
return this.model
|
|
}
|
|
|
|
activated () {
|
|
this.isActivating = true
|
|
if (!this.hasFocus()) {
|
|
// Don't steal focus from children.
|
|
this.focus()
|
|
}
|
|
this.isActivating = false
|
|
}
|
|
|
|
activeStatusChanged (active) {
|
|
if (active) {
|
|
this.classList.add('active')
|
|
} else {
|
|
this.classList.remove('active')
|
|
}
|
|
}
|
|
|
|
activeItemChanged (item) {
|
|
delete this.dataset.activeItemName
|
|
delete this.dataset.activeItemPath
|
|
if (this.changePathDisposable != null) {
|
|
this.changePathDisposable.dispose()
|
|
}
|
|
if (item == null) {
|
|
return
|
|
}
|
|
const hasFocus = this.hasFocus()
|
|
const itemView = this.views.getView(item)
|
|
const itemPath = typeof item.getPath === 'function' ? item.getPath() : null
|
|
if (itemPath) {
|
|
this.dataset.activeItemName = path.basename(itemPath)
|
|
this.dataset.activeItemPath = itemPath
|
|
if (item.onDidChangePath != null) {
|
|
this.changePathDisposable = item.onDidChangePath(() => {
|
|
const itemPath = item.getPath()
|
|
this.dataset.activeItemName = path.basename(itemPath)
|
|
this.dataset.activeItemPath = itemPath
|
|
})
|
|
}
|
|
}
|
|
if (!this.itemViews.contains(itemView)) {
|
|
this.itemViews.appendChild(itemView)
|
|
}
|
|
for (const child of this.itemViews.children) {
|
|
if (child === itemView) {
|
|
if (this.attached) {
|
|
this.showItemView(child)
|
|
}
|
|
} else {
|
|
this.hideItemView(child)
|
|
}
|
|
}
|
|
if (hasFocus) {
|
|
itemView.focus()
|
|
}
|
|
}
|
|
|
|
showItemView (itemView) {
|
|
const inlineDisplayStyle = this.inlineDisplayStyles.get(itemView)
|
|
if (inlineDisplayStyle != null) {
|
|
itemView.style.display = inlineDisplayStyle
|
|
} else {
|
|
itemView.style.display = ''
|
|
}
|
|
}
|
|
|
|
hideItemView (itemView) {
|
|
const inlineDisplayStyle = itemView.style.display
|
|
if (inlineDisplayStyle !== 'none') {
|
|
if (inlineDisplayStyle != null) {
|
|
this.inlineDisplayStyles.set(itemView, inlineDisplayStyle)
|
|
}
|
|
itemView.style.display = 'none'
|
|
}
|
|
}
|
|
|
|
itemRemoved ({item, index, destroyed}) {
|
|
const viewToRemove = this.views.getView(item)
|
|
if (viewToRemove) {
|
|
viewToRemove.remove()
|
|
}
|
|
}
|
|
|
|
paneDestroyed () {
|
|
this.subscriptions.dispose()
|
|
if (this.changePathDisposable != null) {
|
|
this.changePathDisposable.dispose()
|
|
}
|
|
}
|
|
|
|
flexScaleChanged (flexScale) {
|
|
this.style.flexGrow = flexScale
|
|
}
|
|
|
|
getActiveView () {
|
|
return this.views.getView(this.model.getActiveItem())
|
|
}
|
|
|
|
hasFocus () {
|
|
return (
|
|
this === document.activeElement || this.contains(document.activeElement)
|
|
)
|
|
}
|
|
}
|
|
|
|
module.exports = document.registerElement('atom-pane', {
|
|
prototype: PaneElement.prototype
|
|
})
|