Proyectos de Subversion Moodle

Rev

Rev 1 | Mostrar el archivo completo | | | Autoría | Ultima modificación | Ver Log |

Rev 1 Rev 1441
Línea 1... Línea 1...
1
/**
1
/**
2
 * --------------------------------------------------------------------------
2
 * --------------------------------------------------------------------------
3
 * Bootstrap (v4.6.2): modal.js
3
 * Bootstrap modal.js
4
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5
 * --------------------------------------------------------------------------
5
 * --------------------------------------------------------------------------
6
 */
6
 */
Línea -... Línea 7...
-
 
7
 
-
 
8
import BaseComponent from './base-component'
-
 
9
import EventHandler from './dom/event-handler'
7
 
10
import SelectorEngine from './dom/selector-engine'
-
 
11
import Backdrop from './util/backdrop'
8
import $ from 'jquery'
12
import { enableDismissTrigger } from './util/component-functions'
-
 
13
import FocusTrap from './util/focustrap'
-
 
14
import {
-
 
15
  defineJQueryPlugin, isRTL, isVisible, reflow
-
 
16
} from './util/index'
Línea 9... Línea 17...
9
import Util from './util'
17
import ScrollBarHelper from './util/scrollbar'
10
 
18
 
11
/**
19
/**
Línea 12... Línea 20...
12
 * Constants
20
 * Constants
13
 */
-
 
14
 
21
 */
15
const NAME = 'modal'
22
 
16
const VERSION = '4.6.2'
23
const NAME = 'modal'
17
const DATA_KEY = 'bs.modal'
-
 
18
const EVENT_KEY = `.${DATA_KEY}`
-
 
19
const DATA_API_KEY = '.data-api'
-
 
20
const JQUERY_NO_CONFLICT = $.fn[NAME]
-
 
21
const ESCAPE_KEYCODE = 27 // KeyboardEvent.which value for Escape (Esc) key
-
 
22
 
-
 
23
const CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable'
-
 
24
const CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure'
24
const DATA_KEY = 'bs.modal'
25
const CLASS_NAME_BACKDROP = 'modal-backdrop'
-
 
26
const CLASS_NAME_OPEN = 'modal-open'
-
 
Línea 27... Línea 25...
27
const CLASS_NAME_FADE = 'fade'
25
const EVENT_KEY = `.${DATA_KEY}`
28
const CLASS_NAME_SHOW = 'show'
26
const DATA_API_KEY = '.data-api'
29
const CLASS_NAME_STATIC = 'modal-static'
27
const ESCAPE_KEY = 'Escape'
30
 
28
 
31
const EVENT_HIDE = `hide${EVENT_KEY}`
29
const EVENT_HIDE = `hide${EVENT_KEY}`
32
const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`
-
 
33
const EVENT_HIDDEN = `hidden${EVENT_KEY}`
30
const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`
34
const EVENT_SHOW = `show${EVENT_KEY}`
31
const EVENT_HIDDEN = `hidden${EVENT_KEY}`
35
const EVENT_SHOWN = `shown${EVENT_KEY}`
-
 
36
const EVENT_FOCUSIN = `focusin${EVENT_KEY}`
-
 
37
const EVENT_RESIZE = `resize${EVENT_KEY}`
32
const EVENT_SHOW = `show${EVENT_KEY}`
-
 
33
const EVENT_SHOWN = `shown${EVENT_KEY}`
38
const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`
34
const EVENT_RESIZE = `resize${EVENT_KEY}`
Línea -... Línea 35...
-
 
35
const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`
-
 
36
const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`
-
 
37
const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`
-
 
38
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
-
 
39
 
-
 
