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

152 lines
5.0 KiB
JavaScript
Raw Normal View History

2015-10-17 23:49:24 +02:00
'use strict';
var Backbone = require('backbone'),
2015-10-27 22:57:56 +01:00
FeatureDetector = require('../../util/feature-detector'),
2016-06-04 14:47:56 +02:00
CopyPaste = require('../../comp/copy-paste'),
Tip = require('../../util/tip');
2015-10-17 23:49:24 +02:00
var 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'
},
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;
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) {
Tip.hideTip(this.valueEl);
}
Backbone.View.prototype.remove.apply(this, arguments);
},
2015-10-17 23:49:24 +02:00
update: function() {
if (typeof this.model.value === 'function') {
var newVal = this.model.value();
2015-10-18 14:18:53 +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();
var field = this.model.name;
2015-10-27 22:57:56 +01:00
if (FeatureDetector.shouldMoveHiddenInputToCopySource()) {
var box = this.valueEl[0].getBoundingClientRect();
2016-01-16 15:19:33 +01:00
var textValue = this.value && this.value.isProtected ? this.value.getText() : this.getEditValue(this.value);
2015-10-27 22:57:56 +01:00
if (!textValue) {
return;
}
CopyPaste.createHiddenInput(textValue, box);
2016-07-17 13:30:38 +02:00
// CopyPaste.copy(); // maybe Apple will ever support this?
2015-10-27 22:57:56 +01:00
return;
}
var copyRes;
2015-10-17 23:49:24 +02:00
if (field) {
var value = this.value || '';
2016-01-16 15:19:33 +01:00
if (value && value.isProtected) {
2016-01-22 18:51:36 +01:00
var text = value.getText();
if (!text) {
return;
}
2016-01-22 18:51:36 +01:00
if (!CopyPaste.simpleCopy) {
CopyPaste.createHiddenInput(text);
}
copyRes = CopyPaste.copy(text);
if (copyRes) {
this.trigger('copy', { source: this, copyRes: copyRes });
}
2015-10-17 23:49:24 +02:00
return;
}
}
if (!this.value) {
return;
}
2015-10-17 23:49:24 +02:00
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) {
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;
}
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;
2016-01-17 14:12:35 +01:00
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);
}
2016-01-16 15:19:33 +01:00
var protectedEqual = (newVal && newVal.isProtected) === (this.value && this.value.isProtected);
2016-01-16 13:35:34 +01:00
var nameChanged = extra && extra.newField;
2015-10-17 23:49:24 +02:00
var 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');
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;