/**
* @file
* A Backbone View that provides an interactive toolbar (1 per in-place editor).
*/
(function ($, _, Backbone, Drupal) {
Drupal.quickedit.FieldToolbarView = Backbone.View.extend(
/** @lends Drupal.quickedit.FieldToolbarView# */ {
/**
* The edited element, as indicated by EditorView.getEditedElement.
*
* @type {jQuery}
*/
$editedElement: null,
/**
* A reference to the in-place editor.
*
* @type {Drupal.quickedit.EditorView}
*/
editorView: null,
/**
* @type {string}
*/
_id: null,
/**
* @constructs
*
* @augments Backbone.View
*
* @param {object} options
* Options object to construct the field toolbar.
* @param {jQuery} options.$editedElement
* The element being edited.
* @param {Drupal.quickedit.EditorView} options.editorView
* The EditorView the toolbar belongs to.
*/
initialize(options) {
this.$editedElement = options.$editedElement;
this.editorView = options.editorView;
/**
* @type {jQuery}
*/
this.$root = this.$el;
// Generate a DOM-compatible ID for the form container DOM element.
this._id = `quickedit-toolbar-for-${this.model.id.replace(
/[/[\]]/g,
'_',
)}`;
this.listenTo(this.model, 'change:state', this.stateChange);
},
/**
* {@inheritdoc}
*
* @return {Drupal.quickedit.FieldToolbarView}
* The current FieldToolbarView.
*/
render() {
// Render toolbar and set it as the view's element.
this.setElement(
$(
Drupal.theme('quickeditFieldToolbar', {
id: this._id,
}),
),
);
// Attach to the field toolbar $root element in the entity toolbar.
this.$el.prependTo(this.$root);
return this;
},
/**
* Determines the actions to take given a change of state.
*
* @param {Drupal.quickedit.FieldModel} model
* The quickedit FieldModel
* @param {string} state
* The state of the associated field. One of
* {@link Drupal.quickedit.FieldModel.states}.
*/
stateChange(model, state) {
const from = model.previous('state');
const to = state;
switch (to) {
case 'inactive':
break;
case 'candidate':
// Remove the view's existing element if we went to the 'activating'
// state or later, because it will be recreated. Not doing this would
// result in memory leaks.
if (from !== 'inactive' && from !== 'highlighted') {
this.$el.remove();
this.setElement();
}
break;
case 'highlighted':
break;
case 'activating':
this.render();
if (this.editorView.getQuickEditUISettings().fullWidthToolbar) {
this.$el.addClass('quickedit-toolbar-fullwidth');
}
if (this.editorView.getQuickEditUISettings().unifiedToolbar) {
this.insertWYSIWYGToolGroups();
}
break;
case 'active':
break;
case 'changed':
break;
case 'saving':
break;
case 'saved':
break;
case 'invalid':
break;
}
},
/**
* Insert WYSIWYG markup into the associated toolbar.
*/
insertWYSIWYGToolGroups() {
this.$el
.append(
Drupal.theme('quickeditToolgroup', {
id: this.getFloatedWysiwygToolgroupId(),
classes: [
'wysiwyg-floated',
'quickedit-animate-slow',
'quickedit-animate-invisible',
'quickedit-animate-delay-veryfast',
],
buttons: [],
}),
)
.append(
Drupal.theme('quickeditToolgroup', {
id: this.getMainWysiwygToolgroupId(),
classes: [
'wysiwyg-main',
'quickedit-animate-slow',
'quickedit-animate-invisible',
'quickedit-animate-delay-veryfast',
],
buttons: [],
}),
);
// Animate the toolgroups into visibility.
this.show('wysiwyg-floated');
this.show('wysiwyg-main');
},
/**
* Retrieves the ID for this toolbar's container.
*
* Only used to make sane hovering behavior possible.
*
* @return {string}
* A string that can be used as the ID for this toolbar's container.
*/
getId() {
return `quickedit-toolbar-for-${this._id}`;
},
/**
* Retrieves the ID for this toolbar's floating WYSIWYG toolgroup.
*
* Used to provide an abstraction for any WYSIWYG editor to plug in.
*
* @return {string}
* A string that can be used as the ID.
*/
getFloatedWysiwygToolgroupId() {
return `quickedit-wysiwyg-floated-toolgroup-for-${this._id}`;
},
/**
* Retrieves the ID for this toolbar's main WYSIWYG toolgroup.
*
* Used to provide an abstraction for any WYSIWYG editor to plug in.
*
* @return {string}
* A string that can be used as the ID.
*/
getMainWysiwygToolgroupId() {
return `quickedit-wysiwyg-main-toolgroup-for-${this._id}`;
},
/**
* Finds a toolgroup.
*
* @param {string} toolgroup
* A toolgroup name.
*
* @return {jQuery}
* The toolgroup element.
*/
_find(toolgroup) {
return this.$el.find(`.quickedit-toolgroup.${toolgroup}`);
},
/**
* Shows a toolgroup.
*
* @param {string} toolgroup
* A toolgroup name.
*/
show(toolgroup) {
const $group = this._find(toolgroup);
// Attach a transitionEnd event handler to the toolbar group so that
// update events can be triggered after the animations have ended.
$group.on(Drupal.quickedit.util.constants.transitionEnd, (event) => {
$group.off(Drupal.quickedit.util.constants.transitionEnd);
});
// The call to remove the class and start the animation must be started in
// the next animation frame or the event handler attached above won't be
// triggered.
window.setTimeout(() => {
$group.removeClass('quickedit-animate-invisible');
}, 0);
},
},
);
})(jQuery, _, Backbone, Drupal);