40
const CLASS_NAME_OPEN = 'modal-open'
39
const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`
41
const CLASS_NAME_FADE = 'fade'
40
const EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY}`
42
const CLASS_NAME_SHOW = 'show'
41
const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY}`
43
const CLASS_NAME_STATIC = 'modal-static'
42
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
-
 
43
 
-
 
44
const SELECTOR_DIALOG = '.modal-dialog'
-
 
Línea 45... Línea 44...
45
const SELECTOR_MODAL_BODY = '.modal-body'
44
 
46
const SELECTOR_DATA_TOGGLE = '[data-toggle="modal"]'
45
const OPEN_SELECTOR = '.modal.show'
47
const SELECTOR_DATA_DISMISS = '[data-dismiss="modal"]'
-
 
48
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'
46
const SELECTOR_DIALOG = '.modal-dialog'
49
const SELECTOR_STICKY_CONTENT = '.sticky-top'
47
const SELECTOR_MODAL_BODY = '.modal-body'
50
 
48
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="modal"]'
Línea 51... Línea 49...
51
const Default = {
49
 
52
  backdrop: true,
50
const Default = {
53
  keyboard: true,
-
 
54
  focus: true,
51
  backdrop: true,
55
  show: true
52
  focus: true,
56
}
53
  keyboard: true
Línea 57... Línea 54...
57
 
54
}
58
const DefaultType = {
55
 
59
  backdrop: '(boolean|string)',
56
const DefaultType = {
Línea 60... Línea 57...
60
  keyboard: 'boolean',
57
  backdrop: '(boolean|string)',
61
  focus: 'boolean',
58
  focus: 'boolean',
62
  show: 'boolean'
-
 
63
}
59
  keyboard: 'boolean'
-
 
60
}
64
 
61
 
65
/**
62
/**
-
 
63
 * Class definition
66
 * Class definition
64
 */
67
 */
-
 
68
 
-
 
69
class Modal {
65
 
70
  constructor(element, config) {
66
class Modal extends BaseComponent {
71
    this._config = this._getConfig(config)
-
 
Línea 72... Línea -...
72
    this._element = element
-
 
73
    this._dialog = element.querySelector(SELECTOR_DIALOG)
67
  constructor(element, config) {
74
    this._backdrop = null
-
 
75
    this._isShown = false
68
    super(element, config)
Línea -... Línea 69...
-
 
69
 
76
    this._isBodyOverflowing = false
70
    this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element)
77
    this._ignoreBackdropClick = false
71
    this._backdrop = this._initializeBackDrop()
78
    this._isTransitioning = false
72
    this._focustrap = this._initializeFocusTrap()
Línea -... Línea 73...
-
 
73
    this._isShown = false
-
 
74
    this._isTransitioning = false
-
 
75
    this._scrollBar = new ScrollBarHelper()
-
 
76
 
-
 
77
    this._addEventListeners()
-
 
78
  }
-
 
79
 
-
 
80
  // Getters
79
    this._scrollbarWidth = 0
81
  static get Default() {
80
  }
82
    return Default
81
 
83
  }
82
  // Getters
84
 
Línea 83... Línea 85...
83
  static get VERSION() {
85
  static get DefaultType() {
84
    return VERSION
86
    return DefaultType
85
  }
87
  }
86
 
88
 
Línea 87... Línea 89...
87
  static get Default() {
89
  static get NAME() {
88
    return Default
90
    return NAME
89
  }
91
  }
Línea 90... Línea -...
90
 
-
 
91
  // Public
-
 
92
  toggle(relatedTarget) {
92
 
93
    return this._isShown ? this.hide() : this.show(relatedTarget)
93
  // Public
94
  }
94
  toggle(relatedTarget) {
Línea 95... Línea 95...
95
 
95
    return this._isShown ? this.hide() : this.show(relatedTarget)
-
 
96
  }
Línea 96... Línea -...
96
  show(relatedTarget) {
-
 
97
    if (this._isShown || this._isTransitioning) {
97
 
98
      return
-
 
Línea 99... Línea 98...
99
    }
98
  show(relatedTarget) {
100
 
-
 
Línea 101... Línea 99...
101
    const showEvent = $.Event(EVENT_SHOW, {
99
    if (this._isShown || this._isTransitioning) {
Línea 102... Línea -...
102
      relatedTarget
-
 
103
    })
-
 
104
 
-
 
105
    $(this._element).trigger(showEvent)
-
 
106
 
-
 
107
    if (showEvent.isDefaultPrevented()) {
-
 
108
      return
-
 
109
    }
-
 
110
 
-
 
111
    this._isShown = true
-
 
112
 
-
 
113
    if ($(this._element).hasClass(CLASS_NAME_FADE)) {
-
 
114
      this._isTransitioning = true
-
 
115
    }
-
 
116
 
-
 
117
    this._checkScrollbar()
-
 
118
    this._setScrollbar()
-
 
119
 
100
      return
120
    this._adjustDialog()
101
    }
Línea 121... Línea 102...
121
 
102
 
122
    this._setEscapeEvent()
-
 
123
    this._setResizeEvent()
-
 
124
 
-
 
125
    $(this._element).on(
-
 
126
      EVENT_CLICK_DISMISS,
103
    const showEvent = EventHandler.trigger(this._element, EVENT_SHOW, {
127
      SELECTOR_DATA_DISMISS,
104
      relatedTarget
128
      event => this.hide(event)
105
    })
Línea 129... Línea 106...
129
    )
106
 
Línea 130... Línea -...
130
 
-
 
131
    $(this._dialog).on(EVENT_MOUSEDOWN_DISMISS, () => {
-
 
132
      $(this._element).one(EVENT_MOUSEUP_DISMISS, event => {
107
    if (showEvent.defaultPrevented) {
133
        if ($(event.target).is(this._element)) {
108
      return
134
          this._ignoreBackdropClick = true
109
    }
Línea 135... Línea 110...
135
        }
110
 
136
      })
-
 
137
    })
-
 
138
 
-
 
139
    this._showBackdrop(() => this._showElement(relatedTarget))
111
    this._isShown = true
140
  }
-
 
141
 
-
 
142
  hide(event) {
112
    this._isTransitioning = true
143
    if (event) {
-
 
144
      event.preventDefault()
-
 
145
    }
-
 
146
 
-
 
147
    if (!this._isShown || this._isTransitioning) {
-
 
148
      return
-
 
149
    }
-
 
150
 
-
 
Línea 151... Línea -...
151
    const hideEvent = $.Event(EVENT_HIDE)
-
 
152
 
113
 
Línea 153... Línea -...
153
    $(this._element).trigger(hideEvent)
-
 
154
 
114
    this._scrollBar.hide()
155
    if (!this._isShown || hideEvent.isDefaultPrevented()) {
-
 
156
      return
-
 
157
    }
-
 
158
 
-
 
159
    this._isShown = false
115
 
Línea 160... Línea 116...
160
    const transition = $(this._element).hasClass(CLASS_NAME_FADE)
116
    document.body.classList.add(CLASS_NAME_OPEN)
161
 
117
 
162
    if (transition) {
118
    this._adjustDialog()
-
 
119
 
-
 
120
    this._backdrop.show(() => this._showElement(relatedTarget))
-
 
121
  }
Línea 163... Línea -...
163
      this._isTransitioning = true
-
 
164
    }
-
 
165
 
-
 
166
    this._setEscapeEvent()
-
 
167
    this._setResizeEvent()
-
 
168
 
-
 
169
    $(document).off(EVENT_FOCUSIN)
-
 
170
 
-
 
171
    $(this._element).removeClass(CLASS_NAME_SHOW)
-
 
172
 
-
 
173
    $(this._element).off(EVENT_CLICK_DISMISS)
-
 
174
    $(this._dialog).off(EVENT_MOUSEDOWN_DISMISS)
122
 
175
 
-
 
176
    if (transition) {
-
 
177
      const transitionDuration = Util.getTransitionDurationFromElement(this._element)
-
 
178
 
-
 
179
      $(this._element)
-
 
180
        .one(Util.TRANSITION_END, event => this._hideModal(event))
-
 
181
        .emulateTransitionEnd(transitionDuration)
123
  hide() {
Línea 182... Línea 124...
182
    } else {
124
    if (!this._isShown || this._isTransitioning) {
183
      this._hideModal()
125
      return
184
    }
126
    }
Línea 185... Línea 127...
185
  }
127
 
186
 
128
    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE)
187
  dispose() {
129
 
188
    [window, this._element, this._dialog]
130
    if (hideEvent.defaultPrevented) {
189
      .forEach(htmlElement => $(htmlElement).off(EVENT_KEY))
131
      return
190
 
132
    }
191
    /**
-
 
192
     * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`
