From 36521fb40fd438c14925208020128311c0dddeaa Mon Sep 17 00:00:00 2001 From: koki-higashikawa Date: Fri, 7 Jul 2017 13:56:06 +0900 Subject: [PATCH 1/3] Track of the triggering anchor Changed Dropdown panes so that it is arranged with the position of primary anchor as a reference. --- js/foundation.dropdown.js | 52 +++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/js/foundation.dropdown.js b/js/foundation.dropdown.js index ed32aa8361..dff3708cf8 100644 --- a/js/foundation.dropdown.js +++ b/js/foundation.dropdown.js @@ -49,14 +49,13 @@ class Dropdown extends Positionable { _init() { var $id = this.$element.attr('id'); - this.$anchor = $(`[data-toggle="${$id}"]`).length ? $(`[data-toggle="${$id}"]`) : $(`[data-open="${$id}"]`); - this.$anchor.attr({ + this.$anchors = $(`[data-toggle="${$id}"]`).length ? $(`[data-toggle="${$id}"]`) : $(`[data-open="${$id}"]`); + this.$anchors.attr({ 'aria-controls': $id, 'data-is-focus': false, 'data-yeti-box': $id, 'aria-haspopup': true, 'aria-expanded': false - }); if(this.options.parentClass){ @@ -69,7 +68,7 @@ class Dropdown extends Positionable { 'aria-hidden': 'true', 'data-yeti-box': $id, 'data-resize': $id, - 'aria-labelledby': this.$anchor[0].id || GetYoDigits(6, 'dd-anchor') + 'aria-labelledby': this.$anchors[0].id || GetYoDigits(6, 'dd-anchor') }); super._init(); this._events(); @@ -87,7 +86,7 @@ class Dropdown extends Positionable { _getDefaultAlignment() { // handle legacy float approach - var horizontalPosition = /float-(\S+)/.exec(this.$anchor[0].className); + var horizontalPosition = /float-(\S+)/.exec(this.$anchors[0].className); if(horizontalPosition) { return horizontalPosition[1]; } @@ -104,7 +103,19 @@ class Dropdown extends Positionable { * @private */ _setPosition() { - super._setPosition(this.$anchor, this.$element, this.$parent); + super._setPosition(this.$anchors.filter('[data-is-primary]').first(), this.$element, this.$parent); + } + + /** + * Make it a primary anchor. + * primary anchor as the reference for the position of Dropdown panes. + * @param {HTML} el - DOM element of the anchor. + * @function + * @private + */ + _setPrimaryAnchor(el) { + this.$anchors.removeAttr('data-is-primary'); + $(el).attr('data-is-primary', true); } /** @@ -121,22 +132,27 @@ class Dropdown extends Positionable { 'resizeme.zf.trigger': this._setPosition.bind(this) }); + this.$anchors.off('click.zf.trigger') + .on('click.zf.trigger', function() { _this._setPrimaryAnchor(this); }); + if(this.options.hover){ - this.$anchor.off('mouseenter.zf.dropdown mouseleave.zf.dropdown') + this.$anchors.off('mouseenter.zf.dropdown mouseleave.zf.dropdown') .on('mouseenter.zf.dropdown', function(){ + _this._setPrimaryAnchor(this); + var bodyData = $('body').data(); if(typeof(bodyData.whatinput) === 'undefined' || bodyData.whatinput === 'mouse') { clearTimeout(_this.timeout); _this.timeout = setTimeout(function(){ _this.open(); - _this.$anchor.data('hover', true); + _this.$anchors.data('hover', true); }, _this.options.hoverDelay); } }).on('mouseleave.zf.dropdown', function(){ clearTimeout(_this.timeout); _this.timeout = setTimeout(function(){ _this.close(); - _this.$anchor.data('hover', false); + _this.$anchors.data('hover', false); }, _this.options.hoverDelay); }); if(this.options.hoverPane){ @@ -147,19 +163,19 @@ class Dropdown extends Positionable { clearTimeout(_this.timeout); _this.timeout = setTimeout(function(){ _this.close(); - _this.$anchor.data('hover', false); + _this.$anchors.data('hover', false); }, _this.options.hoverDelay); }); } } - this.$anchor.add(this.$element).on('keydown.zf.dropdown', function(e) { + this.$anchors.add(this.$element).on('keydown.zf.dropdown', function(e) { var $target = $(this), visibleFocusableElements = Keyboard.findFocusable(_this.$element); Keyboard.handleKey(e, 'Dropdown', { open: function() { - if ($target.is(_this.$anchor)) { + if ($target.is(_this.$anchors)) { _this.open(); _this.$element.attr('tabindex', -1).focus(); e.preventDefault(); @@ -167,7 +183,7 @@ class Dropdown extends Positionable { }, close: function() { _this.close(); - _this.$anchor.focus(); + _this.$anchors.focus(); } }); }); @@ -183,7 +199,7 @@ class Dropdown extends Positionable { _this = this; $body.off('click.zf.dropdown') .on('click.zf.dropdown', function(e){ - if(_this.$anchor.is(e.target) || _this.$anchor.find(e.target).length) { + if(_this.$anchors.is(e.target) || _this.$anchors.find(e.target).length) { return; } if(_this.$element.find(e.target).length) { @@ -207,7 +223,7 @@ class Dropdown extends Positionable { * @event Dropdown#closeme */ this.$element.trigger('closeme.zf.dropdown', this.$element.attr('id')); - this.$anchor.addClass('hover') + this.$anchors.addClass('hover') .attr({'aria-expanded': true}); // this.$element/*.show()*/; @@ -248,7 +264,7 @@ class Dropdown extends Positionable { this.$element.removeClass('is-open') .attr({'aria-hidden': true}); - this.$anchor.removeClass('hover') + this.$anchors.removeClass('hover') .attr('aria-expanded', false); /** @@ -268,7 +284,7 @@ class Dropdown extends Positionable { */ toggle() { if(this.$element.hasClass('is-open')){ - if(this.$anchor.data('hover')) return; + if(this.$anchors.data('hover')) return; this.close(); }else{ this.open(); @@ -281,7 +297,7 @@ class Dropdown extends Positionable { */ _destroy() { this.$element.off('.zf.trigger').hide(); - this.$anchor.off('.zf.dropdown'); + this.$anchors.off('.zf.dropdown'); $(document.body).off('click.zf.dropdown'); } From 5445fc7bc2bd4f19dee2243a7d428ca26b5c9194 Mon Sep 17 00:00:00 2001 From: koki-higashikawa Date: Sat, 8 Jul 2017 12:10:57 +0900 Subject: [PATCH 2/3] state-driven approach to the javascript --- js/foundation.dropdown.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/js/foundation.dropdown.js b/js/foundation.dropdown.js index dff3708cf8..47e52ac0b0 100644 --- a/js/foundation.dropdown.js +++ b/js/foundation.dropdown.js @@ -58,6 +58,8 @@ class Dropdown extends Positionable { 'aria-expanded': false }); + this._setCurrentAnchor(this.$anchors.first()); + if(this.options.parentClass){ this.$parent = this.$element.parents('.' + this.options.parentClass); }else{ @@ -68,7 +70,7 @@ class Dropdown extends Positionable { 'aria-hidden': 'true', 'data-yeti-box': $id, 'data-resize': $id, - 'aria-labelledby': this.$anchors[0].id || GetYoDigits(6, 'dd-anchor') + 'aria-labelledby': this.$currentAnchor.id || GetYoDigits(6, 'dd-anchor') }); super._init(); this._events(); @@ -86,7 +88,7 @@ class Dropdown extends Positionable { _getDefaultAlignment() { // handle legacy float approach - var horizontalPosition = /float-(\S+)/.exec(this.$anchors[0].className); + var horizontalPosition = /float-(\S+)/.exec(this.$currentAnchor.className); if(horizontalPosition) { return horizontalPosition[1]; } @@ -103,19 +105,18 @@ class Dropdown extends Positionable { * @private */ _setPosition() { - super._setPosition(this.$anchors.filter('[data-is-primary]').first(), this.$element, this.$parent); + super._setPosition(this.$currentAnchor, this.$element, this.$parent); } /** - * Make it a primary anchor. - * primary anchor as the reference for the position of Dropdown panes. + * Make it a current anchor. + * Current anchor as the reference for the position of Dropdown panes. * @param {HTML} el - DOM element of the anchor. * @function * @private */ - _setPrimaryAnchor(el) { - this.$anchors.removeAttr('data-is-primary'); - $(el).attr('data-is-primary', true); + _setCurrentAnchor(el) { + this.$currentAnchor = $(el); } /** @@ -133,12 +134,12 @@ class Dropdown extends Positionable { }); this.$anchors.off('click.zf.trigger') - .on('click.zf.trigger', function() { _this._setPrimaryAnchor(this); }); + .on('click.zf.trigger', function() { _this._setCurrentAnchor(this); }); if(this.options.hover){ this.$anchors.off('mouseenter.zf.dropdown mouseleave.zf.dropdown') .on('mouseenter.zf.dropdown', function(){ - _this._setPrimaryAnchor(this); + _this._setCurrentAnchor(this); var bodyData = $('body').data(); if(typeof(bodyData.whatinput) === 'undefined' || bodyData.whatinput === 'mouse') { From 8e88a4439421063aac2f11f902d95576b0fd099a Mon Sep 17 00:00:00 2001 From: koki-higashikawa Date: Sat, 8 Jul 2017 15:25:35 +0900 Subject: [PATCH 3/3] Add visual test. --- .../dropdown/open-the-same-dropdown.html | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 test/visual/dropdown/open-the-same-dropdown.html diff --git a/test/visual/dropdown/open-the-same-dropdown.html b/test/visual/dropdown/open-the-same-dropdown.html new file mode 100644 index 0000000000..84defcd3b9 --- /dev/null +++ b/test/visual/dropdown/open-the-same-dropdown.html @@ -0,0 +1,43 @@ + + + + + + + + + Foundation for Sites Testing + + + +
+
+
+

Dropdown: Open The Same

+ +

Clickable:

+ + + + + +

Hoverable:

+ + + + +
+
+
+ + + + + +