move views

This commit is contained in:
antelle 2019-09-16 17:43:57 +02:00
parent ad0963e412
commit 7730486f30
10 changed files with 445 additions and 442 deletions

View File

@ -150,7 +150,7 @@ ready(() => {
function showView() {
appModel.prepare();
new AppView({ model: appModel }).render();
new AppView(appModel).render();
Backbone.trigger('app-ready');
logStartupTime();
}

View File

@ -16,7 +16,7 @@ const Resizable = {
let size = dragInfo.startSize + e.offset;
size = Math.max(dragInfo.min, Math.min(dragInfo.max, size));
this.$el[dragInfo.prop](size);
this.trigger('view-resize', size);
this.emit('view-resize', size);
Backbone.trigger('page-geometry', { source: 'resizable' });
},
@ -28,7 +28,7 @@ const Resizable = {
this.$el.css(dragInfo.prop, 'auto');
}
this.fixSize(dragInfo);
this.trigger('view-resize', null);
this.emit('view-resize', null);
Backbone.trigger('page-geometry', { source: 'resizable' });
},

View File

@ -6,9 +6,10 @@ import { Logger } from 'util/logger';
class View extends EventEmitter {
parent = undefined;
replace = false;
template = undefined;
events = {};
model = undefined;
options = {};
views = {};
hidden = false;
removed = false;
@ -19,13 +20,7 @@ class View extends EventEmitter {
super();
this.model = model;
if (options.parent) {
this.parent = options.parent;
}
if (options.replace) {
this.replace = options.replace;
}
this.options = options;
this.setMaxListeners(100);
}
@ -55,24 +50,31 @@ class View extends EventEmitter {
renderElement(templateData) {
const html = this.template(templateData);
if (this.el) {
morphdom(this.el, html);
const mountRoot = this.options.ownParent ? this.el.firstChild : this.el;
morphdom(mountRoot, html);
} else {
if (this.parent) {
let parent = this.parent;
let parent = this.options.parent || this.parent;
if (parent) {
if (typeof parent === 'string') {
parent = document.querySelector(this.parent);
parent = document.querySelector(parent);
}
if (!parent) {
throw new Error(`Error rendering ${this.constructor.name}: parent not found`);
}
if (this.replace) {
if (this.options.replace) {
Tip.destroyTips(parent);
parent.innerHTML = '';
}
const el = document.createElement('div');
el.innerHTML = html;
this.el = el.firstChild;
parent.appendChild(this.el);
const root = el.firstChild;
if (this.options.ownParent) {
parent.appendChild(root);
this.el = parent;
} else {
this.el = root;
parent.appendChild(this.el);
}
} else {
throw new Error(
`Error rendering ${this.constructor.name}: I don't know how to insert the view`
@ -145,6 +147,7 @@ class View extends EventEmitter {
}
stopListening(model, event, callback) {
// TODO: remove a pending callback
model.off(event, callback);
}

View File

@ -1,4 +1,5 @@
import Backbone from 'backbone';
import { View } from 'view-engine/view';
import { IdleTracker } from 'comp/browser/idle-tracker';
import { KeyHandler } from 'comp/browser/key-handler';
import { Launcher } from 'comp/launcher';
@ -22,32 +23,31 @@ import { MenuView } from 'views/menu/menu-view';
import { OpenView } from 'views/open-view';
import { SettingsView } from 'views/settings/settings-view';
import { TagView } from 'views/tag-view';
import template from 'templates/app.hbs';
const AppView = Backbone.View.extend({
el: 'body',
class AppView extends View {
parent = 'body';
template: require('templates/app.hbs'),
template = template;
events: {
'contextmenu': 'contextMenu',
'drop': 'drop',
'dragenter': 'dragover',
'dragover': 'dragover',
events = {
contextmenu: 'contextMenu',
drop: 'drop',
dragenter: 'dragover',
dragover: 'dragover',
'click a[target=_blank]': 'extLinkClick',
'mousedown': 'bodyClick'
},
mousedown: 'bodyClick'
};
views: null,
titlebarStyle = 'default';
titlebarStyle: 'default',
initialize() {
this.views = {};
this.views.menu = new MenuView({ model: this.model.menu });
constructor(model) {
super(model);
this.views.menu = new MenuView(this.model.menu, { ownParent: true });
this.views.menuDrag = new DragView('x', { parent: '.app__menu-drag' });
this.views.footer = new FooterView(this.model);
this.views.listWrap = new ListWrapView(this.model);
this.views.list = new ListView({ model: this.model });
this.views.list = new ListView(this.model);
this.views.listDrag = new DragView('x', { parent: '.app__list-drag' });
this.views.list.dragView = this.views.listDrag;
this.views.details = new DetailsView();
@ -95,13 +95,12 @@ const AppView = Backbone.View.extend({
window.onresize = this.windowResize.bind(this);
window.onblur = this.windowBlur.bind(this);
KeyHandler.onKey(Keys.DOM_VK_ESCAPE, this.escPressed, this);
KeyHandler.onKey(Keys.DOM_VK_BACK_SPACE, this.backspacePressed, this);
this.onKey(Keys.DOM_VK_ESCAPE, this.escPressed);
this.onKey(Keys.DOM_VK_BACK_SPACE, this.backspacePressed);
if (Launcher && Launcher.devTools) {
KeyHandler.onKey(
Keys.DOM_VK_I,
this.openDevTools,
this,
KeyHandler.SHORTCUT_ACTION + KeyHandler.SHORTCUT_OPT
);
}
@ -110,7 +109,7 @@ const AppView = Backbone.View.extend({
this.setWindowClass();
this.fixClicksInEdge();
},
}
setWindowClass() {
const getBrowserCssClass = Features.getBrowserCssClass();
@ -120,7 +119,7 @@ const AppView = Backbone.View.extend({
if (this.titlebarStyle !== 'default') {
this.$el.addClass('titlebar-' + this.titlebarStyle);
}
},
}
fixClicksInEdge() {
// MS Edge doesn't want to handle clicks by default
@ -133,26 +132,24 @@ const AppView = Backbone.View.extend({
.focus();
setTimeout(() => msEdgeScrewer.remove(), 0);
}
},
}
render() {
this.$el.html(
this.template({
beta: this.model.isBeta,
titlebarStyle: this.titlebarStyle
})
);
super.render({
beta: this.model.isBeta,
titlebarStyle: this.titlebarStyle
});
this.panelEl = this.$el.find('.app__panel:first');
this.views.listWrap.render();
this.views.menu.setElement(this.$el.find('.app__menu')).render();
this.views.menu.render();
this.views.menuDrag.render();
this.views.footer.render();
this.views.list.setElement(this.$el.find('.app__list')).render();
this.views.list.render();
this.views.listDrag.render();
this.views.details.setElement(this.$el.find('.app__details')).render();
this.showLastOpenFile();
return this;
},
}
showOpenFile() {
this.hideContextMenu();
@ -167,17 +164,13 @@ const AppView = Backbone.View.extend({
this.hideSettings();
this.hideOpenFile();
this.hideKeyChange();
this.views.open = new OpenView({ model: this.model });
this.views.open.setElement(this.$el.find('.app__body')).render();
this.views.open.on(
'close',
() => {
Backbone.trigger('closed-open-view');
},
this
);
this.views.open.on('close', this.showEntries, this);
},
this.views.open = new OpenView(this.model);
this.views.open.render();
this.views.open.on('close', () => {
Backbone.trigger('closed-open-view');
});
this.views.open.on('close', () => this.showEntries());
}
showLastOpenFile() {
this.showOpenFile();
@ -186,14 +179,14 @@ const AppView = Backbone.View.extend({
this.views.open.currentSelectedIndex = 0;
this.views.open.showOpenFileInfo(lastOpenFile);
}
},
}
launcherOpenFile(file) {
if (file && file.data && /\.kdbx$/i.test(file.data)) {
this.showOpenFile();
this.views.open.showOpenLocalFile(file.data, file.key);
}
},
}
updateApp() {
if (
@ -203,7 +196,7 @@ const AppView = Backbone.View.extend({
) {
window.location.reload();
}
},
}
showEntries() {
this.views.menu.show();
@ -217,14 +210,14 @@ const AppView = Backbone.View.extend({
this.hideOpenFile();
this.hideSettings();
this.hideKeyChange();
},
}
hideOpenFile() {
if (this.views.open) {
this.views.open.remove();
this.views.open = null;
}
},
}
hidePanelView() {
if (this.views.panel) {
@ -232,7 +225,7 @@ const AppView = Backbone.View.extend({
this.views.panel = null;
this.panelEl.addClass('hide');
}
},
}
showPanelView(view) {
this.views.listWrap.hide();
@ -243,7 +236,7 @@ const AppView = Backbone.View.extend({
view.render();
this.views.panel = view;
this.panelEl.removeClass('hide');
},
}
hideSettings() {
if (this.views.settings) {
@ -251,14 +244,14 @@ const AppView = Backbone.View.extend({
this.views.settings.remove();
this.views.settings = null;
}
},
}
hideKeyChange() {
if (this.views.keyChange) {
this.views.keyChange.hide();
this.views.keyChange = null;
}
},
}
showSettings(selectedMenuItem) {
this.model.menu.setMenu('settings');
@ -278,15 +271,15 @@ const AppView = Backbone.View.extend({
}
this.model.menu.select({ item: selectedMenuItem });
this.views.menu.switchVisibility(false);
},
}
showEditGroup(group) {
this.showPanelView(new GrpView(group));
},
}
showEditTag() {
this.showPanelView(new TagView(this.model));
},
}
showKeyChange(file, viewConfig) {
if (Alerts.alertDisplayed) {
@ -310,7 +303,7 @@ const AppView = Backbone.View.extend({
this.views.keyChange.render();
this.views.keyChange.on('accept', this.keyChangeAccept.bind(this));
this.views.keyChange.on('cancel', this.showEntries.bind(this));
},
}
fileListUpdated() {
if (this.model.files.hasOpenFiles()) {
@ -319,7 +312,7 @@ const AppView = Backbone.View.extend({
this.showOpenFile();
}
this.fixClicksInEdge();
},
}
showFileSettings(e) {
const menuItem = this.model.menu.filesSection
@ -334,7 +327,7 @@ const AppView = Backbone.View.extend({
} else {
this.showSettings(menuItem);
}
},
}
toggleOpenFile() {
if (this.views.open) {
@ -344,7 +337,7 @@ const AppView = Backbone.View.extend({
} else {
this.showOpenFile();
}
},
}
beforeUnload(e) {
const exitEvent = {
@ -419,70 +412,70 @@ const AppView = Backbone.View.extend({
Launcher.minimizeApp();
return Launcher.preventExit(e);
}
},
}
windowResize() {
Backbone.trigger('page-geometry', { source: 'window' });
},
}
windowBlur(e) {
if (e.target === window) {
Backbone.trigger('page-blur');
}
},
}
enterFullScreen() {
this.$el.addClass('fullscreen');
},
}
leaveFullScreen() {
this.$el.removeClass('fullscreen');
},
}
escPressed() {
if (this.views.open && this.model.files.hasOpenFiles()) {
this.showEntries();
}
},
}
backspacePressed(e) {
if (e.target === document.body) {
e.preventDefault();
}
},
}
openDevTools() {
if (Launcher && Launcher.devTools) {
Launcher.openDevTools();
}
},
}
selectAll() {
this.menuSelect({ item: this.model.menu.allItemsSection.get('items').first() });
},
}
menuSelect(opt) {
this.model.menu.select(opt);
if (this.views.panel && !this.views.panel.isHidden()) {
this.showEntries();
}
},
}
userIdle() {
this.lockWorkspace(true);
},
}
osLocked() {
if (this.model.settings.get('lockOnOsLock')) {
this.lockWorkspace(true);
}
},
}
appMinimized() {
if (this.model.settings.get('lockOnMinimize')) {
this.lockWorkspace(true);
}
},
}
lockWorkspace(autoInit) {
if (Alerts.alertDisplayed) {
@ -518,7 +511,7 @@ const AppView = Backbone.View.extend({
} else {
this.closeAllFilesAndShowFirst();
}
},
}
handleAutoSaveTimer() {
if (this.model.settings.get('autoSaveInterval') !== 0) {
@ -531,7 +524,7 @@ const AppView = Backbone.View.extend({
this.model.settings.get('autoSaveInterval') * 1000 * 60
);
}
},
}
saveAndLock(complete) {
let pendingCallbacks = 0;
@ -574,7 +567,7 @@ const AppView = Backbone.View.extend({
}
}
}
},
}
closeAllFilesAndShowFirst() {
let fileToShow = this.model.files.find(file => !file.get('demo') && !file.get('created'));
@ -592,27 +585,27 @@ const AppView = Backbone.View.extend({
this.views.open.showOpenFileInfo(fileInfo);
}
}
},
}
saveAll() {
this.model.files.forEach(function(file) {
this.model.syncFile(file);
}, this);
},
}
syncAllByTimer() {
if (this.model.settings.get('autoSave')) {
this.saveAll();
}
},
}
remoteKeyChanged(e) {
this.showKeyChange(e.file, { remote: true });
},
}
keyChangePending(e) {
this.showKeyChange(e.file, { expired: true });
},
}
keyChangeAccept(e) {
this.showEntries();
@ -632,7 +625,7 @@ const AppView = Backbone.View.extend({
}
});
}
},
}
toggleSettings(page) {
let menuItem = page ? this.model.menu[page + 'Section'] : null;
@ -658,16 +651,16 @@ const AppView = Backbone.View.extend({
this.model.menu.select({ item: menuItem });
}
}
},
}
toggleMenu() {
this.views.menu.switchVisibility();
},
}
toggleDetails(visible) {
this.$el.find('.app').toggleClass('app--details-visible', visible);
this.views.menu.switchVisibility(false);
},
}
editGroup(group) {
if (group && !(this.views.panel instanceof GrpView)) {
@ -675,7 +668,7 @@ const AppView = Backbone.View.extend({
} else {
this.showEntries();
}
},
}
editTag(tag) {
if (tag && !(this.views.panel instanceof TagView)) {
@ -684,7 +677,7 @@ const AppView = Backbone.View.extend({
} else {
this.showEntries();
}
},
}
editGeneratorPresets() {
if (!(this.views.panel instanceof GeneratorPresetsView)) {
@ -695,17 +688,17 @@ const AppView = Backbone.View.extend({
} else {
this.showEntries();
}
},
}
isContextMenuAllowed(e) {
return ['input', 'textarea'].indexOf(e.target.tagName.toLowerCase()) < 0;
},
}
contextMenu(e) {
if (this.isContextMenuAllowed(e)) {
e.preventDefault();
}
},
}
showContextMenu(e) {
if (e.options && this.isContextMenuAllowed(e)) {
@ -723,19 +716,19 @@ const AppView = Backbone.View.extend({
menu.on('select', e => this.contextMenuSelect(e));
this.views.contextMenu = menu;
}
},
}
hideContextMenu() {
if (this.views.contextMenu) {
this.views.contextMenu.remove();
delete this.views.contextMenu;
}
},
}
contextMenuSelect(e) {
this.hideContextMenu();
Backbone.trigger('context-menu-select', e);
},
}
showSingleInstanceAlert() {
this.hideOpenFile();
@ -747,24 +740,24 @@ const AppView = Backbone.View.extend({
click: false,
buttons: []
});
},
}
dragover(e) {
e.preventDefault();
e.originalEvent.dataTransfer.dropEffect = 'none';
},
}
drop(e) {
e.preventDefault();
},
}
setTheme() {
SettingsManager.setTheme(this.model.settings.get('theme'));
},
}
setFontSize() {
SettingsManager.setFontSize(this.model.settings.get('fontSize'));
},
}
setLocale() {
SettingsManager.setLocale(this.model.settings.get('locale'));
@ -773,19 +766,19 @@ const AppView = Backbone.View.extend({
this.showSettings();
}
this.$el.find('.app__beta:first').text(Locale.appBeta);
},
}
extLinkClick(e) {
if (Launcher) {
e.preventDefault();
Launcher.openLink(e.target.href);
}
},
}
bodyClick(e) {
IdleTracker.regUserAction();
Backbone.trigger('click', e);
}
});
}
export { AppView };