-
 
193
     * Do not move `document` in `htmlElements` array
133
 
Línea 194... Línea 134...
194
     * It will remove `EVENT_CLICK_DATA_API` event that should remain
134
    this._isShown = false
195
     */
-
 
196
    $(document).off(EVENT_FOCUSIN)
-
 
197
 
-
 
198
    $.removeData(this._element, DATA_KEY)
-
 
199
 
-
 
200
    this._config = null
-
 
201
    this._element = null
-
 
202
    this._dialog = null
-
 
203
    this._backdrop = null
-
 
204
    this._isShown = null
135
    this._isTransitioning = true
205
    this._isBodyOverflowing = null
136
    this._focustrap.deactivate()
206
    this._ignoreBackdropClick = null
-
 
207
    this._isTransitioning = null
-
 
208
    this._scrollbarWidth = null
-
 
209
  }
-
 
210
 
-
 
211
  handleUpdate() {
-
 
212
    this._adjustDialog()
-
 
213
  }
-
 
214
 
-
 
215
  // Private
-
 
216
  _getConfig(config) {
-
 
217
    config = {
-
 
218
      ...Default,
-
 
219
      ...config
-
 
220
    }
-
 
221
    Util.typeCheckConfig(NAME, config, DefaultType)
137
 
222
    return config
-
 
223
  }
