MediaWiki:Common.js : Différence entre versions
| (15 révisions intermédiaires par 3 utilisateurs non affichées) | |||
| Ligne 1 : | Ligne 1 : | ||
| − | /* | + | /* |
| − | /** | + | Copyright (C) Federico Zivolo 2019 |
| − | // this | + | Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT). |
| − | // | + | */ |
| + | (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&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=e.ownerDocument.defaultView,n=o.getComputedStyle(e,null);return t?n[t]:n}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll|overlay)/.test(r+s+p)?e:n(o(e))}function i(e){return e&&e.referenceNode?e.referenceNode:e}function r(e){return 11===e?re:10===e?pe:re||pe}function p(e){if(!e)return document.documentElement;for(var o=r(10)?document.body:null,n=e.offsetParent||null;n===o&&e.nextElementSibling;)n=(e=e.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TH','TD','TABLE'].indexOf(n.nodeName)&&'static'===t(n,'position')?p(n):n:e?e.ownerDocument.documentElement:document.documentElement}function s(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||p(e.firstElementChild)===e)}function d(e){return null===e.parentNode?e:d(e.parentNode)}function a(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,n=o?e:t,i=o?t:e,r=document.createRange();r.setStart(n,0),r.setEnd(i,0);var l=r.commonAncestorContainer;if(e!==l&&t!==l||n.contains(i))return s(l)?l:p(l);var f=d(e);return f.host?a(f.host,t):a(e,d(t).host)}function l(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:'top',o='top'===t?'scrollTop':'scrollLeft',n=e.nodeName;if('BODY'===n||'HTML'===n){var i=e.ownerDocument.documentElement,r=e.ownerDocument.scrollingElement||i;return r[o]}return e[o]}function f(e,t){var o=2<arguments.length&&void 0!==arguments[2]&&arguments[2],n=l(t,'top'),i=l(t,'left'),r=o?-1:1;return e.top+=n*r,e.bottom+=n*r,e.left+=i*r,e.right+=i*r,e}function m(e,t){var o='x'===t?'Left':'Top',n='Left'==o?'Right':'Bottom';return parseFloat(e['border'+o+'Width'],10)+parseFloat(e['border'+n+'Width'],10)}function h(e,t,o,n){return ee(t['offset'+e],t['scroll'+e],o['client'+e],o['offset'+e],o['scroll'+e],r(10)?parseInt(o['offset'+e])+parseInt(n['margin'+('Height'===e?'Top':'Left')])+parseInt(n['margin'+('Height'===e?'Bottom':'Right')]):0)}function c(e){var t=e.body,o=e.documentElement,n=r(10)&&getComputedStyle(o);return{height:h('Height',t,o,n),width:h('Width',t,o,n)}}function g(e){return le({},e,{right:e.left+e.width,bottom:e.top+e.height})}function u(e){var o={};try{if(r(10)){o=e.getBoundingClientRect();var n=l(e,'top'),i=l(e,'left');o.top+=n,o.left+=i,o.bottom+=n,o.right+=i}else o=e.getBoundingClientRect()}catch(t){}var p={left:o.left,top:o.top,width:o.right-o.left,height:o.bottom-o.top},s='HTML'===e.nodeName?c(e.ownerDocument):{},d=s.width||e.clientWidth||p.width,a=s.height||e.clientHeight||p.height,f=e.offsetWidth-d,h=e.offsetHeight-a;if(f||h){var u=t(e);f-=m(u,'x'),h-=m(u,'y'),p.width-=f,p.height-=h}return g(p)}function b(e,o){var i=2<arguments.length&&void 0!==arguments[2]&&arguments[2],p=r(10),s='HTML'===o.nodeName,d=u(e),a=u(o),l=n(e),m=t(o),h=parseFloat(m.borderTopWidth,10),c=parseFloat(m.borderLeftWidth,10);i&&s&&(a.top=ee(a.top,0),a.left=ee(a.left,0));var b=g({top:d.top-a.top-h,left:d.left-a.left-c,width:d.width,height:d.height});if(b.marginTop=0,b.marginLeft=0,!p&&s){var w=parseFloat(m.marginTop,10),y=parseFloat(m.marginLeft,10);b.top-=h-w,b.bottom-=h-w,b.left-=c-y,b.right-=c-y,b.marginTop=w,b.marginLeft=y}return(p&&!i?o.contains(l):o===l&&'BODY'!==l.nodeName)&&(b=f(b,o)),b}function w(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=e.ownerDocument.documentElement,n=b(e,o),i=ee(o.clientWidth,window.innerWidth||0),r=ee(o.clientHeight,window.innerHeight||0),p=t?0:l(o),s=t?0:l(o,'left'),d={top:p-n.top+n.marginTop,left:s-n.left+n.marginLeft,width:i,height:r};return g(d)}function y(e){var n=e.nodeName;if('BODY'===n||'HTML'===n)return!1;if('fixed'===t(e,'position'))return!0;var i=o(e);return!!i&&y(i)}function E(e){if(!e||!e.parentElement||r())return document.documentElement;for(var o=e.parentElement;o&&'none'===t(o,'transform');)o=o.parentElement;return o||document.documentElement}function v(e,t,r,p){var s=4<arguments.length&&void 0!==arguments[4]&&arguments[4],d={top:0,left:0},l=s?E(e):a(e,i(t));if('viewport'===p)d=w(l,s);else{var f;'scrollParent'===p?(f=n(o(t)),'BODY'===f.nodeName&&(f=e.ownerDocument.documentElement)):'window'===p?f=e.ownerDocument.documentElement:f=p;var m=b(f,l,s);if('HTML'===f.nodeName&&!y(l)){var h=c(e.ownerDocument),g=h.height,u=h.width;d.top+=m.top-m.marginTop,d.bottom=g+m.top,d.left+=m.left-m.marginLeft,d.right=u+m.left}else d=m}r=r||0;var v='number'==typeof r;return d.left+=v?r:r.left||0,d.top+=v?r:r.top||0,d.right-=v?r:r.right||0,d.bottom-=v?r:r.bottom||0,d}function x(e){var t=e.width,o=e.height;return t*o}function O(e,t,o,n,i){var r=5<arguments.length&&void 0!==arguments[5]?arguments[5]:0;if(-1===e.indexOf('auto'))return e;var p=v(o,n,r,i),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 le({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,n=e.height;return t>=o.clientWidth&&n>=o.clientHeight}),l=0<a.length?a[0].key:d[0].key,f=e.split('-')[1];return l+(f?'-'+f:'')}function L(e,t,o){var n=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null,r=n?E(t):a(t,i(o));return b(o,r,n)}function S(e){var t=e.ownerDocument.defaultView,o=t.getComputedStyle(e),n=parseFloat(o.marginTop||0)+parseFloat(o.marginBottom||0),i=parseFloat(o.marginLeft||0)+parseFloat(o.marginRight||0),r={width:e.offsetWidth+i,height:e.offsetHeight+n};return r}function T(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 C(e,t,o){o=o.split('-')[0];var n=S(e),i={width:n.width,height:n.height},r=-1!==['right','left'].indexOf(o),p=r?'top':'left',s=r?'left':'top',d=r?'height':'width',a=r?'width':'height';return i[p]=t[p]+t[d]/2-n[d]/2,i[s]=o===s?t[s]-n[a]:t[T(s)],i}function D(e,t){return Array.prototype.find?e.find(t):e.filter(t)[0]}function N(e,t,o){if(Array.prototype.findIndex)return e.findIndex(function(e){return e[t]===o});var n=D(e,function(e){return e[t]===o});return e.indexOf(n)}function P(t,o,n){var i=void 0===n?t:t.slice(0,N(t,'name',n));return i.forEach(function(t){t['function']&&console.warn('`modifier.function` is deprecated, use `modifier.fn`!');var n=t['function']||t.fn;t.enabled&&e(n)&&(o.offsets.popper=g(o.offsets.popper),o.offsets.reference=g(o.offsets.reference),o=n(o,t))}),o}function k(){if(!this.state.isDestroyed){var e={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};e.offsets.reference=L(this.state,this.popper,this.reference,this.options.positionFixed),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.positionFixed=this.options.positionFixed,e.offsets.popper=C(this.popper,e.offsets.reference,e.placement),e.offsets.popper.position=this.options.positionFixed?'fixed':'absolute',e=P(this.modifiers,e),this.state.isCreated?this.options.onUpdate(e):(this.state.isCreated=!0,this.options.onCreate(e))}}function W(e,t){return e.some(function(e){var o=e.name,n=e.enabled;return n&&o===t})}function B(e){for(var t=[!1,'ms','Webkit','Moz','O'],o=e.charAt(0).toUpperCase()+e.slice(1),n=0;n<t.length;n++){var i=t[n],r=i?''+i+o:e;if('undefined'!=typeof document.body.style[r])return r}return null}function H(){return this.state.isDestroyed=!0,W(this.modifiers,'applyStyle')&&(this.popper.removeAttribute('x-placement'),this.popper.style.position='',this.popper.style.top='',this.popper.style.left='',this.popper.style.right='',this.popper.style.bottom='',this.popper.style.willChange='',this.popper.style[B('transform')]=''),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function A(e){var t=e.ownerDocument;return t?t.defaultView:window}function M(e,t,o,i){var r='BODY'===e.nodeName,p=r?e.ownerDocument.defaultView:e;p.addEventListener(t,o,{passive:!0}),r||M(n(p.parentNode),t,o,i),i.push(p)}function F(e,t,o,i){o.updateBound=i,A(e).addEventListener('resize',o.updateBound,{passive:!0});var r=n(e);return M(r,'scroll',o.updateBound,o.scrollParents),o.scrollElement=r,o.eventsEnabled=!0,o}function I(){this.state.eventsEnabled||(this.state=F(this.reference,this.options,this.state,this.scheduleUpdate))}function R(e,t){return A(e).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&&(cancelAnimationFrame(this.scheduleUpdate),this.state=R(this.reference,this.state))}function Y(e){return''!==e&&!isNaN(parseFloat(e))&&isFinite(e)}function V(e,t){Object.keys(t).forEach(function(o){var n='';-1!==['width','height','top','right','bottom','left'].indexOf(o)&&Y(t[o])&&(n='px'),e.style[o]=t[o]+n})}function j(e,t){Object.keys(t).forEach(function(o){var n=t[o];!1===n?e.removeAttribute(o):e.setAttribute(o,t[o])})}function q(e,t){var o=e.offsets,n=o.popper,i=o.reference,r=$,p=function(e){return e},s=r(i.width),d=r(n.width),a=-1!==['left','right'].indexOf(e.placement),l=-1!==e.placement.indexOf('-'),f=t?a||l||s%2==d%2?r:Z:p,m=t?r:p;return{left:f(1==s%2&&1==d%2&&!l&&t?n.left-1:n.left),top:m(n.top),bottom:m(n.bottom),right:f(n.right)}}function K(e,t,o){var n=D(e,function(e){var o=e.name;return o===t}),i=!!n&&e.some(function(e){return e.name===o&&e.enabled&&e.order<n.order});if(!i){var r='`'+t+'`';console.warn('`'+o+'`'+' modifier is required by '+r+' modifier in order to work, be sure to include it before '+r+'!')}return i}function z(e){return'end'===e?'start':'start'===e?'end':e}function G(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=he.indexOf(e),n=he.slice(o+1).concat(he.slice(0,o));return t?n.reverse():n}function _(e,t,o,n){var i=e.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+i[1],p=i[2];if(!r)return e;if(0===p.indexOf('%')){var s;switch(p){case'%p':s=o;break;case'%':case'%r':default:s=n;}var d=g(s);return d[t]/100*r}if('vh'===p||'vw'===p){var a;return a='vh'===p?ee(document.documentElement.clientHeight,window.innerHeight||0):ee(document.documentElement.clientWidth,window.innerWidth||0),a/100*r}return r}function X(e,t,o,n){var i=[0,0],r=-1!==['right','left'].indexOf(n),p=e.split(/(\+|\-)/).map(function(e){return e.trim()}),s=p.indexOf(D(p,function(e){return-1!==e.search(/,|\s/)}));p[s]&&-1===p[s].indexOf(',')&&console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');var d=/\s*,\s*|\s+/,a=-1===s?[p]:[p.slice(0,s).concat([p[s].split(d)[0]]),[p[s].split(d)[1]].concat(p.slice(s+1))];return a=a.map(function(e,n){var i=(1===n?!r:r)?'height':'width',p=!1;return e.reduce(function(e,t){return''===e[e.length-1]&&-1!==['+','-'].indexOf(t)?(e[e.length-1]=t,p=!0,e):p?(e[e.length-1]+=t,p=!1,e):e.concat(t)},[]).map(function(e){return _(e,i,t,o)})}),a.forEach(function(e,t){e.forEach(function(o,n){Y(o)&&(i[t]+=o*('-'===e[n-1]?-1:1))})}),i}function J(e,t){var o,n=t.offset,i=e.placement,r=e.offsets,p=r.popper,s=r.reference,d=i.split('-')[0];return o=Y(+n)?[+n,0]:X(n,p,s,d),'left'===d?(p.top+=o[0],p.left-=o[1]):'right'===d?(p.top+=o[0],p.left+=o[1]):'top'===d?(p.left+=o[0],p.top-=o[1]):'bottom'===d&&(p.left+=o[0],p.top+=o[1]),e.popper=p,e}var Q=Math.min,Z=Math.floor,$=Math.round,ee=Math.max,te='undefined'!=typeof window&&'undefined'!=typeof document&&'undefined'!=typeof navigator,oe=function(){for(var e=['Edge','Trident','Firefox'],t=0;t<e.length;t+=1)if(te&&0<=navigator.userAgent.indexOf(e[t]))return 1;return 0}(),ne=te&&window.Promise,ie=ne?function(e){var t=!1;return function(){t||(t=!0,window.Promise.resolve().then(function(){t=!1,e()}))}}:function(e){var t=!1;return function(){t||(t=!0,setTimeout(function(){t=!1,e()},oe))}},re=te&&!!(window.MSInputMethodContext&&document.documentMode),pe=te&&/MSIE 10/.test(navigator.userAgent),se=function(e,t){if(!(e instanceof t))throw new TypeError('Cannot call a class as a function')},de=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,n){return o&&e(t.prototype,o),n&&e(t,n),t}}(),ae=function(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e},le=Object.assign||function(e){for(var t,o=1;o<arguments.length;o++)for(var n in t=arguments[o],t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e},fe=te&&/Firefox/i.test(navigator.userAgent),me=['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'],he=me.slice(3),ce={FLIP:'flip',CLOCKWISE:'clockwise',COUNTERCLOCKWISE:'counterclockwise'},ge=function(){function t(o,n){var i=this,r=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};se(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=ie(this.update.bind(this)),this.options=le({},t.Defaults,r),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=o&&o.jquery?o[0]:o,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(le({},t.Defaults.modifiers,r.modifiers)).forEach(function(e){i.options.modifiers[e]=le({},t.Defaults.modifiers[e]||{},r.modifiers?r.modifiers[e]:{})}),this.modifiers=Object.keys(this.options.modifiers).map(function(e){return le({name:e},i.options.modifiers[e])}).sort(function(e,t){return e.order-t.order}),this.modifiers.forEach(function(t){t.enabled&&e(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)}),this.update();var p=this.options.eventsEnabled;p&&this.enableEventListeners(),this.state.eventsEnabled=p}return de(t,[{key:'update',value:function(){return k.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)}}]),t}();return ge.Utils=('undefined'==typeof window?global:window).PopperUtils,ge.placements=me,ge.Defaults={placement:'bottom',positionFixed:!1,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],n=t.split('-')[1];if(n){var i=e.offsets,r=i.reference,p=i.popper,s=-1!==['bottom','top'].indexOf(o),d=s?'left':'top',a=s?'width':'height',l={start:ae({},d,r[d]),end:ae({},d,r[d]+r[a]-p[a])};e.offsets.popper=le({},p,l[n])}return e}},offset:{order:200,enabled:!0,fn:J,offset:0},preventOverflow:{order:300,enabled:!0,fn:function(e,t){var o=t.boundariesElement||p(e.instance.popper);e.instance.reference===o&&(o=p(o));var n=B('transform'),i=e.instance.popper.style,r=i.top,s=i.left,d=i[n];i.top='',i.left='',i[n]='';var a=v(e.instance.popper,e.instance.reference,t.padding,o,e.positionFixed);i.top=r,i.left=s,i[n]=d,t.boundaries=a;var l=t.priority,f=e.offsets.popper,m={primary:function(e){var o=f[e];return f[e]<a[e]&&!t.escapeWithReference&&(o=ee(f[e],a[e])),ae({},e,o)},secondary:function(e){var o='right'===e?'left':'top',n=f[o];return f[e]>a[e]&&!t.escapeWithReference&&(n=Q(f[o],a[e]-('right'===e?f.width:f.height))),ae({},o,n)}};return l.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';f=le({},f,m[t](e))}),e.offsets.popper=f,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,n=t.reference,i=e.placement.split('-')[0],r=Z,p=-1!==['top','bottom'].indexOf(i),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]<r(n[d])&&(e.offsets.popper[d]=r(n[d])-o[a]),o[d]>r(n[s])&&(e.offsets.popper[d]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var n;if(!K(e.instance.modifiers,'arrow','keepTogether'))return e;var i=o.element;if('string'==typeof i){if(i=e.instance.popper.querySelector(i),!i)return e;}else if(!e.instance.popper.contains(i))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',c=a?'bottom':'right',u=S(i)[l];d[c]-u<s[m]&&(e.offsets.popper[m]-=s[m]-(d[c]-u)),d[m]+u>s[c]&&(e.offsets.popper[m]+=d[m]+u-s[c]),e.offsets.popper=g(e.offsets.popper);var b=d[m]+d[l]/2-u/2,w=t(e.instance.popper),y=parseFloat(w['margin'+f],10),E=parseFloat(w['border'+f+'Width'],10),v=b-e.offsets.popper[m]-y-E;return v=ee(Q(s[l]-u,v),0),e.arrowElement=i,e.offsets.arrow=(n={},ae(n,m,$(v)),ae(n,h,''),n),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=v(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement,e.positionFixed),n=e.placement.split('-')[0],i=T(n),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case ce.FLIP:p=[n,i];break;case ce.CLOCKWISE:p=G(n);break;case ce.COUNTERCLOCKWISE:p=G(n,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(n!==s||p.length===d+1)return e;n=e.placement.split('-')[0],i=T(n);var a=e.offsets.popper,l=e.offsets.reference,f=Z,m='left'===n&&f(a.right)>f(l.left)||'right'===n&&f(a.left)<f(l.right)||'top'===n&&f(a.bottom)>f(l.top)||'bottom'===n&&f(a.top)<f(l.bottom),h=f(a.left)<f(o.left),c=f(a.right)>f(o.right),g=f(a.top)<f(o.top),u=f(a.bottom)>f(o.bottom),b='left'===n&&h||'right'===n&&c||'top'===n&&g||'bottom'===n&&u,w=-1!==['top','bottom'].indexOf(n),y=!!t.flipVariations&&(w&&'start'===r&&h||w&&'end'===r&&c||!w&&'start'===r&&g||!w&&'end'===r&&u),E=!!t.flipVariationsByContent&&(w&&'start'===r&&c||w&&'end'===r&&h||!w&&'start'===r&&u||!w&&'end'===r&&g),v=y||E;(m||b||v)&&(e.flipped=!0,(m||b)&&(n=p[d+1]),v&&(r=z(r)),e.placement=n+(r?'-'+r:''),e.offsets.popper=le({},e.offsets.popper,C(e.instance.popper,e.offsets.reference,e.placement)),e=P(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport',flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],n=e.offsets,i=n.popper,r=n.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return i[p?'left':'top']=r[o]-(s?i[p?'width':'height']:0),e.placement=T(t),e.offsets.popper=g(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!K(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=D(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=t.x,n=t.y,i=e.offsets.popper,r=D(e.instance.modifiers,function(e){return'applyStyle'===e.name}).gpuAcceleration;void 0!==r&&console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');var s,d,a=void 0===r?t.gpuAcceleration:r,l=p(e.instance.popper),f=u(l),m={position:i.position},h=q(e,2>window.devicePixelRatio||!fe),c='bottom'===o?'top':'bottom',g='right'===n?'left':'right',b=B('transform');if(d='bottom'==c?'HTML'===l.nodeName?-l.clientHeight+h.bottom:-f.height+h.bottom:h.top,s='right'==g?'HTML'===l.nodeName?-l.clientWidth+h.right:-f.width+h.right:h.left,a&&b)m[b]='translate3d('+s+'px, '+d+'px, 0)',m[c]=0,m[g]=0,m.willChange='transform';else{var w='bottom'==c?-1:1,y='right'==g?-1:1;m[c]=d*w,m[g]=s*y,m.willChange=c+', '+g}var E={"x-placement":e.placement};return e.attributes=le({},E,e.attributes),e.styles=le({},m,e.styles),e.arrowStyles=le({},e.offsets.arrow,e.arrowStyles),e},gpuAcceleration:!0,x:'bottom',y:'right'},applyStyle:{order:900,enabled:!0,fn:function(e){return V(e.instance.popper,e.styles),j(e.instance.popper,e.attributes),e.arrowElement&&Object.keys(e.arrowStyles).length&&V(e.arrowElement,e.arrowStyles),e},onLoad:function(e,t,o,n,i){var r=L(i,t,e,o.positionFixed),p=O(o.placement,r,t,e,o.modifiers.flip.boundariesElement,o.modifiers.flip.padding);return t.setAttribute('x-placement',p),V(t,{position:o.positionFixed?'fixed':'absolute'}),o},gpuAcceleration:void 0}}},ge}); | ||
| + | |||
| + | /*! | ||
| + | * Bootstrap util.js v4.5.0 (https://getbootstrap.com/) | ||
| + | * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) | ||
| + | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | ||
| + | */ | ||
| + | (function (global, factory) { | ||
| + | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery')) : | ||
| + | typeof define === 'function' && define.amd ? define(['jquery'], factory) : | ||
| + | (global = global || self, global.Util = factory(global.jQuery)); | ||
| + | }(this, (function ($) { 'use strict'; | ||
| + | |||
| + | $ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $; | ||
| + | |||
| + | /** | ||
| + | * -------------------------------------------------------------------------- | ||
| + | * Bootstrap (v4.5.0): util.js | ||
| + | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | ||
| + | * -------------------------------------------------------------------------- | ||
| + | */ | ||
| + | /** | ||
| + | * ------------------------------------------------------------------------ | ||
| + | * Private TransitionEnd Helpers | ||
| + | * ------------------------------------------------------------------------ | ||
| + | */ | ||
| + | |||
| + | var TRANSITION_END = 'transitionend'; | ||
| + | var MAX_UID = 1000000; | ||
| + | var MILLISECONDS_MULTIPLIER = 1000; // Shoutout AngusCroll (https://goo.gl/pxwQGp) | ||
| + | |||
| + | function toType(obj) { | ||
| + | if (obj === null || typeof obj === 'undefined') { | ||
| + | return "" + obj; | ||
| + | } | ||
| + | |||
| + | return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase(); | ||
| + | } | ||
| + | |||
| + | function getSpecialTransitionEndEvent() { | ||
| + | return { | ||
| + | bindType: TRANSITION_END, | ||
| + | delegateType: TRANSITION_END, | ||
| + | handle: function handle(event) { | ||
| + | if ($(event.target).is(this)) { | ||
| + | return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params | ||
| + | } | ||
| + | |||
| + | return undefined; | ||
| + | } | ||
| + | }; | ||
| + | } | ||
| + | |||
| + | function transitionEndEmulator(duration) { | ||
| + | var _this = this; | ||
| + | |||
| + | var called = false; | ||
| + | $(this).one(Util.TRANSITION_END, function () { | ||
| + | called = true; | ||
| + | }); | ||
| + | setTimeout(function () { | ||
| + | if (!called) { | ||
| + | Util.triggerTransitionEnd(_this); | ||
| + | } | ||
| + | }, duration); | ||
| + | return this; | ||
| + | } | ||
| + | |||
| + | function setTransitionEndSupport() { | ||
| + | $.fn.emulateTransitionEnd = transitionEndEmulator; | ||
| + | $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent(); | ||
| + | } | ||
| + | /** | ||
| + | * -------------------------------------------------------------------------- | ||
| + | * Public Util Api | ||
| + | * -------------------------------------------------------------------------- | ||
| + | */ | ||
| + | |||
| + | |||
| + | var Util = { | ||
| + | TRANSITION_END: 'bsTransitionEnd', | ||
| + | getUID: function getUID(prefix) { | ||
| + | do { | ||
| + | // eslint-disable-next-line no-bitwise | ||
| + | prefix += ~~(Math.random() * MAX_UID); // "~~" acts like a faster Math.floor() here | ||
| + | } while (document.getElementById(prefix)); | ||
| + | |||
| + | return prefix; | ||
| + | }, | ||
| + | getSelectorFromElement: function getSelectorFromElement(element) { | ||
| + | var selector = element.getAttribute('data-target'); | ||
| + | |||
| + | if (!selector || selector === '#') { | ||
| + | var hrefAttr = element.getAttribute('href'); | ||
| + | selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''; | ||
| + | } | ||
| + | |||
| + | try { | ||
| + | return document.querySelector(selector) ? selector : null; | ||
| + | } catch (err) { | ||
| + | return null; | ||
| + | } | ||
| + | }, | ||
| + | getTransitionDurationFromElement: function getTransitionDurationFromElement(element) { | ||
| + | if (!element) { | ||
| + | return 0; | ||
| + | } // Get transition-duration of the element | ||
| + | |||
| + | |||
| + | var transitionDuration = $(element).css('transition-duration'); | ||
| + | var transitionDelay = $(element).css('transition-delay'); | ||
| + | var floatTransitionDuration = parseFloat(transitionDuration); | ||
| + | var floatTransitionDelay = parseFloat(transitionDelay); // Return 0 if element or transition duration is not found | ||
| + | |||
| + | if (!floatTransitionDuration && !floatTransitionDelay) { | ||
| + | return 0; | ||
| + | } // If multiple durations are defined, take the first | ||
| + | |||
| + | |||
| + | transitionDuration = transitionDuration.split(',')[0]; | ||
| + | transitionDelay = transitionDelay.split(',')[0]; | ||
| + | return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER; | ||
| + | }, | ||
| + | reflow: function reflow(element) { | ||
| + | return element.offsetHeight; | ||
| + | }, | ||
| + | triggerTransitionEnd: function triggerTransitionEnd(element) { | ||
| + | $(element).trigger(TRANSITION_END); | ||
| + | }, | ||
| + | // TODO: Remove in v5 | ||
| + | supportsTransitionEnd: function supportsTransitionEnd() { | ||
| + | return Boolean(TRANSITION_END); | ||
| + | }, | ||
| + | isElement: function isElement(obj) { | ||
| + | return (obj[0] || obj).nodeType; | ||
| + | }, | ||
| + | typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) { | ||
| + | for (var property in configTypes) { | ||
| + | if (Object.prototype.hasOwnProperty.call(configTypes, property)) { | ||
| + | var expectedTypes = configTypes[property]; | ||
| + | var value = config[property]; | ||
| + | var valueType = value && Util.isElement(value) ? 'element' : toType(value); | ||
| + | |||
| + | if (!new RegExp(expectedTypes).test(valueType)) { | ||
| + | throw new Error(componentName.toUpperCase() + ": " + ("Option \"" + property + "\" provided type \"" + valueType + "\" ") + ("but expected type \"" + expectedTypes + "\".")); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | }, | ||
| + | findShadowRoot: function findShadowRoot(element) { | ||
| + | if (!document.documentElement.attachShadow) { | ||
| + | return null; | ||
| + | } // Can find the shadow root otherwise it'll return the document | ||
| + | |||
| + | |||
| + | if (typeof element.getRootNode === 'function') { | ||
| + | var root = element.getRootNode(); | ||
| + | return root instanceof ShadowRoot ? root : null; | ||
| + | } | ||
| + | |||
| + | if (element instanceof ShadowRoot) { | ||
| + | return element; | ||
| + | } // when we don't find a shadow root | ||
| + | |||
| + | |||
| + | if (!element.parentNode) { | ||
| + | return null; | ||
| + | } | ||
| + | |||
| + | return Util.findShadowRoot(element.parentNode); | ||
| + | }, | ||
| + | jQueryDetection: function jQueryDetection() { | ||
| + | if (typeof $ === 'undefined') { | ||
| + | throw new TypeError('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.'); | ||
| + | } | ||
| + | |||
| + | var version = $.fn.jquery.split(' ')[0].split('.'); | ||
| + | var minMajor = 1; | ||
| + | var ltMajor = 2; | ||
| + | var minMinor = 9; | ||
| + | var minPatch = 1; | ||
| + | var maxMajor = 4; | ||
| + | |||
| + | if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) { | ||
| + | throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0'); | ||
| + | } | ||
| + | } | ||
| + | }; | ||
| + | Util.jQueryDetection(); | ||
| + | setTransitionEndSupport(); | ||
| + | |||
| + | return Util; | ||
| + | |||
| + | }))); | ||
| + | //# sourceMappingURL=util.js.map | ||
| + | |||
| + | /*! | ||
| + | * Bootstrap dropdown.js v4.5.0 (https://getbootstrap.com/) | ||
| + | * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) | ||
| + | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | ||
| + | */ | ||
| + | (function (global, factory) { | ||
| + | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('popper.js'), require('./util.js')) : | ||
| + | typeof define === 'function' && define.amd ? define(['jquery', 'popper.js', './util.js'], factory) : | ||
| + | (global = global || self, global.Dropdown = factory(global.jQuery, global.Popper, global.Util)); | ||
| + | }(this, (function ($, Popper, Util) { 'use strict'; | ||
| + | |||
| + | $ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $; | ||
| + | Popper = Popper && Object.prototype.hasOwnProperty.call(Popper, 'default') ? Popper['default'] : Popper; | ||
| + | Util = Util && Object.prototype.hasOwnProperty.call(Util, 'default') ? Util['default'] : Util; | ||
| + | |||
| + | function _defineProperties(target, props) { | ||
| + | for (var i = 0; i < props.length; i++) { | ||
| + | var descriptor = props[i]; | ||
| + | descriptor.enumerable = descriptor.enumerable || false; | ||
| + | descriptor.configurable = true; | ||
| + | if ("value" in descriptor) descriptor.writable = true; | ||
| + | Object.defineProperty(target, descriptor.key, descriptor); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function _createClass(Constructor, protoProps, staticProps) { | ||
| + | if (protoProps) _defineProperties(Constructor.prototype, protoProps); | ||
| + | if (staticProps) _defineProperties(Constructor, staticProps); | ||
| + | return Constructor; | ||
| + | } | ||
| + | |||
| + | function _defineProperty(obj, key, value) { | ||
| + | if (key in obj) { | ||
| + | Object.defineProperty(obj, key, { | ||
| + | value: value, | ||
| + | enumerable: true, | ||
| + | configurable: true, | ||
| + | writable: true | ||
| + | }); | ||
| + | } else { | ||
| + | obj[key] = value; | ||
| + | } | ||
| + | |||
| + | return obj; | ||
| + | } | ||
| + | |||
| + | function ownKeys(object, enumerableOnly) { | ||
| + | var keys = Object.keys(object); | ||
| + | |||
| + | if (Object.getOwnPropertySymbols) { | ||
| + | var symbols = Object.getOwnPropertySymbols(object); | ||
| + | if (enumerableOnly) symbols = symbols.filter(function (sym) { | ||
| + | return Object.getOwnPropertyDescriptor(object, sym).enumerable; | ||
| + | }); | ||
| + | keys.push.apply(keys, symbols); | ||
| + | } | ||
| + | |||
| + | return keys; | ||
| + | } | ||
| + | |||
| + | function _objectSpread2(target) { | ||
| + | for (var i = 1; i < arguments.length; i++) { | ||
| + | var source = arguments[i] != null ? arguments[i] : {}; | ||
| + | |||
| + | if (i % 2) { | ||
| + | ownKeys(Object(source), true).forEach(function (key) { | ||
| + | _defineProperty(target, key, source[key]); | ||
| + | }); | ||
| + | } else if (Object.getOwnPropertyDescriptors) { | ||
| + | Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); | ||
| + | } else { | ||
| + | ownKeys(Object(source)).forEach(function (key) { | ||
| + | Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); | ||
| + | }); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | return target; | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * ------------------------------------------------------------------------ | ||
| + | * Constants | ||
| + | * ------------------------------------------------------------------------ | ||
| + | */ | ||
| + | |||
| + | var NAME = 'dropdown'; | ||
| + | var VERSION = '4.5.0'; | ||
| + | var DATA_KEY = 'bs.dropdown'; | ||
| + | var EVENT_KEY = "." + DATA_KEY; | ||
| + | var DATA_API_KEY = '.data-api'; | ||
| + | var JQUERY_NO_CONFLICT = $.fn[NAME]; | ||
| + | var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key | ||
| + | |||
| + | var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key | ||
| + | |||
| + | var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key | ||
| + | |||
| + | var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key | ||
| + | |||
| + | var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key | ||
| + | |||
| + | var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse) | ||
| + | |||
| + | var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + "|" + ARROW_DOWN_KEYCODE + "|" + ESCAPE_KEYCODE); | ||
| + | var EVENT_HIDE = "hide" + EVENT_KEY; | ||
| + | var EVENT_HIDDEN = "hidden" + EVENT_KEY; | ||
| + | var EVENT_SHOW = "show" + EVENT_KEY; | ||
| + | var EVENT_SHOWN = "shown" + EVENT_KEY; | ||
| + | var EVENT_CLICK = "click" + EVENT_KEY; | ||
| + | var EVENT_CLICK_DATA_API = "click" + EVENT_KEY + DATA_API_KEY; | ||
| + | var EVENT_KEYDOWN_DATA_API = "keydown" + EVENT_KEY + DATA_API_KEY; | ||
| + | var EVENT_KEYUP_DATA_API = "keyup" + EVENT_KEY + DATA_API_KEY; | ||
| + | var CLASS_NAME_DISABLED = 'disabled'; | ||
| + | var CLASS_NAME_SHOW = 'show'; | ||
| + | var CLASS_NAME_DROPUP = 'dropup'; | ||
| + | var CLASS_NAME_DROPRIGHT = 'dropright'; | ||
| + | var CLASS_NAME_DROPLEFT = 'dropleft'; | ||
| + | var CLASS_NAME_MENURIGHT = 'dropdown-menu-right'; | ||
| + | var CLASS_NAME_POSITION_STATIC = 'position-static'; | ||
| + | var SELECTOR_DATA_TOGGLE = '[data-toggle="dropdown"]'; | ||
| + | var SELECTOR_FORM_CHILD = '.dropdown form'; | ||
| + | var SELECTOR_MENU = '.dropdown-menu'; | ||
| + | var SELECTOR_NAVBAR_NAV = '.navbar-nav'; | ||
| + | var SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'; | ||
| + | var PLACEMENT_TOP = 'top-start'; | ||
| + | var PLACEMENT_TOPEND = 'top-end'; | ||
| + | var PLACEMENT_BOTTOM = 'bottom-start'; | ||
| + | var PLACEMENT_BOTTOMEND = 'bottom-end'; | ||
| + | var PLACEMENT_RIGHT = 'right-start'; | ||
| + | var PLACEMENT_LEFT = 'left-start'; | ||
| + | var Default = { | ||
| + | offset: 0, | ||
| + | flip: true, | ||
| + | boundary: 'scrollParent', | ||
| + | reference: 'toggle', | ||
| + | display: 'dynamic', | ||
| + | popperConfig: null | ||
| + | }; | ||
| + | var DefaultType = { | ||
| + | offset: '(number|string|function)', | ||
| + | flip: 'boolean', | ||
| + | boundary: '(string|element)', | ||
| + | reference: '(string|element)', | ||
| + | display: 'string', | ||
| + | popperConfig: '(null|object)' | ||
| + | }; | ||
| + | /** | ||
| + | * ------------------------------------------------------------------------ | ||
| + | * Class Definition | ||
| + | * ------------------------------------------------------------------------ | ||
| + | */ | ||
| + | |||
| + | var Dropdown = /*#__PURE__*/function () { | ||
| + | function Dropdown(element, config) { | ||
| + | this._element = element; | ||
| + | this._popper = null; | ||
| + | this._config = this._getConfig(config); | ||
| + | this._menu = this._getMenuElement(); | ||
| + | this._inNavbar = this._detectNavbar(); | ||
| + | |||
| + | this._addEventListeners(); | ||
| + | } // Getters | ||
| + | |||
| + | |||
| + | var _proto = Dropdown.prototype; | ||
| + | |||
| + | // Public | ||
| + | _proto.toggle = function toggle() { | ||
| + | if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED)) { | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | var isActive = $(this._menu).hasClass(CLASS_NAME_SHOW); | ||
| + | |||
| + | Dropdown._clearMenus(); | ||
| + | |||
| + | if (isActive) { | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | this.show(true); | ||
| + | }; | ||
| + | |||
| + | _proto.show = function show(usePopper) { | ||
| + | if (usePopper === void 0) { | ||
| + | usePopper = false; | ||
| + | } | ||
| + | |||
| + | if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || $(this._menu).hasClass(CLASS_NAME_SHOW)) { | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | var relatedTarget = { | ||
| + | relatedTarget: this._element | ||
| + | }; | ||
| + | var showEvent = $.Event(EVENT_SHOW, relatedTarget); | ||
| + | |||
| + | var parent = Dropdown._getParentFromElement(this._element); | ||
| + | |||
| + | $(parent).trigger(showEvent); | ||
| + | |||
| + | if (showEvent.isDefaultPrevented()) { | ||
| + | return; | ||
| + | } // Disable totally Popper.js for Dropdown in Navbar | ||
| + | |||
| + | |||
| + | if (!this._inNavbar && usePopper) { | ||
| + | /** | ||
| + | * Check for Popper dependency | ||
| + | * Popper - https://popper.js.org | ||
| + | */ | ||
| + | if (typeof Popper === 'undefined') { | ||
| + | throw new TypeError('Bootstrap\'s dropdowns require Popper.js (https://popper.js.org/)'); | ||
| + | } | ||
| + | |||
| + | var referenceElement = this._element; | ||
| + | |||
| + | if (this._config.reference === 'parent') { | ||
| + | referenceElement = parent; | ||
| + | } else if (Util.isElement(this._config.reference)) { | ||
| + | referenceElement = this._config.reference; // Check if it's jQuery element | ||
| + | |||
| + | if (typeof this._config.reference.jquery !== 'undefined') { | ||
| + | referenceElement = this._config.reference[0]; | ||
| + | } | ||
| + | } // If boundary is not `scrollParent`, then set position to `static` | ||
| + | // to allow the menu to "escape" the scroll parent's boundaries | ||
| + | // https://github.com/twbs/bootstrap/issues/24251 | ||
| + | |||
| + | |||
| + | if (this._config.boundary !== 'scrollParent') { | ||
| + | $(parent).addClass(CLASS_NAME_POSITION_STATIC); | ||
| + | } | ||
| + | |||
| + | this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig()); | ||
| + | } // If this is a touch-enabled device we add extra | ||
| + | // empty mouseover listeners to the body's immediate children; | ||
| + | // only needed because of broken event delegation on iOS | ||
| + | // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html | ||
| + | |||
| + | |||
| + | if ('ontouchstart' in document.documentElement && $(parent).closest(SELECTOR_NAVBAR_NAV).length === 0) { | ||
| + | $(document.body).children().on('mouseover', null, $.noop); | ||
| + | } | ||
| + | |||
| + | this._element.focus(); | ||
| + | |||
| + | this._element.setAttribute('aria-expanded', true); | ||
| + | |||
| + | $(this._menu).toggleClass(CLASS_NAME_SHOW); | ||
| + | $(parent).toggleClass(CLASS_NAME_SHOW).trigger($.Event(EVENT_SHOWN, relatedTarget)); | ||
| + | }; | ||
| + | |||
| + | _proto.hide = function hide() { | ||
| + | if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || !$(this._menu).hasClass(CLASS_NAME_SHOW)) { | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | var relatedTarget = { | ||
| + | relatedTarget: this._element | ||
| + | }; | ||
| + | var hideEvent = $.Event(EVENT_HIDE, relatedTarget); | ||
| + | |||
| + | var parent = Dropdown._getParentFromElement(this._element); | ||
| + | |||
| + | $(parent).trigger(hideEvent); | ||
| + | |||
| + | if (hideEvent.isDefaultPrevented()) { | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | if (this._popper) { | ||
| + | this._popper.destroy(); | ||
| + | } | ||
| + | |||
| + | $(this._menu).toggleClass(CLASS_NAME_SHOW); | ||
| + | $(parent).toggleClass(CLASS_NAME_SHOW).trigger($.Event(EVENT_HIDDEN, relatedTarget)); | ||
| + | }; | ||
| + | |||
| + | _proto.dispose = function dispose() { | ||
| + | $.removeData(this._element, DATA_KEY); | ||
| + | $(this._element).off(EVENT_KEY); | ||
| + | this._element = null; | ||
| + | this._menu = null; | ||
| + | |||
| + | if (this._popper !== null) { | ||
| + | this._popper.destroy(); | ||
| + | |||
| + | this._popper = null; | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | _proto.update = function update() { | ||
| + | this._inNavbar = this._detectNavbar(); | ||
| + | |||
| + | if (this._popper !== null) { | ||
| + | this._popper.scheduleUpdate(); | ||
| + | } | ||
| + | } // Private | ||
| + | ; | ||
| + | |||
| + | _proto._addEventListeners = function _addEventListeners() { | ||
| + | var _this = this; | ||
| + | |||
| + | $(this._element).on(EVENT_CLICK, function (event) { | ||
| + | event.preventDefault(); | ||
| + | event.stopPropagation(); | ||
| + | |||
| + | _this.toggle(); | ||
| + | }); | ||
| + | }; | ||
| + | |||
| + | _proto._getConfig = function _getConfig(config) { | ||
| + | config = _objectSpread2(_objectSpread2(_objectSpread2({}, this.constructor.Default), $(this._element).data()), config); | ||
| + | Util.typeCheckConfig(NAME, config, this.constructor.DefaultType); | ||
| + | return config; | ||
| + | }; | ||
| + | |||
| + | _proto._getMenuElement = function _getMenuElement() { | ||
| + | if (!this._menu) { | ||
| + | var parent = Dropdown._getParentFromElement(this._element); | ||
| + | |||
| + | if (parent) { | ||
| + | this._menu = parent.querySelector(SELECTOR_MENU); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | return this._menu; | ||
| + | }; | ||
| + | |||
| + | _proto._getPlacement = function _getPlacement() { | ||
| + | var $parentDropdown = $(this._element.parentNode); | ||
| + | var placement = PLACEMENT_BOTTOM; // Handle dropup | ||
| + | |||
| + | if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) { | ||
| + | placement = $(this._menu).hasClass(CLASS_NAME_MENURIGHT) ? PLACEMENT_TOPEND : PLACEMENT_TOP; | ||
| + | } else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) { | ||
| + | placement = PLACEMENT_RIGHT; | ||
| + | } else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) { | ||
| + | placement = PLACEMENT_LEFT; | ||
| + | } else if ($(this._menu).hasClass(CLASS_NAME_MENURIGHT)) { | ||
| + | placement = PLACEMENT_BOTTOMEND; | ||
| + | } | ||
| + | |||
| + | return placement; | ||
| + | }; | ||
| + | |||
| + | _proto._detectNavbar = function _detectNavbar() { | ||
| + | return $(this._element).closest('.navbar').length > 0; | ||
| + | }; | ||
| + | |||
| + | _proto._getOffset = function _getOffset() { | ||
| + | var _this2 = this; | ||
| + | |||
| + | var offset = {}; | ||
| + | |||
| + | if (typeof this._config.offset === 'function') { | ||
| + | offset.fn = function (data) { | ||
| + | data.offsets = _objectSpread2(_objectSpread2({}, data.offsets), _this2._config.offset(data.offsets, _this2._element) || {}); | ||
| + | return data; | ||
| + | }; | ||
| + | } else { | ||
| + | offset.offset = this._config.offset; | ||
| + | } | ||
| + | |||
| + | return offset; | ||
| + | }; | ||
| + | |||
| + | _proto._getPopperConfig = function _getPopperConfig() { | ||
| + | var popperConfig = { | ||
| + | placement: this._getPlacement(), | ||
| + | modifiers: { | ||
| + | offset: this._getOffset(), | ||
| + | flip: { | ||
| + | enabled: this._config.flip | ||
| + | }, | ||
| + | preventOverflow: { | ||
| + | boundariesElement: this._config.boundary | ||
| + | } | ||
| + | } | ||
| + | }; // Disable Popper.js if we have a static display | ||
| + | |||
| + | if (this._config.display === 'static') { | ||
| + | popperConfig.modifiers.applyStyle = { | ||
| + | enabled: false | ||
| + | }; | ||
| + | } | ||
| + | |||
| + | return _objectSpread2(_objectSpread2({}, popperConfig), this._config.popperConfig); | ||
| + | } // Static | ||
| + | ; | ||
| + | |||
| + | Dropdown._jQueryInterface = function _jQueryInterface(config) { | ||
| + | return this.each(function () { | ||
| + | var data = $(this).data(DATA_KEY); | ||
| + | |||
| + | var _config = typeof config === 'object' ? config : null; | ||
| + | |||
| + | if (!data) { | ||
| + | data = new Dropdown(this, _config); | ||
| + | $(this).data(DATA_KEY, data); | ||
| + | } | ||
| + | |||
| + | if (typeof config === 'string') { | ||
| + | if (typeof data[config] === 'undefined') { | ||
| + | throw new TypeError("No method named \"" + config + "\""); | ||
| + | } | ||
| + | |||
| + | data[config](); | ||
| + | } | ||
| + | }); | ||
| + | }; | ||
| + | |||
| + | Dropdown._clearMenus = function _clearMenus(event) { | ||
| + | if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) { | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | var toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE)); | ||
| + | |||
| + | for (var i = 0, len = toggles.length; i < len; i++) { | ||
| + | var parent = Dropdown._getParentFromElement(toggles[i]); | ||
| + | |||
| + | var context = $(toggles[i]).data(DATA_KEY); | ||
| + | var relatedTarget = { | ||
| + | relatedTarget: toggles[i] | ||
| + | }; | ||
| + | |||
| + | if (event && event.type === 'click') { | ||
| + | relatedTarget.clickEvent = event; | ||
| + | } | ||
| + | |||
| + | if (!context) { | ||
| + | continue; | ||
| + | } | ||
| + | |||
| + | var dropdownMenu = context._menu; | ||
| + | |||
| + | if (!$(parent).hasClass(CLASS_NAME_SHOW)) { | ||
| + | continue; | ||
| + | } | ||
| + | |||
| + | if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $.contains(parent, event.target)) { | ||
| + | continue; | ||
| + | } | ||
| + | |||
| + | var hideEvent = $.Event(EVENT_HIDE, relatedTarget); | ||
| + | $(parent).trigger(hideEvent); | ||
| + | |||
| + | if (hideEvent.isDefaultPrevented()) { | ||
| + | continue; | ||
| + | } // If this is a touch-enabled device we remove the extra | ||
| + | // empty mouseover listeners we added for iOS support | ||
| + | |||
| + | |||
| + | if ('ontouchstart' in document.documentElement) { | ||
| + | $(document.body).children().off('mouseover', null, $.noop); | ||
| + | } | ||
| + | |||
| + | toggles[i].setAttribute('aria-expanded', 'false'); | ||
| + | |||
| + | if (context._popper) { | ||
| + | context._popper.destroy(); | ||
| + | } | ||
| + | |||
| + | $(dropdownMenu).removeClass(CLASS_NAME_SHOW); | ||
| + | $(parent).removeClass(CLASS_NAME_SHOW).trigger($.Event(EVENT_HIDDEN, relatedTarget)); | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | Dropdown._getParentFromElement = function _getParentFromElement(element) { | ||
| + | var parent; | ||
| + | var selector = Util.getSelectorFromElement(element); | ||
| + | |||
| + | if (selector) { | ||
| + | parent = document.querySelector(selector); | ||
| + | } | ||
| + | |||
| + | return parent || element.parentNode; | ||
| + | } // eslint-disable-next-line complexity | ||
| + | ; | ||
| + | |||
| + | Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) { | ||
| + | // If not input/textarea: | ||
| + | // - And not a key in REGEXP_KEYDOWN => not a dropdown command | ||
| + | // If input/textarea: | ||
| + | // - If space key => not a dropdown command | ||
| + | // - If key is other than escape | ||
| + | // - If key is not up or down => not a dropdown command | ||
| + | // - If trigger inside the menu => not a dropdown command | ||
| + | if (/input|textarea/i.test(event.target.tagName) ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $(event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) { | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | if (this.disabled || $(this).hasClass(CLASS_NAME_DISABLED)) { | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | var parent = Dropdown._getParentFromElement(this); | ||
| + | |||
| + | var isActive = $(parent).hasClass(CLASS_NAME_SHOW); | ||
| + | |||
| + | if (!isActive && event.which === ESCAPE_KEYCODE) { | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | event.preventDefault(); | ||
| + | event.stopPropagation(); | ||
| + | |||
| + | if (!isActive || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) { | ||
| + | if (event.which === ESCAPE_KEYCODE) { | ||
| + | $(parent.querySelector(SELECTOR_DATA_TOGGLE)).trigger('focus'); | ||
| + | } | ||
| + | |||
| + | $(this).trigger('click'); | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | var items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS)).filter(function (item) { | ||
| + | return $(item).is(':visible'); | ||
| + | }); | ||
| + | |||
| + | if (items.length === 0) { | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | var index = items.indexOf(event.target); | ||
| + | |||
| + | if (event.which === ARROW_UP_KEYCODE && index > 0) { | ||
| + | // Up | ||
| + | index--; | ||
| + | } | ||
| + | |||
| + | if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { | ||
| + | // Down | ||
| + | index++; | ||
| + | } | ||
| + | |||
| + | if (index < 0) { | ||
| + | index = 0; | ||
| + | } | ||
| + | |||
| + | items[index].focus(); | ||
| + | }; | ||
| + | |||
| + | _createClass(Dropdown, null, [{ | ||
| + | key: "VERSION", | ||
| + | get: function get() { | ||
| + | return VERSION; | ||
| + | } | ||
| + | }, { | ||
| + | key: "Default", | ||
| + | get: function get() { | ||
| + | return Default; | ||
| + | } | ||
| + | }, { | ||
| + | key: "DefaultType", | ||
| + | get: function get() { | ||
| + | return DefaultType; | ||
| + | } | ||
| + | }]); | ||
| + | |||
| + | return Dropdown; | ||
| + | }(); | ||
| + | /** | ||
| + | * ------------------------------------------------------------------------ | ||
| + | * Data Api implementation | ||
| + | * ------------------------------------------------------------------------ | ||
| + | */ | ||
| + | |||
| + | |||
| + | $(document).on(EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown._dataApiKeydownHandler).on(EVENT_CLICK_DATA_API + " " + EVENT_KEYUP_DATA_API, Dropdown._clearMenus).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { | ||
| + | event.preventDefault(); | ||
| + | event.stopPropagation(); | ||
| + | |||
| + | Dropdown._jQueryInterface.call($(this), 'toggle'); | ||
| + | }).on(EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, function (e) { | ||
| + | e.stopPropagation(); | ||
| + | }); | ||
| + | /** | ||
| + | * ------------------------------------------------------------------------ | ||
| + | * jQuery | ||
| + | * ------------------------------------------------------------------------ | ||
| + | */ | ||
| + | |||
| + | $.fn[NAME] = Dropdown._jQueryInterface; | ||
| + | $.fn[NAME].Constructor = Dropdown; | ||
| + | |||
| + | $.fn[NAME].noConflict = function () { | ||
| + | $.fn[NAME] = JQUERY_NO_CONFLICT; | ||
| + | return Dropdown._jQueryInterface; | ||
| + | }; | ||
| + | |||
| + | return Dropdown; | ||
| + | |||
| + | }))); | ||
| + | |||
| + | /*! | ||
| + | * Bootstrap tooltip.js v4.5.0 (https://getbootstrap.com/) | ||
| + | * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) | ||
| + | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | ||
| + | */ | ||
| + | (function (global, factory) { | ||
| + | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('popper.js'), require('./util.js')) : | ||
| + | typeof define === 'function' && define.amd ? define(['jquery', 'popper.js', './util.js'], factory) : | ||
| + | (global = global || self, global.Tooltip = factory(global.jQuery, global.Popper, global.Util)); | ||
| + | }(this, (function ($, Popper, Util) { 'use strict'; | ||
| + | |||
| + | $ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $; | ||
| + | Popper = Popper && Object.prototype.hasOwnProperty.call(Popper, 'default') ? Popper['default'] : Popper; | ||
| + | Util = Util && Object.prototype.hasOwnProperty.call(Util, 'default') ? Util['default'] : Util; | ||
| + | |||
| + | function _defineProperties(target, props) { | ||
| + | for (var i = 0; i < props.length; i++) { | ||
| + | var descriptor = props[i]; | ||
| + | descriptor.enumerable = descriptor.enumerable || false; | ||
| + | descriptor.configurable = true; | ||
| + | if ("value" in descriptor) descriptor.writable = true; | ||
| + | Object.defineProperty(target, descriptor.key, descriptor); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | function _createClass(Constructor, protoProps, staticProps) { | ||
| + | if (protoProps) _defineProperties(Constructor.prototype, protoProps); | ||
| + | if (staticProps) _defineProperties(Constructor, staticProps); | ||
| + | return Constructor; | ||
| + | } | ||
| + | |||
| + | function _defineProperty(obj, key, value) { | ||
| + | if (key in obj) { | ||
| + | Object.defineProperty(obj, key, { | ||
| + | value: value, | ||
| + | enumerable: true, | ||
| + | configurable: true, | ||
| + | writable: true | ||
| + | }); | ||
| + | } else { | ||
| + | obj[key] = value; | ||
| + | } | ||
| + | |||
| + | return obj; | ||
| + | } | ||
| + | |||
| + | function ownKeys(object, enumerableOnly) { | ||
| + | var keys = Object.keys(object); | ||
| + | |||
| + | if (Object.getOwnPropertySymbols) { | ||
| + | var symbols = Object.getOwnPropertySymbols(object); | ||
| + | if (enumerableOnly) symbols = symbols.filter(function (sym) { | ||
| + | return Object.getOwnPropertyDescriptor(object, sym).enumerable; | ||
| + | }); | ||
| + | keys.push.apply(keys, symbols); | ||
| + | } | ||
| + | |||
| + | return keys; | ||
| + | } | ||
| + | |||
| + | function _objectSpread2(target) { | ||
| + | for (var i = 1; i < arguments.length; i++) { | ||
| + | var source = arguments[i] != null ? arguments[i] : {}; | ||
| + | |||
| + | if (i % 2) { | ||
| + | ownKeys(Object(source), true).forEach(function (key) { | ||
| + | _defineProperty(target, key, source[key]); | ||
| + | }); | ||
| + | } else if (Object.getOwnPropertyDescriptors) { | ||
| + | Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); | ||
| + | } else { | ||
| + | ownKeys(Object(source)).forEach(function (key) { | ||
| + | Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); | ||
| + | }); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | return target; | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * -------------------------------------------------------------------------- | ||
| + | * Bootstrap (v4.5.0): tools/sanitizer.js | ||
| + | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | ||
| + | * -------------------------------------------------------------------------- | ||
| + | */ | ||
| + | var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']; | ||
| + | var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i; | ||
| + | var DefaultWhitelist = { | ||
| + | // Global attributes allowed on any supplied element below. | ||
| + | '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN], | ||
| + | a: ['target', 'href', 'title', 'rel'], | ||
| + | area: [], | ||
| + | b: [], | ||
| + | br: [], | ||
| + | col: [], | ||
| + | code: [], | ||
| + | div: [], | ||
| + | em: [], | ||
| + | hr: [], | ||
| + | h1: [], | ||
| + | h2: [], | ||
| + | h3: [], | ||
| + | h4: [], | ||
| + | h5: [], | ||
| + | h6: [], | ||
| + | i: [], | ||
| + | img: ['src', 'srcset', 'alt', 'title', 'width', 'height'], | ||
| + | li: [], | ||
| + | ol: [], | ||
| + | p: [], | ||
| + | pre: [], | ||
| + | s: [], | ||
| + | small: [], | ||
| + | span: [], | ||
| + | sub: [], | ||
| + | sup: [], | ||
| + | strong: [], | ||
| + | u: [], | ||
| + | ul: [] | ||
| + | }; | ||
| + | /** | ||
| + | * A pattern that recognizes a commonly useful subset of URLs that are safe. | ||
| + | * | ||
| + | * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts | ||
| + | */ | ||
| + | |||
| + | var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi; | ||
| + | /** | ||
| + | * A pattern that matches safe data URLs. Only matches image, video and audio types. | ||
| + | * | ||
| + | * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts | ||
| + | */ | ||
| + | |||
| + | var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i; | ||
| + | |||
| + | function allowedAttribute(attr, allowedAttributeList) { | ||
| + | var attrName = attr.nodeName.toLowerCase(); | ||
| + | |||
| + | if (allowedAttributeList.indexOf(attrName) !== -1) { | ||
| + | if (uriAttrs.indexOf(attrName) !== -1) { | ||
| + | return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN)); | ||
| + | } | ||
| + | |||
| + | return true; | ||
| + | } | ||
| + | |||
| + | var regExp = allowedAttributeList.filter(function (attrRegex) { | ||
| + | return attrRegex instanceof RegExp; | ||
| + | }); // Check if a regular expression validates the attribute. | ||
| + | |||
| + | for (var i = 0, len = regExp.length; i < len; i++) { | ||
| + | if (attrName.match(regExp[i])) { | ||
| + | return true; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | return false; | ||
| + | } | ||
| + | |||
| + | function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) { | ||
| + | if (unsafeHtml.length === 0) { | ||
| + | return unsafeHtml; | ||
| + | } | ||
| + | |||
| + | if (sanitizeFn && typeof sanitizeFn === 'function') { | ||
| + | return sanitizeFn(unsafeHtml); | ||
| + | } | ||
| + | |||
| + | var domParser = new window.DOMParser(); | ||
| + | var createdDocument = domParser.parseFromString(unsafeHtml, 'text/html'); | ||
| + | var whitelistKeys = Object.keys(whiteList); | ||
| + | var elements = [].slice.call(createdDocument.body.querySelectorAll('*')); | ||
| + | |||
| + | var _loop = function _loop(i, len) { | ||
| + | var el = elements[i]; | ||
| + | var elName = el.nodeName.toLowerCase(); | ||
| + | |||
| + | if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) { | ||
| + | el.parentNode.removeChild(el); | ||
| + | return "continue"; | ||
| + | } | ||
| + | |||
| + | var attributeList = [].slice.call(el.attributes); | ||
| + | var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []); | ||
| + | attributeList.forEach(function (attr) { | ||
| + | if (!allowedAttribute(attr, whitelistedAttributes)) { | ||
| + | el.removeAttribute(attr.nodeName); | ||
| + | } | ||
| + | }); | ||
| + | }; | ||
| + | |||
| + | for (var i = 0, len = elements.length; i < len; i++) { | ||
| + | var _ret = _loop(i); | ||
| + | |||
| + | if (_ret === "continue") continue; | ||
| + | } | ||
| + | |||
| + | return createdDocument.body.innerHTML; | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | * ------------------------------------------------------------------------ | ||
| + | * Constants | ||
| + | * ------------------------------------------------------------------------ | ||
| + | */ | ||
| + | |||
| + | var NAME = 'tooltip'; | ||
| + | var VERSION = '4.5.0'; | ||
| + | var DATA_KEY = 'bs.tooltip'; | ||
| + | var EVENT_KEY = "." + DATA_KEY; | ||
| + | var JQUERY_NO_CONFLICT = $.fn[NAME]; | ||
| + | var CLASS_PREFIX = 'bs-tooltip'; | ||
| + | var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g'); | ||
| + | var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']; | ||
| + | var DefaultType = { | ||
| + | animation: 'boolean', | ||
| + | template: 'string', | ||
| + | title: '(string|element|function)', | ||
| + | trigger: 'string', | ||
| + | delay: '(number|object)', | ||
| + | html: 'boolean', | ||
| + | selector: '(string|boolean)', | ||
| + | placement: '(string|function)', | ||
| + | offset: '(number|string|function)', | ||
| + | container: '(string|element|boolean)', | ||
| + | fallbackPlacement: '(string|array)', | ||
| + | boundary: '(string|element)', | ||
| + | sanitize: 'boolean', | ||
| + | sanitizeFn: '(null|function)', | ||
| + | whiteList: 'object', | ||
| + | popperConfig: '(null|object)' | ||
| + | }; | ||
| + | var AttachmentMap = { | ||
| + | AUTO: 'auto', | ||
| + | TOP: 'top', | ||
| + | RIGHT: 'right', | ||
| + | BOTTOM: 'bottom', | ||
| + | LEFT: 'left' | ||
| + | }; | ||
| + | var Default = { | ||
| + | animation: true, | ||
| + | template: '<div class="tooltip" role="tooltip">' + '<div class="arrow"></div>' + '<div class="tooltip-inner"></div></div>', | ||
| + | trigger: 'hover focus', | ||
| + | title: '', | ||
| + | delay: 0, | ||
| + | html: false, | ||
| + | selector: false, | ||
| + | placement: 'top', | ||
| + | offset: 0, | ||
| + | container: false, | ||
| + | fallbackPlacement: 'flip', | ||
| + | boundary: 'scrollParent', | ||
| + | sanitize: true, | ||
| + | sanitizeFn: null, | ||
| + | whiteList: DefaultWhitelist, | ||
| + | popperConfig: null | ||
| + | }; | ||
| + | var HOVER_STATE_SHOW = 'show'; | ||
| + | var HOVER_STATE_OUT = 'out'; | ||
| + | var Event = { | ||
| + | HIDE: "hide" + EVENT_KEY, | ||
| + | HIDDEN: "hidden" + EVENT_KEY, | ||
| + | SHOW: "show" + EVENT_KEY, | ||
| + | SHOWN: "shown" + EVENT_KEY, | ||
| + | INSERTED: "inserted" + EVENT_KEY, | ||
| + | CLICK: "click" + EVENT_KEY, | ||
| + | FOCUSIN: "focusin" + EVENT_KEY, | ||
| + | FOCUSOUT: "focusout" + EVENT_KEY, | ||
| + | MOUSEENTER: "mouseenter" + EVENT_KEY, | ||
| + | MOUSELEAVE: "mouseleave" + EVENT_KEY | ||
| + | }; | ||
| + | var CLASS_NAME_FADE = 'fade'; | ||
| + | var CLASS_NAME_SHOW = 'show'; | ||
| + | var SELECTOR_TOOLTIP_INNER = '.tooltip-inner'; | ||
| + | var SELECTOR_ARROW = '.arrow'; | ||
| + | var TRIGGER_HOVER = 'hover'; | ||
| + | var TRIGGER_FOCUS = 'focus'; | ||
| + | var TRIGGER_CLICK = 'click'; | ||
| + | var TRIGGER_MANUAL = 'manual'; | ||
| + | /** | ||
| + | * ------------------------------------------------------------------------ | ||
| + | * Class Definition | ||
| + | * ------------------------------------------------------------------------ | ||
| + | */ | ||
| + | |||
| + | var Tooltip = /*#__PURE__*/function () { | ||
| + | function Tooltip(element, config) { | ||
| + | if (typeof Popper === 'undefined') { | ||
| + | throw new TypeError('Bootstrap\'s tooltips require Popper.js (https://popper.js.org/)'); | ||
| + | } // private | ||
| + | |||
| + | |||
| + | this._isEnabled = true; | ||
| + | this._timeout = 0; | ||
| + | this._hoverState = ''; | ||
| + | this._activeTrigger = {}; | ||
| + | this._popper = null; // Protected | ||
| + | |||
| + | this.element = element; | ||
| + | this.config = this._getConfig(config); | ||
| + | this.tip = null; | ||
| + | |||
| + | this._setListeners(); | ||
| + | } // Getters | ||
| + | |||
| + | |||
| + | var _proto = Tooltip.prototype; | ||
| + | |||
| + | // Public | ||
| + | _proto.enable = function enable() { | ||
| + | this._isEnabled = true; | ||
| + | }; | ||
| + | |||
| + | _proto.disable = function disable() { | ||
| + | this._isEnabled = false; | ||
| + | }; | ||
| + | |||
| + | _proto.toggleEnabled = function toggleEnabled() { | ||
| + | this._isEnabled = !this._isEnabled; | ||
| + | }; | ||
| + | |||
| + | _proto.toggle = function toggle(event) { | ||
| + | if (!this._isEnabled) { | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | if (event) { | ||
| + | var dataKey = this.constructor.DATA_KEY; | ||
| + | var context = $(event.currentTarget).data(dataKey); | ||
| + | |||
| + | if (!context) { | ||
| + | context = new this.constructor(event.currentTarget, this._getDelegateConfig()); | ||
| + | $(event.currentTarget).data(dataKey, context); | ||
| + | } | ||
| + | |||
| + | context._activeTrigger.click = !context._activeTrigger.click; | ||
| + | |||
| + | if (context._isWithActiveTrigger()) { | ||
| + | context._enter(null, context); | ||
| + | } else { | ||
| + | context._leave(null, context); | ||
| + | } | ||
| + | } else { | ||
| + | if ($(this.getTipElement()).hasClass(CLASS_NAME_SHOW)) { | ||
| + | this._leave(null, this); | ||
| + | |||
| + | return; | ||
| + | } | ||
| + | |||
| + | this._enter(null, this); | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | _proto.dispose = function dispose() { | ||
| + | clearTimeout(this._timeout); | ||
| + | $.removeData(this.element, this.constructor.DATA_KEY); | ||
| + | $(this.element).off(this.constructor.EVENT_KEY); | ||
| + | $(this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler); | ||
| + | |||
| + | if (this.tip) { | ||
| + | $(this.tip).remove(); | ||
| + | } | ||
| − | + | this._isEnabled = null; | |
| + | this._timeout = null; | ||
| + | this._hoverState = null; | ||
| + | this._activeTrigger = null; | ||
| − | + | if (this._popper) { | |
| − | + | this._popper.destroy(); | |
| − | + | } | |
| + | this._popper = null; | ||
| + | this.element = null; | ||
| + | this.config = null; | ||
| + | this.tip = null; | ||
| + | }; | ||
| + | _proto.show = function show() { | ||
| + | var _this = this; | ||
| − | function | + | if ($(this.element).css('display') === 'none') { |
| − | { | + | throw new Error('Please use show on visible elements'); |
| − | + | } | |
| − | + | ||
| − | + | var showEvent = $.Event(this.constructor.Event.SHOW); | |
| − | + | ||
| − | + | if (this.isWithContent() && this._isEnabled) { | |
| − | + | $(this.element).trigger(showEvent); | |
| − | if ( | + | var shadowRoot = Util.findShadowRoot(this.element); |
| − | + | var isInTheDom = $.contains(shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement, this.element); | |
| − | + | ||
| + | if (showEvent.isDefaultPrevented() || !isInTheDom) { | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | var tip = this.getTipElement(); | ||
| + | var tipId = Util.getUID(this.constructor.NAME); | ||
| + | tip.setAttribute('id', tipId); | ||
| + | this.element.setAttribute('aria-describedby', tipId); | ||
| + | this.setContent(); | ||
| + | |||
| + | if (this.config.animation) { | ||
| + | $(tip).addClass(CLASS_NAME_FADE); | ||
| + | } | ||
| + | |||
| + | var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement; | ||
| + | |||
| + | var attachment = this._getAttachment(placement); | ||
| + | |||
| + | this.addAttachmentClass(attachment); | ||
| + | |||
| + | var container = this._getContainer(); | ||
| + | |||
| + | $(tip).data(this.constructor.DATA_KEY, this); | ||
| + | |||
| + | if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) { | ||
| + | $(tip).appendTo(container); | ||
| + | } | ||
| + | |||
| + | $(this.element).trigger(this.constructor.Event.INSERTED); | ||
| + | this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment)); | ||
| + | $(tip).addClass(CLASS_NAME_SHOW); // If this is a touch-enabled device we add extra | ||
| + | // empty mouseover listeners to the body's immediate children; | ||
| + | // only needed because of broken event delegation on iOS | ||
| + | // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html | ||
| + | |||
| + | if ('ontouchstart' in document.documentElement) { | ||
| + | $(document.body).children().on('mouseover', null, $.noop); | ||
| + | } | ||
| + | |||
| + | var complete = function complete() { | ||
| + | if (_this.config.animation) { | ||
| + | _this._fixTransition(); | ||
| + | } | ||
| + | |||
| + | var prevHoverState = _this._hoverState; | ||
| + | _this._hoverState = null; | ||
| + | $(_this.element).trigger(_this.constructor.Event.SHOWN); | ||
| + | |||
| + | if (prevHoverState === HOVER_STATE_OUT) { | ||
| + | _this._leave(null, _this); | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | if ($(this.tip).hasClass(CLASS_NAME_FADE)) { | ||
| + | var transitionDuration = Util.getTransitionDurationFromElement(this.tip); | ||
| + | $(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); | ||
| + | } else { | ||
| + | complete(); | ||
| + | } | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | _proto.hide = function hide(callback) { | ||
| + | var _this2 = this; | ||
| + | |||
| + | var tip = this.getTipElement(); | ||
| + | var hideEvent = $.Event(this.constructor.Event.HIDE); | ||
| + | |||
| + | var complete = function complete() { | ||
| + | if (_this2._hoverState !== HOVER_STATE_SHOW && tip.parentNode) { | ||
| + | tip.parentNode.removeChild(tip); | ||
| + | } | ||
| + | |||
| + | _this2._cleanTipClass(); | ||
| + | |||
| + | _this2.element.removeAttribute('aria-describedby'); | ||
| + | |||
| + | $(_this2.element).trigger(_this2.constructor.Event.HIDDEN); | ||
| + | |||
| + | if (_this2._popper !== null) { | ||
| + | _this2._popper.destroy(); | ||
| + | } | ||
| + | |||
| + | if (callback) { | ||
| + | callback(); | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | $(this.element).trigger(hideEvent); | ||
| + | |||
| + | if (hideEvent.isDefaultPrevented()) { | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | $(tip).removeClass(CLASS_NAME_SHOW); // If this is a touch-enabled device we remove the extra | ||
| + | // empty mouseover listeners we added for iOS support | ||
| + | |||
| + | if ('ontouchstart' in document.documentElement) { | ||
| + | $(document.body).children().off('mouseover', null, $.noop); | ||
| + | } | ||
| + | |||
| + | this._activeTrigger[TRIGGER_CLICK] = false; | ||
| + | this._activeTrigger[TRIGGER_FOCUS] = false; | ||
| + | this._activeTrigger[TRIGGER_HOVER] = false; | ||
| + | |||
| + | if ($(this.tip).hasClass(CLASS_NAME_FADE)) { | ||
| + | var transitionDuration = Util.getTransitionDurationFromElement(tip); | ||
| + | $(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); | ||
| + | } else { | ||
| + | complete(); | ||
| + | } | ||
| + | |||
| + | this._hoverState = ''; | ||
| + | }; | ||
| + | |||
| + | _proto.update = function update() { | ||
| + | if (this._popper !== null) { | ||
| + | this._popper.scheduleUpdate(); | ||
| + | } | ||
| + | } // Protected | ||
| + | ; | ||
| + | |||
| + | _proto.isWithContent = function isWithContent() { | ||
| + | return Boolean(this.getTitle()); | ||
| + | }; | ||
| + | |||
| + | _proto.addAttachmentClass = function addAttachmentClass(attachment) { | ||
| + | $(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment); | ||
| + | }; | ||
| + | |||
| + | _proto.getTipElement = function getTipElement() { | ||
| + | this.tip = this.tip || $(this.config.template)[0]; | ||
| + | return this.tip; | ||
| + | }; | ||
| + | |||
| + | _proto.setContent = function setContent() { | ||
| + | var tip = this.getTipElement(); | ||
| + | this.setElementContent($(tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle()); | ||
| + | $(tip).removeClass(CLASS_NAME_FADE + " " + CLASS_NAME_SHOW); | ||
| + | }; | ||
| + | |||
| + | _proto.setElementContent = function setElementContent($element, content) { | ||
| + | if (typeof content === 'object' && (content.nodeType || content.jquery)) { | ||
| + | // Content is a DOM node or a jQuery | ||
| + | if (this.config.html) { | ||
| + | if (!$(content).parent().is($element)) { | ||
| + | $element.empty().append(content); | ||
| + | } | ||
| + | } else { | ||
| + | $element.text($(content).text()); | ||
| + | } | ||
| + | |||
| + | return; | ||
| + | } | ||
| + | |||
| + | if (this.config.html) { | ||
| + | if (this.config.sanitize) { | ||
| + | content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn); | ||
| + | } | ||
| + | |||
| + | $element.html(content); | ||
| + | } else { | ||
| + | $element.text(content); | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | _proto.getTitle = function getTitle() { | ||
| + | var title = this.element.getAttribute('data-original-title'); | ||
| + | |||
| + | if (!title) { | ||
| + | title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title; | ||
| + | } | ||
| + | |||
| + | return title; | ||
| + | } // Private | ||
| + | ; | ||
| + | |||
| + | _proto._getPopperConfig = function _getPopperConfig(attachment) { | ||
| + | var _this3 = this; | ||
| + | |||
| + | var defaultBsConfig = { | ||
| + | placement: attachment, | ||
| + | modifiers: { | ||
| + | offset: this._getOffset(), | ||
| + | flip: { | ||
| + | behavior: this.config.fallbackPlacement | ||
| + | }, | ||
| + | arrow: { | ||
| + | element: SELECTOR_ARROW | ||
| + | }, | ||
| + | preventOverflow: { | ||
| + | boundariesElement: this.config.boundary | ||
| + | } | ||
| + | }, | ||
| + | onCreate: function onCreate(data) { | ||
| + | if (data.originalPlacement !== data.placement) { | ||
| + | _this3._handlePopperPlacementChange(data); | ||
| + | } | ||
| + | }, | ||
| + | onUpdate: function onUpdate(data) { | ||
| + | return _this3._handlePopperPlacementChange(data); | ||
| + | } | ||
| + | }; | ||
| + | return _objectSpread2(_objectSpread2({}, defaultBsConfig), this.config.popperConfig); | ||
| + | }; | ||
| + | |||
| + | _proto._getOffset = function _getOffset() { | ||
| + | var _this4 = this; | ||
| + | |||
| + | var offset = {}; | ||
| + | |||
| + | if (typeof this.config.offset === 'function') { | ||
| + | offset.fn = function (data) { | ||
| + | data.offsets = _objectSpread2(_objectSpread2({}, data.offsets), _this4.config.offset(data.offsets, _this4.element) || {}); | ||
| + | return data; | ||
| + | }; | ||
| + | } else { | ||
| + | offset.offset = this.config.offset; | ||
| + | } | ||
| + | |||
| + | return offset; | ||
| + | }; | ||
| + | |||
| + | _proto._getContainer = function _getContainer() { | ||
| + | if (this.config.container === false) { | ||
| + | return document.body; | ||
| + | } | ||
| + | |||
| + | if (Util.isElement(this.config.container)) { | ||
| + | return $(this.config.container); | ||
| + | } | ||
| + | |||
| + | return $(document).find(this.config.container); | ||
| + | }; | ||
| + | |||
| + | _proto._getAttachment = function _getAttachment(placement) { | ||
| + | return AttachmentMap[placement.toUpperCase()]; | ||
| + | }; | ||
| + | |||
| + | _proto._setListeners = function _setListeners() { | ||
| + | var _this5 = this; | ||
| + | |||
| + | var triggers = this.config.trigger.split(' '); | ||
| + | triggers.forEach(function (trigger) { | ||
| + | if (trigger === 'click') { | ||
| + | $(_this5.element).on(_this5.constructor.Event.CLICK, _this5.config.selector, function (event) { | ||
| + | return _this5.toggle(event); | ||
| + | }); | ||
| + | } else if (trigger !== TRIGGER_MANUAL) { | ||
| + | var eventIn = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSEENTER : _this5.constructor.Event.FOCUSIN; | ||
| + | var eventOut = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSELEAVE : _this5.constructor.Event.FOCUSOUT; | ||
| + | $(_this5.element).on(eventIn, _this5.config.selector, function (event) { | ||
| + | return _this5._enter(event); | ||
| + | }).on(eventOut, _this5.config.selector, function (event) { | ||
| + | return _this5._leave(event); | ||
| + | }); | ||
| + | } | ||
| + | }); | ||
| + | |||
| + | this._hideModalHandler = function () { | ||
| + | if (_this5.element) { | ||
| + | _this5.hide(); | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | $(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler); | ||
| + | |||
| + | if (this.config.selector) { | ||
| + | this.config = _objectSpread2(_objectSpread2({}, this.config), {}, { | ||
| + | trigger: 'manual', | ||
| + | selector: '' | ||
| + | }); | ||
| + | } else { | ||
| + | this._fixTitle(); | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | _proto._fixTitle = function _fixTitle() { | ||
| + | var titleType = typeof this.element.getAttribute('data-original-title'); | ||
| + | |||
| + | if (this.element.getAttribute('title') || titleType !== 'string') { | ||
| + | this.element.setAttribute('data-original-title', this.element.getAttribute('title') || ''); | ||
| + | this.element.setAttribute('title', ''); | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | _proto._enter = function _enter(event, context) { | ||
| + | var dataKey = this.constructor.DATA_KEY; | ||
| + | context = context || $(event.currentTarget).data(dataKey); | ||
| + | |||
| + | if (!context) { | ||
| + | context = new this.constructor(event.currentTarget, this._getDelegateConfig()); | ||
| + | $(event.currentTarget).data(dataKey, context); | ||
| + | } | ||
| + | |||
| + | if (event) { | ||
| + | context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true; | ||
| + | } | ||
| + | |||
| + | if ($(context.getTipElement()).hasClass(CLASS_NAME_SHOW) || context._hoverState === HOVER_STATE_SHOW) { | ||
| + | context._hoverState = HOVER_STATE_SHOW; | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | clearTimeout(context._timeout); | ||
| + | context._hoverState = HOVER_STATE_SHOW; | ||
| + | |||
| + | if (!context.config.delay || !context.config.delay.show) { | ||
| + | context.show(); | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | context._timeout = setTimeout(function () { | ||
| + | if (context._hoverState === HOVER_STATE_SHOW) { | ||
| + | context.show(); | ||
| + | } | ||
| + | }, context.config.delay.show); | ||
| + | }; | ||
| + | |||
| + | _proto._leave = function _leave(event, context) { | ||
| + | var dataKey = this.constructor.DATA_KEY; | ||
| + | context = context || $(event.currentTarget).data(dataKey); | ||
| + | |||
| + | if (!context) { | ||
| + | context = new this.constructor(event.currentTarget, this._getDelegateConfig()); | ||
| + | $(event.currentTarget).data(dataKey, context); | ||
| + | } | ||
| + | |||
| + | if (event) { | ||
| + | context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = false; | ||
| + | } | ||
| + | |||
| + | if (context._isWithActiveTrigger()) { | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | clearTimeout(context._timeout); | ||
| + | context._hoverState = HOVER_STATE_OUT; | ||
| + | |||
| + | if (!context.config.delay || !context.config.delay.hide) { | ||
| + | context.hide(); | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | context._timeout = setTimeout(function () { | ||
| + | if (context._hoverState === HOVER_STATE_OUT) { | ||
| + | context.hide(); | ||
| + | } | ||
| + | }, context.config.delay.hide); | ||
| + | }; | ||
| + | |||
| + | _proto._isWithActiveTrigger = function _isWithActiveTrigger() { | ||
| + | for (var trigger in this._activeTrigger) { | ||
| + | if (this._activeTrigger[trigger]) { | ||
| + | return true; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | return false; | ||
| + | }; | ||
| + | |||
| + | _proto._getConfig = function _getConfig(config) { | ||
| + | var dataAttributes = $(this.element).data(); | ||
| + | Object.keys(dataAttributes).forEach(function (dataAttr) { | ||
| + | if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) { | ||
| + | delete dataAttributes[dataAttr]; | ||
| + | } | ||
| + | }); | ||
| + | config = _objectSpread2(_objectSpread2(_objectSpread2({}, this.constructor.Default), dataAttributes), typeof config === 'object' && config ? config : {}); | ||
| + | |||
| + | if (typeof config.delay === 'number') { | ||
| + | config.delay = { | ||
| + | show: config.delay, | ||
| + | hide: config.delay | ||
| + | }; | ||
| + | } | ||
| + | |||
| + | if (typeof config.title === 'number') { | ||
| + | config.title = config.title.toString(); | ||
| + | } | ||
| + | |||
| + | if (typeof config.content === 'number') { | ||
| + | config.content = config.content.toString(); | ||
| + | } | ||
| + | |||
| + | Util.typeCheckConfig(NAME, config, this.constructor.DefaultType); | ||
| + | |||
| + | if (config.sanitize) { | ||
| + | config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn); | ||
| + | } | ||
| + | |||
| + | return config; | ||
| + | }; | ||
| + | |||
| + | _proto._getDelegateConfig = function _getDelegateConfig() { | ||
| + | var config = {}; | ||
| + | |||
| + | if (this.config) { | ||
| + | for (var key in this.config) { | ||
| + | if (this.constructor.Default[key] !== this.config[key]) { | ||
| + | config[key] = this.config[key]; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | return config; | ||
| + | }; | ||
| + | |||
| + | _proto._cleanTipClass = function _cleanTipClass() { | ||
| + | var $tip = $(this.getTipElement()); | ||
| + | var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX); | ||
| + | |||
| + | if (tabClass !== null && tabClass.length) { | ||
| + | $tip.removeClass(tabClass.join('')); | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | _proto._handlePopperPlacementChange = function _handlePopperPlacementChange(popperData) { | ||
| + | this.tip = popperData.instance.popper; | ||
| + | |||
| + | this._cleanTipClass(); | ||
| + | |||
| + | this.addAttachmentClass(this._getAttachment(popperData.placement)); | ||
| + | }; | ||
| + | |||
| + | _proto._fixTransition = function _fixTransition() { | ||
| + | var tip = this.getTipElement(); | ||
| + | var initConfigAnimation = this.config.animation; | ||
| + | |||
| + | if (tip.getAttribute('x-placement') !== null) { | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | $(tip).removeClass(CLASS_NAME_FADE); | ||
| + | this.config.animation = false; | ||
| + | this.hide(); | ||
| + | this.show(); | ||
| + | this.config.animation = initConfigAnimation; | ||
| + | } // Static | ||
| + | ; | ||
| + | |||
| + | Tooltip._jQueryInterface = function _jQueryInterface(config) { | ||
| + | return this.each(function () { | ||
| + | var data = $(this).data(DATA_KEY); | ||
| + | |||
| + | var _config = typeof config === 'object' && config; | ||
| + | |||
| + | if (!data && /dispose|hide/.test(config)) { | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | if (!data) { | ||
| + | data = new Tooltip(this, _config); | ||
| + | $(this).data(DATA_KEY, data); | ||
| + | } | ||
| + | |||
| + | if (typeof config === 'string') { | ||
| + | if (typeof data[config] === 'undefined') { | ||
| + | throw new TypeError("No method named \"" + config + "\""); | ||
| + | } | ||
| + | |||
| + | data[config](); | ||
| + | } | ||
| + | }); | ||
| + | }; | ||
| + | |||
| + | _createClass(Tooltip, null, [{ | ||
| + | key: "VERSION", | ||
| + | get: function get() { | ||
| + | return VERSION; | ||
| + | } | ||
| + | }, { | ||
| + | key: "Default", | ||
| + | get: function get() { | ||
| + | return Default; | ||
| + | } | ||
| + | }, { | ||
| + | key: "NAME", | ||
| + | get: function get() { | ||
| + | return NAME; | ||
| + | } | ||
| + | }, { | ||
| + | key: "DATA_KEY", | ||
| + | get: function get() { | ||
| + | return DATA_KEY; | ||
| + | } | ||
| + | }, { | ||
| + | key: "Event", | ||
| + | get: function get() { | ||
| + | return Event; | ||
| + | } | ||
| + | }, { | ||
| + | key: "EVENT_KEY", | ||
| + | get: function get() { | ||
| + | return EVENT_KEY; | ||
| + | } | ||
| + | }, { | ||
| + | key: "DefaultType", | ||
| + | get: function get() { | ||
| + | return DefaultType; | ||
| + | } | ||
| + | }]); | ||
| + | |||
| + | return Tooltip; | ||
| + | }(); | ||
| + | /** | ||
| + | * ------------------------------------------------------------------------ | ||
| + | * jQuery | ||
| + | * ------------------------------------------------------------------------ | ||
| + | */ | ||
| + | |||
| + | |||
| + | $.fn[NAME] = Tooltip._jQueryInterface; | ||
| + | $.fn[NAME].Constructor = Tooltip; | ||
| + | |||
| + | $.fn[NAME].noConflict = function () { | ||
| + | $.fn[NAME] = JQUERY_NO_CONFLICT; | ||
| + | return Tooltip._jQueryInterface; | ||
| + | }; | ||
| + | |||
| + | return Tooltip; | ||
| + | |||
| + | }))); | ||
| + | |||
| + | /** | ||
| + | * CatRename | ||
| + | * | ||
| + | * Ajoute un onglet permettant de renommer une catégorie, en déplaçant les pages | ||
| + | * incluses dans celle-ci. Permet de faire faire l'action à un bot en un clic. | ||
| + | * | ||
| + | * {{Projet:JavaScript/Script|CatRename}} | ||
| + | */ | ||
| + | /* <nowiki> */ | ||
| + | |||
| + | /* globals mw, OO, $ */ | ||
| + | |||
| + | if ( mw.config.get( 'wgNamespaceNumber' ) === 14 ) { | ||
| + | mw.loader.using( 'mediawiki.util', function () { | ||
| + | 'use strict'; | ||
| + | |||
| + | // Site-related parameters | ||
| + | const TAG = 'RenommageCategorie'; | ||
| + | const DAILY_LIMIT = 250; | ||
| + | const RBOT_PAGE = 'Wikipédia:Bot/Requêtes/Catégories'; | ||
| + | const DR_TEMPLATE = '{{Suppression Immédiate|raison=Catégorie récemment renommée en [[:Catégorie:$2]] ($3)|utilisateur=$4}}\n\n'; | ||
| + | const RBOT_TEMPLATE = '\n{{Déplacement catégorie|ancienne=$1|nouvelle=$2|raison=$3|demandeur=$4}}'; | ||
| + | |||
| + | // Literal non-breaking space, for situations where HTML entities can't be used | ||
| + | const NBSP = String.fromCharCode( 0xA0 ); | ||
| + | |||
| + | // Messages | ||
| + | const messages = { | ||
| + | 'fr': { | ||
| + | 'catrename-title': 'Renommer une catégorie', | ||
| + | 'catrename-portlet-title': 'CatRename', | ||
| + | |||
| + | 'catrename-action-rename': 'Renommer', | ||
| + | 'catrename-action-cancel': 'Annuler', | ||
| + | 'catrename-action-rbot': '… ou faire faire la tâche par un bot', | ||
| + | |||
| + | 'catrename-checkbox-movetalk': 'Renommer aussi la page de discussion associée', | ||
| + | 'catrename-checkbox-leave-redirect': 'Laisser une redirection vers le nouveau titre', | ||
| + | 'catrename-checkbox-post-dr': 'Déposer une demande de suppression de l\'ancienne catégorie', | ||
| + | 'catrename-checkbox-watch': 'Suivre les catégories originale et nouvelle', | ||
| + | 'catrename-checkbox-watch-members': 'Suivre les pages modifiées', | ||
| + | |||
| + | 'catrename-field-title': 'Nouveau titre' + NBSP + ':', | ||
| + | 'catrename-field-reason': 'Motif' + NBSP + ':', | ||
| + | |||
| + | 'catrename-summary': 'Remplacement de la catégorie [[Catégorie:$1]] par [[Catégorie:$2]] : $3', | ||
| + | 'catrename-dr-summary': 'Demande de suppression après renommage', | ||
| + | 'catrename-rbot-summary': 'RBOT : Demande de renommage de catégorie', | ||
| + | |||
| + | 'catrename-status-checkcategory': 'Vérification de la catégorie cible', | ||
| + | 'catrename-status-getmembers': 'Récupération des pages membres de la catégorie', | ||
| + | 'catrename-status-waitinglock': 'En attente de la fin de renommage dans d\'autres onglets', | ||
| + | 'catrename-status-checklimits': 'Vérification de la limite journalière', | ||
| + | 'catrename-status-editmembers': 'Modification de la page $1 sur $2', | ||
| + | 'catrename-status-renamecategory': 'Renommage de la catégorie', | ||
| + | 'catrename-status-postdr': 'Dépôt de la demande de suppression', | ||
| + | 'catrename-status-postrbot': 'Dépôt de la requête aux bots', | ||
| + | |||
| + | 'catrename-error-canceled': 'Le processus de renommage a été annulé.', | ||
| + | 'catrename-error-same': 'Le nouveau titre est identique au titre actuel.', | ||
| + | 'catrename-error-invalidtitle': 'Le titre de la catégorie demandée est non valide, vide, ou mal formé.', | ||
| + | 'catrename-error-noreason': 'Veuillez indiquer un motif pour ce renommage.', | ||
| + | 'catrename-error-protected': 'Cette catégorie est protégée, vous n\'êtes pas autorisé à la renommer.', | ||
| + | 'catrename-error-categoryexist': 'Il existe déjà une catégorie avec ce nom…', | ||
| + | 'catrename-error-limitreached': 'Le renommage de cette catégorie vous ferait faire plus de $1 modifications avec ce script en moins de 24h. Vous pouvez cependant faire une requête aux bots via le bouton en bas à gauche.', | ||
| + | 'catrename-error-categorypresent': 'La page contient déjà la nouvelle catégorie.', | ||
| + | 'catrename-error-notfound': 'La catégorie n\'a pas été trouvée dans le code de la page, peut-être est-elle incluse via un modèle' + NBSP + '?', | ||
| + | 'catrename-error-pageprotected': 'La page est protégée en écriture.', | ||
| + | 'catrename-error-articleexists': 'Impossible de déplacer la catégorie, la page de destination «' + NBSP + '$1' + NBSP + '» existe déjà.', | ||
| + | } | ||
| + | }; | ||
| + | mw.messages.set( messages.fr ); | ||
| + | var lang = mw.config.get( 'wgUserLanguage' ); | ||
| + | if ( lang !== 'fr' && lang in messages ) { | ||
| + | mw.messages.set( messages[ lang ] ); | ||
} | } | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | var | + | var isBootstrapped = false; |
| + | var instanceWindowManager; | ||
| + | var instanceCatRename; | ||
| + | |||
| + | $( function ( $ ) { | ||
| + | var portlet = mw.util.addPortletLink( 'p-cactions', '#', mw.msg( 'catrename-portlet-title' ) ); | ||
| + | $( portlet ).on( 'click', function ( e ) { | ||
| + | e.preventDefault(); | ||
| + | mw.loader.using( [ 'oojs-ui', 'mediawiki.storage', 'mediawiki.api' ], function () { | ||
| + | bootstrapOnce(); | ||
| + | instanceCatRename.open(); | ||
| + | } ); | ||
| + | } ); | ||
| + | } ); | ||
| + | |||
| + | |||
| + | /* Instanciate CatRename and add it to MediaWiki's UI. */ | ||
| + | |||
| + | function bootstrapOnce() { | ||
| + | if (isBootstrapped) { | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | isBootstrapped = true; | ||
| + | |||
| + | /** | ||
| + | * Main class of the gadget CatRename, which is displayed as a ProcessDialog | ||
| + | * | ||
| + | * @class | ||
| + | * @extends OO.ui.ProcessDialog | ||
| + | * | ||
| + | * @constructor | ||
| + | */ | ||
| + | var CatRename = function () { | ||
| + | // Initialize config | ||
| + | var config = { size: 'medium' }; | ||
| + | |||
| + | // Parent constructor | ||
| + | CatRename.parent.call( this, config ); | ||
| + | |||
| + | // Properties | ||
| + | this.api = new mw.Api( { timeout: 7000 } ); | ||
| + | this.oldTitle; | ||
| + | this.newTitle; | ||
| + | this.oldPageName; | ||
| + | this.newPageName; | ||
| + | this.reason; | ||
| + | this.deferred; | ||
| + | this.members; | ||
| + | this.lockID; | ||
| + | this.nextTab; | ||
| + | this.noSpammingDelay; | ||
| + | |||
| + | // Graphical properties | ||
| + | this.configContent = new OO.ui.PanelLayout( { padded: true, expanded: false } ); | ||
| + | this.statusContent = new OO.ui.PanelLayout( { padded: true, expanded: false } ); | ||
| + | this.newNameInput; | ||
| + | this.reasonInput; | ||
| + | this.optionCheckboxes; | ||
| + | this.layout; | ||
| + | this.$body; | ||
| + | this.statusIndicator; | ||
| + | this.pagesInError; | ||
| + | }; | ||
| + | |||
| + | |||
| + | |||
| + | /* Setup */ | ||
| + | |||
| + | OO.inheritClass( CatRename, OO.ui.ProcessDialog ); | ||
| + | |||
| + | |||
| + | |||
| + | /* Static Properties */ | ||
| + | |||
| + | CatRename.static.name = 'catrename'; | ||
| + | CatRename.static.title = mw.msg( 'catrename-title' ); | ||
| + | CatRename.static.actions = [ | ||
| + | { action: 'rename', label: mw.msg( 'catrename-action-rename' ), flags: [ 'primary', 'progressive' ] }, | ||
| + | { action: 'cancel', label: mw.msg( 'catrename-action-cancel' ), flags: [ 'safe', 'back' ] }, | ||
| + | { action: 'rbot', label: mw.msg( 'catrename-action-rbot' ), flags: 'other' } | ||
| + | ]; | ||
| + | |||
| + | |||
| + | |||
| + | /* ProcessDialog-related Methods */ | ||
| + | |||
| + | /** | ||
| + | * Build the interface displayed inside the ProcessDialog box. | ||
| + | */ | ||
| + | CatRename.prototype.initialize = function () { | ||
| + | CatRename.parent.prototype.initialize.apply( this, arguments ); | ||
| + | |||
| + | this.newNameInput = new OO.ui.TextInputWidget( { value: mw.config.get( 'wgTitle' ) } ); | ||
| + | this.reasonInput = new OO.ui.TextInputWidget( { | ||
| + | maxLength: 500, | ||
| + | name: 'wpSummary' | ||
| + | } ); | ||
| + | |||
| + | this.optionCheckboxes = new OO.ui.CheckboxMultiselectInputWidget( { | ||
| + | value: [ 'movetalk', 'post-dr' ], | ||
| + | options: [ | ||
| + | { data: 'movetalk', label: mw.msg( 'catrename-checkbox-movetalk' ) }, | ||
| + | ( this.userInGroup( 'sysop' ) || this.userInGroup( 'bot' ) ? | ||
| + | { data: 'leave-redirect', label: mw.msg( 'catrename-checkbox-leave-redirect' ) } : | ||
| + | { data: 'post-dr', label: mw.msg( 'catrename-checkbox-post-dr' ) } | ||
| + | ), | ||
| + | { data: 'watch', label: mw.msg( 'catrename-checkbox-watch' ) }, | ||
| + | { data: 'watch-members', label: mw.msg( 'catrename-checkbox-watch-members' ) } | ||
| + | ] | ||
| + | } ); | ||
| + | |||
| + | this.layout = new OO.ui.Widget( { | ||
| + | content: [ | ||
| + | new OO.ui.FieldLayout( | ||
| + | this.newNameInput, { | ||
| + | align: 'top', | ||
| + | label: mw.msg( 'catrename-field-title' ), | ||
| + | } | ||
| + | ), | ||
| + | new OO.ui.FieldLayout( | ||
| + | this.reasonInput, { | ||
| + | align: 'top', | ||
| + | label: mw.msg( 'catrename-field-reason' ), | ||
| + | } | ||
| + | ), | ||
| + | new OO.ui.FieldLayout( | ||
| + | this.optionCheckboxes, {} | ||
| + | ) | ||
| + | ], | ||
| + | } ); | ||
| + | |||
| + | this.configContent.$element.append( this.layout.$element ); | ||
| + | |||
| + | this.$body.append( this.configContent.$element ); | ||
| + | |||
| + | this.statusIndicator = $( '<h3>' ) | ||
| + | .css( 'text-align', 'center' ) | ||
| + | .css( 'margin-top', '1em' ) | ||
| + | .css( 'margin-bottom', '2em' ); | ||
| + | this.pagesInError = $( '<ul>' ); | ||
| + | this.statusContent.$element.append( this.statusIndicator ).append( this.pagesInError ); | ||
| + | |||
| + | this.setSize( this.size ); | ||
| + | this.updateSize(); | ||
| + | }; | ||
| + | |||
| + | /** | ||
| + | * Get a process for taking action. | ||
| + | * | ||
| + | * This method is called within the ProcessDialog when the user clicks | ||
| + | * on an action button (the one defined in CatRename.static.actions). | ||
| + | * Here is defined in which order each method of the category moving | ||
| + | * process is called. | ||
| + | * @param {string} action Name of the action button clicked. | ||
| + | * @return {OO.ui.Process} Action process. | ||
| + | */ | ||
| + | CatRename.prototype.getActionProcess = function ( action ) { | ||
| + | var process = new OO.ui.Process(), | ||
| + | options = this.optionCheckboxes.getValue(); | ||
| + | |||
| + | if ( action === 'cancel' || action === '' ) { // empty string when closing with Escape key | ||
| + | return process.next( this.unlockMultitabs, this ) | ||
| + | .next( this.closeDialog, this ); | ||
| + | } | ||
| + | else if ( action === 'rename' ) { | ||
| + | process.next( this.prepare, this ) | ||
| + | .next( this.checkCategory, this ) | ||
| + | .next( this.getMembers, this ) | ||
| + | .next( this.lockMultitabs, this ) | ||
| + | .next( this.checkLimits, this ) | ||
| + | .next( this.editMembers, this ) | ||
| + | .next( this.renameCategory, this ); | ||
| + | } | ||
| + | else if ( action === 'rbot' ) { | ||
| + | process.next( this.prepare, this ) | ||
| + | .next( this.checkCategory, this ) | ||
| + | .next( this.getMembers, this ) | ||
| + | .next( this.postRBot, this ) | ||
| + | .next( this.renameCategory, this ); | ||
| + | } | ||
| + | |||
| + | if ( options.indexOf( 'post-dr' ) > -1 ) { | ||
| + | process.next( this.postDR, this ); | ||
| + | } | ||
| + | process.next( this.unlockMultitabs, this ) | ||
| + | .next( this.success, this ) | ||
| + | .next( this.closeDialog, this ); | ||
| + | |||
| + | return process; | ||
| + | }; | ||
| + | |||
| + | /** | ||
| + | * Close the window. | ||
| + | * | ||
| + | * @return {jQuery.Promise} Promise resolved when window is closed | ||
| + | */ | ||
| + | CatRename.prototype.closeDialog = function () { | ||
| + | var dialog = this; | ||
| + | |||
| + | var lifecycle = dialog.close(); | ||
| + | |||
| + | return lifecycle.closed; | ||
| + | }; | ||
| + | |||
| + | /** | ||
| + | * Get the height of the window body. | ||
| + | * Used by the ProcessDialog to set an accurate height to the dialog. | ||
| + | * | ||
| + | * @return {number} Height in px the dialog should be. | ||
| + | */ | ||
| + | CatRename.prototype.getBodyHeight = function () { | ||
| + | return this.configContent.$element.outerHeight( true ); | ||
| + | }; | ||
| + | |||
| + | |||
| + | |||
| + | /* Process step methods */ | ||
| + | |||
| + | /** | ||
| + | * Fetch and validate user's input to make it easily accessible later. | ||
| + | * | ||
| + | * @return {undefined|OO.ui.Error} Error message for the ProcessDialog | ||
| + | * to display, if any. | ||
| + | */ | ||
| + | CatRename.prototype.prepare = function () { | ||
| + | var dialog = this; | ||
| + | |||
| + | this.oldTitle = mw.config.get( 'wgTitle' ); | ||
| + | this.newTitle = this.newNameInput.getValue().trim().replace(/^([Cc]atégorie|[Cc]ategory):/, ''); | ||
| + | this.reason = this.reasonInput.getValue().trim(); | ||
| + | |||
| + | if ( mw.config.get( 'wgCaseSensitiveNamespaces' ).indexOf( 14 ) === -1 ) { | ||
| + | this.newTitle = this.newTitle.charAt( 0 ).toUpperCase() + this.newTitle.slice( 1 ); | ||
| + | } | ||
| + | if ( this.newTitle === this.oldTitle ) { | ||
| + | return new OO.ui.Error( mw.msg( 'catrename-error-same' ) ); | ||
| + | } | ||
| + | if ( mw.Title.makeTitle( 14, this.newTitle ) === null ) { | ||
| + | return new OO.ui.Error( mw.msg( 'catrename-error-invalidtitle' ) ); | ||
| + | } | ||
| + | if ( this.reason === '' ) { | ||
| + | return new OO.ui.Error( mw.msg( 'catrename-error-noreason' ) ); | ||
| + | } | ||
| + | |||
| + | this.oldPageName = mw.config.get('wgFormattedNamespaces')[ 14 ] + ':' + this.oldTitle; | ||
| + | this.newPageName = mw.config.get('wgFormattedNamespaces')[ 14 ] + ':' + this.newTitle; | ||
| + | |||
| + | // Disable actions button when a process is runing | ||
| + | this.getActions().get( { actions: 'rename' } )[ 0 ].setDisabled( true ); | ||
| + | this.getActions().get( { actions: 'rbot' } )[ 0 ].setDisabled( true ); | ||
| + | // Except for the cancel button, which behaviour change to cancel the ongoing process | ||
| + | this.getActions().get( { actions: 'cancel' } )[ 0 ].on( 'click', function () { | ||
| + | dialog.errorHandler( mw.msg( 'catrename-error-canceled' ) ); | ||
| + | } ); | ||
| + | |||
| + | return; | ||
| + | }; | ||
| + | |||
| + | /** | ||
| + | * Check if it is technically possible to move the category. | ||
| + | * | ||
| + | * Two main checks are performed: | ||
| + | * * Has the user the right to move the category according to the | ||
| + | * protection level? | ||
| + | * * Is the target title free? | ||
| + | * @return {JQuery.Deferred} Promise telling to continue the process if | ||
| + | * successful or stopping the process if rejected. | ||
| + | */ | ||
| + | CatRename.prototype.checkCategory = function () { | ||
| + | var dialog = this; | ||
| + | this.deferred = $.Deferred(); | ||
| + | |||
| + | this.showStatus( mw.msg( 'catrename-status-checkcategory' ) ); | ||
| + | |||
| + | var restrictionMove = mw.config.get( 'wgRestrictionMove' ); | ||
| + | for ( var i = 0; i < restrictionMove.length; i++ ) { | ||
| + | if ( ! this.userInGroup( restrictionMove[ i ] ) ) { | ||
| + | this.errorHandler( mw.msg( 'catrename-error-protected' ) ); | ||
| + | return this.deferred; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | this.api.get( { | ||
| + | 'action': 'query', | ||
| + | 'format': 'json', | ||
| + | 'formatversion': 2, | ||
| + | 'prop': 'categoryinfo', | ||
| + | 'titles': this.newPageName | ||
| + | } ).then( function ( data ) { | ||
| + | if ( data.query.pages[ 0 ].missing !== true ) { | ||
| + | //TODO: Allow user to move pages without renaming the cat | ||
| + | dialog.errorHandler( mw.msg( 'catrename-error-categoryexist' ) ); | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | dialog.deferred.resolve(); | ||
| + | } ).fail( function ( error ) { | ||
| + | dialog.errorHandler( error ); | ||
| + | } ); | ||
| + | |||
| + | return this.deferred; | ||
| + | }; | ||
| + | |||
| + | /** | ||
| + | * Get all pages, files and sub-categories in the source category. | ||
| + | * | ||
| + | * This method populates the attribute 'members'. | ||
| + | * @return {JQuery.Deferred} Promise telling to continue the process if | ||
| + | * successful or stopping the process if rejected. | ||
| + | */ | ||
| + | CatRename.prototype.getMembers = function () { | ||
| + | var dialog = this; | ||
| + | this.deferred = $.Deferred(); | ||
| + | this.members = []; | ||
| + | |||
| + | this.showStatus( mw.msg( 'catrename-status-getmembers' ) ); | ||
| + | |||
| + | function doGetMembers( paramsContinue ) { | ||
| + | var params = { | ||
| + | 'action': 'query', | ||
| + | 'format': 'json', | ||
| + | 'list': 'categorymembers', | ||
| + | 'formatversion': '2', | ||
| + | 'cmtitle': mw.config.get( 'wgPageName' ), | ||
| + | 'cmprop': 'title', | ||
| + | 'cmlimit': 'max', | ||
| + | }; | ||
| + | if ( paramsContinue ) { | ||
| + | $.extend( params, paramsContinue ); | ||
| + | } | ||
| + | |||
| + | dialog.api.get( params ).then( function ( data ) { | ||
| + | |||
| + | var categoryMembers = data.query.categorymembers; | ||
| + | for ( var i = 0; i < categoryMembers.length; i++ ) { | ||
| + | dialog.members.push( categoryMembers[ i ].title ); | ||
| + | } | ||
| + | |||
| + | if ( data[ 'continue' ] ) { | ||
| + | doGetMembers( data[ 'continue' ] ); | ||
| + | } | ||
| + | else { | ||
| + | dialog.deferred.resolve(); | ||
| + | } | ||
| + | } ).fail( function ( error ) { | ||
| + | dialog.errorHandler( error ); | ||
| + | } ); | ||
| + | |||
| + | } | ||
| + | doGetMembers(); | ||
| + | |||
| + | return this.deferred; | ||
| + | }; | ||
| + | |||
| + | /** | ||
| + | * Lock the process while other instances of CatRename are running. | ||
| + | * | ||
| + | * This method acts a bit like the POSIX sem_wait. | ||
| + | * @return {JQuery.Deferred} Promise telling to continue the process | ||
| + | * when it is its turn to execute. | ||
| + | */ | ||
| + | CatRename.prototype.lockMultitabs = function () { | ||
| + | var dialog = this; | ||
| + | this.deferred = $.Deferred(); | ||
| + | |||
| + | if ( this.userInGroup( 'bot' ) ) { | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | this.lockID = 'catrename-' + this.randomString( 16 ); | ||
| + | this.nextTab = null; | ||
| + | |||
| + | this.showStatus( mw.msg( 'catrename-status-waitinglock' ) ); | ||
| + | |||
| + | //TODO: check lock timestamp | ||
| + | if ( mw.storage.get( 'catrename-lock' ) === null ) { | ||
| + | mw.storage.set( 'catrename-lock', this.lockID ); | ||
| + | this.deferred.resolve(); | ||
| + | } | ||
| + | else { | ||
| + | $( window ).on( 'storage.catrename.catrename-waiting', function ( event ) { | ||
| + | if ( event.originalEvent.key === 'catrename-lock' && event.originalEvent.newValue === dialog.lockID ) { | ||
| + | $( window ).off( 'storage.catrename-waiting' ); | ||
| + | dialog.deferred.resolve(); | ||
| + | } | ||
| + | } ); | ||
| + | mw.storage.set( 'catrename-addtab', this.lockID ); | ||
| + | } | ||
| + | |||
| + | |||
| + | $( window ).on( 'storage.catrename', function ( event ) { | ||
| + | // if this tab has no successor and a new one appears, add it as our successor | ||
| + | if ( dialog.nextTab === null && event.originalEvent.key === 'catrename-addtab' && event.originalEvent.newValue !== null ) { | ||
| + | dialog.nextTab = event.originalEvent.newValue; | ||
| + | mw.storage.set( dialog.lockID, dialog.nextTab ); | ||
| + | } | ||
| + | // if our successor decides to leave, remove it and take its successor | ||
| + | else if ( dialog.nextTab !== null && event.originalEvent.key === 'catrename-removetab' && event.originalEvent.newValue === dialog.nextTab ) { | ||
| + | dialog.nextTab = mw.storage.get( dialog.nextTab ); | ||
| + | if ( dialog.nextTab !== null ) { | ||
| + | mw.storage.set( dialog.lockID, dialog.nextTab ); | ||
| + | } | ||
| + | else { | ||
| + | mw.storage.remove( dialog.lockID ); | ||
| + | } | ||
| + | } | ||
| + | } ); | ||
| + | |||
| + | window.addEventListener( 'unload', function (e) { | ||
| + | dialog.unlockMultitabs(); | ||
| + | } ); | ||
| + | |||
| + | return this.deferred; | ||
| + | }; | ||
| + | |||
| + | /** | ||
| + | * Check if the daily limit of edits using this script would be reached | ||
| + | * if the move is performed. | ||
| + | * | ||
| + | * In fact, we are not looking realy on a daily basis, but a 24h rolling | ||
| + | * period. | ||
| + | * @return {JQuery.Deferred} Promise telling to continue the process | ||
| + | * when it is its turn to execute. | ||
| + | */ | ||
| + | CatRename.prototype.checkLimits = function () { | ||
| + | var dialog = this; | ||
| + | this.deferred = $.Deferred(); | ||
| + | var yesterday = new Date(); | ||
| + | yesterday.setDate( yesterday.getDate() - 1 ); | ||
| + | |||
| + | if ( this.userInGroup( 'bot' ) ) { | ||
| + | this.noSpammingDelay = 0; | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | this.noSpammingDelay = 5000; | ||
| + | if ( this.members.length > 50 ) { | ||
| + | this.noSpammingDelay = 20000; | ||
| + | } | ||
| + | else if ( this.members.length > 10 ) { | ||
| + | this.noSpammingDelay = 10000; | ||
| + | } | ||
| + | |||
| + | this.showStatus( mw.msg( 'catrename-status-checklimits' ) ); | ||
| + | |||
| + | this.api.get( { | ||
| + | 'action': 'query', | ||
| + | 'format': 'json', | ||
| + | 'list': 'usercontribs', | ||
| + | 'formatversion': '2', | ||
| + | 'uclimit': 'max', // only query DAILY_LIMIT results ? | ||
| + | 'ucend': yesterday.toISOString(), | ||
| + | 'ucuser': mw.config.get( 'wgUserName' ), | ||
| + | 'ucprop': 'timestamp', | ||
| + | 'uctag': TAG | ||
| + | } ).then( function ( data ) { | ||
| + | |||
| + | if ( data.query.usercontribs.length + dialog.members.length >= DAILY_LIMIT ) { | ||
| + | dialog.errorHandler( mw.msg( 'catrename-error-limitreached', DAILY_LIMIT ), false ); | ||
| + | } | ||
| + | else { | ||
| + | dialog.deferred.resolve(); | ||
| + | } | ||
| + | } ).fail( function ( error ) { | ||
| + | dialog.errorHandler( error ); | ||
| + | } ); | ||
| + | |||
| + | return this.deferred; | ||
| + | }; | ||
| + | |||
| + | /** | ||
| + | * Try to move all the pages inside the 'members' attribute from the old | ||
| + | * to the new category name by fetching and editing their wikicode. | ||
| + | * | ||
| + | * @return {JQuery.Deferred} Promise telling to continue the process | ||
| + | * when it is its turn to execute. | ||
| + | */ | ||
| + | CatRename.prototype.editMembers = function () { | ||
| + | var dialog = this, | ||
| + | totalPages = this.members.length, | ||
| + | oldCatRegex = this.buildRegex( this.oldTitle ), | ||
| + | newCatRegex = this.buildRegex( this.newTitle ), | ||
| + | summary = mw.msg( 'catrename-summary', this.oldTitle, this.newTitle, this.reason ), | ||
| + | commonPayload = { | ||
| + | summary: summary, | ||
| + | minor: true, | ||
| + | tags: TAG | ||
| + | }; | ||
| + | this.deferred = $.Deferred(); | ||
| + | |||
| + | if ( this.userInGroup( 'bot' ) ) { | ||
| + | commonPayload[ 'bot' ] = 1; | ||
| + | } | ||
| + | if ( this.optionCheckboxes.getValue().indexOf( 'watch-members' ) > -1 ) { | ||
| + | commonPayload[ 'watchlist' ] = 'watch'; | ||
| + | } | ||
| + | |||
| + | function doEdit() { | ||
| + | var member = dialog.members.pop(); | ||
| + | if ( dialog.deferred.state() !== 'pending' ) { | ||
| + | return; | ||
| + | } | ||
| + | if ( member === undefined ) { | ||
| + | dialog.deferred.resolve(); | ||
| + | return; | ||
| + | } | ||
| + | |||
| + | //TODO: a progress-bar ? | ||
| + | dialog.showStatus( mw.msg( 'catrename-status-editmembers', totalPages - dialog.members.length, totalPages ) ); | ||
| + | |||
| + | dialog.api.edit( member, function ( revision ) { | ||
| + | var content = revision.content, | ||
| + | newCatInPageList = content.match( newCatRegex ); | ||
| + | |||
| + | if ( newCatInPageList !== null ) { | ||
| + | dialog.logFailedPages( member, mw.msg( 'catrename-error-categorypresent' ) ); | ||
| + | } | ||
| + | else { | ||
| + | content = content.replace( | ||
| + | oldCatRegex, | ||
| + | '$1[[' + dialog.newPageName + '$6]]' | ||
| + | ); | ||
| + | } | ||
| + | |||
| + | return $.extend( { text: content }, commonPayload ); | ||
| + | } ) | ||
| + | .then( function ( result ) { | ||
| + | if ( result.nochange === true ) { | ||
| + | dialog.logFailedPages( member, mw.msg( 'catrename-error-notfound' ) ); | ||
| + | } | ||
| + | |||
| + | setTimeout( doEdit, dialog.noSpammingDelay ); | ||
| + | } ) | ||
| + | .fail( function ( code, data ) { | ||
| + | if ( code === 'protectedpage' ) { | ||
| + | dialog.logFailedPages( member, mw.msg( 'catrename-error-pageprotected' ) ); | ||
| + | doEdit(); | ||
| + | } | ||
| + | else { | ||
| + | dialog.errorHandler( code ); | ||
| + | } | ||
| + | } ); | ||
| + | } | ||
| + | doEdit(); | ||
| + | |||
| + | return this.deferred; | ||
| + | }; | ||
| + | |||
| + | /** | ||
| + | * Move the category itself. | ||
| + | * | ||
| + | * @return {JQuery.Deferred} Promise telling to continue the process | ||
| + | * when it is its turn to execute. | ||
| + | */ | ||
| + | CatRename.prototype.renameCategory = function () { | ||
| + | var dialog = this; | ||
| + | this.deferred = $.Deferred(); | ||
| + | |||
| + | this.showStatus( mw.msg( 'catrename-status-renamecategory' ) ); | ||
| + | |||
| + | var payload = { | ||
| + | 'action': 'move', | ||
| + | 'format': 'json', | ||
| + | 'from': mw.config.get( 'wgPageName' ), | ||
| + | 'to': this.newPageName, | ||
| + | 'reason': this.reason, | ||
| + | 'tags': TAG, | ||
| + | 'formatversion': '2' | ||
| + | }; | ||
| + | |||
| + | var options = this.optionCheckboxes.getValue(); | ||
| + | if ( options.indexOf( 'movetalk' ) > -1 ) { | ||
| + | payload[ 'movetalk' ] = 1; | ||
| + | } | ||
| + | if ( options.indexOf( 'watch' ) > -1 ) { | ||
| + | payload[ 'watchlist' ] = 'watch'; | ||
| + | } | ||
| + | if ( this.userInGroup( 'sysop' ) || this.userInGroup( 'bot' ) ) { | ||
| + | if ( options.indexOf( 'leave-redirect' ) === -1 ) { | ||
| + | payload[ 'noredirect' ] = 1; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | this.api.postWithToken( 'csrf', payload ).then( function ( data ) { | ||
| + | dialog.deferred.resolve(); | ||
| + | } ).fail( function ( error ) { | ||
| + | if ( error === 'articleexists' ) { | ||
| + | dialog.errorHandler( mw.msg( 'catrename-error-articleexists', dialog.newPageName ) ); | ||
| + | } | ||
| + | else { | ||
| + | dialog.errorHandler( error ); | ||
| + | } | ||
| + | } ); | ||
| + | |||
| + | return this.deferred; | ||
| + | }; | ||
| + | |||
| + | /** | ||
| + | * Post a deletion request. | ||
| + | * | ||
| + | * @return {JQuery.Deferred} Promise telling to continue the process | ||
| + | * when it is its turn to execute. | ||
| + | */ | ||
| + | CatRename.prototype.postDR = function () { | ||
| + | var dialog = this; | ||
| + | this.deferred = $.Deferred(); | ||
| + | |||
| + | this.showStatus( mw.msg( 'catrename-status-postdr' ) ); | ||
| + | |||
| + | var content = DR_TEMPLATE | ||
| + | .replace( /\$1/g, this.oldTitle ) | ||
| + | .replace( /\$2/g, this.newTitle ) | ||
| + | .replace( /\$3/g, this.reason ) | ||
| + | .replace( /\$4/g, mw.config.get( 'wgUserName' ) ); | ||
| + | |||
| + | this.api.postWithToken( 'csrf', { | ||
| + | 'action': 'edit', | ||
| + | 'format': 'json', | ||
| + | 'title': this.oldPageName, | ||
| + | 'summary': mw.msg( 'catrename-dr-summary' ), | ||
| + | 'tags': TAG, | ||
| + | 'nocreate': 1, | ||
| + | 'prependtext': content, | ||
| + | 'formatversion': '2' | ||
| + | } ).then( function ( data ) { | ||
| + | dialog.deferred.resolve(); | ||
| + | } ).fail( function ( error ) { | ||
| + | dialog.errorHandler( error ); | ||
| + | } ); | ||
| + | |||
| + | return this.deferred; | ||
| + | }; | ||
| + | |||
| + | /** | ||
| + | * Post a move request for the bots. | ||
| + | * | ||
| + | * @return {JQuery.Deferred} Promise telling to continue the process | ||
| + | * when it is its turn to execute. | ||
| + | */ | ||
| + | CatRename.prototype.postRBot = function () { | ||
| + | var dialog = this; | ||
| + | this.deferred = $.Deferred(); | ||
| + | |||
| + | this.showStatus( mw.msg( 'catrename-status-postrbot' ) ); | ||
| + | |||
| + | var content = RBOT_TEMPLATE | ||
| + | .replace( /\$1/g, this.oldTitle ) | ||
| + | .replace( /\$2/g, this.newTitle ) | ||
| + | .replace( /\$3/g, this.reason ) | ||
| + | .replace( /\$4/g, mw.config.get( 'wgUserName' ) ); | ||
| + | |||
| + | this.api.postWithToken( 'csrf', { | ||
| + | 'action': 'edit', | ||
| + | 'format': 'json', | ||
| + | 'title': RBOT_PAGE, | ||
| + | 'summary': mw.msg( 'catrename-rbot-summary' ), | ||
| + | 'tags': TAG, | ||
| + | 'nocreate': 1, | ||
| + | 'appendtext': content, | ||
| + | 'formatversion': '2' | ||
| + | } ).then( function ( data ) { | ||
| + | dialog.deferred.resolve(); | ||
| + | } ).fail( function ( error ) { | ||
| + | dialog.errorHandler( error ); | ||
| + | } ); | ||
| + | |||
| + | return this.deferred; | ||
| + | }; | ||
| + | |||
| + | /** | ||
| + | * Release the lock to allow other instances of CatRename to execute. | ||
| + | * | ||
| + | * This method acts a bit like the POSIX sem_post. | ||
| + | */ | ||
| + | CatRename.prototype.unlockMultitabs = function () { | ||
| + | if ( this.lockID !== undefined ) { | ||
| + | $( window ).off( 'storage.catrename' ); | ||
| + | |||
| + | mw.storage.set( 'catrename-removetab', this.lockID ); //Inform other tabs that we're closing | ||
| + | mw.storage.remove( this.lockID ); //Clean up our mess from the localStorage | ||
| + | |||
| + | // wake up the next tab, or reset if there is none | ||
| + | if ( mw.storage.get( 'catrename-lock' ) === this.lockID ) { | ||
| + | if ( this.nextTab !== null ) { | ||
| + | mw.storage.set( 'catrename-lock', this.nextTab ); | ||
| + | } | ||
| + | else { | ||
| + | mw.storage.remove( 'catrename-lock' ); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | delete this.lockID; | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | /** | ||
| + | * Method called when all has gone well (yeah !). | ||
| + | */ | ||
| + | CatRename.prototype.success = function () { | ||
| + | var dialog = this; | ||
| + | |||
| + | setTimeout( function () { | ||
| + | window.location = mw.util.getUrl( dialog.newPageName ); | ||
| + | }, 1000 ); | ||
| + | }; | ||
| + | |||
| + | |||
| + | |||
| + | /* Helper Methods */ | ||
| + | |||
| + | /** | ||
| + | * Get information about the current user's groups. | ||
| + | * | ||
| + | * @param {string} groupName Name of the group to check. | ||
| + | * @return {boolean} Whether the current user is in the given group. | ||
| + | */ | ||
| + | CatRename.prototype.userInGroup = function ( groupName ) { | ||
| + | return ( mw.config.get( 'wgUserGroups' ).indexOf( groupName ) > -1 ); | ||
| + | }; | ||
| + | |||
| + | /** | ||
| + | * Display a status message inside the main content of the dialog. | ||
| + | * | ||
| + | * @return {string} Status message to display. | ||
| + | */ | ||
| + | CatRename.prototype.showStatus = function ( status ) { | ||
| + | this.statusIndicator.text( status ); | ||
| + | this.$body.children().detach(); | ||
| + | this.$body.append( this.statusContent.$element ); | ||
| + | }; | ||
| + | |||
| + | /** | ||
| + | * Raise an error using OO.ui.Error, and reset all what should be. | ||
| + | * | ||
| + | * @param {string} error Error message to display to the user. | ||
| + | * @param {boolean} recoverable Is the error recoverable (default to true). | ||
| + | * @param {boolean} warning Should we raise a warning instead an error (default to false). | ||
| + | */ | ||
| + | CatRename.prototype.errorHandler = function ( error, recoverable, warning ) { | ||
| + | var errorMessage = new OO.ui.Error( error, { recoverable: recoverable || true, warning: warning || false } ); | ||
| + | |||
| + | this.unlockMultitabs(); | ||
| + | this.$body.children().detach(); | ||
| + | this.$body.append( this.configContent.$element ); | ||
| + | |||
| + | this.getActions().get( { actions: 'rename' } )[ 0 ].setDisabled( false ); | ||
| + | this.getActions().get( { actions: 'rbot' } )[ 0 ].setDisabled( false ); | ||
| + | |||
| + | this.deferred.reject( errorMessage ); | ||
| + | }; | ||
| + | |||
| + | /** | ||
| + | * Add a page to the error log. | ||
| + | * | ||
| + | * @param {string} pageName Name (including namespace) of the page. | ||
| + | * @param {string} reason Explaination of the error. | ||
| + | */ | ||
| + | CatRename.prototype.logFailedPages = function ( pageName, reason ) { | ||
| + | var li = $( '<li>' ).text( ' - ' + reason ), | ||
| + | a = $( '<a>' ).attr( 'href', mw.util.getUrl( pageName ) ).text( pageName ); | ||
| + | this.pagesInError.append( li.prepend( a ) ); | ||
| + | }; | ||
| + | |||
| + | /** | ||
| + | * Build a regex to extract the link to a given category from wikicode. | ||
| + | * | ||
| + | * @param {string} category Name (without namespace) of the category. | ||
| + | * @return {RegExp} Regex object to extract the given category. | ||
| + | */ | ||
| + | CatRename.prototype.buildRegex = function ( category ) { | ||
| + | var formattedNamespace = mw.config.get( 'wgFormattedNamespaces' )[ 14 ], | ||
| + | isFirstLetterCaseSensitive = ( mw.config.get( 'wgCaseSensitiveNamespaces' ).indexOf( 14 ) > -1 ), | ||
| + | namespace = '(?:[' + formattedNamespace.charAt( 0 ) + formattedNamespace.charAt( 0 ).toLowerCase() + ']' + formattedNamespace.slice( 1 ) + '|[Cc]ategory)'; | ||
| + | |||
| + | category = category.replace( /([\\\^\$\*\+\?\.\|\{\}\[\]\(\)])/g, '\\$1' ); | ||
| + | |||
| + | if ( ! isFirstLetterCaseSensitive ) { | ||
| + | var firstLetter = category.charAt(0); | ||
| + | if ( firstLetter.toUpperCase() !== firstLetter.toLowerCase() ) { | ||
| + | category = '[' + firstLetter.toUpperCase() + firstLetter.toLowerCase() + ']' | ||
| + | + category.slice(1); | ||
| + | } | ||
| + | } | ||
| − | + | return new RegExp('(\\s*)\\[\\[( |_)*' + namespace + '( |_)*:( |_)*' + category + '( |_)*(\\|[^\\]]*)?\\]\\]', 'g'); | |
| − | + | }; | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | var | + | /** |
| − | var | + | * Generate a random string. |
| − | + | * | |
| + | * @param {number} length Length of the string to generate. | ||
| + | * @return {string} The generated string. | ||
| + | */ | ||
| + | CatRename.prototype.randomString = function ( length ) { | ||
| + | var result = ''; | ||
| + | var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; | ||
| + | for ( var i = 0; i < length; ++i ) { | ||
| + | result += chars.charAt( Math.floor( Math.random() * chars.length ) ); | ||
| + | } | ||
| + | return result; | ||
| + | }; | ||
| − | + | instanceWindowManager = new OO.ui.WindowManager(); | |
| − | + | $( 'body' ).append( instanceWindowManager.$element ); | |
| − | |||
| − | |||
| − | |||
| + | instanceCatRename = new CatRename(); | ||
| + | instanceWindowManager.addWindows( [ instanceCatRename ] ); | ||
| + | } | ||
| − | + | } ); | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | } | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
} | } | ||
| − | |||
| + | /* </nowiki> */ | ||
| − | + | var navHeight = $('#esp-navbar ul').height(); | |
| − | + | var $nav = $('#esp-navbar'); | |
| − | + | $('#navbar-toggler').click(function(e) { | |
| − | + | if (!$nav.hasClass('open')) { | |
| − | + | $nav.css('height', navHeight + 'px'); | |
| − | + | } else { | |
| − | + | $nav.css('height', ''); | |
| − | + | } | |
| − | + | $nav.toggleClass('open'); | |
| − | + | }); | |
| − | + | ||
| − | + | $('.timeline-wrapper').on('mousedown touchstart', function (me) { | |
| − | + | if ($(me.target).hasClass('timeline-desc')) return; | |
| − | + | var move = $(this).find('ul'); | |
| − | + | var lastOffset = move.data('lastTransform'); | |
| − | + | var lastOffsetX = lastOffset ? lastOffset.dx : 0; | |
| − | + | var pageX = me.originalEvent.touches ? me.originalEvent.touches[0].pageX : me.pageX; | |
| − | + | var startX = pageX - lastOffsetX; | |
| − | + | $(document).on('mousemove touchmove', function (e) { | |
| − | + | var newX = e.originalEvent.touches ? e.originalEvent.touches[0].pageX : e.pageX; | |
| − | + | var max = $(move).attr('data-maxtranslate'); | |
| − | + | if (max > 0) max = 0; | |
| − | + | var newDx = Math.max(Math.min(0, newX - startX), max); | |
| − | + | move.css('transform', 'translate(' + newDx + 'px)'); | |
| − | + | move.data('lastTransform', { | |
| − | + | dx: newDx | |
| − | + | }); | |
| − | + | }); | |
| − | + | }); | |
| − | + | $(document).on('mouseup touchend', function () { | |
| − | + | $(this).off('mousemove touchmove'); | |
| − | + | }); | |
| − | + | $('.timeline-wrapper').each(function () { | |
| − | + | var maxTranslate = ($(this).find('li').length * 200 - $(this).width()) * - 1; | |
| − | + | $(this).find('ul').attr('data-maxTranslate', maxTranslate); | |
| − | + | var desc = $('<div>', { | |
| − | + | 'class': 'timeline-desc' | |
| − | + | }); | |
| − | + | $(this).append(desc); | |
| − | + | $(this).find('.event').on('click touch', function () { | |
| − | + | $('.event.active').removeClass('active'); | |
| − | + | $(this).addClass('active'); | |
| − | + | desc.html($(this).find('.description').html()); | |
| − | + | }); | |
| − | + | $(this).find('li:first-of-type .event').click(); | |
| − | + | }); | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | } | ||
Version actuelle datée du 27 février 2025 à 12:53
/*
Copyright (C) Federico Zivolo 2019
Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT).
*/
(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&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=e.ownerDocument.defaultView,n=o.getComputedStyle(e,null);return t?n[t]:n}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll|overlay)/.test(r+s+p)?e:n(o(e))}function i(e){return e&&e.referenceNode?e.referenceNode:e}function r(e){return 11===e?re:10===e?pe:re||pe}function p(e){if(!e)return document.documentElement;for(var o=r(10)?document.body:null,n=e.offsetParent||null;n===o&&e.nextElementSibling;)n=(e=e.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TH','TD','TABLE'].indexOf(n.nodeName)&&'static'===t(n,'position')?p(n):n:e?e.ownerDocument.documentElement:document.documentElement}function s(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||p(e.firstElementChild)===e)}function d(e){return null===e.parentNode?e:d(e.parentNode)}function a(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,n=o?e:t,i=o?t:e,r=document.createRange();r.setStart(n,0),r.setEnd(i,0);var l=r.commonAncestorContainer;if(e!==l&&t!==l||n.contains(i))return s(l)?l:p(l);var f=d(e);return f.host?a(f.host,t):a(e,d(t).host)}function l(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:'top',o='top'===t?'scrollTop':'scrollLeft',n=e.nodeName;if('BODY'===n||'HTML'===n){var i=e.ownerDocument.documentElement,r=e.ownerDocument.scrollingElement||i;return r[o]}return e[o]}function f(e,t){var o=2<arguments.length&&void 0!==arguments[2]&&arguments[2],n=l(t,'top'),i=l(t,'left'),r=o?-1:1;return e.top+=n*r,e.bottom+=n*r,e.left+=i*r,e.right+=i*r,e}function m(e,t){var o='x'===t?'Left':'Top',n='Left'==o?'Right':'Bottom';return parseFloat(e['border'+o+'Width'],10)+parseFloat(e['border'+n+'Width'],10)}function h(e,t,o,n){return ee(t['offset'+e],t['scroll'+e],o['client'+e],o['offset'+e],o['scroll'+e],r(10)?parseInt(o['offset'+e])+parseInt(n['margin'+('Height'===e?'Top':'Left')])+parseInt(n['margin'+('Height'===e?'Bottom':'Right')]):0)}function c(e){var t=e.body,o=e.documentElement,n=r(10)&&getComputedStyle(o);return{height:h('Height',t,o,n),width:h('Width',t,o,n)}}function g(e){return le({},e,{right:e.left+e.width,bottom:e.top+e.height})}function u(e){var o={};try{if(r(10)){o=e.getBoundingClientRect();var n=l(e,'top'),i=l(e,'left');o.top+=n,o.left+=i,o.bottom+=n,o.right+=i}else o=e.getBoundingClientRect()}catch(t){}var p={left:o.left,top:o.top,width:o.right-o.left,height:o.bottom-o.top},s='HTML'===e.nodeName?c(e.ownerDocument):{},d=s.width||e.clientWidth||p.width,a=s.height||e.clientHeight||p.height,f=e.offsetWidth-d,h=e.offsetHeight-a;if(f||h){var u=t(e);f-=m(u,'x'),h-=m(u,'y'),p.width-=f,p.height-=h}return g(p)}function b(e,o){var i=2<arguments.length&&void 0!==arguments[2]&&arguments[2],p=r(10),s='HTML'===o.nodeName,d=u(e),a=u(o),l=n(e),m=t(o),h=parseFloat(m.borderTopWidth,10),c=parseFloat(m.borderLeftWidth,10);i&&s&&(a.top=ee(a.top,0),a.left=ee(a.left,0));var b=g({top:d.top-a.top-h,left:d.left-a.left-c,width:d.width,height:d.height});if(b.marginTop=0,b.marginLeft=0,!p&&s){var w=parseFloat(m.marginTop,10),y=parseFloat(m.marginLeft,10);b.top-=h-w,b.bottom-=h-w,b.left-=c-y,b.right-=c-y,b.marginTop=w,b.marginLeft=y}return(p&&!i?o.contains(l):o===l&&'BODY'!==l.nodeName)&&(b=f(b,o)),b}function w(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=e.ownerDocument.documentElement,n=b(e,o),i=ee(o.clientWidth,window.innerWidth||0),r=ee(o.clientHeight,window.innerHeight||0),p=t?0:l(o),s=t?0:l(o,'left'),d={top:p-n.top+n.marginTop,left:s-n.left+n.marginLeft,width:i,height:r};return g(d)}function y(e){var n=e.nodeName;if('BODY'===n||'HTML'===n)return!1;if('fixed'===t(e,'position'))return!0;var i=o(e);return!!i&&y(i)}function E(e){if(!e||!e.parentElement||r())return document.documentElement;for(var o=e.parentElement;o&&'none'===t(o,'transform');)o=o.parentElement;return o||document.documentElement}function v(e,t,r,p){var s=4<arguments.length&&void 0!==arguments[4]&&arguments[4],d={top:0,left:0},l=s?E(e):a(e,i(t));if('viewport'===p)d=w(l,s);else{var f;'scrollParent'===p?(f=n(o(t)),'BODY'===f.nodeName&&(f=e.ownerDocument.documentElement)):'window'===p?f=e.ownerDocument.documentElement:f=p;var m=b(f,l,s);if('HTML'===f.nodeName&&!y(l)){var h=c(e.ownerDocument),g=h.height,u=h.width;d.top+=m.top-m.marginTop,d.bottom=g+m.top,d.left+=m.left-m.marginLeft,d.right=u+m.left}else d=m}r=r||0;var v='number'==typeof r;return d.left+=v?r:r.left||0,d.top+=v?r:r.top||0,d.right-=v?r:r.right||0,d.bottom-=v?r:r.bottom||0,d}function x(e){var t=e.width,o=e.height;return t*o}function O(e,t,o,n,i){var r=5<arguments.length&&void 0!==arguments[5]?arguments[5]:0;if(-1===e.indexOf('auto'))return e;var p=v(o,n,r,i),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 le({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,n=e.height;return t>=o.clientWidth&&n>=o.clientHeight}),l=0<a.length?a[0].key:d[0].key,f=e.split('-')[1];return l+(f?'-'+f:'')}function L(e,t,o){var n=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null,r=n?E(t):a(t,i(o));return b(o,r,n)}function S(e){var t=e.ownerDocument.defaultView,o=t.getComputedStyle(e),n=parseFloat(o.marginTop||0)+parseFloat(o.marginBottom||0),i=parseFloat(o.marginLeft||0)+parseFloat(o.marginRight||0),r={width:e.offsetWidth+i,height:e.offsetHeight+n};return r}function T(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 C(e,t,o){o=o.split('-')[0];var n=S(e),i={width:n.width,height:n.height},r=-1!==['right','left'].indexOf(o),p=r?'top':'left',s=r?'left':'top',d=r?'height':'width',a=r?'width':'height';return i[p]=t[p]+t[d]/2-n[d]/2,i[s]=o===s?t[s]-n[a]:t[T(s)],i}function D(e,t){return Array.prototype.find?e.find(t):e.filter(t)[0]}function N(e,t,o){if(Array.prototype.findIndex)return e.findIndex(function(e){return e[t]===o});var n=D(e,function(e){return e[t]===o});return e.indexOf(n)}function P(t,o,n){var i=void 0===n?t:t.slice(0,N(t,'name',n));return i.forEach(function(t){t['function']&&console.warn('`modifier.function` is deprecated, use `modifier.fn`!');var n=t['function']||t.fn;t.enabled&&e(n)&&(o.offsets.popper=g(o.offsets.popper),o.offsets.reference=g(o.offsets.reference),o=n(o,t))}),o}function k(){if(!this.state.isDestroyed){var e={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};e.offsets.reference=L(this.state,this.popper,this.reference,this.options.positionFixed),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.positionFixed=this.options.positionFixed,e.offsets.popper=C(this.popper,e.offsets.reference,e.placement),e.offsets.popper.position=this.options.positionFixed?'fixed':'absolute',e=P(this.modifiers,e),this.state.isCreated?this.options.onUpdate(e):(this.state.isCreated=!0,this.options.onCreate(e))}}function W(e,t){return e.some(function(e){var o=e.name,n=e.enabled;return n&&o===t})}function B(e){for(var t=[!1,'ms','Webkit','Moz','O'],o=e.charAt(0).toUpperCase()+e.slice(1),n=0;n<t.length;n++){var i=t[n],r=i?''+i+o:e;if('undefined'!=typeof document.body.style[r])return r}return null}function H(){return this.state.isDestroyed=!0,W(this.modifiers,'applyStyle')&&(this.popper.removeAttribute('x-placement'),this.popper.style.position='',this.popper.style.top='',this.popper.style.left='',this.popper.style.right='',this.popper.style.bottom='',this.popper.style.willChange='',this.popper.style[B('transform')]=''),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function A(e){var t=e.ownerDocument;return t?t.defaultView:window}function M(e,t,o,i){var r='BODY'===e.nodeName,p=r?e.ownerDocument.defaultView:e;p.addEventListener(t,o,{passive:!0}),r||M(n(p.parentNode),t,o,i),i.push(p)}function F(e,t,o,i){o.updateBound=i,A(e).addEventListener('resize',o.updateBound,{passive:!0});var r=n(e);return M(r,'scroll',o.updateBound,o.scrollParents),o.scrollElement=r,o.eventsEnabled=!0,o}function I(){this.state.eventsEnabled||(this.state=F(this.reference,this.options,this.state,this.scheduleUpdate))}function R(e,t){return A(e).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&&(cancelAnimationFrame(this.scheduleUpdate),this.state=R(this.reference,this.state))}function Y(e){return''!==e&&!isNaN(parseFloat(e))&&isFinite(e)}function V(e,t){Object.keys(t).forEach(function(o){var n='';-1!==['width','height','top','right','bottom','left'].indexOf(o)&&Y(t[o])&&(n='px'),e.style[o]=t[o]+n})}function j(e,t){Object.keys(t).forEach(function(o){var n=t[o];!1===n?e.removeAttribute(o):e.setAttribute(o,t[o])})}function q(e,t){var o=e.offsets,n=o.popper,i=o.reference,r=$,p=function(e){return e},s=r(i.width),d=r(n.width),a=-1!==['left','right'].indexOf(e.placement),l=-1!==e.placement.indexOf('-'),f=t?a||l||s%2==d%2?r:Z:p,m=t?r:p;return{left:f(1==s%2&&1==d%2&&!l&&t?n.left-1:n.left),top:m(n.top),bottom:m(n.bottom),right:f(n.right)}}function K(e,t,o){var n=D(e,function(e){var o=e.name;return o===t}),i=!!n&&e.some(function(e){return e.name===o&&e.enabled&&e.order<n.order});if(!i){var r='`'+t+'`';console.warn('`'+o+'`'+' modifier is required by '+r+' modifier in order to work, be sure to include it before '+r+'!')}return i}function z(e){return'end'===e?'start':'start'===e?'end':e}function G(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=he.indexOf(e),n=he.slice(o+1).concat(he.slice(0,o));return t?n.reverse():n}function _(e,t,o,n){var i=e.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+i[1],p=i[2];if(!r)return e;if(0===p.indexOf('%')){var s;switch(p){case'%p':s=o;break;case'%':case'%r':default:s=n;}var d=g(s);return d[t]/100*r}if('vh'===p||'vw'===p){var a;return a='vh'===p?ee(document.documentElement.clientHeight,window.innerHeight||0):ee(document.documentElement.clientWidth,window.innerWidth||0),a/100*r}return r}function X(e,t,o,n){var i=[0,0],r=-1!==['right','left'].indexOf(n),p=e.split(/(\+|\-)/).map(function(e){return e.trim()}),s=p.indexOf(D(p,function(e){return-1!==e.search(/,|\s/)}));p[s]&&-1===p[s].indexOf(',')&&console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');var d=/\s*,\s*|\s+/,a=-1===s?[p]:[p.slice(0,s).concat([p[s].split(d)[0]]),[p[s].split(d)[1]].concat(p.slice(s+1))];return a=a.map(function(e,n){var i=(1===n?!r:r)?'height':'width',p=!1;return e.reduce(function(e,t){return''===e[e.length-1]&&-1!==['+','-'].indexOf(t)?(e[e.length-1]=t,p=!0,e):p?(e[e.length-1]+=t,p=!1,e):e.concat(t)},[]).map(function(e){return _(e,i,t,o)})}),a.forEach(function(e,t){e.forEach(function(o,n){Y(o)&&(i[t]+=o*('-'===e[n-1]?-1:1))})}),i}function J(e,t){var o,n=t.offset,i=e.placement,r=e.offsets,p=r.popper,s=r.reference,d=i.split('-')[0];return o=Y(+n)?[+n,0]:X(n,p,s,d),'left'===d?(p.top+=o[0],p.left-=o[1]):'right'===d?(p.top+=o[0],p.left+=o[1]):'top'===d?(p.left+=o[0],p.top-=o[1]):'bottom'===d&&(p.left+=o[0],p.top+=o[1]),e.popper=p,e}var Q=Math.min,Z=Math.floor,$=Math.round,ee=Math.max,te='undefined'!=typeof window&&'undefined'!=typeof document&&'undefined'!=typeof navigator,oe=function(){for(var e=['Edge','Trident','Firefox'],t=0;t<e.length;t+=1)if(te&&0<=navigator.userAgent.indexOf(e[t]))return 1;return 0}(),ne=te&&window.Promise,ie=ne?function(e){var t=!1;return function(){t||(t=!0,window.Promise.resolve().then(function(){t=!1,e()}))}}:function(e){var t=!1;return function(){t||(t=!0,setTimeout(function(){t=!1,e()},oe))}},re=te&&!!(window.MSInputMethodContext&&document.documentMode),pe=te&&/MSIE 10/.test(navigator.userAgent),se=function(e,t){if(!(e instanceof t))throw new TypeError('Cannot call a class as a function')},de=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,n){return o&&e(t.prototype,o),n&&e(t,n),t}}(),ae=function(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e},le=Object.assign||function(e){for(var t,o=1;o<arguments.length;o++)for(var n in t=arguments[o],t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e},fe=te&&/Firefox/i.test(navigator.userAgent),me=['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'],he=me.slice(3),ce={FLIP:'flip',CLOCKWISE:'clockwise',COUNTERCLOCKWISE:'counterclockwise'},ge=function(){function t(o,n){var i=this,r=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};se(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=ie(this.update.bind(this)),this.options=le({},t.Defaults,r),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=o&&o.jquery?o[0]:o,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(le({},t.Defaults.modifiers,r.modifiers)).forEach(function(e){i.options.modifiers[e]=le({},t.Defaults.modifiers[e]||{},r.modifiers?r.modifiers[e]:{})}),this.modifiers=Object.keys(this.options.modifiers).map(function(e){return le({name:e},i.options.modifiers[e])}).sort(function(e,t){return e.order-t.order}),this.modifiers.forEach(function(t){t.enabled&&e(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)}),this.update();var p=this.options.eventsEnabled;p&&this.enableEventListeners(),this.state.eventsEnabled=p}return de(t,[{key:'update',value:function(){return k.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)}}]),t}();return ge.Utils=('undefined'==typeof window?global:window).PopperUtils,ge.placements=me,ge.Defaults={placement:'bottom',positionFixed:!1,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],n=t.split('-')[1];if(n){var i=e.offsets,r=i.reference,p=i.popper,s=-1!==['bottom','top'].indexOf(o),d=s?'left':'top',a=s?'width':'height',l={start:ae({},d,r[d]),end:ae({},d,r[d]+r[a]-p[a])};e.offsets.popper=le({},p,l[n])}return e}},offset:{order:200,enabled:!0,fn:J,offset:0},preventOverflow:{order:300,enabled:!0,fn:function(e,t){var o=t.boundariesElement||p(e.instance.popper);e.instance.reference===o&&(o=p(o));var n=B('transform'),i=e.instance.popper.style,r=i.top,s=i.left,d=i[n];i.top='',i.left='',i[n]='';var a=v(e.instance.popper,e.instance.reference,t.padding,o,e.positionFixed);i.top=r,i.left=s,i[n]=d,t.boundaries=a;var l=t.priority,f=e.offsets.popper,m={primary:function(e){var o=f[e];return f[e]<a[e]&&!t.escapeWithReference&&(o=ee(f[e],a[e])),ae({},e,o)},secondary:function(e){var o='right'===e?'left':'top',n=f[o];return f[e]>a[e]&&!t.escapeWithReference&&(n=Q(f[o],a[e]-('right'===e?f.width:f.height))),ae({},o,n)}};return l.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';f=le({},f,m[t](e))}),e.offsets.popper=f,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,n=t.reference,i=e.placement.split('-')[0],r=Z,p=-1!==['top','bottom'].indexOf(i),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]<r(n[d])&&(e.offsets.popper[d]=r(n[d])-o[a]),o[d]>r(n[s])&&(e.offsets.popper[d]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var n;if(!K(e.instance.modifiers,'arrow','keepTogether'))return e;var i=o.element;if('string'==typeof i){if(i=e.instance.popper.querySelector(i),!i)return e;}else if(!e.instance.popper.contains(i))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',c=a?'bottom':'right',u=S(i)[l];d[c]-u<s[m]&&(e.offsets.popper[m]-=s[m]-(d[c]-u)),d[m]+u>s[c]&&(e.offsets.popper[m]+=d[m]+u-s[c]),e.offsets.popper=g(e.offsets.popper);var b=d[m]+d[l]/2-u/2,w=t(e.instance.popper),y=parseFloat(w['margin'+f],10),E=parseFloat(w['border'+f+'Width'],10),v=b-e.offsets.popper[m]-y-E;return v=ee(Q(s[l]-u,v),0),e.arrowElement=i,e.offsets.arrow=(n={},ae(n,m,$(v)),ae(n,h,''),n),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=v(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement,e.positionFixed),n=e.placement.split('-')[0],i=T(n),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case ce.FLIP:p=[n,i];break;case ce.CLOCKWISE:p=G(n);break;case ce.COUNTERCLOCKWISE:p=G(n,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(n!==s||p.length===d+1)return e;n=e.placement.split('-')[0],i=T(n);var a=e.offsets.popper,l=e.offsets.reference,f=Z,m='left'===n&&f(a.right)>f(l.left)||'right'===n&&f(a.left)<f(l.right)||'top'===n&&f(a.bottom)>f(l.top)||'bottom'===n&&f(a.top)<f(l.bottom),h=f(a.left)<f(o.left),c=f(a.right)>f(o.right),g=f(a.top)<f(o.top),u=f(a.bottom)>f(o.bottom),b='left'===n&&h||'right'===n&&c||'top'===n&&g||'bottom'===n&&u,w=-1!==['top','bottom'].indexOf(n),y=!!t.flipVariations&&(w&&'start'===r&&h||w&&'end'===r&&c||!w&&'start'===r&&g||!w&&'end'===r&&u),E=!!t.flipVariationsByContent&&(w&&'start'===r&&c||w&&'end'===r&&h||!w&&'start'===r&&u||!w&&'end'===r&&g),v=y||E;(m||b||v)&&(e.flipped=!0,(m||b)&&(n=p[d+1]),v&&(r=z(r)),e.placement=n+(r?'-'+r:''),e.offsets.popper=le({},e.offsets.popper,C(e.instance.popper,e.offsets.reference,e.placement)),e=P(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport',flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],n=e.offsets,i=n.popper,r=n.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return i[p?'left':'top']=r[o]-(s?i[p?'width':'height']:0),e.placement=T(t),e.offsets.popper=g(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!K(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=D(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=t.x,n=t.y,i=e.offsets.popper,r=D(e.instance.modifiers,function(e){return'applyStyle'===e.name}).gpuAcceleration;void 0!==r&&console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');var s,d,a=void 0===r?t.gpuAcceleration:r,l=p(e.instance.popper),f=u(l),m={position:i.position},h=q(e,2>window.devicePixelRatio||!fe),c='bottom'===o?'top':'bottom',g='right'===n?'left':'right',b=B('transform');if(d='bottom'==c?'HTML'===l.nodeName?-l.clientHeight+h.bottom:-f.height+h.bottom:h.top,s='right'==g?'HTML'===l.nodeName?-l.clientWidth+h.right:-f.width+h.right:h.left,a&&b)m[b]='translate3d('+s+'px, '+d+'px, 0)',m[c]=0,m[g]=0,m.willChange='transform';else{var w='bottom'==c?-1:1,y='right'==g?-1:1;m[c]=d*w,m[g]=s*y,m.willChange=c+', '+g}var E={"x-placement":e.placement};return e.attributes=le({},E,e.attributes),e.styles=le({},m,e.styles),e.arrowStyles=le({},e.offsets.arrow,e.arrowStyles),e},gpuAcceleration:!0,x:'bottom',y:'right'},applyStyle:{order:900,enabled:!0,fn:function(e){return V(e.instance.popper,e.styles),j(e.instance.popper,e.attributes),e.arrowElement&&Object.keys(e.arrowStyles).length&&V(e.arrowElement,e.arrowStyles),e},onLoad:function(e,t,o,n,i){var r=L(i,t,e,o.positionFixed),p=O(o.placement,r,t,e,o.modifiers.flip.boundariesElement,o.modifiers.flip.padding);return t.setAttribute('x-placement',p),V(t,{position:o.positionFixed?'fixed':'absolute'}),o},gpuAcceleration:void 0}}},ge});
/*!
* Bootstrap util.js v4.5.0 (https://getbootstrap.com/)
* Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery')) :
typeof define === 'function' && define.amd ? define(['jquery'], factory) :
(global = global || self, global.Util = factory(global.jQuery));
}(this, (function ($) { 'use strict';
$ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $;
/**
* --------------------------------------------------------------------------
* Bootstrap (v4.5.0): util.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* --------------------------------------------------------------------------
*/
/**
* ------------------------------------------------------------------------
* Private TransitionEnd Helpers
* ------------------------------------------------------------------------
*/
var TRANSITION_END = 'transitionend';
var MAX_UID = 1000000;
var MILLISECONDS_MULTIPLIER = 1000; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
function toType(obj) {
if (obj === null || typeof obj === 'undefined') {
return "" + obj;
}
return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
}
function getSpecialTransitionEndEvent() {
return {
bindType: TRANSITION_END,
delegateType: TRANSITION_END,
handle: function handle(event) {
if ($(event.target).is(this)) {
return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params
}
return undefined;
}
};
}
function transitionEndEmulator(duration) {
var _this = this;
var called = false;
$(this).one(Util.TRANSITION_END, function () {
called = true;
});
setTimeout(function () {
if (!called) {
Util.triggerTransitionEnd(_this);
}
}, duration);
return this;
}
function setTransitionEndSupport() {
$.fn.emulateTransitionEnd = transitionEndEmulator;
$.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent();
}
/**
* --------------------------------------------------------------------------
* Public Util Api
* --------------------------------------------------------------------------
*/
var Util = {
TRANSITION_END: 'bsTransitionEnd',
getUID: function getUID(prefix) {
do {
// eslint-disable-next-line no-bitwise
prefix += ~~(Math.random() * MAX_UID); // "~~" acts like a faster Math.floor() here
} while (document.getElementById(prefix));
return prefix;
},
getSelectorFromElement: function getSelectorFromElement(element) {
var selector = element.getAttribute('data-target');
if (!selector || selector === '#') {
var hrefAttr = element.getAttribute('href');
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : '';
}
try {
return document.querySelector(selector) ? selector : null;
} catch (err) {
return null;
}
},
getTransitionDurationFromElement: function getTransitionDurationFromElement(element) {
if (!element) {
return 0;
} // Get transition-duration of the element
var transitionDuration = $(element).css('transition-duration');
var transitionDelay = $(element).css('transition-delay');
var floatTransitionDuration = parseFloat(transitionDuration);
var floatTransitionDelay = parseFloat(transitionDelay); // Return 0 if element or transition duration is not found
if (!floatTransitionDuration && !floatTransitionDelay) {
return 0;
} // If multiple durations are defined, take the first
transitionDuration = transitionDuration.split(',')[0];
transitionDelay = transitionDelay.split(',')[0];
return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
},
reflow: function reflow(element) {
return element.offsetHeight;
},
triggerTransitionEnd: function triggerTransitionEnd(element) {
$(element).trigger(TRANSITION_END);
},
// TODO: Remove in v5
supportsTransitionEnd: function supportsTransitionEnd() {
return Boolean(TRANSITION_END);
},
isElement: function isElement(obj) {
return (obj[0] || obj).nodeType;
},
typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) {
for (var property in configTypes) {
if (Object.prototype.hasOwnProperty.call(configTypes, property)) {
var expectedTypes = configTypes[property];
var value = config[property];
var valueType = value && Util.isElement(value) ? 'element' : toType(value);
if (!new RegExp(expectedTypes).test(valueType)) {
throw new Error(componentName.toUpperCase() + ": " + ("Option \"" + property + "\" provided type \"" + valueType + "\" ") + ("but expected type \"" + expectedTypes + "\"."));
}
}
}
},
findShadowRoot: function findShadowRoot(element) {
if (!document.documentElement.attachShadow) {
return null;
} // Can find the shadow root otherwise it'll return the document
if (typeof element.getRootNode === 'function') {
var root = element.getRootNode();
return root instanceof ShadowRoot ? root : null;
}
if (element instanceof ShadowRoot) {
return element;
} // when we don't find a shadow root
if (!element.parentNode) {
return null;
}
return Util.findShadowRoot(element.parentNode);
},
jQueryDetection: function jQueryDetection() {
if (typeof $ === 'undefined') {
throw new TypeError('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.');
}
var version = $.fn.jquery.split(' ')[0].split('.');
var minMajor = 1;
var ltMajor = 2;
var minMinor = 9;
var minPatch = 1;
var maxMajor = 4;
if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {
throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0');
}
}
};
Util.jQueryDetection();
setTransitionEndSupport();
return Util;
})));
//# sourceMappingURL=util.js.map
/*!
* Bootstrap dropdown.js v4.5.0 (https://getbootstrap.com/)
* Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('popper.js'), require('./util.js')) :
typeof define === 'function' && define.amd ? define(['jquery', 'popper.js', './util.js'], factory) :
(global = global || self, global.Dropdown = factory(global.jQuery, global.Popper, global.Util));
}(this, (function ($, Popper, Util) { 'use strict';
$ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $;
Popper = Popper && Object.prototype.hasOwnProperty.call(Popper, 'default') ? Popper['default'] : Popper;
Util = Util && Object.prototype.hasOwnProperty.call(Util, 'default') ? Util['default'] : Util;
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly) symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
if (i % 2) {
ownKeys(Object(source), true).forEach(function (key) {
_defineProperty(target, key, source[key]);
});
} else if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
} else {
ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
}
return target;
}
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
*/
var NAME = 'dropdown';
var VERSION = '4.5.0';
var DATA_KEY = 'bs.dropdown';
var EVENT_KEY = "." + DATA_KEY;
var DATA_API_KEY = '.data-api';
var JQUERY_NO_CONFLICT = $.fn[NAME];
var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key
var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key
var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key
var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key
var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse)
var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + "|" + ARROW_DOWN_KEYCODE + "|" + ESCAPE_KEYCODE);
var EVENT_HIDE = "hide" + EVENT_KEY;
var EVENT_HIDDEN = "hidden" + EVENT_KEY;
var EVENT_SHOW = "show" + EVENT_KEY;
var EVENT_SHOWN = "shown" + EVENT_KEY;
var EVENT_CLICK = "click" + EVENT_KEY;
var EVENT_CLICK_DATA_API = "click" + EVENT_KEY + DATA_API_KEY;
var EVENT_KEYDOWN_DATA_API = "keydown" + EVENT_KEY + DATA_API_KEY;
var EVENT_KEYUP_DATA_API = "keyup" + EVENT_KEY + DATA_API_KEY;
var CLASS_NAME_DISABLED = 'disabled';
var CLASS_NAME_SHOW = 'show';
var CLASS_NAME_DROPUP = 'dropup';
var CLASS_NAME_DROPRIGHT = 'dropright';
var CLASS_NAME_DROPLEFT = 'dropleft';
var CLASS_NAME_MENURIGHT = 'dropdown-menu-right';
var CLASS_NAME_POSITION_STATIC = 'position-static';
var SELECTOR_DATA_TOGGLE = '[data-toggle="dropdown"]';
var SELECTOR_FORM_CHILD = '.dropdown form';
var SELECTOR_MENU = '.dropdown-menu';
var SELECTOR_NAVBAR_NAV = '.navbar-nav';
var SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';
var PLACEMENT_TOP = 'top-start';
var PLACEMENT_TOPEND = 'top-end';
var PLACEMENT_BOTTOM = 'bottom-start';
var PLACEMENT_BOTTOMEND = 'bottom-end';
var PLACEMENT_RIGHT = 'right-start';
var PLACEMENT_LEFT = 'left-start';
var Default = {
offset: 0,
flip: true,
boundary: 'scrollParent',
reference: 'toggle',
display: 'dynamic',
popperConfig: null
};
var DefaultType = {
offset: '(number|string|function)',
flip: 'boolean',
boundary: '(string|element)',
reference: '(string|element)',
display: 'string',
popperConfig: '(null|object)'
};
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
var Dropdown = /*#__PURE__*/function () {
function Dropdown(element, config) {
this._element = element;
this._popper = null;
this._config = this._getConfig(config);
this._menu = this._getMenuElement();
this._inNavbar = this._detectNavbar();
this._addEventListeners();
} // Getters
var _proto = Dropdown.prototype;
// Public
_proto.toggle = function toggle() {
if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED)) {
return;
}
var isActive = $(this._menu).hasClass(CLASS_NAME_SHOW);
Dropdown._clearMenus();
if (isActive) {
return;
}
this.show(true);
};
_proto.show = function show(usePopper) {
if (usePopper === void 0) {
usePopper = false;
}
if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || $(this._menu).hasClass(CLASS_NAME_SHOW)) {
return;
}
var relatedTarget = {
relatedTarget: this._element
};
var showEvent = $.Event(EVENT_SHOW, relatedTarget);
var parent = Dropdown._getParentFromElement(this._element);
$(parent).trigger(showEvent);
if (showEvent.isDefaultPrevented()) {
return;
} // Disable totally Popper.js for Dropdown in Navbar
if (!this._inNavbar && usePopper) {
/**
* Check for Popper dependency
* Popper - https://popper.js.org
*/
if (typeof Popper === 'undefined') {
throw new TypeError('Bootstrap\'s dropdowns require Popper.js (https://popper.js.org/)');
}
var referenceElement = this._element;
if (this._config.reference === 'parent') {
referenceElement = parent;
} else if (Util.isElement(this._config.reference)) {
referenceElement = this._config.reference; // Check if it's jQuery element
if (typeof this._config.reference.jquery !== 'undefined') {
referenceElement = this._config.reference[0];
}
} // If boundary is not `scrollParent`, then set position to `static`
// to allow the menu to "escape" the scroll parent's boundaries
// https://github.com/twbs/bootstrap/issues/24251
if (this._config.boundary !== 'scrollParent') {
$(parent).addClass(CLASS_NAME_POSITION_STATIC);
}
this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig());
} // If this is a touch-enabled device we add extra
// empty mouseover listeners to the body's immediate children;
// only needed because of broken event delegation on iOS
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
if ('ontouchstart' in document.documentElement && $(parent).closest(SELECTOR_NAVBAR_NAV).length === 0) {
$(document.body).children().on('mouseover', null, $.noop);
}
this._element.focus();
this._element.setAttribute('aria-expanded', true);
$(this._menu).toggleClass(CLASS_NAME_SHOW);
$(parent).toggleClass(CLASS_NAME_SHOW).trigger($.Event(EVENT_SHOWN, relatedTarget));
};
_proto.hide = function hide() {
if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || !$(this._menu).hasClass(CLASS_NAME_SHOW)) {
return;
}
var relatedTarget = {
relatedTarget: this._element
};
var hideEvent = $.Event(EVENT_HIDE, relatedTarget);
var parent = Dropdown._getParentFromElement(this._element);
$(parent).trigger(hideEvent);
if (hideEvent.isDefaultPrevented()) {
return;
}
if (this._popper) {
this._popper.destroy();
}
$(this._menu).toggleClass(CLASS_NAME_SHOW);
$(parent).toggleClass(CLASS_NAME_SHOW).trigger($.Event(EVENT_HIDDEN, relatedTarget));
};
_proto.dispose = function dispose() {
$.removeData(this._element, DATA_KEY);
$(this._element).off(EVENT_KEY);
this._element = null;
this._menu = null;
if (this._popper !== null) {
this._popper.destroy();
this._popper = null;
}
};
_proto.update = function update() {
this._inNavbar = this._detectNavbar();
if (this._popper !== null) {
this._popper.scheduleUpdate();
}
} // Private
;
_proto._addEventListeners = function _addEventListeners() {
var _this = this;
$(this._element).on(EVENT_CLICK, function (event) {
event.preventDefault();
event.stopPropagation();
_this.toggle();
});
};
_proto._getConfig = function _getConfig(config) {
config = _objectSpread2(_objectSpread2(_objectSpread2({}, this.constructor.Default), $(this._element).data()), config);
Util.typeCheckConfig(NAME, config, this.constructor.DefaultType);
return config;
};
_proto._getMenuElement = function _getMenuElement() {
if (!this._menu) {
var parent = Dropdown._getParentFromElement(this._element);
if (parent) {
this._menu = parent.querySelector(SELECTOR_MENU);
}
}
return this._menu;
};
_proto._getPlacement = function _getPlacement() {
var $parentDropdown = $(this._element.parentNode);
var placement = PLACEMENT_BOTTOM; // Handle dropup
if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) {
placement = $(this._menu).hasClass(CLASS_NAME_MENURIGHT) ? PLACEMENT_TOPEND : PLACEMENT_TOP;
} else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) {
placement = PLACEMENT_RIGHT;
} else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) {
placement = PLACEMENT_LEFT;
} else if ($(this._menu).hasClass(CLASS_NAME_MENURIGHT)) {
placement = PLACEMENT_BOTTOMEND;
}
return placement;
};
_proto._detectNavbar = function _detectNavbar() {
return $(this._element).closest('.navbar').length > 0;
};
_proto._getOffset = function _getOffset() {
var _this2 = this;
var offset = {};
if (typeof this._config.offset === 'function') {
offset.fn = function (data) {
data.offsets = _objectSpread2(_objectSpread2({}, data.offsets), _this2._config.offset(data.offsets, _this2._element) || {});
return data;
};
} else {
offset.offset = this._config.offset;
}
return offset;
};
_proto._getPopperConfig = function _getPopperConfig() {
var popperConfig = {
placement: this._getPlacement(),
modifiers: {
offset: this._getOffset(),
flip: {
enabled: this._config.flip
},
preventOverflow: {
boundariesElement: this._config.boundary
}
}
}; // Disable Popper.js if we have a static display
if (this._config.display === 'static') {
popperConfig.modifiers.applyStyle = {
enabled: false
};
}
return _objectSpread2(_objectSpread2({}, popperConfig), this._config.popperConfig);
} // Static
;
Dropdown._jQueryInterface = function _jQueryInterface(config) {
return this.each(function () {
var data = $(this).data(DATA_KEY);
var _config = typeof config === 'object' ? config : null;
if (!data) {
data = new Dropdown(this, _config);
$(this).data(DATA_KEY, data);
}
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
throw new TypeError("No method named \"" + config + "\"");
}
data[config]();
}
});
};
Dropdown._clearMenus = function _clearMenus(event) {
if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) {
return;
}
var toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE));
for (var i = 0, len = toggles.length; i < len; i++) {
var parent = Dropdown._getParentFromElement(toggles[i]);
var context = $(toggles[i]).data(DATA_KEY);
var relatedTarget = {
relatedTarget: toggles[i]
};
if (event && event.type === 'click') {
relatedTarget.clickEvent = event;
}
if (!context) {
continue;
}
var dropdownMenu = context._menu;
if (!$(parent).hasClass(CLASS_NAME_SHOW)) {
continue;
}
if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $.contains(parent, event.target)) {
continue;
}
var hideEvent = $.Event(EVENT_HIDE, relatedTarget);
$(parent).trigger(hideEvent);
if (hideEvent.isDefaultPrevented()) {
continue;
} // If this is a touch-enabled device we remove the extra
// empty mouseover listeners we added for iOS support
if ('ontouchstart' in document.documentElement) {
$(document.body).children().off('mouseover', null, $.noop);
}
toggles[i].setAttribute('aria-expanded', 'false');
if (context._popper) {
context._popper.destroy();
}
$(dropdownMenu).removeClass(CLASS_NAME_SHOW);
$(parent).removeClass(CLASS_NAME_SHOW).trigger($.Event(EVENT_HIDDEN, relatedTarget));
}
};
Dropdown._getParentFromElement = function _getParentFromElement(element) {
var parent;
var selector = Util.getSelectorFromElement(element);
if (selector) {
parent = document.querySelector(selector);
}
return parent || element.parentNode;
} // eslint-disable-next-line complexity
;
Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) {
// If not input/textarea:
// - And not a key in REGEXP_KEYDOWN => not a dropdown command
// If input/textarea:
// - If space key => not a dropdown command
// - If key is other than escape
// - If key is not up or down => not a dropdown command
// - If trigger inside the menu => not a dropdown command
if (/input|textarea/i.test(event.target.tagName) ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $(event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {
return;
}
if (this.disabled || $(this).hasClass(CLASS_NAME_DISABLED)) {
return;
}
var parent = Dropdown._getParentFromElement(this);
var isActive = $(parent).hasClass(CLASS_NAME_SHOW);
if (!isActive && event.which === ESCAPE_KEYCODE) {
return;
}
event.preventDefault();
event.stopPropagation();
if (!isActive || isActive && (event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {
if (event.which === ESCAPE_KEYCODE) {
$(parent.querySelector(SELECTOR_DATA_TOGGLE)).trigger('focus');
}
$(this).trigger('click');
return;
}
var items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS)).filter(function (item) {
return $(item).is(':visible');
});
if (items.length === 0) {
return;
}
var index = items.indexOf(event.target);
if (event.which === ARROW_UP_KEYCODE && index > 0) {
// Up
index--;
}
if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) {
// Down
index++;
}
if (index < 0) {
index = 0;
}
items[index].focus();
};
_createClass(Dropdown, null, [{
key: "VERSION",
get: function get() {
return VERSION;
}
}, {
key: "Default",
get: function get() {
return Default;
}
}, {
key: "DefaultType",
get: function get() {
return DefaultType;
}
}]);
return Dropdown;
}();
/**
* ------------------------------------------------------------------------
* Data Api implementation
* ------------------------------------------------------------------------
*/
$(document).on(EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown._dataApiKeydownHandler).on(EVENT_CLICK_DATA_API + " " + EVENT_KEYUP_DATA_API, Dropdown._clearMenus).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
event.preventDefault();
event.stopPropagation();
Dropdown._jQueryInterface.call($(this), 'toggle');
}).on(EVENT_CLICK_DATA_API, SELECTOR_FORM_CHILD, function (e) {
e.stopPropagation();
});
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
$.fn[NAME] = Dropdown._jQueryInterface;
$.fn[NAME].Constructor = Dropdown;
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return Dropdown._jQueryInterface;
};
return Dropdown;
})));
/*!
* Bootstrap tooltip.js v4.5.0 (https://getbootstrap.com/)
* Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery'), require('popper.js'), require('./util.js')) :
typeof define === 'function' && define.amd ? define(['jquery', 'popper.js', './util.js'], factory) :
(global = global || self, global.Tooltip = factory(global.jQuery, global.Popper, global.Util));
}(this, (function ($, Popper, Util) { 'use strict';
$ = $ && Object.prototype.hasOwnProperty.call($, 'default') ? $['default'] : $;
Popper = Popper && Object.prototype.hasOwnProperty.call(Popper, 'default') ? Popper['default'] : Popper;
Util = Util && Object.prototype.hasOwnProperty.call(Util, 'default') ? Util['default'] : Util;
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly) symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
if (i % 2) {
ownKeys(Object(source), true).forEach(function (key) {
_defineProperty(target, key, source[key]);
});
} else if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
} else {
ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
}
return target;
}
/**
* --------------------------------------------------------------------------
* Bootstrap (v4.5.0): tools/sanitizer.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* --------------------------------------------------------------------------
*/
var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href'];
var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
var DefaultWhitelist = {
// Global attributes allowed on any supplied element below.
'*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
a: ['target', 'href', 'title', 'rel'],
area: [],
b: [],
br: [],
col: [],
code: [],
div: [],
em: [],
hr: [],
h1: [],
h2: [],
h3: [],
h4: [],
h5: [],
h6: [],
i: [],
img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],
li: [],
ol: [],
p: [],
pre: [],
s: [],
small: [],
span: [],
sub: [],
sup: [],
strong: [],
u: [],
ul: []
};
/**
* A pattern that recognizes a commonly useful subset of URLs that are safe.
*
* Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
*/
var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi;
/**
* A pattern that matches safe data URLs. Only matches image, video and audio types.
*
* Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
*/
var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;
function allowedAttribute(attr, allowedAttributeList) {
var attrName = attr.nodeName.toLowerCase();
if (allowedAttributeList.indexOf(attrName) !== -1) {
if (uriAttrs.indexOf(attrName) !== -1) {
return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN));
}
return true;
}
var regExp = allowedAttributeList.filter(function (attrRegex) {
return attrRegex instanceof RegExp;
}); // Check if a regular expression validates the attribute.
for (var i = 0, len = regExp.length; i < len; i++) {
if (attrName.match(regExp[i])) {
return true;
}
}
return false;
}
function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {
if (unsafeHtml.length === 0) {
return unsafeHtml;
}
if (sanitizeFn && typeof sanitizeFn === 'function') {
return sanitizeFn(unsafeHtml);
}
var domParser = new window.DOMParser();
var createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');
var whitelistKeys = Object.keys(whiteList);
var elements = [].slice.call(createdDocument.body.querySelectorAll('*'));
var _loop = function _loop(i, len) {
var el = elements[i];
var elName = el.nodeName.toLowerCase();
if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) {
el.parentNode.removeChild(el);
return "continue";
}
var attributeList = [].slice.call(el.attributes);
var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []);
attributeList.forEach(function (attr) {
if (!allowedAttribute(attr, whitelistedAttributes)) {
el.removeAttribute(attr.nodeName);
}
});
};
for (var i = 0, len = elements.length; i < len; i++) {
var _ret = _loop(i);
if (_ret === "continue") continue;
}
return createdDocument.body.innerHTML;
}
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
*/
var NAME = 'tooltip';
var VERSION = '4.5.0';
var DATA_KEY = 'bs.tooltip';
var EVENT_KEY = "." + DATA_KEY;
var JQUERY_NO_CONFLICT = $.fn[NAME];
var CLASS_PREFIX = 'bs-tooltip';
var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g');
var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn'];
var DefaultType = {
animation: 'boolean',
template: 'string',
title: '(string|element|function)',
trigger: 'string',
delay: '(number|object)',
html: 'boolean',
selector: '(string|boolean)',
placement: '(string|function)',
offset: '(number|string|function)',
container: '(string|element|boolean)',
fallbackPlacement: '(string|array)',
boundary: '(string|element)',
sanitize: 'boolean',
sanitizeFn: '(null|function)',
whiteList: 'object',
popperConfig: '(null|object)'
};
var AttachmentMap = {
AUTO: 'auto',
TOP: 'top',
RIGHT: 'right',
BOTTOM: 'bottom',
LEFT: 'left'
};
var Default = {
animation: true,
template: '<div class="tooltip" role="tooltip">' + '<div class="arrow"></div>' + '<div class="tooltip-inner"></div></div>',
trigger: 'hover focus',
title: '',
delay: 0,
html: false,
selector: false,
placement: 'top',
offset: 0,
container: false,
fallbackPlacement: 'flip',
boundary: 'scrollParent',
sanitize: true,
sanitizeFn: null,
whiteList: DefaultWhitelist,
popperConfig: null
};
var HOVER_STATE_SHOW = 'show';
var HOVER_STATE_OUT = 'out';
var Event = {
HIDE: "hide" + EVENT_KEY,
HIDDEN: "hidden" + EVENT_KEY,
SHOW: "show" + EVENT_KEY,
SHOWN: "shown" + EVENT_KEY,
INSERTED: "inserted" + EVENT_KEY,
CLICK: "click" + EVENT_KEY,
FOCUSIN: "focusin" + EVENT_KEY,
FOCUSOUT: "focusout" + EVENT_KEY,
MOUSEENTER: "mouseenter" + EVENT_KEY,
MOUSELEAVE: "mouseleave" + EVENT_KEY
};
var CLASS_NAME_FADE = 'fade';
var CLASS_NAME_SHOW = 'show';
var SELECTOR_TOOLTIP_INNER = '.tooltip-inner';
var SELECTOR_ARROW = '.arrow';
var TRIGGER_HOVER = 'hover';
var TRIGGER_FOCUS = 'focus';
var TRIGGER_CLICK = 'click';
var TRIGGER_MANUAL = 'manual';
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
var Tooltip = /*#__PURE__*/function () {
function Tooltip(element, config) {
if (typeof Popper === 'undefined') {
throw new TypeError('Bootstrap\'s tooltips require Popper.js (https://popper.js.org/)');
} // private
this._isEnabled = true;
this._timeout = 0;
this._hoverState = '';
this._activeTrigger = {};
this._popper = null; // Protected
this.element = element;
this.config = this._getConfig(config);
this.tip = null;
this._setListeners();
} // Getters
var _proto = Tooltip.prototype;
// Public
_proto.enable = function enable() {
this._isEnabled = true;
};
_proto.disable = function disable() {
this._isEnabled = false;
};
_proto.toggleEnabled = function toggleEnabled() {
this._isEnabled = !this._isEnabled;
};
_proto.toggle = function toggle(event) {
if (!this._isEnabled) {
return;
}
if (event) {
var dataKey = this.constructor.DATA_KEY;
var context = $(event.currentTarget).data(dataKey);
if (!context) {
context = new this.constructor(event.currentTarget, this._getDelegateConfig());
$(event.currentTarget).data(dataKey, context);
}
context._activeTrigger.click = !context._activeTrigger.click;
if (context._isWithActiveTrigger()) {
context._enter(null, context);
} else {
context._leave(null, context);
}
} else {
if ($(this.getTipElement()).hasClass(CLASS_NAME_SHOW)) {
this._leave(null, this);
return;
}
this._enter(null, this);
}
};
_proto.dispose = function dispose() {
clearTimeout(this._timeout);
$.removeData(this.element, this.constructor.DATA_KEY);
$(this.element).off(this.constructor.EVENT_KEY);
$(this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler);
if (this.tip) {
$(this.tip).remove();
}
this._isEnabled = null;
this._timeout = null;
this._hoverState = null;
this._activeTrigger = null;
if (this._popper) {
this._popper.destroy();
}
this._popper = null;
this.element = null;
this.config = null;
this.tip = null;
};
_proto.show = function show() {
var _this = this;
if ($(this.element).css('display') === 'none') {
throw new Error('Please use show on visible elements');
}
var showEvent = $.Event(this.constructor.Event.SHOW);
if (this.isWithContent() && this._isEnabled) {
$(this.element).trigger(showEvent);
var shadowRoot = Util.findShadowRoot(this.element);
var isInTheDom = $.contains(shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement, this.element);
if (showEvent.isDefaultPrevented() || !isInTheDom) {
return;
}
var tip = this.getTipElement();
var tipId = Util.getUID(this.constructor.NAME);
tip.setAttribute('id', tipId);
this.element.setAttribute('aria-describedby', tipId);
this.setContent();
if (this.config.animation) {
$(tip).addClass(CLASS_NAME_FADE);
}
var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement;
var attachment = this._getAttachment(placement);
this.addAttachmentClass(attachment);
var container = this._getContainer();
$(tip).data(this.constructor.DATA_KEY, this);
if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {
$(tip).appendTo(container);
}
$(this.element).trigger(this.constructor.Event.INSERTED);
this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment));
$(tip).addClass(CLASS_NAME_SHOW); // If this is a touch-enabled device we add extra
// empty mouseover listeners to the body's immediate children;
// only needed because of broken event delegation on iOS
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
if ('ontouchstart' in document.documentElement) {
$(document.body).children().on('mouseover', null, $.noop);
}
var complete = function complete() {
if (_this.config.animation) {
_this._fixTransition();
}
var prevHoverState = _this._hoverState;
_this._hoverState = null;
$(_this.element).trigger(_this.constructor.Event.SHOWN);
if (prevHoverState === HOVER_STATE_OUT) {
_this._leave(null, _this);
}
};
if ($(this.tip).hasClass(CLASS_NAME_FADE)) {
var transitionDuration = Util.getTransitionDurationFromElement(this.tip);
$(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
} else {
complete();
}
}
};
_proto.hide = function hide(callback) {
var _this2 = this;
var tip = this.getTipElement();
var hideEvent = $.Event(this.constructor.Event.HIDE);
var complete = function complete() {
if (_this2._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {
tip.parentNode.removeChild(tip);
}
_this2._cleanTipClass();
_this2.element.removeAttribute('aria-describedby');
$(_this2.element).trigger(_this2.constructor.Event.HIDDEN);
if (_this2._popper !== null) {
_this2._popper.destroy();
}
if (callback) {
callback();
}
};
$(this.element).trigger(hideEvent);
if (hideEvent.isDefaultPrevented()) {
return;
}
$(tip).removeClass(CLASS_NAME_SHOW); // If this is a touch-enabled device we remove the extra
// empty mouseover listeners we added for iOS support
if ('ontouchstart' in document.documentElement) {
$(document.body).children().off('mouseover', null, $.noop);
}
this._activeTrigger[TRIGGER_CLICK] = false;
this._activeTrigger[TRIGGER_FOCUS] = false;
this._activeTrigger[TRIGGER_HOVER] = false;
if ($(this.tip).hasClass(CLASS_NAME_FADE)) {
var transitionDuration = Util.getTransitionDurationFromElement(tip);
$(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
} else {
complete();
}
this._hoverState = '';
};
_proto.update = function update() {
if (this._popper !== null) {
this._popper.scheduleUpdate();
}
} // Protected
;
_proto.isWithContent = function isWithContent() {
return Boolean(this.getTitle());
};
_proto.addAttachmentClass = function addAttachmentClass(attachment) {
$(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment);
};
_proto.getTipElement = function getTipElement() {
this.tip = this.tip || $(this.config.template)[0];
return this.tip;
};
_proto.setContent = function setContent() {
var tip = this.getTipElement();
this.setElementContent($(tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle());
$(tip).removeClass(CLASS_NAME_FADE + " " + CLASS_NAME_SHOW);
};
_proto.setElementContent = function setElementContent($element, content) {
if (typeof content === 'object' && (content.nodeType || content.jquery)) {
// Content is a DOM node or a jQuery
if (this.config.html) {
if (!$(content).parent().is($element)) {
$element.empty().append(content);
}
} else {
$element.text($(content).text());
}
return;
}
if (this.config.html) {
if (this.config.sanitize) {
content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn);
}
$element.html(content);
} else {
$element.text(content);
}
};
_proto.getTitle = function getTitle() {
var title = this.element.getAttribute('data-original-title');
if (!title) {
title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title;
}
return title;
} // Private
;
_proto._getPopperConfig = function _getPopperConfig(attachment) {
var _this3 = this;
var defaultBsConfig = {
placement: attachment,
modifiers: {
offset: this._getOffset(),
flip: {
behavior: this.config.fallbackPlacement
},
arrow: {
element: SELECTOR_ARROW
},
preventOverflow: {
boundariesElement: this.config.boundary
}
},
onCreate: function onCreate(data) {
if (data.originalPlacement !== data.placement) {
_this3._handlePopperPlacementChange(data);
}
},
onUpdate: function onUpdate(data) {
return _this3._handlePopperPlacementChange(data);
}
};
return _objectSpread2(_objectSpread2({}, defaultBsConfig), this.config.popperConfig);
};
_proto._getOffset = function _getOffset() {
var _this4 = this;
var offset = {};
if (typeof this.config.offset === 'function') {
offset.fn = function (data) {
data.offsets = _objectSpread2(_objectSpread2({}, data.offsets), _this4.config.offset(data.offsets, _this4.element) || {});
return data;
};
} else {
offset.offset = this.config.offset;
}
return offset;
};
_proto._getContainer = function _getContainer() {
if (this.config.container === false) {
return document.body;
}
if (Util.isElement(this.config.container)) {
return $(this.config.container);
}
return $(document).find(this.config.container);
};
_proto._getAttachment = function _getAttachment(placement) {
return AttachmentMap[placement.toUpperCase()];
};
_proto._setListeners = function _setListeners() {
var _this5 = this;
var triggers = this.config.trigger.split(' ');
triggers.forEach(function (trigger) {
if (trigger === 'click') {
$(_this5.element).on(_this5.constructor.Event.CLICK, _this5.config.selector, function (event) {
return _this5.toggle(event);
});
} else if (trigger !== TRIGGER_MANUAL) {
var eventIn = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSEENTER : _this5.constructor.Event.FOCUSIN;
var eventOut = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSELEAVE : _this5.constructor.Event.FOCUSOUT;
$(_this5.element).on(eventIn, _this5.config.selector, function (event) {
return _this5._enter(event);
}).on(eventOut, _this5.config.selector, function (event) {
return _this5._leave(event);
});
}
});
this._hideModalHandler = function () {
if (_this5.element) {
_this5.hide();
}
};
$(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler);
if (this.config.selector) {
this.config = _objectSpread2(_objectSpread2({}, this.config), {}, {
trigger: 'manual',
selector: ''
});
} else {
this._fixTitle();
}
};
_proto._fixTitle = function _fixTitle() {
var titleType = typeof this.element.getAttribute('data-original-title');
if (this.element.getAttribute('title') || titleType !== 'string') {
this.element.setAttribute('data-original-title', this.element.getAttribute('title') || '');
this.element.setAttribute('title', '');
}
};
_proto._enter = function _enter(event, context) {
var dataKey = this.constructor.DATA_KEY;
context = context || $(event.currentTarget).data(dataKey);
if (!context) {
context = new this.constructor(event.currentTarget, this._getDelegateConfig());
$(event.currentTarget).data(dataKey, context);
}
if (event) {
context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;
}
if ($(context.getTipElement()).hasClass(CLASS_NAME_SHOW) || context._hoverState === HOVER_STATE_SHOW) {
context._hoverState = HOVER_STATE_SHOW;
return;
}
clearTimeout(context._timeout);
context._hoverState = HOVER_STATE_SHOW;
if (!context.config.delay || !context.config.delay.show) {
context.show();
return;
}
context._timeout = setTimeout(function () {
if (context._hoverState === HOVER_STATE_SHOW) {
context.show();
}
}, context.config.delay.show);
};
_proto._leave = function _leave(event, context) {
var dataKey = this.constructor.DATA_KEY;
context = context || $(event.currentTarget).data(dataKey);
if (!context) {
context = new this.constructor(event.currentTarget, this._getDelegateConfig());
$(event.currentTarget).data(dataKey, context);
}
if (event) {
context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = false;
}
if (context._isWithActiveTrigger()) {
return;
}
clearTimeout(context._timeout);
context._hoverState = HOVER_STATE_OUT;
if (!context.config.delay || !context.config.delay.hide) {
context.hide();
return;
}
context._timeout = setTimeout(function () {
if (context._hoverState === HOVER_STATE_OUT) {
context.hide();
}
}, context.config.delay.hide);
};
_proto._isWithActiveTrigger = function _isWithActiveTrigger() {
for (var trigger in this._activeTrigger) {
if (this._activeTrigger[trigger]) {
return true;
}
}
return false;
};
_proto._getConfig = function _getConfig(config) {
var dataAttributes = $(this.element).data();
Object.keys(dataAttributes).forEach(function (dataAttr) {
if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) {
delete dataAttributes[dataAttr];
}
});
config = _objectSpread2(_objectSpread2(_objectSpread2({}, this.constructor.Default), dataAttributes), typeof config === 'object' && config ? config : {});
if (typeof config.delay === 'number') {
config.delay = {
show: config.delay,
hide: config.delay
};
}
if (typeof config.title === 'number') {
config.title = config.title.toString();
}
if (typeof config.content === 'number') {
config.content = config.content.toString();
}
Util.typeCheckConfig(NAME, config, this.constructor.DefaultType);
if (config.sanitize) {
config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn);
}
return config;
};
_proto._getDelegateConfig = function _getDelegateConfig() {
var config = {};
if (this.config) {
for (var key in this.config) {
if (this.constructor.Default[key] !== this.config[key]) {
config[key] = this.config[key];
}
}
}
return config;
};
_proto._cleanTipClass = function _cleanTipClass() {
var $tip = $(this.getTipElement());
var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX);
if (tabClass !== null && tabClass.length) {
$tip.removeClass(tabClass.join(''));
}
};
_proto._handlePopperPlacementChange = function _handlePopperPlacementChange(popperData) {
this.tip = popperData.instance.popper;
this._cleanTipClass();
this.addAttachmentClass(this._getAttachment(popperData.placement));
};
_proto._fixTransition = function _fixTransition() {
var tip = this.getTipElement();
var initConfigAnimation = this.config.animation;
if (tip.getAttribute('x-placement') !== null) {
return;
}
$(tip).removeClass(CLASS_NAME_FADE);
this.config.animation = false;
this.hide();
this.show();
this.config.animation = initConfigAnimation;
} // Static
;
Tooltip._jQueryInterface = function _jQueryInterface(config) {
return this.each(function () {
var data = $(this).data(DATA_KEY);
var _config = typeof config === 'object' && config;
if (!data && /dispose|hide/.test(config)) {
return;
}
if (!data) {
data = new Tooltip(this, _config);
$(this).data(DATA_KEY, data);
}
if (typeof config === 'string') {
if (typeof data[config] === 'undefined') {
throw new TypeError("No method named \"" + config + "\"");
}
data[config]();
}
});
};
_createClass(Tooltip, null, [{
key: "VERSION",
get: function get() {
return VERSION;
}
}, {
key: "Default",
get: function get() {
return Default;
}
}, {
key: "NAME",
get: function get() {
return NAME;
}
}, {
key: "DATA_KEY",
get: function get() {
return DATA_KEY;
}
}, {
key: "Event",
get: function get() {
return Event;
}
}, {
key: "EVENT_KEY",
get: function get() {
return EVENT_KEY;
}
}, {
key: "DefaultType",
get: function get() {
return DefaultType;
}
}]);
return Tooltip;
}();
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
$.fn[NAME] = Tooltip._jQueryInterface;
$.fn[NAME].Constructor = Tooltip;
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT;
return Tooltip._jQueryInterface;
};
return Tooltip;
})));
/**
* CatRename
*
* Ajoute un onglet permettant de renommer une catégorie, en déplaçant les pages
* incluses dans celle-ci. Permet de faire faire l'action à un bot en un clic.
*
* {{Projet:JavaScript/Script|CatRename}}
*/
/* <nowiki> */
/* globals mw, OO, $ */
if ( mw.config.get( 'wgNamespaceNumber' ) === 14 ) {
mw.loader.using( 'mediawiki.util', function () {
'use strict';
// Site-related parameters
const TAG = 'RenommageCategorie';
const DAILY_LIMIT = 250;
const RBOT_PAGE = 'Wikipédia:Bot/Requêtes/Catégories';
const DR_TEMPLATE = '{{Suppression Immédiate|raison=Catégorie récemment renommée en [[:Catégorie:$2]] ($3)|utilisateur=$4}}\n\n';
const RBOT_TEMPLATE = '\n{{Déplacement catégorie|ancienne=$1|nouvelle=$2|raison=$3|demandeur=$4}}';
// Literal non-breaking space, for situations where HTML entities can't be used
const NBSP = String.fromCharCode( 0xA0 );
// Messages
const messages = {
'fr': {
'catrename-title': 'Renommer une catégorie',
'catrename-portlet-title': 'CatRename',
'catrename-action-rename': 'Renommer',
'catrename-action-cancel': 'Annuler',
'catrename-action-rbot': '… ou faire faire la tâche par un bot',
'catrename-checkbox-movetalk': 'Renommer aussi la page de discussion associée',
'catrename-checkbox-leave-redirect': 'Laisser une redirection vers le nouveau titre',
'catrename-checkbox-post-dr': 'Déposer une demande de suppression de l\'ancienne catégorie',
'catrename-checkbox-watch': 'Suivre les catégories originale et nouvelle',
'catrename-checkbox-watch-members': 'Suivre les pages modifiées',
'catrename-field-title': 'Nouveau titre' + NBSP + ':',
'catrename-field-reason': 'Motif' + NBSP + ':',
'catrename-summary': 'Remplacement de la catégorie [[Catégorie:$1]] par [[Catégorie:$2]] : $3',
'catrename-dr-summary': 'Demande de suppression après renommage',
'catrename-rbot-summary': 'RBOT : Demande de renommage de catégorie',
'catrename-status-checkcategory': 'Vérification de la catégorie cible',
'catrename-status-getmembers': 'Récupération des pages membres de la catégorie',
'catrename-status-waitinglock': 'En attente de la fin de renommage dans d\'autres onglets',
'catrename-status-checklimits': 'Vérification de la limite journalière',
'catrename-status-editmembers': 'Modification de la page $1 sur $2',
'catrename-status-renamecategory': 'Renommage de la catégorie',
'catrename-status-postdr': 'Dépôt de la demande de suppression',
'catrename-status-postrbot': 'Dépôt de la requête aux bots',
'catrename-error-canceled': 'Le processus de renommage a été annulé.',
'catrename-error-same': 'Le nouveau titre est identique au titre actuel.',
'catrename-error-invalidtitle': 'Le titre de la catégorie demandée est non valide, vide, ou mal formé.',
'catrename-error-noreason': 'Veuillez indiquer un motif pour ce renommage.',
'catrename-error-protected': 'Cette catégorie est protégée, vous n\'êtes pas autorisé à la renommer.',
'catrename-error-categoryexist': 'Il existe déjà une catégorie avec ce nom…',
'catrename-error-limitreached': 'Le renommage de cette catégorie vous ferait faire plus de $1 modifications avec ce script en moins de 24h. Vous pouvez cependant faire une requête aux bots via le bouton en bas à gauche.',
'catrename-error-categorypresent': 'La page contient déjà la nouvelle catégorie.',
'catrename-error-notfound': 'La catégorie n\'a pas été trouvée dans le code de la page, peut-être est-elle incluse via un modèle' + NBSP + '?',
'catrename-error-pageprotected': 'La page est protégée en écriture.',
'catrename-error-articleexists': 'Impossible de déplacer la catégorie, la page de destination «' + NBSP + '$1' + NBSP + '» existe déjà.',
}
};
mw.messages.set( messages.fr );
var lang = mw.config.get( 'wgUserLanguage' );
if ( lang !== 'fr' && lang in messages ) {
mw.messages.set( messages[ lang ] );
}
var isBootstrapped = false;
var instanceWindowManager;
var instanceCatRename;
$( function ( $ ) {
var portlet = mw.util.addPortletLink( 'p-cactions', '#', mw.msg( 'catrename-portlet-title' ) );
$( portlet ).on( 'click', function ( e ) {
e.preventDefault();
mw.loader.using( [ 'oojs-ui', 'mediawiki.storage', 'mediawiki.api' ], function () {
bootstrapOnce();
instanceCatRename.open();
} );
} );
} );
/* Instanciate CatRename and add it to MediaWiki's UI. */
function bootstrapOnce() {
if (isBootstrapped) {
return;
}
isBootstrapped = true;
/**
* Main class of the gadget CatRename, which is displayed as a ProcessDialog
*
* @class
* @extends OO.ui.ProcessDialog
*
* @constructor
*/
var CatRename = function () {
// Initialize config
var config = { size: 'medium' };
// Parent constructor
CatRename.parent.call( this, config );
// Properties
this.api = new mw.Api( { timeout: 7000 } );
this.oldTitle;
this.newTitle;
this.oldPageName;
this.newPageName;
this.reason;
this.deferred;
this.members;
this.lockID;
this.nextTab;
this.noSpammingDelay;
// Graphical properties
this.configContent = new OO.ui.PanelLayout( { padded: true, expanded: false } );
this.statusContent = new OO.ui.PanelLayout( { padded: true, expanded: false } );
this.newNameInput;
this.reasonInput;
this.optionCheckboxes;
this.layout;
this.$body;
this.statusIndicator;
this.pagesInError;
};
/* Setup */
OO.inheritClass( CatRename, OO.ui.ProcessDialog );
/* Static Properties */
CatRename.static.name = 'catrename';
CatRename.static.title = mw.msg( 'catrename-title' );
CatRename.static.actions = [
{ action: 'rename', label: mw.msg( 'catrename-action-rename' ), flags: [ 'primary', 'progressive' ] },
{ action: 'cancel', label: mw.msg( 'catrename-action-cancel' ), flags: [ 'safe', 'back' ] },
{ action: 'rbot', label: mw.msg( 'catrename-action-rbot' ), flags: 'other' }
];
/* ProcessDialog-related Methods */
/**
* Build the interface displayed inside the ProcessDialog box.
*/
CatRename.prototype.initialize = function () {
CatRename.parent.prototype.initialize.apply( this, arguments );
this.newNameInput = new OO.ui.TextInputWidget( { value: mw.config.get( 'wgTitle' ) } );
this.reasonInput = new OO.ui.TextInputWidget( {
maxLength: 500,
name: 'wpSummary'
} );
this.optionCheckboxes = new OO.ui.CheckboxMultiselectInputWidget( {
value: [ 'movetalk', 'post-dr' ],
options: [
{ data: 'movetalk', label: mw.msg( 'catrename-checkbox-movetalk' ) },
( this.userInGroup( 'sysop' ) || this.userInGroup( 'bot' ) ?
{ data: 'leave-redirect', label: mw.msg( 'catrename-checkbox-leave-redirect' ) } :
{ data: 'post-dr', label: mw.msg( 'catrename-checkbox-post-dr' ) }
),
{ data: 'watch', label: mw.msg( 'catrename-checkbox-watch' ) },
{ data: 'watch-members', label: mw.msg( 'catrename-checkbox-watch-members' ) }
]
} );
this.layout = new OO.ui.Widget( {
content: [
new OO.ui.FieldLayout(
this.newNameInput, {
align: 'top',
label: mw.msg( 'catrename-field-title' ),
}
),
new OO.ui.FieldLayout(
this.reasonInput, {
align: 'top',
label: mw.msg( 'catrename-field-reason' ),
}
),
new OO.ui.FieldLayout(
this.optionCheckboxes, {}
)
],
} );
this.configContent.$element.append( this.layout.$element );
this.$body.append( this.configContent.$element );
this.statusIndicator = $( '<h3>' )
.css( 'text-align', 'center' )
.css( 'margin-top', '1em' )
.css( 'margin-bottom', '2em' );
this.pagesInError = $( '<ul>' );
this.statusContent.$element.append( this.statusIndicator ).append( this.pagesInError );
this.setSize( this.size );
this.updateSize();
};
/**
* Get a process for taking action.
*
* This method is called within the ProcessDialog when the user clicks
* on an action button (the one defined in CatRename.static.actions).
* Here is defined in which order each method of the category moving
* process is called.
* @param {string} action Name of the action button clicked.
* @return {OO.ui.Process} Action process.
*/
CatRename.prototype.getActionProcess = function ( action ) {
var process = new OO.ui.Process(),
options = this.optionCheckboxes.getValue();
if ( action === 'cancel' || action === '' ) { // empty string when closing with Escape key
return process.next( this.unlockMultitabs, this )
.next( this.closeDialog, this );
}
else if ( action === 'rename' ) {
process.next( this.prepare, this )
.next( this.checkCategory, this )
.next( this.getMembers, this )
.next( this.lockMultitabs, this )
.next( this.checkLimits, this )
.next( this.editMembers, this )
.next( this.renameCategory, this );
}
else if ( action === 'rbot' ) {
process.next( this.prepare, this )
.next( this.checkCategory, this )
.next( this.getMembers, this )
.next( this.postRBot, this )
.next( this.renameCategory, this );
}
if ( options.indexOf( 'post-dr' ) > -1 ) {
process.next( this.postDR, this );
}
process.next( this.unlockMultitabs, this )
.next( this.success, this )
.next( this.closeDialog, this );
return process;
};
/**
* Close the window.
*
* @return {jQuery.Promise} Promise resolved when window is closed
*/
CatRename.prototype.closeDialog = function () {
var dialog = this;
var lifecycle = dialog.close();
return lifecycle.closed;
};
/**
* Get the height of the window body.
* Used by the ProcessDialog to set an accurate height to the dialog.
*
* @return {number} Height in px the dialog should be.
*/
CatRename.prototype.getBodyHeight = function () {
return this.configContent.$element.outerHeight( true );
};
/* Process step methods */
/**
* Fetch and validate user's input to make it easily accessible later.
*
* @return {undefined|OO.ui.Error} Error message for the ProcessDialog
* to display, if any.
*/
CatRename.prototype.prepare = function () {
var dialog = this;
this.oldTitle = mw.config.get( 'wgTitle' );
this.newTitle = this.newNameInput.getValue().trim().replace(/^([Cc]atégorie|[Cc]ategory):/, '');
this.reason = this.reasonInput.getValue().trim();
if ( mw.config.get( 'wgCaseSensitiveNamespaces' ).indexOf( 14 ) === -1 ) {
this.newTitle = this.newTitle.charAt( 0 ).toUpperCase() + this.newTitle.slice( 1 );
}
if ( this.newTitle === this.oldTitle ) {
return new OO.ui.Error( mw.msg( 'catrename-error-same' ) );
}
if ( mw.Title.makeTitle( 14, this.newTitle ) === null ) {
return new OO.ui.Error( mw.msg( 'catrename-error-invalidtitle' ) );
}
if ( this.reason === '' ) {
return new OO.ui.Error( mw.msg( 'catrename-error-noreason' ) );
}
this.oldPageName = mw.config.get('wgFormattedNamespaces')[ 14 ] + ':' + this.oldTitle;
this.newPageName = mw.config.get('wgFormattedNamespaces')[ 14 ] + ':' + this.newTitle;
// Disable actions button when a process is runing
this.getActions().get( { actions: 'rename' } )[ 0 ].setDisabled( true );
this.getActions().get( { actions: 'rbot' } )[ 0 ].setDisabled( true );
// Except for the cancel button, which behaviour change to cancel the ongoing process
this.getActions().get( { actions: 'cancel' } )[ 0 ].on( 'click', function () {
dialog.errorHandler( mw.msg( 'catrename-error-canceled' ) );
} );
return;
};
/**
* Check if it is technically possible to move the category.
*
* Two main checks are performed:
* * Has the user the right to move the category according to the
* protection level?
* * Is the target title free?
* @return {JQuery.Deferred} Promise telling to continue the process if
* successful or stopping the process if rejected.
*/
CatRename.prototype.checkCategory = function () {
var dialog = this;
this.deferred = $.Deferred();
this.showStatus( mw.msg( 'catrename-status-checkcategory' ) );
var restrictionMove = mw.config.get( 'wgRestrictionMove' );
for ( var i = 0; i < restrictionMove.length; i++ ) {
if ( ! this.userInGroup( restrictionMove[ i ] ) ) {
this.errorHandler( mw.msg( 'catrename-error-protected' ) );
return this.deferred;
}
}
this.api.get( {
'action': 'query',
'format': 'json',
'formatversion': 2,
'prop': 'categoryinfo',
'titles': this.newPageName
} ).then( function ( data ) {
if ( data.query.pages[ 0 ].missing !== true ) {
//TODO: Allow user to move pages without renaming the cat
dialog.errorHandler( mw.msg( 'catrename-error-categoryexist' ) );
return;
}
dialog.deferred.resolve();
} ).fail( function ( error ) {
dialog.errorHandler( error );
} );
return this.deferred;
};
/**
* Get all pages, files and sub-categories in the source category.
*
* This method populates the attribute 'members'.
* @return {JQuery.Deferred} Promise telling to continue the process if
* successful or stopping the process if rejected.
*/
CatRename.prototype.getMembers = function () {
var dialog = this;
this.deferred = $.Deferred();
this.members = [];
this.showStatus( mw.msg( 'catrename-status-getmembers' ) );
function doGetMembers( paramsContinue ) {
var params = {
'action': 'query',
'format': 'json',
'list': 'categorymembers',
'formatversion': '2',
'cmtitle': mw.config.get( 'wgPageName' ),
'cmprop': 'title',
'cmlimit': 'max',
};
if ( paramsContinue ) {
$.extend( params, paramsContinue );
}
dialog.api.get( params ).then( function ( data ) {
var categoryMembers = data.query.categorymembers;
for ( var i = 0; i < categoryMembers.length; i++ ) {
dialog.members.push( categoryMembers[ i ].title );
}
if ( data[ 'continue' ] ) {
doGetMembers( data[ 'continue' ] );
}
else {
dialog.deferred.resolve();
}
} ).fail( function ( error ) {
dialog.errorHandler( error );
} );
}
doGetMembers();
return this.deferred;
};
/**
* Lock the process while other instances of CatRename are running.
*
* This method acts a bit like the POSIX sem_wait.
* @return {JQuery.Deferred} Promise telling to continue the process
* when it is its turn to execute.
*/
CatRename.prototype.lockMultitabs = function () {
var dialog = this;
this.deferred = $.Deferred();
if ( this.userInGroup( 'bot' ) ) {
return;
}
this.lockID = 'catrename-' + this.randomString( 16 );
this.nextTab = null;
this.showStatus( mw.msg( 'catrename-status-waitinglock' ) );
//TODO: check lock timestamp
if ( mw.storage.get( 'catrename-lock' ) === null ) {
mw.storage.set( 'catrename-lock', this.lockID );
this.deferred.resolve();
}
else {
$( window ).on( 'storage.catrename.catrename-waiting', function ( event ) {
if ( event.originalEvent.key === 'catrename-lock' && event.originalEvent.newValue === dialog.lockID ) {
$( window ).off( 'storage.catrename-waiting' );
dialog.deferred.resolve();
}
} );
mw.storage.set( 'catrename-addtab', this.lockID );
}
$( window ).on( 'storage.catrename', function ( event ) {
// if this tab has no successor and a new one appears, add it as our successor
if ( dialog.nextTab === null && event.originalEvent.key === 'catrename-addtab' && event.originalEvent.newValue !== null ) {
dialog.nextTab = event.originalEvent.newValue;
mw.storage.set( dialog.lockID, dialog.nextTab );
}
// if our successor decides to leave, remove it and take its successor
else if ( dialog.nextTab !== null && event.originalEvent.key === 'catrename-removetab' && event.originalEvent.newValue === dialog.nextTab ) {
dialog.nextTab = mw.storage.get( dialog.nextTab );
if ( dialog.nextTab !== null ) {
mw.storage.set( dialog.lockID, dialog.nextTab );
}
else {
mw.storage.remove( dialog.lockID );
}
}
} );
window.addEventListener( 'unload', function (e) {
dialog.unlockMultitabs();
} );
return this.deferred;
};
/**
* Check if the daily limit of edits using this script would be reached
* if the move is performed.
*
* In fact, we are not looking realy on a daily basis, but a 24h rolling
* period.
* @return {JQuery.Deferred} Promise telling to continue the process
* when it is its turn to execute.
*/
CatRename.prototype.checkLimits = function () {
var dialog = this;
this.deferred = $.Deferred();
var yesterday = new Date();
yesterday.setDate( yesterday.getDate() - 1 );
if ( this.userInGroup( 'bot' ) ) {
this.noSpammingDelay = 0;
return;
}
this.noSpammingDelay = 5000;
if ( this.members.length > 50 ) {
this.noSpammingDelay = 20000;
}
else if ( this.members.length > 10 ) {
this.noSpammingDelay = 10000;
}
this.showStatus( mw.msg( 'catrename-status-checklimits' ) );
this.api.get( {
'action': 'query',
'format': 'json',
'list': 'usercontribs',
'formatversion': '2',
'uclimit': 'max', // only query DAILY_LIMIT results ?
'ucend': yesterday.toISOString(),
'ucuser': mw.config.get( 'wgUserName' ),
'ucprop': 'timestamp',
'uctag': TAG
} ).then( function ( data ) {
if ( data.query.usercontribs.length + dialog.members.length >= DAILY_LIMIT ) {
dialog.errorHandler( mw.msg( 'catrename-error-limitreached', DAILY_LIMIT ), false );
}
else {
dialog.deferred.resolve();
}
} ).fail( function ( error ) {
dialog.errorHandler( error );
} );
return this.deferred;
};
/**
* Try to move all the pages inside the 'members' attribute from the old
* to the new category name by fetching and editing their wikicode.
*
* @return {JQuery.Deferred} Promise telling to continue the process
* when it is its turn to execute.
*/
CatRename.prototype.editMembers = function () {
var dialog = this,
totalPages = this.members.length,
oldCatRegex = this.buildRegex( this.oldTitle ),
newCatRegex = this.buildRegex( this.newTitle ),
summary = mw.msg( 'catrename-summary', this.oldTitle, this.newTitle, this.reason ),
commonPayload = {
summary: summary,
minor: true,
tags: TAG
};
this.deferred = $.Deferred();
if ( this.userInGroup( 'bot' ) ) {
commonPayload[ 'bot' ] = 1;
}
if ( this.optionCheckboxes.getValue().indexOf( 'watch-members' ) > -1 ) {
commonPayload[ 'watchlist' ] = 'watch';
}
function doEdit() {
var member = dialog.members.pop();
if ( dialog.deferred.state() !== 'pending' ) {
return;
}
if ( member === undefined ) {
dialog.deferred.resolve();
return;
}
//TODO: a progress-bar ?
dialog.showStatus( mw.msg( 'catrename-status-editmembers', totalPages - dialog.members.length, totalPages ) );
dialog.api.edit( member, function ( revision ) {
var content = revision.content,
newCatInPageList = content.match( newCatRegex );
if ( newCatInPageList !== null ) {
dialog.logFailedPages( member, mw.msg( 'catrename-error-categorypresent' ) );
}
else {
content = content.replace(
oldCatRegex,
'$1[[' + dialog.newPageName + '$6]]'
);
}
return $.extend( { text: content }, commonPayload );
} )
.then( function ( result ) {
if ( result.nochange === true ) {
dialog.logFailedPages( member, mw.msg( 'catrename-error-notfound' ) );
}
setTimeout( doEdit, dialog.noSpammingDelay );
} )
.fail( function ( code, data ) {
if ( code === 'protectedpage' ) {
dialog.logFailedPages( member, mw.msg( 'catrename-error-pageprotected' ) );
doEdit();
}
else {
dialog.errorHandler( code );
}
} );
}
doEdit();
return this.deferred;
};
/**
* Move the category itself.
*
* @return {JQuery.Deferred} Promise telling to continue the process
* when it is its turn to execute.
*/
CatRename.prototype.renameCategory = function () {
var dialog = this;
this.deferred = $.Deferred();
this.showStatus( mw.msg( 'catrename-status-renamecategory' ) );
var payload = {
'action': 'move',
'format': 'json',
'from': mw.config.get( 'wgPageName' ),
'to': this.newPageName,
'reason': this.reason,
'tags': TAG,
'formatversion': '2'
};
var options = this.optionCheckboxes.getValue();
if ( options.indexOf( 'movetalk' ) > -1 ) {
payload[ 'movetalk' ] = 1;
}
if ( options.indexOf( 'watch' ) > -1 ) {
payload[ 'watchlist' ] = 'watch';
}
if ( this.userInGroup( 'sysop' ) || this.userInGroup( 'bot' ) ) {
if ( options.indexOf( 'leave-redirect' ) === -1 ) {
payload[ 'noredirect' ] = 1;
}
}
this.api.postWithToken( 'csrf', payload ).then( function ( data ) {
dialog.deferred.resolve();
} ).fail( function ( error ) {
if ( error === 'articleexists' ) {
dialog.errorHandler( mw.msg( 'catrename-error-articleexists', dialog.newPageName ) );
}
else {
dialog.errorHandler( error );
}
} );
return this.deferred;
};
/**
* Post a deletion request.
*
* @return {JQuery.Deferred} Promise telling to continue the process
* when it is its turn to execute.
*/
CatRename.prototype.postDR = function () {
var dialog = this;
this.deferred = $.Deferred();
this.showStatus( mw.msg( 'catrename-status-postdr' ) );
var content = DR_TEMPLATE
.replace( /\$1/g, this.oldTitle )
.replace( /\$2/g, this.newTitle )
.replace( /\$3/g, this.reason )
.replace( /\$4/g, mw.config.get( 'wgUserName' ) );
this.api.postWithToken( 'csrf', {
'action': 'edit',
'format': 'json',
'title': this.oldPageName,
'summary': mw.msg( 'catrename-dr-summary' ),
'tags': TAG,
'nocreate': 1,
'prependtext': content,
'formatversion': '2'
} ).then( function ( data ) {
dialog.deferred.resolve();
} ).fail( function ( error ) {
dialog.errorHandler( error );
} );
return this.deferred;
};
/**
* Post a move request for the bots.
*
* @return {JQuery.Deferred} Promise telling to continue the process
* when it is its turn to execute.
*/
CatRename.prototype.postRBot = function () {
var dialog = this;
this.deferred = $.Deferred();
this.showStatus( mw.msg( 'catrename-status-postrbot' ) );
var content = RBOT_TEMPLATE
.replace( /\$1/g, this.oldTitle )
.replace( /\$2/g, this.newTitle )
.replace( /\$3/g, this.reason )
.replace( /\$4/g, mw.config.get( 'wgUserName' ) );
this.api.postWithToken( 'csrf', {
'action': 'edit',
'format': 'json',
'title': RBOT_PAGE,
'summary': mw.msg( 'catrename-rbot-summary' ),
'tags': TAG,
'nocreate': 1,
'appendtext': content,
'formatversion': '2'
} ).then( function ( data ) {
dialog.deferred.resolve();
} ).fail( function ( error ) {
dialog.errorHandler( error );
} );
return this.deferred;
};
/**
* Release the lock to allow other instances of CatRename to execute.
*
* This method acts a bit like the POSIX sem_post.
*/
CatRename.prototype.unlockMultitabs = function () {
if ( this.lockID !== undefined ) {
$( window ).off( 'storage.catrename' );
mw.storage.set( 'catrename-removetab', this.lockID ); //Inform other tabs that we're closing
mw.storage.remove( this.lockID ); //Clean up our mess from the localStorage
// wake up the next tab, or reset if there is none
if ( mw.storage.get( 'catrename-lock' ) === this.lockID ) {
if ( this.nextTab !== null ) {
mw.storage.set( 'catrename-lock', this.nextTab );
}
else {
mw.storage.remove( 'catrename-lock' );
}
}
delete this.lockID;
}
};
/**
* Method called when all has gone well (yeah !).
*/
CatRename.prototype.success = function () {
var dialog = this;
setTimeout( function () {
window.location = mw.util.getUrl( dialog.newPageName );
}, 1000 );
};
/* Helper Methods */
/**
* Get information about the current user's groups.
*
* @param {string} groupName Name of the group to check.
* @return {boolean} Whether the current user is in the given group.
*/
CatRename.prototype.userInGroup = function ( groupName ) {
return ( mw.config.get( 'wgUserGroups' ).indexOf( groupName ) > -1 );
};
/**
* Display a status message inside the main content of the dialog.
*
* @return {string} Status message to display.
*/
CatRename.prototype.showStatus = function ( status ) {
this.statusIndicator.text( status );
this.$body.children().detach();
this.$body.append( this.statusContent.$element );
};
/**
* Raise an error using OO.ui.Error, and reset all what should be.
*
* @param {string} error Error message to display to the user.
* @param {boolean} recoverable Is the error recoverable (default to true).
* @param {boolean} warning Should we raise a warning instead an error (default to false).
*/
CatRename.prototype.errorHandler = function ( error, recoverable, warning ) {
var errorMessage = new OO.ui.Error( error, { recoverable: recoverable || true, warning: warning || false } );
this.unlockMultitabs();
this.$body.children().detach();
this.$body.append( this.configContent.$element );
this.getActions().get( { actions: 'rename' } )[ 0 ].setDisabled( false );
this.getActions().get( { actions: 'rbot' } )[ 0 ].setDisabled( false );
this.deferred.reject( errorMessage );
};
/**
* Add a page to the error log.
*
* @param {string} pageName Name (including namespace) of the page.
* @param {string} reason Explaination of the error.
*/
CatRename.prototype.logFailedPages = function ( pageName, reason ) {
var li = $( '<li>' ).text( ' - ' + reason ),
a = $( '<a>' ).attr( 'href', mw.util.getUrl( pageName ) ).text( pageName );
this.pagesInError.append( li.prepend( a ) );
};
/**
* Build a regex to extract the link to a given category from wikicode.
*
* @param {string} category Name (without namespace) of the category.
* @return {RegExp} Regex object to extract the given category.
*/
CatRename.prototype.buildRegex = function ( category ) {
var formattedNamespace = mw.config.get( 'wgFormattedNamespaces' )[ 14 ],
isFirstLetterCaseSensitive = ( mw.config.get( 'wgCaseSensitiveNamespaces' ).indexOf( 14 ) > -1 ),
namespace = '(?:[' + formattedNamespace.charAt( 0 ) + formattedNamespace.charAt( 0 ).toLowerCase() + ']' + formattedNamespace.slice( 1 ) + '|[Cc]ategory)';
category = category.replace( /([\\\^\$\*\+\?\.\|\{\}\[\]\(\)])/g, '\\$1' );
if ( ! isFirstLetterCaseSensitive ) {
var firstLetter = category.charAt(0);
if ( firstLetter.toUpperCase() !== firstLetter.toLowerCase() ) {
category = '[' + firstLetter.toUpperCase() + firstLetter.toLowerCase() + ']'
+ category.slice(1);
}
}
return new RegExp('(\\s*)\\[\\[( |_)*' + namespace + '( |_)*:( |_)*' + category + '( |_)*(\\|[^\\]]*)?\\]\\]', 'g');
};
/**
* Generate a random string.
*
* @param {number} length Length of the string to generate.
* @return {string} The generated string.
*/
CatRename.prototype.randomString = function ( length ) {
var result = '';
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for ( var i = 0; i < length; ++i ) {
result += chars.charAt( Math.floor( Math.random() * chars.length ) );
}
return result;
};
instanceWindowManager = new OO.ui.WindowManager();
$( 'body' ).append( instanceWindowManager.$element );
instanceCatRename = new CatRename();
instanceWindowManager.addWindows( [ instanceCatRename ] );
}
} );
}
/* </nowiki> */
var navHeight = $('#esp-navbar ul').height();
var $nav = $('#esp-navbar');
$('#navbar-toggler').click(function(e) {
if (!$nav.hasClass('open')) {
$nav.css('height', navHeight + 'px');
} else {
$nav.css('height', '');
}
$nav.toggleClass('open');
});
$('.timeline-wrapper').on('mousedown touchstart', function (me) {
if ($(me.target).hasClass('timeline-desc')) return;
var move = $(this).find('ul');
var lastOffset = move.data('lastTransform');
var lastOffsetX = lastOffset ? lastOffset.dx : 0;
var pageX = me.originalEvent.touches ? me.originalEvent.touches[0].pageX : me.pageX;
var startX = pageX - lastOffsetX;
$(document).on('mousemove touchmove', function (e) {
var newX = e.originalEvent.touches ? e.originalEvent.touches[0].pageX : e.pageX;
var max = $(move).attr('data-maxtranslate');
if (max > 0) max = 0;
var newDx = Math.max(Math.min(0, newX - startX), max);
move.css('transform', 'translate(' + newDx + 'px)');
move.data('lastTransform', {
dx: newDx
});
});
});
$(document).on('mouseup touchend', function () {
$(this).off('mousemove touchmove');
});
$('.timeline-wrapper').each(function () {
var maxTranslate = ($(this).find('li').length * 200 - $(this).width()) * - 1;
$(this).find('ul').attr('data-maxTranslate', maxTranslate);
var desc = $('<div>', {
'class': 'timeline-desc'
});
$(this).append(desc);
$(this).find('.event').on('click touch', function () {
$('.event.active').removeClass('active');
$(this).addClass('active');
desc.html($(this).find('.description').html());
});
$(this).find('li:first-of-type .event').click();
});
