Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
/**
2
 * --------------------------------------------------------------------------
3
 * Bootstrap (v4.6.2): tab.js
4
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5
 * --------------------------------------------------------------------------
6
 */
7
 
8
import $ from 'jquery'
9
import Util from './util'
10
 
11
/**
12
 * Constants
13
 */
14
 
15
const NAME = 'tab'
16
const VERSION = '4.6.2'
17
const DATA_KEY = 'bs.tab'
18
const EVENT_KEY = `.${DATA_KEY}`
19
const DATA_API_KEY = '.data-api'
20
const JQUERY_NO_CONFLICT = $.fn[NAME]
21
 
22
const CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu'
23
const CLASS_NAME_ACTIVE = 'active'
24
const CLASS_NAME_DISABLED = 'disabled'
25
const CLASS_NAME_FADE = 'fade'
26
const CLASS_NAME_SHOW = 'show'
27
 
28
const EVENT_HIDE = `hide${EVENT_KEY}`
29
const EVENT_HIDDEN = `hidden${EVENT_KEY}`
30
const EVENT_SHOW = `show${EVENT_KEY}`
31
const EVENT_SHOWN = `shown${EVENT_KEY}`
32
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
33
 
34
const SELECTOR_DROPDOWN = '.dropdown'
35
const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'
36
const SELECTOR_ACTIVE = '.active'
37
const SELECTOR_ACTIVE_UL = '> li > .active'
38
const SELECTOR_DATA_TOGGLE = '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]'
39
const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'
40
const SELECTOR_DROPDOWN_ACTIVE_CHILD = '> .dropdown-menu .active'
41
 
42
/**
43
 * Class definition
44
 */
45
 
