keeweb/app/scripts/views/fields/field-view.js

169 lines
5.3 KiB
JavaScript
Raw Normal View History

2017-01-31 07:50:28 +01:00
const Backbone = require('backbone');
const CopyPaste = require('../../comp/copy-paste');
const Tip = require('../../util/tip');
2015-10-17 23:49:24 +02:00
2017-01-31 07:50:28 +01:00
const FieldView = Backbone.View.extend({
2015-12-16 22:50:45 +01:00
template: require('templates/details/field.hbs'),
2015-10-17 23:49:24 +02:00
events: {
'click .details__field-label': 'fieldLabelClick',
'click .details__field-value': 'fieldValueClick',
'dragstart .details__field-label': 'fieldLabelDrag'
2015-10-17 23:49:24 +02:00
},
2016-06-04 14:47:56 +02:00
render: function() {
2015-10-17 23:49:24 +02:00
this.value = typeof this.model.value === 'function' ? this.model.value() : this.model.value;
2019-08-16 23:05:39 +02:00
this.renderTemplate({
editable: !this.readonly,
multiline: this.model.multiline,
title: this.model.title,
canEditTitle: this.model.newField,
protect: this.value && this.value.isProtected
});
2015-10-17 23:49:24 +02:00
this.valueEl = this.$el.find('.details__field-value');
this.valueEl.html(this.renderValue(this.value));
this.labelEl = this.$el.find('.details__field-label');
2016-06-04 14:47:56 +02:00
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);
}
}
2015-10-17 23:49:24 +02:00
return this;
},
2016-06-04 14:47:56 +02:00
remove: function() {
if (this.tip) {
2017-04-16 10:19:46 +02:00
Tip.hideTip(this.valueEl[0]);
2016-06-04 14:47:56 +02:00
}
Backbone.View.prototype.remove.apply(this, arguments);
},
2015-10-17 23:49:24 +02:00
update: function() {
if (typeof this.model.value === 'function') {
2017-01-31 07:50:28 +01:00
const newVal = this.model.value();
2019-08-16 23:05:39 +02:00
if (
!_.isEqual(newVal, this.value) ||
(this.value && newVal && this.value.toString() !== newVal.toString())
) {
2015-10-17 23:49:24 +02:00
this.render();
}
}
},
fieldLabelClick: function(e) {
e.stopImmediatePropagation();
2017-04-16 12:15:53 +02:00
if (this.preventCopy) {
return;
}
2017-01-31 07:50:28 +01:00
const field = this.model.name;
let copyRes;
2015-10-17 23:49:24 +02:00
if (field) {
2017-01-31 07:50:28 +01:00
const value = this.value || '';
2016-01-16 15:19:33 +01:00
if (value && value.isProtected) {
2017-01-31 07:50:28 +01:00
const text = value.getText();
if (!text) {
return;
}
2016-01-22 18:51:36 +01:00
if (!CopyPaste.simpleCopy) {
CopyPaste.createHiddenInput(text);
}
copyRes = CopyPaste.copy(text);
this.trigger('copy', { source: this, copyRes: copyRes });
2015-10-17 23:49:24 +02:00
return;
}
}
if (!this.value) {
return;
}
2017-01-31 07:50:28 +01:00
const selection = window.getSelection();
const range = document.createRange();
2015-10-17 23:49:24 +02:00
range.selectNodeContents(this.valueEl[0]);
selection.removeAllRanges();
selection.addRange(range);
copyRes = CopyPaste.copy(this.valueEl[0].innerText || this.valueEl.text());
if (copyRes) {
2015-10-17 23:49:24 +02:00
selection.removeAllRanges();
this.trigger('copy', { source: this, copyRes: copyRes });
2015-10-17 23:49:24 +02:00
}
},
fieldValueClick: function(e) {
if (['a', 'input', 'textarea'].indexOf(e.target.tagName.toLowerCase()) >= 0) {
return;
}
2017-01-31 07:50:28 +01:00
const sel = window.getSelection().toString();
2015-10-17 23:49:24 +02:00
if (!sel) {
this.edit();
}
},
fieldLabelDrag: function(e) {
e.stopPropagation();
if (!this.value) {
return;
}
const dt = e.originalEvent.dataTransfer;
const txtval = this.value.isProtected ? this.value.getText() : this.value;
if (this.valueEl[0].tagName.toLowerCase() === 'a') {
dt.setData('text/uri-list', txtval);
}
dt.setData('text/plain', txtval);
dt.effectAllowed = 'copy';
},
2015-10-17 23:49:24 +02:00
edit: function() {
if (this.readonly || this.editing) {
return;
}
this.$el.addClass('details__field--edit');
this.startEdit();
this.editing = true;
2017-04-16 12:15:53 +02:00
this.preventCopy = true;
this.labelEl[0].setAttribute('draggable', 'false');
2015-10-17 23:49:24 +02:00
},
endEdit: function(newVal, extra) {
if (!this.editing) {
return;
}
this.editing = false;
2019-08-16 23:05:39 +02:00
setTimeout(() => {
this.preventCopy = false;
}, 300);
2017-01-31 07:50:28 +01:00
let textEqual;
2016-01-17 14:12:35 +01:00
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);
}
2017-01-31 07:50:28 +01:00
const protectedEqual = (newVal && newVal.isProtected) === (this.value && this.value.isProtected);
const nameChanged = extra && extra.newField;
let arg;
2016-01-16 13:35:34 +01:00
if (newVal !== undefined && (!textEqual || !protectedEqual || nameChanged)) {
2015-10-17 23:49:24 +02:00
arg = { val: newVal, field: this.model.name };
if (extra) {
_.extend(arg, extra);
}
} else if (extra) {
arg = extra;
}
if (arg) {
2016-06-05 16:49:00 +02:00
this.triggerChange(arg);
2015-10-17 23:49:24 +02:00
}
this.valueEl.html(this.renderValue(this.value));
this.$el.removeClass('details__field--edit');
this.labelEl[0].setAttribute('draggable', 'true');
2016-06-05 16:49:00 +02:00
},
triggerChange: function(arg) {
arg.sender = this;
this.trigger('change', arg);
2015-10-17 23:49:24 +02:00
}
});
module.exports = FieldView;