-
 
224
 
138
    this._element.classList.remove(CLASS_NAME_SHOW)
Línea 225... Línea 139...
225
  _triggerBackdropTransition() {
139
 
226
    const hideEventPrevented = $.Event(EVENT_HIDE_PREVENTED)
-
 
227
 
-
 
228
    $(this._element).trigger(hideEventPrevented)
-
 
229
    if (hideEventPrevented.isDefaultPrevented()) {
140
    this._queueCallback(() => this._hideModal(), this._element, this._isAnimated())
230
      return
141
  }
231
    }
-
 
232
 
142
 
233
    const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight
143
  dispose() {
Línea 234... Línea 144...
234
 
144
    EventHandler.off(window, EVENT_KEY)
235
    if (!isModalOverflowing) {
145
    EventHandler.off(this._dialog, EVENT_KEY)
236
      this._element.style.overflowY = 'hidden'
146
 
237
    }
147
    this._backdrop.dispose()
-
 
148
    this._focustrap.deactivate()
Línea 238... Línea 149...
238
 
149
 
-
 
150
    super.dispose()
239
    this._element.classList.add(CLASS_NAME_STATIC)
151
  }
240
 
-
 
241
    const modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog)
-
 
242
    $(this._element).off(Util.TRANSITION_END)
152
 
Línea 243... Línea -...
243
 
-
 
244
    $(this._element).one(Util.TRANSITION_END, () => {
153
  handleUpdate() {
245
      this._element.classList.remove(CLASS_NAME_STATIC)
-
 
246
      if (!isModalOverflowing) {
-
 
247
        $(this._element).one(Util.TRANSITION_END, () => {
-
 
248
          this._element.style.overflowY = ''
-
 
249
        })
-
 
250
          .emulateTransitionEnd(this._element, modalTransitionDuration)
-
 
251
      }
-
 
Línea 252... Línea 154...
252
    })
154
    this._adjustDialog()
253
      .emulateTransitionEnd(modalTransitionDuration)
-
 
254
    this._element.focus()
-
 
Línea 255... Línea 155...
255
  }
155
  }
256
 
156
 
