comparison core/modules/quickedit/js/views/FieldToolbarView.es6.js @ 4:a9cd425dd02b

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