event listeners

This commit is contained in:
antelle 2019-09-16 21:49:21 +02:00
parent 1aa29237e2
commit 0dea89c0de
7 changed files with 58 additions and 36 deletions

View File

@ -4,6 +4,11 @@ import { Tip } from 'util/ui/tip';
import { KeyHandler } from 'comp/browser/key-handler';
import { Logger } from 'util/logger';
const OnlyDirectEvents = {
mouseenter: true,
mouseleave: true
};
class View extends EventEmitter {
parent = undefined;
template = undefined;
@ -13,7 +18,7 @@ class View extends EventEmitter {
views = {};
hidden = false;
removed = false;
boundEvents = [];
eventListeners = {};
debugLogger = localStorage.debugViews ? new Logger('view', this.constructor.name) : undefined;
constructor(model = undefined, options = {}) {
@ -40,9 +45,7 @@ class View extends EventEmitter {
Tip.destroyTips(this.el);
}
this.unbindEvents();
this.renderElement(templateData);
this.bindEvents();
Tip.createTips(this.el);
@ -81,6 +84,7 @@ class View extends EventEmitter {
this.el = root;
parent.appendChild(this.el);
}
this.bindEvents();
} else {
throw new Error(
`Error rendering ${this.constructor.name}: I don't know how to insert the view`
@ -91,32 +95,56 @@ class View extends EventEmitter {
}
bindEvents() {
const eventsMap = {};
for (const [eventDef, method] of Object.entries(this.events)) {
const spaceIx = eventDef.indexOf(' ');
let event, targets;
let event, selector;
if (spaceIx > 0) {
event = eventDef.substr(0, spaceIx);
const selector = eventDef.substr(spaceIx + 1);
targets = this.el.querySelectorAll(selector);
selector = eventDef.substr(spaceIx + 1);
if (OnlyDirectEvents[event]) {
throw new Error(
`Event listener ${eventDef} defined in ${this.constructor.name} ` +
`can be installed only on the view itself`
);
}
} else {
event = eventDef;
targets = [this.el];
}
for (const target of targets) {
const listener = e => {
this.debugLogger && this.debugLogger.debug('Listener', method);
this[method](e);
};
target.addEventListener(event, listener);
this.boundEvents.push({ target, event, listener });
if (!eventsMap[event]) {
eventsMap[event] = [];
}
eventsMap[event].push({ selector, method });
}
for (const [event, handlers] of Object.entries(eventsMap)) {
this.debugLogger && this.debugLogger.debug('Bind', event, handlers);
const listener = e => this.eventListener(e, handlers);
this.eventListeners[event] = listener;
this.el.addEventListener(event, listener);
}
}
unbindEvents() {
for (const boundEvent of this.boundEvents) {
const { target, event, listener } = boundEvent;
target.removeEventListener(event, listener);
for (const [event, listener] of Object.values(this.eventListeners)) {
this.el.removeEventListener(event, listener);
}
}
eventListener(e, handlers) {
this.debugLogger && this.debugLogger.debug('Listener fired', e.type);
for (const { selector, method } of handlers) {
if (selector) {
const closest = e.target.closest(selector);
if (!closest || !this.el.contains(closest)) {
continue;
}
}
if (!this[method]) {
this.debugLogger && this.debugLogger.debug('Method not defined', method);
continue;
}
this.debugLogger && this.debugLogger.debug('Handling event', e.type, method);
this[method](e);
}
}

View File

@ -743,7 +743,7 @@ class AppView extends View {
dragover(e) {
e.preventDefault();
e.originalEvent.dataTransfer.dropEffect = 'none';
e.dataTransfer.dropEffect = 'none';
}
drop(e) {

View File

@ -727,7 +727,7 @@ class DetailsView extends View {
dragover(e) {
e.preventDefault();
e.stopPropagation();
const dt = e.originalEvent.dataTransfer;
const dt = e.dataTransfer;
if (
!dt.types ||
(dt.types.indexOf ? dt.types.indexOf('Files') === -1 : !dt.types.contains('Files'))
@ -765,7 +765,7 @@ class DetailsView extends View {
}
this.$el.find('.details').removeClass('details--drag');
this.dragging = false;
const files = e.target.files || e.originalEvent.dataTransfer.files;
const files = e.target.files || e.dataTransfer.files;
this.addAttachedFiles(files);
}

View File

@ -107,7 +107,7 @@ class FieldView extends View {
if (!this.value) {
return;
}
const dt = e.originalEvent.dataTransfer;
const dt = e.dataTransfer;
const txtval = this.value.isProtected ? this.value.getText() : this.value;
if (this.valueEl[0].tagName.toLowerCase() === 'a') {
dt.setData('text/uri-list', txtval);

View File

@ -265,8 +265,8 @@ class ListView extends View {
const id = $(e.target)
.closest('.list__item')
.attr('id');
e.originalEvent.dataTransfer.setData('text/entry', id);
e.originalEvent.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/entry', id);
e.dataTransfer.effectAllowed = 'move';
DragDropInfo.dragObject = this.items.get(id);
}

View File

@ -178,7 +178,7 @@ class MenuItemView extends View {
}
dropAllowed(e) {
const types = e.originalEvent.dataTransfer.types;
const types = e.dataTransfer.types;
for (let i = 0; i < types.length; i++) {
if (types[i] === 'text/group' || types[i] === 'text/entry') {
return true;
@ -190,8 +190,8 @@ class MenuItemView extends View {
dragstart(e) {
e.stopPropagation();
if (this.model.get('drag')) {
e.originalEvent.dataTransfer.setData('text/group', this.model.id);
e.originalEvent.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/group', this.model.id);
e.dataTransfer.effectAllowed = 'move';
DragDropInfo.dragObject = this.model;
}
}
@ -230,7 +230,7 @@ class MenuItemView extends View {
}
dropTopAllowed(e) {
const types = e.originalEvent.dataTransfer.types;
const types = e.dataTransfer.types;
for (let i = 0; i < types.length; i++) {
if (types[i] === 'text/group') {
return true;

View File

@ -34,7 +34,7 @@ class OpenView extends View {
'click .open__icon-more': 'toggleMore',
'click .open__icon-storage': 'openStorage',
'click .open__icon-settings': 'openSettings',
'click .open__pass-input': 'passInputClick',
'click .open__pass-input[readonly]': 'openFile',
'input .open__pass-input': 'inputInput',
'keydown .open__pass-input': 'inputKeydown',
'keyup .open__pass-input': 'inputKeyup',
@ -322,12 +322,6 @@ class OpenView extends View {
});
}
passInputClick(e) {
if (e.target.readOnly) {
this.openFile();
}
}
openFile() {
if (this.model.settings.get('canOpen') === false) {
return;
@ -466,7 +460,7 @@ class OpenView extends View {
}
e.preventDefault();
e.stopPropagation();
const dt = e.originalEvent.dataTransfer;
const dt = e.dataTransfer;
if (
!dt.types ||
(dt.types.indexOf ? dt.types.indexOf('Files') === -1 : !dt.types.contains('Files'))
@ -508,7 +502,7 @@ class OpenView extends View {
}
this.closeConfig();
this.$el.removeClass('open--drag');
const files = [...(e.target.files || e.originalEvent.dataTransfer.files)];
const files = [...(e.target.files || e.dataTransfer.files)];
const dataFile = files.find(file => /\.kdbx$/i.test(file.name));
const keyFile = files.find(file => /\.key$/i.test(file.name));
if (dataFile) {