plainTextEditor.es6.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /**
  2. * @file
  3. * ContentEditable-based in-place editor for plain text content.
  4. */
  5. (function($, _, Drupal) {
  6. Drupal.quickedit.editors.plain_text = Drupal.quickedit.EditorView.extend(
  7. /** @lends Drupal.quickedit.editors.plain_text# */ {
  8. /**
  9. * Stores the textual DOM element that is being in-place edited.
  10. */
  11. $textElement: null,
  12. /**
  13. * @constructs
  14. *
  15. * @augments Drupal.quickedit.EditorView
  16. *
  17. * @param {object} options
  18. * Options for the plain text editor.
  19. */
  20. initialize(options) {
  21. Drupal.quickedit.EditorView.prototype.initialize.call(this, options);
  22. const editorModel = this.model;
  23. const fieldModel = this.fieldModel;
  24. // Store the original value of this field. Necessary for reverting
  25. // changes.
  26. const $fieldItems = this.$el.find('.quickedit-field');
  27. const $textElement = $fieldItems.length ? $fieldItems.eq(0) : this.$el;
  28. this.$textElement = $textElement;
  29. editorModel.set('originalValue', $.trim(this.$textElement.text()));
  30. // Sets the state to 'changed' whenever the value changes.
  31. let previousText = editorModel.get('originalValue');
  32. $textElement.on('keyup paste', event => {
  33. const currentText = $.trim($textElement.text());
  34. if (previousText !== currentText) {
  35. previousText = currentText;
  36. editorModel.set('currentValue', currentText);
  37. fieldModel.set('state', 'changed');
  38. }
  39. });
  40. },
  41. /**
  42. * @inheritdoc
  43. *
  44. * @return {jQuery}
  45. * The text element for the plain text editor.
  46. */
  47. getEditedElement() {
  48. return this.$textElement;
  49. },
  50. /**
  51. * @inheritdoc
  52. *
  53. * @param {object} fieldModel
  54. * The field model that holds the state.
  55. * @param {string} state
  56. * The state to change to.
  57. * @param {object} options
  58. * State options, if needed by the state change.
  59. */
  60. stateChange(fieldModel, state, options) {
  61. const from = fieldModel.previous('state');
  62. const to = state;
  63. switch (to) {
  64. case 'inactive':
  65. break;
  66. case 'candidate':
  67. if (from !== 'inactive') {
  68. this.$textElement.removeAttr('contenteditable');
  69. }
  70. if (from === 'invalid') {
  71. this.removeValidationErrors();
  72. }
  73. break;
  74. case 'highlighted':
  75. break;
  76. case 'activating':
  77. // Defer updating the field model until the current state change has
  78. // propagated, to not trigger a nested state change event.
  79. _.defer(() => {
  80. fieldModel.set('state', 'active');
  81. });
  82. break;
  83. case 'active':
  84. this.$textElement.attr('contenteditable', 'true');
  85. break;
  86. case 'changed':
  87. break;
  88. case 'saving':
  89. if (from === 'invalid') {
  90. this.removeValidationErrors();
  91. }
  92. this.save(options);
  93. break;
  94. case 'saved':
  95. break;
  96. case 'invalid':
  97. this.showValidationErrors();
  98. break;
  99. }
  100. },
  101. /**
  102. * @inheritdoc
  103. *
  104. * @return {object}
  105. * A settings object for the quick edit UI.
  106. */
  107. getQuickEditUISettings() {
  108. return {
  109. padding: true,
  110. unifiedToolbar: false,
  111. fullWidthToolbar: false,
  112. popup: false,
  113. };
  114. },
  115. /**
  116. * @inheritdoc
  117. */
  118. revert() {
  119. this.$textElement.html(this.model.get('originalValue'));
  120. },
  121. },
  122. );
  123. })(jQuery, _, Drupal);