View File

@ -1,4 +1,5 @@
import Backbone from 'backbone';
import { View } from 'view-engine/view';
import { Shortcuts } from 'comp/app/shortcuts';
import { KeyHandler } from 'comp/browser/key-handler';
import { Keys } from 'const/keys';
@ -7,11 +8,14 @@ import { Features } from 'util/features';
import { StringFormat } from 'util/formatting/string-format';
import { Locale } from 'util/locale';
import { DropdownView } from 'views/dropdown-view';
import template from 'templates/list-search.hbs';
const ListSearchView = Backbone.View.extend({
template: require('templates/list-search.hbs'),
class ListSearchView extends View {
parent = '.list__header';
events: {
template = template;
events = {
'keydown .list__search-field': 'inputKeyDown',
'keypress .list__search-field': 'inputKeyPress',
'input .list__search-field': 'inputChange',
@ -21,18 +25,17 @@ const ListSearchView = Backbone.View.extend({
'click .list__search-icon-search': 'advancedSearchClick',
'click .list__search-btn-menu': 'toggleMenu',
'change .list__search-adv input[type=checkbox]': 'toggleAdvCheck'
},
};
views: null,
inputEl = null;
sortOptions = null;
sortIcons = null;
createOptions = null;
advancedSearchEnabled = false;
advancedSearch = null;
inputEl: null,
sortOptions: null,
sortIcons: null,
createOptions: null,
advancedSearchEnabled: false,
advancedSearch: null,
initialize() {
constructor(model) {
super(model);
this.sortOptions = [
{
value: 'title',
@ -116,24 +119,16 @@ const ListSearchView = Backbone.View.extend({
this.advancedSearch = _.extend({}, this.model.advancedSearch);
}
this.setLocale();
KeyHandler.onKey(Keys.DOM_VK_F, this.findKeyPress, this, KeyHandler.SHORTCUT_ACTION);
KeyHandler.onKey(Keys.DOM_VK_N, this.newKeyPress, this, KeyHandler.SHORTCUT_OPT);
KeyHandler.onKey(Keys.DOM_VK_DOWN, this.downKeyPress, this);
KeyHandler.onKey(Keys.DOM_VK_UP, this.upKeyPress, this);
this.onKey(Keys.DOM_VK_F, this.findKeyPress, KeyHandler.SHORTCUT_ACTION);
this.onKey(Keys.DOM_VK_N, this.newKeyPress, KeyHandler.SHORTCUT_OPT);
this.onKey(Keys.DOM_VK_DOWN, this.downKeyPress);
this.onKey(Keys.DOM_VK_UP, this.upKeyPress);
this.listenTo(this, 'show', this.viewShown);
this.listenTo(this, 'hide', this.viewHidden);
this.listenTo(Backbone, 'filter', this.filterChanged);
this.listenTo(Backbone, 'set-locale', this.setLocale);
this.listenTo(Backbone, 'page-blur', this.pageBlur);
},
remove() {
KeyHandler.offKey(Keys.DOM_VK_F, this.findKeyPress, this);
KeyHandler.offKey(Keys.DOM_VK_N, this.newKeyPress, this);
KeyHandler.offKey(Keys.DOM_VK_DOWN, this.downKeyPress, this);
KeyHandler.offKey(Keys.DOM_VK_UP, this.upKeyPress, this);
Backbone.View.prototype.remove.apply(this);
},
}
setLocale() {
this.sortOptions.forEach(opt => {
@ -150,27 +145,29 @@ const ListSearchView = Backbone.View.extend({
{ value: 'entry', icon: 'key', text: StringFormat.capFirst(Locale.entry) + entryDesc },
{ value: 'group', icon: 'folder', text: StringFormat.capFirst(Locale.group) }
];
this.render();
},
if (this.el) {
this.render();
}
}
pageBlur() {
this.inputEl.blur();
},
}
viewShown() {
this.listenTo(KeyHandler, 'keypress', this.documentKeyPress);
},
}
viewHidden() {
this.stopListening(KeyHandler, 'keypress', this.documentKeyPress);
},
}
render() {
let searchVal;
if (this.inputEl) {
searchVal = this.inputEl.val();
}
this.renderTemplate({
super.render({
adv: this.advancedSearch,
advEnabled: this.advancedSearchEnabled
});
@ -179,7 +176,7 @@ const ListSearchView = Backbone.View.extend({
this.inputEl.val(searchVal);
}
return this;
},
}
inputKeyDown(e) {
switch (e.which) {
@ -200,22 +197,22 @@ const ListSearchView = Backbone.View.extend({
return;
}
e.preventDefault();
},
}
inputKeyPress(e) {
e.stopPropagation();
},
}
inputChange() {
Backbone.trigger('add-filter', { text: this.inputEl.val() });
},
}
inputFocus(e) {
$(e.target).select();
},
}
documentKeyPress(e) {
if (this._hidden) {
if (this.hidden) {
return;
}
const code = e.charCode;
@ -227,35 +224,35 @@ const ListSearchView = Backbone.View.extend({
this.inputEl[0].setSelectionRange(1, 1);
this.inputChange();
e.preventDefault();
},
}
findKeyPress(e) {
if (!this._hidden) {
if (!this.hidden) {
e.preventDefault();
this.hideSearchOptions();
this.inputEl.select().focus();
}
},
}
newKeyPress(e) {
if (!this._hidden) {
if (!this.hidden) {
e.preventDefault();
this.hideSearchOptions();
this.trigger('create-entry');
this.emit('create-entry');
}
},
}
downKeyPress(e) {
e.preventDefault();
this.hideSearchOptions();
this.trigger('select-next');
},
this.emit('select-next');
}
upKeyPress(e) {
e.preventDefault();
this.hideSearchOptions();
this.trigger('select-prev');
},
this.emit('select-prev');
}
filterChanged(filter) {
this.hideSearchOptions();
@ -272,22 +269,22 @@ const ListSearchView = Backbone.View.extend({
this.advancedSearchEnabled = adv;
this.$el.find('.list__search-adv').toggleClass('hide', !this.advancedSearchEnabled);
}
},
}
createOptionsClick(e) {
e.stopImmediatePropagation();
if (e.shiftKey) {
this.hideSearchOptions();
this.trigger('create-entry');
this.emit('create-entry');
return;
}
this.toggleCreateOptions();
},
}
sortOptionsClick(e) {
this.toggleSortOptions();
e.stopImmediatePropagation();
},
}
advancedSearchClick() {
this.advancedSearchEnabled = !this.advancedSearchEnabled;
@ -299,17 +296,17 @@ const ListSearchView = Backbone.View.extend({
advanced = this.model.advancedSearch;
}
Backbone.trigger('add-filter', { advanced });
},
}
toggleMenu() {
Backbone.trigger('toggle-menu');
},
}
toggleAdvCheck(e) {
const setting = $(e.target).data('id');
this.advancedSearch[setting] = e.target.checked;
Backbone.trigger('add-filter', { advanced: this.advancedSearch });
},
}
hideSearchOptions() {
if (this.views.searchDropdown) {
@ -319,7 +316,7 @@ const ListSearchView = Backbone.View.extend({
.find('.list__search-btn-sort,.list__search-btn-new')
.removeClass('sel--active');
}
},
}
toggleSortOptions() {
if (this.views.searchDropdown && this.views.searchDropdown.isSort) {
@ -343,7 +340,7 @@ const ListSearchView = Backbone.View.extend({
options: this.sortOptions
});
this.views.searchDropdown = view;
},
}
toggleCreateOptions() {
if (this.views.searchDropdown && this.views.searchDropdown.isCreate) {
@ -365,7 +362,7 @@ const ListSearchView = Backbone.View.extend({
options: this.createOptions.concat(this.getCreateEntryTemplateOptions())
});
this.views.searchDropdown = view;
},
}
getCreateEntryTemplateOptions() {
const entryTemplates = this.model.getEntryTemplates();
@ -390,35 +387,35 @@ const ListSearchView = Backbone.View.extend({
text: StringFormat.capFirst(Locale.template)
});
return options;
},
}
sortDropdownSelect(e) {
this.hideSearchOptions();
Backbone.trigger('set-sort', e.item);
},
}
createDropdownSelect(e) {
this.hideSearchOptions();
switch (e.item) {
case 'entry':
this.trigger('create-entry');
this.emit('create-entry');
break;
case 'group':
this.trigger('create-group');
this.emit('create-group');
break;
case 'tmpl':
this.trigger('create-template');
this.emit('create-template');
break;
default:
if (this.entryTemplates[e.item]) {
this.trigger('create-entry', { template: this.entryTemplates[e.item] });
this.emit('create-entry', { template: this.entryTemplates[e.item] });
}
}
},
}
addArrow(str) {
return str.replace('{}', '&rarr;');
}
});
}
export { ListSearchView };

