X-Git-Url: http://www.aleph1.co.uk/gitweb/?a=blobdiff_plain;ds=sidebyside;f=web%2Fcore%2Fmodules%2Fckeditor%2Fjs%2Fviews%2FVisualView.es6.js;fp=web%2Fcore%2Fmodules%2Fckeditor%2Fjs%2Fviews%2FVisualView.es6.js;h=413e69be857bd04c83bdd124b1572d7633bf68a8;hb=9917807b03b64faf00f6a1f29dcb6eafc454efa5;hp=0000000000000000000000000000000000000000;hpb=aea91e65e895364e460983b890e295aa5d5540a5;p=yaffs-website diff --git a/web/core/modules/ckeditor/js/views/VisualView.es6.js b/web/core/modules/ckeditor/js/views/VisualView.es6.js new file mode 100644 index 000000000..413e69be8 --- /dev/null +++ b/web/core/modules/ckeditor/js/views/VisualView.es6.js @@ -0,0 +1,268 @@ +/** + * @file + * A Backbone View that provides the visual UX view of CKEditor toolbar + * configuration. + */ + +(function (Drupal, Backbone, $) { + Drupal.ckeditor.VisualView = Backbone.View.extend(/** @lends Drupal.ckeditor.VisualView# */{ + + events: { + 'click .ckeditor-toolbar-group-name': 'onGroupNameClick', + 'click .ckeditor-groupnames-toggle': 'onGroupNamesToggleClick', + 'click .ckeditor-add-new-group button': 'onAddGroupButtonClick', + }, + + /** + * Backbone View for CKEditor toolbar configuration; visual UX. + * + * @constructs + * + * @augments Backbone.View + */ + initialize() { + this.listenTo(this.model, 'change:isDirty change:groupNamesVisible', this.render); + + // Add a toggle for the button group names. + $(Drupal.theme('ckeditorButtonGroupNamesToggle')) + .prependTo(this.$el.find('#ckeditor-active-toolbar').parent()); + + this.render(); + }, + + /** + * Render function for rendering the toolbar configuration. + * + * @param {*} model + * Model used for the view. + * @param {string} [value] + * The value that was changed. + * @param {object} changedAttributes + * The attributes that was changed. + * + * @return {Drupal.ckeditor.VisualView} + * The {@link Drupal.ckeditor.VisualView} object. + */ + render(model, value, changedAttributes) { + this.insertPlaceholders(); + this.applySorting(); + + // Toggle button group names. + let groupNamesVisible = this.model.get('groupNamesVisible'); + // If a button was just placed in the active toolbar, ensure that the + // button group names are visible. + if (changedAttributes && changedAttributes.changes && changedAttributes.changes.isDirty) { + this.model.set({ groupNamesVisible: true }, { silent: true }); + groupNamesVisible = true; + } + this.$el.find('[data-toolbar="active"]').toggleClass('ckeditor-group-names-are-visible', groupNamesVisible); + this.$el.find('.ckeditor-groupnames-toggle') + .text((groupNamesVisible) ? Drupal.t('Hide group names') : Drupal.t('Show group names')) + .attr('aria-pressed', groupNamesVisible); + + return this; + }, + + /** + * Handles clicks to a button group name. + * + * @param {jQuery.Event} event + * The click event on the button group. + */ + onGroupNameClick(event) { + const $group = $(event.currentTarget).closest('.ckeditor-toolbar-group'); + Drupal.ckeditor.openGroupNameDialog(this, $group); + + event.stopPropagation(); + event.preventDefault(); + }, + + /** + * Handles clicks on the button group names toggle button. + * + * @param {jQuery.Event} event + * The click event on the toggle button. + */ + onGroupNamesToggleClick(event) { + this.model.set('groupNamesVisible', !this.model.get('groupNamesVisible')); + event.preventDefault(); + }, + + /** + * Prompts the user to provide a name for a new button group; inserts it. + * + * @param {jQuery.Event} event + * The event of the button click. + */ + onAddGroupButtonClick(event) { + /** + * Inserts a new button if the openGroupNameDialog function returns true. + * + * @param {bool} success + * A flag that indicates if the user created a new group (true) or + * canceled out of the dialog (false). + * @param {jQuery} $group + * A jQuery DOM fragment that represents the new button group. It has + * not been added to the DOM yet. + */ + function insertNewGroup(success, $group) { + if (success) { + $group.appendTo($(event.currentTarget).closest('.ckeditor-row').children('.ckeditor-toolbar-groups')); + // Focus on the new group. + $group.trigger('focus'); + } + } + + // Pass in a DOM fragment of a placeholder group so that the new group + // name can be applied to it. + Drupal.ckeditor.openGroupNameDialog(this, $(Drupal.theme('ckeditorToolbarGroup')), insertNewGroup); + + event.preventDefault(); + }, + + /** + * Handles jQuery Sortable stop sort of a button group. + * + * @param {jQuery.Event} event + * The event triggered on the group drag. + * @param {object} ui + * A jQuery.ui.sortable argument that contains information about the + * elements involved in the sort action. + */ + endGroupDrag(event, ui) { + const view = this; + Drupal.ckeditor.registerGroupMove(this, ui.item, (success) => { + if (!success) { + // Cancel any sorting in the configuration area. + view.$el.find('.ckeditor-toolbar-configuration').find('.ui-sortable').sortable('cancel'); + } + }); + }, + + /** + * Handles jQuery Sortable start sort of a button. + * + * @param {jQuery.Event} event + * The event triggered on the group drag. + * @param {object} ui + * A jQuery.ui.sortable argument that contains information about the + * elements involved in the sort action. + */ + startButtonDrag(event, ui) { + this.$el.find('a:focus').trigger('blur'); + + // Show the button group names as soon as the user starts dragging. + this.model.set('groupNamesVisible', true); + }, + + /** + * Handles jQuery Sortable stop sort of a button. + * + * @param {jQuery.Event} event + * The event triggered on the button drag. + * @param {object} ui + * A jQuery.ui.sortable argument that contains information about the + * elements involved in the sort action. + */ + endButtonDrag(event, ui) { + const view = this; + Drupal.ckeditor.registerButtonMove(this, ui.item, (success) => { + if (!success) { + // Cancel any sorting in the configuration area. + view.$el.find('.ui-sortable').sortable('cancel'); + } + // Refocus the target button so that the user can continue from a known + // place. + ui.item.find('a').trigger('focus'); + }); + }, + + /** + * Invokes jQuery.sortable() on new buttons and groups in a CKEditor config. + */ + applySorting() { + // Make the buttons sortable. + this.$el.find('.ckeditor-buttons').not('.ui-sortable').sortable({ + // Change this to .ckeditor-toolbar-group-buttons. + connectWith: '.ckeditor-buttons', + placeholder: 'ckeditor-button-placeholder', + forcePlaceholderSize: true, + tolerance: 'pointer', + cursor: 'move', + start: this.startButtonDrag.bind(this), + // Sorting within a sortable. + stop: this.endButtonDrag.bind(this), + }).disableSelection(); + + // Add the drag and drop functionality to button groups. + this.$el.find('.ckeditor-toolbar-groups').not('.ui-sortable').sortable({ + connectWith: '.ckeditor-toolbar-groups', + cancel: '.ckeditor-add-new-group', + placeholder: 'ckeditor-toolbar-group-placeholder', + forcePlaceholderSize: true, + cursor: 'move', + stop: this.endGroupDrag.bind(this), + }); + + // Add the drag and drop functionality to buttons. + this.$el.find('.ckeditor-multiple-buttons li').draggable({ + connectToSortable: '.ckeditor-toolbar-active .ckeditor-buttons', + helper: 'clone', + }); + }, + + /** + * Wraps the invocation of methods to insert blank groups and rows. + */ + insertPlaceholders() { + this.insertPlaceholderRow(); + this.insertNewGroupButtons(); + }, + + /** + * Inserts a blank row at the bottom of the CKEditor configuration. + */ + insertPlaceholderRow() { + let $rows = this.$el.find('.ckeditor-row'); + // Add a placeholder row. to the end of the list if one does not exist. + if (!$rows.eq(-1).hasClass('placeholder')) { + this.$el + .find('.ckeditor-toolbar-active') + .children('.ckeditor-active-toolbar-configuration') + .append(Drupal.theme('ckeditorRow')); + } + // Update the $rows variable to include the new row. + $rows = this.$el.find('.ckeditor-row'); + // Remove blank rows except the last one. + const len = $rows.length; + $rows.filter((index, row) => { + // Do not remove the last row. + if (index + 1 === len) { + return false; + } + return $(row).find('.ckeditor-toolbar-group').not('.placeholder').length === 0; + }) + // Then get all rows that are placeholders and remove them. + .remove(); + }, + + /** + * Inserts a button in each row that will add a new CKEditor button group. + */ + insertNewGroupButtons() { + // Insert an add group button to each row. + this.$el.find('.ckeditor-row').each(function () { + const $row = $(this); + const $groups = $row.find('.ckeditor-toolbar-group'); + const $button = $row.find('.ckeditor-add-new-group'); + if ($button.length === 0) { + $row.children('.ckeditor-toolbar-groups').append(Drupal.theme('ckeditorNewButtonGroup')); + } + // If a placeholder group exists, make sure it's at the end of the row. + else if (!$groups.eq(-1).hasClass('ckeditor-add-new-group')) { + $button.appendTo($row.children('.ckeditor-toolbar-groups')); + } + }); + }, + }); +}(Drupal, Backbone, jQuery));