257
  _showElement(relatedTarget) {
157
  // Private
258
    const transition = $(this._element).hasClass(CLASS_NAME_FADE)
158
  _initializeBackDrop() {
Línea 259... Línea 159...
259
    const modalBody = this._dialog ? this._dialog.querySelector(SELECTOR_MODAL_BODY) : null
159
    return new Backdrop({
260
 
160
      isVisible: Boolean(this._config.backdrop), // 'static' option will be translated to true, and booleans will keep their value,
261
    if (!this._element.parentNode ||
-
 
262
        this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
-
 
263
      // Don't move modal's DOM position
-
 
264
      document.body.appendChild(this._element)
-
 
265
    }
-
 
266
 
161
      isAnimated: this._isAnimated()
267
    this._element.style.display = 'block'
-
 
268
    this._element.removeAttribute('aria-hidden')
-
 
269
    this._element.setAttribute('aria-modal', true)
-
 
270
    this._element.setAttribute('role', 'dialog')
-
 
271
 
-
 
272
    if ($(this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) {
-
 
273
      modalBody.scrollTop = 0
-
 
274
    } else {
-
 
275
      this._element.scrollTop = 0
-
 
276
    }
-
 
277
 
-
 
278
    if (transition) {
-
 
279
      Util.reflow(this._element)
-
 
280
    }
-
 
281
 
-
 
282
    $(this._element).addClass(CLASS_NAME_SHOW)
-
 
283
 
162
    })
284
    if (this._config.focus) {
-
 
285
      this._enforceFocus()
-
 
286
    }
-
 
287
 
-
 
288
    const shownEvent = $.Event(EVENT_SHOWN, {
-
 
289
      relatedTarget
-
 
290
    })
-
 
291
 
-
 
292
    const transitionComplete = () => {
-
 
293
      if (this._config.focus) {
-
 
294
        this._element.focus()
-
 
295
      }
-
 
296
 
-
 
297
      this._isTransitioning = false
-
 
298
      $(this._element).trigger(shownEvent)
163
  }
299
    }
-
 
300
 
-
 
301
    if (transition) {
-
 
302
      const transitionDuration = Util.getTransitionDurationFromElement(this._dialog)
-
 
303
 
-
 
304
      $(this._dialog)
-
 
305
        .one(Util.TRANSITION_END, transitionComplete)
-
 
306
        .emulateTransitionEnd(transitionDuration)
-
 
307
    } else {
-
 
Línea 308... Línea -...
308
      transitionComplete()
-
 
309
    }
-
 
310
  }
164
 
311
 
-
 
312
  _enforceFocus() {
-
 
313
    $(document)
-
 
314
      .off(EVENT_FOCUSIN) // Guard against infinite focus loop
-
 
315
      .on(EVENT_FOCUSIN, event => {
-
 
316
        if (document !== event.target &&
-
 
317
            this._element !== event.target &&
-
 
318
            $(this._element).has(event.target).length === 0) {
-
 
319
          this._element.focus()
-
 
320
        }
165
  _initializeFocusTrap() {
Línea 321... Línea 166...
321
      })
166
    return new FocusTrap({
322
  }
167
      trapElement: this._element
323
 
168
    })
324
  _setEscapeEvent() {
169
  }
325
    if (this._isShown) {
170
 
326
      $(this._element).on(EVENT_KEYDOWN_DISMISS, event => {
-
 
Línea 327... Línea 171...
327
        if (this._config.keyboard && event.which === ESCAPE_KEYCODE) {
171
  _showElement(relatedTarget) {
328
          event.preventDefault()
172
    // try to append dynamic modal
329
          this.hide()
173
    if (!document.body.contains(this._element)) {
-
 
174
      document.body.append(this._element)
Línea 330... Línea -...
330
        } else if (!this._config.keyboard && event.which === ESCAPE_KEYCODE) {
-
 
331
          this._triggerBackdropTransition()
175
    }
332
        }
176
 
Línea -... Línea 177...
-
 
177
    this._element.style.display = 'block'
333
      })
178
    this._element.removeAttribute('aria-hidden')
334
    } else if (!this._isShown) {
179
    this._element.setAttribute('aria-modal', true)
335
      $(this._element).off(EVENT_KEYDOWN_DISMISS)
180
    this._element.setAttribute('role', 'dialog')
-
 
181
    this._element.scrollTop = 0
Línea 336... Línea 182...
336
    }
182
 
337
  }
-
 
-
 
183
    const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog)
338
 
184
    if (modalBody) {
339
  _setResizeEvent() {
-
 
340
    if (this._isShown) {
185
      modalBody.scrollTop = 0
341
      $(window).on(EVENT_RESIZE, event => this.handleUpdate(event))
186
    }
342
    } else {
187
 
Línea 343... Línea 188...
343
      $(window).off(EVENT_RESIZE)
188
    reflow(this._element)
-
 
189
 
344
    }
190
    this._element.classList.add(CLASS_NAME_SHOW)
345
  }
191
 
Línea 346... Línea 192...
346
 
192
    const transitionComplete = () => {
347
  _hideModal() {
-
 
348
    this._element.style.display = 'none'
-
 
349
    this._element.setAttribute('aria-hidden', true)
193
      if (this._config.focus) {
350
    this._element.removeAttribute('aria-modal')
194
        this._focustrap.activate()
351
    this._element.removeAttribute('role')
195
      }
-
 
196
 
-
 
197
      this._isTransitioning = false
Línea 352... Línea 198...
352
    this._isTransitioning = false
198
      EventHandler.trigger(this._element, EVENT_SHOWN, {
-
 
199
        relatedTarget
-
 
200
      })
-
 
201
    }
353
    this._showBackdrop(() => {
202
 
354
      $(document.body).removeClass(CLASS_NAME_OPEN)
203
    this._queueCallback(transitionComplete, this._dialog, this._isAnimated())
Línea -... Línea 204...
-
 
204
  }
355
      this._resetAdjustments()
205
 
-
 
206
  _addEventListeners() {
-
 
207
    EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {
-
 
208
      if (event.key !== ESCAPE_KEY) {
-
 
209
        return
-
 
210
      }
Línea 356... Línea 211...
356
      this._resetScrollbar()
211
 
357
      $(this._element).trigger(EVENT_HIDDEN)
212
      if (this._config.keyboard) {
358
    })
213
        this.hide()
Línea 359... Línea 214...
359
  }
214
        return
-
 
215
      }
360
 
216
 
361
  _removeBackdrop() {
217
      this._triggerBackdropTransition()
362
    if (this._backdrop) {
218
    })
Línea 363... Línea 219...
363
      $(this._backdrop).remove()
219
 
-
 
220
    EventHandler.on(window, EVENT_RESIZE, () => {
-
 
221
      if (this._isShown && !this._isTransitioning) {
-
 
222
        this._adjustDialog()
-
 
223
      }
-
 
224
    })
Línea 364... Línea 225...
364
      this._backdrop = null
225
 
365
    }
-
 
366
  }
