123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- /**
- * @file
- * Block behaviors.
- */
- (function ($, window, Drupal) {
- /**
- * Provide the summary information for the block settings vertical tabs.
- *
- * @type {Drupal~behavior}
- *
- * @prop {Drupal~behaviorAttach} attach
- * Attaches the behavior for the block settings summaries.
- */
- Drupal.behaviors.blockSettingsSummary = {
- attach() {
- // The drupalSetSummary method required for this behavior is not available
- // on the Blocks administration page, so we need to make sure this
- // behavior is processed only if drupalSetSummary is defined.
- if (typeof $.fn.drupalSetSummary === 'undefined') {
- return;
- }
- /**
- * Create a summary for checkboxes in the provided context.
- *
- * @param {HTMLDocument|HTMLElement} context
- * A context where one would find checkboxes to summarize.
- *
- * @return {string}
- * A string with the summary.
- */
- function checkboxesSummary(context) {
- const vals = [];
- const $checkboxes = $(context).find('input[type="checkbox"]:checked + label');
- const il = $checkboxes.length;
- for (let i = 0; i < il; i++) {
- vals.push($($checkboxes[i]).html());
- }
- if (!vals.length) {
- vals.push(Drupal.t('Not restricted'));
- }
- return vals.join(', ');
- }
- $('[data-drupal-selector="edit-visibility-node-type"], [data-drupal-selector="edit-visibility-language"], [data-drupal-selector="edit-visibility-user-role"]').drupalSetSummary(checkboxesSummary);
- $('[data-drupal-selector="edit-visibility-request-path"]').drupalSetSummary((context) => {
- const $pages = $(context).find('textarea[name="visibility[request_path][pages]"]');
- if (!$pages.val()) {
- return Drupal.t('Not restricted');
- }
- return Drupal.t('Restricted to certain pages');
- });
- },
- };
- /**
- * Move a block in the blocks table between regions via select list.
- *
- * This behavior is dependent on the tableDrag behavior, since it uses the
- * objects initialized in that behavior to update the row.
- *
- * @type {Drupal~behavior}
- *
- * @prop {Drupal~behaviorAttach} attach
- * Attaches the tableDrag behaviour for blocks in block administration.
- */
- Drupal.behaviors.blockDrag = {
- attach(context, settings) {
- // tableDrag is required and we should be on the blocks admin page.
- if (typeof Drupal.tableDrag === 'undefined' || typeof Drupal.tableDrag.blocks === 'undefined') {
- return;
- }
- /**
- * Function to check empty regions and toggle classes based on this.
- *
- * @param {jQuery} table
- * The jQuery object representing the table to inspect.
- * @param {jQuery} rowObject
- * The jQuery object representing the table row.
- */
- function checkEmptyRegions(table, rowObject) {
- table.find('tr.region-message').each(function () {
- const $this = $(this);
- // If the dragged row is in this region, but above the message row,
- // swap it down one space.
- if ($this.prev('tr').get(0) === rowObject.element) {
- // Prevent a recursion problem when using the keyboard to move rows
- // up.
- if ((rowObject.method !== 'keyboard' || rowObject.direction === 'down')) {
- rowObject.swap('after', this);
- }
- }
- // This region has become empty.
- if ($this.next('tr').is(':not(.draggable)') || $this.next('tr').length === 0) {
- $this.removeClass('region-populated').addClass('region-empty');
- }
- // This region has become populated.
- else if ($this.is('.region-empty')) {
- $this.removeClass('region-empty').addClass('region-populated');
- }
- });
- }
- /**
- * Function to update the last placed row with the correct classes.
- *
- * @param {jQuery} table
- * The jQuery object representing the table to inspect.
- * @param {jQuery} rowObject
- * The jQuery object representing the table row.
- */
- function updateLastPlaced(table, rowObject) {
- // Remove the color-success class from new block if applicable.
- table.find('.color-success').removeClass('color-success');
- const $rowObject = $(rowObject);
- if (!$rowObject.is('.drag-previous')) {
- table.find('.drag-previous').removeClass('drag-previous');
- $rowObject.addClass('drag-previous');
- }
- }
- /**
- * Update block weights in the given region.
- *
- * @param {jQuery} table
- * Table with draggable items.
- * @param {string} region
- * Machine name of region containing blocks to update.
- */
- function updateBlockWeights(table, region) {
- // Calculate minimum weight.
- let weight = -Math.round(table.find('.draggable').length / 2);
- // Update the block weights.
- table.find(`.region-${region}-message`).nextUntil('.region-title')
- .find('select.block-weight').val(() =>
- // Increment the weight before assigning it to prevent using the
- // absolute minimum available weight. This way we always have an
- // unused upper and lower bound, which makes manually setting the
- // weights easier for users who prefer to do it that way.
- ++weight);
- }
- const table = $('#blocks');
- // Get the blocks tableDrag object.
- const tableDrag = Drupal.tableDrag.blocks;
- // Add a handler for when a row is swapped, update empty regions.
- tableDrag.row.prototype.onSwap = function (swappedRow) {
- checkEmptyRegions(table, this);
- updateLastPlaced(table, this);
- };
- // Add a handler so when a row is dropped, update fields dropped into
- // new regions.
- tableDrag.onDrop = function () {
- const dragObject = this;
- const $rowElement = $(dragObject.rowObject.element);
- // Use "region-message" row instead of "region" row because
- // "region-{region_name}-message" is less prone to regexp match errors.
- const regionRow = $rowElement.prevAll('tr.region-message').get(0);
- const regionName = regionRow.className.replace(/([^ ]+[ ]+)*region-([^ ]+)-message([ ]+[^ ]+)*/, '$2');
- const regionField = $rowElement.find('select.block-region-select');
- // Check whether the newly picked region is available for this block.
- if (regionField.find(`option[value=${regionName}]`).length === 0) {
- // If not, alert the user and keep the block in its old region
- // setting.
- window.alert(Drupal.t('The block cannot be placed in this region.'));
- // Simulate that there was a selected element change, so the row is
- // put back to from where the user tried to drag it.
- regionField.trigger('change');
- }
- // Update region and weight fields if the region has been changed.
- if (!regionField.is(`.block-region-${regionName}`)) {
- const weightField = $rowElement.find('select.block-weight');
- const oldRegionName = weightField[0].className.replace(/([^ ]+[ ]+)*block-weight-([^ ]+)([ ]+[^ ]+)*/, '$2');
- regionField.removeClass(`block-region-${oldRegionName}`).addClass(`block-region-${regionName}`);
- weightField.removeClass(`block-weight-${oldRegionName}`).addClass(`block-weight-${regionName}`);
- regionField.val(regionName);
- }
- updateBlockWeights(table, regionName);
- };
- // Add the behavior to each region select list.
- $(context).find('select.block-region-select').once('block-region-select')
- .on('change', function (event) {
- // Make our new row and select field.
- const row = $(this).closest('tr');
- const select = $(this);
- // Find the correct region and insert the row as the last in the
- // region.
- tableDrag.rowObject = new tableDrag.row(row[0]);
- const region_message = table.find(`.region-${select[0].value}-message`);
- const region_items = region_message.nextUntil('.region-message, .region-title');
- if (region_items.length) {
- region_items.last().after(row);
- }
- // We found that region_message is the last row.
- else {
- region_message.after(row);
- }
- updateBlockWeights(table, select[0].value);
- // Modify empty regions with added or removed fields.
- checkEmptyRegions(table, tableDrag.rowObject);
- // Update last placed block indication.
- updateLastPlaced(table, row);
- // Show unsaved changes warning.
- if (!tableDrag.changed) {
- $(Drupal.theme('tableDragChangedWarning')).insertBefore(tableDrag.table).hide().fadeIn('slow');
- tableDrag.changed = true;
- }
- // Remove focus from selectbox.
- select.trigger('blur');
- });
- },
- };
- }(jQuery, window, Drupal));
|