aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Otto <[email protected]>2017-06-14 19:13:44 -0700
committerMark Otto <[email protected]>2017-06-14 19:13:44 -0700
commit22bd955434ac3cb6d4a5a7f2d21129a9a7f4b343 (patch)
tree664ea7715e7ea5409fe26c5e89e33f6f6e04c168
parent3fb1bf7a20ea3fcc582e6b84416d7489a65880a8 (diff)
parent8f431fc5b81a3fddeb6d3907edf6f07c25df0f86 (diff)
downloadbootstrap-22bd955434ac3cb6d4a5a7f2d21129a9a7f4b343.tar.xz
bootstrap-22bd955434ac3cb6d4a5a7f2d21129a9a7f4b343.zip
Merge branch 'v4-dev' into form-tweaks
-rw-r--r--Gruntfile.js2
-rw-r--r--_config.yml4
-rw-r--r--assets/js/vendor/popper.min.js2
-rw-r--r--bower.json2
-rw-r--r--build/npm-shrinkwrap.json6
-rw-r--r--docs/4.0/components/collapse.md31
-rw-r--r--docs/4.0/components/dropdowns.md2
-rw-r--r--docs/4.0/components/popovers.md2
-rw-r--r--docs/4.0/components/tooltips.md2
-rw-r--r--docs/4.0/examples/album/index.html2
-rw-r--r--docs/4.0/examples/blog/index.html2
-rw-r--r--docs/4.0/examples/carousel/index.html2
-rw-r--r--docs/4.0/examples/cover/index.html2
-rw-r--r--docs/4.0/examples/dashboard/index.html2
-rw-r--r--docs/4.0/examples/jumbotron/index.html2
-rw-r--r--docs/4.0/examples/justified-nav/index.html2
-rw-r--r--docs/4.0/examples/navbar-top-fixed/index.html2
-rw-r--r--docs/4.0/examples/navbar-top/index.html2
-rw-r--r--docs/4.0/examples/navbars/index.html2
-rw-r--r--docs/4.0/examples/offcanvas/index.html2
-rw-r--r--docs/4.0/examples/starter-template/index.html2
-rw-r--r--docs/4.0/examples/sticky-footer-navbar/index.html2
-rw-r--r--docs/4.0/examples/tooltip-viewport/index.html2
-rw-r--r--js/src/collapse.js35
-rw-r--r--js/tests/unit/collapse.js93
-rw-r--r--js/tests/unit/dropdown.js34
-rw-r--r--js/tests/vendor/qunit.css4
-rw-r--r--js/tests/vendor/qunit.js563
-rw-r--r--package.json2
29 files changed, 521 insertions, 291 deletions
diff --git a/Gruntfile.js b/Gruntfile.js
index e3044bf04..351802b94 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -18,7 +18,7 @@ module.exports = function (grunt) {
concurrency: 10,
maxRetries: 3,
maxPollRetries: 4,
- urls: ['http://127.0.0.1:3000/js/tests/index.html?hidepassed'],
+ urls: ['http://localhost:3000/js/tests/index.html?hidepassed'],
browsers: grunt.file.readYAML('build/sauce_browsers.yml')
}
}
diff --git a/_config.yml b/_config.yml
index ebf6e74e7..b169e9d15 100644
--- a/_config.yml
+++ b/_config.yml
@@ -53,5 +53,5 @@ cdn:
js_hash: "sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn"
jquery: https://code.jquery.com/jquery-3.2.1.slim.min.js
jquery_hash: "sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
- popper: https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js
- popper_hash: "sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc="
+ popper: https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.10.1/umd/popper.min.js
+ popper_hash: "sha256-nxD3NU7Wocq19nG7DTQAx9troUwVoxjUhYrAhFSO3HM="
diff --git a/assets/js/vendor/popper.min.js b/assets/js/vendor/popper.min.js
index ac85cba98..2e231df3f 100644
--- a/assets/js/vendor/popper.min.js
+++ b/assets/js/vendor/popper.min.js
@@ -1,3 +1,3 @@
-var _Mathfloor=Math.floor,_Mathmin=Math.min,_Mathround=Math.round,_Mathmax=Math.max;(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function o(Ne){return''!==Ne&&!isNaN(parseFloat(Ne))&&isFinite(Ne)}function r(Ne,We){Object.keys(We).forEach(function(Pe){var De='';-1!==['width','height','top','right','bottom','left'].indexOf(Pe)&&o(We[Pe])&&(De='px'),Ne.style[Pe]=We[Pe]+De})}function p(Ne){return Ne&&'[object Function]'==={}.toString.call(Ne)}function s(Ne,We){if(1!==Ne.nodeType)return[];var Pe=window.getComputedStyle(Ne,null);return We?Pe[We]:Pe}function d(Ne){return'HTML'===Ne.nodeName?Ne:Ne.parentNode||Ne.host}function f(Ne){if(!Ne||-1!==['HTML','BODY','#document'].indexOf(Ne.nodeName))return window.document.body;var We=s(Ne),Pe=We.overflow,De=We.overflowX,He=We.overflowY;return /(auto|scroll)/.test(Pe+He+De)?Ne:f(d(Ne))}function l(Ne){var We=Ne.nodeName;return'BODY'!==We&&('HTML'===We||Ne.firstElementChild.offsetParent===Ne)}function m(Ne){return null===Ne.parentNode?Ne:m(Ne.parentNode)}function h(Ne){var We=Ne&&Ne.offsetParent,Pe=We&&We.nodeName;return Pe&&'BODY'!==Pe&&'HTML'!==Pe?We:window.document.documentElement}function c(Ne,We){if(!Ne||!Ne.nodeType||!We||!We.nodeType)return window.document.documentElement;var Pe=Ne.compareDocumentPosition(We)&Node.DOCUMENT_POSITION_FOLLOWING,De=Pe?Ne:We,He=Pe?We:Ne,Be=document.createRange();Be.setStart(De,0),Be.setEnd(He,0);var Me=Be.commonAncestorContainer;if(Ne!==Me&&We!==Me||De.contains(He))return l(Me)?Me:h(Me);var Ie=m(Ne);return Ie.host?c(Ie.host,We):c(Ne,m(We).host)}function u(Ne){var We=1<arguments.length&&void 0!==arguments[1]?arguments[1]:'top',Pe='top'===We?'scrollTop':'scrollLeft',De=Ne.nodeName;if('BODY'===De||'HTML'===De){var He=window.document.documentElement,Be=window.document.scrollingElement||He;return Be[Pe]}return Ne[Pe]}function g(Ne,We){var Pe=2<arguments.length&&void 0!==arguments[2]&&arguments[2],De=u(We,'top'),He=u(We,'left'),Be=Pe?-1:1;return Ne.top+=De*Be,Ne.bottom+=De*Be,Ne.left+=He*Be,Ne.right+=He*Be,Ne}function w(Ne,We){var Pe='x'===We?'Left':'Top',De='Left'==Pe?'Right':'Bottom';return+Ne['border'+Pe+'Width'].split('px')[0]+ +Ne['border'+De+'Width'].split('px')[0]}function E(Ne,We,Pe,De){return _Mathmax(We['offset'+Ne],Pe['client'+Ne],Pe['offset'+Ne],ye()?Pe['offset'+Ne]+De['margin'+('Height'===Ne?'Top':'Left')]+De['margin'+('Height'===Ne?'Bottom':'Right')]:0)}function v(){var Ne=window.document.body,We=window.document.documentElement,Pe=ye()&&window.getComputedStyle(We);return{height:E('Height',Ne,We,Pe),width:E('Width',Ne,We,Pe)}}function O(Ne){return xe({},Ne,{right:Ne.left+Ne.width,bottom:Ne.top+Ne.height})}function L(Ne){var We={};if(ye())try{We=Ne.getBoundingClientRect();var Pe=u(Ne,'top'),De=u(Ne,'left');We.top+=Pe,We.left+=De,We.bottom+=Pe,We.right+=De}catch(Ye){}else We=Ne.getBoundingClientRect();var He={left:We.left,top:We.top,width:We.right-We.left,height:We.bottom-We.top},Be='HTML'===Ne.nodeName?v():{},Me=Be.width||Ne.clientWidth||He.right-He.left,Ie=Be.height||Ne.clientHeight||He.bottom-He.top,Ae=Ne.offsetWidth-Me,Re=Ne.offsetHeight-Ie;if(Ae||Re){var Ue=s(Ne);Ae-=w(Ue,'x'),Re-=w(Ue,'y'),He.width-=Ae,He.height-=Re}return O(He)}function S(Ne,We){var Pe=ye(),De='HTML'===We.nodeName,He=L(Ne),Be=L(We),Me=f(Ne),Ie=O({top:He.top-Be.top,left:He.left-Be.left,width:He.width,height:He.height});if(De||'BODY'===We.nodeName){var Ae=s(We),Re=Pe&&De?0:+Ae.borderTopWidth.split('px')[0],Ue=Pe&&De?0:+Ae.borderLeftWidth.split('px')[0],Ye=Pe&&De?0:+Ae.marginTop.split('px')[0],Fe=Pe&&De?0:+Ae.marginLeft.split('px')[0];Ie.top-=Re-Ye,Ie.bottom-=Re-Ye,Ie.left-=Ue-Fe,Ie.right-=Ue-Fe,Ie.marginTop=Ye,Ie.marginLeft=Fe}return(Pe?We.contains(Me):We===Me&&'BODY'!==Me.nodeName)&&(Ie=g(Ie,We)),Ie}function C(Ne){var We=window.document.documentElement,Pe=S(Ne,We),De=_Mathmax(We.clientWidth,window.innerWidth||0),He=_Mathmax(We.clientHeight,window.innerHeight||0),Be=u(We),Me=u(We,'left'),Ie={top:Be-Pe.top+Pe.marginTop,left:Me-Pe.left+Pe.marginLeft,width:De,height:He};return O(Ie)}function T(Ne){var We=Ne.nodeName;return'BODY'===We||'HTML'===We?!1:'fixed'===s(Ne,'position')||T(d(Ne))}function k(Ne,We,Pe,De){var He={top:0,left:0},Be=c(Ne,We);if('viewport'===De)He=C(Be);else{var Me;'scrollParent'===De?(Me=f(d(Ne)),'BODY'===Me.nodeName&&(Me=window.document.documentElement)):'window'===De?Me=window.document.documentElement:Me=De;var Ie=S(Me,Be);if('HTML'===Me.nodeName&&!T(Be)){var Ae=v(),Re=Ae.height,Ue=Ae.width;He.top+=Ie.top-Ie.marginTop,He.bottom=Re+Ie.top,He.left+=Ie.left-Ie.marginLeft,He.right=Ue+Ie.left}else He=Ie}return He.left+=Pe,He.top+=Pe,He.right-=Pe,He.bottom-=Pe,He}function N(Ne){var We=Ne.width,Pe=Ne.height;return We*Pe}function W(Ne,We,Pe,De,He){var Be=5<arguments.length&&void 0!==arguments[5]?arguments[5]:0;if(-1===Ne.indexOf('auto'))return Ne;var Me=k(Pe,De,Be,He),Ie={top:{width:Me.width,height:We.top-Me.top},right:{width:Me.right-We.right,height:Me.height},bottom:{width:Me.width,height:Me.bottom-We.bottom},left:{width:We.left-Me.left,height:Me.height}},Ae=Object.keys(Ie).map(function(Fe){return xe({key:Fe},Ie[Fe],{area:N(Ie[Fe])})}).sort(function(Fe,je){return je.area-Fe.area}),Re=Ae.filter(function(Fe){var je=Fe.width,qe=Fe.height;return je>=Pe.clientWidth&&qe>=Pe.clientHeight}),Ue=0<Re.length?Re[0].key:Ae[0].key,Ye=Ne.split('-')[1];return Ue+(Ye?'-'+Ye:'')}function P(Ne,We,Pe){var De=c(We,Pe);return S(Pe,De)}function D(Ne){var We=window.getComputedStyle(Ne),Pe=parseFloat(We.marginTop)+parseFloat(We.marginBottom),De=parseFloat(We.marginLeft)+parseFloat(We.marginRight),He={width:Ne.offsetWidth+De,height:Ne.offsetHeight+Pe};return He}function H(Ne){var We={left:'right',right:'left',bottom:'top',top:'bottom'};return Ne.replace(/left|right|bottom|top/g,function(Pe){return We[Pe]})}function B(Ne,We,Pe){Pe=Pe.split('-')[0];var De=D(Ne),He={width:De.width,height:De.height},Be=-1!==['right','left'].indexOf(Pe),Me=Be?'top':'left',Ie=Be?'left':'top',Ae=Be?'height':'width',Re=Be?'width':'height';return He[Me]=We[Me]+We[Ae]/2-De[Ae]/2,He[Ie]=Pe===Ie?We[Ie]-De[Re]:We[H(Ie)],He}function M(Ne,We){return Array.prototype.find?Ne.find(We):Ne.filter(We)[0]}function I(Ne,We,Pe){if(Array.prototype.findIndex)return Ne.findIndex(function(He){return He[We]===Pe});var De=M(Ne,function(He){return He[We]===Pe});return Ne.indexOf(De)}function A(Ne,We,Pe){var De=void 0===Pe?Ne:Ne.slice(0,I(Ne,'name',Pe));return De.forEach(function(He){He.function&&console.warn('`modifier.function` is deprecated, use `modifier.fn`!');var Be=He.function||He.fn;He.enabled&&p(Be)&&(We=Be(We,He))}),We}function R(){if(!this.state.isDestroyed){var Ne={instance:this,styles:{},attributes:{},flipped:!1,offsets:{}};Ne.offsets.reference=P(this.state,this.popper,this.reference),Ne.placement=W(this.options.placement,Ne.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),Ne.originalPlacement=Ne.placement,Ne.offsets.popper=B(this.popper,Ne.offsets.reference,Ne.placement),Ne.offsets.popper.position='absolute',Ne=A(this.modifiers,Ne),this.state.isCreated?this.options.onUpdate(Ne):(this.state.isCreated=!0,this.options.onCreate(Ne))}}function U(Ne,We){return Ne.some(function(Pe){var De=Pe.name,He=Pe.enabled;return He&&De===We})}function Y(Ne){for(var We=[!1,'ms','webkit','moz','o'],Pe=Ne.charAt(0).toUpperCase()+Ne.slice(1),De=0;De<We.length-1;De++){var He=We[De],Be=He?''+He+Pe:Ne;if('undefined'!=typeof window.document.body.style[Be])return Be}return null}function F(){return this.state.isDestroyed=!0,U(this.modifiers,'applyStyle')&&(this.popper.removeAttribute('x-placement'),this.popper.style.left='',this.popper.style.position='',this.popper.style.top='',this.popper.style[Y('transform')]=''),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function j(Ne,We,Pe,De){var He='BODY'===Ne.nodeName,Be=He?window:Ne;Be.addEventListener(We,Pe,{passive:!0}),He||j(f(Be.parentNode),We,Pe,De),De.push(Be)}function q(Ne,We,Pe,De){Pe.updateBound=De,window.addEventListener('resize',Pe.updateBound,{passive:!0});var He=f(Ne);return j(He,'scroll',Pe.updateBound,Pe.scrollParents),Pe.scrollElement=He,Pe.eventsEnabled=!0,Pe}function K(){this.state.eventsEnabled||(this.state=q(this.reference,this.options,this.state,this.scheduleUpdate))}function z(Ne,We){return window.removeEventListener('resize',We.updateBound),We.scrollParents.forEach(function(Pe){Pe.removeEventListener('scroll',We.updateBound)}),We.updateBound=null,We.scrollParents=[],We.scrollElement=null,We.eventsEnabled=!1,We}function _(){this.state.eventsEnabled&&(window.cancelAnimationFrame(this.scheduleUpdate),this.state=z(this.reference,this.state))}function V(Ne,We){Object.keys(We).forEach(function(Pe){var De=We[Pe];!1===De?Ne.removeAttribute(Pe):Ne.setAttribute(Pe,We[Pe])})}function Q(Ne,We,Pe){var De=M(Ne,function(Ie){var Ae=Ie.name;return Ae===We}),He=!!De&&Ne.some(function(Ie){return Ie.name===Pe&&Ie.enabled&&Ie.order<De.order});if(!He){var Be='`'+We+'`';console.warn('`'+Pe+'`'+' modifier is required by '+Be+' modifier in order to work, be sure to include it before '+Be+'!')}return He}function $(Ne){return'end'===Ne?'start':'start'===Ne?'end':Ne}function J(Ne){var We=1<arguments.length&&void 0!==arguments[1]&&arguments[1],Pe=Le.indexOf(Ne),De=Le.slice(Pe+1).concat(Le.slice(0,Pe));return We?De.reverse():De}function oe(Ne,We,Pe,De){var He=Ne.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),Be=+He[1],Me=He[2];if(!Be)return Ne;if(0===Me.indexOf('%')){var Ie;switch(Me){case'%p':Ie=Pe;break;case'%':case'%r':default:Ie=De;}var Ae=O(Ie);return Ae[We]/100*Be}if('vh'===Me||'vw'===Me){var Re;return Re='vh'===Me?_Mathmax(document.documentElement.clientHeight,window.innerHeight||0):_Mathmax(document.documentElement.clientWidth,window.innerWidth||0),Re/100*Be}return Be}function ie(Ne,We,Pe,De){var He=[0,0],Be=-1!==['right','left'].indexOf(De),Me=Ne.split(/(\+|\-)/).map(function(Ue){return Ue.trim()}),Ie=Me.indexOf(M(Me,function(Ue){return-1!==Ue.search(/,|\s/)}));Me[Ie]&&-1===Me[Ie].indexOf(',')&&console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');var Ae=/\s*,\s*|\s+/,Re=-1===Ie?[Me]:[Me.slice(0,Ie).concat([Me[Ie].split(Ae)[0]]),[Me[Ie].split(Ae)[1]].concat(Me.slice(Ie+1))];return Re=Re.map(function(Ue,Ye){var Fe=(1===Ye?!Be:Be)?'height':'width',je=!1;return Ue.reduce(function(qe,Ke){return''===qe[qe.length-1]&&-1!==['+','-'].indexOf(Ke)?(qe[qe.length-1]=Ke,je=!0,qe):je?(qe[qe.length-1]+=Ke,je=!1,qe):qe.concat(Ke)},[]).map(function(qe){return oe(qe,Fe,We,Pe)})}),Re.forEach(function(Ue,Ye){Ue.forEach(function(Fe,je){o(Fe)&&(He[Ye]+=Fe*('-'===Ue[je-1]?-1:1))})}),He}for(var de=['native code','[object MutationObserverConstructor]'],fe=function(Ne){return de.some(function(We){return-1<(Ne||'').toString().indexOf(We)})},le='undefined'!=typeof window,me=['Edge','Trident','Firefox'],he=0,ce=0;ce<me.length;ce+=1)if(le&&0<=navigator.userAgent.indexOf(me[ce])){he=1;break}var be,ue=le&&fe(window.MutationObserver),ge=ue?function(Ne){var We=!1,Pe=0,De=document.createElement('span'),He=new MutationObserver(function(){Ne(),We=!1});return He.observe(De,{attributes:!0}),function(){We||(We=!0,De.setAttribute('x-index',Pe),++Pe)}}:function(Ne){var We=!1;return function(){We||(We=!0,setTimeout(function(){We=!1,Ne()},he))}},ye=function(){return void 0==be&&(be=-1!==navigator.appVersion.indexOf('MSIE 10')),be},we=function(Ne,We){if(!(Ne instanceof We))throw new TypeError('Cannot call a class as a function')},Ee=function(){function Ne(We,Pe){for(var He,De=0;De<Pe.length;De++)He=Pe[De],He.enumerable=He.enumerable||!1,He.configurable=!0,'value'in He&&(He.writable=!0),Object.defineProperty(We,He.key,He)}return function(We,Pe,De){return Pe&&Ne(We.prototype,Pe),De&&Ne(We,De),We}}(),ve=function(Ne,We,Pe){return We in Ne?Object.defineProperty(Ne,We,{value:Pe,enumerable:!0,configurable:!0,writable:!0}):Ne[We]=Pe,Ne},xe=Object.assign||function(Ne){for(var Pe,We=1;We<arguments.length;We++)for(var De in Pe=arguments[We],Pe)Object.prototype.hasOwnProperty.call(Pe,De)&&(Ne[De]=Pe[De]);return Ne},Oe=['auto-start','auto','auto-end','top-start','top','top-end','right-start','right','right-end','bottom-end','bottom','bottom-start','left-end','left','left-start'],Le=Oe.slice(3),Se={FLIP:'flip',CLOCKWISE:'clockwise',COUNTERCLOCKWISE:'counterclockwise'},ke=function(){function Ne(We,Pe){var De=this,He=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};we(this,Ne),this.scheduleUpdate=function(){return requestAnimationFrame(De.update)},this.update=ge(this.update.bind(this)),this.options=xe({},Ne.Defaults,He),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=We.jquery?We[0]:We,this.popper=Pe.jquery?Pe[0]:Pe,r(this.popper,{position:'absolute'}),this.options.modifiers={},Object.keys(xe({},Ne.Defaults.modifiers,He.modifiers)).forEach(function(Me){De.options.modifiers[Me]=xe({},Ne.Defaults.modifiers[Me]||{},He.modifiers?He.modifiers[Me]:{})}),this.modifiers=Object.keys(this.options.modifiers).map(function(Me){return xe({name:Me},De.options.modifiers[Me])}).sort(function(Me,Ie){return Me.order-Ie.order}),this.modifiers.forEach(function(Me){Me.enabled&&p(Me.onLoad)&&Me.onLoad(De.reference,De.popper,De.options,Me,De.state)}),this.update();var Be=this.options.eventsEnabled;Be&&this.enableEventListeners(),this.state.eventsEnabled=Be}return Ee(Ne,[{key:'update',value:function(){return R.call(this)}},{key:'destroy',value:function(){return F.call(this)}},{key:'enableEventListeners',value:function(){return K.call(this)}},{key:'disableEventListeners',value:function(){return _.call(this)}}]),Ne}();return ke.Utils=('undefined'==typeof window?global:window).PopperUtils,ke.placements=Oe,ke.Defaults={placement:'bottom',eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(Ne){var We=Ne.placement,Pe=We.split('-')[0],De=We.split('-')[1];if(De){var He=Ne.offsets.reference,Be=O(Ne.offsets.popper),Me=-1!==['bottom','top'].indexOf(Pe),Ie=Me?'left':'top',Ae=Me?'width':'height',Re={start:ve({},Ie,He[Ie]),end:ve({},Ie,He[Ie]+He[Ae]-Be[Ae])};Ne.offsets.popper=xe({},Be,Re[De])}return Ne}},offset:{order:200,enabled:!0,fn:function(Ne,We){var Ae,Pe=We.offset,De=Ne.placement,He=Ne.offsets,Be=He.popper,Me=He.reference,Ie=De.split('-')[0];return Ae=o(+Pe)?[+Pe,0]:ie(Pe,Be,Me,Ie),'left'===Ie?(Be.top+=Ae[0],Be.left-=Ae[1]):'right'===Ie?(Be.top+=Ae[0],Be.left+=Ae[1]):'top'===Ie?(Be.left+=Ae[0],Be.top-=Ae[1]):'bottom'===Ie&&(Be.left+=Ae[0],Be.top+=Ae[1]),Ne.popper=Be,Ne},offset:0},preventOverflow:{order:300,enabled:!0,fn:function(Ne,We){var Pe=We.boundariesElement||h(Ne.instance.popper),De=k(Ne.instance.popper,Ne.instance.reference,We.padding,Pe);We.boundaries=De;var He=We.priority,Be=O(Ne.offsets.popper),Me={primary:function(Ae){var Re=Be[Ae];return Be[Ae]<De[Ae]&&!We.escapeWithReference&&(Re=_Mathmax(Be[Ae],De[Ae])),ve({},Ae,Re)},secondary:function(Ae){var Re='right'===Ae?'left':'top',Ue=Be[Re];return Be[Ae]>De[Ae]&&!We.escapeWithReference&&(Ue=_Mathmin(Be[Re],De[Ae]-('right'===Ae?Be.width:Be.height))),ve({},Re,Ue)}};return He.forEach(function(Ie){var Ae=-1===['left','top'].indexOf(Ie)?'secondary':'primary';Be=xe({},Be,Me[Ae](Ie))}),Ne.offsets.popper=Be,Ne},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(Ne){var We=O(Ne.offsets.popper),Pe=Ne.offsets.reference,De=Ne.placement.split('-')[0],He=_Mathfloor,Be=-1!==['top','bottom'].indexOf(De),Me=Be?'right':'bottom',Ie=Be?'left':'top',Ae=Be?'width':'height';return We[Me]<He(Pe[Ie])&&(Ne.offsets.popper[Ie]=He(Pe[Ie])-We[Ae]),We[Ie]>He(Pe[Me])&&(Ne.offsets.popper[Ie]=He(Pe[Me])),Ne}},arrow:{order:500,enabled:!0,fn:function(Ne,We){if(!Q(Ne.instance.modifiers,'arrow','keepTogether'))return Ne;var Pe=We.element;if('string'==typeof Pe){if(Pe=Ne.instance.popper.querySelector(Pe),!Pe)return Ne;}else if(!Ne.instance.popper.contains(Pe))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),Ne;var De=Ne.placement.split('-')[0],He=O(Ne.offsets.popper),Be=Ne.offsets.reference,Me=-1!==['left','right'].indexOf(De),Ie=Me?'height':'width',Ae=Me?'top':'left',Re=Me?'left':'top',Ue=Me?'bottom':'right',Ye=D(Pe)[Ie];Be[Ue]-Ye<He[Ae]&&(Ne.offsets.popper[Ae]-=He[Ae]-(Be[Ue]-Ye)),Be[Ae]+Ye>He[Ue]&&(Ne.offsets.popper[Ae]+=Be[Ae]+Ye-He[Ue]);var Fe=Be[Ae]+Be[Ie]/2-Ye/2,je=Fe-O(Ne.offsets.popper)[Ae];return je=_Mathmax(_Mathmin(He[Ie]-Ye,je),0),Ne.arrowElement=Pe,Ne.offsets.arrow={},Ne.offsets.arrow[Ae]=_Mathfloor(je),Ne.offsets.arrow[Re]='',Ne},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(Ne,We){if(U(Ne.instance.modifiers,'inner'))return Ne;if(Ne.flipped&&Ne.placement===Ne.originalPlacement)return Ne;var Pe=k(Ne.instance.popper,Ne.instance.reference,We.padding,We.boundariesElement),De=Ne.placement.split('-')[0],He=H(De),Be=Ne.placement.split('-')[1]||'',Me=[];switch(We.behavior){case Se.FLIP:Me=[De,He];break;case Se.CLOCKWISE:Me=J(De);break;case Se.COUNTERCLOCKWISE:Me=J(De,!0);break;default:Me=We.behavior;}return Me.forEach(function(Ie,Ae){if(De!==Ie||Me.length===Ae+1)return Ne;De=Ne.placement.split('-')[0],He=H(De);var Re=O(Ne.offsets.popper),Ue=Ne.offsets.reference,Ye=_Mathfloor,Fe='left'===De&&Ye(Re.right)>Ye(Ue.left)||'right'===De&&Ye(Re.left)<Ye(Ue.right)||'top'===De&&Ye(Re.bottom)>Ye(Ue.top)||'bottom'===De&&Ye(Re.top)<Ye(Ue.bottom),je=Ye(Re.left)<Ye(Pe.left),qe=Ye(Re.right)>Ye(Pe.right),Ke=Ye(Re.top)<Ye(Pe.top),ze=Ye(Re.bottom)>Ye(Pe.bottom),_e='left'===De&&je||'right'===De&&qe||'top'===De&&Ke||'bottom'===De&&ze,Ve=-1!==['top','bottom'].indexOf(De),Ge=!!We.flipVariations&&(Ve&&'start'===Be&&je||Ve&&'end'===Be&&qe||!Ve&&'start'===Be&&Ke||!Ve&&'end'===Be&&ze);(Fe||_e||Ge)&&(Ne.flipped=!0,(Fe||_e)&&(De=Me[Ae+1]),Ge&&(Be=$(Be)),Ne.placement=De+(Be?'-'+Be:''),Ne.offsets.popper=xe({},Ne.offsets.popper,B(Ne.instance.popper,Ne.offsets.reference,Ne.placement)),Ne=A(Ne.instance.modifiers,Ne,'flip'))}),Ne},behavior:'flip',padding:5,boundariesElement:'viewport'},inner:{order:700,enabled:!1,fn:function(Ne){var We=Ne.placement,Pe=We.split('-')[0],De=O(Ne.offsets.popper),He=O(Ne.offsets.reference),Be=-1!==['left','right'].indexOf(Pe),Me=-1===['top','left'].indexOf(Pe);return De[Be?'left':'top']=He[We]-(Me?De[Be?'width':'height']:0),Ne.placement=H(We),Ne.offsets.popper=O(De),Ne}},hide:{order:800,enabled:!0,fn:function(Ne){if(!Q(Ne.instance.modifiers,'hide','preventOverflow'))return Ne;var We=Ne.offsets.reference,Pe=M(Ne.instance.modifiers,function(De){return'preventOverflow'===De.name}).boundaries;if(We.bottom<Pe.top||We.left>Pe.right||We.top>Pe.bottom||We.right<Pe.left){if(!0===Ne.hide)return Ne;Ne.hide=!0,Ne.attributes['x-out-of-boundaries']=''}else{if(!1===Ne.hide)return Ne;Ne.hide=!1,Ne.attributes['x-out-of-boundaries']=!1}return Ne}},applyStyle:{order:900,enabled:!0,fn:function(Ne,We){var Pe={position:Ne.offsets.popper.position},De={'x-placement':Ne.placement},He=_Mathround(Ne.offsets.popper.left),Be=_Mathround(Ne.offsets.popper.top),Me=Y('transform');return We.gpuAcceleration&&Me?(Pe[Me]='translate3d('+He+'px, '+Be+'px, 0)',Pe.top=0,Pe.left=0,Pe.willChange='transform'):(Pe.left=He,Pe.top=Be,Pe.willChange='top, left'),r(Ne.instance.popper,xe({},Pe,Ne.styles)),V(Ne.instance.popper,xe({},De,Ne.attributes)),Ne.offsets.arrow&&r(Ne.arrowElement,Ne.offsets.arrow),Ne},onLoad:function(Ne,We,Pe,De,He){var Be=P(He,We,Ne),Me=W(Pe.placement,Be,We,Ne,Pe.modifiers.flip.boundariesElement,Pe.modifiers.flip.padding);return We.setAttribute('x-placement',Me),Pe},gpuAcceleration:!0}}},ke});
+(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return''!==e&&!isNaN(parseFloat(e))&&isFinite(e)}function t(t,o){Object.keys(o).forEach(function(i){var n='';-1!==['width','height','top','right','bottom','left'].indexOf(i)&&e(o[i])&&(n='px'),t.style[i]=o[i]+n})}function o(e){return e&&'[object Function]'==={}.toString.call(e)}function n(e,t){if(1!==e.nodeType)return[];var o=window.getComputedStyle(e,null);return t?o[t]:o}function r(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function p(e){if(!e||-1!==['HTML','BODY','#document'].indexOf(e.nodeName))return window.document.body;var t=n(e),o=t.overflow,i=t.overflowX,s=t.overflowY;return /(auto|scroll)/.test(o+s+i)?e:p(r(e))}function s(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||e.firstElementChild.offsetParent===e)}function d(e){return null===e.parentNode?e:d(e.parentNode)}function a(e){var t=e&&e.offsetParent,o=t&&t.nodeName;return o&&'BODY'!==o&&'HTML'!==o?t:window.document.documentElement}function f(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return window.document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,i=o?e:t,n=o?t:e,r=document.createRange();r.setStart(i,0),r.setEnd(n,0);var p=r.commonAncestorContainer;if(e!==p&&t!==p||i.contains(n))return s(p)?p:a(p);var l=d(e);return l.host?f(l.host,t):f(e,d(t).host)}function l(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:'top',o='top'===t?'scrollTop':'scrollLeft',i=e.nodeName;if('BODY'===i||'HTML'===i){var n=window.document.documentElement,r=window.document.scrollingElement||n;return r[o]}return e[o]}function m(e,t){var o=2<arguments.length&&void 0!==arguments[2]&&arguments[2],i=l(t,'top'),n=l(t,'left'),r=o?-1:1;return e.top+=i*r,e.bottom+=i*r,e.left+=n*r,e.right+=n*r,e}function h(e,t){var o='x'===t?'Left':'Top',i='Left'==o?'Right':'Bottom';return+e['border'+o+'Width'].split('px')[0]+ +e['border'+i+'Width'].split('px')[0]}function c(e,t,o,i){return _(t['offset'+e],o['client'+e],o['offset'+e],ie()?o['offset'+e]+i['margin'+('Height'===e?'Top':'Left')]+i['margin'+('Height'===e?'Bottom':'Right')]:0)}function g(){var e=window.document.body,t=window.document.documentElement,o=ie()&&window.getComputedStyle(t);return{height:c('Height',e,t,o),width:c('Width',e,t,o)}}function u(e){return se({},e,{right:e.left+e.width,bottom:e.top+e.height})}function b(e){var t={};if(ie())try{t=e.getBoundingClientRect();var o=l(e,'top'),i=l(e,'left');t.top+=o,t.left+=i,t.bottom+=o,t.right+=i}catch(e){}else t=e.getBoundingClientRect();var r={left:t.left,top:t.top,width:t.right-t.left,height:t.bottom-t.top},p='HTML'===e.nodeName?g():{},s=p.width||e.clientWidth||r.right-r.left,d=p.height||e.clientHeight||r.bottom-r.top,a=e.offsetWidth-s,f=e.offsetHeight-d;if(a||f){var m=n(e);a-=h(m,'x'),f-=h(m,'y'),r.width-=a,r.height-=f}return u(r)}function y(e,t){var o=ie(),i='HTML'===t.nodeName,r=b(e),s=b(t),d=p(e),a=u({top:r.top-s.top,left:r.left-s.left,width:r.width,height:r.height});if(i||'BODY'===t.nodeName){var f=n(t),l=o&&i?0:+f.borderTopWidth.split('px')[0],h=o&&i?0:+f.borderLeftWidth.split('px')[0],c=o&&i?0:+f.marginTop.split('px')[0],g=o&&i?0:+f.marginLeft.split('px')[0];a.top-=l-c,a.bottom-=l-c,a.left-=h-g,a.right-=h-g,a.marginTop=c,a.marginLeft=g}return(o?t.contains(d):t===d&&'BODY'!==d.nodeName)&&(a=m(a,t)),a}function w(e){var t=window.document.documentElement,o=y(e,t),i=_(t.clientWidth,window.innerWidth||0),n=_(t.clientHeight,window.innerHeight||0),r=l(t),p=l(t,'left'),s={top:r-o.top+o.marginTop,left:p-o.left+o.marginLeft,width:i,height:n};return u(s)}function v(e){var t=e.nodeName;return'BODY'===t||'HTML'===t?!1:'fixed'===n(e,'position')||v(r(e))}function E(e,t,o,i){var n={top:0,left:0},s=f(e,t);if('viewport'===i)n=w(s);else{var d;'scrollParent'===i?(d=p(r(e)),'BODY'===d.nodeName&&(d=window.document.documentElement)):'window'===i?d=window.document.documentElement:d=i;var a=y(d,s);if('HTML'===d.nodeName&&!v(s)){var l=g(),m=l.height,h=l.width;n.top+=a.top-a.marginTop,n.bottom=m+a.top,n.left+=a.left-a.marginLeft,n.right=h+a.left}else n=a}return n.left+=o,n.top+=o,n.right-=o,n.bottom-=o,n}function x(e){var t=e.width,o=e.height;return t*o}function O(e,t,o,i,n){var r=5<arguments.length&&void 0!==arguments[5]?arguments[5]:0;if(-1===e.indexOf('auto'))return e;var p=E(o,i,r,n),s={top:{width:p.width,height:t.top-p.top},right:{width:p.right-t.right,height:p.height},bottom:{width:p.width,height:p.bottom-t.bottom},left:{width:t.left-p.left,height:p.height}},d=Object.keys(s).map(function(e){return se({key:e},s[e],{area:x(s[e])})}).sort(function(e,t){return t.area-e.area}),a=d.filter(function(e){var t=e.width,i=e.height;return t>=o.clientWidth&&i>=o.clientHeight}),f=0<a.length?a[0].key:d[0].key,l=e.split('-')[1];return f+(l?'-'+l:'')}function L(e,t,o){var i=f(t,o);return y(o,i)}function S(e){var t=window.getComputedStyle(e),o=parseFloat(t.marginTop)+parseFloat(t.marginBottom),i=parseFloat(t.marginLeft)+parseFloat(t.marginRight),n={width:e.offsetWidth+i,height:e.offsetHeight+o};return n}function C(e){var t={left:'right',right:'left',bottom:'top',top:'bottom'};return e.replace(/left|right|bottom|top/g,function(e){return t[e]})}function T(e,t,o){o=o.split('-')[0];var i=S(e),n={width:i.width,height:i.height},r=-1!==['right','left'].indexOf(o),p=r?'top':'left',s=r?'left':'top',d=r?'height':'width',a=r?'width':'height';return n[p]=t[p]+t[d]/2-i[d]/2,n[s]=o===s?t[s]-i[a]:t[C(s)],n}function N(e,t){return Array.prototype.find?e.find(t):e.filter(t)[0]}function k(e,t,o){if(Array.prototype.findIndex)return e.findIndex(function(e){return e[t]===o});var i=N(e,function(e){return e[t]===o});return e.indexOf(i)}function B(e,t,i){var n=void 0===i?e:e.slice(0,k(e,'name',i));return n.forEach(function(e){e.function&&console.warn('`modifier.function` is deprecated, use `modifier.fn`!');var i=e.function||e.fn;e.enabled&&o(i)&&(t.offsets.popper=u(t.offsets.popper),t.offsets.reference=u(t.offsets.reference),t=i(t,e))}),t}function W(){if(!this.state.isDestroyed){var e={instance:this,styles:{},attributes:{},flipped:!1,offsets:{}};e.offsets.reference=L(this.state,this.popper,this.reference),e.placement=O(this.options.placement,e.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),e.originalPlacement=e.placement,e.offsets.popper=T(this.popper,e.offsets.reference,e.placement),e.offsets.popper.position='absolute',e=B(this.modifiers,e),this.state.isCreated?this.options.onUpdate(e):(this.state.isCreated=!0,this.options.onCreate(e))}}function P(e,t){return e.some(function(e){var o=e.name,i=e.enabled;return i&&o===t})}function D(e){for(var t=[!1,'ms','webkit','moz','o'],o=e.charAt(0).toUpperCase()+e.slice(1),n=0;n<t.length-1;n++){var i=t[n],r=i?''+i+o:e;if('undefined'!=typeof window.document.body.style[r])return r}return null}function H(){return this.state.isDestroyed=!0,P(this.modifiers,'applyStyle')&&(this.popper.removeAttribute('x-placement'),this.popper.style.left='',this.popper.style.position='',this.popper.style.top='',this.popper.style[D('transform')]=''),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function A(e,t,o,i){var n='BODY'===e.nodeName,r=n?window:e;r.addEventListener(t,o,{passive:!0}),n||A(p(r.parentNode),t,o,i),i.push(r)}function M(e,t,o,i){o.updateBound=i,window.addEventListener('resize',o.updateBound,{passive:!0});var n=p(e);return A(n,'scroll',o.updateBound,o.scrollParents),o.scrollElement=n,o.eventsEnabled=!0,o}function I(){this.state.eventsEnabled||(this.state=M(this.reference,this.options,this.state,this.scheduleUpdate))}function R(e,t){return window.removeEventListener('resize',t.updateBound),t.scrollParents.forEach(function(e){e.removeEventListener('scroll',t.updateBound)}),t.updateBound=null,t.scrollParents=[],t.scrollElement=null,t.eventsEnabled=!1,t}function U(){this.state.eventsEnabled&&(window.cancelAnimationFrame(this.scheduleUpdate),this.state=R(this.reference,this.state))}function Y(e,t){Object.keys(t).forEach(function(o){var i=t[o];!1===i?e.removeAttribute(o):e.setAttribute(o,t[o])})}function F(e,t,o){var i=N(e,function(e){var o=e.name;return o===t}),n=!!i&&e.some(function(e){return e.name===o&&e.enabled&&e.order<i.order});if(!n){var r='`'+t+'`';console.warn('`'+o+'`'+' modifier is required by '+r+' modifier in order to work, be sure to include it before '+r+'!')}return n}function j(e){return'end'===e?'start':'start'===e?'end':e}function K(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=ae.indexOf(e),i=ae.slice(o+1).concat(ae.slice(0,o));return t?i.reverse():i}function q(e,t,o,i){var n=e.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+n[1],p=n[2];if(!r)return e;if(0===p.indexOf('%')){var s;switch(p){case'%p':s=o;break;case'%':case'%r':default:s=i;}var d=u(s);return d[t]/100*r}if('vh'===p||'vw'===p){var a;return a='vh'===p?_(document.documentElement.clientHeight,window.innerHeight||0):_(document.documentElement.clientWidth,window.innerWidth||0),a/100*r}return r}function G(t,o,i,n){var r=[0,0],p=-1!==['right','left'].indexOf(n),s=t.split(/(\+|\-)/).map(function(e){return e.trim()}),d=s.indexOf(N(s,function(e){return-1!==e.search(/,|\s/)}));s[d]&&-1===s[d].indexOf(',')&&console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');var a=/\s*,\s*|\s+/,f=-1===d?[s]:[s.slice(0,d).concat([s[d].split(a)[0]]),[s[d].split(a)[1]].concat(s.slice(d+1))];return f=f.map(function(e,t){var n=(1===t?!p:p)?'height':'width',r=!1;return e.reduce(function(e,t){return''===e[e.length-1]&&-1!==['+','-'].indexOf(t)?(e[e.length-1]=t,r=!0,e):r?(e[e.length-1]+=t,r=!1,e):e.concat(t)},[]).map(function(e){return q(e,n,o,i)})}),f.forEach(function(t,o){t.forEach(function(i,n){e(i)&&(r[o]+=i*('-'===t[n-1]?-1:1))})}),r}for(var z=Math.floor,V=Math.min,_=Math.max,X=['native code','[object MutationObserverConstructor]'],Q=function(e){return X.some(function(t){return-1<(e||'').toString().indexOf(t)})},J='undefined'!=typeof window,Z=['Edge','Trident','Firefox'],$=0,ee=0;ee<Z.length;ee+=1)if(J&&0<=navigator.userAgent.indexOf(Z[ee])){$=1;break}var i,te=J&&Q(window.MutationObserver),oe=te?function(e){var t=!1,o=0,i=document.createElement('span'),n=new MutationObserver(function(){e(),t=!1});return n.observe(i,{attributes:!0}),function(){t||(t=!0,i.setAttribute('x-index',o),++o)}}:function(e){var t=!1;return function(){t||(t=!0,setTimeout(function(){t=!1,e()},$))}},ie=function(){return void 0==i&&(i=-1!==navigator.appVersion.indexOf('MSIE 10')),i},ne=function(e,t){if(!(e instanceof t))throw new TypeError('Cannot call a class as a function')},re=function(){function e(e,t){for(var o,n=0;n<t.length;n++)o=t[n],o.enumerable=o.enumerable||!1,o.configurable=!0,'value'in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}return function(t,o,i){return o&&e(t.prototype,o),i&&e(t,i),t}}(),pe=function(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e},se=Object.assign||function(e){for(var t,o=1;o<arguments.length;o++)for(var i in t=arguments[o],t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e},de=['auto-start','auto','auto-end','top-start','top','top-end','right-start','right','right-end','bottom-end','bottom','bottom-start','left-end','left','left-start'],ae=de.slice(3),fe={FLIP:'flip',CLOCKWISE:'clockwise',COUNTERCLOCKWISE:'counterclockwise'},le=function(){function e(i,n){var r=this,p=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};ne(this,e),this.scheduleUpdate=function(){return requestAnimationFrame(r.update)},this.update=oe(this.update.bind(this)),this.options=se({},e.Defaults,p),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=i.jquery?i[0]:i,this.popper=n.jquery?n[0]:n,t(this.popper,{position:'absolute'}),this.options.modifiers={},Object.keys(se({},e.Defaults.modifiers,p.modifiers)).forEach(function(t){r.options.modifiers[t]=se({},e.Defaults.modifiers[t]||{},p.modifiers?p.modifiers[t]:{})}),this.modifiers=Object.keys(this.options.modifiers).map(function(e){return se({name:e},r.options.modifiers[e])}).sort(function(e,t){return e.order-t.order}),this.modifiers.forEach(function(e){e.enabled&&o(e.onLoad)&&e.onLoad(r.reference,r.popper,r.options,e,r.state)}),this.update();var s=this.options.eventsEnabled;s&&this.enableEventListeners(),this.state.eventsEnabled=s}return re(e,[{key:'update',value:function(){return W.call(this)}},{key:'destroy',value:function(){return H.call(this)}},{key:'enableEventListeners',value:function(){return I.call(this)}},{key:'disableEventListeners',value:function(){return U.call(this)}}]),e}();return le.Utils=('undefined'==typeof window?global:window).PopperUtils,le.placements=de,le.Defaults={placement:'bottom',eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(e){var t=e.placement,o=t.split('-')[0],i=t.split('-')[1];if(i){var n=e.offsets,r=n.reference,p=n.popper,s=-1!==['bottom','top'].indexOf(o),d=s?'left':'top',a=s?'width':'height',f={start:pe({},d,r[d]),end:pe({},d,r[d]+r[a]-p[a])};e.offsets.popper=se({},p,f[i])}return e}},offset:{order:200,enabled:!0,fn:function(t,o){var i,n=o.offset,r=t.placement,p=t.offsets,s=p.popper,d=p.reference,a=r.split('-')[0];return i=e(+n)?[+n,0]:G(n,s,d,a),'left'===a?(s.top+=i[0],s.left-=i[1]):'right'===a?(s.top+=i[0],s.left+=i[1]):'top'===a?(s.left+=i[0],s.top-=i[1]):'bottom'===a&&(s.left+=i[0],s.top+=i[1]),t.popper=s,t},offset:0},preventOverflow:{order:300,enabled:!0,fn:function(e,t){var o=t.boundariesElement||a(e.instance.popper),i=E(e.instance.popper,e.instance.reference,t.padding,o);t.boundaries=i;var n=t.priority,r=e.offsets.popper,p={primary:function(e){var o=r[e];return r[e]<i[e]&&!t.escapeWithReference&&(o=_(r[e],i[e])),pe({},e,o)},secondary:function(e){var o='right'===e?'left':'top',n=r[o];return r[e]>i[e]&&!t.escapeWithReference&&(n=V(r[o],i[e]-('right'===e?r.width:r.height))),pe({},o,n)}};return n.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';r=se({},r,p[t](e))}),e.offsets.popper=r,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,i=t.reference,n=e.placement.split('-')[0],r=z,p=-1!==['top','bottom'].indexOf(n),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]<r(i[d])&&(e.offsets.popper[d]=r(i[d])-o[a]),o[d]>r(i[s])&&(e.offsets.popper[d]=r(i[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!F(e.instance.modifiers,'arrow','keepTogether'))return e;var o=t.element;if('string'==typeof o){if(o=e.instance.popper.querySelector(o),!o)return e;}else if(!e.instance.popper.contains(o))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var i=e.placement.split('-')[0],n=e.offsets,r=n.popper,p=n.reference,s=-1!==['left','right'].indexOf(i),d=s?'height':'width',a=s?'top':'left',f=s?'left':'top',l=s?'bottom':'right',m=S(o)[d];p[l]-m<r[a]&&(e.offsets.popper[a]-=r[a]-(p[l]-m)),p[a]+m>r[l]&&(e.offsets.popper[a]+=p[a]+m-r[l]);var h=p[a]+p[d]/2-m/2,c=h-u(e.offsets.popper)[a];return c=_(V(r[d]-m,c),0),e.arrowElement=o,e.offsets.arrow={},e.offsets.arrow[a]=z(c),e.offsets.arrow[f]='',e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(P(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=E(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement),i=e.placement.split('-')[0],n=C(i),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case fe.FLIP:p=[i,n];break;case fe.CLOCKWISE:p=K(i);break;case fe.COUNTERCLOCKWISE:p=K(i,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(i!==s||p.length===d+1)return e;i=e.placement.split('-')[0],n=C(i);var a=e.offsets.popper,f=e.offsets.reference,l=z,m='left'===i&&l(a.right)>l(f.left)||'right'===i&&l(a.left)<l(f.right)||'top'===i&&l(a.bottom)>l(f.top)||'bottom'===i&&l(a.top)<l(f.bottom),h=l(a.left)<l(o.left),c=l(a.right)>l(o.right),g=l(a.top)<l(o.top),u=l(a.bottom)>l(o.bottom),b='left'===i&&h||'right'===i&&c||'top'===i&&g||'bottom'===i&&u,y=-1!==['top','bottom'].indexOf(i),w=!!t.flipVariations&&(y&&'start'===r&&h||y&&'end'===r&&c||!y&&'start'===r&&g||!y&&'end'===r&&u);(m||b||w)&&(e.flipped=!0,(m||b)&&(i=p[d+1]),w&&(r=j(r)),e.placement=i+(r?'-'+r:''),e.offsets.popper=se({},e.offsets.popper,T(e.instance.popper,e.offsets.reference,e.placement)),e=B(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport'},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],i=e.offsets,n=i.popper,r=i.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return n[p?'left':'top']=r[t]-(s?n[p?'width':'height']:0),e.placement=C(t),e.offsets.popper=u(n),e}},hide:{order:800,enabled:!0,fn:function(e){if(!F(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=N(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottom<o.top||t.left>o.right||t.top>o.bottom||t.right<o.left){if(!0===e.hide)return e;e.hide=!0,e.attributes['x-out-of-boundaries']=''}else{if(!1===e.hide)return e;e.hide=!1,e.attributes['x-out-of-boundaries']=!1}return e}},computeStyle:{order:850,enabled:!0,fn:function(e,t){var o=Math.round,i=t.x,n=t.y,r=e.offsets.popper,p=N(e.instance.modifiers,function(e){return'applyStyle'===e.name}).gpuAcceleration;void 0!==p&&console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');var s,d,f=void 0===p?t.gpuAcceleration:p,l=a(e.instance.popper),m=b(l),h={position:r.position},c={left:o(r.left),top:o(r.top),bottom:o(r.bottom),right:o(r.right)},g='bottom'===i?'top':'bottom',u='right'===n?'left':'right',y=D('transform');if(d='bottom'==g?-m.height+c.bottom:c.top,s='right'==u?-m.width+c.right:c.left,f&&y)h[y]='translate3d('+s+'px, '+d+'px, 0)',h[g]=0,h[u]=0,h.willChange='transform';else{var w='bottom'==g?-1:1,v='right'==u?-1:1;h[g]=d*w,h[u]=s*v,h.willChange=g+', '+u}var E={'x-placement':e.placement};return e.attributes=E,e.styles=se({},h,e.styles),e},gpuAcceleration:!0,x:'bottom',y:'right'},applyStyle:{order:900,enabled:!0,fn:function(e){return t(e.instance.popper,e.styles),Y(e.instance.popper,e.attributes),e.offsets.arrow&&t(e.arrowElement,e.offsets.arrow),e},onLoad:function(e,t,o,i,n){var r=L(n,t,e),p=O(o.placement,r,t,e,o.modifiers.flip.boundariesElement,o.modifiers.flip.padding);return t.setAttribute('x-placement',p),o},gpuAcceleration:void 0}}},le});
//# sourceMappingURL=popper.min.js.map \ No newline at end of file
diff --git a/bower.json b/bower.json
index befdde18f..257eb184b 100644
--- a/bower.json
+++ b/bower.json
@@ -32,6 +32,6 @@
],
"dependencies": {
"jquery": ">=1.9.1",
- "popper.js": "^1.9.9"
+ "popper.js": "^1.10.1"
}
}
diff --git a/build/npm-shrinkwrap.json b/build/npm-shrinkwrap.json
index eab64153b..1ae4e341e 100644
--- a/build/npm-shrinkwrap.json
+++ b/build/npm-shrinkwrap.json
@@ -3390,9 +3390,9 @@
"dev": true
},
"popper.js": {
- "version": "1.9.9",
- "from": "popper.js@>=1.9.9 <3.0.0",
- "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.9.9.tgz"
+ "version": "1.10.1",
+ "from": "popper.js@>=1.10.1 <2.0.0",
+ "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.10.1.tgz"
},
"postcss": {
"version": "5.2.17",
diff --git a/docs/4.0/components/collapse.md b/docs/4.0/components/collapse.md
index cbdc50bb7..e1d3e3b64 100644
--- a/docs/4.0/components/collapse.md
+++ b/docs/4.0/components/collapse.md
@@ -32,6 +32,35 @@ You can use a link with the `href` attribute, or a button with the `data-target`
</div>
{% endexample %}
+## Multiple triggers / targets
+
+A `<button>` or `<a>` can show and hide multiple elements by referencing them with a JQuery selector in its `href` or `data-target` attribute.
+Multiple `<button>` or `<a>` can show and hide an element if they each reference it with their `href` or `data-target` attribute
+
+{% example html %}
+<p>
+ <a class="btn btn-primary" data-toggle="collapse" href="#multiCollapseExample1" aria-expanded="false" aria-controls="multiCollapseExample1">Toggle first element</a>
+ <button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#multiCollapseExample2" aria-expanded="false" aria-controls="multiCollapseExample1">Toggle second element</button>
+ <button class="btn btn-primary" type="button" data-toggle="collapse" data-target=".multi-collapse" aria-expanded="false" aria-controls="multiCollapseExample1 multiCollapseExample2">Toggle both elements</button>
+</p>
+<div class="row">
+ <div class="col">
+ <div class="collapse multi-collapse" id="multiCollapseExample1">
+ <div class="card card-block">
+ Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident.
+ </div>
+ </div>
+ </div>
+ <div class="col">
+ <div class="collapse multi-collapse" id="multiCollapseExample2">
+ <div class="card card-block">
+ Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident.
+ </div>
+ </div>
+ </div>
+</div>
+{% endexample %}
+
## Accordion example
Using the [card]({{ site.baseurl }}/docs/{{ site.docs_version }}/components/card/) component, you can extend the default collapse behavior to create an accordion.
@@ -129,7 +158,7 @@ These classes can be found in `_transitions.scss`.
### Via data attributes
-Just add `data-toggle="collapse"` and a `data-target` to the element to automatically assign control of a collapsible element. The `data-target` attribute accepts a CSS selector to apply the collapse to. Be sure to add the class `collapse` to the collapsible element. If you'd like it to default open, add the additional class `show`.
+Just add `data-toggle="collapse"` and a `data-target` to the element to automatically assign control of one or more collapsible elements. The `data-target` attribute accepts a CSS selector to apply the collapse to. Be sure to add the class `collapse` to the collapsible element. If you'd like it to default open, add the additional class `show`.
To add accordion-like group management to a collapsible area, add the data attribute `data-parent="#selector"`. Refer to the demo to see this in action.
diff --git a/docs/4.0/components/dropdowns.md b/docs/4.0/components/dropdowns.md
index 01c35c7a2..4840e8480 100644
--- a/docs/4.0/components/dropdowns.md
+++ b/docs/4.0/components/dropdowns.md
@@ -10,7 +10,7 @@ toc: true
Dropdowns are toggleable, contextual overlays for displaying lists of links and more. They're made interactive with the included Bootstrap dropdown JavaScript plugin. They're toggled by clicking, not by hovering; this is [an intentional design decision.](http://markdotto.com/2012/02/27/bootstrap-explained-dropdowns/)
-Dropdowns are built on a third party library, [Popper.js](https://popper.js.org), which provides dynamic positioning and viewport detection. Be sure to include [popper.min.js](https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js) before Bootstrap's JavaScript.
+Dropdowns are built on a third party library, [Popper.js](https://popper.js.org), which provides dynamic positioning and viewport detection. Be sure to include [popper.min.js](https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.10.1/umd/popper.min.js) before Bootstrap's JavaScript.
## Accessibility
diff --git a/docs/4.0/components/popovers.md b/docs/4.0/components/popovers.md
index 20ab3fe75..cd6599158 100644
--- a/docs/4.0/components/popovers.md
+++ b/docs/4.0/components/popovers.md
@@ -11,7 +11,7 @@ toc: true
Things to know when using the popover plugin:
-- Popovers rely on the 3rd party library [Popper.js](https://popper.js.org) for positioning. You must include [popper.min.js](https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js) before bootstrap.js in order for popovers to work!
+- Popovers rely on the 3rd party library [Popper.js](https://popper.js.org) for positioning. You must include [popper.min.js](https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.10.1/umd/popper.min.js) before bootstrap.js in order for popovers to work!
- Popovers require the [tooltip plugin]({{ site.baseurl }}/docs/{{ site.docs_version }}/components/tooltips/) as a dependency.
- Popovers are opt-in for performance reasons, so **you must initialize them yourself**.
- Zero-length `title` and `content` values will never show a popover.
diff --git a/docs/4.0/components/tooltips.md b/docs/4.0/components/tooltips.md
index c6cf14dc9..7c0bd9f6a 100644
--- a/docs/4.0/components/tooltips.md
+++ b/docs/4.0/components/tooltips.md
@@ -10,7 +10,7 @@ toc: true
Things to know when using the tooltip plugin:
-- Tooltips rely on the 3rd party library [Popper.js](https://popper.js.org) for positioning. You must include [popper.min.js](https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js) before bootstrap.js in order for tooltips to work!
+- Tooltips rely on the 3rd party library [Popper.js](https://popper.js.org) for positioning. You must include [popper.min.js](https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.10.1/umd/popper.min.js) before bootstrap.js in order for tooltips to work!
- Tooltips are opt-in for performance reasons, so **you must initialize them yourself**.
- Tooltips with zero-length titles are never displayed.
- Specify `container: 'body'` to avoid rendering problems in more complex components (like our input groups, button groups, etc).
diff --git a/docs/4.0/examples/album/index.html b/docs/4.0/examples/album/index.html
index f30905813..f442be943 100644
--- a/docs/4.0/examples/album/index.html
+++ b/docs/4.0/examples/album/index.html
@@ -118,7 +118,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../assets/js/vendor/holder.min.js"></script>
<script>
$(function () {
diff --git a/docs/4.0/examples/blog/index.html b/docs/4.0/examples/blog/index.html
index c79abdde9..8225c246a 100644
--- a/docs/4.0/examples/blog/index.html
+++ b/docs/4.0/examples/blog/index.html
@@ -158,7 +158,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/carousel/index.html b/docs/4.0/examples/carousel/index.html
index 95a8bed58..451b4c38f 100644
--- a/docs/4.0/examples/carousel/index.html
+++ b/docs/4.0/examples/carousel/index.html
@@ -176,7 +176,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- Just to make our placeholder images work. Don't actually copy the next line! -->
<script src="../../../../assets/js/vendor/holder.min.js"></script>
diff --git a/docs/4.0/examples/cover/index.html b/docs/4.0/examples/cover/index.html
index 87efec4d7..7edfe51ed 100644
--- a/docs/4.0/examples/cover/index.html
+++ b/docs/4.0/examples/cover/index.html
@@ -60,7 +60,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/dashboard/index.html b/docs/4.0/examples/dashboard/index.html
index 01d94fba4..e535f19d1 100644
--- a/docs/4.0/examples/dashboard/index.html
+++ b/docs/4.0/examples/dashboard/index.html
@@ -254,7 +254,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/jumbotron/index.html b/docs/4.0/examples/jumbotron/index.html
index a2f4a7b71..15b449f78 100644
--- a/docs/4.0/examples/jumbotron/index.html
+++ b/docs/4.0/examples/jumbotron/index.html
@@ -93,7 +93,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/justified-nav/index.html b/docs/4.0/examples/justified-nav/index.html
index 4ebaeed06..16ac2a10b 100644
--- a/docs/4.0/examples/justified-nav/index.html
+++ b/docs/4.0/examples/justified-nav/index.html
@@ -96,7 +96,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/navbar-top-fixed/index.html b/docs/4.0/examples/navbar-top-fixed/index.html
index 5f81d4905..f27b42dd8 100644
--- a/docs/4.0/examples/navbar-top-fixed/index.html
+++ b/docs/4.0/examples/navbar-top-fixed/index.html
@@ -56,7 +56,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/navbar-top/index.html b/docs/4.0/examples/navbar-top/index.html
index 66f86f6bf..bdad69171 100644
--- a/docs/4.0/examples/navbar-top/index.html
+++ b/docs/4.0/examples/navbar-top/index.html
@@ -56,7 +56,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/navbars/index.html b/docs/4.0/examples/navbars/index.html
index de0a500fb..7b829a8b2 100644
--- a/docs/4.0/examples/navbars/index.html
+++ b/docs/4.0/examples/navbars/index.html
@@ -351,7 +351,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/offcanvas/index.html b/docs/4.0/examples/offcanvas/index.html
index d0581f997..89485ea62 100644
--- a/docs/4.0/examples/offcanvas/index.html
+++ b/docs/4.0/examples/offcanvas/index.html
@@ -127,7 +127,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/starter-template/index.html b/docs/4.0/examples/starter-template/index.html
index ce430a60d..d69f5a397 100644
--- a/docs/4.0/examples/starter-template/index.html
+++ b/docs/4.0/examples/starter-template/index.html
@@ -66,7 +66,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/sticky-footer-navbar/index.html b/docs/4.0/examples/sticky-footer-navbar/index.html
index aa1f046ad..4f5fe32dd 100644
--- a/docs/4.0/examples/sticky-footer-navbar/index.html
+++ b/docs/4.0/examples/sticky-footer-navbar/index.html
@@ -64,7 +64,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/docs/4.0/examples/tooltip-viewport/index.html b/docs/4.0/examples/tooltip-viewport/index.html
index f60ca4707..f44e98b0e 100644
--- a/docs/4.0/examples/tooltip-viewport/index.html
+++ b/docs/4.0/examples/tooltip-viewport/index.html
@@ -39,7 +39,7 @@
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="../../../../assets/js/vendor/jquery.min.js"><\/script>')</script>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.9.9/umd/popper.min.js" integrity="sha256-c477vRLKQv1jt9o7w6TTBzFyFznTaZjoMLTDFi7Hlxc=" crossorigin="anonymous"></script>
+ <script src="../../../../assets/js/vendor/popper.min.js"></script>
<script src="../../../../dist/js/bootstrap.min.js"></script>
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
<script src="../../../../assets/js/ie10-viewport-bug-workaround.js"></script>
diff --git a/js/src/collapse.js b/js/src/collapse.js
index bf1c738f5..78ed32906 100644
--- a/js/src/collapse.js
+++ b/js/src/collapse.js
@@ -77,6 +77,14 @@ const Collapse = (($) => {
`[data-toggle="collapse"][href="#${element.id}"],` +
`[data-toggle="collapse"][data-target="#${element.id}"]`
))
+ const tabToggles = $(Selector.DATA_TOGGLE)
+ for (let i = 0; i < tabToggles.length; i++) {
+ const elem = tabToggles[i]
+ const selector = Util.getSelectorFromElement(elem)
+ if (selector !== null && $(selector).filter(element).length > 0) {
+ this._triggerArray.push(elem)
+ }
+ }
this._parent = this._config.parent ? this._getParent() : null
@@ -215,9 +223,17 @@ const Collapse = (($) => {
.removeClass(ClassName.SHOW)
if (this._triggerArray.length) {
- $(this._triggerArray)
- .addClass(ClassName.COLLAPSED)
- .attr('aria-expanded', false)
+ for (let i = 0; i < this._triggerArray.length; i++) {
+ const trigger = this._triggerArray[i]
+ const selector = Util.getSelectorFromElement(trigger)
+ if (selector !== null) {
+ const $elem = $(selector)
+ if (!$elem.hasClass(ClassName.SHOW)) {
+ $(trigger).addClass(ClassName.COLLAPSED)
+ .attr('aria-expanded', false)
+ }
+ }
+ }
}
this.setTransitioning(true)
@@ -349,11 +365,14 @@ const Collapse = (($) => {
event.preventDefault()
}
- const target = Collapse._getTargetFromElement(this)
- const data = $(target).data(DATA_KEY)
- const config = data ? 'toggle' : $(this).data()
-
- Collapse._jQueryInterface.call($(target), config)
+ const $trigger = $(this)
+ const selector = Util.getSelectorFromElement(this)
+ $(selector).each(function () {
+ const $target = $(this)
+ const data = $target.data(DATA_KEY)
+ const config = data ? 'toggle' : $trigger.data()
+ Collapse._jQueryInterface.call($target, config)
+ })
})
diff --git a/js/tests/unit/collapse.js b/js/tests/unit/collapse.js
index 2b9d0e58f..0e9e8b6a7 100644
--- a/js/tests/unit/collapse.js
+++ b/js/tests/unit/collapse.js
@@ -52,8 +52,28 @@ $(function () {
assert.ok(!/height/i.test($el.attr('style')), 'has height reset')
})
+
+ QUnit.test('should show multiple collapsed elements', function (assert) {
+ assert.expect(4)
+ var done = assert.async()
+ var $target = $('<a role="button" data-toggle="collapse" class="collapsed" href=".multi"/>').appendTo('#qunit-fixture')
+ var $el = $('<div class="collapse multi"/>').appendTo('#qunit-fixture')
+ var $el2 = $('<div class="collapse multi"/>').appendTo('#qunit-fixture')
+ $el.one('shown.bs.collapse', function () {
+ assert.ok($el.hasClass('show'), 'has class "show"')
+ assert.ok(!/height/i.test($el.attr('style')), 'has height reset')
+ })
+ $el2.one('shown.bs.collapse', function () {
+ assert.ok($el2.hasClass('show'), 'has class "show"')
+ assert.ok(!/height/i.test($el2.attr('style')), 'has height reset')
+ done()
+ })
+ $target.trigger('click')
+ })
+
QUnit.test('should collapse only the first collapse', function (assert) {
assert.expect(2)
+ var done = assert.async()
var html = [
'<div class="panel-group" id="accordion1">',
'<div class="panel">',
@@ -69,10 +89,11 @@ $(function () {
$(html).appendTo('#qunit-fixture')
var $el1 = $('#collapse1')
var $el2 = $('#collapse2')
- $el1.bootstrapCollapse('show')
-
- assert.ok($el1.hasClass('show'))
- assert.ok($el2.hasClass('show'))
+ $el1.one('shown.bs.collapse', function () {
+ assert.ok($el1.hasClass('show'))
+ assert.ok($el2.hasClass('show'))
+ done()
+ }).bootstrapCollapse('show')
})
QUnit.test('should hide a collapsed element', function (assert) {
@@ -588,4 +609,68 @@ $(function () {
$target.trigger($.Event('click'))
})
+
+ QUnit.test('should add "collapsed" class to triggers only when all the targeted collapse are hidden', function (assert) {
+ assert.expect(9)
+ var done = assert.async()
+
+ var $trigger1 = $('<a role="button" data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
+ var $trigger2 = $('<a role="button" data-toggle="collapse" href="#test2"/>').appendTo('#qunit-fixture')
+ var $trigger3 = $('<a role="button" data-toggle="collapse" href=".multi"/>').appendTo('#qunit-fixture')
+
+ var $target1 = $('<div id="test1" class="multi"/>').appendTo('#qunit-fixture')
+ var $target2 = $('<div id="test2" class="multi"/>').appendTo('#qunit-fixture')
+
+ $target2.one('shown.bs.collapse', function () {
+ assert.ok(!$trigger1.hasClass('collapsed'), 'trigger1 does not have collapsed class')
+ assert.ok(!$trigger2.hasClass('collapsed'), 'trigger2 does not have collapsed class')
+ assert.ok(!$trigger3.hasClass('collapsed'), 'trigger3 does not have collapsed class')
+ $target2.one('hidden.bs.collapse', function () {
+ assert.ok(!$trigger1.hasClass('collapsed'), 'trigger1 does not have collapsed class')
+ assert.ok($trigger2.hasClass('collapsed'), 'trigger2 has collapsed class')
+ assert.ok(!$trigger3.hasClass('collapsed'), 'trigger3 does not have collapsed class')
+ $target1.one('hidden.bs.collapse', function () {
+ assert.ok($trigger1.hasClass('collapsed'), 'trigger1 has collapsed class')
+ assert.ok($trigger2.hasClass('collapsed'), 'trigger2 has collapsed class')
+ assert.ok($trigger3.hasClass('collapsed'), 'trigger3 has collapsed class')
+ done()
+ })
+ $trigger1.trigger('click')
+ })
+ $trigger2.trigger('click')
+ })
+ $trigger3.trigger('click')
+ })
+
+ QUnit.test('should set aria-expanded="true" to triggers targetting shown collaspe and aria-expanded="false" only when all the targeted collapses are shown', function (assert) {
+ assert.expect(9)
+ var done = assert.async()
+
+ var $trigger1 = $('<a role="button" data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
+ var $trigger2 = $('<a role="button" data-toggle="collapse" href="#test2"/>').appendTo('#qunit-fixture')
+ var $trigger3 = $('<a role="button" data-toggle="collapse" href=".multi"/>').appendTo('#qunit-fixture')
+
+ var $target1 = $('<div id="test1" class="multi collapse"/>').appendTo('#qunit-fixture')
+ var $target2 = $('<div id="test2" class="multi collapse"/>').appendTo('#qunit-fixture')
+
+ $target2.one('shown.bs.collapse', function () {
+ assert.strictEqual($trigger1.attr('aria-expanded'), 'true', 'aria-expanded on trigger1 is "true"')
+ assert.strictEqual($trigger2.attr('aria-expanded'), 'true', 'aria-expanded on trigger2 is "true"')
+ assert.strictEqual($trigger3.attr('aria-expanded'), 'true', 'aria-expanded on trigger3 is "true"')
+ $target2.one('hidden.bs.collapse', function () {
+ assert.strictEqual($trigger1.attr('aria-expanded'), 'true', 'aria-expanded on trigger1 is "true"')
+ assert.strictEqual($trigger2.attr('aria-expanded'), 'false', 'aria-expanded on trigger2 is "false"')
+ assert.strictEqual($trigger3.attr('aria-expanded'), 'true', 'aria-expanded on trigger3 is "true"')
+ $target1.one('hidden.bs.collapse', function () {
+ assert.strictEqual($trigger1.attr('aria-expanded'), 'false', 'aria-expanded on trigger1 is "fasle"')
+ assert.strictEqual($trigger2.attr('aria-expanded'), 'false', 'aria-expanded on trigger2 is "false"')
+ assert.strictEqual($trigger3.attr('aria-expanded'), 'false', 'aria-expanded on trigger3 is "false"')
+ done()
+ })
+ $trigger1.trigger('click')
+ })
+ $trigger2.trigger('click')
+ })
+ $trigger3.trigger('click')
+ })
})
diff --git a/js/tests/unit/dropdown.js b/js/tests/unit/dropdown.js
index 1dd675b0b..7e96745ab 100644
--- a/js/tests/unit/dropdown.js
+++ b/js/tests/unit/dropdown.js
@@ -45,7 +45,8 @@ $(function () {
})
QUnit.test('should not open dropdown if target is disabled via attribute', function (assert) {
- assert.expect(0)
+ assert.expect(1)
+ var done = assert.async()
var dropdownHTML = '<div class="tabs">'
+ '<div class="dropdown">'
+ '<button disabled href="#" class="btn dropdown-toggle" data-toggle="dropdown">Dropdown</button>'
@@ -57,10 +58,13 @@ $(function () {
+ '</div>'
+ '</div>'
+ '</div>'
- var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown()
- setTimeout(function () {
- assert.ok(!$dropdown.parent('.dropdown').hasClass('show'), '"show" class added on click')
- }, 300)
+ $(dropdownHTML).appendTo('#qunit-fixture')
+ var $dropdown = $('#qunit-fixture').find('[data-toggle="dropdown"]').bootstrapDropdown()
+ $dropdown.on('click', function () {
+ assert.ok(!$dropdown.parent('.dropdown').hasClass('show'))
+ done()
+ })
+ $dropdown.trigger($.Event('click'))
})
QUnit.test('should set aria-expanded="true" on target when dropdown menu is shown', function (assert) {
@@ -77,7 +81,10 @@ $(function () {
+ '</div>'
+ '</div>'
+ '</div>'
- var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown()
+ var $dropdown = $(dropdownHTML)
+ .appendTo('#qunit-fixture')
+ .find('[data-toggle="dropdown"]')
+ .bootstrapDropdown()
$dropdown
.parent('.dropdown')
.on('shown.bs.dropdown', function () {
@@ -118,7 +125,8 @@ $(function () {
})
QUnit.test('should not open dropdown if target is disabled via class', function (assert) {
- assert.expect(0)
+ assert.expect(1)
+ var done = assert.async()
var dropdownHTML = '<div class="tabs">'
+ '<div class="dropdown">'
+ '<button href="#" class="btn dropdown-toggle disabled" data-toggle="dropdown">Dropdown</button>'
@@ -130,10 +138,14 @@ $(function () {
+ '</div>'
+ '</div>'
+ '</div>'
- var $dropdown = $(dropdownHTML).find('[data-toggle="dropdown"]').bootstrapDropdown().trigger('click')
- setTimeout(function () {
- assert.ok(!$dropdown.parent('.dropdown').hasClass('show'), '"show" class added on click')
- }, 300)
+
+ $(dropdownHTML).appendTo('#qunit-fixture')
+ var $dropdown = $('#qunit-fixture').find('[data-toggle="dropdown"]').bootstrapDropdown()
+ $dropdown.on('click', function () {
+ assert.ok(!$dropdown.parent('.dropdown').hasClass('show'))
+ done()
+ })
+ $dropdown.trigger($.Event('click'))
})
QUnit.test('should add class show to menu if clicked', function (assert) {
diff --git a/js/tests/vendor/qunit.css b/js/tests/vendor/qunit.css
index 75d8b6279..7a4693533 100644
--- a/js/tests/vendor/qunit.css
+++ b/js/tests/vendor/qunit.css
@@ -1,12 +1,12 @@
/*!
- * QUnit 2.3.2
+ * QUnit 2.3.3
* https://qunitjs.com/
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license
* https://jquery.org/license
*
- * Date: 2017-04-18T02:19Z
+ * Date: 2017-06-02T14:07Z
*/
/** Font Family and Sizes */
diff --git a/js/tests/vendor/qunit.js b/js/tests/vendor/qunit.js
index fa728db5b..3cda99631 100644
--- a/js/tests/vendor/qunit.js
+++ b/js/tests/vendor/qunit.js
@@ -1,12 +1,12 @@
/*!
- * QUnit 2.3.2
+ * QUnit 2.3.3
* https://qunitjs.com/
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license
* https://jquery.org/license
*
- * Date: 2017-04-18T02:19Z
+ * Date: 2017-06-02T14:07Z
*/
(function (global$1) {
'use strict';
@@ -14,6 +14,7 @@
global$1 = 'default' in global$1 ? global$1['default'] : global$1;
var window = global$1.window;
+ var self$1 = global$1.self;
var console = global$1.console;
var setTimeout = global$1.setTimeout;
var clearTimeout = global$1.clearTimeout;
@@ -238,6 +239,27 @@
return objectType(obj) === type;
}
+ // Based on Java's String.hashCode, a simple but not
+ // rigorously collision resistant hashing function
+ function generateHash(module, testName) {
+ var str = module + "\x1C" + testName;
+ var hash = 0;
+
+ for (var i = 0; i < str.length; i++) {
+ hash = (hash << 5) - hash + str.charCodeAt(i);
+ hash |= 0;
+ }
+
+ // Convert the possibly negative integer hash code into an 8 character hex string, which isn't
+ // strictly necessary but increases user understanding that the id is a SHA-like hash
+ var hex = (0x100000000 + hash).toString(16);
+ if (hex.length < 8) {
+ hex = "0000000" + hex;
+ }
+
+ return hex.slice(-8);
+ }
+
// Test for equality any JavaScript type.
// Authors: Philippe Rathé <[email protected]>, David Chan <[email protected]>
var equiv = (function () {
@@ -608,21 +630,19 @@
// Set of all modules.
modules: [],
- // Stack of nested modules
- moduleStack: [],
-
// The first unnamed module
currentModule: {
name: "",
tests: [],
childModules: [],
- testsRun: 0
+ testsRun: 0,
+ unskippedTestsRun: 0
},
callbacks: {},
// The storage module to use for reordering tests
- storage: sessionStorage
+ storage: localSessionStorage
};
// take a predefined QUnit.config and extend the defaults
@@ -1064,6 +1084,135 @@
return extractStacktrace(error, offset);
}
+ var priorityCount = 0;
+ var unitSampler = void 0;
+
+ /**
+ * Advances the ProcessingQueue to the next item if it is ready.
+ * @param {Boolean} last
+ */
+ function advance() {
+ var start = now();
+ config.depth = (config.depth || 0) + 1;
+
+ while (config.queue.length && !config.blocking) {
+ var elapsedTime = now() - start;
+
+ if (!defined.setTimeout || config.updateRate <= 0 || elapsedTime < config.updateRate) {
+ if (priorityCount > 0) {
+ priorityCount--;
+ }
+
+ config.queue.shift()();
+ } else {
+ setTimeout(advance, 13);
+ break;
+ }
+ }
+
+ config.depth--;
+
+ if (!config.blocking && !config.queue.length && config.depth === 0) {
+ done();
+ }
+ }
+
+ function addToQueueImmediate(callback) {
+ if (objectType(callback) === "array") {
+ while (callback.length) {
+ addToQueueImmediate(callback.pop());
+ }
+
+ return;
+ }
+
+ config.queue.unshift(callback);
+ priorityCount++;
+ }
+
+ /**
+ * Adds a function to the ProcessingQueue for execution.
+ * @param {Function|Array} callback
+ * @param {Boolean} priority
+ * @param {String} seed
+ */
+ function addToQueue(callback, prioritize, seed) {
+ if (prioritize) {
+ config.queue.splice(priorityCount++, 0, callback);
+ } else if (seed) {
+ if (!unitSampler) {
+ unitSampler = unitSamplerGenerator(seed);
+ }
+
+ // Insert into a random position after all prioritized items
+ var index = Math.floor(unitSampler() * (config.queue.length - priorityCount + 1));
+ config.queue.splice(priorityCount + index, 0, callback);
+ } else {
+ config.queue.push(callback);
+ }
+ }
+
+ /**
+ * Creates a seeded "sample" generator which is used for randomizing tests.
+ */
+ function unitSamplerGenerator(seed) {
+
+ // 32-bit xorshift, requires only a nonzero seed
+ // http://excamera.com/sphinx/article-xorshift.html
+ var sample = parseInt(generateHash(seed), 16) || -1;
+ return function () {
+ sample ^= sample << 13;
+ sample ^= sample >>> 17;
+ sample ^= sample << 5;
+
+ // ECMAScript has no unsigned number type
+ if (sample < 0) {
+ sample += 0x100000000;
+ }
+
+ return sample / 0x100000000;
+ };
+ }
+
+ /**
+ * This function is called when the ProcessingQueue is done processing all
+ * items. It handles emitting the final run events.
+ */
+ function done() {
+ var storage = config.storage;
+
+ ProcessingQueue.finished = true;
+
+ var runtime = now() - config.started;
+ var passed = config.stats.all - config.stats.bad;
+
+ emit("runEnd", globalSuite.end(true));
+ runLoggingCallbacks("done", {
+ passed: passed,
+ failed: config.stats.bad,
+ total: config.stats.all,
+ runtime: runtime
+ });
+
+ // Clear own storage items if all tests passed
+ if (storage && config.stats.bad === 0) {
+ for (var i = storage.length - 1; i >= 0; i--) {
+ var key = storage.key(i);
+
+ if (key.indexOf("qunit-test-") === 0) {
+ storage.removeItem(key);
+ }
+ }
+ }
+ }
+
+ var ProcessingQueue = {
+ finished: false,
+ add: addToQueue,
+ addImmediate: addToQueueImmediate,
+ advance: advance
+ };
+
var TestReport = function () {
function TestReport(name, suite, options) {
classCallCheck(this, TestReport);
@@ -1077,6 +1226,8 @@
this.skipped = !!options.skip;
this.todo = !!options.todo;
+ this.valid = options.valid;
+
this._startTime = 0;
this._endTime = 0;
@@ -1149,13 +1300,24 @@
value: function getAssertions() {
return this.assertions.slice();
}
+
+ // Remove actual and expected values from assertions. This is to prevent
+ // leaking memory throughout a test suite.
+
+ }, {
+ key: "slimAssertions",
+ value: function slimAssertions() {
+ this.assertions = this.assertions.map(function (assertion) {
+ delete assertion.actual;
+ delete assertion.expected;
+ return assertion;
+ });
+ }
}]);
return TestReport;
}();
- var unitSampler;
var focused = false;
- var priorityCount = 0;
function Test(settings) {
var i, l;
@@ -1166,14 +1328,14 @@
extend(this, settings);
this.assertions = [];
this.semaphore = 0;
- this.usedAsync = false;
this.module = config.currentModule;
this.stack = sourceFromStacktrace(3);
this.steps = [];
this.testReport = new TestReport(settings.testName, this.module.suiteReport, {
todo: settings.todo,
- skip: settings.skip
+ skip: settings.skip,
+ valid: this.valid()
});
// Register unique strings
@@ -1187,7 +1349,8 @@
this.module.tests.push({
name: this.testName,
- testId: this.testId
+ testId: this.testId,
+ skip: !!settings.skip
});
if (settings.skip) {
@@ -1234,12 +1397,6 @@
config.current = this;
- if (module.testEnvironment) {
- delete module.testEnvironment.before;
- delete module.testEnvironment.beforeEach;
- delete module.testEnvironment.afterEach;
- delete module.testEnvironment.after;
- }
this.testEnvironment = extend({}, module.testEnvironment);
this.started = now();
@@ -1297,14 +1454,14 @@
test = this;
return function runHook() {
if (hookName === "before") {
- if (hookOwner.testsRun !== 0) {
+ if (hookOwner.unskippedTestsRun !== 0) {
return;
}
test.preserveEnvironment = true;
}
- if (hookName === "after" && hookOwner.testsRun !== numberOfTests(hookOwner) - 1) {
+ if (hookName === "after" && hookOwner.unskippedTestsRun !== numberOfUnskippedTests(hookOwner) - 1 && config.queue.length > 2) {
return;
}
@@ -1334,8 +1491,8 @@
if (module.parentModule) {
processHooks(test, module.parentModule);
}
- if (module.testEnvironment && objectType(module.testEnvironment[handler]) === "function") {
- hooks.push(test.queueHook(module.testEnvironment[handler], handler, module));
+ if (module.hooks && objectType(module.hooks[handler]) === "function") {
+ hooks.push(test.queueHook(module.hooks[handler], handler, module));
}
}
@@ -1378,7 +1535,7 @@
}
}
- notifyTestsRan(module);
+ notifyTestsRan(module, skipped);
// Store result when possible
if (storage) {
@@ -1389,7 +1546,11 @@
}
}
+ // After emitting the js-reporters event we cleanup the assertion data to
+ // avoid leaking it. It is not used by the legacy testDone callbacks.
emit("testEnd", this.testReport.end(true));
+ this.testReport.slimAssertions();
+
runLoggingCallbacks("testDone", {
name: testName,
module: moduleName,
@@ -1409,6 +1570,20 @@
});
if (module.testsRun === numberOfTests(module)) {
+ logSuiteEnd(module);
+
+ // Check if the parent modules, iteratively, are done. If that the case,
+ // we emit the `suiteEnd` event and trigger `moduleDone` callback.
+ var parent = module.parentModule;
+ while (parent && parent.testsRun === numberOfTests(parent)) {
+ logSuiteEnd(parent);
+ parent = parent.parentModule;
+ }
+ }
+
+ config.current = undefined;
+
+ function logSuiteEnd(module) {
emit("suiteEnd", module.suiteReport.end(true));
runLoggingCallbacks("moduleDone", {
name: module.name,
@@ -1419,8 +1594,6 @@
runtime: now() - module.stats.started
});
}
-
- config.current = undefined;
},
preserveTestEnvironment: function preserveTestEnvironment() {
@@ -1431,18 +1604,16 @@
},
queue: function queue() {
- var priority,
- previousFailCount,
- test = this;
+ var test = this;
if (!this.valid()) {
return;
}
- function run() {
+ function runTest() {
// Each of these can by async
- synchronize([function () {
+ ProcessingQueue.addImmediate([function () {
test.before();
}, test.hooks("before"), function () {
test.preserveTestEnvironment();
@@ -1455,17 +1626,26 @@
}]);
}
- previousFailCount = config.storage && +config.storage.getItem("qunit-test-" + this.module.name + "-" + this.testName);
+ var previousFailCount = config.storage && +config.storage.getItem("qunit-test-" + this.module.name + "-" + this.testName);
// Prioritize previously failed tests, detected from storage
- priority = config.reorder && previousFailCount;
+ var prioritize = config.reorder && !!previousFailCount;
this.previousFailure = !!previousFailCount;
- return synchronize(run, priority, config.seed);
+ ProcessingQueue.add(runTest, prioritize, config.seed);
+
+ // If the queue has already finished, we manually process the new test
+ if (ProcessingQueue.finished) {
+ ProcessingQueue.advance();
+ }
},
+
pushResult: function pushResult(resultInfo) {
+ if (this !== config.current) {
+ throw new Error("Assertion occured after test had finished.");
+ }
// Destructure of resultInfo = { result, actual, expected, message, negative }
var source,
@@ -1503,7 +1683,7 @@
throw new Error("pushFailure() assertion outside test context, was " + sourceFromStacktrace(2));
}
- this.assert.pushResult({
+ this.pushResult({
result: false,
message: message || "error",
actual: actual || null,
@@ -1643,79 +1823,6 @@
return currentTest.pushFailure.apply(currentTest, arguments);
}
- // Based on Java's String.hashCode, a simple but not
- // rigorously collision resistant hashing function
- function generateHash(module, testName) {
- var hex,
- i = 0,
- hash = 0,
- str = module + "\x1C" + testName,
- len = str.length;
-
- for (; i < len; i++) {
- hash = (hash << 5) - hash + str.charCodeAt(i);
- hash |= 0;
- }
-
- // Convert the possibly negative integer hash code into an 8 character hex string, which isn't
- // strictly necessary but increases user understanding that the id is a SHA-like hash
- hex = (0x100000000 + hash).toString(16);
- if (hex.length < 8) {
- hex = "0000000" + hex;
- }
-
- return hex.slice(-8);
- }
-
- function synchronize(callback, priority, seed) {
- var last = !priority,
- index;
-
- if (objectType(callback) === "array") {
- while (callback.length) {
- synchronize(callback.shift());
- }
- return;
- }
-
- if (priority) {
- config.queue.splice(priorityCount++, 0, callback);
- } else if (seed) {
- if (!unitSampler) {
- unitSampler = unitSamplerGenerator(seed);
- }
-
- // Insert into a random position after all priority items
- index = Math.floor(unitSampler() * (config.queue.length - priorityCount + 1));
- config.queue.splice(priorityCount + index, 0, callback);
- } else {
- config.queue.push(callback);
- }
-
- if (internalState.autorun && !config.blocking) {
- process(last);
- }
- }
-
- function unitSamplerGenerator(seed) {
-
- // 32-bit xorshift, requires only a nonzero seed
- // http://excamera.com/sphinx/article-xorshift.html
- var sample = parseInt(generateHash(seed), 16) || -1;
- return function () {
- sample ^= sample << 13;
- sample ^= sample >>> 17;
- sample ^= sample << 5;
-
- // ECMAScript has no unsigned number type
- if (sample < 0) {
- sample += 0x100000000;
- }
-
- return sample / 0x100000000;
- };
- }
-
function saveGlobal() {
config.pollution = [];
@@ -1888,24 +1995,40 @@
}
}
- function numberOfTests(module) {
- var count = module.tests.length,
- modules = [].concat(toConsumableArray(module.childModules));
+ function collectTests(module) {
+ var tests = [].concat(module.tests);
+ var modules = [].concat(toConsumableArray(module.childModules));
// Do a breadth-first traversal of the child modules
while (modules.length) {
var nextModule = modules.shift();
- count += nextModule.tests.length;
+ tests.push.apply(tests, nextModule.tests);
modules.push.apply(modules, toConsumableArray(nextModule.childModules));
}
- return count;
+ return tests;
+ }
+
+ function numberOfTests(module) {
+ return collectTests(module).length;
+ }
+
+ function numberOfUnskippedTests(module) {
+ return collectTests(module).filter(function (test) {
+ return !test.skip;
+ }).length;
}
- function notifyTestsRan(module) {
+ function notifyTestsRan(module, skipped) {
module.testsRun++;
+ if (!skipped) {
+ module.unskippedTestsRun++;
+ }
while (module = module.parentModule) {
module.testsRun++;
+ if (!skipped) {
+ module.unskippedTestsRun++;
+ }
}
}
@@ -1978,18 +2101,22 @@
}, {
key: "async",
value: function async(count) {
- var test$$1 = this.test,
- popped = false,
+ var test$$1 = this.test;
+
+ var popped = false,
acceptCallCount = count;
if (typeof acceptCallCount === "undefined") {
acceptCallCount = 1;
}
- test$$1.usedAsync = true;
var resume = internalStop(test$$1);
return function done() {
+ if (config.current !== test$$1) {
+ throw Error("assert.async callback called after test finished.");
+ }
+
if (popped) {
test$$1.pushFailure("Too many calls to the `assert.async` callback", sourceFromStacktrace(2));
return;
@@ -2027,8 +2154,8 @@
value: function pushResult(resultInfo) {
// Destructure of resultInfo = { result, actual, expected, message, negative }
- var assert = this,
- currentTest = assert instanceof Assert && assert.test || config.current;
+ var assert = this;
+ var currentTest = assert instanceof Assert && assert.test || config.current;
// Backwards compatibility fix.
// Allows the direct use of global exported assertions and QUnit.assert.*
@@ -2039,12 +2166,6 @@
throw new Error("assertion outside test context, in " + sourceFromStacktrace(2));
}
- if (currentTest.usedAsync === true && currentTest.semaphore === 0) {
- currentTest.pushFailure("Assertion after the final `assert.async` was resolved", sourceFromStacktrace(2));
-
- // Allow this assertion to continue running anyway...
- }
-
if (!(assert instanceof Assert)) {
assert = currentTest.assert;
}
@@ -2181,8 +2302,9 @@
key: "throws",
value: function throws(block, expected, message) {
var actual = void 0,
- result = false,
- currentTest = this instanceof Assert && this.test || config.current;
+ result = false;
+
+ var currentTest = this instanceof Assert && this.test || config.current;
// 'expected' is optional unless doing string comparison
if (objectType(expected) === "string") {
@@ -2306,6 +2428,11 @@
});
QUnit.config.autostart = false;
}
+
+ // For Web/Service Workers
+ if (self$1 && self$1.WorkerGlobalScope && self$1 instanceof self$1.WorkerGlobalScope) {
+ self$1.QUnit = QUnit;
+ }
}
var SuiteReport = function () {
@@ -2386,8 +2513,11 @@
var counts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { passed: 0, failed: 0, skipped: 0, todo: 0, total: 0 };
counts = this.tests.reduce(function (counts, test) {
- counts[test.getStatus()]++;
- counts.total++;
+ if (test.valid) {
+ counts[test.getStatus()]++;
+ counts.total++;
+ }
+
return counts;
}, counts);
@@ -2451,27 +2581,49 @@
// it since each module has a suiteReport associated with it.
config.currentModule.suiteReport = globalSuite;
+ var moduleStack = [];
var globalStartCalled = false;
var runStarted = false;
- var internalState = {
- autorun: false
- };
-
// Figure out if we're running the tests from a server or not
QUnit.isLocal = !(defined.document && window.location.protocol !== "file:");
// Expose the current QUnit version
- QUnit.version = "2.2.0";
+ QUnit.version = "2.3.3";
+
+ function createModule(name, testEnvironment) {
+ var parentModule = moduleStack.length ? moduleStack.slice(-1)[0] : null;
+ var moduleName = parentModule !== null ? [parentModule.name, name].join(" > ") : name;
+ var parentSuite = parentModule ? parentModule.suiteReport : globalSuite;
+
+ var module = {
+ name: moduleName,
+ parentModule: parentModule,
+ tests: [],
+ moduleId: generateHash(moduleName),
+ testsRun: 0,
+ unskippedTestsRun: 0,
+ childModules: [],
+ suiteReport: new SuiteReport(name, parentSuite)
+ };
+
+ var env = {};
+ if (parentModule) {
+ parentModule.childModules.push(module);
+ extend(env, parentModule.testEnvironment);
+ }
+ extend(env, testEnvironment);
+ module.testEnvironment = env;
+
+ config.modules.push(module);
+ return module;
+ }
extend(QUnit, {
on: on,
// Call on start of module test to prepend name to all tests
module: function module(name, testEnvironment, executeNow) {
- var module, moduleFns;
- var currentModule = config.currentModule;
-
if (arguments.length === 2) {
if (objectType(testEnvironment) === "function") {
executeNow = testEnvironment;
@@ -2479,57 +2631,40 @@
}
}
- module = createModule();
+ var module = createModule(name, testEnvironment);
+
+ // Move any hooks to a 'hooks' object
+ if (module.testEnvironment) {
+ module.hooks = {
+ before: module.testEnvironment.before,
+ beforeEach: module.testEnvironment.beforeEach,
+ afterEach: module.testEnvironment.afterEach,
+ after: module.testEnvironment.after
+ };
+
+ delete module.testEnvironment.before;
+ delete module.testEnvironment.beforeEach;
+ delete module.testEnvironment.afterEach;
+ delete module.testEnvironment.after;
+ }
- moduleFns = {
+ var moduleFns = {
before: setHook(module, "before"),
beforeEach: setHook(module, "beforeEach"),
afterEach: setHook(module, "afterEach"),
after: setHook(module, "after")
};
+ var currentModule = config.currentModule;
if (objectType(executeNow) === "function") {
- config.moduleStack.push(module);
- setCurrentModule(module);
+ moduleStack.push(module);
+ config.currentModule = module;
executeNow.call(module.testEnvironment, moduleFns);
- config.moduleStack.pop();
+ moduleStack.pop();
module = module.parentModule || currentModule;
}
- setCurrentModule(module);
-
- function createModule() {
- var parentModule = config.moduleStack.length ? config.moduleStack.slice(-1)[0] : null;
- var moduleName = parentModule !== null ? [parentModule.name, name].join(" > ") : name;
- var parentSuite = parentModule ? parentModule.suiteReport : globalSuite;
-
- var module = {
- name: moduleName,
- parentModule: parentModule,
- tests: [],
- moduleId: generateHash(moduleName),
- testsRun: 0,
- childModules: [],
- suiteReport: new SuiteReport(name, parentSuite)
- };
-
- var env = {};
- if (parentModule) {
- parentModule.childModules.push(module);
- extend(env, parentModule.testEnvironment);
- delete env.beforeEach;
- delete env.afterEach;
- }
- extend(env, testEnvironment);
- module.testEnvironment = env;
-
- config.modules.push(module);
- return module;
- }
-
- function setCurrentModule(module) {
- config.currentModule = module;
- }
+ config.currentModule = module;
},
test: test,
@@ -2664,73 +2799,16 @@
}
config.blocking = false;
- process(true);
- }
-
- function process(last) {
- function next() {
- process(last);
- }
- var start = now();
- config.depth = (config.depth || 0) + 1;
-
- while (config.queue.length && !config.blocking) {
- if (!defined.setTimeout || config.updateRate <= 0 || now() - start < config.updateRate) {
- if (config.current) {
-
- // Reset async tracking for each phase of the Test lifecycle
- config.current.usedAsync = false;
- }
- config.queue.shift()();
- } else {
- setTimeout(next, 13);
- break;
- }
- }
- config.depth--;
- if (last && !config.blocking && !config.queue.length && config.depth === 0) {
- done();
- }
- }
-
- function done() {
- var runtime,
- passed,
- i,
- key,
- storage = config.storage;
-
- internalState.autorun = true;
-
- runtime = now() - config.started;
- passed = config.stats.all - config.stats.bad;
-
- emit("runEnd", globalSuite.end(true));
- runLoggingCallbacks("done", {
- failed: config.stats.bad,
- passed: passed,
- total: config.stats.all,
- runtime: runtime
- });
-
- // Clear own storage items if all tests passed
- if (storage && config.stats.bad === 0) {
- for (i = storage.length - 1; i >= 0; i--) {
- key = storage.key(i);
- if (key.indexOf("qunit-test-") === 0) {
- storage.removeItem(key);
- }
- }
- }
+ ProcessingQueue.advance();
}
function setHook(module, hookName) {
- if (module.testEnvironment === undefined) {
- module.testEnvironment = {};
+ if (!module.hooks) {
+ module.hooks = {};
}
return function (callback) {
- module.testEnvironment[hookName] = callback;
+ module.hooks[hookName] = callback;
};
}
@@ -3588,13 +3666,19 @@
message += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeText(actual) + "</pre></td></tr>";
- // Don't show diff if actual or expected are booleans
- if (!/^(true|false)$/.test(actual) && !/^(true|false)$/.test(expected)) {
+ if (typeof details.actual === "number" && typeof details.expected === "number") {
+ if (!isNaN(details.actual) && !isNaN(details.expected)) {
+ showDiff = true;
+ diff = details.actual - details.expected;
+ diff = (diff > 0 ? "+" : "") + diff;
+ }
+ } else if (typeof details.actual !== "boolean" && typeof details.expected !== "boolean") {
diff = QUnit.diff(expected, actual);
+
+ // don't show diff if there is zero overlap
showDiff = stripHtml(diff).length !== stripHtml(expected).length + stripHtml(actual).length;
}
- // Don't show diff if expected and actual are totally different
if (showDiff) {
message += "<tr class='test-diff'><th>Diff: </th><td><pre>" + diff + "</pre></td></tr>";
}
@@ -3691,6 +3775,7 @@
var todoLabel = document$$1.createElement("em");
todoLabel.className = "qunit-todo-label";
todoLabel.innerHTML = "todo";
+ testItem.className += " todo";
testItem.insertBefore(todoLabel, testTitle);
}
diff --git a/package.json b/package.json
index 08fe1b40c..bedd027e1 100644
--- a/package.json
+++ b/package.json
@@ -70,7 +70,7 @@
"license": "MIT",
"dependencies": {
"jquery": ">=1.9.1",
- "popper.js": "^1.9.9"
+ "popper.js": "^1.10.1"
},
"devDependencies": {
"autoprefixer": "^7.1.1",