-
 
367
 
-
 
368
  _showBackdrop(callback) {
226
    EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => {
369
    const animate = $(this._element).hasClass(CLASS_NAME_FADE) ?
-
 
370
      CLASS_NAME_FADE : ''
-
 
371
 
-
 
372
    if (this._isShown && this._config.backdrop) {
-
 
373
      this._backdrop = document.createElement('div')
-
 
374
      this._backdrop.className = CLASS_NAME_BACKDROP
-
 
375
 
227
      // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks
Línea -... Línea 228...
-
 
228
      EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => {
-
 
229
        if (this._element !== event.target || this._element !== event2.target) {
376
      if (animate) {
230
          return
-
 
231
        }
377
        this._backdrop.classList.add(animate)
232
 
-
 
233
        if (this._config.backdrop === 'static') {
-
 
234
          this._triggerBackdropTransition()
Línea 378... Línea -...
378
      }
-
 
379
 
-
 
380
      $(this._backdrop).appendTo(document.body)
-
 
381
 
-
 
382
      $(this._element).on(EVENT_CLICK_DISMISS, event => {
235
          return
383
        if (this._ignoreBackdropClick) {
-
 
384
          this._ignoreBackdropClick = false
-
 
385
          return
-
 
386
        }
-
 
387
 
236
        }
Línea 388... Línea -...
388
        if (event.target !== event.currentTarget) {
-
 
-
 
237
 
389
          return
238
        if (this._config.backdrop) {
390
        }
-
 
391
 
-
 
-
 
239
          this.hide()
Línea 392... Línea 240...
392
        if (this._config.backdrop === 'static') {
240
        }
393
          this._triggerBackdropTransition()
241
      })
-
 
242
    })
-
 
243
  }
Línea 394... Línea 244...
394
        } else {
244
 
-
 
245
  _hideModal() {
395
          this.hide()
246
    this._element.style.display = 'none'
396
        }
247
    this._element.setAttribute('aria-hidden', true)
Línea 397... Línea 248...
397
      })
248
    this._element.removeAttribute('aria-modal')
-
 
249
    this._element.removeAttribute('role')
398
 
250
    this._isTransitioning = false
