Security update for Core, with self-updated composer
[yaffs-website] / web / core / modules / quickedit / js / views / EntityToolbarView.js
1 /**
2 * DO NOT EDIT THIS FILE.
3 * See the following change record for more information,
4 * https://www.drupal.org/node/2815083
5 * @preserve
6 **/
7
8 (function ($, _, Backbone, Drupal, debounce) {
9   Drupal.quickedit.EntityToolbarView = Backbone.View.extend({
10     _fieldToolbarRoot: null,
11
12     events: function events() {
13       var map = {
14         'click button.action-save': 'onClickSave',
15         'click button.action-cancel': 'onClickCancel',
16         mouseenter: 'onMouseenter'
17       };
18       return map;
19     },
20     initialize: function initialize(options) {
21       var that = this;
22       this.appModel = options.appModel;
23       this.$entity = $(this.model.get('el'));
24
25       this.listenTo(this.model, 'change:isActive change:isDirty change:state', this.render);
26
27       this.listenTo(this.appModel, 'change:highlightedField change:activeField', this.render);
28
29       this.listenTo(this.model.get('fields'), 'change:state', this.fieldStateChange);
30
31       $(window).on('resize.quickedit scroll.quickedit drupalViewportOffsetChange.quickedit', debounce($.proxy(this.windowChangeHandler, this), 150));
32
33       $(document).on('drupalViewportOffsetChange.quickedit', function (event, offsets) {
34         if (that.$fence) {
35           that.$fence.css(offsets);
36         }
37       });
38
39       var $toolbar = this.buildToolbarEl();
40       this.setElement($toolbar);
41       this._fieldToolbarRoot = $toolbar.find('.quickedit-toolbar-field').get(0);
42
43       this.render();
44     },
45     render: function render() {
46       if (this.model.get('isActive')) {
47         var $body = $('body');
48         if ($body.children('#quickedit-entity-toolbar').length === 0) {
49           $body.append(this.$el);
50         }
51
52         if ($body.children('#quickedit-toolbar-fence').length === 0) {
53           this.$fence = $(Drupal.theme('quickeditEntityToolbarFence')).css(Drupal.displace()).appendTo($body);
54         }
55
56         this.label();
57
58         this.show('ops');
59
60         this.position();
61       }
62
63       var $button = this.$el.find('.quickedit-button.action-save');
64       var isDirty = this.model.get('isDirty');
65
66       switch (this.model.get('state')) {
67         case 'opened':
68           $button.removeClass('action-saving icon-throbber icon-end').text(Drupal.t('Save')).removeAttr('disabled').attr('aria-hidden', !isDirty);
69           break;
70
71         case 'committing':
72           $button.addClass('action-saving icon-throbber icon-end').text(Drupal.t('Saving')).attr('disabled', 'disabled');
73           break;
74
75         default:
76           $button.attr('aria-hidden', true);
77           break;
78       }
79
80       return this;
81     },
82     remove: function remove() {
83       this.$fence.remove();
84
85       $(window).off('resize.quickedit scroll.quickedit drupalViewportOffsetChange.quickedit');
86       $(document).off('drupalViewportOffsetChange.quickedit');
87
88       Backbone.View.prototype.remove.call(this);
89     },
90     windowChangeHandler: function windowChangeHandler(event) {
91       this.position();
92     },
93     fieldStateChange: function fieldStateChange(model, state) {
94       switch (state) {
95         case 'active':
96           this.render();
97           break;
98
99         case 'invalid':
100           this.render();
101           break;
102       }
103     },
104     position: function position(element) {
105       clearTimeout(this.timer);
106
107       var that = this;
108
109       var edge = document.documentElement.dir === 'rtl' ? 'right' : 'left';
110
111       var delay = 0;
112
113       var check = 0;
114
115       var horizontalPadding = 0;
116       var of = void 0;
117       var activeField = void 0;
118       var highlightedField = void 0;
119
120       do {
121         switch (check) {
122           case 0:
123             of = element;
124             break;
125
126           case 1:
127             activeField = Drupal.quickedit.app.model.get('activeField');
128             of = activeField && activeField.editorView && activeField.editorView.$formContainer && activeField.editorView.$formContainer.find('.quickedit-form');
129             break;
130
131           case 2:
132             of = activeField && activeField.editorView && activeField.editorView.getEditedElement();
133             if (activeField && activeField.editorView && activeField.editorView.getQuickEditUISettings().padding) {
134               horizontalPadding = 5;
135             }
136             break;
137
138           case 3:
139             highlightedField = Drupal.quickedit.app.model.get('highlightedField');
140             of = highlightedField && highlightedField.editorView && highlightedField.editorView.getEditedElement();
141             delay = 250;
142             break;
143
144           default:
145             var fieldModels = this.model.get('fields').models;
146             var topMostPosition = 1000000;
147             var topMostField = null;
148
149             for (var i = 0; i < fieldModels.length; i++) {
150               var pos = fieldModels[i].get('el').getBoundingClientRect().top;
151               if (pos < topMostPosition) {
152                 topMostPosition = pos;
153                 topMostField = fieldModels[i];
154               }
155             }
156             of = topMostField.get('el');
157             delay = 50;
158             break;
159         }
160
161         check++;
162       } while (!of);
163
164       function refinePosition(view, suggested, info) {
165         var isBelow = suggested.top > info.target.top;
166         info.element.element.toggleClass('quickedit-toolbar-pointer-top', isBelow);
167
168         if (view.$entity[0] === info.target.element[0]) {
169           var $field = view.$entity.find('.quickedit-editable').eq(isBelow ? -1 : 0);
170           if ($field.length > 0) {
171             suggested.top = isBelow ? $field.offset().top + $field.outerHeight(true) : $field.offset().top - info.element.element.outerHeight(true);
172           }
173         }
174
175         var fenceTop = view.$fence.offset().top;
176         var fenceHeight = view.$fence.height();
177         var toolbarHeight = info.element.element.outerHeight(true);
178         if (suggested.top < fenceTop) {
179           suggested.top = fenceTop;
180         } else if (suggested.top + toolbarHeight > fenceTop + fenceHeight) {
181           suggested.top = fenceTop + fenceHeight - toolbarHeight;
182         }
183
184         info.element.element.css({
185           left: Math.floor(suggested.left),
186           top: Math.floor(suggested.top)
187         });
188       }
189
190       function positionToolbar() {
191         that.$el.position({
192           my: edge + ' bottom',
193
194           at: edge + '+' + (1 + horizontalPadding) + ' top',
195           of: of,
196           collision: 'flipfit',
197           using: refinePosition.bind(null, that),
198           within: that.$fence
199         }).css({
200           'max-width': document.documentElement.clientWidth < 450 ? document.documentElement.clientWidth : 450,
201
202           'min-width': document.documentElement.clientWidth < 240 ? document.documentElement.clientWidth : 240,
203           width: '100%'
204         });
205       }
206
207       this.timer = setTimeout(function () {
208         _.defer(positionToolbar);
209       }, delay);
210     },
211     onClickSave: function onClickSave(event) {
212       event.stopPropagation();
213       event.preventDefault();
214
215       this.model.set('state', 'committing');
216     },
217     onClickCancel: function onClickCancel(event) {
218       event.preventDefault();
219       this.model.set('state', 'deactivating');
220     },
221     onMouseenter: function onMouseenter(event) {
222       clearTimeout(this.timer);
223     },
224     buildToolbarEl: function buildToolbarEl() {
225       var $toolbar = $(Drupal.theme('quickeditEntityToolbar', {
226         id: 'quickedit-entity-toolbar'
227       }));
228
229       $toolbar.find('.quickedit-toolbar-entity').prepend(Drupal.theme('quickeditToolgroup', {
230         classes: ['ops'],
231         buttons: [{
232           label: Drupal.t('Save'),
233           type: 'submit',
234           classes: 'action-save quickedit-button icon',
235           attributes: {
236             'aria-hidden': true
237           }
238         }, {
239           label: Drupal.t('Close'),
240           classes: 'action-cancel quickedit-button icon icon-close icon-only'
241         }]
242       }));
243
244       $toolbar.css({
245         left: this.$entity.offset().left,
246         top: this.$entity.offset().top
247       });
248
249       return $toolbar;
250     },
251     getToolbarRoot: function getToolbarRoot() {
252       return this._fieldToolbarRoot;
253     },
254     label: function label() {
255       var label = '';
256       var entityLabel = this.model.get('label');
257
258       var activeField = Drupal.quickedit.app.model.get('activeField');
259       var activeFieldLabel = activeField && activeField.get('metadata').label;
260
261       var highlightedField = Drupal.quickedit.app.model.get('highlightedField');
262       var highlightedFieldLabel = highlightedField && highlightedField.get('metadata').label;
263
264       if (activeFieldLabel) {
265         label = Drupal.theme('quickeditEntityToolbarLabel', {
266           entityLabel: entityLabel,
267           fieldLabel: activeFieldLabel
268         });
269       } else if (highlightedFieldLabel) {
270         label = Drupal.theme('quickeditEntityToolbarLabel', {
271           entityLabel: entityLabel,
272           fieldLabel: highlightedFieldLabel
273         });
274       } else {
275         label = Drupal.checkPlain(entityLabel);
276       }
277
278       this.$el.find('.quickedit-toolbar-label').html(label);
279     },
280     addClass: function addClass(toolgroup, classes) {
281       this._find(toolgroup).addClass(classes);
282     },
283     removeClass: function removeClass(toolgroup, classes) {
284       this._find(toolgroup).removeClass(classes);
285     },
286     _find: function _find(toolgroup) {
287       return this.$el.find('.quickedit-toolbar .quickedit-toolgroup.' + toolgroup);
288     },
289     show: function show(toolgroup) {
290       this.$el.removeClass('quickedit-animate-invisible');
291     }
292   });
293 })(jQuery, _, Backbone, Drupal, Drupal.debounce);