]> git.ipfire.org Git - thirdparty/foundation/foundation-sites.git/commitdiff
Use pull request #11425 from ncoden/fix/drilldown-submenu-height-11416 for v6.5.0
authorNicolas Coden <nicolas@ncoden.fr>
Sat, 25 Aug 2018 20:33:41 +0000 (22:33 +0200)
committerNicolas Coden <nicolas@ncoden.fr>
Sat, 25 Aug 2018 20:33:41 +0000 (22:33 +0200)
c7ce8d5b9 fix: set the Drilldown height for on the currently opened (sub)menu #11416
43c1fac65 test: add unit tests for Drilldown resizing on toggling
7f7dfd83a test: check the Drilldrown wrapper height instead of the element height
90c4e45f8 fix: set a default for the current menu in Drilldown before it is used
1db6a1f2a test: add unit test for the Drilldown height when reopened from a submenu #11416
d4617ac08 clean: remove infinite timeout used for development in Drilldown tests

Signed-off-by: Nicolas Coden <nicolas@ncoden.fr>
js/foundation.drilldown.js
test/javascript/components/drilldown.js

index b8eb2a4e7325d1a660f7dddf8b5a7cf3417f7b1f..9deaf3272f423641e005824f89f461e8d5f0fc54 100644 (file)
@@ -61,6 +61,11 @@ class Drilldown extends Plugin {
     this.$submenuAnchors = this.$element.find('li.is-drilldown-submenu-parent').children('a');
     this.$submenus = this.$submenuAnchors.parent('li').children('[data-submenu]').attr('role', 'group');
     this.$menuItems = this.$element.find('li').not('.js-drilldown-back').attr('role', 'treeitem').find('a');
+
+    // Set the main menu as current by default (unless a submenu is selected)
+    // Used to set the wrapper height when the drilldown is closed/reopened from any (sub)menu
+    this.$currentMenu = this.$element;
+
     this.$element.attr('data-mutate', (this.$element.attr('data-drilldown') || GetYoDigits(6, 'drilldown')));
 
     this._prepareMenu();
@@ -392,6 +397,9 @@ class Drilldown extends Plugin {
       _this._setHideSubMenuClasses($(this));
     });
 
