FieldToolbarView.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /**
  2. * @file
  3. * A Backbone View that provides an interactive toolbar (1 per in-place editor).
  4. */
  5. (function ($, _, Backbone, Drupal) {
  6. 'use strict';
  7. Drupal.quickedit.FieldToolbarView = Backbone.View.extend(/** @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: function (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(/[\/\[\]]/g, '_');
  45. this.listenTo(this.model, 'change:state', this.stateChange);
  46. },
  47. /**
  48. * @inheritdoc
  49. *
  50. * @return {Drupal.quickedit.FieldToolbarView}
  51. * The current FieldToolbarView.
  52. */
  53. render: function () {
  54. // Render toolbar and set it as the view's element.
  55. this.setElement($(Drupal.theme('quickeditFieldToolbar', {
  56. id: this._id
  57. })));
  58. // Attach to the field toolbar $root element in the entity toolbar.
  59. this.$el.prependTo(this.$root);
  60. return this;
  61. },
  62. /**
  63. * Determines the actions to take given a change of state.
  64. *
  65. * @param {Drupal.quickedit.FieldModel} model
  66. * The quickedit FieldModel
  67. * @param {string} state
  68. * The state of the associated field. One of
  69. * {@link Drupal.quickedit.FieldModel.states}.
  70. */
  71. stateChange: function (model, state) {
  72. var from = model.previous('state');
  73. var to = state;
  74. switch (to) {
  75. case 'inactive':
  76. break;
  77. case 'candidate':
  78. // Remove the view's existing element if we went to the 'activating'
  79. // state or later, because it will be recreated. Not doing this would
  80. // result in memory leaks.
  81. if (from !== 'inactive' && from !== 'highlighted') {
  82. this.$el.remove();
  83. this.setElement();
  84. }
  85. break;
  86. case 'highlighted':
  87. break;
  88. case 'activating':
  89. this.render();
  90. if (this.editorView.getQuickEditUISettings().fullWidthToolbar) {
  91. this.$el.addClass('quickedit-toolbar-fullwidth');
  92. }
  93. if (this.editorView.getQuickEditUISettings().unifiedToolbar) {
  94. this.insertWYSIWYGToolGroups();
  95. }
  96. break;
  97. case 'active':
  98. break;
  99. case 'changed':
  100. break;
  101. case 'saving':
  102. break;
  103. case 'saved':
  104. break;
  105. case 'invalid':
  106. break;
  107. }
  108. },
  109. /**
  110. * Insert WYSIWYG markup into the associated toolbar.
  111. */
  112. insertWYSIWYGToolGroups: function () {
  113. this.$el
  114. .append(Drupal.theme('quickeditToolgroup', {
  115. id: this.getFloatedWysiwygToolgroupId(),
  116. classes: ['wysiwyg-floated', 'quickedit-animate-slow', 'quickedit-animate-invisible', 'quickedit-animate-delay-veryfast'],
  117. buttons: []
  118. }))
  119. .append(Drupal.theme('quickeditToolgroup', {
  120. id: this.getMainWysiwygToolgroupId(),
  121. classes: ['wysiwyg-main', 'quickedit-animate-slow', 'quickedit-animate-invisible', 'quickedit-animate-delay-veryfast'],
  122. buttons: []
  123. }));
  124. // Animate the toolgroups into visibility.
  125. this.show('wysiwyg-floated');
  126. this.show('wysiwyg-main');
  127. },
  128. /**
  129. * Retrieves the ID for this toolbar's container.
  130. *
  131. * Only used to make sane hovering behavior possible.
  132. *
  133. * @return {string}
  134. * A string that can be used as the ID for this toolbar's container.
  135. */
  136. getId: function () {
  137. return 'quickedit-toolbar-for-' + this._id;
  138. },
  139. /**
  140. * Retrieves the ID for this toolbar's floating WYSIWYG toolgroup.
  141. *
  142. * Used to provide an abstraction for any WYSIWYG editor to plug in.
  143. *
  144. * @return {string}
  145. * A string that can be used as the ID.
  146. */
  147. getFloatedWysiwygToolgroupId: function () {
  148. return 'quickedit-wysiwyg-floated-toolgroup-for-' + this._id;
  149. },
  150. /**
  151. * Retrieves the ID for this toolbar's main WYSIWYG toolgroup.
  152. *
  153. * Used to provide an abstraction for any WYSIWYG editor to plug in.
  154. *
  155. * @return {string}
  156. * A string that can be used as the ID.
  157. */
  158. getMainWysiwygToolgroupId: function () {
  159. return 'quickedit-wysiwyg-main-toolgroup-for-' + this._id;
  160. },
  161. /**
  162. * Finds a toolgroup.
  163. *
  164. * @param {string} toolgroup
  165. * A toolgroup name.
  166. *
  167. * @return {jQuery}
  168. * The toolgroup element.
  169. */
  170. _find: function (toolgroup) {
  171. return this.$el.find('.quickedit-toolgroup.' + toolgroup);
  172. },
  173. /**
  174. * Shows a toolgroup.
  175. *
  176. * @param {string} toolgroup
  177. * A toolgroup name.
  178. */
  179. show: function (toolgroup) {
  180. var $group = this._find(toolgroup);
  181. // Attach a transitionEnd event handler to the toolbar group so that
  182. // update events can be triggered after the animations have ended.
  183. $group.on(Drupal.quickedit.util.constants.transitionEnd, function (event) {
  184. $group.off(Drupal.quickedit.util.constants.transitionEnd);
  185. });
  186. // The call to remove the class and start the animation must be started in
  187. // the next animation frame or the event handler attached above won't be
  188. // triggered.
  189. window.setTimeout(function () {
  190. $group.removeClass('quickedit-animate-invisible');
  191. }, 0);
  192. }
  193. });
  194. })(jQuery, _, Backbone, Drupal);