--- /dev/null
+/**
+ * @file
+ * A Backbone View that provides an interactive toolbar (1 per in-place editor).
+ */
+
+(function ($, _, Backbone, Drupal) {
+
+ 'use strict';
+
+ 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: function (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: function () {
+ // 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: function (model, state) {
+ var from = model.previous('state');
+ var 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: function () {
+ 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: function () {
+ 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: function () {
+ 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: function () {
+ return 'quickedit-wysiwyg-main-toolgroup-for-' + this._id;
+ },
+
+ /**
+ * Finds a toolgroup.
+ *
+ * @param {string} toolgroup
+ * A toolgroup name.
+ *
+ * @return {jQuery}
+ * The toolgroup element.
+ */
+ _find: function (toolgroup) {
+ return this.$el.find('.quickedit-toolgroup.' + toolgroup);
+ },
+
+ /**
+ * Shows a toolgroup.
+ *
+ * @param {string} toolgroup
+ * A toolgroup name.
+ */
+ show: function (toolgroup) {
+ var $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, function (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(function () {
+ $group.removeClass('quickedit-animate-invisible');
+ }, 0);
+ }
+
+ });
+
+})(jQuery, _, Backbone, Drupal);