From: Nicolas Coden Date: Thu, 11 Oct 2018 20:49:56 +0000 (+0200) Subject: Use pull request #11530 from ncoden/fix/tabs-accordion-deep-linking-11527 for v6.5.0 X-Git-Tag: v6.5.0-rc.4^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3c194db8a70fbe6ecdaa70e1543786d600687b55;p=thirdparty%2Ffoundation%2Ffoundation-sites.git Use pull request #11530 from ncoden/fix/tabs-accordion-deep-linking-11527 for v6.5.0 33c55db80 fix: fix scroll to deep-linking default anchor on initialization in Tabs/Accordion 8d4a13ead fix: prevent Tabs/Accordion to scroll to others components' anchors 7bccec66f fix: ensure Tab deep-linking to redirect to hash with # 9fbc2eeb5 test: add visual test for Tabs deep-linking Signed-off-by: Nicolas Coden --- diff --git a/js/foundation.accordion.js b/js/foundation.accordion.js index 311a5df96..b30ca15a2 100644 --- a/js/foundation.accordion.js +++ b/js/foundation.accordion.js @@ -40,6 +40,8 @@ class Accordion extends Plugin { * @private */ _init() { + this._isInitializing = true; + this.$element.attr('role', 'tablist'); this.$tabs = this.$element.children('[data-accordion-item]'); @@ -70,13 +72,17 @@ class Accordion extends Plugin { this._checkDeepLink = () => { var anchor = window.location.hash; - // If there is no anchor, return to the initial panel - if (!anchor.length && this._initialAnchor) { - anchor = this._initialAnchor; + if (!anchor.length) { + // If we are still initializing and there is no anchor, then there is nothing to do + if (this._isInitializing) return; + // Otherwise, move to the initial anchor + if (this._initialAnchor) anchor = this._initialAnchor; } var $anchor = anchor && $(anchor); var $link = anchor && this.$element.find(`[href$="${anchor}"]`); + // Whether the anchor element that has been found is part of this element + var isOwnAnchor = !!($anchor.length && $link.length); // If there is an anchor for the hash, open it (if not already active) if ($anchor && $link && $link.length) { @@ -89,15 +95,15 @@ class Accordion extends Plugin { this._closeAllTabs(); } - // Roll up a little to show the titles - if (this.options.deepLinkSmudge) { - onLoad($(window), () => { - var offset = this.$element.offset(); - $('html, body').animate({ scrollTop: offset.top }, this.options.deepLinkSmudgeDelay); - }); - } + if (isOwnAnchor) { + // Roll up a little to show the titles + if (this.options.deepLinkSmudge) { + onLoad($(window), () => { + var offset = this.$element.offset(); + $('html, body').animate({ scrollTop: offset.top }, this.options.deepLinkSmudgeDelay); + }); + } - if ($anchor && $link) { /** * Fires when the plugin has deeplinked at pageload * @event Accordion#deeplink @@ -112,6 +118,8 @@ class Accordion extends Plugin { } this._events(); + + this._isInitializing = false; } /** diff --git a/js/foundation.tabs.js b/js/foundation.tabs.js index 489640e53..4febb1cc3 100644 --- a/js/foundation.tabs.js +++ b/js/foundation.tabs.js @@ -45,6 +45,7 @@ class Tabs extends Plugin { */ _init() { var _this = this; + this._isInitializing = true; this.$element.attr({'role': 'tablist'}); this.$tabTitles = this.$element.find(`.${this.options.linkClass}`); @@ -105,13 +106,17 @@ class Tabs extends Plugin { this._checkDeepLink = () => { var anchor = window.location.hash; - // If there is no anchor, return to the initial panel - if (!anchor.length && this._initialAnchor) { - anchor = this._initialAnchor; + if (!anchor.length) { + // If we are still initializing and there is no anchor, then there is nothing to do + if (this._isInitializing) return; + // Otherwise, move to the initial anchor + if (this._initialAnchor) anchor = this._initialAnchor; } var $anchor = anchor && $(anchor); var $link = anchor && this.$element.find('[href$="'+anchor+'"]'); + // Whether the anchor element that has been found is part of this element + var isOwnAnchor = !!($anchor.length && $link.length); // If there is an anchor for the hash, select it if ($anchor && $anchor.length && $link && $link.length) { @@ -122,13 +127,13 @@ class Tabs extends Plugin { this._collapse(); } - // Roll up a little to show the titles - if (this.options.deepLinkSmudge) { - var offset = this.$element.offset(); - $('html, body').animate({ scrollTop: offset.top }, this.options.deepLinkSmudgeDelay); - } + if (isOwnAnchor) { + // Roll up a little to show the titles + if (this.options.deepLinkSmudge) { + var offset = this.$element.offset(); + $('html, body').animate({ scrollTop: offset.top }, this.options.deepLinkSmudgeDelay); + } - if ($anchor && $link) { /** * Fires when the plugin has deeplinked at pageload * @event Tabs#deeplink @@ -143,6 +148,8 @@ class Tabs extends Plugin { } this._events(); + + this._isInitializing = false; } /** @@ -252,8 +259,9 @@ class Tabs extends Plugin { var $oldTab = this.$element. find(`.${this.options.linkClass}.${this.options.linkActiveClass}`), $tabLink = $target.find('[role="tab"]'), - hash = $tabLink.attr('data-tabs-target') || $tabLink[0].hash.slice(1), - $targetContent = this.$tabContent.find(`#${hash}`); + target = $tabLink.attr('data-tabs-target'), + anchor = target && target.length ? `#${target}` : $tabLink[0].hash, + $targetContent = this.$tabContent.find(anchor); //close old tab this._collapseTab($oldTab); @@ -264,9 +272,9 @@ class Tabs extends Plugin { //either replace or update browser history if (this.options.deepLink && !historyHandled) { if (this.options.updateHistory) { - history.pushState({}, '', hash); + history.pushState({}, '', anchor); } else { - history.replaceState({}, '', hash); + history.replaceState({}, '', anchor); } } diff --git a/test/visual/tabs/deep-linking.html b/test/visual/tabs/deep-linking.html new file mode 100644 index 000000000..e2d908cf0 --- /dev/null +++ b/test/visual/tabs/deep-linking.html @@ -0,0 +1,86 @@ + + + + + + + + Tabs Deep Linking + + + +
+
+
+ +

Tabs Deep Linking

+ +

+

  • When a tab is set as active, #panel... should be set in the url. +
  • Refresing the page should make it scroll down to the active tab
  • +
  • Going back in history should restore the previous state (even if no all tabs were active before).
  • +

    + +
    + Placeholder +
    + + + +
    +
    +

    Content for #panel1. I should be active by default.

    +
    +
    +

    Content for #panel2

    +
    +
    +

    Content for #panel3

    +
    +
    +

    Content for #panel4

    +
    +
    + +
    + Placeholder +
    + + + +
    +
    +

    Content for #panel5. I can collapse.

    +
    +
    +

    Content for #panel6. I can collapse.

    +
    +
    +

    Content for #panel7. I can collapse.

    +
    +
    +

    Content for #panel8. I can collapse.

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