/**
* @file
* ContentEditable-based in-place editor for plain text content.
*/
(function ($, _, Drupal) {
Drupal.quickedit.editors.plain_text = Drupal.quickedit.EditorView.extend(
/** @lends Drupal.quickedit.editors.plain_text# */ {
/**
* Stores the textual DOM element that is being in-place edited.
*/
$textElement: null,
/**
* @constructs
*
* @augments Drupal.quickedit.EditorView
*
* @param {object} options
* Options for the plain text editor.
*/
initialize(options) {
Drupal.quickedit.EditorView.prototype.initialize.call(this, options);
const editorModel = this.model;
const fieldModel = this.fieldModel;
// Store the original value of this field. Necessary for reverting
// changes.
const $fieldItems = this.$el.find('.quickedit-field');
const $textElement = $fieldItems.length ? $fieldItems.eq(0) : this.$el;
this.$textElement = $textElement;
editorModel.set('originalValue', $.trim(this.$textElement.text()));
// Sets the state to 'changed' whenever the value changes.
let previousText = editorModel.get('originalValue');
$textElement.on('keyup paste', (event) => {
const currentText = $.trim($textElement.text());
if (previousText !== currentText) {
previousText = currentText;
editorModel.set('currentValue', currentText);
fieldModel.set('state', 'changed');
}
});
},
/**
* {@inheritdoc}
*
* @return {jQuery}
* The text element for the plain text editor.
*/
getEditedElement() {
return this.$textElement;
},
/**
* {@inheritdoc}
*
* @param {object} fieldModel
* The field model that holds the state.
* @param {string} state
* The state to change to.
* @param {object} options
* State options, if needed by the state change.
*/
stateChange(fieldModel, state, options) {
const from = fieldModel.previous('state');
const to = state;
switch (to) {
case 'inactive':
break;
case 'candidate':
if (from !== 'inactive') {
this.$textElement.removeAttr('contenteditable');
}
if (from === 'invalid') {
this.removeValidationErrors();
}
break;
case 'highlighted':
break;
case 'activating':
// Defer updating the field model until the current state change has
// propagated, to not trigger a nested state change event.
_.defer(() => {
fieldModel.set('state', 'active');
});
break;
case 'active':
this.$textElement.attr('contenteditable', 'true');
break;
case 'changed':
break;
case 'saving':
if (from === 'invalid') {
this.removeValidationErrors();
}
this.save(options);
break;
case 'saved':
break;
case 'invalid':
this.showValidationErrors();
break;
}
},
/**
* {@inheritdoc}
*
* @return {object}
* A settings object for the quick edit UI.
*/
getQuickEditUISettings() {
return {
padding: true,
unifiedToolbar: false,
fullWidthToolbar: false,
popup: false,
};
},
/**
* {@inheritdoc}
*/
revert() {
this.$textElement.html(this.model.get('originalValue'));
},
},
);
})(jQuery, _, Drupal);