Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
collapse.js381 linesDownload Raw Back to src
1/**2 * --------------------------------------------------------------------------3 * Bootstrap (v4.6.2): collapse.js4 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)5 * --------------------------------------------------------------------------6 */7 8import $ from 'jquery'9import Util from './util'10 11/**12 * Constants13 */14 15const NAME = 'collapse'16const VERSION = '4.6.2'17const DATA_KEY = 'bs.collapse'18const EVENT_KEY = `.${DATA_KEY}`19const DATA_API_KEY = '.data-api'20const JQUERY_NO_CONFLICT = $.fn[NAME]21 22const CLASS_NAME_SHOW = 'show'23const CLASS_NAME_COLLAPSE = 'collapse'24const CLASS_NAME_COLLAPSING = 'collapsing'25const CLASS_NAME_COLLAPSED = 'collapsed'26 27const DIMENSION_WIDTH = 'width'28const DIMENSION_HEIGHT = 'height'29 30const EVENT_SHOW = `show${EVENT_KEY}`31const EVENT_SHOWN = `shown${EVENT_KEY}`32const EVENT_HIDE = `hide${EVENT_KEY}`33const EVENT_HIDDEN = `hidden${EVENT_KEY}`34const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`35 36const SELECTOR_ACTIVES = '.show, .collapsing'37const SELECTOR_DATA_TOGGLE = '[data-toggle="collapse"]'38 39const Default = {40  toggle: true,41  parent: ''42}43 44const DefaultType = {45  toggle: 'boolean',46  parent: '(string|element)'47}48 49/**50 * Class definition51 */52 53class Collapse {54  constructor(element, config) {55    this._isTransitioning = false56    this._element = element57    this._config = this._getConfig(config)58    this._triggerArray = [].slice.call(document.querySelectorAll(59      `[data-toggle="collapse"][href="#${element.id}"],` +60      `[data-toggle="collapse"][data-target="#${element.id}"]`61    ))62 63    const toggleList = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE))64    for (let i = 0, len = toggleList.length; i < len; i++) {65      const elem = toggleList[i]66      const selector = Util.getSelectorFromElement(elem)67      const filterElement = [].slice.call(document.querySelectorAll(selector))68        .filter(foundElem => foundElem === element)69 70      if (selector !== null && filterElement.length > 0) {71        this._selector = selector72        this._triggerArray.push(elem)73      }74    }75 76    this._parent = this._config.parent ? this._getParent() : null77 78    if (!this._config.parent) {79      this._addAriaAndCollapsedClass(this._element, this._triggerArray)80    }81 82    if (this._config.toggle) {83      this.toggle()84    }85  }86 87  // Getters88  static get VERSION() {89    return VERSION90  }91 92  static get Default() {93    return Default94  }95 96  // Public97  toggle() {98    if ($(this._element).hasClass(CLASS_NAME_SHOW)) {99      this.hide()100    } else {101      this.show()102    }103  }104 105  show() {106    if (this._isTransitioning ||107      $(this._element).hasClass(CLASS_NAME_SHOW)) {108      return109    }110 111    let actives112    let activesData113 114    if (this._parent) {115      actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES))116        .filter(elem => {117          if (typeof this._config.parent === 'string') {118            return elem.getAttribute('data-parent') === this._config.parent119          }120 121          return elem.classList.contains(CLASS_NAME_COLLAPSE)122        })123 124      if (actives.length === 0) {125        actives = null126      }127    }128 129    if (actives) {130      activesData = $(actives).not(this._selector).data(DATA_KEY)131      if (activesData && activesData._isTransitioning) {132        return133      }134    }135 136    const startEvent = $.Event(EVENT_SHOW)137    $(this._element).trigger(startEvent)138    if (startEvent.isDefaultPrevented()) {139      return140    }141 142    if (actives) {143      Collapse._jQueryInterface.call($(actives).not(this._selector), 'hide')144      if (!activesData) {145        $(actives).data(DATA_KEY, null)146      }147    }148 149    const dimension = this._getDimension()150 151    $(this._element)152      .removeClass(CLASS_NAME_COLLAPSE)153      .addClass(CLASS_NAME_COLLAPSING)154 155    this._element.style[dimension] = 0156 157    if (this._triggerArray.length) {158      $(this._triggerArray)159        .removeClass(CLASS_NAME_COLLAPSED)160        .attr('aria-expanded', true)161    }162 163    this.setTransitioning(true)164 165    const complete = () => {166      $(this._element)167        .removeClass(CLASS_NAME_COLLAPSING)168        .addClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)169 170      this._element.style[dimension] = ''171 172      this.setTransitioning(false)173 174      $(this._element).trigger(EVENT_SHOWN)175    }176 177    const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1)178    const scrollSize = `scroll${capitalizedDimension}`179    const transitionDuration = Util.getTransitionDurationFromElement(this._element)180 181    $(this._element)182      .one(Util.TRANSITION_END, complete)183      .emulateTransitionEnd(transitionDuration)184 185    this._element.style[dimension] = `${this._element[scrollSize]}px`186  }187 188  hide() {189    if (this._isTransitioning ||190      !$(this._element).hasClass(CLASS_NAME_SHOW)) {191      return192    }193 194    const startEvent = $.Event(EVENT_HIDE)195    $(this._element).trigger(startEvent)196    if (startEvent.isDefaultPrevented()) {197      return198    }199 200    const dimension = this._getDimension()201 202    this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`203 204    Util.reflow(this._element)205 206    $(this._element)207      .addClass(CLASS_NAME_COLLAPSING)208      .removeClass(`${CLASS_NAME_COLLAPSE} ${CLASS_NAME_SHOW}`)209 210    const triggerArrayLength = this._triggerArray.length211    if (triggerArrayLength > 0) {212      for (let i = 0; i < triggerArrayLength; i++) {213        const trigger = this._triggerArray[i]214        const selector = Util.getSelectorFromElement(trigger)215 216        if (selector !== null) {217          const $elem = $([].slice.call(document.querySelectorAll(selector)))218          if (!$elem.hasClass(CLASS_NAME_SHOW)) {219            $(trigger).addClass(CLASS_NAME_COLLAPSED)220              .attr('aria-expanded', false)221          }222        }223      }224    }225 226    this.setTransitioning(true)227 228    const complete = () => {229      this.setTransitioning(false)230      $(this._element)231        .removeClass(CLASS_NAME_COLLAPSING)232        .addClass(CLASS_NAME_COLLAPSE)233        .trigger(EVENT_HIDDEN)234    }235 236    this._element.style[dimension] = ''237    const transitionDuration = Util.getTransitionDurationFromElement(this._element)238 239    $(this._element)240      .one(Util.TRANSITION_END, complete)241      .emulateTransitionEnd(transitionDuration)242  }243 244  setTransitioning(isTransitioning) {245    this._isTransitioning = isTransitioning246  }247 248  dispose() {249    $.removeData(this._element, DATA_KEY)250 251    this._config = null252    this._parent = null253    this._element = null254    this._triggerArray = null255    this._isTransitioning = null256  }257 258  // Private259  _getConfig(config) {260    config = {261      ...Default,262      ...config263    }264    config.toggle = Boolean(config.toggle) // Coerce string values265    Util.typeCheckConfig(NAME, config, DefaultType)266    return config267  }268 269  _getDimension() {270    const hasWidth = $(this._element).hasClass(DIMENSION_WIDTH)271    return hasWidth ? DIMENSION_WIDTH : DIMENSION_HEIGHT272  }273 274  _getParent() {275    let parent276 277    if (Util.isElement(this._config.parent)) {278      parent = this._config.parent279 280      // It's a jQuery object281      if (typeof this._config.parent.jquery !== 'undefined') {282        parent = this._config.parent[0]283      }284    } else {285      parent = document.querySelector(this._config.parent)286    }287 288    const selector = `[data-toggle="collapse"][data-parent="${this._config.parent}"]`289    const children = [].slice.call(parent.querySelectorAll(selector))290 291    $(children).each((i, element) => {292      this._addAriaAndCollapsedClass(293        Collapse._getTargetFromElement(element),294        [element]295      )296    })297 298    return parent299  }300 301  _addAriaAndCollapsedClass(element, triggerArray) {302    const isOpen = $(element).hasClass(CLASS_NAME_SHOW)303 304    if (triggerArray.length) {305      $(triggerArray)306        .toggleClass(CLASS_NAME_COLLAPSED, !isOpen)307        .attr('aria-expanded', isOpen)308    }309  }310 311  // Static312  static _getTargetFromElement(element) {313    const selector = Util.getSelectorFromElement(element)314    return selector ? document.querySelector(selector) : null315  }316 317  static _jQueryInterface(config) {318    return this.each(function () {319      const $element = $(this)320      let data = $element.data(DATA_KEY)321      const _config = {322        ...Default,323        ...$element.data(),324        ...(typeof config === 'object' && config ? config : {})325      }326 327      if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {328        _config.toggle = false329      }330 331      if (!data) {332        data = new Collapse(this, _config)333        $element.data(DATA_KEY, data)334      }335 336      if (typeof config === 'string') {337        if (typeof data[config] === 'undefined') {338          throw new TypeError(`No method named "${config}"`)339        }340 341        data[config]()342      }343    })344  }345}346 347/**348 * Data API implementation349 */350 351$(document).on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {352  // preventDefault only for <a> elements (which change the URL) not inside the collapsible element353  if (event.currentTarget.tagName === 'A') {354    event.preventDefault()355  }356 357  const $trigger = $(this)358  const selector = Util.getSelectorFromElement(this)359  const selectors = [].slice.call(document.querySelectorAll(selector))360 361  $(selectors).each(function () {362    const $target = $(this)363    const data = $target.data(DATA_KEY)364    const config = data ? 'toggle' : $trigger.data()365    Collapse._jQueryInterface.call($target, config)366  })367})368 369/**370 * jQuery371 */372 373$.fn[NAME] = Collapse._jQueryInterface374$.fn[NAME].Constructor = Collapse375$.fn[NAME].noConflict = () => {376  $.fn[NAME] = JQUERY_NO_CONFLICT377  return Collapse._jQueryInterface378}379 380export default Collapse381