mirror of
https://github.com/keeweb/keeweb.git
synced 2024-06-26 07:39:04 +02:00
details view
This commit is contained in:
parent
813ed6d541
commit
ccace95a6c
|
@ -16,7 +16,7 @@ class View extends EventEmitter {
|
||||||
boundEvents = [];
|
boundEvents = [];
|
||||||
debugLogger = localStorage.debugViews ? new Logger('view', this.constructor.name) : undefined;
|
debugLogger = localStorage.debugViews ? new Logger('view', this.constructor.name) : undefined;
|
||||||
|
|
||||||
constructor(model, options = {}) {
|
constructor(model = undefined, options = {}) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.model = model;
|
this.model = model;
|
||||||
|
|
|
@ -50,7 +50,7 @@ class AppView extends View {
|
||||||
this.views.list = new ListView(this.model, { ownParent: true });
|
this.views.list = new ListView(this.model, { ownParent: true });
|
||||||
this.views.listDrag = new DragView('x', { parent: '.app__list-drag' });
|
this.views.listDrag = new DragView('x', { parent: '.app__list-drag' });
|
||||||
this.views.list.dragView = this.views.listDrag;
|
this.views.list.dragView = this.views.listDrag;
|
||||||
this.views.details = new DetailsView();
|
this.views.details = new DetailsView(undefined, { ownParent: true });
|
||||||
this.views.details.appModel = this.model;
|
this.views.details.appModel = this.model;
|
||||||
|
|
||||||
this.views.menu.listenDrag(this.views.menuDrag);
|
this.views.menu.listenDrag(this.views.menuDrag);
|
||||||
|
@ -146,7 +146,7 @@ class AppView extends View {
|
||||||
this.views.footer.render();
|
this.views.footer.render();
|
||||||
this.views.list.render();
|
this.views.list.render();
|
||||||
this.views.listDrag.render();
|
this.views.listDrag.render();
|
||||||
this.views.details.setElement(this.$el.find('.app__details')).render();
|
this.views.details.render();
|
||||||
this.showLastOpenFile();
|
this.showLastOpenFile();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { AutoType } from 'auto-type';
|
|
||||||
import Backbone from 'backbone';
|
import Backbone from 'backbone';
|
||||||
import kdbxweb from 'kdbxweb';
|
import kdbxweb from 'kdbxweb';
|
||||||
|
import { View } from 'view-engine/view';
|
||||||
|
import { AutoType } from 'auto-type';
|
||||||
import { CopyPaste } from 'comp/browser/copy-paste';
|
import { CopyPaste } from 'comp/browser/copy-paste';
|
||||||
import { KeyHandler } from 'comp/browser/key-handler';
|
import { KeyHandler } from 'comp/browser/key-handler';
|
||||||
import { OtpQrReader } from 'comp/format/otp-qr-reader';
|
import { OtpQrReader } from 'comp/format/otp-qr-reader';
|
||||||
|
@ -33,20 +34,19 @@ import { FieldViewTags } from 'views/fields/field-view-tags';
|
||||||
import { FieldViewText } from 'views/fields/field-view-text';
|
import { FieldViewText } from 'views/fields/field-view-text';
|
||||||
import { FieldViewUrl } from 'views/fields/field-view-url';
|
import { FieldViewUrl } from 'views/fields/field-view-url';
|
||||||
import { IconSelectView } from 'views/icon-select-view';
|
import { IconSelectView } from 'views/icon-select-view';
|
||||||
|
import template from 'templates/details/details.hbs';
|
||||||
|
import emptyTemplate from 'templates/details/details-empty.hbs';
|
||||||
|
import groupTemplate from 'templates/details/details-group.hbs';
|
||||||
|
|
||||||
const DetailsView = Backbone.View.extend({
|
class DetailsView extends View {
|
||||||
template: require('templates/details/details.hbs'),
|
parent = '.app__details';
|
||||||
emptyTemplate: require('templates/details/details-empty.hbs'),
|
fieldViews = null;
|
||||||
groupTemplate: require('templates/details/details-group.hbs'),
|
passEditView = null;
|
||||||
|
userEditView = null;
|
||||||
|
urlEditView = null;
|
||||||
|
fieldCopyTip = null;
|
||||||
|
|
||||||
fieldViews: null,
|
events = {
|
||||||
views: null,
|
|
||||||
passEditView: null,
|
|
||||||
userEditView: null,
|
|
||||||
urlEditView: null,
|
|
||||||
fieldCopyTip: null,
|
|
||||||
|
|
||||||
events: {
|
|
||||||
'click .details__colors-popup-item': 'selectColor',
|
'click .details__colors-popup-item': 'selectColor',
|
||||||
'click .details__header-icon': 'toggleIcons',
|
'click .details__header-icon': 'toggleIcons',
|
||||||
'click .details__attachment': 'toggleAttachment',
|
'click .details__attachment': 'toggleAttachment',
|
||||||
|
@ -61,11 +61,11 @@ const DetailsView = Backbone.View.extend({
|
||||||
'dragleave .details': 'dragleave',
|
'dragleave .details': 'dragleave',
|
||||||
'drop .details': 'drop',
|
'drop .details': 'drop',
|
||||||
'contextmenu .details': 'contextMenu'
|
'contextmenu .details': 'contextMenu'
|
||||||
},
|
};
|
||||||
|
|
||||||
initialize() {
|
constructor(model, options) {
|
||||||
|
super(model, options);
|
||||||
this.fieldViews = [];
|
this.fieldViews = [];
|
||||||
this.views = {};
|
|
||||||
this.initScroll();
|
this.initScroll();
|
||||||
this.listenTo(Backbone, 'entry-selected', this.showEntry);
|
this.listenTo(Backbone, 'entry-selected', this.showEntry);
|
||||||
this.listenTo(Backbone, 'copy-password', this.copyPassword);
|
this.listenTo(Backbone, 'copy-password', this.copyPassword);
|
||||||
|
@ -76,62 +76,42 @@ const DetailsView = Backbone.View.extend({
|
||||||
this.listenTo(Backbone, 'set-locale', this.render);
|
this.listenTo(Backbone, 'set-locale', this.render);
|
||||||
this.listenTo(OtpQrReader, 'qr-read', this.otpCodeRead);
|
this.listenTo(OtpQrReader, 'qr-read', this.otpCodeRead);
|
||||||
this.listenTo(OtpQrReader, 'enter-manually', this.otpEnterManually);
|
this.listenTo(OtpQrReader, 'enter-manually', this.otpEnterManually);
|
||||||
KeyHandler.onKey(
|
this.onKey(
|
||||||
Keys.DOM_VK_C,
|
Keys.DOM_VK_C,
|
||||||
this.copyPasswordFromShortcut,
|
this.copyPasswordFromShortcut,
|
||||||
this,
|
|
||||||
KeyHandler.SHORTCUT_ACTION,
|
KeyHandler.SHORTCUT_ACTION,
|
||||||
false,
|
false,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
KeyHandler.onKey(Keys.DOM_VK_B, this.copyUserName, this, KeyHandler.SHORTCUT_ACTION);
|
this.onKey(Keys.DOM_VK_B, this.copyUserName, KeyHandler.SHORTCUT_ACTION);
|
||||||
KeyHandler.onKey(Keys.DOM_VK_U, this.copyUrl, this, KeyHandler.SHORTCUT_ACTION);
|
this.onKey(Keys.DOM_VK_U, this.copyUrl, KeyHandler.SHORTCUT_ACTION);
|
||||||
if (AutoType.enabled) {
|
if (AutoType.enabled) {
|
||||||
KeyHandler.onKey(Keys.DOM_VK_T, this.autoType, this, KeyHandler.SHORTCUT_ACTION);
|
this.onKey(Keys.DOM_VK_T, this.autoType, KeyHandler.SHORTCUT_ACTION);
|
||||||
}
|
}
|
||||||
KeyHandler.onKey(
|
this.onKey(
|
||||||
Keys.DOM_VK_DELETE,
|
Keys.DOM_VK_DELETE,
|
||||||
this.deleteKeyPress,
|
this.deleteKeyPress,
|
||||||
this,
|
|
||||||
KeyHandler.SHORTCUT_ACTION,
|
KeyHandler.SHORTCUT_ACTION,
|
||||||
false,
|
false,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
KeyHandler.onKey(
|
this.onKey(
|
||||||
Keys.DOM_VK_BACK_SPACE,
|
Keys.DOM_VK_BACK_SPACE,
|
||||||
this.deleteKeyPress,
|
this.deleteKeyPress,
|
||||||
this,
|
|
||||||
KeyHandler.SHORTCUT_ACTION,
|
KeyHandler.SHORTCUT_ACTION,
|
||||||
false,
|
false,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
},
|
this.once('remove', () => {
|
||||||
|
this.removeFieldViews();
|
||||||
remove() {
|
});
|
||||||
KeyHandler.offKey(Keys.DOM_VK_C, this.copyPassword, this);
|
}
|
||||||
KeyHandler.offKey(Keys.DOM_VK_B, this.copyUserName, this);
|
|
||||||
KeyHandler.offKey(Keys.DOM_VK_U, this.copyUrl, this);
|
|
||||||
KeyHandler.offKey(
|
|
||||||
Keys.DOM_VK_DELETE,
|
|
||||||
this.deleteKeyPress,
|
|
||||||
this,
|
|
||||||
KeyHandler.SHORTCUT_ACTION
|
|
||||||
);
|
|
||||||
KeyHandler.offKey(
|
|
||||||
Keys.DOM_VK_BACK_SPACE,
|
|
||||||
this.deleteKeyPress,
|
|
||||||
this,
|
|
||||||
KeyHandler.SHORTCUT_ACTION
|
|
||||||
);
|
|
||||||
this.removeFieldViews();
|
|
||||||
Backbone.View.prototype.remove.call(this);
|
|
||||||
},
|
|
||||||
|
|
||||||
removeFieldViews() {
|
removeFieldViews() {
|
||||||
this.fieldViews.forEach(fieldView => fieldView.remove());
|
this.fieldViews.forEach(fieldView => fieldView.remove());
|
||||||
this.fieldViews = [];
|
this.fieldViews = [];
|
||||||
this.hideFieldCopyTip();
|
this.hideFieldCopyTip();
|
||||||
},
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
Tip.destroyTips(this.$el);
|
Tip.destroyTips(this.$el);
|
||||||
|
@ -139,17 +119,18 @@ const DetailsView = Backbone.View.extend({
|
||||||
this.removeFieldViews();
|
this.removeFieldViews();
|
||||||
this.removeInnerViews();
|
this.removeInnerViews();
|
||||||
if (!this.model) {
|
if (!this.model) {
|
||||||
this.$el.html(this.emptyTemplate());
|
this.template = emptyTemplate;
|
||||||
|
super.render();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.model instanceof GroupModel) {
|
if (this.model instanceof GroupModel) {
|
||||||
this.$el.html(this.groupTemplate());
|
this.template = groupTemplate;
|
||||||
Tip.createTips(this.$el);
|
super.render();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const model = $.extend({ deleted: this.appModel.filter.trash }, this.model);
|
const model = Object.assign({ deleted: this.appModel.filter.trash }, this.model);
|
||||||
this.$el.html(this.template(model));
|
this.template = template;
|
||||||
Tip.createTips(this.$el);
|
super.render(model);
|
||||||
this.setSelectedColor(this.model.color);
|
this.setSelectedColor(this.model.color);
|
||||||
this.model.initOtpGenerator();
|
this.model.initOtpGenerator();
|
||||||
this.addFieldViews();
|
this.addFieldViews();
|
||||||
|
@ -166,7 +147,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
this.pageResized();
|
this.pageResized();
|
||||||
this.showCopyTip();
|
this.showCopyTip();
|
||||||
return this;
|
return this;
|
||||||
},
|
}
|
||||||
|
|
||||||
addFieldViews() {
|
addFieldViews() {
|
||||||
const model = this.model;
|
const model = this.model;
|
||||||
|
@ -313,44 +294,40 @@ const DetailsView = Backbone.View.extend({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
_.forEach(
|
_.forEach(model.fields, (value, field) => {
|
||||||
model.fields,
|
if (field === 'otp' && this.model.otpGenerator) {
|
||||||
function(value, field) {
|
this.fieldViews.push(
|
||||||
if (field === 'otp' && this.model.otpGenerator) {
|
new FieldViewOtp({
|
||||||
this.fieldViews.push(
|
model: {
|
||||||
new FieldViewOtp({
|
name: '$' + field,
|
||||||
model: {
|
title: field,
|
||||||
name: '$' + field,
|
value() {
|
||||||
title: field,
|
return model.otpGenerator;
|
||||||
value() {
|
|
||||||
return model.otpGenerator;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
);
|
})
|
||||||
} else {
|
);
|
||||||
this.fieldViews.push(
|
} else {
|
||||||
new FieldViewCustom({
|
this.fieldViews.push(
|
||||||
model: {
|
new FieldViewCustom({
|
||||||
name: '$' + field,
|
model: {
|
||||||
title: field,
|
name: '$' + field,
|
||||||
multiline: true,
|
title: field,
|
||||||
value() {
|
multiline: true,
|
||||||
return model.fields[field];
|
value() {
|
||||||
}
|
return model.fields[field];
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
);
|
})
|
||||||
}
|
);
|
||||||
},
|
}
|
||||||
this
|
});
|
||||||
);
|
|
||||||
|
|
||||||
const hideEmptyFields = AppSettingsModel.instance.get('hideEmptyFields');
|
const hideEmptyFields = AppSettingsModel.instance.get('hideEmptyFields');
|
||||||
|
|
||||||
const fieldsMainEl = this.$el.find('.details__body-fields');
|
const fieldsMainEl = this.$el.find('.details__body-fields');
|
||||||
const fieldsAsideEl = this.$el.find('.details__body-aside');
|
const fieldsAsideEl = this.$el.find('.details__body-aside');
|
||||||
this.fieldViews.forEach(function(fieldView) {
|
this.fieldViews.forEach(fieldView => {
|
||||||
fieldView.setElement(fieldView.readonly ? fieldsAsideEl : fieldsMainEl).render();
|
fieldView.setElement(fieldView.readonly ? fieldsAsideEl : fieldsMainEl).render();
|
||||||
fieldView.on('change', this.fieldChanged.bind(this));
|
fieldView.on('change', this.fieldChanged.bind(this));
|
||||||
fieldView.on('copy', this.fieldCopied.bind(this));
|
fieldView.on('copy', this.fieldCopied.bind(this));
|
||||||
|
@ -366,13 +343,13 @@ const DetailsView = Backbone.View.extend({
|
||||||
fieldView.hide();
|
fieldView.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, this);
|
});
|
||||||
|
|
||||||
this.moreView = new DetailsAddFieldView();
|
this.moreView = new DetailsAddFieldView();
|
||||||
this.moreView.render();
|
this.moreView.render();
|
||||||
this.moreView.on('add-field', this.addNewField.bind(this));
|
this.moreView.on('add-field', this.addNewField.bind(this));
|
||||||
this.moreView.on('more-click', this.toggleMoreOptions.bind(this));
|
this.moreView.on('more-click', this.toggleMoreOptions.bind(this));
|
||||||
},
|
}
|
||||||
|
|
||||||
addNewField() {
|
addNewField() {
|
||||||
this.moreView.remove();
|
this.moreView.remove();
|
||||||
|
@ -402,7 +379,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
fieldView.setElement(this.$el.find('.details__body-fields')).render();
|
fieldView.setElement(this.$el.find('.details__body-fields')).render();
|
||||||
fieldView.edit();
|
fieldView.edit();
|
||||||
this.fieldViews.push(fieldView);
|
this.fieldViews.push(fieldView);
|
||||||
},
|
}
|
||||||
|
|
||||||
toggleMoreOptions() {
|
toggleMoreOptions() {
|
||||||
if (this.views.dropdownView) {
|
if (this.views.dropdownView) {
|
||||||
|
@ -469,7 +446,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
this.views.dropdownView = dropdownView;
|
this.views.dropdownView = dropdownView;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
moreOptionsSelect(e) {
|
moreOptionsSelect(e) {
|
||||||
this.views.dropdownView.remove();
|
this.views.dropdownView.remove();
|
||||||
|
@ -504,11 +481,11 @@ const DetailsView = Backbone.View.extend({
|
||||||
fieldView.edit();
|
fieldView.edit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
getUserNameCompletions(part) {
|
getUserNameCompletions(part) {
|
||||||
return this.appModel.completeUserNames(part);
|
return this.appModel.completeUserNames(part);
|
||||||
},
|
}
|
||||||
|
|
||||||
setSelectedColor(color) {
|
setSelectedColor(color) {
|
||||||
this.$el
|
this.$el
|
||||||
|
@ -526,7 +503,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
.addClass('details__colors-popup-item--active');
|
.addClass('details__colors-popup-item--active');
|
||||||
colorEl.classList.add(color + '-color');
|
colorEl.classList.add(color + '-color');
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
selectColor(e) {
|
selectColor(e) {
|
||||||
let color = $(e.target)
|
let color = $(e.target)
|
||||||
|
@ -540,7 +517,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
}
|
}
|
||||||
this.model.setColor(color);
|
this.model.setColor(color);
|
||||||
this.entryUpdated();
|
this.entryUpdated();
|
||||||
},
|
}
|
||||||
|
|
||||||
toggleIcons() {
|
toggleIcons() {
|
||||||
if (this.views.sub && this.views.sub instanceof IconSelectView) {
|
if (this.views.sub && this.views.sub instanceof IconSelectView) {
|
||||||
|
@ -563,7 +540,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
subView.render();
|
subView.render();
|
||||||
this.pageResized();
|
this.pageResized();
|
||||||
this.views.sub = subView;
|
this.views.sub = subView;
|
||||||
},
|
}
|
||||||
|
|
||||||
toggleAttachment(e) {
|
toggleAttachment(e) {
|
||||||
const attBtn = $(e.target).closest('.details__attachment');
|
const attBtn = $(e.target).closest('.details__attachment');
|
||||||
|
@ -586,7 +563,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
subView.render(this.pageResized.bind(this));
|
subView.render(this.pageResized.bind(this));
|
||||||
this.views.sub = subView;
|
this.views.sub = subView;
|
||||||
attBtn.addClass('details__attachment--active');
|
attBtn.addClass('details__attachment--active');
|
||||||
},
|
}
|
||||||
|
|
||||||
removeSubView() {
|
removeSubView() {
|
||||||
this.$el.find('.details__attachment').removeClass('details__attachment--active');
|
this.$el.find('.details__attachment').removeClass('details__attachment--active');
|
||||||
|
@ -594,7 +571,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
this.views.sub.remove();
|
this.views.sub.remove();
|
||||||
delete this.views.sub;
|
delete this.views.sub;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
downloadAttachment(attachment) {
|
downloadAttachment(attachment) {
|
||||||
const data = attachment.getBinary();
|
const data = attachment.getBinary();
|
||||||
|
@ -604,7 +581,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
const mimeType = attachment.mimeType || 'application/octet-stream';
|
const mimeType = attachment.mimeType || 'application/octet-stream';
|
||||||
const blob = new Blob([data], { type: mimeType });
|
const blob = new Blob([data], { type: mimeType });
|
||||||
FileSaver.saveAs(blob, attachment.title);
|
FileSaver.saveAs(blob, attachment.title);
|
||||||
},
|
}
|
||||||
|
|
||||||
iconSelected(sel) {
|
iconSelected(sel) {
|
||||||
if (sel.custom) {
|
if (sel.custom) {
|
||||||
|
@ -620,7 +597,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
} else {
|
} else {
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
showEntry(entry) {
|
showEntry(entry) {
|
||||||
this.model = entry;
|
this.model = entry;
|
||||||
|
@ -628,7 +605,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
if (entry && !entry.title && entry.isJustCreated) {
|
if (entry && !entry.title && entry.isJustCreated) {
|
||||||
this.editTitle();
|
this.editTitle();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
copyKeyPress(editView) {
|
copyKeyPress(editView) {
|
||||||
if (this.isHidden()) {
|
if (this.isHidden()) {
|
||||||
|
@ -649,26 +626,26 @@ const DetailsView = Backbone.View.extend({
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
}
|
||||||
|
|
||||||
copyPasswordFromShortcut(e) {
|
copyPasswordFromShortcut(e) {
|
||||||
const copied = this.copyKeyPress(this.passEditView);
|
const copied = this.copyKeyPress(this.passEditView);
|
||||||
if (copied) {
|
if (copied) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
copyPassword() {
|
copyPassword() {
|
||||||
this.copyKeyPress(this.passEditView);
|
this.copyKeyPress(this.passEditView);
|
||||||
},
|
}
|
||||||
|
|
||||||
copyUserName() {
|
copyUserName() {
|
||||||
this.copyKeyPress(this.userEditView);
|
this.copyKeyPress(this.userEditView);
|
||||||
},
|
}
|
||||||
|
|
||||||
copyUrl() {
|
copyUrl() {
|
||||||
this.copyKeyPress(this.urlEditView);
|
this.copyKeyPress(this.urlEditView);
|
||||||
},
|
}
|
||||||
|
|
||||||
showCopyTip() {
|
showCopyTip() {
|
||||||
if (this.helpTipCopyShown) {
|
if (this.helpTipCopyShown) {
|
||||||
|
@ -687,11 +664,11 @@ const DetailsView = Backbone.View.extend({
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
tip.hide();
|
tip.hide();
|
||||||
}, Timeouts.AutoHideHint);
|
}, Timeouts.AutoHideHint);
|
||||||
},
|
}
|
||||||
|
|
||||||
settingsToggled() {
|
settingsToggled() {
|
||||||
this.hideFieldCopyTip();
|
this.hideFieldCopyTip();
|
||||||
},
|
}
|
||||||
|
|
||||||
fieldChanged(e) {
|
fieldChanged(e) {
|
||||||
if (e.field) {
|
if (e.field) {
|
||||||
|
@ -755,7 +732,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
if (e.tab) {
|
if (e.tab) {
|
||||||
this.focusNextField(e.tab);
|
this.focusNextField(e.tab);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
otpFieldChanged(value) {
|
otpFieldChanged(value) {
|
||||||
let oldValue = this.model.fields.otp;
|
let oldValue = this.model.fields.otp;
|
||||||
|
@ -771,7 +748,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
}
|
}
|
||||||
this.model.setOtpUrl(value);
|
this.model.setOtpUrl(value);
|
||||||
return true;
|
return true;
|
||||||
},
|
}
|
||||||
|
|
||||||
dragover(e) {
|
dragover(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -792,7 +769,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
this.dragging = true;
|
this.dragging = true;
|
||||||
this.$el.find('.details').addClass('details--drag');
|
this.$el.find('.details').addClass('details--drag');
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
dragleave() {
|
dragleave() {
|
||||||
if (this.dragTimeout) {
|
if (this.dragTimeout) {
|
||||||
|
@ -802,7 +779,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
this.$el.find('.details').removeClass('details--drag');
|
this.$el.find('.details').removeClass('details--drag');
|
||||||
this.dragging = false;
|
this.dragging = false;
|
||||||
}, 100);
|
}, 100);
|
||||||
},
|
}
|
||||||
|
|
||||||
drop(e) {
|
drop(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -816,15 +793,15 @@ const DetailsView = Backbone.View.extend({
|
||||||
this.dragging = false;
|
this.dragging = false;
|
||||||
const files = e.target.files || e.originalEvent.dataTransfer.files;
|
const files = e.target.files || e.originalEvent.dataTransfer.files;
|
||||||
this.addAttachedFiles(files);
|
this.addAttachedFiles(files);
|
||||||
},
|
}
|
||||||
|
|
||||||
attachmentBtnClick() {
|
attachmentBtnClick() {
|
||||||
this.$el.find('.details__attachment-input-file')[0].click();
|
this.$el.find('.details__attachment-input-file')[0].click();
|
||||||
},
|
}
|
||||||
|
|
||||||
attachmentFileChange(e) {
|
attachmentFileChange(e) {
|
||||||
this.addAttachedFiles(e.target.files);
|
this.addAttachedFiles(e.target.files);
|
||||||
},
|
}
|
||||||
|
|
||||||
addAttachedFiles(files) {
|
addAttachedFiles(files) {
|
||||||
_.forEach(
|
_.forEach(
|
||||||
|
@ -838,13 +815,13 @@ const DetailsView = Backbone.View.extend({
|
||||||
},
|
},
|
||||||
this
|
this
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
|
|
||||||
addAttachment(name, data) {
|
addAttachment(name, data) {
|
||||||
this.model.addAttachment(name, data).then(() => {
|
this.model.addAttachment(name, data).then(() => {
|
||||||
this.entryUpdated();
|
this.entryUpdated();
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
|
|
||||||
deleteKeyPress(e) {
|
deleteKeyPress(e) {
|
||||||
if (this.views.sub && this.views.sub.attId !== undefined) {
|
if (this.views.sub && this.views.sub.attId !== undefined) {
|
||||||
|
@ -853,7 +830,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
this.model.removeAttachment(attachment.title);
|
this.model.removeAttachment(attachment.title);
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
editTitle() {
|
editTitle() {
|
||||||
const input = $('<input/>')
|
const input = $('<input/>')
|
||||||
|
@ -868,15 +845,15 @@ const DetailsView = Backbone.View.extend({
|
||||||
});
|
});
|
||||||
$('.details__header-title').replaceWith(input);
|
$('.details__header-title').replaceWith(input);
|
||||||
input.focus()[0].setSelectionRange(this.model.title.length, this.model.title.length);
|
input.focus()[0].setSelectionRange(this.model.title.length, this.model.title.length);
|
||||||
},
|
}
|
||||||
|
|
||||||
titleInputBlur(e) {
|
titleInputBlur(e) {
|
||||||
this.setTitle(e.target.value);
|
this.setTitle(e.target.value);
|
||||||
},
|
}
|
||||||
|
|
||||||
titleInputInput(e) {
|
titleInputInput(e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
},
|
}
|
||||||
|
|
||||||
titleInputKeydown(e) {
|
titleInputKeydown(e) {
|
||||||
KeyHandler.reg();
|
KeyHandler.reg();
|
||||||
|
@ -901,7 +878,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
this.focusNextField({ field: '$Title' });
|
this.focusNextField({ field: '$Title' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
setTitle(title) {
|
setTitle(title) {
|
||||||
if (this.model.title instanceof kdbxweb.ProtectedValue) {
|
if (this.model.title instanceof kdbxweb.ProtectedValue) {
|
||||||
|
@ -913,14 +890,14 @@ const DetailsView = Backbone.View.extend({
|
||||||
}
|
}
|
||||||
const newTitle = $('<h1 class="details__header-title"></h1>').text(title || '(no title)');
|
const newTitle = $('<h1 class="details__header-title"></h1>').text(title || '(no title)');
|
||||||
this.$el.find('.details__header-title-input').replaceWith(newTitle);
|
this.$el.find('.details__header-title-input').replaceWith(newTitle);
|
||||||
},
|
}
|
||||||
|
|
||||||
entryUpdated(skipRender) {
|
entryUpdated(skipRender) {
|
||||||
Backbone.trigger('entry-updated', { entry: this.model });
|
Backbone.trigger('entry-updated', { entry: this.model });
|
||||||
if (!skipRender) {
|
if (!skipRender) {
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
focusNextField(config) {
|
focusNextField(config) {
|
||||||
let found = false,
|
let found = false,
|
||||||
|
@ -943,7 +920,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
if (nextFieldView) {
|
if (nextFieldView) {
|
||||||
nextFieldView.edit();
|
nextFieldView.edit();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
showHistory() {
|
showHistory() {
|
||||||
this.removeSubView();
|
this.removeSubView();
|
||||||
|
@ -955,7 +932,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
subView.render();
|
subView.render();
|
||||||
this.pageResized();
|
this.pageResized();
|
||||||
this.views.sub = subView;
|
this.views.sub = subView;
|
||||||
},
|
}
|
||||||
|
|
||||||
historyClosed(e) {
|
historyClosed(e) {
|
||||||
if (e.updated) {
|
if (e.updated) {
|
||||||
|
@ -963,7 +940,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
} else {
|
} else {
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
moveToTrash() {
|
moveToTrash() {
|
||||||
const doMove = () => {
|
const doMove = () => {
|
||||||
|
@ -980,16 +957,16 @@ const DetailsView = Backbone.View.extend({
|
||||||
} else {
|
} else {
|
||||||
doMove();
|
doMove();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
clone() {
|
clone() {
|
||||||
const newEntry = this.model.cloneEntry(' ' + Locale.detClonedName);
|
const newEntry = this.model.cloneEntry(' ' + Locale.detClonedName);
|
||||||
Backbone.trigger('select-entry', newEntry);
|
Backbone.trigger('select-entry', newEntry);
|
||||||
},
|
}
|
||||||
|
|
||||||
copyToClipboard() {
|
copyToClipboard() {
|
||||||
CopyPaste.copyHtml(this.model.getHtml());
|
CopyPaste.copyHtml(this.model.getHtml());
|
||||||
},
|
}
|
||||||
|
|
||||||
deleteFromTrash() {
|
deleteFromTrash() {
|
||||||
Alerts.yesno({
|
Alerts.yesno({
|
||||||
|
@ -1005,11 +982,11 @@ const DetailsView = Backbone.View.extend({
|
||||||
Backbone.trigger('refresh');
|
Backbone.trigger('refresh');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
|
|
||||||
backClick() {
|
backClick() {
|
||||||
Backbone.trigger('toggle-details', false);
|
Backbone.trigger('toggle-details', false);
|
||||||
},
|
}
|
||||||
|
|
||||||
contextMenu(e) {
|
contextMenu(e) {
|
||||||
const canCopy = document.queryCommandSupported('copy');
|
const canCopy = document.queryCommandSupported('copy');
|
||||||
|
@ -1039,7 +1016,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
options.push({ value: 'det-auto-type', icon: 'keyboard-o', text: Locale.detAutoType });
|
options.push({ value: 'det-auto-type', icon: 'keyboard-o', text: Locale.detAutoType });
|
||||||
}
|
}
|
||||||
Backbone.trigger('show-context-menu', _.extend(e, { options }));
|
Backbone.trigger('show-context-menu', _.extend(e, { options }));
|
||||||
},
|
}
|
||||||
|
|
||||||
contextMenuSelect(e) {
|
contextMenuSelect(e) {
|
||||||
switch (e.item) {
|
switch (e.item) {
|
||||||
|
@ -1062,16 +1039,16 @@ const DetailsView = Backbone.View.extend({
|
||||||
this.copyToClipboard();
|
this.copyToClipboard();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
setupOtp() {
|
setupOtp() {
|
||||||
OtpQrReader.read();
|
OtpQrReader.read();
|
||||||
},
|
}
|
||||||
|
|
||||||
otpCodeRead(otp) {
|
otpCodeRead(otp) {
|
||||||
this.model.setOtp(otp);
|
this.model.setOtp(otp);
|
||||||
this.entryUpdated();
|
this.entryUpdated();
|
||||||
},
|
}
|
||||||
|
|
||||||
otpEnterManually() {
|
otpEnterManually() {
|
||||||
if (this.model.fields.otp) {
|
if (this.model.fields.otp) {
|
||||||
|
@ -1095,7 +1072,7 @@ const DetailsView = Backbone.View.extend({
|
||||||
fieldView.edit();
|
fieldView.edit();
|
||||||
this.fieldViews.push(fieldView);
|
this.fieldViews.push(fieldView);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
toggleAutoType() {
|
toggleAutoType() {
|
||||||
if (this.views.autoType) {
|
if (this.views.autoType) {
|
||||||
|
@ -1105,14 +1082,14 @@ const DetailsView = Backbone.View.extend({
|
||||||
}
|
}
|
||||||
this.views.autoType = new DetailsAutoTypeView(this.model);
|
this.views.autoType = new DetailsAutoTypeView(this.model);
|
||||||
this.views.autoType.render();
|
this.views.autoType.render();
|
||||||
},
|
}
|
||||||
|
|
||||||
autoType() {
|
autoType() {
|
||||||
Backbone.trigger('auto-type', { entry: this.model });
|
Backbone.trigger('auto-type', { entry: this.model });
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
_.extend(DetailsView.prototype, Scrollable);
|
Object.assign(DetailsView.prototype, Scrollable);
|
||||||
_.extend(DetailsView.prototype, Copyable);
|
Object.assign(DetailsView.prototype, Copyable);
|
||||||
|
|
||||||
export { DetailsView };
|
export { DetailsView };
|
||||||
|
|
Loading…
Reference in New Issue
Block a user