Verified Commit bbc87431 authored by Lee Rowlands's avatar Lee Rowlands
Browse files

Issue #2531700 by dmsmidt, alexrayu, cboyden, finne, tameeshb, kattekrab,...

Issue #2531700 by dmsmidt, alexrayu, cboyden, finne, tameeshb, kattekrab, andrewmacpherson, hass, droplet, drpal, dsnopek, nod_: Fragment links to children elements in closed grouping elements don't work
parent 4f1d0f7f
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -137,6 +137,28 @@
    },
  };

  /**
   * Open parent details elements of a targeted page fragment.
   *
   * Opens all (nested) details element on a hash change or fragment link click
   * when the target is a child element, in order to make sure the targeted
   * element is visible. Aria attributes on the summary
   * are set by triggering the click event listener in details-aria.js.
   *
   * @param {jQuery.Event} e
   *   The event triggered.
   * @param {jQuery} $target
   *   The targeted node as a jQuery object.
   */
  const handleFragmentLinkClickOrHashChange = (e, $target) => {
    $target.parents('details').not('[open]').find('> summary').trigger('click');
  };

  /**
   * Binds a listener to handle fragment link clicks and URL hash changes.
   */
  $('body').on('formFragmentLinkClickOrHashChange.details', handleFragmentLinkClickOrHashChange);

  // Expose constructor in the public space.
  Drupal.CollapsibleDetails = CollapsibleDetails;
}(jQuery, Modernizr, Drupal));
+6 −0
Original line number Diff line number Diff line
@@ -77,5 +77,11 @@
    }
  };

  var handleFragmentLinkClickOrHashChange = function handleFragmentLinkClickOrHashChange(e, $target) {
    $target.parents('details').not('[open]').find('> summary').trigger('click');
  };

  $('body').on('formFragmentLinkClickOrHashChange.details', handleFragmentLinkClickOrHashChange);

  Drupal.CollapsibleDetails = CollapsibleDetails;
})(jQuery, Modernizr, Drupal);
 No newline at end of file
+51 −0
Original line number Diff line number Diff line
@@ -12,6 +12,16 @@
 * @event formUpdated
 */

/**
 * Triggers when a click on a page fragment link or hash change is detected.
 *
 * The event triggers when the fragment in the URL changes (a hash change) and
 * when a link containing a fragment identifier is clicked. In case the hash
 * changes due to a click this event will only be triggered once.
 *
 * @event formFragmentLinkClickOrHashChange
 */

(function ($, Drupal, debounce) {
  /**
   * Retrieves the summary for the first element.
@@ -245,4 +255,45 @@
      });
    },
  };

  /**
   * Sends a fragment interaction event on a hash change or fragment link click.
   *
   * @param {jQuery.Event} e
   *   The event triggered.
   *
   * @fires event:formFragmentLinkClickOrHashChange
   */
  const handleFragmentLinkClickOrHashChange = (e) => {
    let $target;

    if (e.type === 'click') {
      $target = e.currentTarget.location ? $(e.currentTarget.location.hash) : $(e.currentTarget.hash);
    }
    else {
      $target = $(`#${location.hash.substr(1)}`);
    }

    $('body').trigger('formFragmentLinkClickOrHashChange', [$target]);

    /**
     * Clicking a fragment link or a hash change should focus the target
     * element, but event timing issues in multiple browsers require a timeout.
     */
    setTimeout(() => {
      $target.focus();
    }, 300, $target);
  };

  // Binds a listener to handle URL fragment changes.
  $(window).on('hashchange.form-fragment', debounce(handleFragmentLinkClickOrHashChange, 300, true));

  /**
   * Binds a listener to handle clicks on fragment links and absolute URL links
   * containing a fragment, this is needed next to the hash change listener
   * because clicking such links doesn't trigger a hash change when the fragment
   * is already in the URL.
   */
  $(document).on('click.form-fragment', 'a[href*="#"]', debounce(handleFragmentLinkClickOrHashChange, 300, true));

}(jQuery, Drupal, Drupal.debounce));
+20 −0
Original line number Diff line number Diff line
@@ -124,4 +124,24 @@
      });
    }
  };

  var handleFragmentLinkClickOrHashChange = function handleFragmentLinkClickOrHashChange(e) {
    var $target = void 0;

    if (e.type === 'click') {
      $target = e.currentTarget.location ? $(e.currentTarget.location.hash) : $(e.currentTarget.hash);
    } else {
      $target = $('#' + location.hash.substr(1));
    }

    $('body').trigger('formFragmentLinkClickOrHashChange', [$target]);

    setTimeout(function () {
      $target.focus();
    }, 300, $target);
  };

  $(window).on('hashchange.form-fragment', debounce(handleFragmentLinkClickOrHashChange, 300, true));

  $(document).on('click.form-fragment', 'a[href*="#"]', debounce(handleFragmentLinkClickOrHashChange, 300, true));
})(jQuery, Drupal, Drupal.debounce);
 No newline at end of file
+22 −0
Original line number Diff line number Diff line
@@ -13,6 +13,23 @@
 */

(function ($, Drupal, drupalSettings) {
  /**
   * Show the parent vertical tab pane of a targeted page fragment.
   *
   * In order to make sure a targeted element inside a vertical tab pane is
   * visible on a hash change or fragment link click, show all parent panes.
   *
   * @param {jQuery.Event} e
   *   The event triggered.
   * @param {jQuery} $target
   *   The targeted node as a jQuery object.
   */
  const handleFragmentLinkClickOrHashChange = (e, $target) => {
    $target.parents('.vertical-tabs__pane').each((index, pane) => {
      $(pane).data('verticalTab').focus();
    });
  };

  /**
   * This script transforms a set of details into a stack of vertical tabs.
   *
@@ -36,6 +53,11 @@
        return;
      }

      /**
       * Binds a listener to handle fragment link clicks and URL hash changes.
       */
      $('body').once('vertical-tabs-fragments').on('formFragmentLinkClickOrHashChange.verticalTabs', handleFragmentLinkClickOrHashChange);

      $(context).find('[data-vertical-tabs-panes]').once('vertical-tabs').each(function () {
        const $this = $(this).addClass('vertical-tabs__panes');
        const focusID = $this.find(':hidden.vertical-tabs__active-tab').val();
Loading