399
      if (animate) {
251
 
400
        Util.reflow(this._backdrop)
252
    this._backdrop.hide(() => {
Línea 401... Línea 253...
401
      }
253
      document.body.classList.remove(CLASS_NAME_OPEN)
402
 
254
      this._resetAdjustments()
403
      $(this._backdrop).addClass(CLASS_NAME_SHOW)
255
      this._scrollBar.reset()
404
 
256
      EventHandler.trigger(this._element, EVENT_HIDDEN)
Línea 405... Línea -...
405
      if (!callback) {
-
 
406
        return
-
 
407
      }
-
 
408
 
-
 
409
      if (!animate) {
-
 
410
        callback()
-
 
411
        return
-
 
412
      }
-
 
413
 
-
 
414
      const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)
-
 
415
 
-
 
416
      $(this._backdrop)
-
 
417
        .one(Util.TRANSITION_END, callback)
-
 
418
        .emulateTransitionEnd(backdropTransitionDuration)
-
 
419
    } else if (!this._isShown && this._backdrop) {
-
 
420
      $(this._backdrop).removeClass(CLASS_NAME_SHOW)
-
 
421
 
-
 
422
      const callbackRemove = () => {
-
 
423
        this._removeBackdrop()
-
 
424
        if (callback) {
-
 
425
          callback()
-
 
426
        }
-
 
427
      }
-
 
428
 
-
 
429
      if ($(this._element).hasClass(CLASS_NAME_FADE)) {
-
 
430
        const backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop)
-
 
431
 
-
 
432
        $(this._backdrop)
-
 
433
          .one(Util.TRANSITION_END, callbackRemove)
-
 
434
          .emulateTransitionEnd(backdropTransitionDuration)
-
 
435
      } else {
-
 
436
        callbackRemove()
-
 
437
      }
-
 
438
    } else if (callback) {
-
 
439
      callback()
-
 
440
    }
-
 
441
  }
-
 
442
 
-
 
443
  // ----------------------------------------------------------------------
-
 
444
  // the following methods are used to handle overflowing modals
-
 
445
  // todo (fat): these should probably be refactored out of modal.js
-
 
446
  // ----------------------------------------------------------------------
-
 
447
 
-
 
448
  _adjustDialog() {
-
 
449
    const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight
-
 
450
 
-
 
451
    if (!this._isBodyOverflowing && isModalOverflowing) {
-
 
452
      this._element.style.paddingLeft = `${this._scrollbarWidth}px`
-
 
453
    }
-
 
454
 
-
 
455
    if (this._isBodyOverflowing && !isModalOverflowing) {
-
 
456
      this._element.style.paddingRight = `${this._scrollbarWidth}px`
-
 
457
    }
-
 
458
  }
-
 
459
 
-
 
460
  _resetAdjustments() {
-
 
461
    this._element.style.paddingLeft = ''
-
 
462
    this._element.style.paddingRight = ''
-
 
463
  }
-
 
464
 
-
 
465
  _checkScrollbar() {
-
 
466
    const rect = document.body.getBoundingClientRect()
-
 
467
    this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth
-
 
468
    this._scrollbarWidth = this._getScrollbarWidth()
-
 
469
  }
-
 
470
 
-
 
471
  _setScrollbar() {
-
 
472
    if (this._isBodyOverflowing) {
-
 
473
      // Note: DOMNode.style.paddingRight returns the actual value or '' if not set
-
 
474
      //   while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set
-
 
475
      const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))
-
 
476
      const stickyContent = [].slice.call(document.querySelectorAll(SELECTOR_STICKY_CONTENT))
-
 
477
 
-
 
478
      // Adjust fixed content padding
-
 
479
      $(fixedContent).each((index, element) => {
-
 
480
        const actualPadding = element.style.paddingRight
257
    })
481
        const calculatedPadding = $(element).css('padding-right')
258
  }
482
        $(element)
259
 
483
          .data('padding-right', actualPadding)
-
 
484
          .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)
-
 
485
      })
-
 
486
 
-
 
487
      // Adjust sticky content margin
260
  _isAnimated() {
488
      $(stickyContent).each((index, element) => {
-
 
Línea 489... Línea -...
489
        const actualMargin = element.style.marginRight
-
 
490
        const calculatedMargin = $(element).css('margin-right')
261
    return this._element.classList.contains(CLASS_NAME_FADE)
491
        $(element)
262
  }
492
          .data('margin-right', actualMargin)
263
 
Línea 493... Línea -...
493
          .css('margin-right', `${parseFloat(calculatedMargin) - this._scrollbarWidth}px`)
-
 
494
      })