View File

@ -1,4 +1,5 @@
import Backbone from 'backbone';
import { View } from 'view-engine/view';
import { EntryCollection } from 'collections/entry-collection';
import { DragDropInfo } from 'comp/app/drag-drop-info';
import { Alerts } from 'comp/ui/alerts';
@ -10,27 +11,30 @@ import { Resizable } from 'view-engine/resizable';
import { Scrollable } from 'view-engine/scrollable';
import { DropdownView } from 'views/dropdown-view';
import { ListSearchView } from 'views/list-search-view';
import template from 'templates/list.hbs';
import emptyTemplate from 'templates/list-empty.hbs';
const ListView = Backbone.View.extend({
template: require('templates/list.hbs'),
emptyTemplate: require('templates/list-empty.hbs'),
class ListView extends View {
parent = '.app__list';
events: {
template = template;
emptyTemplate = emptyTemplate;
events = {
'click .list__item': 'itemClick',
'click .list__table-options': 'tableOptionsClick',
'dragstart .list__item': 'itemDragStart'
},
};
views: null,
minWidth = 200;
minHeight = 200;
maxWidth = 500;
maxHeight = 500;
minWidth: 200,
minHeight: 200,
maxWidth: 500,
maxHeight: 500,
itemsEl = null;
itemsEl: null,
tableColumns: [
tableColumns = [
{ val: 'title', name: 'title', enabled: true },
{ val: 'user', name: 'user', enabled: true },
{ val: 'url', name: 'website', enabled: true },
@ -38,12 +42,13 @@ const ListView = Backbone.View.extend({
{ val: 'notes', name: 'notes', enabled: true },
{ val: 'groupName', name: 'group', enabled: false },
{ val: 'fileName', name: 'file', enabled: false }
],
];
constructor(model) {
super(model);
initialize() {
this.initScroll();
this.views = {};
this.views.search = new ListSearchView({ model: this.model });
this.views.search = new ListSearchView(this.model);
this.listenTo(this.views.search, 'select-prev', this.selectPrev);
this.listenTo(this.views.search, 'select-next', this.selectNext);
@ -62,13 +67,13 @@ const ListView = Backbone.View.extend({
this.readTableColumnsEnabled();
this.items = new EntryCollection();
},
}
render() {
if (!this.itemsEl) {
this.$el.html(this.template());
super.render();
this.itemsEl = this.$el.find('.list__items>.scroller');
this.views.search.setElement(this.$el.find('.list__header')).render();
this.views.search.render();
this.setTableView();
this.createScroll({
@ -105,7 +110,7 @@ const ListView = Backbone.View.extend({
}
this.pageResized();
return this;
},
}
getItemsTemplate() {
if (this.model.settings.get('tableView')) {
@ -113,11 +118,11 @@ const ListView = Backbone.View.extend({
} else {
return this.renderPlainItems;
}
},
}
renderPlainItems(itemsHtml) {
return itemsHtml.items;
},
}
getItemTemplate() {
if (this.model.settings.get('tableView')) {
@ -125,11 +130,11 @@ const ListView = Backbone.View.extend({
} else {
return require('templates/list-item-short.hbs');
}
},
}
getDescField() {
return this.model.sort.replace('-', '');
},
}
itemClick(e) {
const id = $(e.target)
@ -140,33 +145,33 @@ const ListView = Backbone.View.extend({
this.selectItem(item);
}
Backbone.trigger('toggle-details', true);
},
}
selectPrev() {
const ix = this.items.indexOf(this.items.get(this.model.activeEntryId));
if (ix > 0) {
this.selectItem(this.items.at(ix - 1));
}
},
}
selectNext() {
const ix = this.items.indexOf(this.items.get(this.model.activeEntryId));
if (ix < this.items.length - 1) {
this.selectItem(this.items.at(ix + 1));
}
},
}
createEntry(arg) {
const newEntry = this.model.createNewEntry(arg);
this.items.unshift(newEntry);
this.render();
this.selectItem(newEntry);
},
}
createGroup() {
const newGroup = this.model.createNewGroup();
Backbone.trigger('edit-group', newGroup);
},
}
createTemplate() {
if (!this.model.settings.get('templateHelpShown')) {
@ -189,7 +194,7 @@ const ListView = Backbone.View.extend({
this.items.unshift(templateEntry);
this.render();
this.selectItem(templateEntry);
},
}
selectItem(item) {
this.model.activeEntryId = item.id;
@ -205,25 +210,25 @@ const ListView = Backbone.View.extend({
} else if (itemRect.bottom > listRect.bottom) {
listEl.scrollTop += itemRect.bottom - listRect.bottom;
}
},
}
viewShown() {
this.views.search.show();
},
}
viewHidden() {
this.views.search.hide();
},
}
setTableView() {
const isTable = this.model.settings.get('tableView');
this.dragView.setCoord(isTable ? 'y' : 'x');
this.setDefaultSize();
},
}
setDefaultSize() {
this.setSize(this.model.settings.get('listViewWidth'));
},
}
setSize(size) {
this.$el.css({ width: 'auto', height: 'auto' });
@ -232,27 +237,27 @@ const ListView = Backbone.View.extend({
} else {
this.$el.css('flex', null);
}
},
}
viewResized(size) {
this.setSize(size);
this.throttleSetViewSizeSetting(size);
},
}
throttleSetViewSizeSetting: _.throttle(size => {
throttleSetViewSizeSetting = _.throttle(size => {
AppSettingsModel.instance.set('listViewWidth', size);
}, 1000),
}, 1000);
filterChanged(filter) {
this.items = filter.entries;
this.render();
},
}
entryUpdated() {
const scrollTop = this.itemsEl[0].scrollTop;
this.render();
this.itemsEl[0].scrollTop = scrollTop;
},
}
itemDragStart(e) {
e.stopPropagation();
@ -262,7 +267,7 @@ const ListView = Backbone.View.extend({
e.originalEvent.dataTransfer.setData('text/entry', id);
e.originalEvent.dataTransfer.effectAllowed = 'move';
DragDropInfo.dragObject = this.items.get(id);
},
}
tableOptionsClick(e) {
e.stopImmediatePropagation();
@ -287,14 +292,14 @@ const ListView = Backbone.View.extend({
options
});
this.views.optionsDropdown = view;
},
}
hideOptionsDropdown() {
if (this.views.optionsDropdown) {
this.views.optionsDropdown.remove();
delete this.views.optionsDropdown;
}
},
}
optionsDropdownSelect(e) {
const col = _.find(this.tableColumns, c => c.val === e.item);
@ -302,7 +307,7 @@ const ListView = Backbone.View.extend({
e.el.find('i:first').toggleClass('fa-check-square-o fa-square-o');
this.render();
this.saveTableColumnsEnabled();
},
}
readTableColumnsEnabled() {
const tableViewColumns = AppSettingsModel.instance.get('tableViewColumns');
@ -311,7 +316,7 @@ const ListView = Backbone.View.extend({
col.enabled = tableViewColumns.indexOf(col.name) >= 0;
});
}
},
}
saveTableColumnsEnabled() {
const tableViewColumns = this.tableColumns
@ -319,9 +324,9 @@ const ListView = Backbone.View.extend({
.map(column => column.name);
AppSettingsModel.instance.set('tableViewColumns', tableViewColumns);
}
});
}
_.extend(ListView.prototype, Resizable);
_.extend(ListView.prototype, Scrollable);
Object.assign(ListView.prototype, Resizable);
Object.assign(ListView.prototype, Scrollable);
export { ListView };

