Compare commits
3 Commits
master
...
SABERES_31
Author | SHA1 | Date |
---|---|---|
Matheus Garcia | 1675a667f4 | 3 years ago |
Matheus Garcia | dac74b36b7 | 3 years ago |
Matheus Garcia | 079d14fcbb | 3 years ago |
@ -0,0 +1,2 @@ |
|||
define ("theme_ilb/aria",["exports","jquery","core/pending"],function(a,b,c){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.init=void 0;b=d(b);c=d(c);function d(a){return a&&a.__esModule?a:{default:a}}var e=function(){var a=!1,d=function(){a=!0},e=function(){var b=a;a=!1;return b};document.addEventListener("keydown",function(a){if(a.target.matches("[data-toggle=\"dropdown\"]")){var b=a.key;if("ArrowUp"==b){d()}if(" "==b||"Enter"==b){a.preventDefault();a.target.click()}}});var f=function(a){setTimeout(function delayedFocus(b){a.focus();b.resolve()},50,new c.default("core/aria:delayed-focus"))};(0,b.default)(".dropdown").on("shown.bs.dropdown",function(a){var b=a.target.querySelector("[role=\"menu\"]"),c=!1,d=!1;if(b){c=b.querySelectorAll("[role=\"menuitem\"]")}if(c&&0<c.length){if(e()){d=c[c.length-1]}else{d=c[0]}}if(d){f(d)}});document.addEventListener("keypress",function(a){if(a.target.matches(".dropdown [role=\"menu\"] [role=\"menuitem\"]")){var g=a.target.closest("[role=\"menu\"]");if(!g){return}var h=g.querySelectorAll("[role=\"menuitem\"]");if(!h){return}for(var b=a.key.toLowerCase(),c=0;c<h.length;c++){var d=h[c],e=d.text.trim().toLowerCase();if(0==e.indexOf(b)){f(d);break}}}});document.addEventListener("keydown",function(a){if(a.target.matches(".dropdown [role=\"menu\"] [role=\"menuitem\"]")){var b=a.key,c=!1,d=a.target.closest("[role=\"menu\"]");if(!d){return}var e=d.querySelectorAll("[role=\"menuitem\"]");if(!e){return}if("ArrowDown"==b){for(var g=0;g<e.length-1;g++){if(e[g]==a.target){c=e[g+1];break}}if(!c){c=e[0]}}else if("ArrowUp"==b){for(var h=1;h<e.length;h++){if(e[h]==a.target){c=e[h-1];break}}if(!c){c=e[e.length-1]}}else if("Home"==b){c=e[0]}else if("End"==b){c=e[e.length-1]}if(c){a.preventDefault();f(c)}}});(0,b.default)(".dropdown").on("hidden.bs.dropdown",function(a){var b=a.target.querySelector("[data-toggle=\"dropdown\"]");if(b){f(b)}})},f=function(){window.addEventListener("load",function(){var a=document.querySelectorAll("[data-aria-autofocus=\"true\"][role=\"alert\"]");Array.prototype.forEach.call(a,function(a){a.innerHTML+=" ";a.removeAttribute("data-aria-autofocus")})})},g=function(a){for(var c=a.target.closest("[role=\"tablist\"]"),d="vertical"==c.getAttribute("aria-orientation"),e=window.right_to_left(),f=d?"ArrowDown":e?"ArrowLeft":"ArrowRight",g=d?"ArrowUp":e?"ArrowRight":"ArrowLeft",h=Array.prototype.filter.call(c.querySelectorAll("[role=\"tab\"]"),function(a){return"none"!==getComputedStyle(a).display}),j=0;j<h.length;j++){h[j].index=j}switch(a.key){case f:a.preventDefault();if(a.target.index!==void 0&&h[a.target.index+1]){h[a.target.index+1].focus()}else{h[0].focus()}break;case g:a.preventDefault();if(a.target.index!==void 0&&h[a.target.index-1]){h[a.target.index-1].focus()}else{h[h.length-1].focus()}break;case"Home":a.preventDefault();h[0].focus();break;case"End":a.preventDefault();h[h.length-1].focus();break;case"Enter":case" ":a.preventDefault();(0,b.default)(a.target).tab("show");h.forEach(function(a){a.tabIndex=-1});a.target.tabIndex=0;}},h=function(){document.addEventListener("keydown",function(a){if(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight","Home","End","Enter"," "].includes(a.key)){if(a.target.matches("[role=\"tablist\"] [role=\"tab\"]")){g(a)}}});document.addEventListener("click",function(a){if(a.target.matches("[role=\"tablist\"] [role=\"tab\"]")){var c=a.target.closest("[role=\"tablist\"]").querySelectorAll("[role=\"tab\"]");a.preventDefault();(0,b.default)(a.target).tab("show");c.forEach(function(a){a.tabIndex=-1});a.target.tabIndex=0}})};a.init=function init(){e();f();h()}}); |
|||
//# sourceMappingURL=aria.min.js.map
|
@ -0,0 +1,2 @@ |
|||
define ("theme_ilb/bootstrap/alert",["exports","jquery","./util"],function(a,b,c){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;b=d(b);c=d(c);function d(a){return a&&a.__esModule?a:{default:a}}function e(a,b){if(!(a instanceof b)){throw new TypeError("Cannot call a class as a function")}}function f(a,b){for(var c=0,d;c<b.length;c++){d=b[c];d.enumerable=d.enumerable||!1;d.configurable=!0;if("value"in d)d.writable=!0;Object.defineProperty(a,d.key,d)}}function g(a,b,c){if(b)f(a.prototype,b);if(c)f(a,c);return a}var h="bs.alert",i=".".concat(h),j=b.default.fn.alert,k="close".concat(i),l="closed".concat(i),m="click".concat(i).concat(".data-api"),n=function(){function a(b){e(this,a);this._element=b}g(a,[{key:"close",value:function close(a){var b=this._element;if(a){b=this._getRootElement(a)}var c=this._triggerCloseEvent(b);if(c.isDefaultPrevented()){return}this._removeElement(b)}},{key:"dispose",value:function dispose(){b.default.removeData(this._element,h);this._element=null}},{key:"_getRootElement",value:function _getRootElement(a){var d=c.default.getSelectorFromElement(a),e=!1;if(d){e=document.querySelector(d)}if(!e){e=(0,b.default)(a).closest(".".concat("alert"))[0]}return e}},{key:"_triggerCloseEvent",value:function _triggerCloseEvent(a){var c=b.default.Event(k);(0,b.default)(a).trigger(c);return c}},{key:"_removeElement",value:function _removeElement(a){var d=this;(0,b.default)(a).removeClass("show");if(!(0,b.default)(a).hasClass("fade")){this._destroyElement(a);return}var e=c.default.getTransitionDurationFromElement(a);(0,b.default)(a).one(c.default.TRANSITION_END,function(b){return d._destroyElement(a,b)}).emulateTransitionEnd(e)}},{key:"_destroyElement",value:function _destroyElement(a){(0,b.default)(a).detach().trigger(l).remove()}}],[{key:"_jQueryInterface",value:function _jQueryInterface(c){return this.each(function(){var d=(0,b.default)(this),e=d.data(h);if(!e){e=new a(this);d.data(h,e)}if("close"===c){e[c](this)}})}},{key:"_handleDismiss",value:function _handleDismiss(a){return function(b){if(b){b.preventDefault()}a.close(this)}}},{key:"VERSION",get:function get(){return"4.6.0"}}]);return a}();(0,b.default)(document).on(m,"[data-dismiss=\"alert\"]",n._handleDismiss(new n));b.default.fn.alert=n._jQueryInterface;b.default.fn.alert.Constructor=n;b.default.fn.alert.noConflict=function(){b.default.fn.alert=j;return n._jQueryInterface};a.default=n;return a.default}); |
|||
//# sourceMappingURL=alert.min.js.map
|
@ -0,0 +1,2 @@ |
|||
define ("theme_ilb/bootstrap/button",["exports","jquery"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;b=function(a){return a&&a.__esModule?a:{default:a}}(b);function c(a,b){if(!(a instanceof b)){throw new TypeError("Cannot call a class as a function")}}function d(a,b){for(var c=0,d;c<b.length;c++){d=b[c];d.enumerable=d.enumerable||!1;d.configurable=!0;if("value"in d)d.writable=!0;Object.defineProperty(a,d.key,d)}}function e(a,b,c){if(b)d(a.prototype,b);if(c)d(a,c);return a}var f="bs.button",g=".".concat(f),h=".data-api",i=b.default.fn.button,j="active",k="[data-toggle^=\"button\"]",l="input:not([type=\"hidden\"])",m=".btn",n="click".concat(g).concat(h),o="focus".concat(g).concat(h," ")+"blur".concat(g).concat(h),p="load".concat(g).concat(h),q=function(){function a(b){c(this,a);this._element=b;this.shouldAvoidTriggerChange=!1}e(a,[{key:"toggle",value:function toggle(){var a=!0,c=!0,d=(0,b.default)(this._element).closest("[data-toggle=\"buttons\"]")[0];if(d){var e=this._element.querySelector(l);if(e){if("radio"===e.type){if(e.checked&&this._element.classList.contains(j)){a=!1}else{var f=d.querySelector(".active");if(f){(0,b.default)(f).removeClass(j)}}}if(a){if("checkbox"===e.type||"radio"===e.type){e.checked=!this._element.classList.contains(j)}if(!this.shouldAvoidTriggerChange){(0,b.default)(e).trigger("change")}}e.focus();c=!1}}if(!(this._element.hasAttribute("disabled")||this._element.classList.contains("disabled"))){if(c){this._element.setAttribute("aria-pressed",!this._element.classList.contains(j))}if(a){(0,b.default)(this._element).toggleClass(j)}}}},{key:"dispose",value:function dispose(){b.default.removeData(this._element,f);this._element=null}}],[{key:"_jQueryInterface",value:function _jQueryInterface(c,d){return this.each(function(){var e=(0,b.default)(this),g=e.data(f);if(!g){g=new a(this);e.data(f,g)}g.shouldAvoidTriggerChange=d;if("toggle"===c){g[c]()}})}},{key:"VERSION",get:function get(){return"4.6.0"}}]);return a}();(0,b.default)(document).on(n,k,function(a){var c=a.target,d=c;if(!(0,b.default)(c).hasClass("btn")){c=(0,b.default)(c).closest(m)[0]}if(!c||c.hasAttribute("disabled")||c.classList.contains("disabled")){a.preventDefault()}else{var e=c.querySelector(l);if(e&&(e.hasAttribute("disabled")||e.classList.contains("disabled"))){a.preventDefault();return}if("INPUT"===d.tagName||"LABEL"!==c.tagName){q._jQueryInterface.call((0,b.default)(c),"toggle","INPUT"===d.tagName)}}}).on(o,k,function(a){var c=(0,b.default)(a.target).closest(m)[0];(0,b.default)(c).toggleClass("focus",/^focus(in)?$/.test(a.type))});(0,b.default)(window).on(p,function(){for(var a=[].slice.call(document.querySelectorAll("[data-toggle=\"buttons\"] .btn")),b=0,c=a.length;b<c;b++){var d=a[b],e=d.querySelector(l);if(e.checked||e.hasAttribute("checked")){d.classList.add(j)}else{d.classList.remove(j)}}a=[].slice.call(document.querySelectorAll("[data-toggle=\"button\"]"));for(var f=0,g=a.length,h;f<g;f++){h=a[f];if("true"===h.getAttribute("aria-pressed")){h.classList.add(j)}else{h.classList.remove(j)}}});b.default.fn.button=q._jQueryInterface;b.default.fn.button.Constructor=q;b.default.fn.button.noConflict=function(){b.default.fn.button=i;return q._jQueryInterface};a.default=q;return a.default}); |
|||
//# sourceMappingURL=button.min.js.map
|
@ -0,0 +1,2 @@ |
|||
define ("theme_ilb/bootstrap/tab",["exports","jquery","./util"],function(a,b,c){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;b=d(b);c=d(c);function d(a){return a&&a.__esModule?a:{default:a}}function e(a,b){if(!(a instanceof b)){throw new TypeError("Cannot call a class as a function")}}function f(a,b){for(var c=0,d;c<b.length;c++){d=b[c];d.enumerable=d.enumerable||!1;d.configurable=!0;if("value"in d)d.writable=!0;Object.defineProperty(a,d.key,d)}}function g(a,b,c){if(b)f(a.prototype,b);if(c)f(a,c);return a}var h="bs.tab",i=".".concat(h),j=b.default.fn.tab,k="hide".concat(i),l="hidden".concat(i),m="show".concat(i),n="shown".concat(i),o="click".concat(i).concat(".data-api"),p="active",q="fade",r="show",s=".active",t="> li > .active",u=function(){function a(b){e(this,a);this._element=b}g(a,[{key:"show",value:function show(){var a=this;if(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&(0,b.default)(this._element).hasClass(p)||(0,b.default)(this._element).hasClass("disabled")){return}var d,e,f=(0,b.default)(this._element).closest(".nav, .list-group")[0],g=c.default.getSelectorFromElement(this._element);if(f){var o="UL"===f.nodeName||"OL"===f.nodeName?t:s;e=b.default.makeArray((0,b.default)(f).find(o));e=e[e.length-1]}var h=b.default.Event(k,{relatedTarget:this._element}),i=b.default.Event(m,{relatedTarget:e});if(e){(0,b.default)(e).trigger(h)}(0,b.default)(this._element).trigger(i);if(i.isDefaultPrevented()||h.isDefaultPrevented()){return}if(g){d=document.querySelector(g)}this._activate(this._element,f);var j=function(){var c=b.default.Event(l,{relatedTarget:a._element}),d=b.default.Event(n,{relatedTarget:e});(0,b.default)(e).trigger(c);(0,b.default)(a._element).trigger(d)};if(d){this._activate(d,d.parentNode,j)}else{j()}}},{key:"dispose",value:function dispose(){b.default.removeData(this._element,h);this._element=null}},{key:"_activate",value:function _activate(a,d,e){var f=this,g=d&&("UL"===d.nodeName||"OL"===d.nodeName)?(0,b.default)(d).find(t):(0,b.default)(d).children(s),h=g[0],i=e&&h&&(0,b.default)(h).hasClass(q),j=function(){return f._transitionComplete(a,h,e)};if(h&&i){var k=c.default.getTransitionDurationFromElement(h);(0,b.default)(h).removeClass(r).one(c.default.TRANSITION_END,j).emulateTransitionEnd(k)}else{j()}}},{key:"_transitionComplete",value:function _transitionComplete(a,d,e){if(d){(0,b.default)(d).removeClass(p);var f=(0,b.default)(d.parentNode).find("> .dropdown-menu .active")[0];if(f){(0,b.default)(f).removeClass(p)}if("tab"===d.getAttribute("role")){d.setAttribute("aria-selected",!1)}}(0,b.default)(a).addClass(p);if("tab"===a.getAttribute("role")){a.setAttribute("aria-selected",!0)}c.default.reflow(a);if(a.classList.contains(q)){a.classList.add(r)}if(a.parentNode&&(0,b.default)(a.parentNode).hasClass("dropdown-menu")){var g=(0,b.default)(a).closest(".dropdown")[0];if(g){var h=[].slice.call(g.querySelectorAll(".dropdown-toggle"));(0,b.default)(h).addClass(p)}a.setAttribute("aria-expanded",!0)}if(e){e()}}}],[{key:"_jQueryInterface",value:function _jQueryInterface(c){return this.each(function(){var d=(0,b.default)(this),e=d.data(h);if(!e){e=new a(this);d.data(h,e)}if("string"==typeof c){if("undefined"==typeof e[c]){throw new TypeError("No method named \"".concat(c,"\""))}e[c]()}})}},{key:"VERSION",get:function get(){return"4.6.0"}}]);return a}();(0,b.default)(document).on(o,"[data-toggle=\"tab\"], [data-toggle=\"pill\"], [data-toggle=\"list\"]",function(a){a.preventDefault();u._jQueryInterface.call((0,b.default)(this),"show")});b.default.fn.tab=u._jQueryInterface;b.default.fn.tab.Constructor=u;b.default.fn.tab.noConflict=function(){b.default.fn.tab=j;return u._jQueryInterface};a.default=u;return a.default}); |
|||
//# sourceMappingURL=tab.min.js.map
|
@ -0,0 +1,2 @@ |
|||
define ("theme_ilb/bootstrap/toast",["exports","jquery","./util"],function(a,b,c){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;b=d(b);c=d(c);function d(a){return a&&a.__esModule?a:{default:a}}function e(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){e=function(a){return typeof a}}else{e=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return e(a)}function f(a,b){var c=Object.keys(a);if(Object.getOwnPropertySymbols){var d=Object.getOwnPropertySymbols(a);if(b)d=d.filter(function(b){return Object.getOwnPropertyDescriptor(a,b).enumerable});c.push.apply(c,d)}return c}function g(a){for(var b=1,c;b<arguments.length;b++){c=null!=arguments[b]?arguments[b]:{};if(b%2){f(Object(c),!0).forEach(function(b){h(a,b,c[b])})}else if(Object.getOwnPropertyDescriptors){Object.defineProperties(a,Object.getOwnPropertyDescriptors(c))}else{f(Object(c)).forEach(function(b){Object.defineProperty(a,b,Object.getOwnPropertyDescriptor(c,b))})}}return a}function h(a,b,c){if(b in a){Object.defineProperty(a,b,{value:c,enumerable:!0,configurable:!0,writable:!0})}else{a[b]=c}return a}function i(a,b){if(!(a instanceof b)){throw new TypeError("Cannot call a class as a function")}}function j(a,b){for(var c=0,d;c<b.length;c++){d=b[c];d.enumerable=d.enumerable||!1;d.configurable=!0;if("value"in d)d.writable=!0;Object.defineProperty(a,d.key,d)}}function k(a,b,c){if(b)j(a.prototype,b);if(c)j(a,c);return a}var l="bs.toast",m=".".concat(l),n=b.default.fn.toast,o="click.dismiss".concat(m),p="hide".concat(m),q="hidden".concat(m),r="show".concat(m),s="shown".concat(m),t="hide",u="show",v="showing",w={animation:"boolean",autohide:"boolean",delay:"number"},x={animation:!0,autohide:!0,delay:500},y=function(){function a(b,c){i(this,a);this._element=b;this._config=this._getConfig(c);this._timeout=null;this._setListeners()}k(a,[{key:"show",value:function show(){var a=this,d=b.default.Event(r);(0,b.default)(this._element).trigger(d);if(d.isDefaultPrevented()){return}this._clearTimeout();if(this._config.animation){this._element.classList.add("fade")}var e=function(){a._element.classList.remove(v);a._element.classList.add(u);(0,b.default)(a._element).trigger(s);if(a._config.autohide){a._timeout=setTimeout(function(){a.hide()},a._config.delay)}};this._element.classList.remove(t);c.default.reflow(this._element);this._element.classList.add(v);if(this._config.animation){var f=c.default.getTransitionDurationFromElement(this._element);(0,b.default)(this._element).one(c.default.TRANSITION_END,e).emulateTransitionEnd(f)}else{e()}}},{key:"hide",value:function hide(){if(!this._element.classList.contains(u)){return}var a=b.default.Event(p);(0,b.default)(this._element).trigger(a);if(a.isDefaultPrevented()){return}this._close()}},{key:"dispose",value:function dispose(){this._clearTimeout();if(this._element.classList.contains(u)){this._element.classList.remove(u)}(0,b.default)(this._element).off(o);b.default.removeData(this._element,l);this._element=null;this._config=null}},{key:"_getConfig",value:function _getConfig(a){a=g({},x,{},(0,b.default)(this._element).data(),{},"object"===e(a)&&a?a:{});c.default.typeCheckConfig("toast",a,this.constructor.DefaultType);return a}},{key:"_setListeners",value:function _setListeners(){var a=this;(0,b.default)(this._element).on(o,"[data-dismiss=\"toast\"]",function(){return a.hide()})}},{key:"_close",value:function _close(){var a=this,d=function(){a._element.classList.add(t);(0,b.default)(a._element).trigger(q)};this._element.classList.remove(u);if(this._config.animation){var e=c.default.getTransitionDurationFromElement(this._element);(0,b.default)(this._element).one(c.default.TRANSITION_END,d).emulateTransitionEnd(e)}else{d()}}},{key:"_clearTimeout",value:function _clearTimeout(){clearTimeout(this._timeout);this._timeout=null}}],[{key:"_jQueryInterface",value:function _jQueryInterface(c){return this.each(function(){var d=(0,b.default)(this),f=d.data(l),g="object"===e(c)&&c;if(!f){f=new a(this,g);d.data(l,f)}if("string"==typeof c){if("undefined"==typeof f[c]){throw new TypeError("No method named \"".concat(c,"\""))}f[c](this)}})}},{key:"VERSION",get:function get(){return"4.6.0"}},{key:"DefaultType",get:function get(){return w}},{key:"Default",get:function get(){return x}}]);return a}();b.default.fn.toast=y._jQueryInterface;b.default.fn.toast.Constructor=y;b.default.fn.toast.noConflict=function(){b.default.fn.toast=n;return y._jQueryInterface};a.default=y;return a.default}); |
|||
//# sourceMappingURL=toast.min.js.map
|
@ -0,0 +1,2 @@ |
|||
define ("theme_ilb/bootstrap/tools/sanitizer",["exports"],function(a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.sanitizeHtml=function(a,c,d){if(0===a.length){return a}if(d&&"function"==typeof d){return d(a)}for(var e=new window.DOMParser,f=e.parseFromString(a,"text/html"),g=Object.keys(c),h=[].slice.call(f.body.querySelectorAll("*")),j=function(a){var d=h[a],e=d.nodeName.toLowerCase();if(-1===g.indexOf(d.nodeName.toLowerCase())){d.parentNode.removeChild(d);return"continue"}var f=[].slice.call(d.attributes),i=[].concat(c["*"]||[],c[e]||[]);f.forEach(function(a){if(!b(a,i)){d.removeAttribute(a.nodeName)}})},k=0,l=h.length,m;k<l;k++){m=j(k,l);if("continue"===m)continue}return f.body.innerHTML};a.DefaultWhitelist=void 0;var c=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"];a.DefaultWhitelist={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],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:[]};function b(a,b){var d=a.nodeName.toLowerCase();if(-1!==b.indexOf(d)){if(-1!==c.indexOf(d)){return!!(a.nodeValue.match(/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi)||a.nodeValue.match(/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i))}return!0}for(var e=b.filter(function(a){return a instanceof RegExp}),f=0,g=e.length;f<g;f++){if(d.match(e[f])){return!0}}return!1}}); |
|||
//# sourceMappingURL=sanitizer.min.js.map
|
@ -0,0 +1,2 @@ |
|||
define ("theme_ilb/bootstrap/util",["exports","jquery"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;b=function(a){return a&&a.__esModule?a:{default:a}}(b);function c(a){if(null===a||"undefined"==typeof a){return"".concat(a)}return{}.toString.call(a).match(/\s([a-z]+)/i)[1].toLowerCase()}function d(){return{bindType:"transitionend",delegateType:"transitionend",handle:function handle(a){if((0,b.default)(a.target).is(this)){return a.handleObj.handler.apply(this,arguments)}}}}function e(a){var c=this,d=!1;(0,b.default)(this).one(g.TRANSITION_END,function(){d=!0});setTimeout(function(){if(!d){g.triggerTransitionEnd(c)}},a);return this}function f(){b.default.fn.emulateTransitionEnd=e;b.default.event.special[g.TRANSITION_END]=d()}var g={TRANSITION_END:"bsTransitionEnd",getUID:function getUID(a){do{a+=~~(Math.random()*1e6)}while(document.getElementById(a));return a},getSelectorFromElement:function getSelectorFromElement(a){var b=a.getAttribute("data-target");if(!b||"#"===b){var c=a.getAttribute("href");b=c&&"#"!==c?c.trim():""}try{return document.querySelector(b)?b:null}catch(a){return null}},getTransitionDurationFromElement:function getTransitionDurationFromElement(a){if(!a){return 0}var c=(0,b.default)(a).css("transition-duration"),d=(0,b.default)(a).css("transition-delay"),e=parseFloat(c),f=parseFloat(d);if(!e&&!f){return 0}c=c.split(",")[0];d=d.split(",")[0];return(parseFloat(c)+parseFloat(d))*1e3},reflow:function reflow(a){return a.offsetHeight},triggerTransitionEnd:function triggerTransitionEnd(a){(0,b.default)(a).trigger("transitionend")},supportsTransitionEnd:function supportsTransitionEnd(){return!0},isElement:function isElement(a){return(a[0]||a).nodeType},typeCheckConfig:function typeCheckConfig(a,b,d){for(var i in d){if(Object.prototype.hasOwnProperty.call(d,i)){var e=d[i],f=b[i],h=f&&g.isElement(f)?"element":c(f);if(!new RegExp(e).test(h)){throw new Error("".concat(a.toUpperCase(),": ")+"Option \"".concat(i,"\" provided type \"").concat(h,"\" ")+"but expected type \"".concat(e,"\"."))}}}},findShadowRoot:function findShadowRoot(a){if(!document.documentElement.attachShadow){return null}if("function"==typeof a.getRootNode){var b=a.getRootNode();return b instanceof ShadowRoot?b:null}if(a instanceof ShadowRoot){return a}if(!a.parentNode){return null}return g.findShadowRoot(a.parentNode)},jQueryDetection:function jQueryDetection(){if("undefined"==typeof b.default){throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.")}var a=b.default.fn.jquery.split(" ")[0].split("."),c=9;if(a[0]<2&&a[1]<c||a[0]===1&&a[1]===c&&a[2]<1||a[0]>=4){throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}}};g.jQueryDetection();f();a.default=g;return a.default}); |
|||
//# sourceMappingURL=util.min.js.map
|
@ -0,0 +1,2 @@ |
|||
define ("theme_ilb/drawer",["jquery","core/custom_interaction_events","core/log","core/pubsub","core/aria"],function(a,b,c,d,e){var f={TOGGLE_REGION:"[data-region=\"drawer-toggle\"]",TOGGLE_ACTION:"[data-action=\"toggle-drawer\"]",TOGGLE_TARGET:"aria-controls",TOGGLE_SIDE:"left",BODY:"body",SECTION:".list-group-item[href*=\"#section-\"]",DRAWER:"#nav-drawer"},g=768>a(document).width(),h=function(){if(!a(f.TOGGLE_REGION).length){c.debug("Page is missing a drawer region")}if(!a(f.TOGGLE_ACTION).length){c.debug("Page is missing a drawer toggle link")}a(f.TOGGLE_REGION).each(function(b,c){var d=a(c).find(f.TOGGLE_ACTION),e=d.attr("aria-controls"),h=a(document.getElementById(e)),i="false"==d.attr("aria-expanded"),j=d.attr("data-side"),k=a(f.BODY),l=d.attr("data-preference");if(g){M.util.set_user_preference(l,"false")}h.on("mousewheel DOMMouseScroll",this.preventPageScroll);if(!i){k.addClass("drawer-open-"+j);d.attr("aria-expanded","true")}else{d.attr("aria-expanded","false")}}.bind(this));this.registerEventListeners();if(g){this.closeAll()}};h.prototype.closeAll=function(){a(f.TOGGLE_REGION).each(function(b,c){var d=a(c).find(f.TOGGLE_ACTION),h=d.attr("data-side"),i=a(f.BODY),j=d.attr("aria-controls"),k=a(document.getElementById(j)),l=d.attr("data-preference");d.attr("aria-expanded","false");i.removeClass("drawer-open-"+h);e.hide(k.get());k.addClass("closed");if(!g){M.util.set_user_preference(l,"false")}})};h.prototype.toggleDrawer=function(b){var c=a(b.target).closest("[data-action=toggle-drawer]"),h=c.attr("aria-controls"),i=a(document.getElementById(h)),j=a(f.BODY),k=c.attr("data-side"),l=c.attr("data-preference");if(g){M.util.set_user_preference(l,"false")}j.addClass("drawer-ease");var m="true"==c.attr("aria-expanded");if(!m){c.attr("aria-expanded","true");e.unhide(i.get());i.focus();j.addClass("drawer-open-"+k);i.removeClass("closed");if(!g){M.util.set_user_preference(l,"true")}}else{j.removeClass("drawer-open-"+k);c.attr("aria-expanded","false");i.addClass("closed").delay(500).queue(function(){if(a(this).hasClass("closed")){e.hide(this)}a(this).dequeue()});if(!g){M.util.set_user_preference(l,"false")}}d.publish("nav-drawer-toggle-start",m)};h.prototype.preventPageScroll=function(b){var c=b.wheelDelta||b.originalEvent&&b.originalEvent.wheelDelta||-b.originalEvent.detail,d=0<=this.scrollTop+a(this).outerHeight()-this.scrollHeight,e=0>=this.scrollTop;if(0>c&&d||0<c&&e){b.preventDefault()}};h.prototype.registerEventListeners=function(){a(f.TOGGLE_ACTION).each(function(c,d){b.define(a(d),[b.events.activate]);a(d).on(b.events.activate,function(a,b){this.toggleDrawer(b.originalEvent);b.originalEvent.preventDefault()}.bind(this))}.bind(this));a(f.SECTION).click(function(){if(g){this.closeAll()}}.bind(this));a(f.DRAWER).on("webkitTransitionEnd msTransitionEnd transitionend",function(b){var c=a(b.target).closest(f.DRAWER),e=!!c.attr("aria-hidden");d.publish("nav-drawer-toggle-end",e)})};return{init:function init(){return new h}}}); |
|||
//# sourceMappingURL=drawer.min.js.map
|
@ -0,0 +1,2 @@ |
|||
define ("theme_ilb/form-display-errors",["jquery","core/event"],function(a,b){return{enhance:function enhance(c){var d=document.getElementById(c);if(!d){return}a(d).on(b.Events.FORM_FIELD_VALIDATION,function(b,c){b.preventDefault();var e=a(d).closest(".form-group"),f=e.find(".form-control-feedback"),g=f.attr("id"),h=a(d).attr("aria-describedby");if("undefined"==typeof h){h=""}var i=[];if(h.length){i=h.split(" ")}var j=i.indexOf(g);if("TEXTAREA"==a(d).prop("tagName")&&e.find("[contenteditable]")){d=e.find("[contenteditable]")}if(""!==c){e.addClass("has-danger");e.data("client-validation-error",!0);a(d).addClass("is-invalid");if(-1===j){i.push(g);a(d).attr("aria-describedby",i.join(" "))}a(d).attr("aria-invalid",!0);f.attr("tabindex",0);f.html(c);if(!f.is(":visible")){f.show();f.focus()}}else{if(!0===e.data("client-validation-error")){e.removeClass("has-danger");e.data("client-validation-error",!1);a(d).removeClass("is-invalid");if(-1<j){i.splice(j,1)}if(i.length){h=i.join(" ");a(d).attr("aria-describedby",h)}else{a(d).removeAttr("aria-describedby")}a(d).attr("aria-invalid",!1);f.hide()}}});var e=d.closest("form");if(e&&!("ilbFormErrorsEnhanced"in e.dataset)){e.addEventListener("submit",function(){var b=a(".form-control-feedback:visible");if(b.length){b[0].focus()}});e.dataset.ilbFormErrorsEnhanced=1}}}}); |
|||
//# sourceMappingURL=form-display-errors.min.js.map
|
@ -0,0 +1,2 @@ |
|||
define ("theme_ilb/index",["exports","./bootstrap/alert","./bootstrap/button","./bootstrap/carousel","./bootstrap/collapse","./bootstrap/dropdown","./bootstrap/modal","./bootstrap/popover","./bootstrap/scrollspy","./bootstrap/tab","./bootstrap/toast","./bootstrap/tooltip","./bootstrap/util"],function(a,b,c,d,e,f,g,h,i,j,k,l,m){"use strict";Object.defineProperty(a,"__esModule",{value:!0});Object.defineProperty(a,"Alert",{enumerable:!0,get:function get(){return b.default}});Object.defineProperty(a,"Button",{enumerable:!0,get:function get(){return c.default}});Object.defineProperty(a,"Carousel",{enumerable:!0,get:function get(){return d.default}});Object.defineProperty(a,"Collapse",{enumerable:!0,get:function get(){return e.default}});Object.defineProperty(a,"Dropdown",{enumerable:!0,get:function get(){return f.default}});Object.defineProperty(a,"Modal",{enumerable:!0,get:function get(){return g.default}});Object.defineProperty(a,"Popover",{enumerable:!0,get:function get(){return h.default}});Object.defineProperty(a,"Scrollspy",{enumerable:!0,get:function get(){return i.default}});Object.defineProperty(a,"Tab",{enumerable:!0,get:function get(){return j.default}});Object.defineProperty(a,"Toast",{enumerable:!0,get:function get(){return k.default}});Object.defineProperty(a,"Tooltip",{enumerable:!0,get:function get(){return l.default}});Object.defineProperty(a,"Util",{enumerable:!0,get:function get(){return m.default}});b=n(b);c=n(c);d=n(d);e=n(e);f=n(f);g=n(g);h=n(h);i=n(i);j=n(j);k=n(k);l=n(l);m=n(m);function n(a){return a&&a.__esModule?a:{default:a}}}); |
|||
//# sourceMappingURL=index.min.js.map
|
@ -0,0 +1 @@ |
|||
{"version":3,"sources":["../src/index.js"],"names":[],"mappings":"g6CAOA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,O","sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap (v4.6.0): index.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport Alert from './bootstrap/alert';\nimport Button from './bootstrap/button';\nimport Carousel from './bootstrap/carousel';\nimport Collapse from './bootstrap/collapse';\nimport Dropdown from './bootstrap/dropdown';\nimport Modal from './bootstrap/modal';\nimport Popover from './bootstrap/popover';\nimport Scrollspy from './bootstrap/scrollspy';\nimport Tab from './bootstrap/tab';\nimport Toast from './bootstrap/toast';\nimport Tooltip from './bootstrap/tooltip';\nimport Util from './bootstrap/util';\n\nexport {\n Util,\n Alert,\n Button,\n Carousel,\n Collapse,\n Dropdown,\n Modal,\n Popover,\n Scrollspy,\n Tab,\n Toast,\n Tooltip\n};\n"],"file":"index.min.js"} |
@ -0,0 +1,2 @@ |
|||
function _typeof(a){"@babel/helpers - typeof";if("function"==typeof Symbol&&"symbol"==typeof Symbol.iterator){_typeof=function(a){return typeof a}}else{_typeof=function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a}}return _typeof(a)}define ("theme_ilb/loader",["exports","jquery","./aria","./index","core/pending","./scroll","./pending"],function(a,b,c,d,e,f,g){"use strict";Object.defineProperty(a,"__esModule",{value:!0});Object.defineProperty(a,"Bootstrap",{enumerable:!0,get:function get(){return d.default}});b=j(b);c=i(c);d=j(d);e=j(e);f=j(f);g=j(g);function h(){if("function"!=typeof WeakMap)return null;var a=new WeakMap;h=function(){return a};return a}function i(a){if(a&&a.__esModule){return a}if(null===a||"object"!==_typeof(a)&&"function"!=typeof a){return{default:a}}var b=h();if(b&&b.has(a)){return b.get(a)}var c={},d=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var e in a){if(Object.prototype.hasOwnProperty.call(a,e)){var f=d?Object.getOwnPropertyDescriptor(a,e):null;if(f&&(f.get||f.set)){Object.defineProperty(c,e,f)}else{c[e]=a[e]}}}c.default=a;if(b){b.set(a,c)}return c}function j(a){return a&&a.__esModule?a:{default:a}}var k=function(){(0,b.default)("a[data-toggle=\"tab\"]").on("shown.bs.tab",function(a){var c=(0,b.default)(a.target).attr("href");if(history.replaceState){history.replaceState(null,null,c)}else{location.hash=c}});var a=window.location.hash;if(a){var c=document.querySelector(".nav-link[href=\""+a+"\"]");if(c){c.click()}}},l=function(){(0,b.default)("body").popover({container:"body",selector:"[data-toggle=\"popover\"]",trigger:"focus"});document.addEventListener("keydown",function(a){if("Escape"===a.key&&a.target.closest("[data-toggle=\"popover\"]")){(0,b.default)(a.target).popover("hide")}})},m=function(){(0,b.default)("body").tooltip({container:"body",selector:"[data-toggle=\"tooltip\"]"})},n=new e.default("theme_ilb/loader:init");(0,g.default)();c.init();k();l();m();new f.default().init();b.default.fn.dropdown.Constructor.Default.flip=!1;n.resolve()}); |
|||
//# sourceMappingURL=loader.min.js.map
|
@ -0,0 +1 @@ |
|||
{"version":3,"sources":["../src/loader.js"],"names":["rememberTabs","on","e","hash","target","attr","history","replaceState","location","window","tab","document","querySelector","click","enablePopovers","popover","container","selector","trigger","addEventListener","key","closest","enableTooltips","tooltip","pendingPromise","Pending","Aria","init","Scroll","$","fn","dropdown","Constructor","Default","flip","resolve"],"mappings":"8jBAwBA,OACA,OACA,OACA,OACA,OACA,O,4lBAKMA,CAAAA,CAAY,CAAG,UAAM,CACvB,cAAE,wBAAF,EAA0BC,EAA1B,CAA6B,cAA7B,CAA6C,SAASC,CAAT,CAAY,CACrD,GAAIC,CAAAA,CAAI,CAAG,cAAED,CAAC,CAACE,MAAJ,EAAYC,IAAZ,CAAiB,MAAjB,CAAX,CACA,GAAIC,OAAO,CAACC,YAAZ,CAA0B,CACtBD,OAAO,CAACC,YAAR,CAAqB,IAArB,CAA2B,IAA3B,CAAiCJ,CAAjC,CACH,CAFD,IAEO,CACHK,QAAQ,CAACL,IAAT,CAAgBA,CACnB,CACJ,CAPD,EAQA,GAAMA,CAAAA,CAAI,CAAGM,MAAM,CAACD,QAAP,CAAgBL,IAA7B,CACA,GAAIA,CAAJ,CAAU,CACN,GAAMO,CAAAA,CAAG,CAAGC,QAAQ,CAACC,aAAT,CAAuB,oBAAqBT,CAArB,CAA4B,KAAnD,CAAZ,CACA,GAAIO,CAAJ,CAAS,CACLA,CAAG,CAACG,KAAJ,EACH,CACJ,CACJ,C,CAMKC,CAAc,CAAG,UAAM,CACzB,cAAE,MAAF,EAAUC,OAAV,CAAkB,CACdC,SAAS,CAAE,MADG,CAEdC,QAAQ,CAAE,2BAFI,CAGdC,OAAO,CAAE,OAHK,CAAlB,EAMAP,QAAQ,CAACQ,gBAAT,CAA0B,SAA1B,CAAqC,SAAAjB,CAAC,CAAI,CACtC,GAAc,QAAV,GAAAA,CAAC,CAACkB,GAAF,EAAsBlB,CAAC,CAACE,MAAF,CAASiB,OAAT,CAAiB,2BAAjB,CAA1B,CAAuE,CACnE,cAAEnB,CAAC,CAACE,MAAJ,EAAYW,OAAZ,CAAoB,MAApB,CACH,CACJ,CAJD,CAKH,C,CAMKO,CAAc,CAAG,UAAM,CACzB,cAAE,MAAF,EAAUC,OAAV,CAAkB,CACdP,SAAS,CAAE,MADG,CAEdC,QAAQ,CAAE,2BAFI,CAAlB,CAIH,C,CAEKO,CAAc,CAAG,GAAIC,UAAJ,CAAY,yBAAZ,C,CAGvB,gBAGAC,CAAI,CAACC,IAAL,GAGA3B,CAAY,GAGZc,CAAc,GAGdQ,CAAc,GAGb,GAAIM,UAAJ,EAAD,CAAeD,IAAf,GAGAE,UAAEC,EAAF,CAAKC,QAAL,CAAcC,WAAd,CAA0BC,OAA1B,CAAkCC,IAAlC,IAEAV,CAAc,CAACW,OAAf,E","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Template renderer for Moodle. Load and render Moodle templates with Mustache.\n *\n * @module theme_ilb/loader\n * @copyright 2015 Damyon Wiese <damyon@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 2.9\n */\n\nimport $ from 'jquery';\nimport * as Aria from './aria';\nimport Bootstrap from './index';\nimport Pending from 'core/pending';\nimport Scroll from './scroll';\nimport setupBootstrapPendingChecks from './pending';\n\n/**\n * Rember the last visited tabs.\n */\nconst rememberTabs = () => {\n $('a[data-toggle=\"tab\"]').on('shown.bs.tab', function(e) {\n var hash = $(e.target).attr('href');\n if (history.replaceState) {\n history.replaceState(null, null, hash);\n } else {\n location.hash = hash;\n }\n });\n const hash = window.location.hash;\n if (hash) {\n const tab = document.querySelector('.nav-link[href=\"' + hash + '\"]');\n if (tab) {\n tab.click();\n }\n }\n};\n\n/**\n * Enable all popovers\n *\n */\nconst enablePopovers = () => {\n $('body').popover({\n container: 'body',\n selector: '[data-toggle=\"popover\"]',\n trigger: 'focus',\n });\n\n document.addEventListener('keydown', e => {\n if (e.key === 'Escape' && e.target.closest('[data-toggle=\"popover\"]')) {\n $(e.target).popover('hide');\n }\n });\n};\n\n/**\n * Enable tooltips\n *\n */\nconst enableTooltips = () => {\n $('body').tooltip({\n container: 'body',\n selector: '[data-toggle=\"tooltip\"]',\n });\n};\n\nconst pendingPromise = new Pending('theme_ilb/loader:init');\n\n// Add pending promise event listeners to relevant Bootstrap custom events.\nsetupBootstrapPendingChecks();\n\n// Setup Aria helpers for Bootstrap features.\nAria.init();\n\n// Remember the last visited tabs.\nrememberTabs();\n\n// Enable all popovers.\nenablePopovers();\n\n// Enable all tooltips.\nenableTooltips();\n\n// Add scroll handling.\n(new Scroll()).init();\n\n// Disables flipping the dropdowns up and getting hidden behind the navbar.\n$.fn.dropdown.Constructor.Default.flip = false;\n\npendingPromise.resolve();\n\nexport {\n Bootstrap,\n};\n"],"file":"loader.min.js"} |
@ -0,0 +1,2 @@ |
|||
define ("theme_ilb/pending",["exports","jquery"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;b=function(a){return a&&a.__esModule?a:{default:a}}(b);function c(a,b){return h(a)||g(a,b)||e(a,b)||d()}function d(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function e(a,b){if(!a)return;if("string"==typeof a)return f(a,b);var c=Object.prototype.toString.call(a).slice(8,-1);if("Object"===c&&a.constructor)c=a.constructor.name;if("Map"===c||"Set"===c)return Array.from(c);if("Arguments"===c||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c))return f(a,b)}function f(a,b){if(null==b||b>a.length)b=a.length;for(var c=0,d=Array(b);c<b;c++){d[c]=a[c]}return d}function g(a,b){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(a)))return;var c=[],d=!0,e=!1,f=void 0;try{for(var g=a[Symbol.iterator](),h;!(d=(h=g.next()).done);d=!0){c.push(h.value);if(b&&c.length===b)break}}catch(a){e=!0;f=a}finally{try{if(!d&&null!=g["return"])g["return"]()}finally{if(e)throw f}}return c}function h(a){if(Array.isArray(a))return a}var i={alert:[{start:"close",end:"closed"}],carousel:[{start:"slide",end:"slid"}],collapse:[{start:"hide",end:"hidden"},{start:"show",end:"shown"}],dropdown:[{start:"hide",end:"hidden"},{start:"show",end:"shown"}],modal:[{start:"hide",end:"hidden"},{start:"show",end:"shown"}],popover:[{start:"hide",end:"hidden"},{start:"show",end:"shown"}],tab:[{start:"hide",end:"hidden"},{start:"show",end:"shown"}],toast:[{start:"hide",end:"hidden"},{start:"show",end:"shown"}],tooltip:[{start:"hide",end:"hidden"},{start:"show",end:"shown"}]};a.default=function(){Object.entries(i).forEach(function(a){var d=c(a,2),e=d[0],f=d[1];f.forEach(function(a){var c="".concat(a.start,".bs.").concat(e),d="".concat(a.end,".bs.").concat(e);(0,b.default)(document.body).on(c,function(a){M.util.js_pending(d);(0,b.default)(a.target).one(d,function(){M.util.js_complete(d)})})})})};return a.default}); |
|||
//# sourceMappingURL=pending.min.js.map
|
@ -0,0 +1,2 @@ |
|||
define ("theme_ilb/popover",["exports","./bootstrap/popover"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});Object.defineProperty(a,"Popover",{enumerable:!0,get:function get(){return b.default}});b=function(a){return a&&a.__esModule?a:{default:a}}(b)}); |
|||
//# sourceMappingURL=popover.min.js.map
|
@ -0,0 +1 @@ |
|||
{"version":3,"sources":["../src/popover.js"],"names":[],"mappings":"oOAuBA,sD","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Backward compatibility file for the old popover.js\n *\n * @module theme_ilb/popover\n * @copyright 2020 Bas Brands <bas@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Popover from './bootstrap/popover';\n\nexport {\n Popover\n};\n"],"file":"popover.min.js"} |
@ -0,0 +1,2 @@ |
|||
define ("theme_ilb/scroll",["exports"],function(a){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;function b(a,b){if(!(a instanceof b)){throw new TypeError("Cannot call a class as a function")}}function c(a,b){for(var c=0,d;c<b.length;c++){d=b[c];d.enumerable=d.enumerable||!1;d.configurable=!0;if("value"in d)d.writable=!0;Object.defineProperty(a,d.key,d)}}function d(a,b,d){if(b)c(a.prototype,b);if(d)c(a,d);return a}var e=function(){function a(){b(this,a)}d(a,[{key:"init",value:function init(){this.scrollY=0;window.addEventListener("scroll",this.scrollHandler.bind(this));return this}},{key:"getScrollPosition",value:function getScrollPosition(){return window.pageYOffset||document.documentElement.scrollTop}},{key:"scrollHandler",value:function scrollHandler(){var a=document.querySelector("body"),b=this.getScrollPosition();if(b>=window.innerHeight){a.classList.add("scrolled")}else{a.classList.remove("scrolled")}}}]);return a}();a.default=e;return a.default}); |
|||
//# sourceMappingURL=scroll.min.js.map
|
@ -0,0 +1 @@ |
|||
{"version":3,"sources":["../src/scroll.js"],"names":["MoodleScroll","scrollY","window","addEventListener","scrollHandler","bind","pageYOffset","document","documentElement","scrollTop","body","querySelector","getScrollPosition","innerHeight","classList","add","remove"],"mappings":"wcA8BqBA,CAAAA,C,yEASV,CACH,KAAKC,OAAL,CAAe,CAAf,CACAC,MAAM,CAACC,gBAAP,CAAwB,QAAxB,CAAkC,KAAKC,aAAL,CAAmBC,IAAnB,CAAwB,IAAxB,CAAlC,EACA,MAAO,KACV,C,6DASmB,CAChB,MAAOH,CAAAA,MAAM,CAACI,WAAP,EAAsBC,QAAQ,CAACC,eAAT,CAAyBC,SACzD,C,qDAQe,IACNC,CAAAA,CAAI,CAAGH,QAAQ,CAACI,aAAT,CAAuB,MAAvB,CADD,CAENV,CAAO,CAAG,KAAKW,iBAAL,EAFJ,CAGZ,GAAIX,CAAO,EAAIC,MAAM,CAACW,WAAtB,CAAmC,CAC/BH,CAAI,CAACI,SAAL,CAAeC,GAAf,CAAmB,UAAnB,CACH,CAFD,IAEO,CACHL,CAAI,CAACI,SAAL,CAAeE,MAAf,CAAsB,UAAtB,CACH,CACJ,C","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Manage user scroll in Moodle for future floating elements.\n *\n * @module theme_ilb/scroll\n * @copyright 2020 Ferran Recio <ferran@moodle.org>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * Moodle scroll handling. For now it just handle a \"scrolled\" class\n * on the body tag but in the near future could handle more floating\n * elements like option bars, docked elements or other active elements.\n *\n * @class theme_ilb/scroll\n */\nexport default class MoodleScroll {\n\n /**\n * Initialise the scroll monitoring.\n *\n * @method init\n * @chainable\n * @return {Object} this.\n */\n init() {\n this.scrollY = 0;\n window.addEventListener(\"scroll\", this.scrollHandler.bind(this));\n return this;\n }\n\n /**\n * Add special classes to body depending on scroll position.\n *\n * @method update\n * @chainable\n * @return {Integer} current scroll position.\n */\n getScrollPosition() {\n return window.pageYOffset || document.documentElement.scrollTop;\n }\n\n /**\n * Add special classes to body depending on scroll position.\n *\n * @method update\n * @chainable\n */\n scrollHandler() {\n const body = document.querySelector('body');\n const scrollY = this.getScrollPosition();\n if (scrollY >= window.innerHeight) {\n body.classList.add('scrolled');\n } else {\n body.classList.remove('scrolled');\n }\n }\n}\n"],"file":"scroll.min.js"} |
@ -0,0 +1,2 @@ |
|||
define ("theme_ilb/toast",["exports","./bootstrap/toast"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});Object.defineProperty(a,"Toast",{enumerable:!0,get:function get(){return b.default}});b=function(a){return a&&a.__esModule?a:{default:a}}(b)}); |
|||
//# sourceMappingURL=toast.min.js.map
|
@ -0,0 +1 @@ |
|||
{"version":3,"sources":["../src/toast.js"],"names":[],"mappings":"8NAuBA,sD","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Backward compatibility file for the old toast.js\n *\n * @module theme_ilb/toast\n * @copyright 2020 Bas Brands <bas@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Toast from './bootstrap/toast';\n\nexport {\n Toast\n};\n"],"file":"toast.min.js"} |
@ -0,0 +1,282 @@ |
|||
// This file is part of Moodle - http://moodle.org/
|
|||
//
|
|||
// Moodle is free software: you can redistribute it and/or modify
|
|||
// it under the terms of the GNU General Public License as published by
|
|||
// the Free Software Foundation, either version 3 of the License, or
|
|||
// (at your option) any later version.
|
|||
//
|
|||
// Moodle is distributed in the hope that it will be useful,
|
|||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
// GNU General Public License for more details.
|
|||
//
|
|||
// You should have received a copy of the GNU General Public License
|
|||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
|||
/** |
|||
* Enhancements to Bootstrap components for accessibility. |
|||
* |
|||
* @module theme_ilb/aria |
|||
* @copyright 2018 Damyon Wiese <damyon@moodle.com> |
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|||
*/ |
|||
|
|||
import $ from 'jquery'; |
|||
import Pending from 'core/pending'; |
|||
|
|||
/** |
|||
* Drop downs from bootstrap don't support keyboard accessibility by default. |
|||
*/ |
|||
const dropdownFix = () => { |
|||
let focusEnd = false; |
|||
const setFocusEnd = () => { |
|||
focusEnd = true; |
|||
}; |
|||
const getFocusEnd = () => { |
|||
const result = focusEnd; |
|||
focusEnd = false; |
|||
return result; |
|||
}; |
|||
|
|||
// Special handling for "up" keyboard control.
|
|||
document.addEventListener('keydown', e => { |
|||
if (e.target.matches('[data-toggle="dropdown"]')) { |
|||
const trigger = e.key; |
|||
|
|||
// Up key opens the menu at the end.
|
|||
if (trigger == 'ArrowUp') { |
|||
// Focus the end of the menu, not the beginning.
|
|||
setFocusEnd(); |
|||
} |
|||
|
|||
// Space key or Enter key opens the menu.
|
|||
if (trigger == ' ' || trigger == 'Enter') { |
|||
// Cancel random scroll.
|
|||
e.preventDefault(); |
|||
// Open the menu instead.
|
|||
e.target.click(); |
|||
} |
|||
} |
|||
}); |
|||
|
|||
// Special handling for navigation keys when menu is open.
|
|||
const shiftFocus = element => { |
|||
const delayedFocus = pendingPromise => { |
|||
element.focus(); |
|||
pendingPromise.resolve(); |
|||
}; |
|||
setTimeout(delayedFocus, 50, new Pending('core/aria:delayed-focus')); |
|||
}; |
|||
|
|||
$('.dropdown').on('shown.bs.dropdown', e => { |
|||
// We need to focus on the first menuitem.
|
|||
const menu = e.target.querySelector('[role="menu"]'); |
|||
let menuItems = false; |
|||
let foundMenuItem = false; |
|||
|
|||
if (menu) { |
|||
menuItems = menu.querySelectorAll('[role="menuitem"]'); |
|||
} |
|||
if (menuItems && menuItems.length > 0) { |
|||
if (getFocusEnd()) { |
|||
foundMenuItem = menuItems[menuItems.length - 1]; |
|||
} else { |
|||
// The first menu entry, pretty reasonable.
|
|||
foundMenuItem = menuItems[0]; |
|||
} |
|||
} |
|||
if (foundMenuItem) { |
|||
shiftFocus(foundMenuItem); |
|||
} |
|||
}); |
|||
// Search for menu items by finding the first item that has
|
|||
// text starting with the typed character (case insensitive).
|
|||
document.addEventListener('keypress', e => { |
|||
if (e.target.matches('.dropdown [role="menu"] [role="menuitem"]')) { |
|||
const menu = e.target.closest('[role="menu"]'); |
|||
if (!menu) { |
|||
return; |
|||
} |
|||
const menuItems = menu.querySelectorAll('[role="menuitem"]'); |
|||
if (!menuItems) { |
|||
return; |
|||
} |
|||
|
|||
const trigger = e.key.toLowerCase(); |
|||
|
|||
for (let i = 0; i < menuItems.length; i++) { |
|||
const item = menuItems[i]; |
|||
const itemText = item.text.trim().toLowerCase(); |
|||
if (itemText.indexOf(trigger) == 0) { |
|||
shiftFocus(item); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
}); |
|||
|
|||
// Keyboard navigation for arrow keys, home and end keys.
|
|||
document.addEventListener('keydown', e => { |
|||
if (e.target.matches('.dropdown [role="menu"] [role="menuitem"]')) { |
|||
const trigger = e.key; |
|||
let next = false; |
|||
const menu = e.target.closest('[role="menu"]'); |
|||
|
|||
if (!menu) { |
|||
return; |
|||
} |
|||
const menuItems = menu.querySelectorAll('[role="menuitem"]'); |
|||
if (!menuItems) { |
|||
return; |
|||
} |
|||
// Down key.
|
|||
if (trigger == 'ArrowDown') { |
|||
for (let i = 0; i < menuItems.length - 1; i++) { |
|||
if (menuItems[i] == e.target) { |
|||
next = menuItems[i + 1]; |
|||
break; |
|||
} |
|||
} |
|||
if (!next) { |
|||
// Wrap to first item.
|
|||
next = menuItems[0]; |
|||
} |
|||
|
|||
} else if (trigger == 'ArrowUp') { |
|||
// Up key.
|
|||
for (let i = 1; i < menuItems.length; i++) { |
|||
if (menuItems[i] == e.target) { |
|||
next = menuItems[i - 1]; |
|||
break; |
|||
} |
|||
} |
|||
if (!next) { |
|||
// Wrap to last item.
|
|||
next = menuItems[menuItems.length - 1]; |
|||
} |
|||
|
|||
} else if (trigger == 'Home') { |
|||
// Home key.
|
|||
next = menuItems[0]; |
|||
|
|||
} else if (trigger == 'End') { |
|||
// End key.
|
|||
next = menuItems[menuItems.length - 1]; |
|||
} |
|||
// Variable next is set if we do want to act on the keypress.
|
|||
if (next) { |
|||
e.preventDefault(); |
|||
shiftFocus(next); |
|||
} |
|||
return; |
|||
} |
|||
}); |
|||
|
|||
$('.dropdown').on('hidden.bs.dropdown', e => { |
|||
// We need to focus on the menu trigger.
|
|||
const trigger = e.target.querySelector('[data-toggle="dropdown"]'); |
|||
if (trigger) { |
|||
shiftFocus(trigger); |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
/** |
|||
* After page load, focus on any element with special autofocus attribute. |
|||
*/ |
|||
const autoFocus = () => { |
|||
window.addEventListener("load", () => { |
|||
const alerts = document.querySelectorAll('[data-aria-autofocus="true"][role="alert"]'); |
|||
Array.prototype.forEach.call(alerts, autofocusElement => { |
|||
// According to the specification an role="alert" region is only read out on change to the content
|
|||
// of that region.
|
|||
autofocusElement.innerHTML += ' '; |
|||
autofocusElement.removeAttribute('data-aria-autofocus'); |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
/** |
|||
* Changes the focus to the correct tab based on the key that is pressed. |
|||
* @param {KeyboardEvent} e |
|||
*/ |
|||
const updateTabFocus = e => { |
|||
const tabList = e.target.closest('[role="tablist"]'); |
|||
const vertical = tabList.getAttribute('aria-orientation') == 'vertical'; |
|||
const rtl = window.right_to_left(); |
|||
const arrowNext = vertical ? 'ArrowDown' : (rtl ? 'ArrowLeft' : 'ArrowRight'); |
|||
const arrowPrevious = vertical ? 'ArrowUp' : (rtl ? 'ArrowRight' : 'ArrowLeft'); |
|||
const tabs = Array.prototype.filter.call( |
|||
tabList.querySelectorAll('[role="tab"]'), |
|||
tab => getComputedStyle(tab).display !== 'none'); // We only work with the visible tabs.
|
|||
|
|||
for (let i = 0; i < tabs.length; i++) { |
|||
tabs[i].index = i; |
|||
} |
|||
|
|||
switch (e.key) { |
|||
case arrowNext: |
|||
e.preventDefault(); |
|||
if (e.target.index !== undefined && tabs[e.target.index + 1]) { |
|||
tabs[e.target.index + 1].focus(); |
|||
} else { |
|||
tabs[0].focus(); |
|||
} |
|||
break; |
|||
case arrowPrevious: |
|||
e.preventDefault(); |
|||
if (e.target.index !== undefined && tabs[e.target.index - 1]) { |
|||
tabs[e.target.index - 1].focus(); |
|||
} else { |
|||
tabs[tabs.length - 1].focus(); |
|||
} |
|||
break; |
|||
case 'Home': |
|||
e.preventDefault(); |
|||
tabs[0].focus(); |
|||
break; |
|||
case 'End': |
|||
e.preventDefault(); |
|||
tabs[tabs.length - 1].focus(); |
|||
break; |
|||
case 'Enter': |
|||
case ' ': |
|||
e.preventDefault(); |
|||
$(e.target).tab('show'); |
|||
tabs.forEach(tab => { |
|||
tab.tabIndex = -1; |
|||
}); |
|||
e.target.tabIndex = 0; |
|||
} |
|||
}; |
|||
|
|||
/** |
|||
* Fix accessibility issues regarding tab elements focus and their tab order in Bootstrap navs. |
|||
*/ |
|||
const tabElementFix = () => { |
|||
document.addEventListener('keydown', e => { |
|||
if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Home', 'End', 'Enter', ' '].includes(e.key)) { |
|||
if (e.target.matches('[role="tablist"] [role="tab"]')) { |
|||
updateTabFocus(e); |
|||
} |
|||
} |
|||
}); |
|||
|
|||
document.addEventListener('click', e => { |
|||
if (e.target.matches('[role="tablist"] [role="tab"]')) { |
|||
const tabs = e.target.closest('[role="tablist"]').querySelectorAll('[role="tab"]'); |
|||
e.preventDefault(); |
|||
$(e.target).tab('show'); |
|||
tabs.forEach(tab => { |
|||
tab.tabIndex = -1; |
|||
}); |
|||
e.target.tabIndex = 0; |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
export const init = () => { |
|||
dropdownFix(); |
|||
autoFocus(); |
|||
tabElementFix(); |
|||
}; |
@ -0,0 +1,173 @@ |
|||
/** |
|||
* -------------------------------------------------------------------------- |
|||
* Bootstrap (v4.6.0): alert.js |
|||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|||
* -------------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
import $ from 'jquery' |
|||
import Util from './util' |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Constants |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
const NAME = 'alert' |
|||
const VERSION = '4.6.0' |
|||
const DATA_KEY = 'bs.alert' |
|||
const EVENT_KEY = `.${DATA_KEY}` |
|||
const DATA_API_KEY = '.data-api' |
|||
const JQUERY_NO_CONFLICT = $.fn[NAME] |
|||
|
|||
const SELECTOR_DISMISS = '[data-dismiss="alert"]' |
|||
|
|||
const EVENT_CLOSE = `close${EVENT_KEY}` |
|||
const EVENT_CLOSED = `closed${EVENT_KEY}` |
|||
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` |
|||
|
|||
const CLASS_NAME_ALERT = 'alert' |
|||
const CLASS_NAME_FADE = 'fade' |
|||
const CLASS_NAME_SHOW = 'show' |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Class Definition |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
class Alert { |
|||
constructor(element) { |
|||
this._element = element |
|||
} |
|||
|
|||
// Getters
|
|||
|
|||
static get VERSION() { |
|||
return VERSION |
|||
} |
|||
|
|||
// Public
|
|||
|
|||
close(element) { |
|||
let rootElement = this._element |
|||
if (element) { |
|||
rootElement = this._getRootElement(element) |
|||
} |
|||
|
|||
const customEvent = this._triggerCloseEvent(rootElement) |
|||
|
|||
if (customEvent.isDefaultPrevented()) { |
|||
return |
|||
} |
|||
|
|||
this._removeElement(rootElement) |
|||
} |
|||
|
|||
dispose() { |
|||
$.removeData(this._element, DATA_KEY) |
|||
this._element = null |
|||
} |
|||
|
|||
// Private
|
|||
|
|||
_getRootElement(element) { |
|||
const selector = Util.getSelectorFromElement(element) |
|||
let parent = false |
|||
|
|||
if (selector) { |
|||
parent = document.querySelector(selector) |
|||
} |
|||
|
|||
if (!parent) { |
|||
parent = $(element).closest(`.${CLASS_NAME_ALERT}`)[0] |
|||
} |
|||
|
|||
return parent |
|||
} |
|||
|
|||
_triggerCloseEvent(element) { |
|||
const closeEvent = $.Event(EVENT_CLOSE) |
|||
|
|||
$(element).trigger(closeEvent) |
|||
return closeEvent |
|||
} |
|||
|
|||
_removeElement(element) { |
|||
$(element).removeClass(CLASS_NAME_SHOW) |
|||
|
|||
if (!$(element).hasClass(CLASS_NAME_FADE)) { |
|||
this._destroyElement(element) |
|||
return |
|||
} |
|||
|
|||
const transitionDuration = Util.getTransitionDurationFromElement(element) |
|||
|
|||
$(element) |
|||
.one(Util.TRANSITION_END, event => this._destroyElement(element, event)) |
|||
.emulateTransitionEnd(transitionDuration) |
|||
} |
|||
|
|||
_destroyElement(element) { |
|||
$(element) |
|||
.detach() |
|||
.trigger(EVENT_CLOSED) |
|||
.remove() |
|||
} |
|||
|
|||
// Static
|
|||
|
|||
static _jQueryInterface(config) { |
|||
return this.each(function () { |
|||
const $element = $(this) |
|||
let data = $element.data(DATA_KEY) |
|||
|
|||
if (!data) { |
|||
data = new Alert(this) |
|||
$element.data(DATA_KEY, data) |
|||
} |
|||
|
|||
if (config === 'close') { |
|||
data[config](this) |
|||
} |
|||
}) |
|||
} |
|||
|
|||
static _handleDismiss(alertInstance) { |
|||
return function (event) { |
|||
if (event) { |
|||
event.preventDefault() |
|||
} |
|||
|
|||
alertInstance.close(this) |
|||
} |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Data Api implementation |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
$(document).on( |
|||
EVENT_CLICK_DATA_API, |
|||
SELECTOR_DISMISS, |
|||
Alert._handleDismiss(new Alert()) |
|||
) |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* jQuery |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
$.fn[NAME] = Alert._jQueryInterface |
|||
$.fn[NAME].Constructor = Alert |
|||
$.fn[NAME].noConflict = () => { |
|||
$.fn[NAME] = JQUERY_NO_CONFLICT |
|||
return Alert._jQueryInterface |
|||
} |
|||
|
|||
export default Alert |
@ -0,0 +1,209 @@ |
|||
/** |
|||
* -------------------------------------------------------------------------- |
|||
* Bootstrap (v4.6.0): button.js |
|||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|||
* -------------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
import $ from 'jquery' |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Constants |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
const NAME = 'button' |
|||
const VERSION = '4.6.0' |
|||
const DATA_KEY = 'bs.button' |
|||
const EVENT_KEY = `.${DATA_KEY}` |
|||
const DATA_API_KEY = '.data-api' |
|||
const JQUERY_NO_CONFLICT = $.fn[NAME] |
|||
|
|||
const CLASS_NAME_ACTIVE = 'active' |
|||
const CLASS_NAME_BUTTON = 'btn' |
|||
const CLASS_NAME_FOCUS = 'focus' |
|||
|
|||
const SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^="button"]' |
|||
const SELECTOR_DATA_TOGGLES = '[data-toggle="buttons"]' |
|||
const SELECTOR_DATA_TOGGLE = '[data-toggle="button"]' |
|||
const SELECTOR_DATA_TOGGLES_BUTTONS = '[data-toggle="buttons"] .btn' |
|||
const SELECTOR_INPUT = 'input:not([type="hidden"])' |
|||
const SELECTOR_ACTIVE = '.active' |
|||
const SELECTOR_BUTTON = '.btn' |
|||
|
|||
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` |
|||
const EVENT_FOCUS_BLUR_DATA_API = `focus${EVENT_KEY}${DATA_API_KEY} ` + |
|||
`blur${EVENT_KEY}${DATA_API_KEY}` |
|||
const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}` |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Class Definition |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
class Button { |
|||
constructor(element) { |
|||
this._element = element |
|||
this.shouldAvoidTriggerChange = false |
|||
} |
|||
|
|||
// Getters
|
|||
|
|||
static get VERSION() { |
|||
return VERSION |
|||
} |
|||
|
|||
// Public
|
|||
|
|||
toggle() { |
|||
let triggerChangeEvent = true |
|||
let addAriaPressed = true |
|||
const rootElement = $(this._element).closest(SELECTOR_DATA_TOGGLES)[0] |
|||
|
|||
if (rootElement) { |
|||
const input = this._element.querySelector(SELECTOR_INPUT) |
|||
|
|||
if (input) { |
|||
if (input.type === 'radio') { |
|||
if (input.checked && this._element.classList.contains(CLASS_NAME_ACTIVE)) { |
|||
triggerChangeEvent = false |
|||
} else { |
|||
const activeElement = rootElement.querySelector(SELECTOR_ACTIVE) |
|||
|
|||
if (activeElement) { |
|||
$(activeElement).removeClass(CLASS_NAME_ACTIVE) |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (triggerChangeEvent) { |
|||
// if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input
|
|||
if (input.type === 'checkbox' || input.type === 'radio') { |
|||
input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE) |
|||
} |
|||
|
|||
if (!this.shouldAvoidTriggerChange) { |
|||
$(input).trigger('change') |
|||
} |
|||
} |
|||
|
|||
input.focus() |
|||
addAriaPressed = false |
|||
} |
|||
} |
|||
|
|||
if (!(this._element.hasAttribute('disabled') || this._element.classList.contains('disabled'))) { |
|||
if (addAriaPressed) { |
|||
this._element.setAttribute('aria-pressed', !this._element.classList.contains(CLASS_NAME_ACTIVE)) |
|||
} |
|||
|
|||
if (triggerChangeEvent) { |
|||
$(this._element).toggleClass(CLASS_NAME_ACTIVE) |
|||
} |
|||
} |
|||
} |
|||
|
|||
dispose() { |
|||
$.removeData(this._element, DATA_KEY) |
|||
this._element = null |
|||
} |
|||
|
|||
// Static
|
|||
|
|||
static _jQueryInterface(config, avoidTriggerChange) { |
|||
return this.each(function () { |
|||
const $element = $(this) |
|||
let data = $element.data(DATA_KEY) |
|||
|
|||
if (!data) { |
|||
data = new Button(this) |
|||
$element.data(DATA_KEY, data) |
|||
} |
|||
|
|||
data.shouldAvoidTriggerChange = avoidTriggerChange |
|||
|
|||
if (config === 'toggle') { |
|||
data[config]() |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Data Api implementation |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
$(document) |
|||
.on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => { |
|||
let button = event.target |
|||
const initialButton = button |
|||
|
|||
if (!$(button).hasClass(CLASS_NAME_BUTTON)) { |
|||
button = $(button).closest(SELECTOR_BUTTON)[0] |
|||
} |
|||
|
|||
if (!button || button.hasAttribute('disabled') || button.classList.contains('disabled')) { |
|||
event.preventDefault() // work around Firefox bug #1540995
|
|||
} else { |
|||
const inputBtn = button.querySelector(SELECTOR_INPUT) |
|||
|
|||
if (inputBtn && (inputBtn.hasAttribute('disabled') || inputBtn.classList.contains('disabled'))) { |
|||
event.preventDefault() // work around Firefox bug #1540995
|
|||
return |
|||
} |
|||
|
|||
if (initialButton.tagName === 'INPUT' || button.tagName !== 'LABEL') { |
|||
Button._jQueryInterface.call($(button), 'toggle', initialButton.tagName === 'INPUT') |
|||
} |
|||
} |
|||
}) |
|||
.on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, event => { |
|||
const button = $(event.target).closest(SELECTOR_BUTTON)[0] |
|||
$(button).toggleClass(CLASS_NAME_FOCUS, /^focus(in)?$/.test(event.type)) |
|||
}) |
|||
|
|||
$(window).on(EVENT_LOAD_DATA_API, () => { |
|||
// ensure correct active class is set to match the controls' actual values/states
|
|||
|
|||
// find all checkboxes/readio buttons inside data-toggle groups
|
|||
let buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLES_BUTTONS)) |
|||
for (let i = 0, len = buttons.length; i < len; i++) { |
|||
const button = buttons[i] |
|||
const input = button.querySelector(SELECTOR_INPUT) |
|||
if (input.checked || input.hasAttribute('checked')) { |
|||
button.classList.add(CLASS_NAME_ACTIVE) |
|||
} else { |
|||
button.classList.remove(CLASS_NAME_ACTIVE) |
|||
} |
|||
} |
|||
|
|||
// find all button toggles
|
|||
buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE)) |
|||
for (let i = 0, len = buttons.length; i < len; i++) { |
|||
const button = buttons[i] |
|||
if (button.getAttribute('aria-pressed') === 'true') { |
|||
button.classList.add(CLASS_NAME_ACTIVE) |
|||
} else { |
|||
button.classList.remove(CLASS_NAME_ACTIVE) |
|||
} |
|||
} |
|||
}) |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* jQuery |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
$.fn[NAME] = Button._jQueryInterface |
|||
$.fn[NAME].Constructor = Button |
|||
$.fn[NAME].noConflict = () => { |
|||
$.fn[NAME] = JQUERY_NO_CONFLICT |
|||
return Button._jQueryInterface |
|||
} |
|||
|
|||
export default Button |
@ -0,0 +1,613 @@ |
|||
/** |
|||
* -------------------------------------------------------------------------- |
|||
* Bootstrap (v4.6.0): carousel.js |
|||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|||
* -------------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
import $ from 'jquery' |
|||
import Util from './util' |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Constants |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
const NAME = 'carousel' |
|||
const VERSION = '4.6.0' |
|||
const DATA_KEY = 'bs.carousel' |
|||
const EVENT_KEY = `.${DATA_KEY}` |
|||
const DATA_API_KEY = '.data-api' |
|||
const JQUERY_NO_CONFLICT = $.fn[NAME] |
|||
const ARROW_LEFT_KEYCODE = 37 // KeyboardEvent.which value for left arrow key
|
|||
const ARROW_RIGHT_KEYCODE = 39 // KeyboardEvent.which value for right arrow key
|
|||
const TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch
|
|||
const SWIPE_THRESHOLD = 40 |
|||
|
|||
const Default = { |
|||
interval: 5000, |
|||
keyboard: true, |
|||
slide: false, |
|||
pause: 'hover', |
|||
wrap: true, |
|||
touch: true |
|||
} |
|||
|
|||
const DefaultType = { |
|||
interval: '(number|boolean)', |
|||
keyboard: 'boolean', |
|||
slide: '(boolean|string)', |
|||
pause: '(string|boolean)', |
|||
wrap: 'boolean', |
|||
touch: 'boolean' |
|||
} |
|||
|
|||
const DIRECTION_NEXT = 'next' |
|||
const DIRECTION_PREV = 'prev' |
|||
const DIRECTION_LEFT = 'left' |
|||
const DIRECTION_RIGHT = 'right' |
|||
|
|||
const EVENT_SLIDE = `slide${EVENT_KEY}` |
|||
const EVENT_SLID = `slid${EVENT_KEY}` |
|||
const EVENT_KEYDOWN = `keydown${EVENT_KEY}` |
|||
const EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}` |
|||
const EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}` |
|||
const EVENT_TOUCHSTART = `touchstart${EVENT_KEY}` |
|||
const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}` |
|||
const EVENT_TOUCHEND = `touchend${EVENT_KEY}` |
|||
const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}` |
|||
const EVENT_POINTERUP = `pointerup${EVENT_KEY}` |
|||
const EVENT_DRAG_START = `dragstart${EVENT_KEY}` |
|||
const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}` |
|||
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` |
|||
|
|||
const CLASS_NAME_CAROUSEL = 'carousel' |
|||
const CLASS_NAME_ACTIVE = 'active' |
|||
const CLASS_NAME_SLIDE = 'slide' |
|||
const CLASS_NAME_RIGHT = 'carousel-item-right' |
|||
const CLASS_NAME_LEFT = 'carousel-item-left' |
|||
const CLASS_NAME_NEXT = 'carousel-item-next' |
|||
const CLASS_NAME_PREV = 'carousel-item-prev' |
|||
const CLASS_NAME_POINTER_EVENT = 'pointer-event' |
|||
|
|||
const SELECTOR_ACTIVE = '.active' |
|||
const SELECTOR_ACTIVE_ITEM = '.active.carousel-item' |
|||
const SELECTOR_ITEM = '.carousel-item' |
|||
const SELECTOR_ITEM_IMG = '.carousel-item img' |
|||
const SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev' |
|||
const SELECTOR_INDICATORS = '.carousel-indicators' |
|||
const SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]' |
|||
const SELECTOR_DATA_RIDE = '[data-ride="carousel"]' |
|||
|
|||
const PointerType = { |
|||
TOUCH: 'touch', |
|||
PEN: 'pen' |
|||
} |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Class Definition |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
class Carousel { |
|||
constructor(element, config) { |
|||
this._items = null |
|||
this._interval = null |
|||
this._activeElement = null |
|||
this._isPaused = false |
|||
this._isSliding = false |
|||
this.touchTimeout = null |
|||
this.touchStartX = 0 |
|||
this.touchDeltaX = 0 |
|||
|
|||
this._config = this._getConfig(config) |
|||
this._element = element |
|||
this._indicatorsElement = this._element.querySelector(SELECTOR_INDICATORS) |
|||
this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0 |
|||
this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent) |
|||
|
|||
this._addEventListeners() |
|||
} |
|||
|
|||
// Getters
|
|||
|
|||
static get VERSION() { |
|||
return VERSION |
|||
} |
|||
|
|||
static get Default() { |
|||
return Default |
|||
} |
|||
|
|||
// Public
|
|||
|
|||
next() { |
|||
if (!this._isSliding) { |
|||
this._slide(DIRECTION_NEXT) |
|||
} |
|||
} |
|||
|
|||
nextWhenVisible() { |
|||
const $element = $(this._element) |
|||
// Don't call next when the page isn't visible
|
|||
// or the carousel or its parent isn't visible
|
|||
if (!document.hidden && |
|||
($element.is(':visible') && $element.css('visibility') !== 'hidden')) { |
|||
this.next() |
|||
} |
|||
} |
|||
|
|||
prev() { |
|||
if (!this._isSliding) { |
|||
this._slide(DIRECTION_PREV) |
|||
} |
|||
} |
|||
|
|||
pause(event) { |
|||
if (!event) { |
|||
this._isPaused = true |
|||
} |
|||
|
|||
if (this._element.querySelector(SELECTOR_NEXT_PREV)) { |
|||
Util.triggerTransitionEnd(this._element) |
|||
this.cycle(true) |
|||
} |
|||
|
|||
clearInterval(this._interval) |
|||
this._interval = null |
|||
} |
|||
|
|||
cycle(event) { |
|||
if (!event) { |
|||
this._isPaused = false |
|||
} |
|||
|
|||
if (this._interval) { |
|||
clearInterval(this._interval) |
|||
this._interval = null |
|||
} |
|||
|
|||
if (this._config.interval && !this._isPaused) { |
|||
this._updateInterval() |
|||
|
|||
this._interval = setInterval( |
|||
(document.visibilityState ? this.nextWhenVisible : this.next).bind(this), |
|||
this._config.interval |
|||
) |
|||
} |
|||
} |
|||
|
|||
to(index) { |
|||
this._activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM) |
|||
|
|||
const activeIndex = this._getItemIndex(this._activeElement) |
|||
|
|||
if (index > this._items.length - 1 || index < 0) { |
|||
return |
|||
} |
|||
|
|||
if (this._isSliding) { |
|||
$(this._element).one(EVENT_SLID, () => this.to(index)) |
|||
return |
|||
} |
|||
|
|||
if (activeIndex === index) { |
|||
this.pause() |
|||
this.cycle() |
|||
return |
|||
} |
|||
|
|||
const direction = index > activeIndex ? |
|||
DIRECTION_NEXT : |
|||
DIRECTION_PREV |
|||
|
|||
this._slide(direction, this._items[index]) |
|||
} |
|||
|
|||
dispose() { |
|||
$(this._element).off(EVENT_KEY) |
|||
$.removeData(this._element, DATA_KEY) |
|||
|
|||
this._items = null |
|||
this._config = null |
|||
this._element = null |
|||
this._interval = null |
|||
this._isPaused = null |
|||
this._isSliding = null |
|||
this._activeElement = null |
|||
this._indicatorsElement = null |
|||
} |
|||
|
|||
// Private
|
|||
|
|||
_getConfig(config) { |
|||
config = { |
|||
...Default, |
|||
...config |
|||
} |
|||
Util.typeCheckConfig(NAME, config, DefaultType) |
|||
return config |
|||
} |
|||
|
|||
_handleSwipe() { |
|||
const absDeltax = Math.abs(this.touchDeltaX) |
|||
|
|||
if (absDeltax <= SWIPE_THRESHOLD) { |
|||
return |
|||
} |
|||
|
|||
const direction = absDeltax / this.touchDeltaX |
|||
|
|||
this.touchDeltaX = 0 |
|||
|
|||
// swipe left
|
|||
if (direction > 0) { |
|||
this.prev() |
|||
} |
|||
|
|||
// swipe right
|
|||
if (direction < 0) { |
|||
this.next() |
|||
} |
|||
} |
|||
|
|||
_addEventListeners() { |
|||
if (this._config.keyboard) { |
|||
$(this._element).on(EVENT_KEYDOWN, event => this._keydown(event)) |
|||
} |
|||
|
|||
if (this._config.pause === 'hover') { |
|||
$(this._element) |
|||
.on(EVENT_MOUSEENTER, event => this.pause(event)) |
|||
.on(EVENT_MOUSELEAVE, event => this.cycle(event)) |
|||
} |
|||
|
|||
if (this._config.touch) { |
|||
this._addTouchEventListeners() |
|||
} |
|||
} |
|||
|
|||
_addTouchEventListeners() { |
|||
if (!this._touchSupported) { |
|||
return |
|||
} |
|||
|
|||
const start = event => { |
|||
if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) { |
|||
this.touchStartX = event.originalEvent.clientX |
|||
} else if (!this._pointerEvent) { |
|||
this.touchStartX = event.originalEvent.touches[0].clientX |
|||
} |
|||
} |
|||
|
|||
const move = event => { |
|||
// ensure swiping with one touch and not pinching
|
|||
if (event.originalEvent.touches && event.originalEvent.touches.length > 1) { |
|||
this.touchDeltaX = 0 |
|||
} else { |
|||
this.touchDeltaX = event.originalEvent.touches[0].clientX - this.touchStartX |
|||
} |
|||
} |
|||
|
|||
const end = event => { |
|||
if (this._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) { |
|||
this.touchDeltaX = event.originalEvent.clientX - this.touchStartX |
|||
} |
|||
|
|||
this._handleSwipe() |
|||
if (this._config.pause === 'hover') { |
|||
// If it's a touch-enabled device, mouseenter/leave are fired as
|
|||
// part of the mouse compatibility events on first tap - the carousel
|
|||
// would stop cycling until user tapped out of it;
|
|||
// here, we listen for touchend, explicitly pause the carousel
|
|||
// (as if it's the second time we tap on it, mouseenter compat event
|
|||
// is NOT fired) and after a timeout (to allow for mouse compatibility
|
|||
// events to fire) we explicitly restart cycling
|
|||
|
|||
this.pause() |
|||
if (this.touchTimeout) { |
|||
clearTimeout(this.touchTimeout) |
|||
} |
|||
|
|||
this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval) |
|||
} |
|||
} |
|||
|
|||
$(this._element.querySelectorAll(SELECTOR_ITEM_IMG)) |
|||
.on(EVENT_DRAG_START, e => e.preventDefault()) |
|||
|
|||
if (this._pointerEvent) { |
|||
$(this._element).on(EVENT_POINTERDOWN, event => start(event)) |
|||
$(this._element).on(EVENT_POINTERUP, event => end(event)) |
|||
|
|||
this._element.classList.add(CLASS_NAME_POINTER_EVENT) |
|||
} else { |
|||
$(this._element).on(EVENT_TOUCHSTART, event => start(event)) |
|||
$(this._element).on(EVENT_TOUCHMOVE, event => move(event)) |
|||
$(this._element).on(EVENT_TOUCHEND, event => end(event)) |
|||
} |
|||
} |
|||
|
|||
_keydown(event) { |
|||
if (/input|textarea/i.test(event.target.tagName)) { |
|||
return |
|||
} |
|||
|
|||
switch (event.which) { |
|||
case ARROW_LEFT_KEYCODE: |
|||
event.preventDefault() |
|||
this.prev() |
|||
break |
|||
case ARROW_RIGHT_KEYCODE: |
|||
event.preventDefault() |
|||
this.next() |
|||
break |
|||
default: |
|||
} |
|||
} |
|||
|
|||
_getItemIndex(element) { |
|||
this._items = element && element.parentNode ? |
|||
[].slice.call(element.parentNode.querySelectorAll(SELECTOR_ITEM)) : |
|||
[] |
|||
return this._items.indexOf(element) |
|||
} |
|||
|
|||
_getItemByDirection(direction, activeElement) { |
|||
const isNextDirection = direction === DIRECTION_NEXT |
|||
const isPrevDirection = direction === DIRECTION_PREV |
|||
const activeIndex = this._getItemIndex(activeElement) |
|||
const lastItemIndex = this._items.length - 1 |
|||
const isGoingToWrap = isPrevDirection && activeIndex === 0 || |
|||
isNextDirection && activeIndex === lastItemIndex |
|||
|
|||
if (isGoingToWrap && !this._config.wrap) { |
|||
return activeElement |
|||
} |
|||
|
|||
const delta = direction === DIRECTION_PREV ? -1 : 1 |
|||
const itemIndex = (activeIndex + delta) % this._items.length |
|||
|
|||
return itemIndex === -1 ? |
|||
this._items[this._items.length - 1] : this._items[itemIndex] |
|||
} |
|||
|
|||
_triggerSlideEvent(relatedTarget, eventDirectionName) { |
|||
const targetIndex = this._getItemIndex(relatedTarget) |
|||
const fromIndex = this._getItemIndex(this._element.querySelector(SELECTOR_ACTIVE_ITEM)) |
|||
const slideEvent = $.Event(EVENT_SLIDE, { |
|||
relatedTarget, |
|||
direction: eventDirectionName, |
|||
from: fromIndex, |
|||
to: targetIndex |
|||
}) |
|||
|
|||
$(this._element).trigger(slideEvent) |
|||
|
|||
return slideEvent |
|||
} |
|||
|
|||
_setActiveIndicatorElement(element) { |
|||
if (this._indicatorsElement) { |
|||
const indicators = [].slice.call(this._indicatorsElement.querySelectorAll(SELECTOR_ACTIVE)) |
|||
$(indicators).removeClass(CLASS_NAME_ACTIVE) |
|||
|
|||
const nextIndicator = this._indicatorsElement.children[ |
|||
this._getItemIndex(element) |
|||
] |
|||
|
|||
if (nextIndicator) { |
|||
$(nextIndicator).addClass(CLASS_NAME_ACTIVE) |
|||
} |
|||
} |
|||
} |
|||
|
|||
_updateInterval() { |
|||
const element = this._activeElement || this._element.querySelector(SELECTOR_ACTIVE_ITEM) |
|||
|
|||
if (!element) { |
|||
return |
|||
} |
|||
|
|||
const elementInterval = parseInt(element.getAttribute('data-interval'), 10) |
|||
|
|||
if (elementInterval) { |
|||
this._config.defaultInterval = this._config.defaultInterval || this._config.interval |
|||
this._config.interval = elementInterval |
|||
} else { |
|||
this._config.interval = this._config.defaultInterval || this._config.interval |
|||
} |
|||
} |
|||
|
|||
_slide(direction, element) { |
|||
const activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM) |
|||
const activeElementIndex = this._getItemIndex(activeElement) |
|||
const nextElement = element || activeElement && |
|||
this._getItemByDirection(direction, activeElement) |
|||
const nextElementIndex = this._getItemIndex(nextElement) |
|||
const isCycling = Boolean(this._interval) |
|||
|
|||
let directionalClassName |
|||
let orderClassName |
|||
let eventDirectionName |
|||
|
|||
if (direction === DIRECTION_NEXT) { |
|||
directionalClassName = CLASS_NAME_LEFT |
|||
orderClassName = CLASS_NAME_NEXT |
|||
eventDirectionName = DIRECTION_LEFT |
|||
} else { |
|||
directionalClassName = CLASS_NAME_RIGHT |
|||
orderClassName = CLASS_NAME_PREV |
|||
eventDirectionName = DIRECTION_RIGHT |
|||
} |
|||
|
|||
if (nextElement && $(nextElement).hasClass(CLASS_NAME_ACTIVE)) { |
|||
this._isSliding = false |
|||
return |
|||
} |
|||
|
|||
const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName) |
|||
if (slideEvent.isDefaultPrevented()) { |
|||
return |
|||
} |
|||
|
|||
if (!activeElement || !nextElement) { |
|||
// Some weirdness is happening, so we bail
|
|||
return |
|||
} |
|||
|
|||
this._isSliding = true |
|||
|
|||
if (isCycling) { |
|||
this.pause() |
|||
} |
|||
|
|||
this._setActiveIndicatorElement(nextElement) |
|||
this._activeElement = nextElement |
|||
|
|||
const slidEvent = $.Event(EVENT_SLID, { |
|||
relatedTarget: nextElement, |
|||
direction: eventDirectionName, |
|||
from: activeElementIndex, |
|||
to: nextElementIndex |
|||
}) |
|||
|
|||
if ($(this._element).hasClass(CLASS_NAME_SLIDE)) { |
|||
$(nextElement).addClass(orderClassName) |
|||
|
|||
Util.reflow(nextElement) |
|||
|
|||
$(activeElement).addClass(directionalClassName) |
|||
$(nextElement).addClass(directionalClassName) |
|||
|
|||
const transitionDuration = Util.getTransitionDurationFromElement(activeElement) |
|||
|
|||
$(activeElement) |
|||
.one(Util.TRANSITION_END, () => { |
|||
$(nextElement) |
|||
.removeClass(`${directionalClassName} ${orderClassName}`) |
|||
.addClass(CLASS_NAME_ACTIVE) |
|||
|
|||
$(activeElement).removeClass(`${CLASS_NAME_ACTIVE} ${orderClassName} ${directionalClassName}`) |
|||
|
|||
this._isSliding = false |
|||
|
|||
setTimeout(() => $(this._element).trigger(slidEvent), 0) |
|||
}) |
|||
.emulateTransitionEnd(transitionDuration) |
|||
} else { |
|||
$(activeElement).removeClass(CLASS_NAME_ACTIVE) |
|||
$(nextElement).addClass(CLASS_NAME_ACTIVE) |
|||
|
|||
this._isSliding = false |
|||
$(this._element).trigger(slidEvent) |
|||
} |
|||
|
|||
if (isCycling) { |
|||
this.cycle() |
|||
} |
|||
} |
|||
|
|||
// Static
|
|||
|
|||
static _jQueryInterface(config) { |
|||
return this.each(function () { |
|||
let data = $(this).data(DATA_KEY) |
|||
let _config = { |
|||
...Default, |
|||
...$(this).data() |
|||
} |
|||
|
|||
if (typeof config === 'object') { |
|||
_config = { |
|||
..._config, |
|||
...config |
|||
} |
|||
} |
|||
|
|||
const action = typeof config === 'string' ? config : _config.slide |
|||
|
|||
if (!data) { |
|||
data = new Carousel(this, _config) |
|||
$(this).data(DATA_KEY, data) |
|||
} |
|||
|
|||
if (typeof config === 'number') { |
|||
data.to(config) |
|||
} else if (typeof action === 'string') { |
|||
if (typeof data[action] === 'undefined') { |
|||
throw new TypeError(`No method named "${action}"`) |
|||
} |
|||
|
|||
data[action]() |
|||
} else if (_config.interval && _config.ride) { |
|||
data.pause() |
|||
data.cycle() |
|||
} |
|||
}) |
|||
} |
|||
|
|||
static _dataApiClickHandler(event) { |
|||
const selector = Util.getSelectorFromElement(this) |
|||
|
|||
if (!selector) { |
|||
return |
|||
} |
|||
|
|||
const target = $(selector)[0] |
|||
|
|||
if (!target || !$(target).hasClass(CLASS_NAME_CAROUSEL)) { |
|||
return |
|||
} |
|||
|
|||
const config = { |
|||
...$(target).data(), |
|||
...$(this).data() |
|||
} |
|||
const slideIndex = this.getAttribute('data-slide-to') |
|||
|
|||
if (slideIndex) { |
|||
config.interval = false |
|||
} |
|||
|
|||
Carousel._jQueryInterface.call($(target), config) |
|||
|
|||
if (slideIndex) { |
|||
$(target).data(DATA_KEY).to(slideIndex) |
|||
} |
|||
|
|||
event.preventDefault() |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Data Api implementation |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, Carousel._dataApiClickHandler) |
|||
|
|||
$(window).on(EVENT_LOAD_DATA_API, () => { |
|||
const carousels = [].slice.call(document.querySelectorAll(SELECTOR_DATA_RIDE)) |
|||
for (let i = 0, len = carousels.length; i < len; i++) { |
|||
const $carousel = $(carousels[i]) |
|||
Carousel._jQueryInterface.call($carousel, $carousel.data()) |
|||
} |
|||
}) |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* jQuery |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
$.fn[NAME] = Carousel._jQueryInterface |
|||
$.fn[NAME].Constructor = Carousel |
|||
$.fn[NAME].noConflict = () => { |
|||
$.fn[NAME] = JQUERY_NO_CONFLICT |
|||
return Carousel._jQueryInterface |
|||
} |
|||
|
|||
export default Carousel |
@ -0,0 +1,392 @@ |
|||
/** |
|||
* -------------------------------------------------------------------------- |
|||
* Bootstrap (v4.6.0): collapse.js |
|||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|||
* -------------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
import $ from 'jquery' |
|||
import Util from './util' |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Constants |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
const NAME = 'collapse' |
|||
const VERSION = '4.6.0' |
|||
const DATA_KEY = 'bs.collapse' |
|||
const EVENT_KEY = `.${DATA_KEY}` |
|||
const DATA_API_KEY = '.data-api' |
|||
const JQUERY_NO_CONFLICT = $.fn[NAME] |
|||
|
|||
const Default = { |
|||
toggle: true, |
|||
parent: '' |
|||
} |
|||
|
|||
const DefaultType = { |
|||
toggle: 'boolean', |
|||
parent: '(string|element)' |
|||
} |
|||
|
|||
const EVENT_SHOW = `show${EVENT_KEY}` |
|||
const EVENT_SHOWN = `shown${EVENT_KEY}` |
|||
const EVENT_HIDE = `hide${EVENT_KEY}` |
|||
const EVENT_HIDDEN = `hidden${EVENT_KEY}` |
|||
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` |
|||
|
|||
const CLASS_NAME_SHOW = 'show' |
|||
const CLASS_NAME_COLLAPSE = 'collapse' |
|||
const CLASS_NAME_COLLAPSING = 'collapsing' |
|||
const CLASS_NAME_COLLAPSED = 'collapsed' |
|||
|
|||
const DIMENSION_WIDTH = 'width' |
|||
const DIMENSION_HEIGHT = 'height' |
|||
|
|||
const SELECTOR_ACTIVES = '.show, .collapsing' |
|||
const SELECTOR_DATA_TOGGLE = '[data-toggle="collapse"]' |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Class Definition |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
class Collapse { |
|||
constructor(element, config) { |
|||
this._isTransitioning = false |
|||
this._element = element |
|||
this._config = this._getConfig(config) |
|||
this._triggerArray = [].slice.call(document.querySelectorAll( |
|||
`[data-toggle="collapse"][href="#${element.id}"],` + |
|||
`[data-toggle="collapse"][data-target="#${element.id}"]` |
|||
)) |
|||
|
|||
const toggleList = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE)) |
|||
for (let i = 0, len = toggleList.length; i < len; i++) { |
|||
const elem = toggleList[i] |
|||
const selector = Util.getSelectorFromElement(elem) |
|||
const filterElement = [].slice.call(document.querySelectorAll(selector)) |
|||
.filter(foundElem => foundElem === element) |
|||
|
|||
if (selector !== null && filterElement.length > 0) { |
|||
this._selector = selector |
|||
this._triggerArray.push(elem) |
|||
} |
|||
} |
|||
|
|||
this._parent = this._config.parent ? this._getParent() : null |
|||
|
|||
if (!this._config.parent) { |
|||
this._addAriaAndCollapsedClass(this._element, this._triggerArray) |
|||
} |
|||
|
|||
if (this._config.toggle) { |
|||
this.toggle() |
|||
} |
|||
} |
|||
|
|||
// Getters
|
|||
|
|||
static get VERSION() { |
|||
return VERSION |
|||
} |
|||
|
|||
static get Default() { |
|||
return Default |
|||
} |
|||
|
|||
// Public
|
|||
|
|||
toggle() { |
|||
if ($(this._element).hasClass(CLASS_NAME_SHOW)) { |
|||
this.hide() |
|||
} else { |
|||
this.show() |
|||
} |
|||
} |
|||
|
|||
show() { |
|||
if (this._isTransitioning || |
|||
$(this._element).hasClass(CLASS_NAME_SHOW)) { |
|||
return |
|||
} |
|||
|
|||
let actives |
|||
let activesData |
|||
|
|||
if (this._parent) { |
|||
actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES)) |
|||
.filter(elem => { |
|||
if (typeof this._config.parent === 'string') { |
|||
return elem.getAttribute('data-parent') === this._config.parent |
|||
} |
|||
|
|||
return elem.classList.contains(CLASS_NAME_COLLAPSE) |
|||
}) |
|||
|
|||
if (actives.length === 0) { |
|||
actives = null |
|||
} |
|||
} |
|||
|
|||
if (actives) { |
|||
activesData = $(actives).not(this._selector).data(DATA_KEY) |
|||
if (activesData && activesData._isTransitioning) { |
|||
return |
|||
} |
|||
} |
|||
|
|||
const startEvent = $.Event(EVENT_SHOW) |
|||
$(this._element).trigger(startEvent) |
|||
if (startEvent.isDefaultPrevented()) { |
|||
return |
|||
} |
|||
|
|||
if (actives) { |
|||
Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide') |
|||
if (!activesData) { |
|||
$(actives).data(DATA_KEY, null) |
|||
} |
|||
} |
|||
|
|||
const dimension = this._getDimension() |
|||
|
|||
$(this._element) |
|||
.removeClass(CLASS_NAME_COLLAPSE) |
|||
.addClass(CLASS_NAME_COLLAPSING) |
|||
|
|||
this._element.style[dimension] = 0 |
|||
|
|||
if (this._triggerArray.length) { |
|||
$(this._triggerArray) |
|||
.removeClass(CLASS_NAME_COLLAPSED) |
|||
.attr('aria-expanded', true) |
|||
} |
|||
|
|||
this.setTransitioning(true) |
|||
|
|||
const complete = () => { |
|||
$(this._element) |
|||
.removeClass(CLASS_NAME_COLLAPSING) |
|||
.addClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`) |
|||
|
|||
this._element.style[dimension] = '' |
|||
|
|||
this.setTransitioning(false) |
|||
|
|||
$(this._element).trigger(EVENT_SHOWN) |
|||
} |
|||
|
|||
const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1) |
|||
const scrollSize = `scroll${capitalizedDimension}` |
|||
const transitionDuration = Util.getTransitionDurationFromElement(this._element) |
|||
|
|||
$(this._element) |
|||
.one(Util.TRANSITION_END, complete) |
|||
.emulateTransitionEnd(transitionDuration) |
|||
|
|||
this._element.style[dimension] = `${this._element[scrollSize]}px` |
|||
} |
|||
|
|||
hide() { |
|||
if (this._isTransitioning || |
|||
!$(this._element).hasClass(CLASS_NAME_SHOW)) { |
|||
return |
|||
} |
|||
|
|||
const startEvent = $.Event(EVENT_HIDE) |
|||
$(this._element).trigger(startEvent) |
|||
if (startEvent.isDefaultPrevented()) { |
|||
return |
|||
} |
|||
|
|||
const dimension = this._getDimension() |
|||
|
|||
this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px` |
|||
|
|||
Util.reflow(this._element) |
|||
|
|||
$(this._element) |
|||
.addClass(CLASS_NAME_COLLAPSING) |
|||
.removeClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`) |
|||
|
|||
const triggerArrayLength = this._triggerArray.length |
|||
if (triggerArrayLength > 0) { |
|||
for (let i = 0; i < triggerArrayLength; i++) { |
|||
const trigger = this._triggerArray[i] |
|||
const selector = Util.getSelectorFromElement(trigger) |
|||
|
|||
if (selector !== null) { |
|||
const $elem = $([].slice.call(document.querySelectorAll(selector))) |
|||
if (!$elem.hasClass(CLASS_NAME_SHOW)) { |
|||
$(trigger).addClass(CLASS_NAME_COLLAPSED) |
|||
.attr('aria-expanded', false) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
this.setTransitioning(true) |
|||
|
|||
const complete = () => { |
|||
this.setTransitioning(false) |
|||
$(this._element) |
|||
.removeClass(CLASS_NAME_COLLAPSING) |
|||
.addClass(CLASS_NAME_COLLAPSE) |
|||
.trigger(EVENT_HIDDEN) |
|||
} |
|||
|
|||
this._element.style[dimension] = '' |
|||
const transitionDuration = Util.getTransitionDurationFromElement(this._element) |
|||
|
|||
$(this._element) |
|||
.one(Util.TRANSITION_END, complete) |
|||
.emulateTransitionEnd(transitionDuration) |
|||
} |
|||
|
|||
setTransitioning(isTransitioning) { |
|||
this._isTransitioning = isTransitioning |
|||
} |
|||
|
|||
dispose() { |
|||
$.removeData(this._element, DATA_KEY) |
|||
|
|||
this._config = null |
|||
this._parent = null |
|||
this._element = null |
|||
this._triggerArray = null |
|||
this._isTransitioning = null |
|||
} |
|||
|
|||
// Private
|
|||
|
|||
_getConfig(config) { |
|||
config = { |
|||
...Default, |
|||
...config |
|||
} |
|||
config.toggle = Boolean(config.toggle) // Coerce string values
|
|||
Util.typeCheckConfig(NAME, config, DefaultType) |
|||
return config |
|||
} |
|||
|
|||
_getDimension() { |
|||
const hasWidth = $(this._element).hasClass(DIMENSION_WIDTH) |
|||
return hasWidth ? DIMENSION_WIDTH : DIMENSION_HEIGHT |
|||
} |
|||
|
|||
_getParent() { |
|||
let parent |
|||
|
|||
if (Util.isElement(this._config.parent)) { |
|||
parent = this._config.parent |
|||
|
|||
// It's a jQuery object
|
|||
if (typeof this._config.parent.jquery !== 'undefined') { |
|||
parent = this._config.parent[0] |
|||
} |
|||
} else { |
|||
parent = document.querySelector(this._config.parent) |
|||
} |
|||
|
|||
const selector = `[data-toggle="collapse"][data-parent="${this._config.parent}"]` |
|||
const children = [].slice.call(parent.querySelectorAll(selector)) |
|||
|
|||
$(children).each((i, element) => { |
|||
this._addAriaAndCollapsedClass( |
|||
Collapse._getTargetFromElement(element), |
|||
[element] |
|||
) |
|||
}) |
|||
|
|||
return parent |
|||
} |
|||
|
|||
_addAriaAndCollapsedClass(element, triggerArray) { |
|||
const isOpen = $(element).hasClass(CLASS_NAME_SHOW) |
|||
|
|||
if (triggerArray.length) { |
|||
$(triggerArray) |
|||
.toggleClass(CLASS_NAME_COLLAPSED, !isOpen) |
|||
.attr('aria-expanded', isOpen) |
|||
} |
|||
} |
|||
|
|||
// Static
|
|||
|
|||
static _getTargetFromElement(element) { |
|||
const selector = Util.getSelectorFromElement(element) |
|||
return selector ? document.querySelector(selector) : null |
|||
} |
|||
|
|||
static _jQueryInterface(config) { |
|||
return this.each(function () { |
|||
const $element = $(this) |
|||
let data = $element.data(DATA_KEY) |
|||
const _config = { |
|||
...Default, |
|||
...$element.data(), |
|||
...(typeof config === 'object' && config ? config : {}) |
|||
} |
|||
|
|||
if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) { |
|||
_config.toggle = false |
|||
} |
|||
|
|||
if (!data) { |
|||
data = new Collapse(this, _config) |
|||
$element.data(DATA_KEY, data) |
|||
} |
|||
|
|||
if (typeof config === 'string') { |
|||
if (typeof data[config] === 'undefined') { |
|||
throw new TypeError(`No method named "${config}"`) |
|||
} |
|||
|
|||
data[config]() |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Data Api implementation |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { |
|||
// preventDefault only for <a> elements (which change the URL) not inside the collapsible element
|
|||
if (event.currentTarget.tagName === 'A') { |
|||
event.preventDefault() |
|||
} |
|||
|
|||
const $trigger = $(this) |
|||
const selector = Util.getSelectorFromElement(this) |
|||
const selectors = [].slice.call(document.querySelectorAll(selector)) |
|||
|
|||
$(selectors).each(function () { |
|||
const $target = $(this) |
|||
const data = $target.data(DATA_KEY) |
|||
const config = data ? 'toggle' : $trigger.data() |
|||
Collapse._jQueryInterface.call($target, config) |
|||
}) |
|||
}) |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* jQuery |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
$.fn[NAME] = Collapse._jQueryInterface |
|||
$.fn[NAME].Constructor = Collapse |
|||
$.fn[NAME].noConflict = () => { |
|||
$.fn[NAME] = JQUERY_NO_CONFLICT |
|||
return Collapse._jQueryInterface |
|||
} |
|||
|
|||
export default Collapse |
@ -0,0 +1,538 @@ |
|||
/** |
|||
* -------------------------------------------------------------------------- |
|||
* Bootstrap (v4.6.0): dropdown.js |
|||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|||
* -------------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
import $ from 'jquery' |
|||
import Popper from 'core/popper' |
|||
import Util from './util' |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Constants |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
const NAME = 'dropdown' |
|||
const VERSION = '4.6.0' |
|||
const DATA_KEY = 'bs.dropdown' |
|||
const EVENT_KEY = `.${DATA_KEY}` |
|||
const DATA_API_KEY = '.data-api' |
|||
const JQUERY_NO_CONFLICT = $.fn[NAME] |
|||
const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key
|
|||
const SPACE_KEYCODE = 32 // KeyboardEvent.which value for space key
|
|||
const TAB_KEYCODE = 9 // KeyboardEvent.which value for tab key
|
|||
const ARROW_UP_KEYCODE = 38 // KeyboardEvent.which value for up arrow key
|
|||
const ARROW_DOWN_KEYCODE = 40 // KeyboardEvent.which value for down arrow key
|
|||
const RIGHT_MOUSE_BUTTON_WHICH = 3 // MouseEvent.which value for the right button (assuming a right-handed mouse)
|
|||
const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEYCODE}|${ARROW_DOWN_KEYCODE}|${ESCAPE_KEYCODE}`) |
|||
|
|||
const EVENT_HIDE = `hide${EVENT_KEY}` |
|||
const EVENT_HIDDEN = `hidden${EVENT_KEY}` |
|||
const EVENT_SHOW = `show${EVENT_KEY}` |
|||
const EVENT_SHOWN = `shown${EVENT_KEY}` |
|||
const EVENT_CLICK = `click${EVENT_KEY}` |
|||
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` |
|||
const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY}${DATA_API_KEY}` |
|||
const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY}${DATA_API_KEY}` |
|||
|
|||
const CLASS_NAME_DISABLED = 'disabled' |
|||
const CLASS_NAME_SHOW = 'show' |
|||
const CLASS_NAME_DROPUP = 'dropup' |
|||
const CLASS_NAME_DROPRIGHT = 'dropright' |
|||
const CLASS_NAME_DROPLEFT = 'dropleft' |
|||
const CLASS_NAME_MENURIGHT = 'dropdown-menu-right' |
|||
const CLASS_NAME_POSITION_STATIC = 'position-static' |
|||
|
|||
const SELECTOR_DATA_TOGGLE = '[data-toggle="dropdown"]' |
|||
const SELECTOR_FORM_CHILD = '.dropdown form' |
|||
const SELECTOR_MENU = '.dropdown-menu' |
|||
const SELECTOR_NAVBAR_NAV = '.navbar-nav' |
|||
const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)' |
|||
|
|||
const PLACEMENT_TOP = 'top-start' |
|||
const PLACEMENT_TOPEND = 'top-end' |
|||
const PLACEMENT_BOTTOM = 'bottom-start' |
|||
const PLACEMENT_BOTTOMEND = 'bottom-end' |
|||
const PLACEMENT_RIGHT = 'right-start' |
|||
const PLACEMENT_LEFT = 'left-start' |
|||
|
|||
const Default = { |
|||
offset: 0, |
|||
flip: true, |
|||
boundary: 'scrollParent', |
|||
reference: 'toggle', |
|||
display: 'dynamic', |
|||
popperConfig: null |
|||
} |
|||
|
|||
const DefaultType = { |
|||
offset: '(number|string|function)', |
|||
flip: 'boolean', |
|||
boundary: '(string|element)', |
|||
reference: '(string|element)', |
|||
display: 'string', |
|||
popperConfig: '(null|object)' |
|||
} |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Class Definition |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
class Dropdown { |
|||
constructor(element, config) { |
|||
this._element = element |
|||
this._popper = null |
|||
this._config = this._getConfig(config) |
|||
this._menu = this._getMenuElement() |
|||
this._inNavbar = this._detectNavbar() |
|||
|
|||
this._addEventListeners() |
|||
} |
|||
|
|||
// Getters
|
|||
|
|||
static get VERSION() { |
|||
return VERSION |
|||
} |
|||
|
|||
static get Default() { |
|||
return Default |
|||
} |
|||
|
|||
static get DefaultType() { |
|||
return DefaultType |
|||
} |
|||
|
|||
// Public
|
|||
|
|||
toggle() { |
|||
if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED)) { |
|||
return |
|||
} |
|||
|
|||
const isActive = $(this._menu).hasClass(CLASS_NAME_SHOW) |
|||
|
|||
Dropdown._clearMenus() |
|||
|
|||
if (isActive) { |
|||
return |
|||
} |
|||
|
|||
this.show(true) |
|||
} |
|||
|
|||
show(usePopper = false) { |
|||
if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || $(this._menu).hasClass(CLASS_NAME_SHOW)) { |
|||
return |
|||
} |
|||
|
|||
const relatedTarget = { |
|||
relatedTarget: this._element |
|||
} |
|||
const showEvent = $.Event(EVENT_SHOW, relatedTarget) |
|||
const parent = Dropdown._getParentFromElement(this._element) |
|||
|
|||
$(parent).trigger(showEvent) |
|||
|
|||
if (showEvent.isDefaultPrevented()) { |
|||
return |
|||
} |
|||
|
|||
// Totally disable Popper for Dropdowns 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 (https://popper.js.org)') |
|||
} |
|||
|
|||
let 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)) |
|||
} |
|||
|
|||
hide() { |
|||
if (this._element.disabled || $(this._element).hasClass(CLASS_NAME_DISABLED) || !$(this._menu).hasClass(CLASS_NAME_SHOW)) { |
|||
return |
|||
} |
|||
|
|||
const relatedTarget = { |
|||
relatedTarget: this._element |
|||
} |
|||
const hideEvent = $.Event(EVENT_HIDE, relatedTarget) |
|||
const 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)) |
|||
} |
|||
|
|||
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 |
|||
} |
|||
} |
|||
|
|||
update() { |
|||
this._inNavbar = this._detectNavbar() |
|||
if (this._popper !== null) { |
|||
this._popper.scheduleUpdate() |
|||
} |
|||
} |
|||
|
|||
// Private
|
|||
|
|||
_addEventListeners() { |
|||
$(this._element).on(EVENT_CLICK, event => { |
|||
event.preventDefault() |
|||
event.stopPropagation() |
|||
this.toggle() |
|||
}) |
|||
} |
|||
|
|||
_getConfig(config) { |
|||
config = { |
|||
...this.constructor.Default, |
|||
...$(this._element).data(), |
|||
...config |
|||
} |
|||
|
|||
Util.typeCheckConfig( |
|||
NAME, |
|||
config, |
|||
this.constructor.DefaultType |
|||
) |
|||
|
|||
return config |
|||
} |
|||
|
|||
_getMenuElement() { |
|||
if (!this._menu) { |
|||
const parent = Dropdown._getParentFromElement(this._element) |
|||
|
|||
if (parent) { |
|||
this._menu = parent.querySelector(SELECTOR_MENU) |
|||
} |
|||
} |
|||
|
|||
return this._menu |
|||
} |
|||
|
|||
_getPlacement() { |
|||
const $parentDropdown = $(this._element.parentNode) |
|||
let 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 |
|||
} |
|||
|
|||
_detectNavbar() { |
|||
return $(this._element).closest('.navbar').length > 0 |
|||
} |
|||
|
|||
_getOffset() { |
|||
const offset = {} |
|||
|
|||
if (typeof this._config.offset === 'function') { |
|||
offset.fn = data => { |
|||
data.offsets = { |
|||
...data.offsets, |
|||
...(this._config.offset(data.offsets, this._element) || {}) |
|||
} |
|||
|
|||
return data |
|||
} |
|||
} else { |
|||
offset.offset = this._config.offset |
|||
} |
|||
|
|||
return offset |
|||
} |
|||
|
|||
_getPopperConfig() { |
|||
const popperConfig = { |
|||
placement: this._getPlacement(), |
|||
modifiers: { |
|||
offset: this._getOffset(), |
|||
flip: { |
|||
enabled: this._config.flip |
|||
}, |
|||
preventOverflow: { |
|||
boundariesElement: this._config.boundary |
|||
} |
|||
} |
|||
} |
|||
|
|||
// Disable Popper if we have a static display
|
|||
if (this._config.display === 'static') { |
|||
popperConfig.modifiers.applyStyle = { |
|||
enabled: false |
|||
} |
|||
} |
|||
|
|||
return { |
|||
...popperConfig, |
|||
...this._config.popperConfig |
|||
} |
|||
} |
|||
|
|||
// Static
|
|||
|
|||
static _jQueryInterface(config) { |
|||
return this.each(function () { |
|||
let data = $(this).data(DATA_KEY) |
|||
const _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]() |
|||
} |
|||
}) |
|||
} |
|||
|
|||
static _clearMenus(event) { |
|||
if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || |
|||
event.type === 'keyup' && event.which !== TAB_KEYCODE)) { |
|||
return |
|||
} |
|||
|
|||
const toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE)) |
|||
|
|||
for (let i = 0, len = toggles.length; i < len; i++) { |
|||
const parent = Dropdown._getParentFromElement(toggles[i]) |
|||
const context = $(toggles[i]).data(DATA_KEY) |
|||
const relatedTarget = { |
|||
relatedTarget: toggles[i] |
|||
} |
|||
|
|||
if (event && event.type === 'click') { |
|||
relatedTarget.clickEvent = event |
|||
} |
|||
|
|||
if (!context) { |
|||
continue |
|||
} |
|||
|
|||
const 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 |
|||
} |
|||
|
|||
const 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)) |
|||
} |
|||
} |
|||
|
|||
static _getParentFromElement(element) { |
|||
let parent |
|||
const selector = Util.getSelectorFromElement(element) |
|||
|
|||
if (selector) { |
|||
parent = document.querySelector(selector) |
|||
} |
|||
|
|||
return parent || element.parentNode |
|||
} |
|||
|
|||
// eslint-disable-next-line complexity
|
|||
static _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 |
|||
} |
|||
|
|||
const parent = Dropdown._getParentFromElement(this) |
|||
const isActive = $(parent).hasClass(CLASS_NAME_SHOW) |
|||
|
|||
if (!isActive && event.which === ESCAPE_KEYCODE) { |
|||
return |
|||
} |
|||
|
|||
event.preventDefault() |
|||
event.stopPropagation() |
|||
|
|||
if (!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 |
|||
} |
|||
|
|||
const items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS)) |
|||
.filter(item => $(item).is(':visible')) |
|||
|
|||
if (items.length === 0) { |
|||
return |
|||
} |
|||
|
|||
let 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() |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* 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, e => { |
|||
e.stopPropagation() |
|||
}) |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* jQuery |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
$.fn[NAME] = Dropdown._jQueryInterface |
|||
$.fn[NAME].Constructor = Dropdown |
|||
$.fn[NAME].noConflict = () => { |
|||
$.fn[NAME] = JQUERY_NO_CONFLICT |
|||
return Dropdown._jQueryInterface |
|||
} |
|||
|
|||
export default Dropdown |
@ -0,0 +1,629 @@ |
|||
/** |
|||
* -------------------------------------------------------------------------- |
|||
* Bootstrap (v4.6.0): modal.js |
|||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|||
* -------------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
import $ from 'jquery' |
|||
import Util from './util' |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Constants |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
const NAME = 'modal' |
|||
const VERSION = '4.6.0' |
|||
const DATA_KEY = 'bs.modal' |
|||
const EVENT_KEY = `.${DATA_KEY}` |
|||
const DATA_API_KEY = '.data-api' |
|||
const JQUERY_NO_CONFLICT = $.fn[NAME] |
|||
const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key
|
|||
|
|||
const Default = { |
|||
backdrop: true, |
|||
keyboard: true, |
|||
focus: true, |
|||
show: true |
|||
} |
|||
|
|||
const DefaultType = { |
|||
backdrop: '(boolean|string)', |
|||
keyboard: 'boolean', |
|||
focus: 'boolean', |
|||
show: 'boolean' |
|||
} |
|||
|
|||
const EVENT_HIDE = `hide${EVENT_KEY}` |
|||
const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}` |
|||
const EVENT_HIDDEN = `hidden${EVENT_KEY}` |
|||
const EVENT_SHOW = `show${EVENT_KEY}` |
|||
const EVENT_SHOWN = `shown${EVENT_KEY}` |
|||
const EVENT_FOCUSIN = `focusin${EVENT_KEY}` |
|||
const EVENT_RESIZE = `resize${EVENT_KEY}` |
|||
const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}` |
|||
const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}` |
|||
const EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}` |
|||
const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}` |
|||
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` |
|||
|
|||
const CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable' |
|||
const CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure' |
|||
const CLASS_NAME_BACKDROP = 'modal-backdrop' |
|||
const CLASS_NAME_OPEN = 'modal-open' |
|||
const CLASS_NAME_FADE = 'fade' |
|||
const CLASS_NAME_SHOW = 'show' |
|||
const CLASS_NAME_STATIC = 'modal-static' |
|||
|
|||
const SELECTOR_DIALOG = '.modal-dialog' |
|||
const SELECTOR_MODAL_BODY = '.modal-body' |
|||
const SELECTOR_DATA_TOGGLE = '[data-toggle="modal"]' |
|||
const SELECTOR_DATA_DISMISS = '[data-dismiss="modal"]' |
|||
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top' |
|||
const SELECTOR_STICKY_CONTENT = '.sticky-top' |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Class Definition |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
class Modal { |
|||
constructor(element, config) { |
|||
this._config = this._getConfig(config) |
|||
this._element = element |
|||
this._dialog = element.querySelector(SELECTOR_DIALOG) |
|||
this._backdrop = null |
|||
this._isShown = false |
|||
this._isBodyOverflowing = false |
|||
this._ignoreBackdropClick = false |
|||
this._isTransitioning = false |
|||
this._scrollbarWidth = 0 |
|||
} |
|||
|
|||
// Getters
|
|||
|
|||
static get VERSION() { |
|||
return VERSION |
|||
} |
|||
|
|||
static get Default() { |
|||
return Default |
|||
} |
|||
|
|||
// Public
|
|||
|
|||
toggle(relatedTarget) { |
|||
return this._isShown ? this.hide() : this.show(relatedTarget) |
|||
} |
|||
|
|||
show(relatedTarget) { |
|||
if (this._isShown || this._isTransitioning) { |
|||
return |
|||
} |
|||
|
|||
if ($(this._element).hasClass(CLASS_NAME_FADE)) { |
|||
this._isTransitioning = true |
|||
} |
|||
|
|||
const showEvent = $.Event(EVENT_SHOW, { |
|||
relatedTarget |
|||
}) |
|||
|
|||
$(this._element).trigger(showEvent) |
|||
|
|||
if (this._isShown || showEvent.isDefaultPrevented()) { |
|||
return |
|||
} |
|||
|
|||
this._isShown = true |
|||
|
|||
this._checkScrollbar() |
|||
this._setScrollbar() |
|||
|
|||
this._adjustDialog() |
|||
|
|||
this._setEscapeEvent() |
|||
this._setResizeEvent() |
|||
|
|||
$(this._element).on( |
|||
EVENT_CLICK_DISMISS, |
|||
SELECTOR_DATA_DISMISS, |
|||
event => this.hide(event) |
|||
) |
|||
|
|||
$(this._dialog).on(EVENT_MOUSEDOWN_DISMISS, () => { |
|||
$(this._element).one(EVENT_MOUSEUP_DISMISS, event => { |
|||
if ($(event.target).is(this._element)) { |
|||
this._ignoreBackdropClick = true |
|||
} |
|||
}) |
|||
}) |
|||
|
|||
this._showBackdrop(() => this._showElement(relatedTarget)) |
|||
} |
|||
|
|||
hide(event) { |
|||
if (event) { |
|||
event.preventDefault() |
|||
} |
|||
|
|||
if (!this._isShown || this._isTransitioning) { |
|||
return |
|||
} |
|||
|
|||
const hideEvent = $.Event(EVENT_HIDE) |
|||
|
|||
$(this._element).trigger(hideEvent) |
|||
|
|||
if (!this._isShown || hideEvent.isDefaultPrevented()) { |
|||
return |
|||
} |
|||
|
|||
this._isShown = false |
|||
const transition = $(this._element).hasClass(CLASS_NAME_FADE) |
|||
|
|||
if (transition) { |
|||
this._isTransitioning = true |
|||
} |
|||
|
|||
this._setEscapeEvent() |
|||
this._setResizeEvent() |
|||
|
|||
$(document).off(EVENT_FOCUSIN) |
|||
|
|||
$(this._element).removeClass(CLASS_NAME_SHOW) |
|||
|
|||
$(this._element).off(EVENT_CLICK_DISMISS) |
|||
$(this._dialog).off(EVENT_MOUSEDOWN_DISMISS) |
|||
|
|||
if (transition) { |
|||
const transitionDuration = Util.getTransitionDurationFromElement(this._element) |
|||
|
|||
$(this._element) |
|||
.one(Util.TRANSITION_END, event => this._hideModal(event)) |
|||
.emulateTransitionEnd(transitionDuration) |
|||
} else { |
|||
this._hideModal() |
|||
} |
|||
} |
|||
|
|||
dispose() { |
|||
[window, this._element, this._dialog] |
|||
.forEach(htmlElement => $(htmlElement).off(EVENT_KEY)) |
|||
|
|||
/** |
|||
* `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API` |
|||
* Do not move `document` in `htmlElements` array |
|||
* It will remove `EVENT_CLICK_DATA_API` event that should remain |
|||
*/ |
|||
$(document).off(EVENT_FOCUSIN) |
|||
|
|||
$.removeData(this._element, DATA_KEY) |
|||
|
|||
this._config = null |
|||
this._element = null |
|||
this._dialog = null |
|||
this._backdrop = null |
|||
this._isShown = null |
|||
this._isBodyOverflowing = null |
|||
this._ignoreBackdropClick = null |
|||
this._isTransitioning = null |
|||
this._scrollbarWidth = null |
|||
} |
|||
|
|||
handleUpdate() { |
|||
this._adjustDialog() |
|||
} |
|||
|
|||
// Private
|
|||
|
|||
_getConfig(config) { |
|||
config = { |
|||
...Default, |
|||
...config |
|||
} |
|||
Util.typeCheckConfig(NAME, config, DefaultType) |
|||
return config |
|||
} |
|||
|
|||
_triggerBackdropTransition() { |
|||
const hideEventPrevented = $.Event(EVENT_HIDE_PREVENTED) |
|||
|
|||
$(this._element).trigger(hideEventPrevented) |
|||
if (hideEventPrevented.isDefaultPrevented()) { |
|||
return |
|||
} |
|||
|
|||
const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight |
|||
|
|||
if (!isModalOverflowing) { |
|||
this._element.style.overflowY = 'hidden' |
|||
} |
|||
|
|||
this._element.classList.add(CLASS_NAME_STATIC) |
|||
|
|||
const modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog) |
|||
$(this._element).off(Util.TRANSITION_END) |
|||
|
|||
$(this._element).one(Util.TRANSITION_END, () => { |
|||
this._element.classList.remove(CLASS_NAME_STATIC) |
|||
if (!isModalOverflowing) { |
|||
$(this._element).one(Util.TRANSITION_END, () => { |
|||
this._element.style.overflowY = '' |
|||
}) |
|||
.emulateTransitionEnd(this._element, modalTransitionDuration) |
|||
} |
|||
}) |
|||
.emulateTransitionEnd(modalTransitionDuration) |
|||
this._element.focus() |
|||
} |
|||
|
|||
_showElement(relatedTarget) { |
|||
const transition = $(this._element).hasClass(CLASS_NAME_FADE) |
|||
const modalBody = this._dialog ? this._dialog.querySelector(SELECTOR_MODAL_BODY) : null |
|||
|
|||
if (!this._element.parentNode || |
|||
this._element.parentNode.nodeType !== Node.ELEMENT_NODE) { |
|||
// Don't move modal's DOM position
|
|||
document.body.appendChild(this._element) |
|||
} |
|||
|
|||
this._element.style.display = 'block' |
|||
this._element.removeAttribute('aria-hidden') |
|||
this._element.setAttribute('aria-modal', true) |
|||
this._element.setAttribute('role', 'dialog') |
|||
|
|||
if ($(this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) { |
|||
modalBody.scrollTop = 0 |
|||
} else { |
|||
this._element.scrollTop = 0 |
|||
} |
|||
|
|||
if (transition) { |
|||
Util.reflow(this._element) |
|||
} |
|||
|
|||
$(this._element).addClass(CLASS_NAME_SHOW) |
|||
|
|||
if (this._config.focus) { |
|||
this._enforceFocus() |
|||
} |
|||
|
|||
const shownEvent = $.Event(EVENT_SHOWN, { |
|||
relatedTarget |
|||
}) |
|||
|
|||
const transitionComplete = () => { |
|||
if (this._config.focus) { |
|||
this._element.focus() |
|||
} |
|||
|
|||
this._isTransitioning = false |
|||
$(this._element).trigger(shownEvent) |
|||
} |
|||
|
|||
if (transition) { |
|||
const transitionDuration = Util.getTransitionDurationFromElement(this._dialog) |
|||
|
|||
$(this._dialog) |
|||
.one(Util.TRANSITION_END, transitionComplete) |
|||
.emulateTransitionEnd(transitionDuration) |
|||
} else { |
|||
transitionComplete() |
|||
} |
|||
} |
|||
|
|||
_enforceFocus() { |
|||
$(document) |
|||
.off(EVENT_FOCUSIN) // Guard against infinite focus loop
|
|||
.on(EVENT_FOCUSIN, event => { |
|||
if (document !== event.target && |
|||
this._element !== event.target && |
|||
$(this._element).has(event.target).length === 0) { |
|||
this._element.focus() |
|||
} |
|||
}) |
|||
} |
|||
|
|||
_setEscapeEvent() { |
|||
if (this._isShown) { |
|||
$(this._element).on(EVENT_KEYDOWN_DISMISS, event => { |
|||
if (this._config.keyboard && event.which === ESCAPE_KEYCODE) { |
|||
event.preventDefault() |
|||
this.hide() |
|||
} else if (!this._config.keyboard && event.which === ESCAPE_KEYCODE) { |
|||
this._triggerBackdropTransition() |
|||
} |
|||
}) |
|||
} else if (!this._isShown) { |
|||
$(this._element).off(EVENT_KEYDOWN_DISMISS) |
|||
} |
|||
} |
|||
|
|||
_setResizeEvent() { |
|||
if (this._isShown) { |
|||
$(window).on(EVENT_RESIZE, event => this.handleUpdate(event)) |
|||
} else { |
|||
$(window).off(EVENT_RESIZE) |
|||
} |
|||
} |
|||
|
|||
_hideModal() { |
|||
this._element.style.display = 'none' |
|||
this._element.setAttribute('aria-hidden', true) |
|||
this._element.removeAttribute('aria-modal') |
|||
this._element.removeAttribute('role') |
|||
this._isTransitioning = false |
|||
this._showBackdrop(() => { |
|||
$(document.body).removeClass(CLASS_NAME_OPEN) |
|||
this._resetAdjustments() |
|||
this._resetScrollbar() |
|||
$(this._element).trigger(EVENT_HIDDEN) |
|||
}) |
|||
} |
|||
|
|||
_removeBackdrop() { |
|||
if (this._backdrop) { |
|||
$(this._backdrop).remove() |
|||
this._backdrop = null |
|||
} |
|||
} |
|||
|
|||
_showBackdrop(callback) { |
|||
const animate = $(this._element).hasClass(CLASS_NAME_FADE) ? |
|||
CLASS_NAME_FADE : '' |
|||
|
|||
if (this._isShown && this._config.backdrop) { |
|||
this._backdrop = document.createElement('div') |
|||
this._backdrop.className = CLASS_NAME_BACKDROP |
|||
|
|||
if (animate) { |
|||
this._backdrop.classList.add(animate) |
|||
} |
|||
|
|||
$(this._backdrop).appendTo(document.body) |
|||
|
|||
$(this._element).on(EVENT_CLICK_DISMISS, event => { |
|||
if (this._ignoreBackdropClick) { |
|||
this._ignoreBackdropClick = false |
|||
return |
|||
} |
|||
|
|||
if (event.target !== event.currentTarget) { |
|||
return |
|||
} |
|||
|
|||
if (this._config.backdrop === 'static') { |
|||
this._triggerBackdropTransition() |
|||
} else { |
|||
this.hide() |
|||
} |
|||
}) |
|||
|
|||
if (animate) { |
|||
Util.reflow(this._backdrop) |
|||
} |
|||
|
|||
$(this._backdrop).addClass(CLASS_NAME_SHOW) |
|||
|
|||
if (!callback) { |
|||
return |
|||
} |
|||
|
|||
if (!animate) { |
|||
callback() |
|||
return |
|||
} |
|||
|
|||
const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop) |
|||
|
|||
$(this._backdrop) |
|||
.one(Util.TRANSITION_END, callback) |
|||
.emulateTransitionEnd(backdropTransitionDuration) |
|||
} else if (!this._isShown && this._backdrop) { |
|||
$(this._backdrop).removeClass(CLASS_NAME_SHOW) |
|||
|
|||
const callbackRemove = () => { |
|||
this._removeBackdrop() |
|||
if (callback) { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
if ($(this._element).hasClass(CLASS_NAME_FADE)) { |
|||
const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop) |
|||
|
|||
$(this._backdrop) |
|||
.one(Util.TRANSITION_END, callbackRemove) |
|||
.emulateTransitionEnd(backdropTransitionDuration) |
|||
} else { |
|||
callbackRemove() |
|||
} |
|||
} else if (callback) { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
// ----------------------------------------------------------------------
|
|||
// the following methods are used to handle overflowing modals
|
|||
// todo (fat): these should probably be refactored out of modal.js
|
|||
// ----------------------------------------------------------------------
|
|||
|
|||
_adjustDialog() { |
|||
const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight |
|||
|
|||
if (!this._isBodyOverflowing && isModalOverflowing) { |
|||
this._element.style.paddingLeft = `${this._scrollbarWidth}px` |
|||
} |
|||
|
|||
if (this._isBodyOverflowing && !isModalOverflowing) { |
|||
this._element.style.paddingRight = `${this._scrollbarWidth}px` |
|||
} |
|||
} |
|||
|
|||
_resetAdjustments() { |
|||
this._element.style.paddingLeft = '' |
|||
this._element.style.paddingRight = '' |
|||
} |
|||
|
|||
_checkScrollbar() { |
|||
const rect = document.body.getBoundingClientRect() |
|||
this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth |
|||
this._scrollbarWidth = this._getScrollbarWidth() |
|||
} |
|||
|
|||
_setScrollbar() { |
|||
if (this._isBodyOverflowing) { |
|||
// Note: DOMNode.style.paddingRight returns the actual value or '' if not set
|
|||
// while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set
|
|||
const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT)) |
|||
const stickyContent = [].slice.call(document.querySelectorAll(SELECTOR_STICKY_CONTENT)) |
|||
|
|||
// Adjust fixed content padding
|
|||
$(fixedContent).each((index, element) => { |
|||
const actualPadding = element.style.paddingRight |
|||
const calculatedPadding = $(element).css('padding-right') |
|||
$(element) |
|||
.data('padding-right', actualPadding) |
|||
.css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`) |
|||
}) |
|||
|
|||
// Adjust sticky content margin
|
|||
$(stickyContent).each((index, element) => { |
|||
const actualMargin = element.style.marginRight |
|||
const calculatedMargin = $(element).css('margin-right') |
|||
$(element) |
|||
.data('margin-right', actualMargin) |
|||
.css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`) |
|||
}) |
|||
|
|||
// Adjust body padding
|
|||
const actualPadding = document.body.style.paddingRight |
|||
const calculatedPadding = $(document.body).css('padding-right') |
|||
$(document.body) |
|||
.data('padding-right', actualPadding) |
|||
.css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`) |
|||
} |
|||
|
|||
$(document.body).addClass(CLASS_NAME_OPEN) |
|||
} |
|||
|
|||
_resetScrollbar() { |
|||
// Restore fixed content padding
|
|||
const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT)) |
|||
$(fixedContent).each((index, element) => { |
|||
const padding = $(element).data('padding-right') |
|||
$(element).removeData('padding-right') |
|||
element.style.paddingRight = padding ? padding : '' |
|||
}) |
|||
|
|||
// Restore sticky content
|
|||
const elements = [].slice.call(document.querySelectorAll(`${SELECTOR_STICKY_CONTENT}`)) |
|||
$(elements).each((index, element) => { |
|||
const margin = $(element).data('margin-right') |
|||
if (typeof margin !== 'undefined') { |
|||
$(element).css('margin-right', margin).removeData('margin-right') |
|||
} |
|||
}) |
|||
|
|||
// Restore body padding
|
|||
const padding = $(document.body).data('padding-right') |
|||
$(document.body).removeData('padding-right') |
|||
document.body.style.paddingRight = padding ? padding : '' |
|||
} |
|||
|
|||
_getScrollbarWidth() { // thx d.walsh
|
|||
const scrollDiv = document.createElement('div') |
|||
scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER |
|||
document.body.appendChild(scrollDiv) |
|||
const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth |
|||
document.body.removeChild(scrollDiv) |
|||
return scrollbarWidth |
|||
} |
|||
|
|||
// Static
|
|||
|
|||
static _jQueryInterface(config, relatedTarget) { |
|||
return this.each(function () { |
|||
let data = $(this).data(DATA_KEY) |
|||
const _config = { |
|||
...Default, |
|||
...$(this).data(), |
|||
...(typeof config === 'object' && config ? config : {}) |
|||
} |
|||
|
|||
if (!data) { |
|||
data = new Modal(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](relatedTarget) |
|||
} else if (_config.show) { |
|||
data.show(relatedTarget) |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Data Api implementation |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { |
|||
let target |
|||
const selector = Util.getSelectorFromElement(this) |
|||
|
|||
if (selector) { |
|||
target = document.querySelector(selector) |
|||
} |
|||
|
|||
const config = $(target).data(DATA_KEY) ? |
|||
'toggle' : { |
|||
...$(target).data(), |
|||
...$(this).data() |
|||
} |
|||
|
|||
if (this.tagName === 'A' || this.tagName === 'AREA') { |
|||
event.preventDefault() |
|||
} |
|||
|
|||
const $target = $(target).one(EVENT_SHOW, showEvent => { |
|||
if (showEvent.isDefaultPrevented()) { |
|||
// Only register focus restorer if modal will actually get shown
|
|||
return |
|||
} |
|||
|
|||
$target.one(EVENT_HIDDEN, () => { |
|||
if ($(this).is(':visible')) { |
|||
this.focus() |
|||
} |
|||
}) |
|||
}) |
|||
|
|||
Modal._jQueryInterface.call($(target), config, this) |
|||
}) |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* jQuery |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
$.fn[NAME] = Modal._jQueryInterface |
|||
$.fn[NAME].Constructor = Modal |
|||
$.fn[NAME].noConflict = () => { |
|||
$.fn[NAME] = JQUERY_NO_CONFLICT |
|||
return Modal._jQueryInterface |
|||
} |
|||
|
|||
export default Modal |
@ -0,0 +1,182 @@ |
|||
/** |
|||
* -------------------------------------------------------------------------- |
|||
* Bootstrap (v4.6.0): popover.js |
|||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|||
* -------------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
import $ from 'jquery' |
|||
import Tooltip from './tooltip' |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Constants |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
const NAME = 'popover' |
|||
const VERSION = '4.6.0' |
|||
const DATA_KEY = 'bs.popover' |
|||
const EVENT_KEY = `.${DATA_KEY}` |
|||
const JQUERY_NO_CONFLICT = $.fn[NAME] |
|||
const CLASS_PREFIX = 'bs-popover' |
|||
const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g') |
|||
|
|||
const Default = { |
|||
...Tooltip.Default, |
|||
placement: 'right', |
|||
trigger: 'click', |
|||
content: '', |
|||
template: '<div class="popover" role="tooltip">' + |
|||
'<div class="arrow"></div>' + |
|||
'<h3 class="popover-header"></h3>' + |
|||
'<div class="popover-body"></div></div>' |
|||
} |
|||
|
|||
const DefaultType = { |
|||
...Tooltip.DefaultType, |
|||
content: '(string|element|function)' |
|||
} |
|||
|
|||
const CLASS_NAME_FADE = 'fade' |
|||
const CLASS_NAME_SHOW = 'show' |
|||
|
|||
const SELECTOR_TITLE = '.popover-header' |
|||
const SELECTOR_CONTENT = '.popover-body' |
|||
|
|||
const 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}` |
|||
} |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Class Definition |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
class Popover extends Tooltip { |
|||
// Getters
|
|||
|
|||
static get VERSION() { |
|||
return VERSION |
|||
} |
|||
|
|||
static get Default() { |
|||
return Default |
|||
} |
|||
|
|||
static get NAME() { |
|||
return NAME |
|||
} |
|||
|
|||
static get DATA_KEY() { |
|||
return DATA_KEY |
|||
} |
|||
|
|||
static get Event() { |
|||
return Event |
|||
} |
|||
|
|||
static get EVENT_KEY() { |
|||
return EVENT_KEY |
|||
} |
|||
|
|||
static get DefaultType() { |
|||
return DefaultType |
|||
} |
|||
|
|||
// Overrides
|
|||
|
|||
isWithContent() { |
|||
return this.getTitle() || this._getContent() |
|||
} |
|||
|
|||
addAttachmentClass(attachment) { |
|||
$(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`) |
|||
} |
|||
|
|||
getTipElement() { |
|||
this.tip = this.tip || $(this.config.template)[0] |
|||
return this.tip |
|||
} |
|||
|
|||
setContent() { |
|||
const $tip = $(this.getTipElement()) |
|||
|
|||
// We use append for html objects to maintain js events
|
|||
this.setElementContent($tip.find(SELECTOR_TITLE), this.getTitle()) |
|||
let content = this._getContent() |
|||
if (typeof content === 'function') { |
|||
content = content.call(this.element) |
|||
} |
|||
|
|||
this.setElementContent($tip.find(SELECTOR_CONTENT), content) |
|||
|
|||
$tip.removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`) |
|||
} |
|||
|
|||
// Private
|
|||
|
|||
_getContent() { |
|||
return this.element.getAttribute('data-content') || |
|||
this.config.content |
|||
} |
|||
|
|||
_cleanTipClass() { |
|||
const $tip = $(this.getTipElement()) |
|||
const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX) |
|||
if (tabClass !== null && tabClass.length > 0) { |
|||
$tip.removeClass(tabClass.join('')) |
|||
} |
|||
} |
|||
|
|||
// Static
|
|||
|
|||
static _jQueryInterface(config) { |
|||
return this.each(function () { |
|||
let data = $(this).data(DATA_KEY) |
|||
const _config = typeof config === 'object' ? config : null |
|||
|
|||
if (!data && /dispose|hide/.test(config)) { |
|||
return |
|||
} |
|||
|
|||
if (!data) { |
|||
data = new Popover(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]() |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* jQuery |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
$.fn[NAME] = Popover._jQueryInterface |
|||
$.fn[NAME].Constructor = Popover |
|||
$.fn[NAME].noConflict = () => { |
|||
$.fn[NAME] = JQUERY_NO_CONFLICT |
|||
return Popover._jQueryInterface |
|||
} |
|||
|
|||
export default Popover |
@ -0,0 +1,324 @@ |
|||
/** |
|||
* -------------------------------------------------------------------------- |
|||
* Bootstrap (v4.6.0): scrollspy.js |
|||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|||
* -------------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
import $ from 'jquery' |
|||
import Util from './util' |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Constants |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
const NAME = 'scrollspy' |
|||
const VERSION = '4.6.0' |
|||
const DATA_KEY = 'bs.scrollspy' |
|||
const EVENT_KEY = `.${DATA_KEY}` |
|||
const DATA_API_KEY = '.data-api' |
|||
const JQUERY_NO_CONFLICT = $.fn[NAME] |
|||
|
|||
const Default = { |
|||
offset: 10, |
|||
method: 'auto', |
|||
target: '' |
|||
} |
|||
|
|||
const DefaultType = { |
|||
offset: 'number', |
|||
method: 'string', |
|||
target: '(string|element)' |
|||
} |
|||
|
|||
const EVENT_ACTIVATE = `activate${EVENT_KEY}` |
|||
const EVENT_SCROLL = `scroll${EVENT_KEY}` |
|||
const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}` |
|||
|
|||
const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item' |
|||
const CLASS_NAME_ACTIVE = 'active' |
|||
|
|||
const SELECTOR_DATA_SPY = '[data-spy="scroll"]' |
|||
const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group' |
|||
const SELECTOR_NAV_LINKS = '.nav-link' |
|||
const SELECTOR_NAV_ITEMS = '.nav-item' |
|||
const SELECTOR_LIST_ITEMS = '.list-group-item' |
|||
const SELECTOR_DROPDOWN = '.dropdown' |
|||
const SELECTOR_DROPDOWN_ITEMS = '.dropdown-item' |
|||
const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle' |
|||
|
|||
const METHOD_OFFSET = 'offset' |
|||
const METHOD_POSITION = 'position' |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Class Definition |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
class ScrollSpy { |
|||
constructor(element, config) { |
|||
this._element = element |
|||
this._scrollElement = element.tagName === 'BODY' ? window : element |
|||
this._config = this._getConfig(config) |
|||
this._selector = `${this._config.target} ${SELECTOR_NAV_LINKS},` + |
|||
`${this._config.target} ${SELECTOR_LIST_ITEMS},` + |
|||
`${this._config.target} ${SELECTOR_DROPDOWN_ITEMS}` |
|||
this._offsets = [] |
|||
this._targets = [] |
|||
this._activeTarget = null |
|||
this._scrollHeight = 0 |
|||
|
|||
$(this._scrollElement).on(EVENT_SCROLL, event => this._process(event)) |
|||
|
|||
this.refresh() |
|||
this._process() |
|||
} |
|||
|
|||
// Getters
|
|||
|
|||
static get VERSION() { |
|||
return VERSION |
|||
} |
|||
|
|||
static get Default() { |
|||
return Default |
|||
} |
|||
|
|||
// Public
|
|||
|
|||
refresh() { |
|||
const autoMethod = this._scrollElement === this._scrollElement.window ? |
|||
METHOD_OFFSET : METHOD_POSITION |
|||
|
|||
const offsetMethod = this._config.method === 'auto' ? |
|||
autoMethod : this._config.method |
|||
|
|||
const offsetBase = offsetMethod === METHOD_POSITION ? |
|||
this._getScrollTop() : 0 |
|||
|
|||
this._offsets = [] |
|||
this._targets = [] |
|||
|
|||
this._scrollHeight = this._getScrollHeight() |
|||
|
|||
const targets = [].slice.call(document.querySelectorAll(this._selector)) |
|||
|
|||
targets |
|||
.map(element => { |
|||
let target |
|||
const targetSelector = Util.getSelectorFromElement(element) |
|||
|
|||
if (targetSelector) { |
|||
target = document.querySelector(targetSelector) |
|||
} |
|||
|
|||
if (target) { |
|||
const targetBCR = target.getBoundingClientRect() |
|||
if (targetBCR.width || targetBCR.height) { |
|||
// TODO (fat): remove sketch reliance on jQuery position/offset
|
|||
return [ |
|||
$(target)[offsetMethod]().top + offsetBase, |
|||
targetSelector |
|||
] |
|||
} |
|||
} |
|||
|
|||
return null |
|||
}) |
|||
.filter(item => item) |
|||
.sort((a, b) => a[0] - b[0]) |
|||
.forEach(item => { |
|||
this._offsets.push(item[0]) |
|||
this._targets.push(item[1]) |
|||
}) |
|||
} |
|||
|
|||
dispose() { |
|||
$.removeData(this._element, DATA_KEY) |
|||
$(this._scrollElement).off(EVENT_KEY) |
|||
|
|||
this._element = null |
|||
this._scrollElement = null |
|||
this._config = null |
|||
this._selector = null |
|||
this._offsets = null |
|||
this._targets = null |
|||
this._activeTarget = null |
|||
this._scrollHeight = null |
|||
} |
|||
|
|||
// Private
|
|||
|
|||
_getConfig(config) { |
|||
config = { |
|||
...Default, |
|||
...(typeof config === 'object' && config ? config : {}) |
|||
} |
|||
|
|||
if (typeof config.target !== 'string' && Util.isElement(config.target)) { |
|||
let id = $(config.target).attr('id') |
|||
if (!id) { |
|||
id = Util.getUID(NAME) |
|||
$(config.target).attr('id', id) |
|||
} |
|||
|
|||
config.target = `#${id}` |
|||
} |
|||
|
|||
Util.typeCheckConfig(NAME, config, DefaultType) |
|||
|
|||
return config |
|||
} |
|||
|
|||
_getScrollTop() { |
|||
return this._scrollElement === window ? |
|||
this._scrollElement.pageYOffset : this._scrollElement.scrollTop |
|||
} |
|||
|
|||
_getScrollHeight() { |
|||
return this._scrollElement.scrollHeight || Math.max( |
|||
document.body.scrollHeight, |
|||
document.documentElement.scrollHeight |
|||
) |
|||
} |
|||
|
|||
_getOffsetHeight() { |
|||
return this._scrollElement === window ? |
|||
window.innerHeight : this._scrollElement.getBoundingClientRect().height |
|||
} |
|||
|
|||
_process() { |
|||
const scrollTop = this._getScrollTop() + this._config.offset |
|||
const scrollHeight = this._getScrollHeight() |
|||
const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight() |
|||
|
|||
if (this._scrollHeight !== scrollHeight) { |
|||
this.refresh() |
|||
} |
|||
|
|||
if (scrollTop >= maxScroll) { |
|||
const target = this._targets[this._targets.length - 1] |
|||
|
|||
if (this._activeTarget !== target) { |
|||
this._activate(target) |
|||
} |
|||
|
|||
return |
|||
} |
|||
|
|||
if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) { |
|||
this._activeTarget = null |
|||
this._clear() |
|||
return |
|||
} |
|||
|
|||
for (let i = this._offsets.length; i--;) { |
|||
const isActiveTarget = this._activeTarget !== this._targets[i] && |
|||
scrollTop >= this._offsets[i] && |
|||
(typeof this._offsets[i + 1] === 'undefined' || |
|||
scrollTop < this._offsets[i + 1]) |
|||
|
|||
if (isActiveTarget) { |
|||
this._activate(this._targets[i]) |
|||
} |
|||
} |
|||
} |
|||
|
|||
_activate(target) { |
|||
this._activeTarget = target |
|||
|
|||
this._clear() |
|||
|
|||
const queries = this._selector |
|||
.split(',') |
|||
.map(selector => `${selector}[data-target="${target}"],${selector}[href="${target}"]`) |
|||
|
|||
const $link = $([].slice.call(document.querySelectorAll(queries.join(',')))) |
|||
|
|||
if ($link.hasClass(CLASS_NAME_DROPDOWN_ITEM)) { |
|||
$link.closest(SELECTOR_DROPDOWN) |
|||
.find(SELECTOR_DROPDOWN_TOGGLE) |
|||
.addClass(CLASS_NAME_ACTIVE) |
|||
$link.addClass(CLASS_NAME_ACTIVE) |
|||
} else { |
|||
// Set triggered link as active
|
|||
$link.addClass(CLASS_NAME_ACTIVE) |
|||
// Set triggered links parents as active
|
|||
// With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
|
|||
$link.parents(SELECTOR_NAV_LIST_GROUP) |
|||
.prev(`${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`) |
|||
.addClass(CLASS_NAME_ACTIVE) |
|||
// Handle special case when .nav-link is inside .nav-item
|
|||
$link.parents(SELECTOR_NAV_LIST_GROUP) |
|||
.prev(SELECTOR_NAV_ITEMS) |
|||
.children(SELECTOR_NAV_LINKS) |
|||
.addClass(CLASS_NAME_ACTIVE) |
|||
} |
|||
|
|||
$(this._scrollElement).trigger(EVENT_ACTIVATE, { |
|||
relatedTarget: target |
|||
}) |
|||
} |
|||
|
|||
_clear() { |
|||
[].slice.call(document.querySelectorAll(this._selector)) |
|||
.filter(node => node.classList.contains(CLASS_NAME_ACTIVE)) |
|||
.forEach(node => node.classList.remove(CLASS_NAME_ACTIVE)) |
|||
} |
|||
|
|||
// Static
|
|||
|
|||
static _jQueryInterface(config) { |
|||
return this.each(function () { |
|||
let data = $(this).data(DATA_KEY) |
|||
const _config = typeof config === 'object' && config |
|||
|
|||
if (!data) { |
|||
data = new ScrollSpy(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]() |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Data Api implementation |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
$(window).on(EVENT_LOAD_DATA_API, () => { |
|||
const scrollSpys = [].slice.call(document.querySelectorAll(SELECTOR_DATA_SPY)) |
|||
const scrollSpysLength = scrollSpys.length |
|||
|
|||
for (let i = scrollSpysLength; i--;) { |
|||
const $spy = $(scrollSpys[i]) |
|||
ScrollSpy._jQueryInterface.call($spy, $spy.data()) |
|||
} |
|||
}) |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* jQuery |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
$.fn[NAME] = ScrollSpy._jQueryInterface |
|||
$.fn[NAME].Constructor = ScrollSpy |
|||
$.fn[NAME].noConflict = () => { |
|||
$.fn[NAME] = JQUERY_NO_CONFLICT |
|||
return ScrollSpy._jQueryInterface |
|||
} |
|||
|
|||
export default ScrollSpy |
@ -0,0 +1,255 @@ |
|||
/** |
|||
* -------------------------------------------------------------------------- |
|||
* Bootstrap (v4.6.0): tab.js |
|||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|||
* -------------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
import $ from 'jquery' |
|||
import Util from './util' |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Constants |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
const NAME = 'tab' |
|||
const VERSION = '4.6.0' |
|||
const DATA_KEY = 'bs.tab' |
|||
const EVENT_KEY = `.${DATA_KEY}` |
|||
const DATA_API_KEY = '.data-api' |
|||
const JQUERY_NO_CONFLICT = $.fn[NAME] |
|||
|
|||
const EVENT_HIDE = `hide${EVENT_KEY}` |
|||
const EVENT_HIDDEN = `hidden${EVENT_KEY}` |
|||
const EVENT_SHOW = `show${EVENT_KEY}` |
|||
const EVENT_SHOWN = `shown${EVENT_KEY}` |
|||
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}` |
|||
|
|||
const CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu' |
|||
const CLASS_NAME_ACTIVE = 'active' |
|||
const CLASS_NAME_DISABLED = 'disabled' |
|||
const CLASS_NAME_FADE = 'fade' |
|||
const CLASS_NAME_SHOW = 'show' |
|||
|
|||
const SELECTOR_DROPDOWN = '.dropdown' |
|||
const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group' |
|||
const SELECTOR_ACTIVE = '.active' |
|||
const SELECTOR_ACTIVE_UL = '> li > .active' |
|||
const SELECTOR_DATA_TOGGLE = '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]' |
|||
const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle' |
|||
const SELECTOR_DROPDOWN_ACTIVE_CHILD = '> .dropdown-menu .active' |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Class Definition |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
class Tab { |
|||
constructor(element) { |
|||
this._element = element |
|||
} |
|||
|
|||
// Getters
|
|||
|
|||
static get VERSION() { |
|||
return VERSION |
|||
} |
|||
|
|||
// Public
|
|||
|
|||
show() { |
|||
if (this._element.parentNode && |
|||
this._element.parentNode.nodeType === Node.ELEMENT_NODE && |
|||
$(this._element).hasClass(CLASS_NAME_ACTIVE) || |
|||
$(this._element).hasClass(CLASS_NAME_DISABLED)) { |
|||
return |
|||
} |
|||
|
|||
let target |
|||
let previous |
|||
const listElement = $(this._element).closest(SELECTOR_NAV_LIST_GROUP)[0] |
|||
const selector = Util.getSelectorFromElement(this._element) |
|||
|
|||
if (listElement) { |
|||
const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE |
|||
previous = $.makeArray($(listElement).find(itemSelector)) |
|||
previous = previous[previous.length - 1] |
|||
} |
|||
|
|||
const hideEvent = $.Event(EVENT_HIDE, { |
|||
relatedTarget: this._element |
|||
}) |
|||
|
|||
const showEvent = $.Event(EVENT_SHOW, { |
|||
relatedTarget: previous |
|||
}) |
|||
|
|||
if (previous) { |
|||
$(previous).trigger(hideEvent) |
|||
} |
|||
|
|||
$(this._element).trigger(showEvent) |
|||
|
|||
if (showEvent.isDefaultPrevented() || |
|||
hideEvent.isDefaultPrevented()) { |
|||
return |
|||
} |
|||
|
|||
if (selector) { |
|||
target = document.querySelector(selector) |
|||
} |
|||
|
|||
this._activate( |
|||
this._element, |
|||
listElement |
|||
) |
|||
|
|||
const complete = () => { |
|||
const hiddenEvent = $.Event(EVENT_HIDDEN, { |
|||
relatedTarget: this._element |
|||
}) |
|||
|
|||
const shownEvent = $.Event(EVENT_SHOWN, { |
|||
relatedTarget: previous |
|||
}) |
|||
|
|||
$(previous).trigger(hiddenEvent) |
|||
$(this._element).trigger(shownEvent) |
|||
} |
|||
|
|||
if (target) { |
|||
this._activate(target, target.parentNode, complete) |
|||
} else { |
|||
complete() |
|||
} |
|||
} |
|||
|
|||
dispose() { |
|||
$.removeData(this._element, DATA_KEY) |
|||
this._element = null |
|||
} |
|||
|
|||
// Private
|
|||
|
|||
_activate(element, container, callback) { |
|||
const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ? |
|||
$(container).find(SELECTOR_ACTIVE_UL) : |
|||
$(container).children(SELECTOR_ACTIVE) |
|||
|
|||
const active = activeElements[0] |
|||
const isTransitioning = callback && (active && $(active).hasClass(CLASS_NAME_FADE)) |
|||
const complete = () => this._transitionComplete( |
|||
element, |
|||
active, |
|||
callback |
|||
) |
|||
|
|||
if (active && isTransitioning) { |
|||
const transitionDuration = Util.getTransitionDurationFromElement(active) |
|||
|
|||
$(active) |
|||
.removeClass(CLASS_NAME_SHOW) |
|||
.one(Util.TRANSITION_END, complete) |
|||
.emulateTransitionEnd(transitionDuration) |
|||
} else { |
|||
complete() |
|||
} |
|||
} |
|||
|
|||
_transitionComplete(element, active, callback) { |
|||
if (active) { |
|||
$(active).removeClass(CLASS_NAME_ACTIVE) |
|||
|
|||
const dropdownChild = $(active.parentNode).find( |
|||
SELECTOR_DROPDOWN_ACTIVE_CHILD |
|||
)[0] |
|||
|
|||
if (dropdownChild) { |
|||
$(dropdownChild).removeClass(CLASS_NAME_ACTIVE) |
|||
} |
|||
|
|||
if (active.getAttribute('role') === 'tab') { |
|||
active.setAttribute('aria-selected', false) |
|||
} |
|||
} |
|||
|
|||
$(element).addClass(CLASS_NAME_ACTIVE) |
|||
if (element.getAttribute('role') === 'tab') { |
|||
element.setAttribute('aria-selected', true) |
|||
} |
|||
|
|||
Util.reflow(element) |
|||
|
|||
if (element.classList.contains(CLASS_NAME_FADE)) { |
|||
element.classList.add(CLASS_NAME_SHOW) |
|||
} |
|||
|
|||
if (element.parentNode && $(element.parentNode).hasClass(CLASS_NAME_DROPDOWN_MENU)) { |
|||
const dropdownElement = $(element).closest(SELECTOR_DROPDOWN)[0] |
|||
|
|||
if (dropdownElement) { |
|||
const dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(SELECTOR_DROPDOWN_TOGGLE)) |
|||
|
|||
$(dropdownToggleList).addClass(CLASS_NAME_ACTIVE) |
|||
} |
|||
|
|||
element.setAttribute('aria-expanded', true) |
|||
} |
|||
|
|||
if (callback) { |
|||
callback() |
|||
} |
|||
} |
|||
|
|||
// Static
|
|||
|
|||
static _jQueryInterface(config) { |
|||
return this.each(function () { |
|||
const $this = $(this) |
|||
let data = $this.data(DATA_KEY) |
|||
|
|||
if (!data) { |
|||
data = new Tab(this) |
|||
$this.data(DATA_KEY, data) |
|||
} |
|||
|
|||
if (typeof config === 'string') { |
|||
if (typeof data[config] === 'undefined') { |
|||
throw new TypeError(`No method named "${config}"`) |
|||
} |
|||
|
|||
data[config]() |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Data Api implementation |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
$(document) |
|||
.on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { |
|||
event.preventDefault() |
|||
Tab._jQueryInterface.call($(this), 'show') |
|||
}) |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* jQuery |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
$.fn[NAME] = Tab._jQueryInterface |
|||
$.fn[NAME].Constructor = Tab |
|||
$.fn[NAME].noConflict = () => { |
|||
$.fn[NAME] = JQUERY_NO_CONFLICT |
|||
return Tab._jQueryInterface |
|||
} |
|||
|
|||
export default Tab |
@ -0,0 +1,230 @@ |
|||
/** |
|||
* -------------------------------------------------------------------------- |
|||
* Bootstrap (v4.6.0): toast.js |
|||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|||
* -------------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
import $ from 'jquery' |
|||
import Util from './util' |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Constants |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
const NAME = 'toast' |
|||
const VERSION = '4.6.0' |
|||
const DATA_KEY = 'bs.toast' |
|||
const EVENT_KEY = `.${DATA_KEY}` |
|||
const JQUERY_NO_CONFLICT = $.fn[NAME] |
|||
|
|||
const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}` |
|||
const EVENT_HIDE = `hide${EVENT_KEY}` |
|||
const EVENT_HIDDEN = `hidden${EVENT_KEY}` |
|||
const EVENT_SHOW = `show${EVENT_KEY}` |
|||
const EVENT_SHOWN = `shown${EVENT_KEY}` |
|||
|
|||
const CLASS_NAME_FADE = 'fade' |
|||
const CLASS_NAME_HIDE = 'hide' |
|||
const CLASS_NAME_SHOW = 'show' |
|||
const CLASS_NAME_SHOWING = 'showing' |
|||
|
|||
const DefaultType = { |
|||
animation: 'boolean', |
|||
autohide: 'boolean', |
|||
delay: 'number' |
|||
} |
|||
|
|||
const Default = { |
|||
animation: true, |
|||
autohide: true, |
|||
delay: 500 |
|||
} |
|||
|
|||
const SELECTOR_DATA_DISMISS = '[data-dismiss="toast"]' |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Class Definition |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
class Toast { |
|||
constructor(element, config) { |
|||
this._element = element |
|||
this._config = this._getConfig(config) |
|||
this._timeout = null |
|||
this._setListeners() |
|||
} |
|||
|
|||
// Getters
|
|||
|
|||
static get VERSION() { |
|||
return VERSION |
|||
} |
|||
|
|||
static get DefaultType() { |
|||
return DefaultType |
|||
} |
|||
|
|||
static get Default() { |
|||
return Default |
|||
} |
|||
|
|||
// Public
|
|||
|
|||
show() { |
|||
const showEvent = $.Event(EVENT_SHOW) |
|||
|
|||
$(this._element).trigger(showEvent) |
|||
if (showEvent.isDefaultPrevented()) { |
|||
return |
|||
} |
|||
|
|||
this._clearTimeout() |
|||
|
|||
if (this._config.animation) { |
|||
this._element.classList.add(CLASS_NAME_FADE) |
|||
} |
|||
|
|||
const complete = () => { |
|||
this._element.classList.remove(CLASS_NAME_SHOWING) |
|||
this._element.classList.add(CLASS_NAME_SHOW) |
|||
|
|||
$(this._element).trigger(EVENT_SHOWN) |
|||
|
|||
if (this._config.autohide) { |
|||
this._timeout = setTimeout(() => { |
|||
this.hide() |
|||
}, this._config.delay) |
|||
} |
|||
} |
|||
|
|||
this._element.classList.remove(CLASS_NAME_HIDE) |
|||
Util.reflow(this._element) |
|||
this._element.classList.add(CLASS_NAME_SHOWING) |
|||
if (this._config.animation) { |
|||
const transitionDuration = Util.getTransitionDurationFromElement(this._element) |
|||
|
|||
$(this._element) |
|||
.one(Util.TRANSITION_END, complete) |
|||
.emulateTransitionEnd(transitionDuration) |
|||
} else { |
|||
complete() |
|||
} |
|||
} |
|||
|
|||
hide() { |
|||
if (!this._element.classList.contains(CLASS_NAME_SHOW)) { |
|||
return |
|||
} |
|||
|
|||
const hideEvent = $.Event(EVENT_HIDE) |
|||
|
|||
$(this._element).trigger(hideEvent) |
|||
if (hideEvent.isDefaultPrevented()) { |
|||
return |
|||
} |
|||
|
|||
this._close() |
|||
} |
|||
|
|||
dispose() { |
|||
this._clearTimeout() |
|||
|
|||
if (this._element.classList.contains(CLASS_NAME_SHOW)) { |
|||
this._element.classList.remove(CLASS_NAME_SHOW) |
|||
} |
|||
|
|||
$(this._element).off(EVENT_CLICK_DISMISS) |
|||
|
|||
$.removeData(this._element, DATA_KEY) |
|||
this._element = null |
|||
this._config = null |
|||
} |
|||
|
|||
// Private
|
|||
|
|||
_getConfig(config) { |
|||
config = { |
|||
...Default, |
|||
...$(this._element).data(), |
|||
...(typeof config === 'object' && config ? config : {}) |
|||
} |
|||
|
|||
Util.typeCheckConfig( |
|||
NAME, |
|||
config, |
|||
this.constructor.DefaultType |
|||
) |
|||
|
|||
return config |
|||
} |
|||
|
|||
_setListeners() { |
|||
$(this._element).on(EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide()) |
|||
} |
|||
|
|||
_close() { |
|||
const complete = () => { |
|||
this._element.classList.add(CLASS_NAME_HIDE) |
|||
$(this._element).trigger(EVENT_HIDDEN) |
|||
} |
|||
|
|||
this._element.classList.remove(CLASS_NAME_SHOW) |
|||
if (this._config.animation) { |
|||
const transitionDuration = Util.getTransitionDurationFromElement(this._element) |
|||
|
|||
$(this._element) |
|||
.one(Util.TRANSITION_END, complete) |
|||
.emulateTransitionEnd(transitionDuration) |
|||
} else { |
|||
complete() |
|||
} |
|||
} |
|||
|
|||
_clearTimeout() { |
|||
clearTimeout(this._timeout) |
|||
this._timeout = null |
|||
} |
|||
|
|||
// Static
|
|||
|
|||
static _jQueryInterface(config) { |
|||
return this.each(function () { |
|||
const $element = $(this) |
|||
let data = $element.data(DATA_KEY) |
|||
const _config = typeof config === 'object' && config |
|||
|
|||
if (!data) { |
|||
data = new Toast(this, _config) |
|||
$element.data(DATA_KEY, data) |
|||
} |
|||
|
|||
if (typeof config === 'string') { |
|||
if (typeof data[config] === 'undefined') { |
|||
throw new TypeError(`No method named "${config}"`) |
|||
} |
|||
|
|||
data[config](this) |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* jQuery |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
$.fn[NAME] = Toast._jQueryInterface |
|||
$.fn[NAME].Constructor = Toast |
|||
$.fn[NAME].noConflict = () => { |
|||
$.fn[NAME] = JQUERY_NO_CONFLICT |
|||
return Toast._jQueryInterface |
|||
} |
|||
|
|||
export default Toast |
@ -0,0 +1,127 @@ |
|||
/** |
|||
* -------------------------------------------------------------------------- |
|||
* Bootstrap (v4.6.0): tools/sanitizer.js |
|||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|||
* -------------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
const uriAttrs = [ |
|||
'background', |
|||
'cite', |
|||
'href', |
|||
'itemtype', |
|||
'longdesc', |
|||
'poster', |
|||
'src', |
|||
'xlink:href' |
|||
] |
|||
|
|||
const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i |
|||
|
|||
export const 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
|
|||
*/ |
|||
const 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
|
|||
*/ |
|||
const 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) { |
|||
const 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 |
|||
} |
|||
|
|||
const regExp = allowedAttributeList.filter(attrRegex => attrRegex instanceof RegExp) |
|||
|
|||
// Check if a regular expression validates the attribute.
|
|||
for (let i = 0, len = regExp.length; i < len; i++) { |
|||
if (attrName.match(regExp[i])) { |
|||
return true |
|||
} |
|||
} |
|||
|
|||
return false |
|||
} |
|||
|
|||
export function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) { |
|||
if (unsafeHtml.length === 0) { |
|||
return unsafeHtml |
|||
} |
|||
|
|||
if (sanitizeFn && typeof sanitizeFn === 'function') { |
|||
return sanitizeFn(unsafeHtml) |
|||
} |
|||
|
|||
const domParser = new window.DOMParser() |
|||
const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html') |
|||
const whitelistKeys = Object.keys(whiteList) |
|||
const elements = [].slice.call(createdDocument.body.querySelectorAll('*')) |
|||
|
|||
for (let i = 0, len = elements.length; i < len; i++) { |
|||
const el = elements[i] |
|||
const elName = el.nodeName.toLowerCase() |
|||
|
|||
if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) { |
|||
el.parentNode.removeChild(el) |
|||
|
|||
continue |
|||
} |
|||
|
|||
const attributeList = [].slice.call(el.attributes) |
|||
const whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []) |
|||
|
|||
attributeList.forEach(attr => { |
|||
if (!allowedAttribute(attr, whitelistedAttributes)) { |
|||
el.removeAttribute(attr.nodeName) |
|||
} |
|||
}) |
|||
} |
|||
|
|||
return createdDocument.body.innerHTML |
|||
} |
@ -0,0 +1,778 @@ |
|||
/** |
|||
* -------------------------------------------------------------------------- |
|||
* Bootstrap (v4.6.0): tooltip.js |
|||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|||
* -------------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
import { |
|||
DefaultWhitelist, |
|||
sanitizeHtml |
|||
} from './tools/sanitizer' |
|||
import $ from 'jquery' |
|||
import Popper from 'core/popper' |
|||
import Util from './util' |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Constants |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
const NAME = 'tooltip' |
|||
const VERSION = '4.6.0' |
|||
const DATA_KEY = 'bs.tooltip' |
|||
const EVENT_KEY = `.${DATA_KEY}` |
|||
const JQUERY_NO_CONFLICT = $.fn[NAME] |
|||
const CLASS_PREFIX = 'bs-tooltip' |
|||
const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g') |
|||
const DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn'] |
|||
|
|||
const 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)', |
|||
customClass: '(string|function)', |
|||
sanitize: 'boolean', |
|||
sanitizeFn: '(null|function)', |
|||
whiteList: 'object', |
|||
popperConfig: '(null|object)' |
|||
} |
|||
|
|||
const AttachmentMap = { |
|||
AUTO: 'auto', |
|||
TOP: 'top', |
|||
RIGHT: 'right', |
|||
BOTTOM: 'bottom', |
|||
LEFT: 'left' |
|||
} |
|||
|
|||
const 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', |
|||
customClass: '', |
|||
sanitize: true, |
|||
sanitizeFn: null, |
|||
whiteList: DefaultWhitelist, |
|||
popperConfig: null |
|||
} |
|||
|
|||
const HOVER_STATE_SHOW = 'show' |
|||
const HOVER_STATE_OUT = 'out' |
|||
|
|||
const 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}` |
|||
} |
|||
|
|||
const CLASS_NAME_FADE = 'fade' |
|||
const CLASS_NAME_SHOW = 'show' |
|||
|
|||
const SELECTOR_TOOLTIP_INNER = '.tooltip-inner' |
|||
const SELECTOR_ARROW = '.arrow' |
|||
|
|||
const TRIGGER_HOVER = 'hover' |
|||
const TRIGGER_FOCUS = 'focus' |
|||
const TRIGGER_CLICK = 'click' |
|||
const TRIGGER_MANUAL = 'manual' |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Class Definition |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
class Tooltip { |
|||
constructor(element, config) { |
|||
if (typeof Popper === 'undefined') { |
|||
throw new TypeError('Bootstrap\'s tooltips require Popper (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
|
|||
|
|||
static get VERSION() { |
|||
return VERSION |
|||
} |
|||
|
|||
static get Default() { |
|||
return Default |
|||
} |
|||
|
|||
static get NAME() { |
|||
return NAME |
|||
} |
|||
|
|||
static get DATA_KEY() { |
|||
return DATA_KEY |
|||
} |
|||
|
|||
static get Event() { |
|||
return Event |
|||
} |
|||
|
|||
static get EVENT_KEY() { |
|||
return EVENT_KEY |
|||
} |
|||
|
|||
static get DefaultType() { |
|||
return DefaultType |
|||
} |
|||
|
|||
// Public
|
|||
|
|||
enable() { |
|||
this._isEnabled = true |
|||
} |
|||
|
|||
disable() { |
|||
this._isEnabled = false |
|||
} |
|||
|
|||
toggleEnabled() { |
|||
this._isEnabled = !this._isEnabled |
|||
} |
|||
|
|||
toggle(event) { |
|||
if (!this._isEnabled) { |
|||
return |
|||
} |
|||
|
|||
if (event) { |
|||
const dataKey = this.constructor.DATA_KEY |
|||
let 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) |
|||
} |
|||
} |
|||
|
|||
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 |
|||
} |
|||
|
|||
show() { |
|||
if ($(this.element).css('display') === 'none') { |
|||
throw new Error('Please use show on visible elements') |
|||
} |
|||
|
|||
const showEvent = $.Event(this.constructor.Event.SHOW) |
|||
if (this.isWithContent() && this._isEnabled) { |
|||
$(this.element).trigger(showEvent) |
|||
|
|||
const shadowRoot = Util.findShadowRoot(this.element) |
|||
const isInTheDom = $.contains( |
|||
shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement, |
|||
this.element |
|||
) |
|||
|
|||
if (showEvent.isDefaultPrevented() || !isInTheDom) { |
|||
return |
|||
} |
|||
|
|||
const tip = this.getTipElement() |
|||
const 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) |
|||
} |
|||
|
|||
const placement = typeof this.config.placement === 'function' ? |
|||
this.config.placement.call(this, tip, this.element) : |
|||
this.config.placement |
|||
|
|||
const attachment = this._getAttachment(placement) |
|||
this.addAttachmentClass(attachment) |
|||
|
|||
const 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) |
|||
$(tip).addClass(this.config.customClass) |
|||
|
|||
// 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) |
|||
} |
|||
|
|||
const complete = () => { |
|||
if (this.config.animation) { |
|||
this._fixTransition() |
|||
} |
|||
|
|||
const 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)) { |
|||
const transitionDuration = Util.getTransitionDurationFromElement(this.tip) |
|||
|
|||
$(this.tip) |
|||
.one(Util.TRANSITION_END, complete) |
|||
.emulateTransitionEnd(transitionDuration) |
|||
} else { |
|||
complete() |
|||
} |
|||
} |
|||
} |
|||
|
|||
hide(callback) { |
|||
const tip = this.getTipElement() |
|||
const hideEvent = $.Event(this.constructor.Event.HIDE) |
|||
const complete = () => { |
|||
if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) { |
|||
tip.parentNode.removeChild(tip) |
|||
} |
|||
|
|||
this._cleanTipClass() |
|||
this.element.removeAttribute('aria-describedby') |
|||
$(this.element).trigger(this.constructor.Event.HIDDEN) |
|||
if (this._popper !== null) { |
|||
this._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)) { |
|||
const transitionDuration = Util.getTransitionDurationFromElement(tip) |
|||
|
|||
$(tip) |
|||
.one(Util.TRANSITION_END, complete) |
|||
.emulateTransitionEnd(transitionDuration) |
|||
} else { |
|||
complete() |
|||
} |
|||
|
|||
this._hoverState = '' |
|||
} |
|||
|
|||
update() { |
|||
if (this._popper !== null) { |
|||
this._popper.scheduleUpdate() |
|||
} |
|||
} |
|||
|
|||
// Protected
|
|||
|
|||
isWithContent() { |
|||
return Boolean(this.getTitle()) |
|||
} |
|||
|
|||
addAttachmentClass(attachment) { |
|||
$(this.getTipElement()).addClass(`${CLASS_PREFIX}-${attachment}`) |
|||
} |
|||
|
|||
getTipElement() { |
|||
this.tip = this.tip || $(this.config.template)[0] |
|||
return this.tip |
|||
} |
|||
|
|||
setContent() { |
|||
const tip = this.getTipElement() |
|||
this.setElementContent($(tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle()) |
|||
$(tip).removeClass(`${CLASS_NAME_FADE} ${CLASS_NAME_SHOW}`) |
|||
} |
|||
|
|||
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) |
|||
} |
|||
} |
|||
|
|||
getTitle() { |
|||
let 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
|
|||
|
|||
_getPopperConfig(attachment) { |
|||
const defaultBsConfig = { |
|||
placement: attachment, |
|||
modifiers: { |
|||
offset: this._getOffset(), |
|||
flip: { |
|||
behavior: this.config.fallbackPlacement |
|||
}, |
|||
arrow: { |
|||
element: SELECTOR_ARROW |
|||
}, |
|||
preventOverflow: { |
|||
boundariesElement: this.config.boundary |
|||
} |
|||
}, |
|||
onCreate: data => { |
|||
if (data.originalPlacement !== data.placement) { |
|||
this._handlePopperPlacementChange(data) |
|||
} |
|||
}, |
|||
onUpdate: data => this._handlePopperPlacementChange(data) |
|||
} |
|||
|
|||
return { |
|||
...defaultBsConfig, |
|||
...this.config.popperConfig |
|||
} |
|||
} |
|||
|
|||
_getOffset() { |
|||
const offset = {} |
|||
|
|||
if (typeof this.config.offset === 'function') { |
|||
offset.fn = data => { |
|||
data.offsets = { |
|||
...data.offsets, |
|||
...(this.config.offset(data.offsets, this.element) || {}) |
|||
} |
|||
|
|||
return data |
|||
} |
|||
} else { |
|||
offset.offset = this.config.offset |
|||
} |
|||
|
|||
return offset |
|||
} |
|||
|
|||
_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) |
|||
} |
|||
|
|||
_getAttachment(placement) { |
|||
return AttachmentMap[placement.toUpperCase()] |
|||
} |
|||
|
|||
_setListeners() { |
|||
const triggers = this.config.trigger.split(' ') |
|||
|
|||
triggers.forEach(trigger => { |
|||
if (trigger === 'click') { |
|||
$(this.element).on( |
|||
this.constructor.Event.CLICK, |
|||
this.config.selector, |
|||
event => this.toggle(event) |
|||
) |
|||
} else if (trigger !== TRIGGER_MANUAL) { |
|||
const eventIn = trigger === TRIGGER_HOVER ? |
|||
this.constructor.Event.MOUSEENTER : |
|||
this.constructor.Event.FOCUSIN |
|||
const eventOut = trigger === TRIGGER_HOVER ? |
|||
this.constructor.Event.MOUSELEAVE : |
|||
this.constructor.Event.FOCUSOUT |
|||
|
|||
$(this.element) |
|||
.on(eventIn, this.config.selector, event => this._enter(event)) |
|||
.on(eventOut, this.config.selector, event => this._leave(event)) |
|||
} |
|||
}) |
|||
|
|||
this._hideModalHandler = () => { |
|||
if (this.element) { |
|||
this.hide() |
|||
} |
|||
} |
|||
|
|||
$(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler) |
|||
|
|||
if (this.config.selector) { |
|||
this.config = { |
|||
...this.config, |
|||
trigger: 'manual', |
|||
selector: '' |
|||
} |
|||
} else { |
|||
this._fixTitle() |
|||
} |
|||
} |
|||
|
|||
_fixTitle() { |
|||
const 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', '') |
|||
} |
|||
} |
|||
|
|||
_enter(event, context) { |
|||
const 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(() => { |
|||
if (context._hoverState === HOVER_STATE_SHOW) { |
|||
context.show() |
|||
} |
|||
}, context.config.delay.show) |
|||
} |
|||
|
|||
_leave(event, context) { |
|||
const 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(() => { |
|||
if (context._hoverState === HOVER_STATE_OUT) { |
|||
context.hide() |
|||
} |
|||
}, context.config.delay.hide) |
|||
} |
|||
|
|||
_isWithActiveTrigger() { |
|||
for (const trigger in this._activeTrigger) { |
|||
if (this._activeTrigger[trigger]) { |
|||
return true |
|||
} |
|||
} |
|||
|
|||
return false |
|||
} |
|||
|
|||
_getConfig(config) { |
|||
const dataAttributes = $(this.element).data() |
|||
|
|||
Object.keys(dataAttributes) |
|||
.forEach(dataAttr => { |
|||
if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) { |
|||
delete dataAttributes[dataAttr] |
|||
} |
|||
}) |
|||
|
|||
config = { |
|||
...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 |
|||
} |
|||
|
|||
_getDelegateConfig() { |
|||
const config = {} |
|||
|
|||
if (this.config) { |
|||
for (const key in this.config) { |
|||
if (this.constructor.Default[key] !== this.config[key]) { |
|||
config[key] = this.config[key] |
|||
} |
|||
} |
|||
} |
|||
|
|||
return config |
|||
} |
|||
|
|||
_cleanTipClass() { |
|||
const $tip = $(this.getTipElement()) |
|||
const tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX) |
|||
if (tabClass !== null && tabClass.length) { |
|||
$tip.removeClass(tabClass.join('')) |
|||
} |
|||
} |
|||
|
|||
_handlePopperPlacementChange(popperData) { |
|||
this.tip = popperData.instance.popper |
|||
this._cleanTipClass() |
|||
this.addAttachmentClass(this._getAttachment(popperData.placement)) |
|||
} |
|||
|
|||
_fixTransition() { |
|||
const tip = this.getTipElement() |
|||
const 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
|
|||
|
|||
static _jQueryInterface(config) { |
|||
return this.each(function () { |
|||
const $element = $(this) |
|||
let data = $element.data(DATA_KEY) |
|||
const _config = typeof config === 'object' && config |
|||
|
|||
if (!data && /dispose|hide/.test(config)) { |
|||
return |
|||
} |
|||
|
|||
if (!data) { |
|||
data = new Tooltip(this, _config) |
|||
$element.data(DATA_KEY, data) |
|||
} |
|||
|
|||
if (typeof config === 'string') { |
|||
if (typeof data[config] === 'undefined') { |
|||
throw new TypeError(`No method named "${config}"`) |
|||
} |
|||
|
|||
data[config]() |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* jQuery |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
$.fn[NAME] = Tooltip._jQueryInterface |
|||
$.fn[NAME].Constructor = Tooltip |
|||
$.fn[NAME].noConflict = () => { |
|||
$.fn[NAME] = JQUERY_NO_CONFLICT |
|||
return Tooltip._jQueryInterface |
|||
} |
|||
|
|||
export default Tooltip |
@ -0,0 +1,198 @@ |
|||
/** |
|||
* -------------------------------------------------------------------------- |
|||
* Bootstrap (v4.6.0): util.js |
|||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|||
* -------------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
import $ from 'jquery' |
|||
|
|||
/** |
|||
* ------------------------------------------------------------------------ |
|||
* Private TransitionEnd Helpers |
|||
* ------------------------------------------------------------------------ |
|||
*/ |
|||
|
|||
const TRANSITION_END = 'transitionend' |
|||
const MAX_UID = 1000000 |
|||
const 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(event) { |
|||
if ($(event.target).is(this)) { |
|||
return event.handleObj.handler.apply(this, arguments) // eslint-disable-line prefer-rest-params
|
|||
} |
|||
|
|||
return undefined |
|||
} |
|||
} |
|||
} |
|||
|
|||
function transitionEndEmulator(duration) { |
|||
let called = false |
|||
|
|||
$(this).one(Util.TRANSITION_END, () => { |
|||
called = true |
|||
}) |
|||
|
|||
setTimeout(() => { |
|||
if (!called) { |
|||
Util.triggerTransitionEnd(this) |
|||
} |
|||
}, duration) |
|||
|
|||
return this |
|||
} |
|||
|
|||
function setTransitionEndSupport() { |
|||
$.fn.emulateTransitionEnd = transitionEndEmulator |
|||
$.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent() |
|||
} |
|||
|
|||
/** |
|||
* -------------------------------------------------------------------------- |
|||
* Public Util Api |
|||
* -------------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
const Util = { |
|||
TRANSITION_END: 'bsTransitionEnd', |
|||
|
|||
getUID(prefix) { |
|||
do { |
|||
prefix += ~~(Math.random() * MAX_UID) // "~~" acts like a faster Math.floor() here
|
|||
} while (document.getElementById(prefix)) |
|||
|
|||
return prefix |
|||
}, |
|||
|
|||
getSelectorFromElement(element) { |
|||
let selector = element.getAttribute('data-target') |
|||
|
|||
if (!selector || selector === '#') { |
|||
const hrefAttr = element.getAttribute('href') |
|||
selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : '' |
|||
} |
|||
|
|||
try { |
|||
return document.querySelector(selector) ? selector : null |
|||
} catch (_) { |
|||
return null |
|||
} |
|||
}, |
|||
|
|||
getTransitionDurationFromElement(element) { |
|||
if (!element) { |
|||
return 0 |
|||
} |
|||
|
|||
// Get transition-duration of the element
|
|||
let transitionDuration = $(element).css('transition-duration') |
|||
let transitionDelay = $(element).css('transition-delay') |
|||
|
|||
const floatTransitionDuration = parseFloat(transitionDuration) |
|||
const 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(element) { |
|||
return element.offsetHeight |
|||
}, |
|||
|
|||
triggerTransitionEnd(element) { |
|||
$(element).trigger(TRANSITION_END) |
|||
}, |
|||
|
|||
supportsTransitionEnd() { |
|||
return Boolean(TRANSITION_END) |
|||
}, |
|||
|
|||
isElement(obj) { |
|||
return (obj[0] || obj).nodeType |
|||
}, |
|||
|
|||
typeCheckConfig(componentName, config, configTypes) { |
|||
for (const property in configTypes) { |
|||
if (Object.prototype.hasOwnProperty.call(configTypes, property)) { |
|||
const expectedTypes = configTypes[property] |
|||
const value = config[property] |
|||
const 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(element) { |
|||
if (!document.documentElement.attachShadow) { |
|||
return null |
|||
} |
|||
|
|||
// Can find the shadow root otherwise it'll return the document
|
|||
if (typeof element.getRootNode === 'function') { |
|||
const 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() { |
|||
if (typeof $ === 'undefined') { |
|||
throw new TypeError('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.') |
|||
} |
|||
|
|||
const version = $.fn.jquery.split(' ')[0].split('.') |
|||
const minMajor = 1 |
|||
const ltMajor = 2 |
|||
const minMinor = 9 |
|||
const minPatch = 1 |
|||
const 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() |
|||
|
|||
export default Util |
@ -0,0 +1,199 @@ |
|||
// This file is part of Moodle - http://moodle.org/
|
|||
//
|
|||
// Moodle is free software: you can redistribute it and/or modify
|
|||
// it under the terms of the GNU General Public License as published by
|
|||
// the Free Software Foundation, either version 3 of the License, or
|
|||
// (at your option) any later version.
|
|||
//
|
|||
// Moodle is distributed in the hope that it will be useful,
|
|||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
// GNU General Public License for more details.
|
|||
//
|
|||
// You should have received a copy of the GNU General Public License
|
|||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
|||
/** |
|||
* Contain the logic for a drawer. |
|||
* |
|||
* @module theme_ilb/drawer |
|||
* @copyright 2016 Damyon Wiese |
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|||
*/ |
|||
define(['jquery', 'core/custom_interaction_events', 'core/log', 'core/pubsub', 'core/aria'], |
|||
function($, CustomEvents, Log, PubSub, Aria) { |
|||
|
|||
var SELECTORS = { |
|||
TOGGLE_REGION: '[data-region="drawer-toggle"]', |
|||
TOGGLE_ACTION: '[data-action="toggle-drawer"]', |
|||
TOGGLE_TARGET: 'aria-controls', |
|||
TOGGLE_SIDE: 'left', |
|||
BODY: 'body', |
|||
SECTION: '.list-group-item[href*="#section-"]', |
|||
DRAWER: '#nav-drawer' |
|||
}; |
|||
|
|||
var small = $(document).width() < 768; |
|||
|
|||
/** |
|||
* Constructor for the Drawer. |
|||
*/ |
|||
var Drawer = function() { |
|||
|
|||
if (!$(SELECTORS.TOGGLE_REGION).length) { |
|||
Log.debug('Page is missing a drawer region'); |
|||
} |
|||
if (!$(SELECTORS.TOGGLE_ACTION).length) { |
|||
Log.debug('Page is missing a drawer toggle link'); |
|||
} |
|||
$(SELECTORS.TOGGLE_REGION).each(function(index, ele) { |
|||
var trigger = $(ele).find(SELECTORS.TOGGLE_ACTION); |
|||
var drawerid = trigger.attr('aria-controls'); |
|||
var drawer = $(document.getElementById(drawerid)); |
|||
var hidden = trigger.attr('aria-expanded') == 'false'; |
|||
var side = trigger.attr('data-side'); |
|||
var body = $(SELECTORS.BODY); |
|||
var preference = trigger.attr('data-preference'); |
|||
if (small) { |
|||
M.util.set_user_preference(preference, 'false'); |
|||
} |
|||
|
|||
drawer.on('mousewheel DOMMouseScroll', this.preventPageScroll); |
|||
|
|||
if (!hidden) { |
|||
body.addClass('drawer-open-' + side); |
|||
trigger.attr('aria-expanded', 'true'); |
|||
} else { |
|||
trigger.attr('aria-expanded', 'false'); |
|||
} |
|||
}.bind(this)); |
|||
|
|||
this.registerEventListeners(); |
|||
if (small) { |
|||
this.closeAll(); |
|||
} |
|||
}; |
|||
|
|||
Drawer.prototype.closeAll = function() { |
|||
$(SELECTORS.TOGGLE_REGION).each(function(index, ele) { |
|||
var trigger = $(ele).find(SELECTORS.TOGGLE_ACTION); |
|||
var side = trigger.attr('data-side'); |
|||
var body = $(SELECTORS.BODY); |
|||
var drawerid = trigger.attr('aria-controls'); |
|||
var drawer = $(document.getElementById(drawerid)); |
|||
var preference = trigger.attr('data-preference'); |
|||
|
|||
trigger.attr('aria-expanded', 'false'); |
|||
body.removeClass('drawer-open-' + side); |
|||
Aria.hide(drawer.get()); |
|||
drawer.addClass('closed'); |
|||
if (!small) { |
|||
M.util.set_user_preference(preference, 'false'); |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
/** |
|||
* Open / close the blocks drawer. |
|||
* |
|||
* @method toggleDrawer |
|||
* @param {Event} e |
|||
*/ |
|||
Drawer.prototype.toggleDrawer = function(e) { |
|||
var trigger = $(e.target).closest('[data-action=toggle-drawer]'); |
|||
var drawerid = trigger.attr('aria-controls'); |
|||
var drawer = $(document.getElementById(drawerid)); |
|||
var body = $(SELECTORS.BODY); |
|||
var side = trigger.attr('data-side'); |
|||
var preference = trigger.attr('data-preference'); |
|||
if (small) { |
|||
M.util.set_user_preference(preference, 'false'); |
|||
} |
|||
|
|||
body.addClass('drawer-ease'); |
|||
var open = trigger.attr('aria-expanded') == 'true'; |
|||
if (!open) { |
|||
// Open.
|
|||
trigger.attr('aria-expanded', 'true'); |
|||
Aria.unhide(drawer.get()); |
|||
drawer.focus(); |
|||
body.addClass('drawer-open-' + side); |
|||
drawer.removeClass('closed'); |
|||
if (!small) { |
|||
M.util.set_user_preference(preference, 'true'); |
|||
} |
|||
} else { |
|||
// Close.
|
|||
body.removeClass('drawer-open-' + side); |
|||
trigger.attr('aria-expanded', 'false'); |
|||
drawer.addClass('closed').delay(500).queue(function() { |
|||
// Ensure that during the delay, the drawer wasn't re-opened.
|
|||
if ($(this).hasClass('closed')) { |
|||
Aria.hide(this); |
|||
} |
|||
$(this).dequeue(); |
|||
}); |
|||
if (!small) { |
|||
M.util.set_user_preference(preference, 'false'); |
|||
} |
|||
} |
|||
|
|||
// Publish an event to tell everything that the drawer has been toggled.
|
|||
// The drawer transitions closed so another event will fire once teh transition
|
|||
// has completed.
|
|||
PubSub.publish('nav-drawer-toggle-start', open); |
|||
}; |
|||
|
|||
/** |
|||
* Prevent the page from scrolling when the drawer is at max scroll. |
|||
* |
|||
* @method preventPageScroll |
|||
* @param {Event} e |
|||
*/ |
|||
Drawer.prototype.preventPageScroll = function(e) { |
|||
var delta = e.wheelDelta || (e.originalEvent && e.originalEvent.wheelDelta) || -e.originalEvent.detail, |
|||
bottomOverflow = (this.scrollTop + $(this).outerHeight() - this.scrollHeight) >= 0, |
|||
topOverflow = this.scrollTop <= 0; |
|||
|
|||
if ((delta < 0 && bottomOverflow) || (delta > 0 && topOverflow)) { |
|||
e.preventDefault(); |
|||
} |
|||
}; |
|||
|
|||
/** |
|||
* Set up all of the event handling for the modal. |
|||
* |
|||
* @method registerEventListeners |
|||
*/ |
|||
Drawer.prototype.registerEventListeners = function() { |
|||
|
|||
$(SELECTORS.TOGGLE_ACTION).each(function(index, element) { |
|||
CustomEvents.define($(element), [CustomEvents.events.activate]); |
|||
$(element).on(CustomEvents.events.activate, function(e, data) { |
|||
this.toggleDrawer(data.originalEvent); |
|||
data.originalEvent.preventDefault(); |
|||
}.bind(this)); |
|||
}.bind(this)); |
|||
|
|||
$(SELECTORS.SECTION).click(function() { |
|||
if (small) { |
|||
this.closeAll(); |
|||
} |
|||
}.bind(this)); |
|||
|
|||
// Publish an event to tell everything that the drawer completed the transition
|
|||
// to either an open or closed state.
|
|||
$(SELECTORS.DRAWER).on('webkitTransitionEnd msTransitionEnd transitionend', function(e) { |
|||
var drawer = $(e.target).closest(SELECTORS.DRAWER); |
|||
// Note: aria-hidden is either present, or absent. It should not be set to false.
|
|||
var open = !!drawer.attr('aria-hidden'); |
|||
PubSub.publish('nav-drawer-toggle-end', open); |
|||
}); |
|||
}; |
|||
|
|||
return { |
|||
'init': function() { |
|||
return new Drawer(); |
|||
} |
|||
}; |
|||
}); |
@ -0,0 +1,114 @@ |
|||
// This file is part of Moodle - http://moodle.org/
|
|||
//
|
|||
// Moodle is free software: you can redistribute it and/or modify
|
|||
// it under the terms of the GNU General Public License as published by
|
|||
// the Free Software Foundation, either version 3 of the License, or
|
|||
// (at your option) any later version.
|
|||
//
|
|||
// Moodle is distributed in the hope that it will be useful,
|
|||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
// GNU General Public License for more details.
|
|||
//
|
|||
// You should have received a copy of the GNU General Public License
|
|||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
|||
/** |
|||
* Custom form error event handler to manipulate the bootstrap markup and show |
|||
* nicely styled errors in an mform. |
|||
* |
|||
* @module theme_ilb/form-display-errors |
|||
* @copyright 2016 Damyon Wiese <damyon@moodle.com> |
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|||
*/ |
|||
define(['jquery', 'core/event'], function($, Event) { |
|||
return { |
|||
enhance: function(elementid) { |
|||
var element = document.getElementById(elementid); |
|||
if (!element) { |
|||
// Some elements (e.g. static) don't have a form field.
|
|||
// Hence there is no validation. So, no setup required here.
|
|||
return; |
|||
} |
|||
|
|||
$(element).on(Event.Events.FORM_FIELD_VALIDATION, function(event, msg) { |
|||
event.preventDefault(); |
|||
var parent = $(element).closest('.form-group'); |
|||
var feedback = parent.find('.form-control-feedback'); |
|||
const feedbackId = feedback.attr('id'); |
|||
|
|||
// Get current aria-describedby value.
|
|||
let describedBy = $(element).attr('aria-describedby'); |
|||
if (typeof describedBy === "undefined") { |
|||
describedBy = ''; |
|||
} |
|||
// Split aria-describedby attribute into an array of IDs if necessary.
|
|||
let describedByIds = []; |
|||
if (describedBy.length) { |
|||
describedByIds = describedBy.split(" "); |
|||
} |
|||
// Find the the feedback container in the aria-describedby attribute.
|
|||
const feedbackIndex = describedByIds.indexOf(feedbackId); |
|||
|
|||
// Sometimes (atto) we have a hidden textarea backed by a real contenteditable div.
|
|||
if (($(element).prop("tagName") == 'TEXTAREA') && parent.find('[contenteditable]')) { |
|||
element = parent.find('[contenteditable]'); |
|||
} |
|||
if (msg !== '') { |
|||
parent.addClass('has-danger'); |
|||
parent.data('client-validation-error', true); |
|||
$(element).addClass('is-invalid'); |
|||
// Append the feedback ID to the aria-describedby attribute if it doesn't exist yet.
|
|||
if (feedbackIndex === -1) { |
|||
describedByIds.push(feedbackId); |
|||
$(element).attr('aria-describedby', describedByIds.join(" ")); |
|||
} |
|||
$(element).attr('aria-invalid', true); |
|||
feedback.attr('tabindex', 0); |
|||
feedback.html(msg); |
|||
|
|||
// Only display and focus when the error was not already visible.
|
|||
// This is so that, when tabbing around the form, you don't get stuck.
|
|||
if (!feedback.is(':visible')) { |
|||
feedback.show(); |
|||
feedback.focus(); |
|||
} |
|||
|
|||
} else { |
|||
if (parent.data('client-validation-error') === true) { |
|||
parent.removeClass('has-danger'); |
|||
parent.data('client-validation-error', false); |
|||
$(element).removeClass('is-invalid'); |
|||
// If the aria-describedby attribute contains the error container's ID, remove it.
|
|||
if (feedbackIndex > -1) { |
|||
describedByIds.splice(feedbackIndex, 1); |
|||
} |
|||
// Check the remaining element IDs in the aria-describedby attribute.
|
|||
if (describedByIds.length) { |
|||
// If there's at least one, combine them with a blank space and update the aria-describedby attribute.
|
|||
describedBy = describedByIds.join(" "); |
|||
// Put back the new describedby attribute.
|
|||
$(element).attr('aria-describedby', describedBy); |
|||
} else { |
|||
// If there's none, remove the aria-describedby attribute.
|
|||
$(element).removeAttr('aria-describedby'); |
|||
} |
|||
$(element).attr('aria-invalid', false); |
|||
feedback.hide(); |
|||
} |
|||
} |
|||
}); |
|||
|
|||
var form = element.closest('form'); |
|||
if (form && !('ilbFormErrorsEnhanced' in form.dataset)) { |
|||
form.addEventListener('submit', function() { |
|||
var visibleError = $('.form-control-feedback:visible'); |
|||
if (visibleError.length) { |
|||
visibleError[0].focus(); |
|||
} |
|||
}); |
|||
form.dataset.ilbFormErrorsEnhanced = 1; |
|||
} |
|||
} |
|||
}; |
|||
}); |
@ -0,0 +1,34 @@ |
|||
/** |
|||
* -------------------------------------------------------------------------- |
|||
* Bootstrap (v4.6.0): index.js |
|||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|||
* -------------------------------------------------------------------------- |
|||
*/ |
|||
|
|||
import Alert from './bootstrap/alert'; |
|||
import Button from './bootstrap/button'; |
|||
import Carousel from './bootstrap/carousel'; |
|||
import Collapse from './bootstrap/collapse'; |
|||
import Dropdown from './bootstrap/dropdown'; |
|||
import Modal from './bootstrap/modal'; |
|||
import Popover from './bootstrap/popover'; |
|||
import Scrollspy from './bootstrap/scrollspy'; |
|||
import Tab from './bootstrap/tab'; |
|||
import Toast from './bootstrap/toast'; |
|||
import Tooltip from './bootstrap/tooltip'; |
|||
import Util from './bootstrap/util'; |
|||
|
|||
export { |
|||
Util, |
|||
Alert, |
|||
Button, |
|||
Carousel, |
|||
Collapse, |
|||
Dropdown, |
|||
Modal, |
|||
Popover, |
|||
Scrollspy, |
|||
Tab, |
|||
Toast, |
|||
Tooltip |
|||
}; |
@ -0,0 +1,109 @@ |
|||
// This file is part of Moodle - http://moodle.org/
|
|||
//
|
|||
// Moodle is free software: you can redistribute it and/or modify
|
|||
// it under the terms of the GNU General Public License as published by
|
|||
// the Free Software Foundation, either version 3 of the License, or
|
|||
// (at your option) any later version.
|
|||
//
|
|||
// Moodle is distributed in the hope that it will be useful,
|
|||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
// GNU General Public License for more details.
|
|||
//
|
|||
// You should have received a copy of the GNU General Public License
|
|||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
|||
/** |
|||
* Template renderer for Moodle. Load and render Moodle templates with Mustache. |
|||
* |
|||
* @module theme_ilb/loader |
|||
* @copyright 2015 Damyon Wiese <damyon@moodle.com> |
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|||
* @since 2.9 |
|||
*/ |
|||
|
|||
import $ from 'jquery'; |
|||
import * as Aria from './aria'; |
|||
import Bootstrap from './index'; |
|||
import Pending from 'core/pending'; |
|||
import Scroll from './scroll'; |
|||
import setupBootstrapPendingChecks from './pending'; |
|||
|
|||
/** |
|||
* Rember the last visited tabs. |
|||
*/ |
|||
const rememberTabs = () => { |
|||
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) { |
|||
var hash = $(e.target).attr('href'); |
|||
if (history.replaceState) { |
|||
history.replaceState(null, null, hash); |
|||
} else { |
|||
location.hash = hash; |
|||
} |
|||
}); |
|||
const hash = window.location.hash; |
|||
if (hash) { |
|||
const tab = document.querySelector('.nav-link[href="' + hash + '"]'); |
|||
if (tab) { |
|||
tab.click(); |
|||
} |
|||
} |
|||
}; |
|||
|
|||
/** |
|||
* Enable all popovers |
|||
* |
|||
*/ |
|||
const enablePopovers = () => { |
|||
$('body').popover({ |
|||
container: 'body', |
|||
selector: '[data-toggle="popover"]', |
|||
trigger: 'focus', |
|||
}); |
|||
|
|||
document.addEventListener('keydown', e => { |
|||
if (e.key === 'Escape' && e.target.closest('[data-toggle="popover"]')) { |
|||
$(e.target).popover('hide'); |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
/** |
|||
* Enable tooltips |
|||
* |
|||
*/ |
|||
const enableTooltips = () => { |
|||
$('body').tooltip({ |
|||
container: 'body', |
|||
selector: '[data-toggle="tooltip"]', |
|||
}); |
|||
}; |
|||
|
|||
const pendingPromise = new Pending('theme_ilb/loader:init'); |
|||
|
|||
// Add pending promise event listeners to relevant Bootstrap custom events.
|
|||
setupBootstrapPendingChecks(); |
|||
|
|||
// Setup Aria helpers for Bootstrap features.
|
|||
Aria.init(); |
|||
|
|||
// Remember the last visited tabs.
|
|||
rememberTabs(); |
|||
|
|||
// Enable all popovers.
|
|||
enablePopovers(); |
|||
|
|||
// Enable all tooltips.
|
|||
enableTooltips(); |
|||
|
|||
// Add scroll handling.
|
|||
(new Scroll()).init(); |
|||
|
|||
// Disables flipping the dropdowns up and getting hidden behind the navbar.
|
|||
$.fn.dropdown.Constructor.Default.flip = false; |
|||
|
|||
pendingPromise.resolve(); |
|||
|
|||
export { |
|||
Bootstrap, |
|||
}; |
@ -0,0 +1,133 @@ |
|||
// This file is part of Moodle - http://moodle.org/
|
|||
//
|
|||
// Moodle is free software: you can redistribute it and/or modify
|
|||
// it under the terms of the GNU General Public License as published by
|
|||
// the Free Software Foundation, either version 3 of the License, or
|
|||
// (at your option) any later version.
|
|||
//
|
|||
// Moodle is distributed in the hope that it will be useful,
|
|||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
// GNU General Public License for more details.
|
|||
//
|
|||
// You should have received a copy of the GNU General Public License
|
|||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
|||
/** |
|||
* Add Pending JS checks to stock Bootstrap transitions. |
|||
* |
|||
* @module theme_ilb/pending |
|||
* @copyright 2019 Andrew Nicols <andrew@nicols.co.uk> |
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|||
*/ |
|||
|
|||
import jQuery from 'jquery'; |
|||
const moduleTransitions = { |
|||
alert: [ |
|||
// Alert.
|
|||
{ |
|||
start: 'close', |
|||
end: 'closed', |
|||
}, |
|||
], |
|||
|
|||
carousel: [ |
|||
{ |
|||
start: 'slide', |
|||
end: 'slid', |
|||
}, |
|||
], |
|||
|
|||
collapse: [ |
|||
{ |
|||
start: 'hide', |
|||
end: 'hidden', |
|||
}, |
|||
{ |
|||
start: 'show', |
|||
end: 'shown', |
|||
}, |
|||
], |
|||
|
|||
dropdown: [ |
|||
{ |
|||
start: 'hide', |
|||
end: 'hidden', |
|||
}, |
|||
{ |
|||
start: 'show', |
|||
end: 'shown', |
|||
}, |
|||
], |
|||
|
|||
modal: [ |
|||
{ |
|||
start: 'hide', |
|||
end: 'hidden', |
|||
}, |
|||
{ |
|||
start: 'show', |
|||
end: 'shown', |
|||
}, |
|||
], |
|||
|
|||
popover: [ |
|||
{ |
|||
start: 'hide', |
|||
end: 'hidden', |
|||
}, |
|||
{ |
|||
start: 'show', |
|||
end: 'shown', |
|||
}, |
|||
], |
|||
|
|||
tab: [ |
|||
{ |
|||
start: 'hide', |
|||
end: 'hidden', |
|||
}, |
|||
{ |
|||
start: 'show', |
|||
end: 'shown', |
|||
}, |
|||
], |
|||
|
|||
toast: [ |
|||
{ |
|||
start: 'hide', |
|||
end: 'hidden', |
|||
}, |
|||
{ |
|||
start: 'show', |
|||
end: 'shown', |
|||
}, |
|||
], |
|||
|
|||
tooltip: [ |
|||
{ |
|||
start: 'hide', |
|||
end: 'hidden', |
|||
}, |
|||
{ |
|||
start: 'show', |
|||
end: 'shown', |
|||
}, |
|||
], |
|||
}; |
|||
|
|||
export default () => { |
|||
Object.entries(moduleTransitions).forEach(([key, pairs]) => { |
|||
pairs.forEach(pair => { |
|||
const eventStart = `${pair.start}.bs.${key}`; |
|||
const eventEnd = `${pair.end}.bs.${key}`; |
|||
jQuery(document.body).on(eventStart, e => { |
|||
M.util.js_pending(eventEnd); |
|||
jQuery(e.target).one(eventEnd, () => { |
|||
M.util.js_complete(eventEnd); |
|||
}); |
|||
}); |
|||
|
|||
}); |
|||
}); |
|||
}; |
@ -0,0 +1,72 @@ |
|||
// This file is part of Moodle - http://moodle.org/
|
|||
//
|
|||
// Moodle is free software: you can redistribute it and/or modify
|
|||
// it under the terms of the GNU General Public License as published by
|
|||
// the Free Software Foundation, either version 3 of the License, or
|
|||
// (at your option) any later version.
|
|||
//
|
|||
// Moodle is distributed in the hope that it will be useful,
|
|||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
// GNU General Public License for more details.
|
|||
//
|
|||
// You should have received a copy of the GNU General Public License
|
|||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
|||
/** |
|||
* Manage user scroll in Moodle for future floating elements. |
|||
* |
|||
* @module theme_ilb/scroll |
|||
* @copyright 2020 Ferran Recio <ferran@moodle.org> |
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|||
*/ |
|||
|
|||
/** |
|||
* Moodle scroll handling. For now it just handle a "scrolled" class |
|||
* on the body tag but in the near future could handle more floating |
|||
* elements like option bars, docked elements or other active elements. |
|||
* |
|||
* @class theme_ilb/scroll |
|||
*/ |
|||
export default class MoodleScroll { |
|||
|
|||
/** |
|||
* Initialise the scroll monitoring. |
|||
* |
|||
* @method init |
|||
* @chainable |
|||
* @return {Object} this. |
|||
*/ |
|||
init() { |
|||
this.scrollY = 0; |
|||
window.addEventListener("scroll", this.scrollHandler.bind(this)); |
|||
return this; |
|||
} |
|||
|
|||
/** |
|||
* Add special classes to body depending on scroll position. |
|||
* |
|||
* @method update |
|||
* @chainable |
|||
* @return {Integer} current scroll position. |
|||
*/ |
|||
getScrollPosition() { |
|||
return window.pageYOffset || document.documentElement.scrollTop; |
|||
} |
|||
|
|||
/** |
|||
* Add special classes to body depending on scroll position. |
|||
* |
|||
* @method update |
|||
* @chainable |
|||
*/ |
|||
scrollHandler() { |
|||
const body = document.querySelector('body'); |
|||
const scrollY = this.getScrollPosition(); |
|||
if (scrollY >= window.innerHeight) { |
|||
body.classList.add('scrolled'); |
|||
} else { |
|||
body.classList.remove('scrolled'); |
|||
} |
|||
} |
|||
} |
@ -1,50 +0,0 @@ |
|||
<?php |
|||
// This file is part of Moodle - http://moodle.org/ |
|||
// |
|||
// Moodle is free software: you can redistribute it and/or modify |
|||
// it under the terms of the GNU General Public License as published by |
|||
// the Free Software Foundation, either version 3 of the License, or |
|||
// (at your option) any later version. |
|||
// |
|||
// Moodle is distributed in the hope that it will be useful, |
|||
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
// GNU General Public License for more details. |
|||
// |
|||
// You should have received a copy of the GNU General Public License |
|||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
|||
|
|||
/** |
|||
* Overriden block settings renderer. |
|||
* |
|||
* @package theme_boost |
|||
* @copyright 2016 Frédéric Massart - FMCorz.net |
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
|||
*/ |
|||
|
|||
namespace theme_boost\output; |
|||
defined('MOODLE_INTERNAL') || die(); |
|||
|
|||
require_once($CFG->dirroot . '/blocks/settings/renderer.php'); |
|||
|
|||
use moodle_url; |
|||
|
|||
/** |
|||
* Overriden block settings renderer. |
|||
* |
|||
* @package theme_boost |
|||
* @copyright 2016 Frédéric Massart - FMCorz.net |
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
|||
*/ |
|||
class block_settings_renderer extends \block_settings_renderer { |
|||
|
|||
public function search_form(moodle_url $formtarget, $searchvalue) { |
|||
$data = [ |
|||
'action' => $formtarget->out(false), |
|||
'label' => get_string('searchinsettings', 'admin'), |
|||
'searchvalue' => $searchvalue |
|||
]; |
|||
return $this->render_from_template('block_settings/search_form', $data); |
|||
} |
|||
|
|||
} |
@ -1,52 +0,0 @@ |
|||
<?php |
|||
// This file is part of Moodle - http://moodle.org/ |
|||
// |
|||
// Moodle is free software: you can redistribute it and/or modify |
|||
// it under the terms of the GNU General Public License as published by |
|||
// the Free Software Foundation, either version 3 of the License, or |
|||
// (at your option) any later version. |
|||
// |
|||
// Moodle is distributed in the hope that it will be useful, |
|||
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
// GNU General Public License for more details. |
|||
// |
|||
// You should have received a copy of the GNU General Public License |
|||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
|||
|
|||
/** |
|||
* Admin renderer. |
|||
* |
|||
* @package theme_noanme |
|||
* @copyright 2016 Frédéric Massart - FMCorz.net |
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
|||
*/ |
|||
|
|||
namespace theme_boost\output\core; |
|||
defined('MOODLE_INTERNAL') || die(); |
|||
|
|||
use moodle_url; |
|||
|
|||
require_once($CFG->dirroot . '/' . $CFG->admin . '/renderer.php'); |
|||
|
|||
/** |
|||
* Admin renderer class. |
|||
* |
|||
* @package theme_noanme |
|||
* @copyright 2016 Frédéric Massart - FMCorz.net |
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
|||
*/ |
|||
class admin_renderer extends \core_admin_renderer { |
|||
|
|||
/** |
|||
* Output a warning message. |
|||
* |
|||
* @param string $message the message to display. |
|||
* @param string $type type class |
|||
* @return string HTML to output. |
|||
*/ |
|||
protected function warning($message, $type = 'warning') { |
|||
return $this->box($message, 'generalbox m-b-1 admin' . $type); |
|||
} |
|||
|
|||
} |
@ -1,81 +0,0 @@ |
|||
<?php |
|||
// This file is part of Moodle - http://moodle.org/ |
|||
// |
|||
// Moodle is free software: you can redistribute it and/or modify |
|||
// it under the terms of the GNU General Public License as published by |
|||
// the Free Software Foundation, either version 3 of the License, or |
|||
// (at your option) any later version. |
|||
// |
|||
// Moodle is distributed in the hope that it will be useful, |
|||
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
// GNU General Public License for more details. |
|||
// |
|||
// You should have received a copy of the GNU General Public License |
|||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
|||
|
|||
/** |
|||
* Course renderer. |
|||
* |
|||
* @package theme_noanme |
|||
* @copyright 2016 Frédéric Massart - FMCorz.net |
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
|||
*/ |
|||
|
|||
namespace theme_boost\output\core; |
|||
defined('MOODLE_INTERNAL') || die(); |
|||
|
|||
use moodle_url; |
|||
|
|||
require_once($CFG->dirroot . '/course/renderer.php'); |
|||
|
|||
/** |
|||
* Course renderer class. |
|||
* |
|||
* @package theme_noanme |
|||
* @copyright 2016 Frédéric Massart - FMCorz.net |
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
|||
*/ |
|||
class course_renderer extends \core_course_renderer { |
|||
|
|||
/** |
|||
* Renders html to display a course search form. |
|||
* |
|||
* @param string $value default value to populate the search field |
|||
* @param string $format display format - 'plain' (default), 'short' or 'navbar' |
|||
* @return string |
|||
*/ |
|||
public function course_search_form($value = '', $format = 'plain') { |
|||
static $count = 0; |
|||
$formid = 'coursesearch'; |
|||
if ((++$count) > 1) { |
|||
$formid .= $count; |
|||
} |
|||
|
|||
switch ($format) { |
|||
case 'navbar' : |
|||
$formid = 'coursesearchnavbar'; |
|||
$inputid = 'navsearchbox'; |
|||
$inputsize = 20; |
|||
break; |
|||
case 'short' : |
|||
$inputid = 'shortsearchbox'; |
|||
$inputsize = 12; |
|||
break; |
|||
default : |
|||
$inputid = 'coursesearchbox'; |
|||
$inputsize = 30; |
|||
} |
|||
|
|||
$data = (object) [ |
|||
'searchurl' => (new moodle_url('/course/search.php'))->out(false), |
|||
'id' => $formid, |
|||
'inputid' => $inputid, |
|||
'inputsize' => $inputsize, |
|||
'value' => $value |
|||
]; |
|||
|
|||
return $this->render_from_template('theme_boost/course_search_form', $data); |
|||
} |
|||
|
|||
} |
@ -1,140 +0,0 @@ |
|||
<?php |
|||
// This file is part of Moodle - http://moodle.org/ |
|||
// |
|||
// Moodle is free software: you can redistribute it and/or modify |
|||
// it under the terms of the GNU General Public License as published by |
|||
// the Free Software Foundation, either version 3 of the License, or |
|||
// (at your option) any later version. |
|||
// |
|||
// Moodle is distributed in the hope that it will be useful, |
|||
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
// GNU General Public License for more details. |
|||
// |
|||
// You should have received a copy of the GNU General Public License |
|||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
|||
|
|||
namespace theme_boost\output\core; |
|||
|
|||
use plugin_renderer_base; |
|||
|
|||
defined('MOODLE_INTERNAL') || die(); |
|||
|
|||
require_once($CFG->dirroot . '/files/renderer.php'); |
|||
|
|||
/** |
|||
* Rendering of files viewer related widgets. |
|||
* @package theme_boost |
|||
* @copyright 2016 Damyon Wiese |
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
|||
*/ |
|||
|
|||
/** |
|||
* Rendering of files viewer related widgets. |
|||
* @package theme_boost |
|||
* @copyright 2016 Damyon Wiese |
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
|||
*/ |
|||
class files_renderer extends \core_files_renderer { |
|||
/** |
|||
* FileManager JS template for window with file information/actions. |
|||
* |
|||
*/ |
|||
protected function fm_js_template_fileselectlayout() { |
|||
$context = [ |
|||
'helpicon' => $this->help_icon('setmainfile', 'repository') |
|||
]; |
|||
return $this->render_from_template('core/filemanager_fileselect', $context); |
|||
} |
|||
|
|||
/** |
|||
* FileManager JS template for popup confirm dialogue window. |
|||
* |
|||
* @return string |
|||
*/ |
|||
protected function fm_js_template_confirmdialog() { |
|||
return $this->render_from_template('core/filemanager_confirmdialog', []); |
|||
} |
|||
|
|||
/** |
|||
* Template for FilePicker with general layout (not QuickUpload). |
|||
* |
|||
* |
|||
* @return string |
|||
*/ |
|||
protected function fp_js_template_generallayout() { |
|||
return $this->render_from_template('core/filemanager_modal_generallayout', []); |
|||
} |
|||
|
|||
/** |
|||
* Returns html for displaying one file manager |
|||
* |
|||
* @param form_filemanager $fm |
|||
* @return string |
|||
*/ |
|||
protected function fm_print_generallayout($fm) { |
|||
$context = [ |
|||
'client_id' => $fm->options->client_id, |
|||
'helpicon' => $this->help_icon('setmainfile', 'repository'), |
|||
'restrictions' => $this->fm_print_restrictions($fm) |
|||
]; |
|||
return $this->render_from_template('core/filemanager_page_generallayout', $context); |
|||
} |
|||
|
|||
/** |
|||
* Returns HTML for default repository searchform to be passed to Filepicker |
|||
* |
|||
* This will be used as contents for search form defined in generallayout template |
|||
* (form with id {TOOLSEARCHID}). |
|||
* Default contents is one text input field with name="s" |
|||
*/ |
|||
public function repository_default_searchform() { |
|||
return $this->render_from_template('core/filemanager_default_searchform', []); |
|||
} |
|||
|
|||
/** |
|||
* FilePicker JS template for 'Upload file' repository |
|||
* |
|||
* @return string |
|||
*/ |
|||
protected function fp_js_template_uploadform() { |
|||
return $this->render_from_template('core/filemanager_uploadform', []); |
|||
} |
|||
|
|||
/** |
|||
* FilePicker JS template for repository login form including templates for each element type |
|||
* |
|||
* @return string |
|||
*/ |
|||
protected function fp_js_template_loginform() { |
|||
return $this->render_from_template('core/filemanager_loginform', []); |
|||
} |
|||
|
|||
/** |
|||
* FilePicker JS template for window appearing to select a file. |
|||
* |
|||
* @return string |
|||
*/ |
|||
protected function fp_js_template_selectlayout() { |
|||
return $this->render_from_template('core/filemanager_selectlayout', []); |
|||
} |
|||
|
|||
/** |
|||
* FilePicker JS template for popup dialogue window asking for action when file with the same name already exists |
|||
* (multiple-file version). |
|||
* |
|||
* @return string |
|||
*/ |
|||
protected function fp_js_template_processexistingfilemultiple() { |
|||
return $this->render_from_template('core/filemanager_processexistingfilemultiple', []); |
|||
} |
|||
|
|||
/** |
|||
* FilePicker JS template for popup dialogue window asking for action when file with the same name already exists. |
|||
* |
|||
* @return string |
|||
*/ |
|||
protected function fp_js_template_processexistingfile() { |
|||
return $this->render_from_template('core/filemanager_processexistingfile', []); |
|||
} |
|||
} |
@ -1,58 +0,0 @@ |
|||
<?php |
|||
// This file is part of Moodle - http://moodle.org/ |
|||
// |
|||
// Moodle is free software: you can redistribute it and/or modify |
|||
// it under the terms of the GNU General Public License as published by |
|||
// the Free Software Foundation, either version 3 of the License, or |
|||
// (at your option) any later version. |
|||
// |
|||
// Moodle is distributed in the hope that it will be useful, |
|||
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
// GNU General Public License for more details. |
|||
// |
|||
// You should have received a copy of the GNU General Public License |
|||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
|||
|
|||
/** |
|||
* Question renderer. |
|||
* |
|||
* @package theme_boost |
|||
* @copyright 2017 onwards Ankit Agarwal <ankit.agrr@gmail.com> |
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
|||
*/ |
|||
|
|||
namespace theme_boost\output\core_question; |
|||
defined('MOODLE_INTERNAL') || die(); |
|||
|
|||
require_once($CFG->dirroot . '/' . $CFG->admin . '/renderer.php'); |
|||
|
|||
/** |
|||
* Question renderer class. |
|||
* |
|||
* @package theme_boost |
|||
* @copyright 2017 onwards Ankit Agarwal <ankit.agrr@gmail.com> |
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
|||
*/ |
|||
class bank_renderer extends \core_question_bank_renderer { |
|||
|
|||
/** |
|||
* Display additional navigation if needed. |
|||
* |
|||
* @return string |
|||
*/ |
|||
public function extra_horizontal_navigation() { |
|||
// Horizontal navigation for question bank. |
|||
if ($questionnode = $this->page->settingsnav->find("questionbank", \navigation_node::TYPE_CONTAINER)) { |
|||
if ($children = $questionnode->children) { |
|||
$tabs = []; |
|||
foreach ($children as $key => $node) { |
|||
$tabs[] = new \tabobject($node->key, $node->action, $node->text); |
|||
} |
|||
$active = $questionnode->find_active_node()->key; |
|||
return \html_writer::div(print_tabs([$tabs], $active, null, null, true), 'questionbank-navigation'); |
|||
} |
|||
} |
|||
return ''; |
|||
} |
|||
} |
@ -1,197 +0,0 @@ |
|||
<?php |
|||
// This file is part of Moodle - http://moodle.org/ |
|||
// |
|||
// Moodle is free software: you can redistribute it and/or modify |
|||
// it under the terms of the GNU General Public License as published by |
|||
// the Free Software Foundation, either version 3 of the License, or |
|||
// (at your option) any later version. |
|||
// |
|||
// Moodle is distributed in the hope that it will be useful, |
|||
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
// GNU General Public License for more details. |
|||
// |
|||
// You should have received a copy of the GNU General Public License |
|||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
|||
|
|||
|
|||
/** |
|||
* Overriden core maintenance renderer. |
|||
* |
|||
* @package theme_boost |
|||
* @copyright 2016 Frédéric Massart - FMCorz.net |
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
|||
*/ |
|||
|
|||
namespace theme_boost\output; |
|||
defined('MOODLE_INTERNAL') || die(); |
|||
|
|||
use coding_exception; |
|||
use moodle_page; |
|||
use block_contents; |
|||
use stdClass; |
|||
|
|||
/** |
|||
* The maintenance renderer. |
|||
* |
|||
* @package theme_boost |
|||
* @copyright 2016 Frédéric Massart - FMCorz.net |
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
|||
*/ |
|||
class core_renderer_maintenance extends core_renderer { |
|||
|
|||
/** |
|||
* Initialises the renderer instance. |
|||
* |
|||
* @param moodle_page $page |
|||
* @param string $target |
|||
* @throws coding_exception |
|||
*/ |
|||
public function __construct(moodle_page $page, $target) { |
|||
if ($target !== RENDERER_TARGET_MAINTENANCE || $page->pagelayout !== 'maintenance') { |
|||
throw new coding_exception('Invalid request for the maintenance renderer.'); |
|||
} |
|||
parent::__construct($page, $target); |
|||
} |
|||
|
|||
/** |
|||
* Does nothing. The maintenance renderer cannot produce blocks. |
|||
* |
|||
* @param block_contents $bc |
|||
* @param string $region |
|||
* @return string |
|||
*/ |
|||
public function block(block_contents $bc, $region) { |
|||
return ''; |
|||
} |
|||
|
|||
/** |
|||
* Does nothing. The maintenance renderer cannot produce blocks. |
|||
* |
|||
* @param string $region |
|||
* @param array $classes |
|||
* @param string $tag |
|||
* @return string |
|||
*/ |
|||
public function blocks($region, $classes = array(), $tag = 'aside') { |
|||
return ''; |
|||
} |
|||
|
|||
/** |
|||
* Does nothing. The maintenance renderer cannot produce blocks. |
|||
* |
|||
* @param string $region |
|||
* @return string |
|||
*/ |
|||
public function blocks_for_region($region) { |
|||
return ''; |
|||
} |
|||
|
|||
/** |
|||
* Does nothing. The maintenance renderer cannot produce a course content header. |
|||
* |
|||
* @param bool $onlyifnotcalledbefore |
|||
* @return string |
|||
*/ |
|||
public function course_content_header($onlyifnotcalledbefore = false) { |
|||
return ''; |
|||
} |
|||
|
|||
/** |
|||
* Does nothing. The maintenance renderer cannot produce a course content footer. |
|||
* |
|||
* @param bool $onlyifnotcalledbefore |
|||
* @return string |
|||
*/ |
|||
public function course_content_footer($onlyifnotcalledbefore = false) { |
|||
return ''; |
|||
} |
|||
|
|||
/** |
|||
* Does nothing. The maintenance renderer cannot produce a course header. |
|||
* |
|||
* @return string |
|||
*/ |
|||
public function course_header() { |
|||
return ''; |
|||
} |
|||
|
|||
/** |
|||
* Does nothing. The maintenance renderer cannot produce a course footer. |
|||
* |
|||
* @return string |
|||
*/ |
|||
public function course_footer() { |
|||
return ''; |
|||
} |
|||
|
|||
/** |
|||
* Does nothing. The maintenance renderer cannot produce a custom menu. |
|||
* |
|||
* @param string $custommenuitems |
|||
* @return string |
|||
*/ |
|||
public function custom_menu($custommenuitems = '') { |
|||
return ''; |
|||
} |
|||
|
|||
/** |
|||
* Does nothing. The maintenance renderer cannot produce a file picker. |
|||
* |
|||
* @param array $options |
|||
* @return string |
|||
*/ |
|||
public function file_picker($options) { |
|||
return ''; |
|||
} |
|||
|
|||
/** |
|||
* Does nothing. The maintenance renderer cannot produce and HTML file tree. |
|||
* |
|||
* @param array $dir |
|||
* @return string |
|||
*/ |
|||
public function htmllize_file_tree($dir) { |
|||
return ''; |
|||
|
|||
} |
|||
|
|||
/** |
|||
* Does nothing. The maintenance renderer does not support JS. |
|||
* |
|||
* @param block_contents $bc |
|||
*/ |
|||
public function init_block_hider_js(block_contents $bc) { |
|||
// Does nothing. |
|||
} |
|||
|
|||
/** |
|||
* Does nothing. The maintenance renderer cannot produce language menus. |
|||
* |
|||
* @return string |
|||
*/ |
|||
public function lang_menu() { |
|||
return ''; |
|||
} |
|||
|
|||
/** |
|||
* Does nothing. The maintenance renderer has no need for login information. |
|||
* |
|||
* @param null $withlinks |
|||
* @return string |
|||
*/ |
|||
public function login_info($withlinks = null) { |
|||
return ''; |
|||
} |
|||
|
|||
/** |
|||
* Does nothing. The maintenance renderer cannot produce user pictures. |
|||
* |
|||
* @param stdClass $user |
|||
* @param array $options |
|||
* @return string |
|||
*/ |
|||
public function user_picture(stdClass $user, array $options = null) { |
|||
return ''; |
|||
} |
|||
} |
@ -0,0 +1,106 @@ |
|||
<?php |
|||
// This file is part of Moodle - http://moodle.org/ |
|||
// |
|||
// Moodle is free software: you can redistribute it and/or modify |
|||
// it under the terms of the GNU General Public License as published by |
|||
// the Free Software Foundation, either version 3 of the License, or |
|||
// (at your option) any later version. |
|||
// |
|||
// Moodle is distributed in the hope that it will be useful, |
|||
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
// GNU General Public License for more details. |
|||
// |
|||
// You should have received a copy of the GNU General Public License |
|||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
|||
|
|||
/** |
|||
* Used to convert a bootswatch file from https://bootswatch.com/ to a Moodle preset. |
|||
* |
|||
* @package theme_ilb |
|||
* @subpackage cli |
|||
* @copyright 2016 Damyon Wiese |
|||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
|||
*/ |
|||
|
|||
define('CLI_SCRIPT', true); |
|||
|
|||
require(__DIR__.'/../../../config.php'); |
|||
require_once($CFG->libdir.'/clilib.php'); |
|||
|
|||
$usage = " |
|||
Utility to convert a Bootswatch theme to a Moodle preset compatible with Bootstrap 4. |
|||
|
|||
Download _variables.scss and _bootswatch.scss files from https://bootswatch.com/ |
|||
Run this script. It will generate a new file 'preset.scss' which can be used as |
|||
a Moodle preset. |
|||
|
|||
Usage: |
|||
# php import-bootswatch.php [--help|-h] |
|||
# php import-bootswatch.php --variables=<path> --bootswatch=<path> --preset=<path> |
|||
|
|||
Options: |
|||
-h --help Print this help. |
|||
--variables=<path> Path to the input variables file, defaults to _variables.scss |
|||
--bootswatch=<path> Path to the input bootswatch file, defauls to _bootswatch.scss |
|||
--preset=<path> Path to the output preset file, defaults to preset.scss |
|||
"; |
|||
|
|||
list($options, $unrecognised) = cli_get_params([ |
|||
'help' => false, |
|||
'variables' => '_variables.scss', |
|||
'bootswatch' => '_bootswatch.scss', |
|||
'preset' => 'preset.scss', |
|||
], [ |
|||
'h' => 'help', |
|||
]); |
|||
|
|||
if ($unrecognised) { |
|||
$unrecognised = implode(PHP_EOL.' ', $unrecognised); |
|||
cli_error(get_string('cliunknowoption', 'core_admin', $unrecognised)); |
|||
} |
|||
|
|||
if ($options['help']) { |
|||
cli_writeln($usage); |
|||
exit(2); |
|||
} |
|||
|
|||
if (is_readable($options['variables'])) { |
|||
$sourcevariables = file_get_contents($options['variables']); |
|||
} else { |
|||
cli_writeln($usage); |
|||
cli_error('Error reading the variables file: '.$options['variables']); |
|||
} |
|||
|
|||
|
|||
if (is_readable($options['bootswatch'])) { |
|||
$sourcebootswatch = file_get_contents($options['bootswatch']); |
|||
} else { |
|||
cli_writeln($usage); |
|||
cli_error('Error reading the bootswatch file: '.$options['bootswatch']); |
|||
} |
|||
|
|||
// Write the preset file. |
|||
$out = fopen($options['preset'], 'w'); |
|||
|
|||
if (!$out) { |
|||
cli_error('Error writing to the preset file'); |
|||
} |
|||
|
|||
fwrite($out, $sourcevariables); |
|||
|
|||
fwrite($out, ' |
|||
// Import FontAwesome. |
|||
@import "fontawesome"; |
|||
|
|||
// Import All of Bootstrap |
|||
@import "bootstrap"; |
|||
|
|||
// Import Core moodle CSS |
|||
@import "moodle"; |
|||
'); |
|||
|
|||
// Add the bootswatch file. |
|||
fwrite($out, $sourcebootswatch); |
|||
|
|||
fclose($out); |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 733 B |
Before Width: | Height: | Size: 792 B |
Before Width: | Height: | Size: 859 B |
Before Width: | Height: | Size: 926 B |
@ -1,48 +0,0 @@ |
|||
(function(audiojs,audiojsInstance,container){var path=(function(){var re=new RegExp('audio(\.min)?\.js.*'),scripts=document.getElementsByTagName('script');for(var i=0,ii=scripts.length;i<ii;i++){var path=scripts[i].getAttribute('src');if(re.test(path))return path.replace(re,'');}})();container[audiojs]={instanceCount:0,instances:{},flashSource:'\ |
|||
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="$1" width="1" height="1" name="$1" style="position: absolute; left: -1px;"> \ |
|||
<param name="movie" value="$2?playerInstance='+audiojs+'.instances[\'$1\']&datetime=$3"> \ |
|||
<param name="allowscriptaccess" value="always"> \ |
|||
<embed name="$1" src="$2?playerInstance='+audiojs+'.instances[\'$1\']&datetime=$3" width="1" height="1" allowscriptaccess="always"> \ |
|||
</object>',settings:{autoplay:false,loop:false,preload:true,imageLocation:path+'player-graphics.gif',swfLocation:path+'audiojs.swf',useFlash:(function(){var a=document.createElement('audio');return!(a.canPlayType&&a.canPlayType('audio/mpeg;').replace(/no/,''));})(),hasFlash:(function(){if(navigator.plugins&&navigator.plugins.length&&navigator.plugins['Shockwave Flash']){return true;}else if(navigator.mimeTypes&&navigator.mimeTypes.length){var mimeType=navigator.mimeTypes['application/x-shockwave-flash'];return mimeType&&mimeType.enabledPlugin;}else{try{var ax=new ActiveXObject('ShockwaveFlash.ShockwaveFlash');return true;}catch(e){}} |
|||
return false;})(),createPlayer:{markup:'\ |
|||
<div class="play-pause"> \ |
|||
<p class="play glyphicon glyphicon-play"></p> \ |
|||
<p class="pause glyphicon glyphicon-pause"></p> \ |
|||
<p class="loading glyphicon glyphicon-repeat"></p> \ |
|||
<p class="error glyphicon glyphicon-remove"></p> \ |
|||
</div> \ |
|||
<div class="scrubber"> \ |
|||
<div class="progress"></div> \ |
|||
<div class="loaded"></div> \ |
|||
</div> \ |
|||
<div class="time"> \ |
|||
<em class="played">00:00</em><strong class="duration">00:00</strong> \ |
|||
</div> \ |
|||
<div class="error-message"></div>',playPauseClass:'play-pause',scrubberClass:'scrubber',progressClass:'progress',loaderClass:'loaded',timeClass:'time',durationClass:'duration',playedClass:'played',errorMessageClass:'error-message',playingClass:'playing',loadingClass:'loading',errorClass:'error'},trackEnded:function(e){},flashError:function(){var player=this.settings.createPlayer,errorMessage=getByClass(player.errorMessageClass,this.wrapper),html='Missing <a href="http://get.adobe.com/flashplayer/">flash player</a> plugin.';if(this.mp3)html+=' <a href="'+this.mp3+'">Download audio file</a>.';container[audiojs].helpers.removeClass(this.wrapper,player.loadingClass);container[audiojs].helpers.addClass(this.wrapper,player.errorClass);errorMessage.innerHTML=html;},loadError:function(e){var player=this.settings.createPlayer,errorMessage=getByClass(player.errorMessageClass,this.wrapper);container[audiojs].helpers.removeClass(this.wrapper,player.loadingClass);container[audiojs].helpers.addClass(this.wrapper,player.errorClass);errorMessage.innerHTML='Error loading: "'+this.mp3+'"';},init:function(){var player=this.settings.createPlayer;container[audiojs].helpers.addClass(this.wrapper,player.loadingClass);},loadStarted:function(){var player=this.settings.createPlayer,duration=getByClass(player.durationClass,this.wrapper),m=Math.floor(this.duration/60),s=Math.floor(this.duration%60);container[audiojs].helpers.removeClass(this.wrapper,player.loadingClass);duration.innerHTML=((m<10?'0':'')+m+':'+(s<10?'0':'')+s);},loadProgress:function(percent){var player=this.settings.createPlayer,scrubber=getByClass(player.scrubberClass,this.wrapper),loaded=getByClass(player.loaderClass,this.wrapper);loaded.style.width=(scrubber.offsetWidth*percent)+'px';},playPause:function(){if(this.playing)this.settings.play();else this.settings.pause();},play:function(){var player=this.settings.createPlayer;container[audiojs].helpers.addClass(this.wrapper,player.playingClass);},pause:function(){var player=this.settings.createPlayer;container[audiojs].helpers.removeClass(this.wrapper,player.playingClass);},updatePlayhead:function(percent){var player=this.settings.createPlayer,scrubber=getByClass(player.scrubberClass,this.wrapper),progress=getByClass(player.progressClass,this.wrapper);progress.style.width=(scrubber.offsetWidth*percent)+'px';var played=getByClass(player.playedClass,this.wrapper),p=this.duration*percent,m=Math.floor(p/60),s=Math.floor(p%60);played.innerHTML=((m<10?'0':'')+m+':'+(s<10?'0':'')+s);}},create:function(element,options){var options=options||{} |
|||
if(element.length){return this.createAll(options,element);}else{return this.newInstance(element,options);}},createAll:function(options,elements){var audioElements=elements||document.getElementsByTagName('audio'),instances=[] |
|||
options=options||{};for(var i=0,ii=audioElements.length;i<ii;i++){instances.push(this.newInstance(audioElements[i],options));} |
|||
return instances;},newInstance:function(element,options){var element=element,s=this.helpers.clone(this.settings),id='audiojs'+this.instanceCount,wrapperId='audiojs_wrapper'+this.instanceCount,instanceCount=this.instanceCount++;if(element.getAttribute('autoplay')!=null)s.autoplay=true;if(element.getAttribute('loop')!=null)s.loop=true;if(element.getAttribute('preload')=='none')s.preload=false;if(options)this.helpers.merge(s,options);if(s.createPlayer.markup)element=this.createPlayer(element,s.createPlayer,wrapperId);else element.parentNode.setAttribute('id',wrapperId);var audio=new container[audiojsInstance](element,s);if(s.css)this.helpers.injectCss(audio,s.css);if(s.useFlash&&s.hasFlash){this.injectFlash(audio,id);this.attachFlashEvents(audio.wrapper,audio);}else if(s.useFlash&&!s.hasFlash){this.settings.flashError.apply(audio);} |
|||
if(!s.useFlash||(s.useFlash&&s.hasFlash))this.attachEvents(audio.wrapper,audio);this.instances[id]=audio;return audio;},createPlayer:function(element,player,id){var wrapper=document.createElement('div'),newElement=element.cloneNode(true);wrapper.setAttribute('class','audiojs');wrapper.setAttribute('className','audiojs');wrapper.setAttribute('id',id);if(newElement.outerHTML&&!document.createElement('audio').canPlayType){newElement=this.helpers.cloneHtml5Node(element);wrapper.innerHTML=player.markup;wrapper.appendChild(newElement);element.outerHTML=wrapper.outerHTML;wrapper=document.getElementById(id);}else{wrapper.appendChild(newElement);wrapper.innerHTML=wrapper.innerHTML+player.markup;element.parentNode.replaceChild(wrapper,element);} |
|||
return wrapper.getElementsByTagName('audio')[0];},attachEvents:function(wrapper,audio){if(!audio.settings.createPlayer)return;var player=audio.settings.createPlayer,playPause=getByClass(player.playPauseClass,wrapper),scrubber=getByClass(player.scrubberClass,wrapper),leftPos=function(elem){var curleft=0;if(elem.offsetParent){do{curleft+=elem.offsetLeft;}while(elem=elem.offsetParent);} |
|||
return curleft;};container[audiojs].events.addListener(playPause,'click',function(e){audio.playPause.apply(audio);});container[audiojs].events.addListener(scrubber,'click',function(e){var relativeLeft=e.clientX-leftPos(this);audio.skipTo(relativeLeft/scrubber.offsetWidth);});if(audio.settings.useFlash)return;container[audiojs].events.trackLoadProgress(audio);container[audiojs].events.addListener(audio.element,'timeupdate',function(e){audio.updatePlayhead.apply(audio);});container[audiojs].events.addListener(audio.element,'ended',function(e){audio.trackEnded.apply(audio);});container[audiojs].events.addListener(audio.source,'error',function(e){clearInterval(audio.readyTimer);clearInterval(audio.loadTimer);audio.settings.loadError.apply(audio);});},attachFlashEvents:function(element,audio){audio['swfReady']=false;audio['load']=function(mp3){audio.mp3=mp3;if(audio.swfReady)audio.element.load(mp3);} |
|||
audio['loadProgress']=function(percent,duration){audio.loadedPercent=percent;audio.duration=duration;audio.settings.loadStarted.apply(audio);audio.settings.loadProgress.apply(audio,[percent]);} |
|||
audio['skipTo']=function(percent){if(percent>audio.loadedPercent)return;audio.updatePlayhead.call(audio,[percent]) |
|||
audio.element.skipTo(percent);} |
|||
audio['updatePlayhead']=function(percent){audio.settings.updatePlayhead.apply(audio,[percent]);} |
|||
audio['play']=function(){if(!audio.settings.preload){audio.settings.preload=true;audio.element.init(audio.mp3);} |
|||
audio.playing=true;audio.element.pplay();audio.settings.play.apply(audio);} |
|||
audio['pause']=function(){audio.playing=false;audio.element.ppause();audio.settings.pause.apply(audio);} |
|||
audio['setVolume']=function(v){audio.element.setVolume(v);} |
|||
audio['loadStarted']=function(){audio.swfReady=true;if(audio.settings.preload)audio.element.init(audio.mp3);if(audio.settings.autoplay)audio.play.apply(audio);}},injectFlash:function(audio,id){var flashSource=this.flashSource.replace(/\$1/g,id);flashSource=flashSource.replace(/\$2/g,audio.settings.swfLocation);flashSource=flashSource.replace(/\$3/g,(+new Date+Math.random()));var html=audio.wrapper.innerHTML,div=document.createElement('div');div.innerHTML=flashSource+html;audio.wrapper.innerHTML=div.innerHTML;audio.element=this.helpers.getSwf(id);},helpers:{merge:function(obj1,obj2){for(attr in obj2){if(obj1.hasOwnProperty(attr)||obj2.hasOwnProperty(attr)){obj1[attr]=obj2[attr];}}},clone:function(obj){if(obj==null||typeof(obj)!=='object')return obj;var temp=new obj.constructor();for(var key in obj)temp[key]=arguments.callee(obj[key]);return temp;},addClass:function(element,className){var re=new RegExp('(\\s|^)'+className+'(\\s|$)');if(re.test(element.className))return;element.className+=' '+className;},removeClass:function(element,className){var re=new RegExp('(\\s|^)'+className+'(\\s|$)');element.className=element.className.replace(re,' ');},injectCss:function(audio,string){var prepend='',styles=document.getElementsByTagName('style'),css=string.replace(/\$1/g,audio.settings.imageLocation);for(var i=0,ii=styles.length;i<ii;i++){var title=styles[i].getAttribute('title');if(title&&~title.indexOf('audiojs')){style=styles[i];if(style.innerHTML===css)return;prepend=style.innerHTML;break;}};var head=document.getElementsByTagName('head')[0],firstchild=head.firstChild,style=document.createElement('style');if(!head)return;style.setAttribute('type','text/css');style.setAttribute('title','audiojs');if(style.styleSheet)style.styleSheet.cssText=prepend+css;else style.appendChild(document.createTextNode(prepend+css));if(firstchild)head.insertBefore(style,firstchild);else head.appendChild(styleElement);},cloneHtml5Node:function(audioTag){var fragment=document.createDocumentFragment(),doc=fragment.createElement?fragment:document;doc.createElement('audio');var div=doc.createElement('div');fragment.appendChild(div);div.innerHTML=audioTag.outerHTML;return div.firstChild;},getSwf:function(name){var swf=document[name]||window[name];return swf.length>1?swf[swf.length-1]:swf;}},events:{memoryLeaking:false,listeners:[],addListener:function(element,eventName,func){if(element.addEventListener){element.addEventListener(eventName,func,false);}else if(element.attachEvent){this.listeners.push(element);if(!this.memoryLeaking){window.attachEvent('onunload',function(){if(this.listeners){for(var i=0,ii=this.listeners.length;i<ii;i++){container[audiojs].events.purge(this.listeners[i]);}}});this.memoryLeaking=true;} |
|||
element.attachEvent('on'+eventName,function(){func.call(element,window.event);});}},trackLoadProgress:function(audio){if(!audio.settings.preload)return;var readyTimer,loadTimer,audio=audio,ios=(/(ipod|iphone|ipad)/i).test(navigator.userAgent);readyTimer=setInterval(function(){if(audio.element.readyState>-1){if(!ios)audio.init.apply(audio);} |
|||
if(audio.element.readyState>1){if(audio.settings.autoplay)audio.play.apply(audio);clearInterval(readyTimer);loadTimer=setInterval(function(){audio.loadProgress.apply(audio);if(audio.loadedPercent>=1)clearInterval(loadTimer);});}},10);audio.readyTimer=readyTimer;audio.loadTimer=loadTimer;},purge:function(d){var a=d.attributes,i;if(a){for(i=0;i<a.length;i+=1){if(typeof d[a[i].name]==='function')d[a[i].name]=null;}} |
|||
a=d.childNodes;if(a){for(i=0;i<a.length;i+=1)purge(d.childNodes[i]);}},ready:(function(){return function(fn){var win=window,done=false,top=true,doc=win.document,root=doc.documentElement,add=doc.addEventListener?'addEventListener':'attachEvent',rem=doc.addEventListener?'removeEventListener':'detachEvent',pre=doc.addEventListener?'':'on',init=function(e){if(e.type=='readystatechange'&&doc.readyState!='complete')return;(e.type=='load'?win:doc)[rem](pre+e.type,init,false);if(!done&&(done=true))fn.call(win,e.type||e);},poll=function(){try{root.doScroll('left');}catch(e){setTimeout(poll,50);return;} |
|||
init('poll');};if(doc.readyState=='complete')fn.call(win,'lazy');else{if(doc.createEventObject&&root.doScroll){try{top=!win.frameElement;}catch(e){} |
|||
if(top)poll();} |
|||
doc[add](pre+'DOMContentLoaded',init,false);doc[add](pre+'readystatechange',init,false);win[add](pre+'load',init,false);}}})()}} |
|||
container[audiojsInstance]=function(element,settings){this.element=element;this.wrapper=element.parentNode;this.source=element.getElementsByTagName('source')[0]||element;this.mp3=(function(element){var source=element.getElementsByTagName('source')[0];return element.getAttribute('src')||(source?source.getAttribute('src'):null);})(element);this.settings=settings;this.loadStartedCalled=false;this.loadedPercent=0;this.duration=1;this.playing=false;} |
|||
container[audiojsInstance].prototype={updatePlayhead:function(){var percent=this.element.currentTime/this.duration;this.settings.updatePlayhead.apply(this,[percent]);},skipTo:function(percent){if(percent>this.loadedPercent)return;this.element.currentTime=this.duration*percent;this.updatePlayhead();},load:function(mp3){this.loadStartedCalled=false;this.source.setAttribute('src',mp3);this.element.load();this.mp3=mp3;container[audiojs].events.trackLoadProgress(this);},loadError:function(){this.settings.loadError.apply(this);},init:function(){this.settings.init.apply(this);},loadStarted:function(){if(!this.element.duration)return false;this.duration=this.element.duration;this.updatePlayhead();this.settings.loadStarted.apply(this);},loadProgress:function(){if(this.element.buffered!=null&&this.element.buffered.length){if(!this.loadStartedCalled){this.loadStartedCalled=this.loadStarted();} |
|||
var durationLoaded=this.element.buffered.end(this.element.buffered.length-1);this.loadedPercent=durationLoaded/this.duration;this.settings.loadProgress.apply(this,[this.loadedPercent]);}},playPause:function(){if(this.playing)this.pause();else this.play();},play:function(){var ios=(/(ipod|iphone|ipad)/i).test(navigator.userAgent);if(ios&&this.element.readyState==0)this.init.apply(this);if(!this.settings.preload){this.settings.preload=true;this.element.setAttribute('preload','auto');container[audiojs].events.trackLoadProgress(this);} |
|||
this.playing=true;this.element.play();this.settings.play.apply(this);},pause:function(){this.playing=false;this.element.pause();this.settings.pause.apply(this);},setVolume:function(v){this.element.volume=v;},trackEnded:function(e){this.skipTo.apply(this,[0]);if(!this.settings.loop)this.pause.apply(this);this.settings.trackEnded.apply(this);}} |
|||
var getByClass=function(searchClass,node){var matches=[];node=node||document;if(node.getElementsByClassName){matches=node.getElementsByClassName(searchClass);}else{var i,l,els=node.getElementsByTagName("*"),pattern=new RegExp("(^|\\s)"+searchClass+"(\\s|$)");for(i=0,l=els.length;i<l;i++){if(pattern.test(els[i].className)){matches.push(els[i]);}}} |
|||
return matches.length>1?matches:matches[0];};})('audiojs','audiojsInstance',this); |
@ -1,35 +0,0 @@ |
|||
// initialise plugins
|
|||
jQuery(document).ready(function($){ |
|||
//alert('is running');
|
|||
// Audio js
|
|||
audiojs.events.ready(function() { |
|||
var as = audiojs.createAll(); |
|||
}); |
|||
|
|||
}); |
|||
|
|||
jQuery(window).load(function($){ |
|||
jQuery(".audiojs").each(function() { |
|||
var wi = jQuery(this).width(); |
|||
if (wi <= 310){ |
|||
jQuery(this).addClass('audioResize'); |
|||
}else { |
|||
jQuery(this).removeClass('audioResize'); |
|||
} |
|||
}); |
|||
|
|||
}); |
|||
|
|||
|
|||
|
|||
/* |
|||
$(window).on("resize load", function () { |
|||
var wi = $('#audiojs_wrapper0').width(); |
|||
if (wi <= 267){ |
|||
$('#audiojs_wrapper0').addClass('audioResize'); |
|||
} |
|||
else { |
|||
$('#audiojs_wrapper0').removeClass('audioResize'); |
|||
} |
|||
}); |
|||
*/ |
@ -1,25 +0,0 @@ |
|||
$(document).ready(function(){ |
|||
$(".div-collapse").click(function () { |
|||
//open up the content needed - toggle the slide- if visible, slide up, if not slidedown.
|
|||
$(".caixa-collapse").slideToggle(2, function () { |
|||
//execute this after slideToggle is done
|
|||
//change text of header based on visibility of content div
|
|||
|
|||
|
|||
}); |
|||
|
|||
if ($("#img_click").attr("src") == "../../theme/ilb/pix/smarts/bg_saiba_mais_header2_curso.png") { |
|||
$('#img_click').attr('src','../../theme/ilb/pix/smarts/bg_saiba_mais_fechado2.png'); |
|||
} |
|||
else{ |
|||
$('#img_click').attr('src','../../theme/ilb/pix/smarts/bg_saiba_mais_header2_curso.png'); |
|||
$(".caixa-collapse").css("margin-top", "0"); |
|||
|
|||
} |
|||
|
|||
$header = $(this); |
|||
//getting the next element
|
|||
|
|||
|
|||
}); |
|||
}); |
@ -1,2 +0,0 @@ |
|||
/*! Lazy Load 1.9.3 - MIT license - Copyright 2010-2013 Mika Tuupola */ |
|||
!function(a,b,c,d){var e=a(b);a.fn.lazyload=function(f){function g(){var b=0;i.each(function(){var c=a(this);if(!j.skip_invisible||c.is(":visible"))if(a.abovethetop(this,j)||a.leftofbegin(this,j));else if(a.belowthefold(this,j)||a.rightoffold(this,j)){if(++b>j.failure_limit)return!1}else c.trigger("appear"),b=0})}var h,i=this,j={threshold:0,failure_limit:0,event:"scroll",effect:"show",container:b,data_attribute:"original",skip_invisible:!0,appear:null,load:null,placeholder:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"};return f&&(d!==f.failurelimit&&(f.failure_limit=f.failurelimit,delete f.failurelimit),d!==f.effectspeed&&(f.effect_speed=f.effectspeed,delete f.effectspeed),a.extend(j,f)),h=j.container===d||j.container===b?e:a(j.container),0===j.event.indexOf("scroll")&&h.bind(j.event,function(){return g()}),this.each(function(){var b=this,c=a(b);b.loaded=!1,(c.attr("src")===d||c.attr("src")===!1)&&c.is("img")&&c.attr("src",j.placeholder),c.one("appear",function(){if(!this.loaded){if(j.appear){var d=i.length;j.appear.call(b,d,j)}a("<img />").bind("load",function(){var d=c.attr("data-"+j.data_attribute);c.hide(),c.is("img")?c.attr("src",d):c.css("background-image","url('"+d+"')"),c[j.effect](j.effect_speed),b.loaded=!0;var e=a.grep(i,function(a){return!a.loaded});if(i=a(e),j.load){var f=i.length;j.load.call(b,f,j)}}).attr("src",c.attr("data-"+j.data_attribute))}}),0!==j.event.indexOf("scroll")&&c.bind(j.event,function(){b.loaded||c.trigger("appear")})}),e.bind("resize",function(){g()}),/(?:iphone|ipod|ipad).*os 5/gi.test(navigator.appVersion)&&e.bind("pageshow",function(b){b.originalEvent&&b.originalEvent.persisted&&i.each(function(){a(this).trigger("appear")})}),a(c).ready(function(){g()}),this},a.belowthefold=function(c,f){var g;return g=f.container===d||f.container===b?(b.innerHeight?b.innerHeight:e.height())+e.scrollTop():a(f.container).offset().top+a(f.container).height(),g<=a(c).offset().top-f.threshold},a.rightoffold=function(c,f){var g;return g=f.container===d||f.container===b?e.width()+e.scrollLeft():a(f.container).offset().left+a(f.container).width(),g<=a(c).offset().left-f.threshold},a.abovethetop=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollTop():a(f.container).offset().top,g>=a(c).offset().top+f.threshold+a(c).height()},a.leftofbegin=function(c,f){var g;return g=f.container===d||f.container===b?e.scrollLeft():a(f.container).offset().left,g>=a(c).offset().left+f.threshold+a(c).width()},a.inviewport=function(b,c){return!(a.rightoffold(b,c)||a.leftofbegin(b,c)||a.belowthefold(b,c)||a.abovethetop(b,c))},a.extend(a.expr[":"],{"below-the-fold":function(b){return a.belowthefold(b,{threshold:0})},"above-the-top":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-screen":function(b){return a.rightoffold(b,{threshold:0})},"left-of-screen":function(b){return!a.rightoffold(b,{threshold:0})},"in-viewport":function(b){return a.inviewport(b,{threshold:0})},"above-the-fold":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-fold":function(b){return a.rightoffold(b,{threshold:0})},"left-of-fold":function(b){return!a.rightoffold(b,{threshold:0})}})}(jQuery,window,document); |
@ -1,11 +0,0 @@ |
|||
{ |
|||
"icons": [ |
|||
{ |
|||
"src": "\/noticias\/++resource++senado.noticias\/favicon\/android-chrome-192x192.png?v=697oma3x8q", |
|||
"sizes": "192x192", |
|||
"type": "image\/png" |
|||
} |
|||
], |
|||
"theme_color": "#00305c", |
|||
"display": "browser" |
|||
} |
@ -1,85 +0,0 @@ |
|||
|
|||
/* - ++resource++static/js/calendario.js - */ |
|||
$(document).ready(function(){ |
|||
// var $ = $18; // version 1.8
|
|||
// alert("[window.$, $]: " + window.$(document).jquery + ", " + $(document).jquery)
|
|||
|
|||
// Agenda
|
|||
configCalendar(); |
|||
|
|||
// Notícia
|
|||
configNoticia(); |
|||
}); |
|||
|
|||
////////////////////////////////////////////////////////////////////////////
|
|||
// Configuração do calendário para a utilização da agenda.
|
|||
var calendarMesAtual = ""; |
|||
|
|||
// Configuração do calendário.
|
|||
function configCalendar() { |
|||
mes = $(".portletCalendar .portletHeader").text(); |
|||
if (mes == calendarMesAtual) { |
|||
return true; |
|||
} |
|||
|
|||
// O mês foi alterado.
|
|||
configCalendarLinks(); |
|||
return false; |
|||
} |
|||
|
|||
// Configuração de links para a agenda.
|
|||
function configCalendarLinks() { |
|||
|
|||
// Modifica o endereço dos links para apontarem para a view.
|
|||
$("table.ploneCalendar a").each(function(index) { |
|||
var linkAgenda = $(this); |
|||
var endereco = linkAgenda.attr('href'); |
|||
var texto = $(this).attr('title'); |
|||
var data = texto.substring(0, 10); |
|||
var parts = endereco.split("/search"); |
|||
var urlPresidencia = parts[0] + "/eventos"; |
|||
var novoEndereco = urlPresidencia + "/pesquisaagenda?data=" + data; |
|||
linkAgenda.attr("href", novoEndereco); |
|||
}); |
|||
|
|||
// Tratamento dos eventos de mudança de mês (previous e next).
|
|||
$(".portletCalendar a#calendar-previous, .portletCalendar a#calendar-next").each(function(index) { |
|||
$(this).click(function() { |
|||
calendarMesAtual = $(".portletCalendar .portletHeader").text(); |
|||
serviceTimer(configCalendar, 1000); |
|||
}); |
|||
}); |
|||
|
|||
} |
|||
|
|||
// Configuração da view de notícia.
|
|||
// Remove a imagem de upload na view de detalhamento da notícia.
|
|||
function configNoticia() { |
|||
imgNoticia = $("div.newsImageContainer"); |
|||
imgNoticia.remove(); |
|||
sumario = $("div#parent-fieldname-description"); |
|||
sumario.remove(); |
|||
$(".newsDataPublicacao").after($('<div />').load('socialshare?NoticiaID='+ window.location)); |
|||
} |
|||
|
|||
function Imprimir(objeto){ |
|||
var printContent = document.getElementById(objeto); |
|||
var parametrosExibicaoJanela = 'left=250,top=150,width=800,height=800px,toolbar=0,scrollbars=0,status=0,directories=no, menubar=no, resizable=no'; |
|||
var winPrint = window.open('', '', parametrosExibicaoJanela); |
|||
|
|||
winPrint.document.write(printContent.innerHTML); |
|||
|
|||
var printIconesAcessibilidade = winPrint.document.getElementById('socialshare'); |
|||
printIconesAcessibilidade.innerHTML = ""; |
|||
|
|||
winPrint.document.close(); |
|||
winPrint.focus(); |
|||
winPrint.print(); |
|||
winPrint.close(); |
|||
} |
|||
|
|||
function EnviarEmail(objeto){ |
|||
titulo = objeto.title; |
|||
endereco = objeto.location; |
|||
window.open("mailto:?Subject=" + titulo + "&body=" + titulo + escape('\n') + endereco); |
|||
} |
@ -1,68 +0,0 @@ |
|||
|
|||
/* - ++resource++static/js/photo-gallery.js - */ |
|||
$(document).ready(function(){ |
|||
$('li img').on('click',function(){ |
|||
var src = $(this).attr('src'); |
|||
var img = '<img src="' + src + '" class="img-responsive"/>'; |
|||
|
|||
//start of new code new code
|
|||
var index = $(this).parent('li').index(); |
|||
|
|||
var html = ''; |
|||
html += img; |
|||
html += '<div style="height:25px;clear:both;display:block;">'; |
|||
html += '<a class="controls next" href="'+ (index+2) + '">próximo </a>'; |
|||
html += '<a class="controls previous" href="' + (index) + '"> anterior</a>'; |
|||
html += '</div>'; |
|||
|
|||
$('#myModal').modal(); |
|||
$('#myModal').on('shown.bs.modal', function(){ |
|||
$('#myModal .modal-body').html(html); |
|||
//new code
|
|||
$('a.controls').trigger('click'); |
|||
}) |
|||
$('#myModal').on('hidden.bs.modal', function(){ |
|||
$('#myModal .modal-body').html(''); |
|||
}); |
|||
|
|||
|
|||
|
|||
|
|||
}); |
|||
}) |
|||
|
|||
|
|||
$(document).on('click', 'a.controls', function(){ |
|||
var index = $(this).attr('href'); |
|||
var src = $('ul.row li:nth-child('+ index +') img').attr('src'); |
|||
|
|||
$('.modal-body img').attr('src', src); |
|||
|
|||
var newPrevIndex = parseInt(index) - 1; |
|||
var newNextIndex = parseInt(newPrevIndex) + 2; |
|||
|
|||
if($(this).hasClass('previous')){ |
|||
$(this).attr('href', newPrevIndex); |
|||
$('a.next').attr('href', newNextIndex); |
|||
}else{ |
|||
$(this).attr('href', newNextIndex); |
|||
$('a.previous').attr('href', newPrevIndex); |
|||
} |
|||
|
|||
var total = $('ul.row li').length + 1; |
|||
//hide next button
|
|||
if(total === newNextIndex){ |
|||
$('a.next').hide(); |
|||
}else{ |
|||
$('a.next').show() |
|||
} |
|||
//hide previous button
|
|||
if(newPrevIndex === 0){ |
|||
$('a.previous').hide(); |
|||
}else{ |
|||
$('a.previous').show() |
|||
} |
|||
|
|||
|
|||
return false; |
|||
}); |
@ -1,22 +0,0 @@ |
|||
/* global jQuery */ |
|||
(function($) { |
|||
|
|||
$(function() { |
|||
|
|||
var carousel = $('#carrosselImagensSenado') |
|||
$("img.lazyload").lazyload({ |
|||
event : "cliqueseta" |
|||
}); |
|||
|
|||
var carregaImagem = function() { |
|||
carousel.find('.item.active img.lazyload').trigger("cliqueseta") |
|||
} |
|||
|
|||
carousel.on('slid.bs.carousel', function () { |
|||
carregaImagem(); |
|||
}) |
|||
|
|||
carregaImagem(); |
|||
}); |
|||
|
|||
})(jQuery); |