264
  _triggerBackdropTransition() {
495
 
265
    const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED)
496
      // Adjust body padding
-
 
497
      const actualPadding = document.body.style.paddingRight
-
 
498
      const calculatedPadding = $(document.body).css('padding-right')
-
 
499
      $(document.body)
-
 
500
        .data('padding-right', actualPadding)
-
 
501
        .css('padding-right', `${parseFloat(calculatedPadding) + this._scrollbarWidth}px`)
266
    if (hideEvent.defaultPrevented) {
-
 
267
      return
-
 
268
    }
502
    }
269
 
503
 
270
    const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight
504
    $(document.body).addClass(CLASS_NAME_OPEN)
271
    const initialOverflowY = this._element.style.overflowY
Línea 505... Línea 272...
505
  }
272
    // return if the following background transition hasn't yet completed
506
 
273
    if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) {
507
  _resetScrollbar() {
274
      return
Línea 508... Línea 275...
508
    // Restore fixed content padding
275
    }
509
    const fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT))
-
 
510
    $(fixedContent).each((index, element) => {
276
 
511
      const padding = $(element).data('padding-right')
-
 
512
      $(element).removeData('padding-right')
-
 
513
      element.style.paddingRight = padding ? padding : ''
-
 
514
    })
-
 
515
 
-
 
516
    // Restore sticky content
-
 
517
    const elements = [].slice.call(document.querySelectorAll(`${SELECTOR_STICKY_CONTENT}`))
-
 
518
    $(elements).each((index, element) => {
-
 
519
      const margin = $(element).data('margin-right')
-
 
520
      if (typeof margin !== 'undefined') {
-
 
Línea 521... Línea 277...
521
        $(element).css('margin-right', margin).removeData('margin-right')
277
    if (!isModalOverflowing) {
522
      }
278
      this._element.style.overflowY = 'hidden'
523
    })
279
    }
Línea 524... Línea 280...
524
 
280
 
525
    // Restore body padding
281
    this._element.classList.add(CLASS_NAME_STATIC)
526
    const padding = $(document.body).data('padding-right')
282
    this._queueCallback(() => {
527
    $(document.body).removeData('padding-right')
283
      this._element.classList.remove(CLASS_NAME_STATIC)
528
    document.body.style.paddingRight = padding ? padding : ''
284
      this._queueCallback(() => {
Línea 529... Línea 285...
529
  }
285
        this._element.style.overflowY = initialOverflowY
530
 
286
      }, this._dialog)
531
  _getScrollbarWidth() { // thx d.walsh
287
    }, this._dialog)
532
    const scrollDiv = document.createElement('div')
288
 
533
    scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER
289
    this._element.focus()
534
    document.body.appendChild(scrollDiv)
290
  }
Línea -... Línea 291...
-
 
291
 
-
 
292
  /**
-
 
293
   * The following methods are used to handle overflowing modals
535
    const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth
294
   */
-
 
295
 
-
 
296
  _adjustDialog() {
-
 
297
    const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight
-
 
298
    const scrollbarWidth = this._scrollBar.getWidth()
-
 
299
    const isBodyOverflowing = scrollbarWidth > 0
536
    document.body.removeChild(scrollDiv)
300
 
Línea -... Línea 301...
-
 
301
    if (isBodyOverflowing && !isModalOverflowing) {
-
 
302
      const property = isRTL() ? 'paddingLeft' : 'paddingRight'
537
    return scrollbarWidth
303
      this._element.style[property] = `${scrollbarWidth}px`
538
  }
304
    }
539
 
305
 
Línea 540... Línea -...
540
  // Static
-
 
541
  static _jQueryInterface(config, relatedTarget) {
306
    if (!isBodyOverflowing && isModalOverflowing) {
542
    return this.each(function () {
-
 
543
      let data = $(this).data(DATA_KEY)
-
 
544
      const _config = {
-
 
545
        ...Default,
-
 
Línea 546... Línea 307...
546
        ...$(this).data(),
307
      const property = isRTL() ? 'paddingRight' : 'paddingLeft'