FieldToolbarView.es6.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /**
  2. * @file
  3. * A Backbone View that provides an interactive toolbar (1 per in-place editor).
  4. */
  5. (function($, _, Backbone, Drupal) {
  6. Drupal.quickedit.FieldToolbarView = Backbone.View.extend(
  7. /** @lends Drupal.quickedit.FieldToolbarView# */ {
  8. /**
  9. * The edited element, as indicated by EditorView.getEditedElement.
  10. *
  11. * @type {jQuery}
  12. */
  13. $editedElement: null,
  14. /**
  15. * A reference to the in-place editor.
  16. *
  17. * @type {Drupal.quickedit.EditorView}
  18. */
  19. editorView: null,
  20. /**
  21. * @type {string}
  22. */
  23. _id: null,
  24. /**
  25. * @constructs
  26. *
  27. * @augments Backbone.View
  28. *
  29. * @param {object} options
  30. * Options object to construct the field toolbar.
  31. * @param {jQuery} options.$editedElement
  32. * The element being edited.
  33. * @param {Drupal.quickedit.EditorView} options.editorView
  34. * The EditorView the toolbar belongs to.
  35. */
  36. initialize(options) {
  37. this.$editedElement = options.$editedElement;
  38. this.editorView = options.editorView;
  39. /**
  40. * @type {jQuery}
  41. */
  42. this.$root = this.$el;
  43. // Generate a DOM-compatible ID for the form container DOM element.
  44. this._id = `quickedit-toolbar-for-${this.model.id.replace(
  45. /[/[\]]/g,
  46. '_',
  47. )}`;
  48. this.listenTo(this.model, 'change:state', this.stateChange);
  49. },
  50. /**
  51. * {@inheritdoc}
  52. *
  53. * @return {Drupal.quickedit.FieldToolbarView}
  54. * The current FieldToolbarView.
  55. */
  56. render() {
  57. // Render toolbar and set it as the view's element.
  58. this.setElement(
  59. $(
  60. Drupal.theme('quickeditFieldToolbar', {
  61. id: this._id,
  62. }),
  63. ),
  64. );
  65. // Attach to the field toolbar $root element in the entity toolbar.
  66. this.$el.prependTo(this.$root);
  67. return this;
  68. },
  69. /**
  70. * Determines the actions to take given a change of state.
  71. *
  72. * @param {Drupal.quickedit.FieldModel} model
  73. * The quickedit FieldModel
  74. * @param {string} state
  75. * The state of the associated field. One of
  76. * {@link Drupal.quickedit.FieldModel.states}.
  77. */
  78. stateChange(model, state) {
  79. const from = model.previous('state');
  80. const to = state;
  81. switch (to) {
  82. case 'inactive':
  83. break;
  84. case 'candidate':
  85. // Remove the view's existing element if we went to the 'activating'
  86. // state or later, because it will be recreated. Not doing this would
  87. // result in memory leaks.
  88. if (from !== 'inactive' && from !== 'highlighted') {
  89. this.$el.remove();
  90. this.setElement();
  91. }
  92. break;
  93. case 'highlighted':
  94. break;
  95. case 'activating':
  96. this.render();
  97. if (this.editorView.getQuickEditUISettings().fullWidthToolbar) {
  98. this.$el.addClass('quickedit-toolbar-fullwidth');
  99. }
  100. if (this.editorView.getQuickEditUISettings().unifiedToolbar) {
  101. this.insertWYSIWYGToolGroups();
  102. }
  103. break;
  104. case 'active':
  105. break;
  106. case 'changed':
  107. break;
  108. case 'saving':
  109. break;
  110. case 'saved':
  111. break;
  112. case 'invalid':
  113. break;
  114. }
  115. },
  116. /**
  117. * Insert WYSIWYG markup into the associated toolbar.
  118. */
  119. insertWYSIWYGToolGroups() {
  120. this.$el
  121. .append(
  122. Drupal.theme('quickeditToolgroup', {
  123. id: this.getFloatedWysiwygToolgroupId(),
  124. classes: [
  125. 'wysiwyg-floated',
  126. 'quickedit-animate-slow',
  127. 'quickedit-animate-invisible',
  128. 'quickedit-animate-delay-veryfast',
  129. ],
  130. buttons: [],
  131. }),
  132. )
  133. .append(
  134. Drupal.theme('quickeditToolgroup', {
  135. id: this.getMainWysiwygToolgroupId(),
  136. classes: [
  137. 'wysiwyg-main',
  138. 'quickedit-animate-slow',
  139. 'quickedit-animate-invisible',
  140. 'quickedit-animate-delay-veryfast',
  141. ],
  142. buttons: [],
  143. }),
  144. );
  145. // Animate the toolgroups into visibility.
  146. this.show('wysiwyg-floated');
  147. this.show('wysiwyg-main');
  148. },
  149. /**
  150. * Retrieves the ID for this toolbar's container.
  151. *
  152. * Only used to make sane hovering behavior possible.
  153. *
  154. * @return {string}
  155. * A string that can be used as the ID for this toolbar's container.
  156. */
  157. getId() {
  158. return `quickedit-toolbar-for-${this._id}`;
  159. },
  160. /**
  161. * Retrieves the ID for this toolbar's floating WYSIWYG toolgroup.
  162. *
  163. * Used to provide an abstraction for any WYSIWYG editor to plug in.
  164. *
  165. * @return {string}
  166. * A string that can be used as the ID.
  167. */
  168. getFloatedWysiwygToolgroupId() {
  169. return `quickedit-wysiwyg-floated-toolgroup-for-${this._id}`;
  170. },
  171. /**
  172. * Retrieves the ID for this toolbar's main WYSIWYG toolgroup.
  173. *
  174. * Used to provide an abstraction for any WYSIWYG editor to plug in.
  175. *
  176. * @return {string}
  177. * A string that can be used as the ID.
  178. */
  179. getMainWysiwygToolgroupId() {
  180. return `quickedit-wysiwyg-main-toolgroup-for-${this._id}`;
  181. },
  182. /**
  183. * Finds a toolgroup.
  184. *
  185. * @param {string} toolgroup
  186. * A toolgroup name.
  187. *
  188. * @return {jQuery}
  189. * The toolgroup element.
  190. */
  191. _find(toolgroup) {
  192. return this.$el.find(`.quickedit-toolgroup.${toolgroup}`);
  193. },
  194. /**
  195. * Shows a toolgroup.
  196. *
  197. * @param {string} toolgroup
  198. * A toolgroup name.
  199. */
  200. show(toolgroup) {
  201. const $group = this._find(toolgroup);
  202. // Attach a transitionEnd event handler to the toolbar group so that
  203. // update events can be triggered after the animations have ended.
  204. $group.on(Drupal.quickedit.util.constants.transitionEnd, event => {
  205. $group.off(Drupal.quickedit.util.constants.transitionEnd);
  206. });
  207. // The call to remove the class and start the animation must be started in
  208. // the next animation frame or the event handler attached above won't be
  209. // triggered.
  210. window.setTimeout(() => {
  211. $group.removeClass('quickedit-animate-invisible');
  212. }, 0);
  213. },
  214. },
  215. );
  216. })(jQuery, _, Backbone, Drupal);