mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
219 lines
5.7 KiB
JavaScript
219 lines
5.7 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, here: true });
|
|
}
|
|
};
|
|
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
|
|
});
|