fix: prevent a backbone fieldview race condition that can delete user input (#25950)
* prevent a backbone fieldview race condition that can delete user input eslint for effected * Fixing quality * Allow _super in fields.js * Fixing new issues * Revert some changes * Fixing errors, formatting * Fix bug * Fix eslint rule allowing _super * Refactor code Co-authored-by: Dylan Grafmyre <dylan@opencraft.com> Co-authored-by: Paulo Viadanna <paulo@opencraft.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
(function(define, undefined) {
|
||||
/* eslint no-underscore-dangle: ["error", { "allow": ["_super"] }] */
|
||||
(function(define, undef) {
|
||||
'use strict';
|
||||
define([
|
||||
'gettext', 'jquery', 'underscore', 'backbone',
|
||||
@@ -25,7 +26,7 @@
|
||||
fieldType: 'generic',
|
||||
|
||||
className: function() {
|
||||
return 'u-field' + ' u-field-' + this.fieldType + ' u-field-' + this.options.valueAttribute;
|
||||
return 'u-field u-field-' + this.fieldType + ' u-field-' + this.options.valueAttribute;
|
||||
},
|
||||
|
||||
tagName: 'div',
|
||||
@@ -100,21 +101,22 @@
|
||||
return HtmlUtils.setHtml(this.$('.u-field-title'), title);
|
||||
},
|
||||
|
||||
getMessage: function(message_status) {
|
||||
if ((message_status + 'Message') in this) {
|
||||
return this[message_status + 'Message'].call(this);
|
||||
getMessage: function(messageStatus) {
|
||||
if ((messageStatus + 'Message') in this) {
|
||||
return this[messageStatus + 'Message'].call(this);
|
||||
} else if (this.showMessages) {
|
||||
return HtmlUtils.joinHtml(this.indicators[message_status], this.messages[message_status]);
|
||||
return HtmlUtils.joinHtml(this.indicators[messageStatus], this.messages[messageStatus]);
|
||||
}
|
||||
return this.indicators[message_status];
|
||||
return this.indicators[messageStatus];
|
||||
},
|
||||
|
||||
showHelpMessage: function(message) {
|
||||
var msg = message;
|
||||
if (_.isUndefined(message) || _.isNull(message)) {
|
||||
message = this.helpMessage;
|
||||
msg = this.helpMessage;
|
||||
}
|
||||
this.$('.u-field-message-notification').html('');
|
||||
HtmlUtils.setHtml(this.$('.u-field-message-help'), message);
|
||||
HtmlUtils.setHtml(this.$('.u-field-message-help'), msg);
|
||||
},
|
||||
|
||||
getNotificationMessage: function() {
|
||||
@@ -139,19 +141,19 @@
|
||||
},
|
||||
|
||||
showSuccessMessage: function() {
|
||||
var successMessage = this.getMessage('success');
|
||||
var context = Date.now(),
|
||||
successMessage = this.getMessage('success'),
|
||||
view = this;
|
||||
|
||||
this.showNotificationMessage(successMessage);
|
||||
|
||||
if (this.options.refreshPageOnSave) {
|
||||
if ("focusNextID" in this.options) {
|
||||
$.cookie('focus_id', this.options.focusNextID );
|
||||
if ('focusNextID' in this.options) {
|
||||
$.cookie('focus_id', this.options.focusNextID);
|
||||
}
|
||||
location.reload(true);
|
||||
}
|
||||
|
||||
var view = this;
|
||||
|
||||
var context = Date.now();
|
||||
this.lastSuccessMessageContext = context;
|
||||
|
||||
setTimeout(function() {
|
||||
@@ -167,11 +169,14 @@
|
||||
},
|
||||
|
||||
showErrorMessage: function(xhr) {
|
||||
var errors,
|
||||
validationErrorMessage,
|
||||
message;
|
||||
if (xhr.status === 400) {
|
||||
try {
|
||||
var errors = JSON.parse(xhr.responseText),
|
||||
validationErrorMessage = errors.field_errors[this.options.valueAttribute].user_message,
|
||||
message = HtmlUtils.joinHtml(this.indicators.validationError, validationErrorMessage);
|
||||
errors = JSON.parse(xhr.responseText);
|
||||
validationErrorMessage = errors.field_errors[this.options.valueAttribute].user_message;
|
||||
message = HtmlUtils.joinHtml(this.indicators.validationError, validationErrorMessage);
|
||||
this.showNotificationMessage(message);
|
||||
} catch (error) {
|
||||
this.showNotificationMessage(this.getMessage('error'));
|
||||
@@ -202,19 +207,19 @@
|
||||
},
|
||||
|
||||
saveAttributes: function(attributes, options) {
|
||||
var view = this;
|
||||
var defaultOptions = {
|
||||
contentType: 'application/merge-patch+json',
|
||||
patch: true,
|
||||
wait: true,
|
||||
success: function() {
|
||||
view.saveSucceeded();
|
||||
},
|
||||
error: function(model, xhr) {
|
||||
view.showErrorMessage(xhr);
|
||||
}
|
||||
};
|
||||
if (this.persistChanges === true) {
|
||||
var view = this;
|
||||
var defaultOptions = {
|
||||
contentType: 'application/merge-patch+json',
|
||||
patch: true,
|
||||
wait: true,
|
||||
success: function() {
|
||||
view.saveSucceeded();
|
||||
},
|
||||
error: function(model, xhr) {
|
||||
view.showErrorMessage(xhr);
|
||||
}
|
||||
};
|
||||
this.showInProgressMessage();
|
||||
this.model.save(attributes, _.extend(defaultOptions, options));
|
||||
}
|
||||
@@ -383,7 +388,12 @@
|
||||
|
||||
updateValueInField: function() {
|
||||
var value = (_.isUndefined(this.modelValue()) || _.isNull(this.modelValue())) ? '' : this.modelValue();
|
||||
this.$('.u-field-value input').val(value);
|
||||
|
||||
var fieldHasFocus = (document.activeElement === this.$('.u-field-value input')[0]);
|
||||
var fieldChanged = this.fieldValue() !== value;
|
||||
if (!fieldHasFocus || !fieldChanged) {
|
||||
this.$('.u-field-value input').val(value);
|
||||
}
|
||||
},
|
||||
|
||||
saveValue: function() {
|
||||
@@ -419,7 +429,7 @@
|
||||
editable: this.editable,
|
||||
title: this.options.title,
|
||||
screenReaderTitle: this.options.screenReaderTitle || this.options.title,
|
||||
titleVisible: this.options.titleVisible !== undefined ? this.options.titleVisible : true,
|
||||
titleVisible: this.options.titleVisible !== undef ? this.options.titleVisible : true,
|
||||
iconName: this.options.iconName,
|
||||
showBlankOption: (!this.options.required || !this.modelValueIsSet()),
|
||||
groupOptions: this.createGroupOptions(),
|
||||
@@ -468,8 +478,9 @@
|
||||
},
|
||||
|
||||
displayValue: function(value) {
|
||||
var option;
|
||||
if (value) {
|
||||
var option = this.optionForValue(value);
|
||||
option = this.optionForValue(value);
|
||||
return (option ? option[1] : '');
|
||||
} else {
|
||||
return '';
|
||||
@@ -477,11 +488,19 @@
|
||||
},
|
||||
|
||||
updateValueInField: function() {
|
||||
var value; // str
|
||||
var fieldHasFocus; // bool
|
||||
var fieldChanged; // bool
|
||||
if (this.editable !== 'never') {
|
||||
this.$('.u-field-value select').val(this.modelValue() || '');
|
||||
value = this.modelValue() || '';
|
||||
fieldHasFocus = (document.activeElement === this.$('.u-field-value select')[0]);
|
||||
fieldChanged = this.fieldValue() !== value;
|
||||
if (!fieldHasFocus || !fieldChanged) {
|
||||
this.$('.u-field-value select').val(value);
|
||||
}
|
||||
}
|
||||
|
||||
var value = this.displayValue(this.modelValue() || '');
|
||||
value = this.displayValue(this.modelValue() || '');
|
||||
if (this.modelValueIsSet() === false) {
|
||||
value = this.options.placeholderValue || '';
|
||||
}
|
||||
@@ -613,24 +632,21 @@
|
||||
'aria-live': 'assertive',
|
||||
'aria-atomic': true
|
||||
});
|
||||
}
|
||||
else if (remainingCharCount < 60) {
|
||||
} else if (remainingCharCount < 60) {
|
||||
$charCount.attr('aria-atomic', 'false');
|
||||
}
|
||||
else if (remainingCharCount < 70) {
|
||||
} else if (remainingCharCount < 70) {
|
||||
$charCount.attr({
|
||||
'aria-live': 'polite',
|
||||
'aria-atomic': true
|
||||
});
|
||||
}
|
||||
$charCount.text(curCharCount);
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
adjustTextareaHeight: function() {
|
||||
if (this.persistChanges === false) { return; }
|
||||
var textarea = this.$('textarea');
|
||||
if (this.persistChanges === false) { return; }
|
||||
textarea.css('height', 'auto').css('height', textarea.prop('scrollHeight') + 10);
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user