annotate core/modules/block/js/block.es6.js @ 0:c75dbcec494b

Initial commit from drush-created site
author Chris Cannam
date Thu, 05 Jul 2018 14:24:15 +0000
parents
children a9cd425dd02b
rev   line source
Chris@0 1 /**
Chris@0 2 * @file
Chris@0 3 * Block behaviors.
Chris@0 4 */
Chris@0 5
Chris@0 6 (function ($, window, Drupal) {
Chris@0 7 /**
Chris@0 8 * Provide the summary information for the block settings vertical tabs.
Chris@0 9 *
Chris@0 10 * @type {Drupal~behavior}
Chris@0 11 *
Chris@0 12 * @prop {Drupal~behaviorAttach} attach
Chris@0 13 * Attaches the behavior for the block settings summaries.
Chris@0 14 */
Chris@0 15 Drupal.behaviors.blockSettingsSummary = {
Chris@0 16 attach() {
Chris@0 17 // The drupalSetSummary method required for this behavior is not available
Chris@0 18 // on the Blocks administration page, so we need to make sure this
Chris@0 19 // behavior is processed only if drupalSetSummary is defined.
Chris@0 20 if (typeof $.fn.drupalSetSummary === 'undefined') {
Chris@0 21 return;
Chris@0 22 }
Chris@0 23
Chris@0 24 /**
Chris@0 25 * Create a summary for checkboxes in the provided context.
Chris@0 26 *
Chris@0 27 * @param {HTMLDocument|HTMLElement} context
Chris@0 28 * A context where one would find checkboxes to summarize.
Chris@0 29 *
Chris@0 30 * @return {string}
Chris@0 31 * A string with the summary.
Chris@0 32 */
Chris@0 33 function checkboxesSummary(context) {
Chris@0 34 const vals = [];
Chris@0 35 const $checkboxes = $(context).find('input[type="checkbox"]:checked + label');
Chris@0 36 const il = $checkboxes.length;
Chris@0 37 for (let i = 0; i < il; i++) {
Chris@0 38 vals.push($($checkboxes[i]).html());
Chris@0 39 }
Chris@0 40 if (!vals.length) {
Chris@0 41 vals.push(Drupal.t('Not restricted'));
Chris@0 42 }
Chris@0 43 return vals.join(', ');
Chris@0 44 }
Chris@0 45
Chris@0 46 $('[data-drupal-selector="edit-visibility-node-type"], [data-drupal-selector="edit-visibility-language"], [data-drupal-selector="edit-visibility-user-role"]').drupalSetSummary(checkboxesSummary);
Chris@0 47
Chris@0 48 $('[data-drupal-selector="edit-visibility-request-path"]').drupalSetSummary((context) => {
Chris@0 49 const $pages = $(context).find('textarea[name="visibility[request_path][pages]"]');
Chris@0 50 if (!$pages.val()) {
Chris@0 51 return Drupal.t('Not restricted');
Chris@0 52 }
Chris@0 53
Chris@0 54 return Drupal.t('Restricted to certain pages');
Chris@0 55 });
Chris@0 56 },
Chris@0 57 };
Chris@0 58
Chris@0 59 /**
Chris@0 60 * Move a block in the blocks table between regions via select list.
Chris@0 61 *
Chris@0 62 * This behavior is dependent on the tableDrag behavior, since it uses the
Chris@0 63 * objects initialized in that behavior to update the row.
Chris@0 64 *
Chris@0 65 * @type {Drupal~behavior}
Chris@0 66 *
Chris@0 67 * @prop {Drupal~behaviorAttach} attach
Chris@0 68 * Attaches the tableDrag behaviour for blocks in block administration.
Chris@0 69 */
Chris@0 70 Drupal.behaviors.blockDrag = {
Chris@0 71 attach(context, settings) {
Chris@0 72 // tableDrag is required and we should be on the blocks admin page.
Chris@0 73 if (typeof Drupal.tableDrag === 'undefined' || typeof Drupal.tableDrag.blocks === 'undefined') {
Chris@0 74 return;
Chris@0 75 }
Chris@0 76
Chris@0 77 /**
Chris@0 78 * Function to check empty regions and toggle classes based on this.
Chris@0 79 *
Chris@0 80 * @param {jQuery} table
Chris@0 81 * The jQuery object representing the table to inspect.
Chris@0 82 * @param {jQuery} rowObject
Chris@0 83 * The jQuery object representing the table row.
Chris@0 84 */
Chris@0 85 function checkEmptyRegions(table, rowObject) {
Chris@0 86 table.find('tr.region-message').each(function () {
Chris@0 87 const $this = $(this);
Chris@0 88 // If the dragged row is in this region, but above the message row,
Chris@0 89 // swap it down one space.
Chris@0 90 if ($this.prev('tr').get(0) === rowObject.element) {
Chris@0 91 // Prevent a recursion problem when using the keyboard to move rows
Chris@0 92 // up.
Chris@0 93 if ((rowObject.method !== 'keyboard' || rowObject.direction === 'down')) {
Chris@0 94 rowObject.swap('after', this);
Chris@0 95 }
Chris@0 96 }
Chris@0 97 // This region has become empty.
Chris@0 98 if ($this.next('tr').is(':not(.draggable)') || $this.next('tr').length === 0) {
Chris@0 99 $this.removeClass('region-populated').addClass('region-empty');
Chris@0 100 }
Chris@0 101 // This region has become populated.
Chris@0 102 else if ($this.is('.region-empty')) {
Chris@0 103 $this.removeClass('region-empty').addClass('region-populated');
Chris@0 104 }
Chris@0 105 });
Chris@0 106 }
Chris@0 107
Chris@0 108 /**
Chris@0 109 * Function to update the last placed row with the correct classes.
Chris@0 110 *
Chris@0 111 * @param {jQuery} table
Chris@0 112 * The jQuery object representing the table to inspect.
Chris@0 113 * @param {jQuery} rowObject
Chris@0 114 * The jQuery object representing the table row.
Chris@0 115 */
Chris@0 116 function updateLastPlaced(table, rowObject) {
Chris@0 117 // Remove the color-success class from new block if applicable.
Chris@0 118 table.find('.color-success').removeClass('color-success');
Chris@0 119
Chris@0 120 const $rowObject = $(rowObject);
Chris@0 121 if (!$rowObject.is('.drag-previous')) {
Chris@0 122 table.find('.drag-previous').removeClass('drag-previous');
Chris@0 123 $rowObject.addClass('drag-previous');
Chris@0 124 }
Chris@0 125 }
Chris@0 126
Chris@0 127 /**
Chris@0 128 * Update block weights in the given region.
Chris@0 129 *
Chris@0 130 * @param {jQuery} table
Chris@0 131 * Table with draggable items.
Chris@0 132 * @param {string} region
Chris@0 133 * Machine name of region containing blocks to update.
Chris@0 134 */
Chris@0 135 function updateBlockWeights(table, region) {
Chris@0 136 // Calculate minimum weight.
Chris@0 137 let weight = -Math.round(table.find('.draggable').length / 2);
Chris@0 138 // Update the block weights.
Chris@0 139 table.find(`.region-${region}-message`).nextUntil('.region-title')
Chris@0 140 .find('select.block-weight').val(() =>
Chris@0 141 // Increment the weight before assigning it to prevent using the
Chris@0 142 // absolute minimum available weight. This way we always have an
Chris@0 143 // unused upper and lower bound, which makes manually setting the
Chris@0 144 // weights easier for users who prefer to do it that way.
Chris@0 145 ++weight);
Chris@0 146 }
Chris@0 147
Chris@0 148 const table = $('#blocks');
Chris@0 149 // Get the blocks tableDrag object.
Chris@0 150 const tableDrag = Drupal.tableDrag.blocks;
Chris@0 151 // Add a handler for when a row is swapped, update empty regions.
Chris@0 152 tableDrag.row.prototype.onSwap = function (swappedRow) {
Chris@0 153 checkEmptyRegions(table, this);
Chris@0 154 updateLastPlaced(table, this);
Chris@0 155 };
Chris@0 156
Chris@0 157 // Add a handler so when a row is dropped, update fields dropped into
Chris@0 158 // new regions.
Chris@0 159 tableDrag.onDrop = function () {
Chris@0 160 const dragObject = this;
Chris@0 161 const $rowElement = $(dragObject.rowObject.element);
Chris@0 162 // Use "region-message" row instead of "region" row because
Chris@0 163 // "region-{region_name}-message" is less prone to regexp match errors.
Chris@0 164 const regionRow = $rowElement.prevAll('tr.region-message').get(0);
Chris@0 165 const regionName = regionRow.className.replace(/([^ ]+[ ]+)*region-([^ ]+)-message([ ]+[^ ]+)*/, '$2');
Chris@0 166 const regionField = $rowElement.find('select.block-region-select');
Chris@0 167 // Check whether the newly picked region is available for this block.
Chris@0 168 if (regionField.find(`option[value=${regionName}]`).length === 0) {
Chris@0 169 // If not, alert the user and keep the block in its old region
Chris@0 170 // setting.
Chris@0 171 window.alert(Drupal.t('The block cannot be placed in this region.'));
Chris@0 172 // Simulate that there was a selected element change, so the row is
Chris@0 173 // put back to from where the user tried to drag it.
Chris@0 174 regionField.trigger('change');
Chris@0 175 }
Chris@0 176
Chris@0 177 // Update region and weight fields if the region has been changed.
Chris@0 178 if (!regionField.is(`.block-region-${regionName}`)) {
Chris@0 179 const weightField = $rowElement.find('select.block-weight');
Chris@0 180 const oldRegionName = weightField[0].className.replace(/([^ ]+[ ]+)*block-weight-([^ ]+)([ ]+[^ ]+)*/, '$2');
Chris@0 181 regionField.removeClass(`block-region-${oldRegionName}`).addClass(`block-region-${regionName}`);
Chris@0 182 weightField.removeClass(`block-weight-${oldRegionName}`).addClass(`block-weight-${regionName}`);
Chris@0 183 regionField.val(regionName);
Chris@0 184 }
Chris@0 185
Chris@0 186 updateBlockWeights(table, regionName);
Chris@0 187 };
Chris@0 188
Chris@0 189 // Add the behavior to each region select list.
Chris@0 190 $(context).find('select.block-region-select').once('block-region-select')
Chris@0 191 .on('change', function (event) {
Chris@0 192 // Make our new row and select field.
Chris@0 193 const row = $(this).closest('tr');
Chris@0 194 const select = $(this);
Chris@0 195 // Find the correct region and insert the row as the last in the
Chris@0 196 // region.
Chris@0 197 tableDrag.rowObject = new tableDrag.row(row[0]);
Chris@0 198 const regionMessage = table.find(`.region-${select[0].value}-message`);
Chris@0 199 const regionItems = regionMessage.nextUntil('.region-message, .region-title');
Chris@0 200 if (regionItems.length) {
Chris@0 201 regionItems.last().after(row);
Chris@0 202 }
Chris@0 203 // We found that regionMessage is the last row.
Chris@0 204 else {
Chris@0 205 regionMessage.after(row);
Chris@0 206 }
Chris@0 207 updateBlockWeights(table, select[0].value);
Chris@0 208 // Modify empty regions with added or removed fields.
Chris@0 209 checkEmptyRegions(table, tableDrag.rowObject);
Chris@0 210 // Update last placed block indication.
Chris@0 211 updateLastPlaced(table, row);
Chris@0 212 // Show unsaved changes warning.
Chris@0 213 if (!tableDrag.changed) {
Chris@0 214 $(Drupal.theme('tableDragChangedWarning')).insertBefore(tableDrag.table).hide().fadeIn('slow');
Chris@0 215 tableDrag.changed = true;
Chris@0 216 }
Chris@0 217 // Remove focus from selectbox.
Chris@0 218 select.trigger('blur');
Chris@0 219 });
Chris@0 220 },
Chris@0 221 };
Chris@0 222 }(jQuery, window, Drupal));