View File

@ -1,14 +1,16 @@
import Backbone from 'backbone';
import { View } from 'view-engine/view';
import { DragDropInfo } from 'comp/app/drag-drop-info';
import { KeyHandler } from 'comp/browser/key-handler';
import { Alerts } from 'comp/ui/alerts';
import { Keys } from 'const/keys';
import { Locale } from 'util/locale';
import template from 'templates/menu/menu-item.hbs';
const MenuItemView = Backbone.View.extend({
template: require('templates/menu/menu-item.hbs'),
class MenuItemView extends View {
template = template;
events: {
events = {
'mouseover': 'mouseover',
'mouseout': 'mouseout',
'click .menu__item-option': 'selectOption',
@ -22,12 +24,13 @@ const MenuItemView = Backbone.View.extend({
'drop': 'drop',
'dragover .menu__item-drag-top': 'dragoverTop',
'dragleave .menu__item-drag-top': 'dragleaveTop'
},
};
iconEl: null,
itemViews: null,
iconEl = null;
itemViews = null;
initialize() {
constructor(model, options) {
super(model, options);
this.itemViews = [];
this.listenTo(this.model, 'change:title', this.changeTitle);
this.listenTo(this.model, 'change:icon', this.changeIcon);
@ -39,70 +42,62 @@ const MenuItemView = Backbone.View.extend({
this.listenTo(this.model, 'insert', this.insertItem);
const shortcut = this.model.get('shortcut');
if (shortcut) {
KeyHandler.onKey(shortcut, this.selectItem, this, KeyHandler.SHORTCUT_OPT);
this.onKey(shortcut, this.selectItem, KeyHandler.SHORTCUT_OPT);
if (shortcut !== Keys.DOM_VK_C) {
KeyHandler.onKey(shortcut, this.selectItem, this, KeyHandler.SHORTCUT_ACTION);
this.onKey(shortcut, this.selectItem, KeyHandler.SHORTCUT_ACTION);
}
}
},
this.once('remove', () => {
this.removeInnerViews();
});
}
render() {
this.removeInnerViews();
this.renderTemplate(this.model.attributes);
super.render(this.model.attributes);
this.iconEl = this.$el.find('.menu__item-icon');
const items = this.model.get('items');
if (items) {
items.forEach(function(item) {
items.forEach(item => {
if (item.get('visible')) {
this.insertItem(item);
}
}, this);
});
}
this.$el.toggleClass('menu__item--collapsed', !this.model.get('expanded'));
return this;
},
}
insertItem(item) {
this.itemViews.push(new MenuItemView({ el: this.$el, model: item }).render());
},
remove() {
this.removeInnerViews();
const shortcut = this.model.get('shortcut');
if (shortcut) {
KeyHandler.offKey(shortcut, this.selectItem, this, KeyHandler.SHORTCUT_OPT);
if (shortcut !== Keys.DOM_VK_C) {
KeyHandler.offKey(shortcut, this.selectItem, this, KeyHandler.SHORTCUT_ACTION);
}
}
Backbone.View.prototype.remove.apply(this);
},
const itemView = new MenuItemView(item, { parent: this.el });
itemView.render();
this.itemViews.push(itemView);
}
removeInnerViews() {
this.itemViews.forEach(itemView => itemView.remove());
this.itemViews = [];
},
}
changeTitle(model, title) {
this.$el
.find('.menu__item-title')
.first()
.text(title || '(no title)');
},
}
changeIcon(model, icon) {
this.iconEl[0].className =
'menu__item-icon fa ' + (icon ? 'fa-' + icon : 'menu__item-icon--no-icon');
},
}
changeActive(model, active) {
this.$el.toggleClass('menu__item--active', active);
},
}
changeExpanded(model, expanded) {
this.$el.toggleClass('menu__item--collapsed', !expanded);
this.model.setExpanded(expanded);
},
}
changeCls(model, cls) {
const oldCls = model.previousAttributes().cls;
@ -110,19 +105,19 @@ const MenuItemView = Backbone.View.extend({
this.$el.removeClass(oldCls);
}
this.$el.addClass(cls);
},
}
mouseover(e) {
if (!e.button) {
this.$el.addClass('menu__item--hover');
e.stopPropagation();
}
},
}
mouseout(e) {
this.$el.removeClass('menu__item--hover');
e.stopPropagation();
},
}
selectItem(e) {
e.stopPropagation();
@ -135,7 +130,7 @@ const MenuItemView = Backbone.View.extend({
} else {
Backbone.trigger('menu-select', { item: this.model });
}
},
}
selectOption(e) {
const options = this.model.get('options');
@ -148,14 +143,14 @@ const MenuItemView = Backbone.View.extend({
}
e.stopImmediatePropagation();
e.preventDefault();
},
}
expandItem(e) {
if (this.model.toggleExpanded) {
this.model.toggleExpanded();
}
e.stopPropagation();
},
}
editItem(e) {
if (this.model.get('active') && this.model.get('editable')) {
@ -169,7 +164,7 @@ const MenuItemView = Backbone.View.extend({
break;
}
}
},
}
emptyTrash(e) {
e.stopPropagation();
@ -181,7 +176,7 @@ const MenuItemView = Backbone.View.extend({
Backbone.trigger('empty-trash');
}
});
},
}
dropAllowed(e) {
const types = e.originalEvent.dataTransfer.types;
@ -191,7 +186,7 @@ const MenuItemView = Backbone.View.extend({
}
}
return false;
},
}
dragstart(e) {
e.stopPropagation();
@ -200,7 +195,7 @@ const MenuItemView = Backbone.View.extend({
e.originalEvent.dataTransfer.effectAllowed = 'move';
DragDropInfo.dragObject = this.model;
}
},
}
dragover(e) {
if (this.model.get('drop') && this.dropAllowed(e)) {
@ -208,14 +203,14 @@ const MenuItemView = Backbone.View.extend({
e.preventDefault();
this.$el.addClass('menu__item--drag');
}
},
}
dragleave(e) {
e.stopPropagation();
if (this.model.get('drop') && this.dropAllowed(e)) {
this.$el.removeClass('menu__item--drag menu__item--drag-top');
}
},
}
drop(e) {
e.stopPropagation();
@ -233,7 +228,7 @@ const MenuItemView = Backbone.View.extend({
}
Backbone.trigger('refresh');
}
},
}
dropTopAllowed(e) {
const types = e.originalEvent.dataTransfer.types;
@ -243,19 +238,19 @@ const MenuItemView = Backbone.View.extend({
}
}
return false;
},
}
dragoverTop(e) {
if (this.dropTopAllowed(e)) {
this.$el.addClass('menu__item--drag-top');
}
},
}
dragleaveTop(e) {
if (this.dropTopAllowed(e)) {
this.$el.removeClass('menu__item--drag-top');
}
}
});
}
export { MenuItemView };

