annotate core/modules/quickedit/js/views/EntityToolbarView.js @ 19:fa3358dc1485 tip

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