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