46
class Tab {
47
  constructor(element) {
48
    this._element = element
49
  }
50
 
51
  // Getters
52
  static get VERSION() {
53
    return VERSION
54
  }
55
 
56
  // Public
57
  show() {
58
    if (this._element.parentNode &&
59
        this._element.parentNode.nodeType === Node.ELEMENT_NODE &&
60
        $(this._element).hasClass(CLASS_NAME_ACTIVE) ||
61
        $(this._element).hasClass(CLASS_NAME_DISABLED) ||
62
        this._element.hasAttribute('disabled')) {
63
      return
64
    }
65
 
66
    let target
67
    let previous
68
    const listElement = $(this._element).closest(SELECTOR_NAV_LIST_GROUP)[0]
69
    const selector = Util.getSelectorFromElement(this._element)
70
 
71
    if (listElement) {
72
      const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE
73
      previous = $.makeArray($(listElement).find(itemSelector))
74
      previous = previous[previous.length - 1]
75
    }
76
 
77
    const hideEvent = $.Event(EVENT_HIDE, {
78
      relatedTarget: this._element
79
    })
80
 
81
    const showEvent = $.Event(EVENT_SHOW, {
82
      relatedTarget: previous
83
    })
84
 
85
    if (previous) {
86
      $(previous).trigger(hideEvent)
87
    }
88
 
89
    $(this._element).trigger(showEvent)
90
 
91
    if (showEvent.isDefaultPrevented() ||
92
        hideEvent.isDefaultPrevented()) {
93
      return
94
    }
95
 
96
    if (selector) {
97
      target = document.querySelector(selector)
98
    }
99
 
100
    this._activate(
101
      this._element,
102
      listElement
103
    )
104
 
105
    const complete = () => {
106
      const hiddenEvent = $.Event(EVENT_HIDDEN, {
107
        relatedTarget: this._element
108
      })
109
 
110
      const shownEvent = $.Event(EVENT_SHOWN, {
111
        relatedTarget: previous
112
      })
113
 
114
      $(previous).trigger(hiddenEvent)
115
      $(this._element).trigger(shownEvent)
116
    }
117
 
118
    if (target) {
119
      this._activate(target, target.parentNode, complete)
120
    } else {
121
      complete()
122
    }
123
  }
124
 
125
  dispose() {
126
    $.removeData(this._element, DATA_KEY)
127
    this._element = null
128
  }
129
 
130
  // Private
131
  _activate(element, container, callback) {
132
    const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ?
133
      $(container).find(SELECTOR_ACTIVE_UL) :
134
      $(container).children(SELECTOR_ACTIVE)
135
 
136
    const active = activeElements[0]
137
    const isTransitioning = callback && (active && $(active).hasClass(CLASS_NAME_FADE))
138
    const complete = () => this._transitionComplete(
139
      element,
140
      active,
141
      callback
142
    )
143
 
144
    if (active && isTransitioning) {
145
      const transitionDuration = Util.getTransitionDurationFromElement(active)
146
 
147
      $(active)
148
        .removeClass(CLASS_NAME_SHOW)
149
        .one(Util.TRANSITION_END, complete)
150
        .emulateTransitionEnd(transitionDuration)
151
    } else {
152
      complete()
153
    }
154
  }
155
 
156
  _transitionComplete(element, active, callback) {
157
    if (active) {
158
      $(active).removeClass(CLASS_NAME_ACTIVE)
159
 
160
      const dropdownChild = $(active.parentNode).find(
161
        SELECTOR_DROPDOWN_ACTIVE_CHILD
162
      )[0]
163
 
164
      if (dropdownChild) {
165
        $(dropdownChild).removeClass(CLASS_NAME_ACTIVE)
166
      }
167
 
168
      if (active.getAttribute('role') === 'tab') {
169
        active.setAttribute('aria-selected', false)
170
      }
171
    }
172
 
173
    $(element).addClass(CLASS_NAME_ACTIVE)
174
    if (element.getAttribute('role') === 'tab') {
175
      element.setAttribute('aria-selected', true)
176
    }
177
 
178
    Util.reflow(element)
179
 
180
    if (element.classList.contains(CLASS_NAME_FADE)) {
181
      element.classList.add(CLASS_NAME_SHOW)
182
    }
183
 
184
    let parent = element.parentNode
185
    if (parent && parent.nodeName === 'LI') {
186
      parent = parent.parentNode
187
    }
188
 
189
    if (parent && $(parent).hasClass(CLASS_NAME_DROPDOWN_MENU)) {
190
      const dropdownElement = $(element).closest(SELECTOR_DROPDOWN)[0]
191
 
192
      if (dropdownElement) {
193
        const dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(SELECTOR_DROPDOWN_TOGGLE))
194
 
195
        $(dropdownToggleList).addClass(CLASS_NAME_ACTIVE)
196
      }
197
 
198
      element.setAttribute('aria-expanded', true)
199
    }
200
 
201
    if (callback) {
202
      callback()
203
    }
204
  }
205
 
206
  // Static
207
  static _jQueryInterface(config) {
208
    return this.each(function () {
209
      const $this = $(this)
210
      let data = $this.data(DATA_KEY)
211
 
212
      if (!data) {
213
        data = new Tab(this)
214
        $this.data(DATA_KEY, data)
215
      }
216
 
217
      if (typeof config === 'string') {
218
        if (typeof data[config] === 'undefined') {
219
          throw new TypeError(`No method named "${config}"`)
220
        }
221
 
222
        data[config]()
223
      }
224
    })
225
  }
226
}
227
 
228
/**
229
 * Data API implementation
230
 */
231
 
232
$(document)
233
  .on(EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
234
    event.preventDefault()
235
    Tab._jQueryInterface.call($(this), 'show')
236
  })
237
 
238
/**
239
 * jQuery
240
 */
241
 
242
$.fn[NAME] = Tab._jQueryInterface
243
$.fn[NAME].Constructor = Tab
244
$.fn[NAME].noConflict = () => {
245
  $.fn[NAME] = JQUERY_NO_CONFLICT
246
  return Tab._jQueryInterface
247
}
248
 
249
export default Tab