mirror of https://github.com/keeweb/keeweb.git
152 lines
5.0 KiB
JavaScript
152 lines
5.0 KiB
JavaScript
'use strict';
|
|
|
|
var Backbone = require('backbone'),
|
|
FeatureDetector = require('../../util/feature-detector'),
|
|
CopyPaste = require('../../comp/copy-paste'),
|
|
Tip = require('../../util/tip');
|
|
|
|
var FieldView = Backbone.View.extend({
|
|
template: require('templates/details/field.hbs'),
|
|
|
|
events: {
|
|
'click .details__field-label': 'fieldLabelClick',
|
|
'click .details__field-value': 'fieldValueClick'
|
|
},
|
|
|
|
render: function() {
|
|
this.value = typeof this.model.value === 'function' ? this.model.value() : this.model.value;
|
|
this.renderTemplate({ editable: !this.readonly, multiline: this.model.multiline, title: this.model.title,
|
|
canEditTitle: this.model.newField, protect: this.value && this.value.isProtected });
|
|
this.valueEl = this.$el.find('.details__field-value');
|
|
this.valueEl.html(this.renderValue(this.value));
|
|
this.labelEl = this.$el.find('.details__field-label');
|
|
if (this.model.tip) {
|
|
this.tip = typeof this.model.tip === 'function' ? this.model.tip() : this.model.tip;
|
|
if (this.tip) {
|
|
this.valueEl.attr('title', this.tip);
|
|
Tip.createTip(this.valueEl);
|
|
}
|
|
}
|
|
return this;
|
|
},
|
|
|
|
remove: function() {
|
|
if (this.tip) {
|
|
Tip.hideTip(this.valueEl);
|
|
}
|
|
Backbone.View.prototype.remove.apply(this, arguments);
|
|
},
|
|
|
|
update: function() {
|
|
if (typeof this.model.value === 'function') {
|
|
var newVal = this.model.value();
|
|
if (!_.isEqual(newVal, this.value) || (this.value && newVal && this.value.toString() !== newVal.toString())) {
|
|
this.render();
|
|
}
|
|
}
|
|
},
|
|
|
|
fieldLabelClick: function(e) {
|
|
e.stopImmediatePropagation();
|
|
var field = this.model.name;
|
|
if (FeatureDetector.shouldMoveHiddenInputToCopySource()) {
|
|
var box = this.valueEl[0].getBoundingClientRect();
|
|
var textValue = this.value && this.value.isProtected ? this.value.getText() : this.getEditValue(this.value);
|
|
if (!textValue) {
|
|
return;
|
|
}
|
|
CopyPaste.createHiddenInput(textValue, box);
|
|
// CopyPaste.copy(); // maybe Apple will ever support this?
|
|
return;
|
|
}
|
|
var copyRes;
|
|
if (field) {
|
|
var value = this.value || '';
|
|
if (value && value.isProtected) {
|
|
var text = value.getText();
|
|
if (!text) {
|
|
return;
|
|
}
|
|
if (!CopyPaste.simpleCopy) {
|
|
CopyPaste.createHiddenInput(text);
|
|
}
|
|
copyRes = CopyPaste.copy(text);
|
|
if (copyRes) {
|
|
this.trigger('copy', { source: this, copyRes: copyRes });
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
if (!this.value) {
|
|
return;
|
|
}
|
|
var selection = window.getSelection();
|
|
var range = document.createRange();
|
|
range.selectNodeContents(this.valueEl[0]);
|
|
selection.removeAllRanges();
|
|
selection.addRange(range);
|
|
copyRes = CopyPaste.copy(this.valueEl[0].innerText || this.valueEl.text());
|
|
if (copyRes) {
|
|
selection.removeAllRanges();
|
|
this.trigger('copy', { source: this, copyRes: copyRes });
|
|
}
|
|
},
|
|
|
|
fieldValueClick: function(e) {
|
|
if (['a', 'input', 'textarea'].indexOf(e.target.tagName.toLowerCase()) >= 0) {
|
|
return;
|
|
}
|
|
var sel = window.getSelection().toString();
|
|
if (!sel) {
|
|
this.edit();
|
|
}
|
|
},
|
|
|
|
edit: function() {
|
|
if (this.readonly || this.editing) {
|
|
return;
|
|
}
|
|
this.$el.addClass('details__field--edit');
|
|
this.startEdit();
|
|
this.editing = true;
|
|
},
|
|
|
|
endEdit: function(newVal, extra) {
|
|
if (!this.editing) {
|
|
return;
|
|
}
|
|
this.editing = false;
|
|
var textEqual;
|
|
if (this.value && this.value.isProtected) {
|
|
textEqual = this.value.equals(newVal);
|
|
} else if (newVal && newVal.isProtected) {
|
|
textEqual = newVal.equals(this.value);
|
|
} else {
|
|
textEqual = _.isEqual(this.value, newVal);
|
|
}
|
|
var protectedEqual = (newVal && newVal.isProtected) === (this.value && this.value.isProtected);
|
|
var nameChanged = extra && extra.newField;
|
|
var arg;
|
|
if (newVal !== undefined && (!textEqual || !protectedEqual || nameChanged)) {
|
|
arg = { val: newVal, field: this.model.name };
|
|
if (extra) {
|
|
_.extend(arg, extra);
|
|
}
|
|
} else if (extra) {
|
|
arg = extra;
|
|
}
|
|
if (arg) {
|
|
this.triggerChange(arg);
|
|
}
|
|
this.valueEl.html(this.renderValue(this.value));
|
|
this.$el.removeClass('details__field--edit');
|
|
},
|
|
|
|
triggerChange: function(arg) {
|
|
arg.sender = this;
|
|
this.trigger('change', arg);
|
|
}
|
|
});
|
|
|
|
module.exports = FieldView;
|