View File

@ -1,31 +1,36 @@
import Backbone from 'backbone';
import { View } from 'view-engine/view';
import { AppSettingsModel } from 'models/app-settings-model';
import { Resizable } from 'view-engine/resizable';
import { Scrollable } from 'view-engine/scrollable';
import { MenuItemView } from 'views/menu/menu-item-view';
import template from 'templates/menu/menu-section.hbs';
const MenuSectionView = Backbone.View.extend({
template: require('templates/menu/menu-section.hbs'),
class MenuSectionView extends View {
template = template;
events: {},
events = {};
itemViews: null,
itemViews = null;
minHeight: 55,
maxHeight() {
return this.$el.parent().height() - 116;
},
autoHeight: 'auto',
minHeight = 55;
autoHeigh = 'auto';
initialize() {
constructor(model, options) {
super(model, options);
this.itemViews = [];
this.listenTo(this.model, 'change-items', this.itemsChanged);
this.listenTo(this, 'view-resize', this.viewResized);
},
this.once('remove', () => {
if (this.scroll) {
this.scroll.dispose();
}
this.removeInnerViews();
});
}
render() {
if (!this.itemsEl) {
this.renderTemplate(this.model.attributes);
super.render(this.model.attributes);
this.itemsEl = this.model.get('scrollable') ? this.$el.find('.scroller') : this.$el;
if (this.model.get('scrollable')) {
this.initScroll();
@ -38,11 +43,11 @@ const MenuSectionView = Backbone.View.extend({
} else {
this.removeInnerViews();
}
this.model.get('items').forEach(function(item) {
const itemView = new MenuItemView({ el: this.itemsEl, model: item });
this.model.get('items').forEach(item => {
const itemView = new MenuItemView(item, { parent: this.itemsEl[0] });
itemView.render();
this.itemViews.push(itemView);
}, this);
});
if (this.model.get('drag')) {
const height = AppSettingsModel.instance.get('tagsViewHeight');
if (typeof height === 'number') {
@ -51,36 +56,32 @@ const MenuSectionView = Backbone.View.extend({
}
}
this.pageResized();
},
}
remove() {
if (this.scroll) {
this.scroll.dispose();
}
this.removeInnerViews();
Backbone.View.prototype.remove.apply(this);
},
maxHeight() {
return this.$el.parent().height() - 116;
}
removeInnerViews() {
this.itemViews.forEach(itemView => itemView.remove());
this.itemViews = [];
},
}
itemsChanged() {
this.render();
},
}
viewResized(size) {
this.$el.css('flex', '0 0 ' + (size ? size + 'px' : 'auto'));
this.saveViewHeight(size);
},
}
saveViewHeight: _.throttle(size => {
saveViewHeight = _.throttle(size => {
AppSettingsModel.instance.set('tagsViewHeight', size);
}, 1000)
});
}, 1000);
}
_.extend(MenuSectionView.prototype, Resizable);
_.extend(MenuSectionView.prototype, Scrollable);
Object.assign(MenuSectionView.prototype, Resizable);
Object.assign(MenuSectionView.prototype, Scrollable);
export { MenuSectionView };

View File

@ -1,49 +1,50 @@
import Backbone from 'backbone';
import { View } from 'view-engine/view';
import { KeyHandler } from 'comp/browser/key-handler';
import { Keys } from 'const/keys';
import { AppSettingsModel } from 'models/app-settings-model';
import { Resizable } from 'view-engine/resizable';
import { DragView } from 'views/drag-view';
import { MenuSectionView } from 'views/menu/menu-section-view';
import template from 'templates/menu/menu.hbs';
const MenuView = Backbone.View.extend({
template: require('templates/menu/menu.hbs'),
class MenuView extends View {
parent = '.app__menu';
events: {},
template = template;
sectionViews: [],
events = {};
minWidth: 130,
maxWidth: 300,
sectionViews = [];
initialize() {
minWidth = 130;
maxWidth = 300;
constructor(model, options) {
super(model, options);
this.listenTo(this.model, 'change:sections', this.menuChanged);
this.listenTo(this, 'view-resize', this.viewResized);
KeyHandler.onKey(
this.onKey(
Keys.DOM_VK_UP,
this.selectPreviousSection,
this,
KeyHandler.SHORTCUT_ACTION + KeyHandler.SHORTCUT_OPT
);
KeyHandler.onKey(
this.onKey(
Keys.DOM_VK_DOWN,
this.selectNextSection,
this,
KeyHandler.SHORTCUT_ACTION + KeyHandler.SHORTCUT_OPT
);
},
remove() {
this.sectionViews.forEach(sectionView => sectionView.remove());
this.sectionViews = [];
Backbone.View.prototype.remove.apply(this);
},
this.once('remove', () => {
this.sectionViews.forEach(sectionView => sectionView.remove());
this.sectionViews = [];
});
}
render() {
this.$el.html(this.template());
super.render();
const sectionsEl = this.$el.find('.menu');
this.model.get('sections').forEach(function(section) {
const sectionView = new MenuSectionView({ el: sectionsEl, model: section });
const sectionView = new MenuSectionView(section, { parent: sectionsEl[0] });
sectionView.render();
if (section.get('drag')) {
const dragEl = $('<div/>')
@ -60,29 +61,29 @@ const MenuView = Backbone.View.extend({
this.$el.width(AppSettingsModel.instance.get('menuViewWidth'));
}
return this;
},
}
menuChanged() {
this.render();
},
}
viewResized: _.throttle(size => {
viewResized = _.throttle(size => {
AppSettingsModel.instance.set('menuViewWidth', size);
}, 1000),
}, 1000);
switchVisibility(visible) {
this.$el.toggleClass('menu-visible', visible);
},
}
selectPreviousSection() {
Backbone.trigger('select-previous-menu-item');
},
}
selectNextSection() {
Backbone.trigger('select-next-menu-item');
}
});
}
_.extend(MenuView.prototype, Resizable);
Object.assign(MenuView.prototype, Resizable);
export { MenuView };

View File

@ -1,5 +1,6 @@
import Backbone from 'backbone';
import kdbxweb from 'kdbxweb';
import { View } from 'view-engine/view';
import { Storage } from 'storage';
import { DropboxChooser } from 'comp/app/dropbox-chooser';
import { FocusDetector } from 'comp/browser/focus-detector';
@ -16,13 +17,16 @@ import { Logger } from 'util/logger';
import { InputFx } from 'util/ui/input-fx';
import { OpenConfigView } from 'views/open-config-view';
import { StorageFileListView } from 'views/storage-file-list-view';
import template from 'templates/open.hbs';
const logger = new Logger('open-view');
const OpenView = Backbone.View.extend({
template: require('templates/open.hbs'),
class OpenView extends View {
parent = '.app__body';
events: {
template = template;
events = {
'change .open__file-ctrl': 'fileSelected',
'click .open__icon-open': 'openFile',
'click .open__icon-new': 'createNew',
@ -30,7 +34,7 @@ const OpenView = Backbone.View.extend({
'click .open__icon-more': 'toggleMore',
'click .open__icon-storage': 'openStorage',
'click .open__icon-settings': 'openSettings',
'click .open__pass-input[readonly]': 'openFile',
'click .open__pass-input': 'passInputClick',
'input .open__pass-input': 'inputInput',
'keydown .open__pass-input': 'inputKeydown',
'keyup .open__pass-input': 'inputKeyup',
@ -38,39 +42,34 @@ const OpenView = Backbone.View.extend({
'click .open__pass-enter-btn': 'openDb',
'click .open__settings-key-file': 'openKeyFile',
'click .open__last-item': 'openLast',
'dragover': 'dragover',
'dragleave': 'dragleave',
'drop': 'drop'
},
dragover: 'dragover',
dragleave: 'dragleave',
drop: 'drop'
};
views: null,
params: null,
passwordInput: null,
busy: false,
currentSelectedIndex: -1,
params = null;
initialize() {
this.views = {};
this.params = {
id: null,
name: '',
storage: null,
path: null,
keyFileName: null,
keyFileData: null,
keyFilePath: null,
fileData: null,
rev: null
};
passwordInput = null;
busy = false;
currentSelectedIndex = -1;
constructor(model) {
super(model);
this.resetParams();
this.passwordInput = new SecureInput();
KeyHandler.onKey(Keys.DOM_VK_Z, this.undoKeyPress, this, KeyHandler.SHORTCUT_ACTION);
KeyHandler.onKey(Keys.DOM_VK_TAB, this.tabKeyPress, this);
KeyHandler.onKey(Keys.DOM_VK_ENTER, this.enterKeyPress, this);
KeyHandler.onKey(Keys.DOM_VK_RETURN, this.enterKeyPress, this);
KeyHandler.onKey(Keys.DOM_VK_DOWN, this.moveOpenFileSelectionDown, this);
KeyHandler.onKey(Keys.DOM_VK_UP, this.moveOpenFileSelectionUp, this);
this.onKey(Keys.DOM_VK_Z, this.undoKeyPress, KeyHandler.SHORTCUT_ACTION);
this.onKey(Keys.DOM_VK_TAB, this.tabKeyPress);
this.onKey(Keys.DOM_VK_ENTER, this.enterKeyPress);
this.onKey(Keys.DOM_VK_RETURN, this.enterKeyPress);
this.onKey(Keys.DOM_VK_DOWN, this.moveOpenFileSelectionDown);
this.onKey(Keys.DOM_VK_UP, this.moveOpenFileSelectionUp);
this.listenTo(Backbone, 'main-window-focus', this.windowFocused.bind(this));
},
this.once('reset', () => {
this.passwordInput.reset();
});
}
render() {
if (this.dragTimeout) {
@ -90,7 +89,7 @@ const OpenView = Backbone.View.extend({
!this.model.settings.get('canOpen') &&
!this.model.settings.get('canCreate') &&
!(this.model.settings.get('canOpenDemo') && !this.model.settings.get('demoOpened'));
this.renderTemplate({
super.render({
lastOpenFiles: this.getLastOpenFiles(),
canOpenKeyFromDropbox: !Launcher && Storage.dropbox.enabled,
demoOpened: this.model.settings.get('demoOpened'),
@ -106,17 +105,31 @@ const OpenView = Backbone.View.extend({
this.inputEl = this.$el.find('.open__pass-input');
this.passwordInput.setElement(this.inputEl);
return this;
},
}
resetParams() {
this.params = {
id: null,
name: '',
storage: null,
path: null,
keyFileName: null,
keyFileData: null,
keyFilePath: null,
fileData: null,
rev: null
};
}
windowFocused() {
this.inputEl.focus();
},
}
focusInput(focusOnMobile) {
if (FocusDetector.hasFocus() && (focusOnMobile || !Features.isMobile)) {
this.inputEl.focus();
}
},
}
getLastOpenFiles() {
return this.model.fileInfos.map(f => {
@ -136,7 +149,7 @@ const OpenView = Backbone.View.extend({
iconSvg: storage ? storage.iconSvg : undefined
};
});
},
}
getDisplayedPath(fileInfo) {
const storage = fileInfo.get('storage');
@ -144,18 +157,7 @@ const OpenView = Backbone.View.extend({
return fileInfo.get('path');
}
return null;
},
remove() {
this.passwordInput.reset();
KeyHandler.offKey(Keys.DOM_VK_Z, this.undoKeyPress, this);
KeyHandler.offKey(Keys.DOM_VK_TAB, this.tabKeyPress, this);
KeyHandler.offKey(Keys.DOM_VK_ENTER, this.enterKeyPress, this);
KeyHandler.offKey(Keys.DOM_VK_RETURN, this.enterKeyPress, this);
KeyHandler.offKey(Keys.DOM_VK_DOWN, this.moveOpenFileSelectionDown, this);
KeyHandler.offKey(Keys.DOM_VK_UP, this.moveOpenFileSelectionUp, this);
Backbone.View.prototype.remove.apply(this);
},
}
showLocalFileAlert() {
if (this.model.settings.get('skipOpenLocalWarn')) {
@ -179,7 +181,7 @@ const OpenView = Backbone.View.extend({
}
}
});
},
}
fileSelected(e) {
const file = e.target.files[0];
@ -190,7 +192,7 @@ const OpenView = Backbone.View.extend({
}
});
}
},
}
processFile(file, complete) {
const reader = new FileReader();
@ -264,7 +266,7 @@ const OpenView = Backbone.View.extend({
} else {
reader.readAsArrayBuffer(file);
}
},
}
getOpenFileFormat(fileData) {
if (fileData.byteLength < 8) {
@ -290,7 +292,7 @@ const OpenView = Backbone.View.extend({
} else {
return undefined;
}
},
}
displayOpenFile() {
this.$el.addClass('open--file');
@ -298,7 +300,7 @@ const OpenView = Backbone.View.extend({
this.inputEl[0].removeAttribute('readonly');
this.inputEl[0].setAttribute('placeholder', Locale.openPassFor + ' ' + this.params.name);
this.focusInput();
},
}
displayOpenKeyFile() {
this.$el.toggleClass('open--key-file', !!this.params.keyFileName);
@ -306,7 +308,7 @@ const OpenView = Backbone.View.extend({
.find('.open__settings-key-file-name')
.text(this.params.keyFileName || this.params.keyFilePath || Locale.openKeyFile);
this.focusInput();
},
}
setFile(file, keyFile, fileReadyCallback) {
this.reading = 'fileData';
@ -319,7 +321,13 @@ const OpenView = Backbone.View.extend({
fileReadyCallback();
}
});
},
}
passInputClick(e) {
if (e.target.readOnly) {
this.openFile();
}
}
openFile() {
if (this.model.settings.get('canOpen') === false) {
@ -329,7 +337,7 @@ const OpenView = Backbone.View.extend({
this.closeConfig();
this.openAny('fileData');
}
},
}
openKeyFile(e) {
if ($(e.target).hasClass('open__settings-key-file-dropbox')) {
@ -345,7 +353,7 @@ const OpenView = Backbone.View.extend({
this.openAny('keyFileData');
}
}
},
}
openKeyFileFromDropbox() {
if (!this.busy) {
@ -358,7 +366,7 @@ const OpenView = Backbone.View.extend({
this.displayOpenKeyFile();
}).choose();
}
},
}
openAny(reading, ext) {
this.reading = reading;
@ -380,7 +388,7 @@ const OpenView = Backbone.View.extend({
} else {
fileInput.click();
}
},
}
openLast(e) {
if (this.busy) {
@ -414,14 +422,14 @@ const OpenView = Backbone.View.extend({
const fileInfo = this.model.fileInfos.get(id);
this.showOpenFileInfo(fileInfo, true);
},
}
removeFile(id) {
this.model.removeFileInfo(id);
this.$el.find('.open__last-item[data-id="' + id + '"]').remove();
this.initialize();
this.resetParams();
this.render();
},
}
inputKeydown(e) {
const code = e.keyCode || e.which;
@ -430,14 +438,14 @@ const OpenView = Backbone.View.extend({
} else if (code === Keys.DOM_VK_CAPS_LOCK) {
this.toggleCapsLockWarning(false);
}
},
}
inputKeyup(e) {
const code = e.keyCode || e.which;
if (code === Keys.DOM_VK_CAPS_LOCK) {
this.toggleCapsLockWarning(false);
}
},
}
inputKeypress(e) {
const charCode = e.keyCode || e.which;
@ -447,11 +455,11 @@ const OpenView = Backbone.View.extend({
if (lower !== upper && !e.shiftKey) {
this.toggleCapsLockWarning(ch !== lower);
}
},
}
toggleCapsLockWarning(on) {
this.$el.find('.open__pass-warning').toggleClass('invisible', !on);
},
}
dragover(e) {
if (this.model.settings.get('canOpen') === false) {
@ -474,7 +482,7 @@ const OpenView = Backbone.View.extend({
if (!this.$el.hasClass('open--drag')) {
this.$el.addClass('open--drag');
}
},
}
dragleave() {
if (this.model.settings.get('canOpen') === false) {
@ -486,7 +494,7 @@ const OpenView = Backbone.View.extend({
this.dragTimeout = setTimeout(() => {
this.$el.removeClass('open--drag');
}, 100);
},
}
drop(e) {
if (this.model.settings.get('canOpen') === false) {
@ -516,22 +524,22 @@ const OpenView = Backbone.View.extend({
this.setFile(xmlFile, null, this.showLocalFileAlert.bind(this));
}
}
},
}
undoKeyPress(e) {
e.preventDefault();
},
}
tabKeyPress() {
this.$el.addClass('open--show-focus');
},
}
enterKeyPress(e) {
const el = this.$el.find('[tabindex]:focus');
if (el.length) {
el.trigger('click', e);
}
},
}
showOpenFileInfo(fileInfo, fileWasClicked) {
if (this.busy || !fileInfo) {
@ -554,7 +562,7 @@ const OpenView = Backbone.View.extend({
if (fileWasClicked) {
this.focusInput(true);
}
},
}
showOpenLocalFile(path, keyFilePath) {
if (this.busy) {
@ -574,7 +582,7 @@ const OpenView = Backbone.View.extend({
this.params.keyFileData = null;
this.displayOpenKeyFile();
}
},
}
openFileWithFingerprint(fileInfo) {
if (!fileInfo.has('fingerprint')) {
@ -588,29 +596,29 @@ const OpenView = Backbone.View.extend({
this.openDb();
});
}
},
}
createDemo() {
if (!this.busy) {
this.closeConfig();
if (!this.model.createDemoFile()) {
this.trigger('close');
this.emit('close');
}
if (!this.model.settings.get('demoOpened')) {
this.model.settings.set('demoOpened', true);
}
}
},
}
createNew() {
if (!this.busy) {
this.model.createNewFile();
}
},
}
openDb() {
if (this.params.id && this.model.files.get(this.params.id)) {
this.trigger('close');
this.emit('close');
return;
}
if (this.busy || !this.params.name) {
@ -623,7 +631,7 @@ const OpenView = Backbone.View.extend({
this.afterPaint(
this.model.openFile.bind(this.model, this.params, this.openDbComplete.bind(this))
);
},
}
openDbComplete(err) {
this.busy = false;
@ -650,9 +658,9 @@ const OpenView = Backbone.View.extend({
});
}
} else {
this.trigger('close');
this.emit('close');
}
},
}
importDbWithXml() {
if (this.busy || !this.params.name) {
@ -670,7 +678,7 @@ const OpenView = Backbone.View.extend({
this.openDbComplete(err);
})
);
},
}
toggleMore() {
if (this.busy) {
@ -678,11 +686,11 @@ const OpenView = Backbone.View.extend({
}
this.closeConfig();
this.$el.find('.open__icons--lower').toggleClass('hide');
},
}
openSettings() {
Backbone.trigger('toggle-settings');
},
}
openStorage(e) {
if (this.busy) {
@ -704,7 +712,7 @@ const OpenView = Backbone.View.extend({
} else {
Alerts.notImplemented();
}
},
}
listStorage(storage, config) {
if (this.busy) {
@ -778,7 +786,7 @@ const OpenView = Backbone.View.extend({
view: listView
});
});
},
}
openStorageFile(storage, file) {
if (this.busy) {
@ -791,7 +799,7 @@ const OpenView = Backbone.View.extend({
this.params.rev = file.rev;
this.params.fileData = null;
this.displayOpenFile();
},
}
showConfig(storage) {
if (this.busy) {
@ -817,7 +825,7 @@ const OpenView = Backbone.View.extend({
this.views.openConfig.render();
this.$el.find('.open__pass-area').addClass('hide');
this.$el.find('.open__icons--lower').addClass('hide');
},
}
closeConfig() {
if (this.busy) {
@ -831,7 +839,7 @@ const OpenView = Backbone.View.extend({
this.$el.find('.open__pass-area').removeClass('hide');
this.$el.find('.open__config').addClass('hide');
this.focusInput();
},
}
applyConfig(config) {
if (this.busy || !config) {
@ -854,7 +862,7 @@ const OpenView = Backbone.View.extend({
} else {
storage.stat(path, opts, this.storageStatComplete.bind(this, req));
}
},
}
storageApplyConfigComplete(req, err) {
if (this.storageWaitId !== req.waitId) {
@ -868,7 +876,7 @@ const OpenView = Backbone.View.extend({
} else {
this.closeConfig();
}
},
}
storageStatComplete(req, err, stat) {
if (this.storageWaitId !== req.waitId) {
@ -890,7 +898,7 @@ const OpenView = Backbone.View.extend({
this.params.fileData = null;
this.displayOpenFile();
}
},
}
moveOpenFileSelection(steps) {
const lastOpenFiles = this.getLastOpenFiles();
@ -911,15 +919,15 @@ const OpenView = Backbone.View.extend({
if (fileInfo && Launcher && Launcher.fingerprints) {
this.openFileWithFingerprint(fileInfo);
}
},
}
moveOpenFileSelectionDown() {
this.moveOpenFileSelection(1);
},
}
moveOpenFileSelectionUp() {
this.moveOpenFileSelection(-1);
}
});
}
export { OpenView };