From 8eee78ca15f51dc7e7d514497078bfd7c012ac21 Mon Sep 17 00:00:00 2001 From: fat <fat@folders.local> Date: Mon, 11 May 2015 12:29:06 -0700 Subject: [PATCH] tab es6 --- Gruntfile.js | 3 +- js/dist/scrollspy.js | 1 - js/dist/scrollspy.js.map | Bin 13403 -> 13346 bytes js/dist/tab.js | 270 +++++++++++++++++++++++++++++++++++++ js/dist/tab.js.map | Bin 0 -> 13219 bytes js/scrollspy.js | 172 ------------------------ js/src/scrollspy.js | 9 +- js/src/tab.js | 278 +++++++++++++++++++++++++++++++++++++++ js/tests/index.html | 2 +- js/tests/visual/tab.html | 38 +++--- 10 files changed, 574 insertions(+), 199 deletions(-) create mode 100644 js/dist/tab.js create mode 100644 js/dist/tab.js.map delete mode 100644 js/scrollspy.js create mode 100644 js/src/tab.js diff --git a/Gruntfile.js b/Gruntfile.js index b3c29c3533..84e3f9bb24 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -70,7 +70,8 @@ module.exports = function (grunt) { 'js/dist/collapse.js' : 'js/src/collapse.js', 'js/dist/dropdown.js' : 'js/src/dropdown.js', 'js/dist/modal.js' : 'js/src/modal.js', - 'js/dist/scrollspy.js' : 'js/src/scrollspy.js' + 'js/dist/scrollspy.js' : 'js/src/scrollspy.js', + 'js/dist/tab.js' : 'js/src/tab.js' } } }, diff --git a/js/dist/scrollspy.js b/js/dist/scrollspy.js index a0d774f438..7cacbab8b9 100644 --- a/js/dist/scrollspy.js +++ b/js/dist/scrollspy.js @@ -23,7 +23,6 @@ var ScrollSpy = (function ($) { var VERSION = '4.0.0'; var DATA_KEY = 'bs.scrollspy'; var JQUERY_NO_CONFLICT = $.fn[NAME]; - var TRANSITION_DURATION = 150; var Defaults = { offset: 10 diff --git a/js/dist/scrollspy.js.map b/js/dist/scrollspy.js.map index ba686262fc673f2f9f97afea8a501eb0480ca028..dcd3cf1b02136d5e850296e9d0ccef9ec6024b89 100644 GIT binary patch delta 243 zcmcbeu_$B0)Wl3Dop49Ta2;nyM@MT%N9Ph}9bZRBUmbr(M}Hl6N5^Cc3nrZdl@4@t z3<OCh>Li2Iz@)37(%DXqj@eEi1@4mzSwtrv5a;3ss{vZ!TI9Uhk?{>1ud|^uOt*8| zW-AV9ZYE35$#udildFYw7|k}X5I)2xQsm>V6YS_1Yz+gBj+vY5L{(WQFOkxkd|paz l@;5169$N(!y|lb&KSy8J*v-Mx(>VBJ@)VH4=9kJv0swKdMGF7` delta 296 zcmZ3KaXVwe)WmEjop49Ta2;nyM@MT%N9QtU9bZRBUmbr(M}Hl6N5@nM3nrZhl@4@t z3<OCh>m-8+n6x2OI@`(75oj_{f#>7^7SYM`#kt^WN}y_TfogKWYTQ8z-60BqZgACi z+N{9%hK<+J6=u4#vCC#j4ry*CbI-}K!YY%agmoBAHn$5OViYOxan}iUbPTqJ0Y}I5 z&9S1Ytdkq1v?s5YQlETLO3y&SRzXECEic;7(bqLLCQm^jIX|zsL?I-|(J$CD#M9p| a-X%215ySwhG&D8X%q=~QWAg^(A^`w3-BU#X diff --git a/js/dist/tab.js b/js/dist/tab.js new file mode 100644 index 0000000000..8c71d01714 --- /dev/null +++ b/js/dist/tab.js @@ -0,0 +1,270 @@ +'use strict'; + +var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0): tab.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +var Tab = (function ($) { + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME = 'tab'; + var VERSION = '4.0.0'; + var DATA_KEY = 'bs.tab'; + var JQUERY_NO_CONFLICT = $.fn[NAME]; + var TRANSITION_DURATION = 150; + + var Event = { + HIDE: 'hide.bs.tab', + HIDDEN: 'hidden.bs.tab', + SHOW: 'show.bs.tab', + SHOWN: 'shown.bs.tab', + CLICK: 'click.bs.tab.data-api' + }; + + var ClassName = { + DROPDOWN_MENU: 'dropdown-menu', + ACTIVE: 'active', + FADE: 'fade', + IN: 'in' + }; + + var Selector = { + A: 'a', + LI: 'li', + LI_DROPDOWN: 'li.dropdown', + UL: 'ul:not(.dropdown-menu)', + FADE_CHILD: '> .fade', + ACTIVE: '.active', + ACTIVE_CHILD: '> .active', + DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"]', + DROPDOWN_ACTIVE_CHILD: '> .dropdown-menu > .active' + }; + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var Tab = (function () { + function Tab(element) { + _classCallCheck(this, Tab); + + this._element = element; + } + + _createClass(Tab, [{ + key: 'show', + + // public + + value: function show() { + var _this = this; + + if (this._element.parentNode && this._element.parentNode.nodeType == Node.ELEMENT_NODE && $(this._element).parent().hasClass(ClassName.ACTIVE)) { + return; + } + + var target = undefined; + var previous = undefined; + var ulElement = $(this._element).closest(Selector.UL)[0]; + var selector = Util.getSelectorFromElement(this._element); + + if (ulElement) { + previous = $.makeArray($(ulElement).find(Selector.ACTIVE)); + previous = previous[previous.length - 1]; + + if (previous) { + previous = $(previous).find(Selector.A)[0]; + } + } + + var hideEvent = $.Event(Event.HIDE, { + relatedTarget: this._element + }); + + var showEvent = $.Event(Event.SHOW, { + relatedTarget: previous + }); + + if (previous) { + $(previous).trigger(hideEvent); + } + + $(this._element).trigger(showEvent); + + if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) { + return; + } + + if (selector) { + target = $(selector)[0]; + } + + this._activate($(this._element).closest(Selector.LI)[0], ulElement); + + var complete = function complete() { + var hiddenEvent = $.Event(Event.HIDDEN, { + relatedTarget: _this._element + }); + + var shownEvent = $.Event(Event.SHOWN, { + relatedTarget: previous + }); + + $(previous).trigger(hiddenEvent); + $(_this._element).trigger(shownEvent); + }; + + if (target) { + this._activate(target, target.parentNode, complete); + } else { + complete(); + } + } + }, { + key: '_activate', + + // private + + value: function _activate(element, container, callback) { + var active = $(container).find(Selector.ACTIVE_CHILD)[0]; + var isTransitioning = callback && Util.supportsTransitionEnd() && (active && $(active).hasClass(ClassName.FADE) || !!$(container).find(Selector.FADE_CHILD)[0]); + + var complete = this._transitionComplete.bind(this, element, active, isTransitioning, callback); + + if (active && isTransitioning) { + $(active).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION); + } else { + complete(); + } + + if (active) { + $(active).removeClass(ClassName.IN); + } + } + }, { + key: '_transitionComplete', + value: function _transitionComplete(element, active, isTransitioning, callback) { + if (active) { + $(active).removeClass(ClassName.ACTIVE); + + var dropdownChild = $(active).find(Selector.DROPDOWN_ACTIVE_CHILD)[0]; + if (dropdownChild) { + $(dropdownChild).removeClass(ClassName.ACTIVE); + } + + var activeToggle = $(active).find(Selector.DATA_TOGGLE)[0]; + if (activeToggle) { + activeToggle.setAttribute('aria-expanded', false); + } + } + + $(element).addClass(ClassName.ACTIVE); + + var elementToggle = $(element).find(Selector.DATA_TOGGLE)[0]; + if (elementToggle) { + elementToggle.setAttribute('aria-expanded', true); + } + + if (isTransitioning) { + Util.reflow(element); + $(element).addClass(ClassName.IN); + } else { + $(element).removeClass(ClassName.FADE); + } + + if (element.parentNode && $(element.parentNode).hasClass(ClassName.DROPDOWN_MENU)) { + + var dropdownElement = $(element).closest(Selector.LI_DROPDOWN)[0]; + if (dropdownElement) { + $(dropdownElement).addClass(ClassName.ACTIVE); + } + + elementToggle = $(element).find(Selector.DATA_TOGGLE)[0]; + if (elementToggle) { + elementToggle.setAttribute('aria-expanded', true); + } + } + + if (callback) { + callback(); + } + } + }], [{ + key: 'VERSION', + + // getters + + get: function () { + return VERSION; + } + }, { + key: 'Default', + get: function () { + return Default; + } + }, { + key: '_jQueryInterface', + + // static + + value: function _jQueryInterface(config) { + return this.each(function () { + var $this = $(this); + var data = $this.data(DATA_KEY); + + if (!data) { + data = data = new Tab(this); + $this.data(DATA_KEY, data); + } + + if (typeof config === 'string') { + data[config](); + } + }); + } + }]); + + return Tab; + })(); + + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + $(document).on(Event.CLICK, Selector.DATA_TOGGLE, function (event) { + event.preventDefault(); + Tab._jQueryInterface.call($(this), 'show'); + }); + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = Tab._jQueryInterface; + $.fn[NAME].Constructor = Tab; + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT; + return Tab._jQueryInterface; + }; + + return Tab; +})(jQuery); +//# sourceMappingURL=tab.js.map \ No newline at end of file diff --git a/js/dist/tab.js.map b/js/dist/tab.js.map new file mode 100644 index 0000000000000000000000000000000000000000..6981e217a58667076fb68a9be96fcb40bd3fd545 GIT binary patch literal 13219 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 Us~jT*{mM2m_kafI+UrmM1%HkcrvLx| literal 0 HcmV?d00001 diff --git a/js/scrollspy.js b/js/scrollspy.js deleted file mode 100644 index f860c1abad..0000000000 --- a/js/scrollspy.js +++ /dev/null @@ -1,172 +0,0 @@ -/* ======================================================================== - * Bootstrap: scrollspy.js v3.3.4 - * http://getbootstrap.com/javascript/#scrollspy - * ======================================================================== - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * ======================================================================== */ - - -+function ($) { - 'use strict'; - - // SCROLLSPY CLASS DEFINITION - // ========================== - - function ScrollSpy(element, options) { - this.$body = $(document.body) - this.$scrollElement = $(element).is(document.body) ? $(window) : $(element) - this.options = $.extend({}, ScrollSpy.DEFAULTS, options) - this.selector = (this.options.target || '') + ' .nav li > a' - this.offsets = [] - this.targets = [] - this.activeTarget = null - this.scrollHeight = 0 - - this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) - this.refresh() - this.process() - } - - ScrollSpy.VERSION = '3.3.4' - - ScrollSpy.DEFAULTS = { - offset: 10 - } - - ScrollSpy.prototype.getScrollHeight = function () { - return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) - } - - ScrollSpy.prototype.refresh = function () { - var that = this - var offsetMethod = 'offset' - var offsetBase = 0 - - this.offsets = [] - this.targets = [] - this.scrollHeight = this.getScrollHeight() - - if (!$.isWindow(this.$scrollElement[0])) { - offsetMethod = 'position' - offsetBase = this.$scrollElement.scrollTop() - } - - this.$body - .find(this.selector) - .map(function () { - var $el = $(this) - var href = $el.data('target') || $el.attr('href') - var $href = /^#./.test(href) && $(href) - - return ($href - && $href.length - && $href.is(':visible') - && [[$href[offsetMethod]().top + offsetBase, href]]) || null - }) - .sort(function (a, b) { return a[0] - b[0] }) - .each(function () { - that.offsets.push(this[0]) - that.targets.push(this[1]) - }) - } - - ScrollSpy.prototype.process = function () { - var scrollTop = this.$scrollElement.scrollTop() + this.options.offset - var scrollHeight = this.getScrollHeight() - var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() - var offsets = this.offsets - var targets = this.targets - var activeTarget = this.activeTarget - var i - - if (this.scrollHeight != scrollHeight) { - this.refresh() - } - - if (scrollTop >= maxScroll) { - return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) - } - - if (activeTarget && scrollTop < offsets[0]) { - this.activeTarget = null - return this.clear() - } - - for (i = offsets.length; i--;) { - activeTarget != targets[i] - && scrollTop >= offsets[i] - && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) - && this.activate(targets[i]) - } - } - - ScrollSpy.prototype.activate = function (target) { - this.activeTarget = target - - this.clear() - - var selector = this.selector + - '[data-target="' + target + '"],' + - this.selector + '[href="' + target + '"]' - - var active = $(selector) - .parents('li') - .addClass('active') - - if (active.parent('.dropdown-menu').length) { - active = active - .closest('li.dropdown') - .addClass('active') - } - - active.trigger('activate.bs.scrollspy') - } - - ScrollSpy.prototype.clear = function () { - $(this.selector) - .parentsUntil(this.options.target, '.active') - .removeClass('active') - } - - - // SCROLLSPY PLUGIN DEFINITION - // =========================== - - function Plugin(option) { - return this.each(function () { - var $this = $(this) - var data = $this.data('bs.scrollspy') - var options = typeof option == 'object' && option - - if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) - if (typeof option == 'string') data[option]() - }) - } - - var old = $.fn.scrollspy - - $.fn.scrollspy = Plugin - $.fn.scrollspy.Constructor = ScrollSpy - - - // SCROLLSPY NO CONFLICT - // ===================== - - $.fn.scrollspy.noConflict = function () { - $.fn.scrollspy = old - return this - } - - - // SCROLLSPY DATA-API - // ================== - - $(window).on('load.bs.scrollspy.data-api', function () { - $('[data-spy="scroll"]').each(function () { - var $spy = $(this) - Plugin.call($spy, $spy.data()) - }) - }) - -}(jQuery); diff --git a/js/src/scrollspy.js b/js/src/scrollspy.js index 985da708d0..b66f7bb886 100644 --- a/js/src/scrollspy.js +++ b/js/src/scrollspy.js @@ -17,11 +17,10 @@ const ScrollSpy = (($) => { * ------------------------------------------------------------------------ */ - const NAME = 'scrollspy' - const VERSION = '4.0.0' - const DATA_KEY = 'bs.scrollspy' - const JQUERY_NO_CONFLICT = $.fn[NAME] - const TRANSITION_DURATION = 150 + const NAME = 'scrollspy' + const VERSION = '4.0.0' + const DATA_KEY = 'bs.scrollspy' + const JQUERY_NO_CONFLICT = $.fn[NAME] const Defaults = { offset : 10 diff --git a/js/src/tab.js b/js/src/tab.js new file mode 100644 index 0000000000..4668ff9e69 --- /dev/null +++ b/js/src/tab.js @@ -0,0 +1,278 @@ +import Util from './util' + + +/** + * -------------------------------------------------------------------------- + * Bootstrap (v4.0.0): tab.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * -------------------------------------------------------------------------- + */ + +const Tab = (($) => { + + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + const NAME = 'tab' + const VERSION = '4.0.0' + const DATA_KEY = 'bs.tab' + const JQUERY_NO_CONFLICT = $.fn[NAME] + const TRANSITION_DURATION = 150 + + const Event = { + HIDE : 'hide.bs.tab', + HIDDEN : 'hidden.bs.tab', + SHOW : 'show.bs.tab', + SHOWN : 'shown.bs.tab', + CLICK : 'click.bs.tab.data-api' + } + + const ClassName = { + DROPDOWN_MENU : 'dropdown-menu', + ACTIVE : 'active', + FADE : 'fade', + IN : 'in' + } + + const Selector = { + A : 'a', + LI : 'li', + LI_DROPDOWN : 'li.dropdown', + UL : 'ul:not(.dropdown-menu)', + FADE_CHILD : '> .fade', + ACTIVE : '.active', + ACTIVE_CHILD : '> .active', + DATA_TOGGLE : '[data-toggle="tab"], [data-toggle="pill"]', + DROPDOWN_ACTIVE_CHILD : '> .dropdown-menu > .active' + } + + + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + class Tab { + + constructor(element) { + this._element = element + } + + + // getters + + static get VERSION() { + return VERSION + } + + static get Default() { + return Default + } + + + // public + + show() { + if (this._element.parentNode && + (this._element.parentNode.nodeType == Node.ELEMENT_NODE) && + ($(this._element).parent().hasClass(ClassName.ACTIVE))) { + return + } + + let target + let previous + let ulElement = $(this._element).closest(Selector.UL)[0] + let selector = Util.getSelectorFromElement(this._element) + + if (ulElement) { + previous = $.makeArray($(ulElement).find(Selector.ACTIVE)) + previous = previous[previous.length - 1] + + if (previous) { + previous = $(previous).find(Selector.A)[0] + } + } + + let hideEvent = $.Event(Event.HIDE, { + relatedTarget: this._element + }) + + let showEvent = $.Event(Event.SHOW, { + relatedTarget: previous + }) + + if (previous) { + $(previous).trigger(hideEvent) + } + + $(this._element).trigger(showEvent) + + if (showEvent.isDefaultPrevented() || + (hideEvent.isDefaultPrevented())) { + return + } + + if (selector) { + target = $(selector)[0] + } + + this._activate( + $(this._element).closest(Selector.LI)[0], + ulElement + ) + + let complete = () => { + let hiddenEvent = $.Event(Event.HIDDEN, { + relatedTarget: this._element + }) + + let shownEvent = $.Event(Event.SHOWN, { + relatedTarget: previous + }) + + $(previous).trigger(hiddenEvent) + $(this._element).trigger(shownEvent) + } + + if (target) { + this._activate(target, target.parentNode, complete) + } else { + complete() + } + } + + + // private + + _activate(element, container, callback) { + let active = $(container).find(Selector.ACTIVE_CHILD)[0] + let isTransitioning = callback + && Util.supportsTransitionEnd() + && ((active && $(active).hasClass(ClassName.FADE)) + || !!$(container).find(Selector.FADE_CHILD)[0]) + + let complete = this._transitionComplete.bind( + this, element, active, isTransitioning, callback) + + if (active && isTransitioning) { + $(active) + .one(Util.TRANSITION_END, complete) + .emulateTransitionEnd(TRANSITION_DURATION) + + } else { + complete() + } + + if (active) { + $(active).removeClass(ClassName.IN) + } + } + + _transitionComplete(element, active, isTransitioning, callback) { + if (active) { + $(active).removeClass(ClassName.ACTIVE) + + let dropdownChild = $(active).find( + Selector.DROPDOWN_ACTIVE_CHILD + )[0] + if (dropdownChild) { + $(dropdownChild).removeClass(ClassName.ACTIVE) + } + + let activeToggle = $(active).find(Selector.DATA_TOGGLE)[0] + if (activeToggle) { + activeToggle.setAttribute('aria-expanded', false) + } + } + + $(element).addClass(ClassName.ACTIVE) + + let elementToggle = $(element).find(Selector.DATA_TOGGLE)[0] + if (elementToggle) { + elementToggle.setAttribute('aria-expanded', true) + } + + if (isTransitioning) { + Util.reflow(element) + $(element).addClass(ClassName.IN) + } else { + $(element).removeClass(ClassName.FADE) + } + + if (element.parentNode && + ($(element.parentNode).hasClass(ClassName.DROPDOWN_MENU))) { + + let dropdownElement = $(element).closest(Selector.LI_DROPDOWN)[0] + if (dropdownElement) { + $(dropdownElement).addClass(ClassName.ACTIVE) + } + + elementToggle = $(element).find(Selector.DATA_TOGGLE)[0] + if (elementToggle) { + elementToggle.setAttribute('aria-expanded', true) + } + } + + if (callback) { + callback() + } + } + + + // static + + static _jQueryInterface(config) { + return this.each(function () { + let $this = $(this) + let data = $this.data(DATA_KEY) + + if (!data) { + data = data = new Tab(this) + $this.data(DATA_KEY, data) + } + + if (typeof config === 'string') { + data[config]() + } + }) + } + + } + + + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + $(document) + .on(Event.CLICK, Selector.DATA_TOGGLE, function (event) { + event.preventDefault() + Tab._jQueryInterface.call($(this), 'show') + }) + + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + $.fn[NAME] = Tab._jQueryInterface + $.fn[NAME].Constructor = Tab + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT + return Tab._jQueryInterface + } + + return Tab + +})(jQuery) + +export default Tab diff --git a/js/tests/index.html b/js/tests/index.html index 0262eec2a9..6f325115bb 100644 --- a/js/tests/index.html +++ b/js/tests/index.html @@ -138,9 +138,9 @@ <script src="../../js/dist/dropdown.js"></script> <script src="../../js/dist/modal.js"></script> <script src="../../js/dist/scrollspy.js"></script> + <script src="../../js/dist/tab.js"></script> <!-- Old Plugin sources --> - <script src="../../js/tab.js"></script> <script src="../../js/tooltip.js"></script> <script src="../../js/popover.js"></script> diff --git a/js/tests/visual/tab.html b/js/tests/visual/tab.html index a3fed1e9fa..ff6685fede 100644 --- a/js/tests/visual/tab.html +++ b/js/tests/visual/tab.html @@ -35,10 +35,10 @@ <h4>Tabs without fade</h4> <ul id="myTab" class="nav nav-tabs"> - <li class="active"><a href="#home" data-toggle="tab">Home</a></li> - <li><a href="#profile" data-toggle="tab">Profile</a></li> - <li class="dropdown"> - <a href="#" id="myTabDrop1" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a> + <li class="active nav-item"><a href="#home" class="nav-link" data-toggle="tab">Home</a></li> + <li class="nav-item"><a href="#profile" data-toggle="tab" class="nav-link">Profile</a></li> + <li class="dropdown nav-item"> + <a href="#" id="myTabDrop1" class="dropdown-toggle nav-link" data-toggle="dropdown">Dropdown <b class="caret"></b></a> <ul class="dropdown-menu" role="menu" aria-labelledby="myTabDrop1"> <li><a href="#dropdown1" tabindex="-1" data-toggle="tab">@fat</a></li> <li><a href="#dropdown2" tabindex="-1" data-toggle="tab">@mdo</a></li> @@ -67,10 +67,10 @@ <h4>Tabs with fade</h4> <ul id="myTab1" class="nav nav-tabs"> - <li class="active"><a href="#home1" data-toggle="tab">Home</a></li> - <li><a href="#profile1" data-toggle="tab">Profile</a></li> - <li class="dropdown"> - <a href="#" id="myTabDrop2" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a> + <li class="active nav-item"><a class="nav-link" href="#home1" data-toggle="tab">Home</a></li> + <li class="nav-item"><a class="nav-link" href="#profile1" data-toggle="tab">Profile</a></li> + <li class="dropdown nav-item"> + <a href="#" id="myTabDrop2" class="dropdown-toggle nav-link" data-toggle="dropdown">Dropdown <b class="caret"></b></a> <ul class="dropdown-menu" role="menu" aria-labelledby="myTabDrop2"> <li><a href="#dropdown1-1" tabindex="-1" data-toggle="tab">@fat</a></li> <li><a href="#dropdown1-2" tabindex="-1" data-toggle="tab">@mdo</a></li> @@ -99,10 +99,10 @@ <h4>Tabs without fade (no initially active pane)</h4> <ul id="myTab2" class="nav nav-tabs"> - <li><a href="#home2" data-toggle="tab">Home</a></li> - <li><a href="#profile2" data-toggle="tab">Profile</a></li> - <li class="dropdown"> - <a href="#" id="myTabDrop3" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a> + <li class="nav-item"><a class="nav-link" href="#home2" data-toggle="tab">Home</a></li> + <li class="nav-item"><a class="nav-link" href="#profile2" data-toggle="tab">Profile</a></li> + <li class="dropdown nav-item"> + <a href="#" id="myTabDrop3" class="dropdown-toggle nav-link" data-toggle="dropdown">Dropdown <b class="caret"></b></a> <ul class="dropdown-menu" role="menu" aria-labelledby="myTabDrop3"> <li><a href="#dropdown2-1" tabindex="-1" data-toggle="tab">@fat</a></li> <li><a href="#dropdown2-2" tabindex="-1" data-toggle="tab">@mdo</a></li> @@ -131,10 +131,10 @@ <h4>Tabs with fade (no initially active pane)</h4> <ul id="myTab3" class="nav nav-tabs"> - <li><a href="#home3" data-toggle="tab">Home</a></li> - <li><a href="#profile3" data-toggle="tab">Profile</a></li> - <li class="dropdown"> - <a href="#" id="myTabDrop4" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a> + <li class="nav-item"><a class="nav-link" href="#home3" data-toggle="tab">Home</a></li> + <li class="nav-item"><a class="nav-link" href="#profile3" data-toggle="tab">Profile</a></li> + <li class="dropdown nav-item"> + <a href="#" id="myTabDrop4" class="dropdown-toggle nav-link" data-toggle="dropdown">Dropdown <b class="caret"></b></a> <ul class="dropdown-menu" role="menu" aria-labelledby="myTabDrop4"> <li><a href="#dropdown3-1" tabindex="-1" data-toggle="tab">@fat</a></li> <li><a href="#dropdown3-2" tabindex="-1" data-toggle="tab">@mdo</a></li> @@ -164,9 +164,9 @@ <!-- JavaScript Includes --> <script src="../vendor/jquery.min.js"></script> -<script src="../../transition.js"></script> -<script src="../../tab.js"></script> -<script src="../../dropdown.js"></script> +<script src="../../dist/util.js"></script> +<script src="../../dist/tab.js"></script> +<script src="../../dist/dropdown.js"></script> </body> </html> -- GitLab