+    // Save the menu as the currently displayed one.
+    this.$currentMenu = $elem;
+
     // If target menu is root, focus first link & exit
     if ($elem.is('[data-drilldown]')) {
       if (autoFocus === true) $elem.find('li[role="treeitem"] > a').first().focus();
@@ -433,9 +441,16 @@ class Drilldown extends Plugin {
    * @param {jQuery} $elem - the current element with a submenu to open, i.e. the `li` tag.
    */
   _show($elem) {
-    if(this.options.autoHeight) this.$wrapper.css({height:$elem.children('[data-submenu]').data('calcHeight')});
+    const $submenu = $elem.children('[data-submenu]');
+
     $elem.attr('aria-expanded', true);
-    $elem.children('[data-submenu]').addClass('is-active').removeClass('invisible').attr('aria-hidden', false);
+
+    this.$currentMenu = $submenu;
+    $submenu.addClass('is-active').removeClass('invisible').attr('aria-hidden', false);
+    if (this.options.autoHeight) {
+      this.$wrapper.css({ height: $submenu.data('calcHeight') });
+    }
+
     /**
      * Fires when the submenu has opened.
      * @event Drilldown#open
@@ -473,18 +488,24 @@ class Drilldown extends Plugin {
    * @private
    */
   _getMaxDims() {
-    var  maxHeight = 0, result = {}, _this = this;
+    var maxHeight = 0, result = {}, _this = this;
+
+    // Recalculate menu heights and total max height
     this.$submenus.add(this.$element).each(function(){
       var numOfElems = $(this).children('li').length;
       var height = Box.GetDimensions(this).height;
+
       maxHeight = height > maxHeight ? height : maxHeight;
+
       if(_this.options.autoHeight) {
         $(this).data('calcHeight',height);
-        if (!$(this).hasClass('is-drilldown-submenu')) result['height'] = height;
       }
     });
 
-    if(!this.options.autoHeight) result['min-height'] = `${maxHeight}px`;
+    if (this.options.autoHeight)
+      result['height'] = this.$currentMenu.data('calcHeight');
+    else
+      result['min-height'] = `${maxHeight}px`;
 
     result['max-width'] = `${this.$element[0].getBoundingClientRect().width}px`;
 
index d3e83187ec448a8152c11e758b9ee2b9ed6c1345..eabd433065441d17d81aae338054286aaa1fa18e 100644 (file)
@@ -4,12 +4,11 @@ describe('Drilldown Menu', function() {
   var template = `<ul class="menu" data-drilldown style="width: 200px" id="m1">
     <li>
       <a href="#">Item 1</a>
-      <ul class="menu">
+      <ul id="Menu-1" class="menu">
         <li>
           <a href="#">Item 1A</a>
-          <ul class="menu">
+          <ul id="Menu-1A" class="menu">
             <li><a href="#Item-1Aa">Item 1Aa</a></li>
-            <li><a href="#Item-1Ba">Item 1Ba</a></li>
           </ul>
         </li>
         <li><a href="#Item-1B">Item 1B</a></li>
@@ -18,7 +17,7 @@ describe('Drilldown Menu', function() {
     </li>
     <li>
       <a href="#">Item 2</a>
-      <ul class="menu">
+      <ul id="Menu-2" class="menu">
         <li><a href="#Item-2A">Item 2A</a></li>
         <li><a href="#Item-2B">Item 2B</a></li>
       </ul>
@@ -26,6 +25,15 @@ describe('Drilldown Menu', function() {
     <li><a href="#Item-3"> Item 3</a></li>
   </ul>`;
 
+  var templateWithToggler = `
+    <div>
+      <button id="trigger" data-toggle="target" type="button">Toggler</button>
+      <div id="target" class="is-hidden" data-toggler="is-hidden">
+        ${template}
+      </div>
+    </div>
+  `;
+
   afterEach(function() {
     plugin.destroy();
     document.activeElement.blur();
@@ -218,6 +226,56 @@ describe('Drilldown Menu', function() {
     });
   });
 
+  describe('toggle events', function () {
+
+    var $trigger, $target, $wrapper, togglerPlugin;
+
+    beforeEach(function () {
+      $html = $(templateWithToggler).appendTo('body');
+      $trigger = $html.find('#trigger');
+      $target = $html.find('#target');
+      $target = $html.find('#target');
+
+      togglerPlugin = new Foundation.Toggler($target, {});
+      plugin = new Foundation.Drilldown($html.find('[data-drilldown]'), { autoHeight: true });
+
+      $wrapper = $html.find('.is-drilldown');
+    });
+
+    it('correctly resize when opened', function () {
+      // Open the Drilldown
+      $trigger.focus().trigger('click');
+
+      // 3 items (including the back button) is around 115px height
+      $wrapper.height().should.be.within(110, 120);
+    });
+
+    it('correctly resize when closed', function () {
+      // Open then close the Drilldown
+      $trigger.focus().trigger('click');
+      $trigger.focus().trigger('click');
+
+      $wrapper.height().should.be.equal(0);
+    });
+
+    it('correctly resize when reopened on a submenu', function () {
+      // Open the Drilldown
+      $trigger.focus().trigger('click');
+      // Show a submenu with a smaller height
+      plugin._showMenu($html.find('#Menu-1A'));
+      // Close then reopen the the Drilldown
+      $trigger.focus().trigger('click');
+      $trigger.focus().trigger('click');
+
+      // 2 items (including the back button) is around 75px height
+      $wrapper.height().should.be.within(70, 80);
+    });
+
+    afterEach(function () {
+      togglerPlugin.destroy();
+    });
+
+  });
 
   describe('keyboard events', function() {
     // Currently not testable, as triggered event won't move on focus