• XhmikosR's avatar
    Revert 4f9270cc. · cae7dee2
    XhmikosR authored
    The validator doesn't choke anymore on this and even though it's not spec compliant, it's needed for some IE versions. So until we move favicon.ico in root, this should do the job.
    cae7dee2
collapse.js 10.70 KiB
import $ from 'jquery'
import Util from './util'
/**
 * --------------------------------------------------------------------------
 * Bootstrap (v4.1.2): collapse.js
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * --------------------------------------------------------------------------
 */
const Collapse = (($) => {
  /**
   * ------------------------------------------------------------------------
   * Constants
   * ------------------------------------------------------------------------
  const NAME                = 'collapse'
  const VERSION             = '4.1.2'
  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}`,
    SHOWN          : `shown${EVENT_KEY}`,
    HIDE           : `hide${EVENT_KEY}`,
    HIDDEN         : `hidden${EVENT_KEY}`,
    CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`
  const ClassName = {
    SHOW       : 'show',
    COLLAPSE   : 'collapse',
    COLLAPSING : 'collapsing',
    COLLAPSED  : 'collapsed'
  const Dimension = {
    WIDTH  : 'width',
    HEIGHT : 'height'
  const Selector = {
    ACTIVES     : '.show, .collapsing',
    DATA_TOGGLE : '[data-toggle="collapse"]'
  /**
   * ------------------------------------------------------------------------
   * Class Definition
   * ------------------------------------------------------------------------
  class Collapse {
    constructor(element, config) {
      this._isTransitioning = false
      this._element         = element
      this._config          = this._getConfig(config)
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
this._triggerArray = $.makeArray(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(ClassName.SHOW)) { this.hide() } else { this.show() } } show() { if (this._isTransitioning || $(this._element).hasClass(ClassName.SHOW)) { return } let actives let activesData if (this._parent) { actives = [].slice.call(this._parent.querySelectorAll(Selector.ACTIVES)) .filter((elem) => elem.getAttribute('data-parent') === this._config.parent) if (actives.length === 0) { actives = null } } if (actives) { activesData = $(actives).not(this._selector).data(DATA_KEY) if (activesData && activesData._isTransitioning) { return
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
} } 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(ClassName.COLLAPSE) .addClass(ClassName.COLLAPSING) this._element.style[dimension] = 0 if (this._triggerArray.length) { $(this._triggerArray) .removeClass(ClassName.COLLAPSED) .attr('aria-expanded', true) } this.setTransitioning(true) const complete = () => { $(this._element) .removeClass(ClassName.COLLAPSING) .addClass(ClassName.COLLAPSE) .addClass(ClassName.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(ClassName.SHOW)) { return } const startEvent = $.Event(Event.HIDE) $(this._element).trigger(startEvent) if (startEvent.isDefaultPrevented()) { return } const dimension = this._getDimension()
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px` Util.reflow(this._element) $(this._element) .addClass(ClassName.COLLAPSING) .removeClass(ClassName.COLLAPSE) .removeClass(ClassName.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(ClassName.SHOW)) { $(trigger).addClass(ClassName.COLLAPSED) .attr('aria-expanded', false) } } } } this.setTransitioning(true) const complete = () => { this.setTransitioning(false) $(this._element) .removeClass(ClassName.COLLAPSING) .addClass(ClassName.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)
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT } _getParent() { let parent = null 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) { if (element) { const isOpen = $(element).hasClass(ClassName.SHOW) if (triggerArray.length) { $(triggerArray) .toggleClass(ClassName.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 $this = $(this) let data = $this.data(DATA_KEY) const _config = { ...Default, ...$this.data(), ...typeof config === 'object' && config ? config : {} } if (!data && _config.toggle && /show|hide/.test(config)) { _config.toggle = false } if (!data) { data = new Collapse(this, _config) $this.data(DATA_KEY, data) } if (typeof config === 'string') { if (typeof data[config] === 'undefined') {
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
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 = function () { $.fn[NAME] = JQUERY_NO_CONFLICT return Collapse._jQueryInterface } return Collapse })($) export default Collapse