Aspie96

bootstrap.native.dynamic

Feb 1st, 2017
299
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Native Javascript for Bootstrap 3
  2. // by dnp_theme
  3.  
  4. "strict mode";
  5.  
  6. if(!String.prototype.trim) {
  7.     String.prototype.trim = function() {
  8.         return this.replace(/^\s+|\s+$/g, "");
  9.     };
  10. }
  11. if(!Element.prototype.matches) {
  12.     Element.prototype.matches = Element.prototype.matchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.webkitMatchesSelector || function(s) {
  13.         var matches = (this.document || this.ownerDocument).querySelectorAll(s);
  14.         var i = matches.length;
  15.         while(--i >= 0 && matches.item(i) !== this);
  16.         return i > -1;            
  17.     };
  18. }
  19. Element.prototype.hasClass = function(cls) {
  20.     return (" " + this.className + " ").indexOf(" " + cls + " ") > -1;
  21. };
  22. Element.prototype.addClass = function(cls) {
  23.     if(!this.hasClass(cls)) {
  24.         if(this.className) {
  25.             this.className += " " + cls;
  26.         } else {
  27.             this.className = cls;
  28.         }
  29.     }
  30. };
  31. Element.prototype.removeClass = function(cls) {
  32.     if(this.hasClass(cls)) {
  33.         var classes = this.className.split(" ");
  34.         classes.splice(classes.indexOf(cls), 1);
  35.         this.className = classes.join(" ");
  36.     }
  37. };
  38.  
  39. // EventListener | CC0 | github.com/jonathantneal/EventListener
  40. this.Element&&Element.prototype.attachEvent&&!Element.prototype.addEventListener&&function(){function e(e,t){Window.prototype[e]=HTMLDocument.prototype[e]=Element.prototype[e]=t}function t(e){t.interval&&document.body&&(t.interval=clearInterval(t.interval),document.dispatchEvent(new CustomEvent("DOMContentLoaded")))}e("addEventListener",function(e,t){var n=this,r=n._c1_listeners=n._c1_listeners||{},o=r[e]=r[e]||[];o.length||n.attachEvent("on"+e,o.event=function(e){var t=n.document&&n.document.documentElement||n.documentElement||{scrollLeft:0,scrollTop:0};e.currentTarget=n,e.pageX=e.clientX+t.scrollLeft,e.pageY=e.clientY+t.scrollTop,e.preventDefault=function(){e.returnValue=!1},e.relatedTarget=e.fromElement||null,e.stopImmediatePropagation=function(){l=!1,e.cancelBubble=!0},e.stopPropagation=function(){e.cancelBubble=!0},e.target=e.srcElement||n,e.timeStamp=+new Date;for(var r,c=0,a=[].concat(o),l=!0;l&&(r=a[c]);++c)for(var i,u=0;i=o[u];++u)if(i==r){i.call(n,e);break}}),o.push(t)}),e("removeEventListener",function(e,t){for(var n,r=this,o=r._c1_listeners=r._c1_listeners||{},c=o[e]=o[e]||[],a=c.length-1;n=c[a];--a)if(n==t){c.splice(a,1);break}!c.length&&c.event&&r.detachEvent("on"+e,c.event)}),e("dispatchEvent",function(e){var t=this,n=e.type,r=t._c1_listeners=t._c1_listeners||{},o=r[n]=r[n]||[];try{return t.fireEvent("on"+n,e)}catch(c){return void(o.event&&o.event(e))}}),Object.defineProperty(Window.prototype,"CustomEvent",{get:function(){var e=this;return function(t,n){n=n||{};var r,o=e.document.createEventObject();o.type=t,o.returnValue=!n.cancelable,o.cancelBubble=!n.bubbles;for(r in n)o[r]=n[r];return o}}}),t.interval=setInterval(t,1),window.addEventListener("load",t)}();try{new window.CustomEvent("?")}catch(e){!function(){window.CustomEvent=function(e,t){var n;t=t||{bubbles:!1,cancelable:!1,detail:void 0};try{n=document.createEvent("CustomEvent"),n.initCustomEvent(e,t.bubbles,t.cancelable,t.detail)}catch(r){n=document.createEvent("Event"),n.initEvent(e,t.bubbles,t.cancelable),n.detail=t.detail}return n}}()}
  41.  
  42. document.on = function(event, selector, handler) {
  43.     if(!handler) {
  44.         handler = selector;
  45.         selector = false;
  46.     }
  47.     var handlerFunc;
  48.     if(selector) {
  49.         handlerFunc = function(e) {
  50.             var target = e.target;
  51.             while(target && target != document) {
  52.                 if(target.matches(selector)){
  53.                     e.currentTarget = target;
  54.                     handler.call(target, e);
  55.                 }
  56.                 target = target.parentNode;
  57.             }
  58.         };
  59.     } else {
  60.         handlerFunc = handler;
  61.     }
  62.     document.addEventListener(event, handlerFunc);
  63. };
  64.  
  65.  
  66.  
  67. // AFFIX DEFINITION
  68. // ===================
  69. function Affix(el) {
  70.     this.element = el;
  71.     var self = this;
  72.  
  73.     this.init = function() {
  74.         self.updateAffix();
  75.         window.addEventListener("scroll", Affix.scrollHandler, false);
  76.         window.addEventListener("resize", Affix.resizeHandler, false);
  77.     };
  78.     this.getTarget = function() {
  79.         return document.querySelector(self.element.getAttribute("data-target"));
  80.     };
  81.     this.offsetTop = function() {
  82.         if(self.getTarget() !== null) {
  83.             return self.targetRect().top + self.scrollOffset();
  84.         } else {
  85.             return parseInt(self.element.getAttribute("data-offset-top"));
  86.         }
  87.     };
  88.     this.offsetBottom = function () {
  89.         return self.getMaxScroll() - self.elementHeight() - self.element.getAttribute("data-offset-bottom");
  90.     };
  91.     this.scrollOffset = function () {
  92.         return window.pageYOffset || document.documentElement.scrollTop;
  93.     };
  94.     this.pinTop = function () {
  95.         self.element.addClass("affix");
  96.     };
  97.     this.unPinTop = function () {
  98.         self.element.removeClass("affix");
  99.     };
  100.     this.pinBottom = function () {
  101.         self.element.addClass("affix-bottom");
  102.     };
  103.     this.unPinBottom = function () {
  104.         self.element.removeClass("affix-bottom");
  105.     };
  106.     this.updatePin = function () {
  107.         if(!self.element.hasClass("affix") && self.offsetTop() - self.scrollOffset() < 0) {
  108.             self.pinTop();
  109.         } else if(self.element.hasClass("affix") && self.scrollOffset() <= self.offsetTop()) {
  110.             self.unPinTop();
  111.         }
  112.         if(!self.element.hasClass("affix-bottom") && self.offsetBottom() - self.scrollOffset() < 0) {
  113.             self.pinBottom();
  114.         } else if(self.element.hasClass("affix-bottom") && self.scrollOffset() <= self.offsetBottom()) {
  115.             self.unPinBottom();
  116.         }
  117.     };
  118.     this.updateAffix = function () {
  119.       self.unPinTop();
  120.       self.unPinBottom();
  121.       self.updatePin();
  122.     };
  123.     this.elementHeight = function() {
  124.       return self.element.offsetHeight;
  125.     };
  126.     this.targetRect = function(){
  127.       return self.getTarget().getBoundingClientRect()
  128.     };
  129.     this.getMaxScroll = function() {
  130.         return Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);
  131.     };
  132.  
  133.     this.on = function(par1, par2, par3) {
  134.         this.element.addEventListener(par1, par2, par3);
  135.     }
  136. }
  137.  
  138. Affix.all = function(callback) {
  139.     var elements = document.querySelectorAll('[data-spy="affix"]');
  140.     for(var i = 0; i < elements.length; i++) {
  141.         callback(new Affix(elements[i]));
  142.     }
  143. };
  144.  
  145. // AFFIX DATA API
  146. // =================
  147. Affix.scrollHandler = function() {
  148.     Affix.all(function(affix) {
  149.         affix.updatePin();
  150.     });
  151. };
  152. Affix.resizeHandler = function() {
  153.     Affix.all(function(affix) {
  154.         setTimeout(function(){
  155.             affix.updateAffix();
  156.         }, 50);
  157.     });
  158. };
  159.  
  160.  
  161.  
  162. // ALERT DEFINITION
  163. // ===================
  164. function Alert(el) {
  165.     this.element = el;
  166.     var self = this;
  167.  
  168.     this.close = function() {
  169.         var event = new CustomEvent("close.bs.alert", { "cancelable": true });
  170.         self.element.dispatchEvent(event);
  171.         if(!event.defaultPrevented) {
  172.             if(self.element.hasClass("in")) {
  173.                 self.element.removeClass("in");
  174.                 setTimeout(function() {
  175.                     self._close();
  176.                 }, 150);
  177.             } else {
  178.                 self._close();
  179.             }
  180.         }
  181.     };
  182.     this._close = function() {
  183.         self.element.parentNode.removeChild(self.element);
  184.         event = new CustomEvent("closed.bs.alert");
  185.         self.element.dispatchEvent(event);
  186.     }
  187.  
  188.     this.on = function(par1, par2, par3) {
  189.         this.element.addEventListener(par1, par2, par3);
  190.     }
  191. }
  192.  
  193. Alert.all = function(callback) {
  194.     var elements = document.querySelectorAll('.alert');
  195.     for(var i = 0; i < elements.length; i++) {
  196.         callback(new Alert(elements[i]));
  197.     }
  198. };
  199.  
  200. // ALERT DATA API
  201. // =================
  202. document.on("click", '[data-dismiss="alert"]', function(e) {
  203.     var alert = this;
  204.     while((alert = alert.parentNode) != document && !alert.hasClass("alert"));
  205.     if(alert.hasClass("alert")) {
  206.         new Alert(alert).close();
  207.         e.preventDefault();
  208.     }
  209. });
  210.  
  211.  
  212.  
  213. // BUTTON DEFINITION
  214. // ===================
  215. function Button(el) {
  216.     this.element = el;
  217.     var self = this;
  218.  
  219.     this.setState = function(option) {
  220.         if(!self.element.getAttribute("data-original-text")) {
  221.             self.element.setAttribute("data-original-text", self.element.innerHTML.replace(/^\s+|\s+$/g, ""));
  222.         }
  223.         if(option === "loading") {
  224.             self.element.addClass("disabled");
  225.             self.element.disabled = true;
  226.         }
  227.         var text = self.element.getAttribute("data-" + option + "-text");
  228.         if(text) {
  229.             self.element.innerHTML = text
  230.         }
  231.     };
  232.     this.reset = function() {
  233.         if(self.element.disabled || self.element.hasClass("disabled")) {
  234.             self.element.removeClass("disabled");
  235.             self.element.disabled = false;
  236.         }
  237.         var text = self.element.getAttribute("data-original-text");
  238.         if(text) {
  239.             self.element.innerHTML = text;
  240.         }
  241.     };
  242.     this.toggle = function(el) {
  243.         var parent = el.parentNode;
  244.         var label = el.tagName === "LABEL" ? el : parent.tagName === "LABEL" ? parent : null;
  245.         if(label) {
  246.             var target = self.element;
  247.             labels = target.querySelectorAll(".btn");
  248.             input = label.getElementsByTagName("INPUT")[0];
  249.             if(input) {
  250.                 if(input.type === "checkbox") {
  251.                     if(input.checked) {
  252.                         label.removeClass("active");
  253.                         input.checked = false;
  254.                     } else {
  255.                         label.addClass("active");
  256.                         input.checked = true;
  257.                     }
  258.                 }
  259.                 if(input.type === "radio") {
  260.                     if(!input.checked) {
  261.                         label.addClass("active");
  262.                         input.checked = true;
  263.                         for(var i = 0; i < labels.length; i++) {
  264.                             var l = labels[i];
  265.                             if(l !== label && l.hasClass("active")) {
  266.                                 var inp = l.getElementsByTagName("INPUT")[0];
  267.                                 l.removeClass("active");
  268.                                 inp.checked = false;
  269.                             }
  270.                         }
  271.                     }                
  272.                 }
  273.             }
  274.         }
  275.     };
  276.  
  277.     this.on = function(par1, par2, par3) {
  278.         this.element.addEventListener(par1, par2, par3);
  279.     }
  280. }
  281.  
  282. Button.all = function(callback) {
  283.     var elements = document.querySelectorAll('[data-toggle="button"],[data-toggle="buttons"]');
  284.     for(var i = 0; i < elements.length; i++) {
  285.         callback(new Button(elements[i]));
  286.     }
  287. };
  288.  
  289. // BUTTON DATA API
  290. // =================
  291. document.on("click", '.btn-group[data-toggle="buttons"]', function(e) {
  292.     new Button(this).toggle(e.target);
  293. });
  294.  
  295.  
  296.  
  297. // CAROUSEL DEFINITION
  298. // ===================
  299. function Carousel(el) {
  300.     this.element = el;
  301.     var self = this;
  302.  
  303.     this.init = function() {
  304.         var interval = self.interval();
  305.         if(interval) {
  306.             self.cycle(interval);
  307.             if(self.element.getAttribute("data-pause") != "false") {
  308.                 self.element.addEventListener("mouseenter", Carousel.pauseHandler, false);
  309.                 self.element.addEventListener("mouseleave", Carousel.resumeHandler, false);
  310.                 self.element.addEventListener("touchstart", Carousel.pauseHandler, false);
  311.                 self.element.addEventListener("touchend", Carousel.resumeHandler, false);
  312.             } else {
  313.                 self.element.removeEventListener("mouseenter", Carousel.pauseHandler, false);
  314.                 self.element.removeEventListener("mouseleave", Carousel.resumeHandler, false);
  315.                 self.element.removeEventListener("touchstart", Carousel.pauseHandler, false);
  316.                 self.element.removeEventListener("touchend", Carousel.resumeHandler, false);
  317.             }
  318.         }
  319.     };
  320.     this._clearInterval = function(removeAttribute) {
  321.         clearTimeout(self.element.getAttribute("data-timer"));
  322.         var timer = self.element.getAttribute("data-timer");
  323.         if(timer) {
  324.             clearTimeout(timer);
  325.             if(removeAttribute !== false) {
  326.                 self.element.removeAttribute("data-timer");
  327.             }
  328.         }
  329.     };
  330.     this.cycle = function(interval) {
  331.         self._clearInterval(false);
  332.         if(!interval) {
  333.             interval = self.interval();
  334.         }
  335.         self.element.setAttribute("data-timer", setTimeout(function() {
  336.             self.slideTo(self.getActiveIndex() + 1);
  337.         }, interval));
  338.     };
  339.     this.slideTo = function(next, slides) {
  340.         var event = new CustomEvent("slide.bs.carousel", { "cancelable": true });
  341.         self.element.dispatchEvent(event);
  342.         if(!event.defaultPrevented) {
  343.             slides = slides || self.element.querySelectorAll(".item");
  344.             var indicators = self.element.querySelectorAll(".carousel-indicators li");
  345.             var active = self.getActiveIndex();
  346.             self._clearInterval();
  347.             var nextNorm = ((next % slides.length) + slides.length) % slides.length;
  348.             indicators[active].removeClass("active");
  349.             indicators[nextNorm].addClass("active");
  350.             if(self.element.hasClass("slide")) {
  351.                 var direction;
  352.                 var dr;
  353.                 if(next > active) {
  354.                     direction = "left";
  355.                     dr = "next";
  356.                 } else {
  357.                     direction = "right";
  358.                     dr = "prev";
  359.                 }
  360.                 slides[nextNorm].addClass(dr);
  361.                 slides[nextNorm].offsetWidth;
  362.                 slides[nextNorm].addClass(direction);
  363.                 slides[active].addClass(direction);
  364.                 event = new CustomEvent("slid.bs.carousel");
  365.                 setTimeout(function() {
  366.                     slides[active].removeClass("active");
  367.                     slides[nextNorm].addClass("active");
  368.                     slides[nextNorm].removeClass(dr);
  369.                     slides[nextNorm].removeClass(direction);
  370.                     slides[active].removeClass(direction);
  371.                     if(self.interval() && !self.element.hasClass("paused")) {
  372.                         self.cycle();
  373.                     }
  374.                     self.element.dispatchEvent(event);
  375.                 }, self.duration() + 100);
  376.             } else {
  377.                 for(var i = 0; i < slides.length; i++) {
  378.                     if(i == nextNorm) {
  379.                         slides[i].addClass("active");
  380.                     } else {
  381.                         slides[i].removeClass("active");
  382.                     }
  383.                 }
  384.                 setTimeout(function() {
  385.                     if(self.interval() && !self.element.hasClass("paused")) {
  386.                         self.cycle();
  387.                     }
  388.                     self.element.dispatchEvent(event);
  389.                 }, self.duration() + 100);
  390.             }
  391.         }
  392.     };
  393.     this.getActiveIndex = function() {
  394.         var slides = self.element.querySelectorAll(".item");
  395.         var retVal = -1;
  396.         var i = 0;
  397.         while(retVal == -1 && i < slides.length) {
  398.             if(slides[i].hasClass("active")) {
  399.                 retVal = i;
  400.             }
  401.             i++;
  402.         }
  403.         return retVal;
  404.     };
  405.     this.interval = function(interval) {
  406.         if(interval === undefined) {
  407.             if(typeof self.element.getAttribute("data-interval") == "string" && self.element.getAttribute("data-interval") != "false") {
  408.                 return parseInt(self.element.getAttribute("data-interval")) || 5000;
  409.             } else {
  410.                 return false;
  411.             }
  412.         }
  413.         if(interval) {
  414.             self.element.setAttribute("data-interval", interval);
  415.         } else {
  416.             self.element.removeAttribute("data-interval");
  417.         }
  418.     };
  419.     this.duration = function(duration) {
  420.         if(duration === undefined) {
  421.             return parseInt(self.element.getAttribute("data-duration")) || 600;
  422.         }
  423.         if(duration) {
  424.             self.element.setAttribute("data-duration", duration);
  425.         } else {
  426.             self.element.removeAttribute("data-duration");
  427.         }
  428.     };
  429.     this.slideRight = function() {
  430.         self.slideTo(self.getActiveIndex() + 1);
  431.     };
  432.     this.slideLeft = function() {
  433.         self.slideTo(self.getActiveIndex() - 1);
  434.     };
  435.  
  436.     this.on = function(par1, par2, par3) {
  437.         this.element.addEventListener(par1, par2, par3);
  438.     };
  439. }
  440.  
  441. Carousel.all = function(callback) {
  442.     var elements = document.querySelectorAll('[data-ride="carousel"]');
  443.     for(var i = 0; i < elements.length; i++) {
  444.         callback(new Carousel(elements[i]));
  445.     }
  446. };
  447.  
  448. // CAROUSEL DATA API
  449. // =================
  450. Carousel.pauseHandler = function(e) {
  451.     if(this.matches('[data-ride="carousel"]')) {
  452.         var carousel = new Carousel(this);
  453.         if(carousel.interval() && !this.hasClass("paused")) {
  454.             carousel._clearInterval();
  455.             this.addClass("paused");
  456.         }
  457.     }
  458. };
  459. Carousel.resumeHandler = function(e) {
  460.     if(this.matches('[data-ride="carousel"]')) {
  461.         var carousel = new Carousel(this);
  462.         if(carousel.interval() && this.hasClass("paused")) {
  463.             this.removeClass("paused");
  464.             carousel.cycle();
  465.         }
  466.     }
  467. };
  468.  
  469. document.on("click", '.carousel-control', function(e) {
  470.     var carousel = this;
  471.     while(carousel != document && !carousel.matches('[data-ride="carousel"]')) {
  472.         carousel = carousel.parentNode;
  473.     }
  474.     if(carousel.matches('[data-ride="carousel"]') && !carousel.hasClass("sliding")) {
  475.         carousel = new Carousel(carousel);
  476.         if(this.getAttribute("data-slide") == "prev") {
  477.             carousel.slideLeft();
  478.         } else {
  479.             carousel.slideRight();
  480.         }
  481.         e.preventDefault();
  482.     }
  483. });
  484.  
  485. document.on("click", '[data-slide-to]', function(e) {
  486.     var carousel = this;
  487.     while(carousel != document && !carousel.matches('[data-ride="carousel"]')) {
  488.         carousel = carousel.parentNode;
  489.     }
  490.     if(carousel.matches('[data-ride="carousel"]') && !carousel.hasClass("sliding")) {
  491.         new Carousel(carousel).slideTo(parseInt(this.getAttribute("data-slide-to")) || 0);
  492.         e.preventDefault();
  493.     }
  494. });
  495.  
  496.  
  497.  
  498. // COLLAPSE DEFINITION
  499. // ===================
  500. function Collapse(el) {
  501.     this.element = el;
  502.     var self = this;
  503.  
  504.     this.toggle = function() {
  505.         var collapse = self.getTarget();
  506.         if(!collapse.hasClass("collapsing")) {
  507.             if(collapse.hasClass("in")) {
  508.                 self.close(collapse);
  509.             } else {
  510.                 self.open(collapse);
  511.             }
  512.         }
  513.     };
  514.     this.close = function(collapse) {
  515.         if(!collapse) {
  516.             collapse = self.getTarget();
  517.         }
  518.         if(collapse.hasClass("in")) {
  519.             self._close(collapse);
  520.             self.element.removeClass("collapsed");
  521.         }
  522.     };
  523.     this.open = function(collapse) {
  524.         if(!collapse) {
  525.             collapse = self.getTarget();
  526.         }
  527.         if(!collapse.hasClass("in")) {
  528.             var event = new CustomEvent("show.bs.dropdown", { "cancelable": true });
  529.             self.element.dispatchEvent(event);
  530.             if(!event.defaultPrevented) {
  531.                 self._open(collapse);
  532.                 self.element.addClass("collapsed");
  533.                 var accordionSelector = self.element.getAttribute("data-parent");
  534.                 if(accordionSelector) {
  535.                     var accordion = self.element;
  536.                     while(accordion != document && !accordion.matches(accordionSelector)) {
  537.                         accordion = accordion.parentNode;
  538.                     }
  539.                     if(accordion.matches(accordionSelector)) {
  540.                         var active = accordion.querySelectorAll(".collapse.in");
  541.                         for(var i = 0; i < active.length; i++) {
  542.                             if(active[i] !== collapse) {
  543.                                 event = new CustomEvent("hide.bs.collapse");
  544.                                 self.element.dispatchEvent(event);
  545.                                 self._close(active[i]);
  546.                             }
  547.                         }
  548.                     }
  549.                 }
  550.             }
  551.         }
  552.     };
  553.     this._open = function(c) {
  554.         c.addClass("in");
  555.         c.setAttribute("aria-expanded", true);
  556.         c.addClass("collapsing");
  557.         setTimeout(function() {
  558.             c.style.height = self.getMaxHeight(c) + "px";                    
  559.             c.style.overflowY = "hidden";
  560.         }, 0);
  561.         setTimeout(function() {
  562.             c.style.height = "";
  563.             c.style.overflowY = "";
  564.             c.removeClass("collapsing");
  565.             var event = new CustomEvent("shown.bs.dropdown");
  566.             c.dispatchEvent(event);
  567.         }, self.duration());
  568.     };
  569.     this._close = function(c) {
  570.         c.setAttribute("aria-expanded", false);
  571.         c.style.height = self.getMaxHeight(c) + "px";
  572.         setTimeout(function() {
  573.             c.style.height = "0px";
  574.             c.style.overflowY = "hidden";
  575.             c.addClass("collapsing");
  576.         },0);
  577.         setTimeout(function() {
  578.             c.removeClass("collapsing");
  579.             c.removeClass("in");
  580.             c.style.overflowY = "";
  581.             c.style.height = "";
  582.             var event = new CustomEvent("hidden.bs.dropdown");
  583.             c.dispatchEvent(event);
  584.         }, self.duration());
  585.     };
  586.     this.getMaxHeight = function(l) {
  587.         var retVal = 0;
  588.         for(var i = 0; i < l.children.length; i++) {
  589.             var el = l.children[i];
  590.             var s = el && el.currentStyle || window.getComputedStyle(el);
  591.             var btp = /px/.test(s.borderTopWidth) ? Math.round(s.borderTopWidth.replace("px", "")) : "0";
  592.             var mtp = /px/.test(s.marginTop) ? Math.round(s.marginTop.replace("px", "")) : "0";
  593.             var mbp = /px/.test(s.marginBottom) ? Math.round(s.marginBottom.replace("px", "")) : "0";
  594.             var bbp = /px/.test(s.borderBottomWidth) ? Math.round(s.borderBottomWidth.replace("px", "")) : "0";
  595.             var mte = /em/.test(s.marginTop) ? Math.round(s.marginTop.replace("em", "") * parseInt(s.fontSize)) : "0";
  596.             var mbe = /em/.test(s.marginBottom) ? Math.round(s.marginBottom.replace("em", "")  * parseInt(s.fontSize)) : "0";
  597.             retVal += el.clientHeight + parseInt(btp) + parseInt(mtp) + parseInt(mbp) + parseInt(bbp) + parseInt(mte) + parseInt(mbe);
  598.         }
  599.         return retVal + 1;
  600.     };
  601.     this.getTarget = function() {
  602.         var t = self.element;
  603.         var h = t.href && t.getAttribute("href").replace("#", "");
  604.         var d = t.getAttribute("data-target") && (t.getAttribute("data-target"));
  605.         var id = h || (d && /#/.test(d)) && d.replace("#", "");
  606.         var cl = (d && d.charAt(0) === ".") && d;
  607.         return id && document.getElementById(id) || cl && document.querySelector(cl);
  608.     };
  609.     this.duration = function(duration) {
  610.         if(duration === undefined) {
  611.             return parseInt(self.element.getAttribute("data-duration")) || 300;
  612.         }
  613.         self.element.setAttribute("data-duration", duration);
  614.     };
  615.  
  616.     this.on = function(par1, par2, par3) {
  617.         this.element.addEventListener(par1, par2, par3);
  618.     };
  619. }
  620.  
  621. Collapse.all = function(callback) {
  622.     var elements = document.querySelectorAll('[data-toggle="collapse"]');
  623.     for(var i = 0; i < elements.length; i++) {
  624.         callback(new Collapse(elements[i]));
  625.     }
  626. }
  627.  
  628. // COLLAPSE DATA API
  629. // =================
  630. document.on("click", '[data-toggle="collapse"]', function(e) {
  631.     new Collapse(this).toggle();
  632.     e.preventDefault();
  633. });
  634.  
  635.  
  636.  
  637. // DROPDOWN DEFINITION
  638. // ===================
  639. function Dropdown(el) {
  640.     this.element = el;
  641.     var self = this;
  642.  
  643.     this.toggle = function() {
  644.         if(self.element.parentNode.hasClass("open")) {
  645.             self.close();
  646.         } else {
  647.             self.open();
  648.         }
  649.     };
  650.     this.open = function() {
  651.         if(!self.element.parentNode.hasClass("open")) {
  652.             var event = new CustomEvent("show.bs.dropdown", { "cancelable": true });
  653.             self.element.parentNode.dispatchEvent(event);
  654.             if(!event.defaultPrevented) {
  655.                 if(!Dropdown.active) {
  656.                     document.addEventListener("keydown", Dropdown.keydownHandler, false);
  657.                 }
  658.                 Dropdown.active = self;
  659.                 self.element.parentNode.addClass("open");
  660.                 self.element.setAttribute("aria-expanded", true);
  661.                 vent = new CustomEvent("shown.bs.dropdown");
  662.                 self.element.parentNode.dispatchEvent(event);
  663.             }
  664.         }
  665.     };
  666.     this.close = function() {
  667.         if(self.element.parentNode.hasClass("open")) {
  668.             var event = new CustomEvent("hide.bs.dropdown");
  669.             self.element.parentNode.dispatchEvent(event);
  670.             if(self.element.parentNode.hasClass("open")) {
  671.                 if(Dropdown.active.element == self.element) {
  672.                     Dropdown.active = null;
  673.                     document.removeEventListener("keydown", Dropdown.keydownHandler, false);
  674.                 }
  675.                 self.element.parentNode.removeClass("open");
  676.                 self.element.setAttribute("aria-expanded", false);
  677.                 event = new CustomEvent("hidden.bs.dropdown");
  678.                 self.element.parentNode.dispatchEvent(event);
  679.             }
  680.         }
  681.     };
  682.  
  683.     this.on = function(par1, par2, par3) {
  684.         this.element.addEventListener(par1, par2, par3);
  685.     };
  686. }
  687.  
  688. Dropdown.all = function(callback) {
  689.     var elements = document.querySelectorAll('[data-toggle="dropdown"]');
  690.     for(var i = 0; i < elements.length; i++) {
  691.         callback(new Dropdown(elements[i]));
  692.     }
  693. };
  694.  
  695. // DROPDOWN DATA API
  696. // =================
  697. Dropdown.keydownHandler = function(e) {
  698.     if(Dropdown.active && e.which == 27) {
  699.         Dropdown.active.close();
  700.     }
  701. };
  702.  
  703. document.on("click", '[data-toggle="dropdown"]', function(e) {
  704.     new Dropdown(this).toggle();
  705.     e.preventDefault();
  706. });
  707.  
  708. document.on("click", function(e) {
  709.     Dropdown.all(function(dropdown) {
  710.         if(!dropdown.element.contains(e.target)) {
  711.             dropdown.close();
  712.         }
  713.     });
  714. });
  715.  
  716.  
  717.  
  718. // MODAL DEFINITION
  719. // ===================
  720. function Modal(el) {
  721.     this.element = el;
  722.     var self = this;
  723.  
  724.     this.open = function() {
  725.         if(!self.element.hasClass("in")) {
  726.             var event = new CustomEvent("show.bs.modal", { "cancelable": true });
  727.             self.element.dispatchEvent(event);
  728.             if(!event.defaultPrevented) {
  729.                 if(!Modal.active) {
  730.                     document.addEventListener("keydown", Modal.keydownHandler, false);
  731.                     window.addEventListener("resize", Modal.resizeHandler, false);
  732.                 }
  733.                 Modal.active = self;
  734.                 var currentOpen = document.querySelector(".modal.in");
  735.                 var duration = self.element.getAttribute("data-duration") || 300;
  736.                 if(currentOpen){
  737.                     clearTimeout(currentOpen.getAttribute("data-timer"));
  738.                     currentOpen.removeClass("in");
  739.                     setTimeout(function() {
  740.                         currentOpen.setAttribute("aria-hidden", true);
  741.                         currentOpen.style.display = "";
  742.                     }, duration / 2);
  743.                 }
  744.                 if(self.element.getAttribute("data-backdrop") != "false") {
  745.                     var overlay = self.createOverlay();
  746.                     setTimeout(function() {
  747.                         overlay.addClass("in");
  748.                     }, 0);
  749.                 }
  750.                 clearTimeout(self.element.getAttribute("data-timer"));
  751.                 self.element.setAttribute("data-timer", setTimeout(function() {
  752.                     self.element.style.display = "block";
  753.                     self.adjustDialog();
  754.                     self.setScrollbar();
  755.                     document.body.addClass("modal-open");
  756.                     self.element.addClass("in");
  757.                     self.element.setAttribute("aria-hidden", false);
  758.                     event = new CustomEvent("shown.bs.modal");
  759.                     self.element.dispatchEvent(event);
  760.                 }, duration / 2));
  761.             }
  762.         }
  763.     };
  764.     this.createOverlay = function() {
  765.         var retVal = document.querySelector(".modal-backdrop");
  766.         if(!retVal) {
  767.             retVal = document.createElement("div");
  768.             retVal.addClass("modal-backdrop");
  769.             retVal.addClass("fade");
  770.             document.body.appendChild(retVal);
  771.         }
  772.         return retVal;
  773.     };
  774.     this.close = function() {
  775.         if(self.element.hasClass("in")) {
  776.             var event = new CustomEvent("hide.bs.modal", { "cancelable": true });
  777.             self.element.dispatchEvent(event);
  778.             if(!event.defaultPrevented) {
  779.                 if(self.element.hasClass("in")) {
  780.                     if(Modal.active.element == self.element) {
  781.                         Modal.active = null;
  782.                         document.removeEventListener("keydown", Modal.keydownHandler, false);
  783.                         window.removeEventListener("resize", Modal.resizeHandler, false);
  784.                     }
  785.                     var overlay = document.querySelector(".modal-backdrop");
  786.                     if(overlay) {
  787.                         overlay.removeClass("in");
  788.                     }      
  789.                     self.element.removeClass("in");
  790.                     self.element.setAttribute("aria-hidden", true);
  791.                     clearTimeout(self.element.getAttribute("data-timer"));
  792.                     var duration = self.element.getAttribute("data-duration") || 300;
  793.                     self.element.setAttribute("data-timer", setTimeout(function() {
  794.                         document.body.removeClass("modal-open");
  795.                         self.resetAdjustments();
  796.                         self.resetScrollbar();
  797.                         self.element.style.display = "";
  798.                     }, duration / 2));
  799.                     setTimeout(function() {
  800.                         if(!document.querySelector(".modal.in")) {
  801.                             self.removeOverlay(overlay);
  802.                         }
  803.                         event = new CustomEvent("hidden.bs.modal");
  804.                         self.element.dispatchEvent(event);
  805.                     }, duration);
  806.                 }
  807.             }
  808.         }
  809.     };
  810.     this.removeOverlay = function(overlay) {
  811.         if(!overlay) {
  812.             overlay = document.querySelector(".modal-backdrop");
  813.         }
  814.         if(overlay) {
  815.             document.body.removeChild(overlay);
  816.         }
  817.     };
  818.     this.content = function(content) {
  819.         if(typeof content == "string") {
  820.             return self.element.querySelector(".modal-content").innerHTML = content;
  821.         } else {
  822.             return self.element.querySelector(".modal-content").innerHTML;
  823.         }
  824.     };
  825.     this.adjustDialog = function() {
  826.         var htmlRect = document.documentElement.getBoundingClientRect();
  827.         var bodyIsOverflowing = document.body.clientWidth < (window.innerWidth || (htmlRect.right - Math.abs(htmlRect.left)));
  828.         var modalIsOverflowing = self.element.scrollHeight > document.documentElement.clientHeight;
  829.         var scrollbarWidth = self.measureScrollbar();
  830.         self.element.style.paddingLeft = !bodyIsOverflowing && modalIsOverflowing ? scrollbarWidth + 'px' : '';
  831.         self.element.style.paddingRight = bodyIsOverflowing && !modalIsOverflowing ? scrollbarWidth + 'px' : '';
  832.     };
  833.     this.resetAdjustments = function() {
  834.         self.element.style.paddingLeft = "";
  835.         self.element.style.paddingRight = "";
  836.     };
  837.     this.setScrollbar = function() {
  838.         var bodyStyle = document.body.currentStyle || window.getComputedStyle(document.body);
  839.         var bodyPad = parseInt((bodyStyle.paddingRight), 10);
  840.         var htmlRect = document.documentElement.getBoundingClientRect();
  841.         if(document.body.clientWidth < (window.innerWidth || (htmlRect.right - Math.abs(htmlRect.left)))) {
  842.             document.body.style.paddingRight = (bodyPad + self.measureScrollbar()) + "px";
  843.         }
  844.     };
  845.     this.resetScrollbar = function() {
  846.         document.body.style.paddingRight = "";
  847.     };
  848.     this.measureScrollbar = function() {
  849.         var scrollDiv = document.createElement("div");
  850.         scrollDiv.className = "modal-scrollbar-measure";
  851.         document.body.appendChild(scrollDiv);
  852.         var retVal = scrollDiv.offsetWidth - scrollDiv.clientWidth;
  853.         document.body.removeChild(scrollDiv);
  854.         return retVal;
  855.     };
  856.  
  857.     this.on = function(par1, par2, par3) {
  858.         this.element.addEventListener(par1, par2, par3);
  859.     };
  860. }
  861.  
  862. Modal.all = function(callback) {
  863.     var elements = document.querySelectorAll('.modal');
  864.     for(var i = 0; i < elements.length; i++) {
  865.         callback(new Modal(elements[i]));
  866.     }
  867. };
  868.  
  869.  
  870. // MODAL DATA API
  871. // =================
  872. Modal.keydownHandler = function(e) {
  873.     if(Modal.active && e.which == 27 && Modal.active.element.getAttribute("data-keyboard") != "false") {
  874.         Modal.active.close();
  875.     }
  876. };
  877.  
  878. Modal.resizeHandler = function(e) {
  879.     if(Modal.active) {
  880.         var overlay = document.querySelector(".modal-backdrop");
  881.         if(overlay && overlay.hasClass("in")) {
  882.             dim = {
  883.                 w: document.documentElement.clientWidth + "px",
  884.                 h: document.documentElement.clientHeight + "px"
  885.             };
  886.             overlay.style.height = dim.h;
  887.             overlay.style.width = dim.w;
  888.             Modal.active.adjustDialog();
  889.         }
  890.     }
  891. };
  892.  
  893. document.on("click", '[data-toggle="modal"]', function(e) {
  894.     new Modal(document.getElementById(this.getAttribute("data-target") && this.getAttribute("data-target").replace("#", "") || this.getAttribute("href") && this.getAttribute("href").replace("#", ""))).open();
  895.     e.preventDefault();
  896. });
  897.  
  898. document.on("click", '.modal', function(e) {
  899.     if(e.target.parentNode.getAttribute("data-dismiss") === "modal" || e.target.getAttribute("data-dismiss") === "modal" || e.target === this) {
  900.         new Modal(this).close();
  901.         e.preventDefault();
  902.     }
  903. });
  904.  
  905.  
  906.  
  907. (function(factory){
  908.  
  909.   // CommonJS/RequireJS and "native" compatibility
  910.   if(typeof module !== "undefined" && typeof exports == "object") {
  911.     // A commonJS/RequireJS environment
  912.     if(typeof window != "undefined") {
  913.       // Window and document exist, so return the factory's return value.
  914.       module.exports = factory();
  915.     } else {
  916.       // Let the user give the factory a Window and Document.
  917.       module.exports = factory;
  918.     }
  919.   } else {
  920.     // Assume a traditional browser.
  921.     window.Popover = factory();
  922.   }
  923.  
  924. })(function(){
  925.  
  926.   // POPOVER DEFINITION
  927.   // ===================
  928.   var Popover = function( element,options ) {
  929.     options = options || {};
  930.     this.isIE = (new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})").exec(navigator.userAgent) != null) ? parseFloat( RegExp.$1 ) : false;
  931.     this.link = typeof element === 'object' ? element : document.querySelector(element);
  932.     this.title = this.link.getAttribute('data-title') || null;
  933.     this.content = this.link.getAttribute('data-content') || null;
  934.     this.popover = null;
  935.     this.options = {};
  936.     this.options.template = options.template ? options.template : null;
  937.     this.options.trigger = options.trigger ? options.trigger : 'hover';
  938.     this.options.animation = options.animation && options.animation !== 'true' ? options.animation : 'true';
  939.     this.options.placement = options.placement ? options.placement : 'top';
  940.     this.options.delay = parseInt(options.delay) || 100;
  941.     this.options.dismiss = options.dismiss && options.dismiss === 'true' ? true : false;    
  942.     this.duration = 150;
  943.     this.options.duration = (this.isIE && this.isIE < 10) ? 0 : (options.duration || this.duration);
  944.     this.options.container = document.body;
  945.     if ( this.content || this.options.template ) this.init();
  946.     this.timer = 0 // the link own event timer
  947.     this.rect = null;
  948.   }
  949.  
  950.   // POPOVER METHODS
  951.   // ================
  952.   Popover.prototype = {
  953.  
  954.     init : function() {
  955.       this.actions();
  956.       var events = ('onmouseleave' in this.link) ? [ 'mouseenter', 'mouseleave'] : [ 'mouseover', 'mouseout' ];
  957.       if (this.options.trigger === 'hover') {
  958.         this.link.addEventListener(events[0], this.open, false);
  959.         if (!this.options.dismiss) { this.link.addEventListener(events[1], this.close, false); }
  960.       } else if (this.options.trigger === 'click') {
  961.         this.link.addEventListener('click', this.toggle, false);
  962.         if (!this.options.dismiss) { this.link.addEventListener('blur', this.close, false); }          
  963.       } else if (this.options.trigger === 'focus') {
  964.         this.link.addEventListener('focus', this.toggle, false);
  965.         if (!this.options.dismiss) { this.link.addEventListener('blur', this.close, false);  }
  966.       }
  967.      
  968.       if (this.options.dismiss) {  document.addEventListener('click', this.dismiss, false); }
  969.        
  970.       if (!(this.isIE && this.isIE < 9) ) { // dismiss on window resize
  971.         window.addEventListener('resize', this.close, false );
  972.       }
  973.     },
  974.  
  975.     actions : function() {
  976.       var self = this;
  977.  
  978.       this.toggle = function(e) {
  979.         if (self.popover === null) {
  980.           self.open()
  981.         } else {
  982.           self.close()
  983.         }
  984.       },
  985.       this.open = function(e) {
  986.         clearTimeout(self.link.getAttribute('data-timer'));
  987.         self.timer = setTimeout( function() {
  988.           if (self.popover === null) {
  989.             self.createPopover();
  990.             self.stylePopover();
  991.             self.updatePopover()
  992.           }
  993.         }, self.options.duration );
  994.         self.link.setAttribute('data-timer',self.timer);
  995.       },
  996.       this.dismiss = function(e) {
  997.         if (self.popover && e.target === self.popover.querySelector('.close')) {          
  998.           self.close();
  999.         }
  1000.       },
  1001.       this.close = function(e) {
  1002.         clearTimeout(self.link.getAttribute('data-timer'));
  1003.         self.timer = setTimeout( function() {
  1004.           if (self.popover && self.popover !== null && /in/.test(self.popover.className)) {
  1005.             self.popover.className = self.popover.className.replace(' in','');
  1006.             setTimeout(function() {
  1007.               self.removePopover(); // for performance/testing reasons we can keep the popovers if we want
  1008.             }, self.options.duration);
  1009.           }
  1010.  
  1011.         }, self.options.delay + self.options.duration);
  1012.         self.link.setAttribute('data-timer',self.timer);
  1013.       },
  1014.  
  1015.       //remove the popover
  1016.       this.removePopover = function() {
  1017.         this.popover && this.options.container.removeChild(this.popover);
  1018.         this.popover = null;
  1019.         this.timer = null
  1020.       },
  1021.  
  1022.       this.createPopover = function() {
  1023.         this.popover = document.createElement('div');
  1024.  
  1025.         if ( this.content !== null && this.options.template === null ) { //create the popover from data attributes
  1026.  
  1027.           this.popover.setAttribute('role','tooltip');
  1028.  
  1029.           var popoverArrow = document.createElement('div');
  1030.           popoverArrow.setAttribute('class','arrow');
  1031.  
  1032.           if (this.title !== null) {
  1033.             var popoverTitle = document.createElement('h3');
  1034.             popoverTitle.setAttribute('class','popover-title');
  1035.            
  1036.             if (this.options.dismiss) {
  1037.               popoverTitle.innerHTML = this.title + '<button type="button" class="close">×</button>';
  1038.             } else {
  1039.               popoverTitle.innerHTML = this.title;
  1040.             }
  1041.             this.popover.appendChild(popoverTitle);
  1042.           }
  1043.  
  1044.           var popoverContent = document.createElement('div');
  1045.           popoverContent.setAttribute('class','popover-content');
  1046.  
  1047.           this.popover.appendChild(popoverArrow);
  1048.           this.popover.appendChild(popoverContent);
  1049.  
  1050.           //set popover content
  1051.           if (this.options.dismiss && this.title === null) {
  1052.             popoverContent.innerHTML = this.content + '<button type="button" class="close">×</button>';
  1053.           } else {
  1054.             popoverContent.innerHTML = this.content;
  1055.           }
  1056.  
  1057.         } else {  // or create the popover from template
  1058.           var template = document.createElement('div');
  1059.           template.innerHTML = this.options.template;
  1060.           this.popover.innerHTML = template.firstChild.innerHTML;
  1061.         }
  1062.  
  1063.         //append to the container
  1064.         this.options.container.appendChild(this.popover);
  1065.         this.popover.style.display = 'block';
  1066.       },
  1067.  
  1068.       this.stylePopover = function(pos) {
  1069.         this.rect = this.getRect();
  1070.         var placement = pos || this.options.placement;
  1071.         var animation = this.options.animation === 'true' ? 'fade' : '';
  1072.         this.popover.setAttribute('class','popover '+placement+' '+animation);
  1073.  
  1074.         var linkDim = { w: this.link.offsetWidth, h: this.link.offsetHeight }; //link real dimensions
  1075.  
  1076.         // all popover dimensions
  1077.         var pd = this.popoverDimensions(this.popover);
  1078.         var toolDim = { w : pd.w, h: pd.h }; //popover real dimensions
  1079.  
  1080.  
  1081.         //window vertical and horizontal scroll
  1082.  
  1083.         var scrollYOffset = this.getScroll().y;
  1084.         var scrollXOffset =  this.getScroll().x;
  1085.  
  1086.         //apply styling
  1087.         if ( /top/.test(placement) ) { //TOP
  1088.           this.popover.style.top = this.rect.top + scrollYOffset - toolDim.h + 'px';
  1089.           this.popover.style.left = this.rect.left + scrollXOffset - toolDim.w/2 + linkDim.w/2 + 'px'
  1090.  
  1091.         } else if ( /bottom/.test(placement) ) { //BOTTOM
  1092.           this.popover.style.top = this.rect.top + scrollYOffset + linkDim.h + 'px';
  1093.           this.popover.style.left = this.rect.left + scrollXOffset - toolDim.w/2 + linkDim.w/2 + 'px';
  1094.  
  1095.         } else if ( /left/.test(placement) ) { //LEFT
  1096.           this.popover.style.top = this.rect.top + scrollYOffset - toolDim.h/2 + linkDim.h/2 + 'px';
  1097.           this.popover.style.left = this.rect.left + scrollXOffset - toolDim.w + 'px';
  1098.  
  1099.         } else if ( /right/.test(placement) ) { //RIGHT
  1100.           this.popover.style.top = this.rect.top + scrollYOffset - toolDim.h/2 + linkDim.h/2 + 'px';
  1101.           this.popover.style.left = this.rect.left + scrollXOffset + linkDim.w + 'px';
  1102.         }
  1103.       },
  1104.  
  1105.       this.updatePopover = function() {
  1106.         var placement = null;
  1107.         if ( !self.isElementInViewport(self.popover) ) {
  1108.           placement = self.updatePlacement();
  1109.         } else {
  1110.           placement = self.options.placement;
  1111.         }
  1112.  
  1113.         self.stylePopover(placement);
  1114.  
  1115.         self.popover.className += ' in';
  1116.       },
  1117.       this.updatePlacement = function() {
  1118.         var pos = this.options.placement;
  1119.         if ( /top/.test(pos) ) { //TOP
  1120.           return 'bottom';
  1121.         } else if ( /bottom/.test(pos) ) { //BOTTOM
  1122.           return 'top';
  1123.         } else if ( /left/.test(pos) ) { //LEFT
  1124.           return 'right';
  1125.         } else if ( /right/.test(pos) ) { //RIGHT
  1126.           return 'left';
  1127.         }
  1128.       },
  1129.       this.getRect = function() {
  1130.         return this.link.getBoundingClientRect()
  1131.       },
  1132.       this.getScroll = function() {
  1133.         return {
  1134.           y : window.pageYOffset || document.documentElement.scrollTop,
  1135.           x : window.pageXOffset || document.documentElement.scrollLeft
  1136.         }
  1137.       },
  1138.       this.popoverDimensions  = function(p) {//check popover width and height
  1139.         return {
  1140.           w : p.offsetWidth,
  1141.           h : p.offsetHeight
  1142.         }
  1143.       },
  1144.       this.isElementInViewport = function(t) { // check if this.popover is in viewport
  1145.         var r = t.getBoundingClientRect();
  1146.         return (
  1147.           r.top >= 0 &&
  1148.           r.left >= 0 &&
  1149.           r.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
  1150.           r.right <= (window.innerWidth || document.documentElement.clientWidth)
  1151.         )
  1152.       }
  1153.     }
  1154.     }
  1155.  
  1156.   // POPOVER DATA API
  1157.   // =================
  1158.     var Popovers = document.querySelectorAll('[data-toggle=popover]'), i = 0, ppl = Popovers.length;
  1159.   for (i;i<ppl;i++){  
  1160.     var item = Popovers[i], options = {};
  1161.     options.trigger = item.getAttribute('data-trigger'); // click / hover / focus
  1162.     options.animation = item.getAttribute('data-animation'); // true / false
  1163.     options.duration = item.getAttribute('data-duration');
  1164.     options.placement = item.getAttribute('data-placement');
  1165.     options.dismiss = item.getAttribute('data-dismiss');
  1166.     options.delay = item.getAttribute('data-delay');
  1167.     new Popover(item,options);
  1168.   }
  1169.  
  1170.   return Popover;
  1171.  
  1172. });
  1173.  
  1174.  
  1175.  
  1176. // PROGRESS DEFINITION
  1177. // ===================
  1178. function Progress(el) {
  1179.     this.element = el;
  1180.     var self = this;
  1181.  
  1182.     this._bar = function() {
  1183.         return self.element.querySelector(".progress-bar");
  1184.     };
  1185.     this.value = function(value, text) {
  1186.         var bar = self._bar();
  1187.         if(value === undefined) {
  1188.             return parseInt(bar.getAttribute("aria-valuenow") || bar.style.slice(0, -1));
  1189.         } else {
  1190.             bar.setAttribute("aria-valuenow", value);
  1191.             bar.style.width = value + "%";
  1192.             if(text) {
  1193.                 bar.innerText = text;
  1194.             }
  1195.         }
  1196.     };
  1197.  
  1198.     this.on = function(par1, par2, par3) {
  1199.         this.element.addEventListener(par1, par2, par3);
  1200.     };
  1201. }
  1202.  
  1203. Progress.all = function(callback) {
  1204.     var elements = document.querySelectorAll('.progress');
  1205.     for(var i = 0; i < elements.length; i++) {
  1206.         callback(new Progress(elements[i]));
  1207.     }
  1208. };
  1209.  
  1210. // PROGRESS DATA API
  1211. // =================
  1212.  
  1213.  
  1214.  
  1215. // SCROLLSPY DEFINITION
  1216. // ===================
  1217. function ScrollSpy(el) {
  1218.     this.element = el;
  1219.     var self = this;
  1220.  
  1221.     this.init = function () {
  1222.         if(self.element.getAttribute("href") && self.element.getAttribute("href").indexOf("#") > -1 ) {
  1223.             this.refresh();
  1224.             this.scrollEvent();
  1225.             window.addEventListener("scroll", ScrollSpy.scrollHandler, false);
  1226.             window.addEventListener("resize", ScrollSpy.resizeHandler, false);
  1227.         }
  1228.     };
  1229.     this.topLimit = function () { // the target offset
  1230.       if ( this.scrollTarget === window ) {
  1231.         return this.tg.getBoundingClientRect().top + this.scrollOffset() - 5
  1232.       } else {
  1233.         return this.tg.offsetTop;
  1234.       }
  1235.     };
  1236.     this.bottomLimit = function () {
  1237.       return this.topLimit() + this.tg.clientHeight
  1238.     };
  1239.     this.scrollOffset = function () {
  1240.       if ( this.scrollTarget === window ) {
  1241.         return window.pageYOffset || document.documentElement.scrollTop
  1242.       } else {
  1243.         return this.element.scrollTop
  1244.       }
  1245.     };
  1246.     this.activate = function () {
  1247.       if ( this.parent && this.parent.tagName === 'LI' && !/active/.test(this.parent.className) ) {
  1248.         this.parent.addClass('active');
  1249.         if ( this.parentParent && this.parentParent.tagName === 'LI' // activate the dropdown as well
  1250.           && /dropdown/.test(this.parentParent.className)
  1251.           && !/active/.test(this.parentParent.className) ) {this.parentParent.addClass("active"); }
  1252.         this.active = true
  1253.       }
  1254.     };
  1255.     this.deactivate = function () {
  1256.       if ( this.parent && this.parent.tagName === 'LI' && /active/.test(this.parent.className) ) {
  1257.         this.parent.removeClass("active");
  1258.         if ( this.parentParent && this.parentParent.tagName === 'LI' // deactivate the dropdown as well
  1259.           && /dropdown/.test(this.parentParent.className)
  1260.           && /active/.test(this.parentParent.className) ) { this.parentParent.removeClass("active"); }
  1261.         this.active = false
  1262.       }
  1263.     };
  1264.     this.toggle = function () {
  1265.       if ( this.active === false
  1266.         && ( this.this.bottomLimit() > this.scrollOffset() && this.scrollOffset() >= this.topLimit() )) { //regular use, scroll just entered the element's topLimit or bottomLimit
  1267.           this.activate();
  1268.       } else if (this.active === true && (this.bottomLimit() <= this.scrollOffset() && this.scrollOffset() < this.topEdge )) {
  1269.         this.deactivate()
  1270.       }
  1271.     };
  1272.     this.refresh = function () { // check edges again
  1273.       this.deactivate();
  1274.       this.toggle() // If any case update values again
  1275.     };
  1276.     this.scollEvent = function(){
  1277.       var self = this;
  1278.       this.scrollTarget.addEventListener('scroll', onSpyScroll, false);
  1279.       function onSpyScroll() {
  1280.         self.refresh();
  1281.       }
  1282.     };
  1283.     this.resizeEvent = function(){
  1284.       var self = this;
  1285.       window.addEventListener('resize', onSpyResize, false);
  1286.       function onSpyResize() {
  1287.         self.refresh()
  1288.       }
  1289.     };
  1290.     this.scrollHeight = function() {
  1291.       if ( this.scrollTarget === window ) {
  1292.         return Math.max( document.body.scrollHeight, document.body.offsetHeight,
  1293.           document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight );
  1294.       } else {
  1295.         return this.element.scrollHeight
  1296.       }
  1297.     };
  1298.  
  1299.     this.on = function(par1, par2, par3) {
  1300.         this.element.addEventListener(par1, par2, par3);
  1301.     }
  1302. }
  1303.  
  1304. ScrollSpy.all = function(callback) {
  1305.     var elements = document.querySelectorAll('[data-spy="scroll"]');
  1306.     for(var i = 0; i < elements.length; i++) {
  1307.         callback(new Alert(elements[i]));
  1308.     }
  1309. };
  1310.  
  1311. // SCROLLSPY DATA API
  1312. // =================
  1313. ScrollSpy.scrollHandler = function() {
  1314.     ScrollSypy.all(function(spy) {
  1315.         spy.refresh();
  1316.     });
  1317. };
  1318. ScrollSpy.resizeHandler = function() {
  1319.     ScrollSypy.all(function(spy) {
  1320.         spy.refresh();
  1321.     });
  1322. };
  1323.  
  1324.  
  1325.  
  1326. // TAB DEFINITION
  1327. // ===================
  1328. function Tab(el) {
  1329.     this.element = el;
  1330.     var self = this;
  1331.  
  1332.     this.action = function() {
  1333.         var tabs = self.element.parentNode.parentNode;
  1334.         var event = new CustomEvent("show.bs.tab", { "cancelable": true });
  1335.         self.element.parentNode.dispatchEvent(event);
  1336.         if(!event.defaultPrevented) {
  1337.             var activeTab = self.getActiveTab();
  1338.             event = new CustomEvent("hide.bs.tab");
  1339.             var newContent = document.getElementById(self.element.getAttribute("href").replace("#", ""));
  1340.             var activeContent = self.getActiveContent();
  1341.             var duration = self.element.getAttribute("data-duration") || 150;
  1342.             var dropdown;
  1343.             if(self.element.parentNode.parentNode.hasClass("dropdown-menu")) {
  1344.                 tabs = tabs.parentNode.parentNode;
  1345.                 dropdown = tabs.parentNode;
  1346.             } else {
  1347.                 dropdown = tabs.querySelector(".dropdown");
  1348.             }
  1349.             if(!self.element.parentNode.hasClass("active")) {
  1350.                 activeTab.removeClass("active");
  1351.                 self.element.parentNode.addClass("active");
  1352.                 if(dropdown) {
  1353.                     if(!self.element.parentNode.parentNode.hasClass("dropdown-menu")) {
  1354.                         dropdown.removeClass("active");
  1355.                     } else {
  1356.                         dropdown.addClass("active");
  1357.                     }
  1358.                 }
  1359.                 activeContent.removeClass("in");
  1360.                 setTimeout(function() {
  1361.                     activeContent.removeClass("active");
  1362.                     newContent.addClass("active");
  1363.                     event = new CustomEvent("hidden.bs.tab");
  1364.                     activeTab.dispatchEvent(event);
  1365.                 }, duration);
  1366.                 setTimeout(function() {
  1367.                     newContent.addClass("in");
  1368.                     event = new CustomEvent("shown.bs.tab");
  1369.                     self.element.parentNode.dispatchEvent(event);
  1370.                 }, duration * 2);
  1371.             }
  1372.         }
  1373.     };
  1374.     this.getActiveTab = function(tabs) {
  1375.         if(!tabs) {
  1376.             tabs = self.element.parentNode.parentNode;
  1377.             if(self.element.parentNode.parentNode.hasClass("dropdown-menu")) {
  1378.                 tabs = tabs.parentNode.parentNode;
  1379.             }
  1380.         }
  1381.         var activeTabs = tabs.querySelectorAll(".active");
  1382.         if(activeTabs.length === 1 && !activeTabs[0].hasClass("dropdown")) {
  1383.             return activeTabs[0];
  1384.         } else if ( activeTabs.length > 1 ) {
  1385.             return activeTabs[activeTabs.length-1]
  1386.         }
  1387.     };
  1388.     this.getActiveContent = function() {
  1389.         var a = self.getActiveTab().getElementsByTagName("A")[0].getAttribute("href").replace("#", "");
  1390.         return a && document.getElementById(a)
  1391.     };
  1392.  
  1393.     this.on = function(par1, par2, par3) {
  1394.         this.element.addEventListener(par1, par2, par3);
  1395.     };
  1396. }
  1397.  
  1398. Tab.all = function(callback) {
  1399.     var elements = document.querySelectorAll('[data-toggle="tab"],[data-toggle="pill"]');
  1400.     for(var i = 0; i < elements.length; i++) {
  1401.         callback(new Tab(elements[i]));
  1402.     }
  1403. };
  1404.  
  1405. // TAB DATA API
  1406. // =================
  1407. document.on("click", "[data-toggle='tab'], [data-toggle='pill']", function(e) {
  1408.     new Tab(this).action();
  1409.     e.preventDefault();
  1410. });
  1411.  
  1412. window.addEventListener("load", function() {
  1413.     Carousel.all(function(carousel) {
  1414.         carousel.init();
  1415.     });
  1416.     Affix.all(function(affix) {
  1417.         affix.init();
  1418.     });
  1419.     /*Scrollspy.all(function(scrollspy) {
  1420.         scrollspy.init();
  1421.     });*/
  1422. }, false);
Advertisement
Add Comment
Please, Sign In to add comment