252 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			252 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @file
							 | 
						||
| 
								 | 
							
								 * tabledrag.js overrides and functionality extensions.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								(($, Drupal) => {
							 | 
						||
| 
								 | 
							
								  /**
							 | 
						||
| 
								 | 
							
								   * Extends core's Tabledrag functionality.
							 | 
						||
| 
								 | 
							
								   *
							 | 
						||
| 
								 | 
							
								   * @type {Drupal~behavior}
							 | 
						||
| 
								 | 
							
								   */
							 | 
						||
| 
								 | 
							
								  Drupal.behaviors.claroTableDrag = {
							 | 
						||
| 
								 | 
							
								    attach(context, settings) {
							 | 
						||
| 
								 | 
							
								      /**
							 | 
						||
| 
								 | 
							
								       * Refactors the table row markup to improve item label text wrapping.
							 | 
						||
| 
								 | 
							
								       *
							 | 
						||
| 
								 | 
							
								       * This addresses an issue specific to item labels that are long enough
							 | 
						||
| 
								 | 
							
								       * to be wrapped to a new line. Without this fix, a new line may start
							 | 
						||
| 
								 | 
							
								       * at the beginning of the table row, instead of the expected behavior of
							 | 
						||
| 
								 | 
							
								       * starting at the x axis of the first line.
							 | 
						||
| 
								 | 
							
								       *
							 | 
						||
| 
								 | 
							
								       * Addressing this issue requires changing the structure of a tabledrag
							 | 
						||
| 
								 | 
							
								       * cell's first row.
							 | 
						||
| 
								 | 
							
								       * @example
							 | 
						||
| 
								 | 
							
								       *   <!-- Default tabledrag structure, which has the wrapping problem. -->
							 | 
						||
| 
								 | 
							
								       *   <tr class="draggable">
							 | 
						||
| 
								 | 
							
								       *     <td>
							 | 
						||
| 
								 | 
							
								       *       <!--
							 | 
						||
| 
								 | 
							
								       *         Indentations are next to each other because they are styled as
							 | 
						||
| 
								 | 
							
								       *         `float: left;`
							 | 
						||
| 
								 | 
							
								       *       -->
							 | 
						||
| 
								 | 
							
								       *       <div class="indentation"></div>
							 | 
						||
| 
								 | 
							
								       *       <div class="indentation"></div>
							 | 
						||
| 
								 | 
							
								       *       <a class="tabledrag-handle"></a>
							 | 
						||
| 
								 | 
							
								       *       <!-- If the text in this link wraps enough times that the element
							 | 
						||
| 
								 | 
							
								       *         is taller than the floated elements preceding it, some lines
							 | 
						||
| 
								 | 
							
								       *         will wrap to the beginning of the row instead of aligning with
							 | 
						||
| 
								 | 
							
								       *         the beginning of the link text.
							 | 
						||
| 
								 | 
							
								       *       -->
							 | 
						||
| 
								 | 
							
								       *       <a class="menu-item__link">A longer label that may require wrapping</a>
							 | 
						||
| 
								 | 
							
								       *     </td>
							 | 
						||
| 
								 | 
							
								       *     <!-- etc. -->
							 | 
						||
| 
								 | 
							
								       *   </tr>
							 | 
						||
| 
								 | 
							
								       * @example
							 | 
						||
| 
								 | 
							
								       * <!-- Claro tabledrag structure, this fixes the wrapping problem. -->
							 | 
						||
| 
								 | 
							
								       *   <tr class="draggable">
							 | 
						||
| 
								 | 
							
								       *     <td class="tabledrag-cell">
							 | 
						||
| 
								 | 
							
								       *       <div class="tabledrag-cell-content">
							 | 
						||
| 
								 | 
							
								       *          <!-- Indentations are next to each other because
							 | 
						||
| 
								 | 
							
								       *            .table-drag-cell-content is styled as `display: table-row;`
							 | 
						||
| 
								 | 
							
								       *            and .table-drag-cell-content > * is styled as
							 | 
						||
| 
								 | 
							
								       *            `display: table-cell;`
							 | 
						||
| 
								 | 
							
								       *          -->
							 | 
						||
| 
								 | 
							
								       *         <div class="indentation"></div>
							 | 
						||
| 
								 | 
							
								       *         <div class="indentation"></div>
							 | 
						||
| 
								 | 
							
								       *         <a class="tabledrag-handle"></a>
							 | 
						||
| 
								 | 
							
								       *         <div class="tabledrag-cell-content__item">
							 | 
						||
| 
								 | 
							
								       *           <!-- Placing the link inside a div styled as
							 | 
						||
| 
								 | 
							
								       *             `display: table-cell;` allows the text to wrap within
							 | 
						||
| 
								 | 
							
								       *             the boundaries of the "cell".
							 | 
						||
| 
								 | 
							
								       *           -->
							 | 
						||
| 
								 | 
							
								       *           <a class="menu-item__link">A longer label that may require wrapping</a>
							 | 
						||
| 
								 | 
							
								       *         </div>
							 | 
						||
| 
								 | 
							
								       *      </div>
							 | 
						||
| 
								 | 
							
								       *    </td>
							 | 
						||
| 
								 | 
							
								       *    <!-- additional <td> -->
							 | 
						||
| 
								 | 
							
								       *   </tr>
							 | 
						||
| 
								 | 
							
								       *
							 | 
						||
| 
								 | 
							
								       * @param {number} index
							 | 
						||
| 
								 | 
							
								       *   The index in the loop, as provided by `jQuery.each`.
							 | 
						||
| 
								 | 
							
								       * @param {HTMLElement} row
							 | 
						||
| 
								 | 
							
								       *   A draggable table row.
							 | 
						||
| 
								 | 
							
								       *
							 | 
						||
| 
								 | 
							
								       * @todo this may be removable as part of https://drupal.org/node/3083044
							 | 
						||
| 
								 | 
							
								       */
							 | 
						||
| 
								 | 
							
								      const createItemWrapBoundaries = (row) => {
							 | 
						||
| 
								 | 
							
								        const $row = $(row);
							 | 
						||
| 
								 | 
							
								        const $firstCell = $row
							 | 
						||
| 
								 | 
							
								          .find('td:first-of-type')
							 | 
						||
| 
								 | 
							
								          .eq(0)
							 | 
						||
| 
								 | 
							
								          .wrapInner(Drupal.theme('tableDragCellContentWrapper'))
							 | 
						||
| 
								 | 
							
								          .wrapInner(
							 | 
						||
| 
								 | 
							
								            $(Drupal.theme('tableDragCellItemsWrapper')).addClass(
							 | 
						||
| 
								 | 
							
								              'js-tabledrag-cell-content',
							 | 
						||
| 
								 | 
							
								            ),
							 | 
						||
| 
								 | 
							
								          );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const $targetElem = $firstCell.find('.js-tabledrag-cell-content');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Move handle into the '.js-tabledrag-cell-content' target.
							 | 
						||
| 
								 | 
							
								        $targetElem
							 | 
						||
| 
								 | 
							
								          .eq(0)
							 | 
						||
| 
								 | 
							
								          .find(
							 | 
						||
| 
								 | 
							
								            '> .tabledrag-cell-content__item > .js-tabledrag-handle, > .tabledrag-cell-content__item > .js-indentation',
							 | 
						||
| 
								 | 
							
								          )
							 | 
						||
| 
								 | 
							
								          .prependTo($targetElem);
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      // Find each row in a draggable table and process it with
							 | 
						||
| 
								 | 
							
								      // createItemWrapBoundaries().
							 | 
						||
| 
								 | 
							
								      Object.keys(settings.tableDrag || {}).forEach((base) => {
							 | 
						||
| 
								 | 
							
								        once(
							 | 
						||
| 
								 | 
							
								          'claroTabledrag',
							 | 
						||
| 
								 | 
							
								          $(context)
							 | 
						||
| 
								 | 
							
								            .find(`#${base}`)
							 | 
						||
| 
								 | 
							
								            .find('> tr.draggable, > tbody > tr.draggable'),
							 | 
						||
| 
								 | 
							
								        ).forEach(createItemWrapBoundaries);
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								  $.extend(Drupal.tableDrag.prototype.row.prototype, {
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Add an asterisk or other marker to the changed row.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @todo this may be removable as part of https://drupal.org/node/3084910
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    markChanged() {
							 | 
						||
| 
								 | 
							
								      const marker = $(Drupal.theme('tableDragChangedMarker')).addClass(
							 | 
						||
| 
								 | 
							
								        'js-tabledrag-changed-marker',
							 | 
						||
| 
								 | 
							
								      );
							 | 
						||
| 
								 | 
							
								      const cell = $(this.element).find('td:first-of-type');
							 | 
						||
| 
								 | 
							
								      if (cell.find('.js-tabledrag-changed-marker').length === 0) {
							 | 
						||
| 
								 | 
							
								        cell.find('.js-tabledrag-handle').after(marker);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      Drupal.tableDrag[this.table.id].changedRowIds.add(this.element.id);
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Moves added indents into Claro's wrapper element.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * For indents to work properly, they must be inside the wrapper
							 | 
						||
| 
								 | 
							
								     * created by createItemWrapBoundaries(). When an indent is added via
							 | 
						||
| 
								 | 
							
								     * dragging, core's tabledrag functionality does not add it inside the
							 | 
						||
| 
								 | 
							
								     * wrapper. This function fires immediately after an indent is added, which
							 | 
						||
| 
								 | 
							
								     * moves the indent into that wrapper.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @see Drupal.tableDrag.prototype.row.prototype.indent
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @todo this may be removable as part of https://drupal.org/node/3083044
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    onIndent() {
							 | 
						||
| 
								 | 
							
								      $(this.table)
							 | 
						||
| 
								 | 
							
								        .find('.tabledrag-cell > .js-indentation')
							 | 
						||
| 
								 | 
							
								        .each((index, indentToMove) => {
							 | 
						||
| 
								 | 
							
								          const $indentToMove = $(indentToMove);
							 | 
						||
| 
								 | 
							
								          const $cellContent = $indentToMove.siblings(
							 | 
						||
| 
								 | 
							
								            '.tabledrag-cell-content',
							 | 
						||
| 
								 | 
							
								          );
							 | 
						||
| 
								 | 
							
								          $indentToMove.prependTo($cellContent);
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  $.extend(
							 | 
						||
| 
								 | 
							
								    Drupal.theme,
							 | 
						||
| 
								 | 
							
								    /** @lends Drupal.theme */ {
							 | 
						||
| 
								 | 
							
								      /**
							 | 
						||
| 
								 | 
							
								       * Constructs the table drag changed marker.
							 | 
						||
| 
								 | 
							
								       *
							 | 
						||
| 
								 | 
							
								       * @return {string}
							 | 
						||
| 
								 | 
							
								       *   Markup for the indentation.
							 | 
						||
| 
								 | 
							
								       */
							 | 
						||
| 
								 | 
							
								      tableDragIndentation() {
							 | 
						||
| 
								 | 
							
								        return '<div class="js-indentation indentation"><svg xmlns="http://www.w3.org/2000/svg" class="tree" width="25" height="25" viewBox="0 0 25 25"><path class="tree__item tree__item-child-ltr tree__item-child-last-ltr tree__item-horizontal tree__item-horizontal-right" d="M12,12.5 H25" stroke="#888"/><path class="tree__item tree__item-child-rtl tree__item-child-last-rtl tree__item-horizontal tree__horizontal-left" d="M0,12.5 H13" stroke="#888"/><path class="tree__item tree__item-child-ltr tree__item-child-rtl tree__item-child-last-ltr tree__item-child-last-rtl tree__vertical tree__vertical-top" d="M12.5,12 v-99" stroke="#888"/><path class="tree__item tree__item-child-ltr tree__item-child-rtl tree__vertical tree__vertical-bottom" d="M12.5,12 v99" stroke="#888"/></svg></div>';
							 | 
						||
| 
								 | 
							
								      },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      /**
							 | 
						||
| 
								 | 
							
								       * Constructs the table drag changed warning.
							 | 
						||
| 
								 | 
							
								       *
							 | 
						||
| 
								 | 
							
								       * @return {string}
							 | 
						||
| 
								 | 
							
								       *   Markup for the warning.
							 | 
						||
| 
								 | 
							
								       */
							 | 
						||
| 
								 | 
							
								      tableDragChangedWarning() {
							 | 
						||
| 
								 | 
							
								        return `<div class="tabledrag-changed-warning messages messages--warning" role="alert">${Drupal.theme(
							 | 
						||
| 
								 | 
							
								          'tableDragChangedMarker',
							 | 
						||
| 
								 | 
							
								        )} ${Drupal.t('You have unsaved changes.')}</div>`;
							 | 
						||
| 
								 | 
							
								      },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      /**
							 | 
						||
| 
								 | 
							
								       * Constructs the table drag handle.
							 | 
						||
| 
								 | 
							
								       *
							 | 
						||
| 
								 | 
							
								       * @return {string}
							 | 
						||
| 
								 | 
							
								       *   A string representing a DOM fragment.
							 | 
						||
| 
								 | 
							
								       */
							 | 
						||
| 
								 | 
							
								      tableDragHandle: (dragOrientation = 'drag') => {
							 | 
						||
| 
								 | 
							
								        const title =
							 | 
						||
| 
								 | 
							
								          dragOrientation === 'drag-y'
							 | 
						||
| 
								 | 
							
								            ? Drupal.t('Change order')
							 | 
						||
| 
								 | 
							
								            : Drupal.t('Move in any direction');
							 | 
						||
| 
								 | 
							
								        return `<a href="#" title="${title}" class="tabledrag-handle js-tabledrag-handle"></a>`;
							 | 
						||
| 
								 | 
							
								      },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      /**
							 | 
						||
| 
								 | 
							
								       * The button for toggling table row weight visibility.
							 | 
						||
| 
								 | 
							
								       *
							 | 
						||
| 
								 | 
							
								       * @return {string}
							 | 
						||
| 
								 | 
							
								       *   HTML markup for the weight toggle button and its container.
							 | 
						||
| 
								 | 
							
								       */
							 | 
						||
| 
								 | 
							
								      tableDragToggle: () =>
							 | 
						||
| 
								 | 
							
								        `<div class="tabledrag-toggle-weight-wrapper" data-drupal-selector="tabledrag-toggle-weight-wrapper">
							 | 
						||
| 
								 | 
							
								            <button type="button" class="link action-link tabledrag-toggle-weight" data-drupal-selector="tabledrag-toggle-weight"></button>
							 | 
						||
| 
								 | 
							
								            </div>`,
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      /**
							 | 
						||
| 
								 | 
							
								       * Constructs contents of the toggle weight button.
							 | 
						||
| 
								 | 
							
								       *
							 | 
						||
| 
								 | 
							
								       * @param {boolean} show
							 | 
						||
| 
								 | 
							
								       *   If the table weights are currently displayed.
							 | 
						||
| 
								 | 
							
								       *
							 | 
						||
| 
								 | 
							
								       * @return {string}
							 | 
						||
| 
								 | 
							
								       *  HTML markup for the weight toggle button content.
							 | 
						||
| 
								 | 
							
								       */
							 | 
						||
| 
								 | 
							
								      toggleButtonContent: (show) => {
							 | 
						||
| 
								 | 
							
								        const classes = [
							 | 
						||
| 
								 | 
							
								          'action-link',
							 | 
						||
| 
								 | 
							
								          'action-link--extrasmall',
							 | 
						||
| 
								 | 
							
								          'tabledrag-toggle-weight',
							 | 
						||
| 
								 | 
							
								        ];
							 | 
						||
| 
								 | 
							
								        let text = '';
							 | 
						||
| 
								 | 
							
								        if (show) {
							 | 
						||
| 
								 | 
							
								          classes.push('action-link--icon-hide');
							 | 
						||
| 
								 | 
							
								          text = Drupal.t('Hide row weights');
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								          classes.push('action-link--icon-show');
							 | 
						||
| 
								 | 
							
								          text = Drupal.t('Show row weights');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return `<span class="${classes.join(' ')}">${text}</a>`;
							 | 
						||
| 
								 | 
							
								      },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      /**
							 | 
						||
| 
								 | 
							
								       * Constructs the wrapper for the initial content of the drag cell.
							 | 
						||
| 
								 | 
							
								       *
							 | 
						||
| 
								 | 
							
								       * @return {string}
							 | 
						||
| 
								 | 
							
								       *   A string representing a DOM fragment.
							 | 
						||
| 
								 | 
							
								       */
							 | 
						||
| 
								 | 
							
								      tableDragCellContentWrapper() {
							 | 
						||
| 
								 | 
							
								        return '<div class="tabledrag-cell-content__item"></div>';
							 | 
						||
| 
								 | 
							
								      },
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      /**
							 | 
						||
| 
								 | 
							
								       * Constructs the wrapper for the whole table drag cell.
							 | 
						||
| 
								 | 
							
								       *
							 | 
						||
| 
								 | 
							
								       * @return {string}
							 | 
						||
| 
								 | 
							
								       *   A string representing a DOM fragment.
							 | 
						||
| 
								 | 
							
								       */
							 | 
						||
| 
								 | 
							
								      tableDragCellItemsWrapper() {
							 | 
						||
| 
								 | 
							
								        return '<div class="tabledrag-cell-content"></div>';
							 | 
						||
| 
								 | 
							
								      },
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								  );
							 | 
						||
| 
								 | 
							
								})(jQuery, Drupal);
							 |