vgapp 1.4.0 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,10 +4,10 @@ import Backdrop from "../../../utils/js/components/backdrop";
4
4
  import Selectors from "../../../utils/js/dom/selectors";
5
5
  import EventHandler from "../../../utils/js/dom/event";
6
6
  import {Manipulator} from "../../../utils/js/dom/manipulator";
7
- import {execute, isDisabled, isRTL, mergeDeepObject, reflow} from "../../../utils/js/functions";
8
- import {dismissTrigger} from "../../module-fn";
9
- import VGModalDrag from "./vgmodal.drag";
10
- import VGModalResize from "./vgmodal.resize";
7
+ import {execute, isDisabled, isRTL, mergeDeepObject, reflow} from "../../../utils/js/functions";
8
+ import {dismissTrigger} from "../../module-fn";
9
+ import VGModalInteraction from "./vgmodal.interaction";
10
+ import VGModalMinimized from "./vgmodal.minimized";
11
11
 
12
12
  /**
13
13
  * Constants
@@ -17,64 +17,55 @@ const NAME_KEY = 'vg.modal';
17
17
 
18
18
  const ESCAPE_KEY = 'Escape';
19
19
 
20
- const OPEN_SELECTOR = '.vg-modal.show:not([data-vg-persistent="true"])';
21
- const SELECTOR_DIALOG = '.vg-modal-dialog';
22
- const SELECTOR_MODAL_BODY = '.vg-modal-body';
23
- const SELECTOR_DATA_TOGGLE = '[data-vg-toggle="modal"]';
24
-
25
- const CLASS_NAME_OPEN = 'vg-modal-open';
26
- const CLASS_NAME_SHOW = 'show';
27
- const CLASS_NAME_FADE = 'fade';
28
- const CLASS_NAME_STATIC = 'vg-modal-static';
29
-
30
- const EVENT_KEY_HIDE = `${NAME_KEY}.hide`;
31
- const EVENT_KEY_HIDDEN = `${NAME_KEY}.hidden`;
32
- const EVENT_KEY_SHOW = `${NAME_KEY}.show`;
33
- const EVENT_KEY_SHOWN = `${NAME_KEY}.shown`;
34
- const EVENT_KEY_RESIZE = `${NAME_KEY}.resize`;
35
- const EVENT_KEY_LOADED = `${NAME_KEY}.loaded`;
36
-
37
- const EVENT_KEY_KEYDOWN_DISMISS = `keydown.dismiss.${NAME_KEY}`;
38
- const EVENT_KEY_HIDE_PREVENTED = `hidePrevented.${NAME_KEY}`;
39
- const EVENT_KEY_CLICK_DATA_API = `click.${NAME_KEY}.data.api`;
40
- const EVENT_KEY_MOUSEDOWN_DISMISS = `mousedown.dismiss${NAME_KEY}`;
41
- const EVENT_KEY_CLICK_DISMISS = `click.dismiss${NAME_KEY}`;
42
- const EVENT_KEY_DOM_LOADED_DATA_API = `DOMContentLoaded.${NAME_KEY}.data.api`;
43
- const EVENT_KEY_POPSTATE_DATA_API = `popstate.${NAME_KEY}.data.api`;
44
-
45
- class VGModal extends BaseModule {
46
- constructor(element, params = {}) {
47
- super(element, params);
48
-
49
- this._interactionDefaults = {
50
- drag: {
51
- enable: false,
52
- selector: '.vg-modal-content',
53
- threshold: 4,
54
- resizeEdgeSize: 8,
55
- debug: false,
56
- },
57
- resize: {
58
- enable: false,
59
- edgeSize: 8,
60
- minWidth: 300,
61
- minHeight: 160,
62
- debug: false,
63
- },
64
- };
65
-
66
- this._params = this._getParams(element, mergeDeepObject({
20
+ const OPEN_SELECTOR = '.vg-modal.show:not([data-vg-persistent="true"])';
21
+ const SELECTOR_DIALOG = '.vg-modal-dialog';
22
+ const SELECTOR_MODAL_BODY = '.vg-modal-body';
23
+ const SELECTOR_DATA_TOGGLE = '[data-vg-toggle="modal"]';
24
+ const BACKDROP_OWNER_ATTR = 'data-vg-backdrop-owner';
25
+ const BACKDROP_OWNER_VALUE = 'modal';
26
+
27
+ const CLASS_NAME_OPEN = 'vg-modal-open';
28
+ const CLASS_NAME_SHOW = 'show';
29
+ const CLASS_NAME_FADE = 'fade';
30
+ const CLASS_NAME_STATIC = 'vg-modal-static';
31
+
32
+ const EVENT_KEY_HIDE = `${NAME_KEY}.hide`;
33
+ const EVENT_KEY_HIDDEN = `${NAME_KEY}.hidden`;
34
+ const EVENT_KEY_SHOW = `${NAME_KEY}.show`;
35
+ const EVENT_KEY_SHOWN = `${NAME_KEY}.shown`;
36
+ const EVENT_KEY_RESIZE = `${NAME_KEY}.resize`;
37
+ const EVENT_KEY_LOADED = `${NAME_KEY}.loaded`;
38
+
39
+ const EVENT_KEY_KEYDOWN_DISMISS = `keydown.dismiss.${NAME_KEY}`;
40
+ const EVENT_KEY_HIDE_PREVENTED = `hidePrevented.${NAME_KEY}`;
41
+ const EVENT_KEY_CLICK_DATA_API = `click.${NAME_KEY}.data.api`;
42
+ const EVENT_KEY_MOUSEDOWN_DISMISS = `mousedown.dismiss${NAME_KEY}`;
43
+ const EVENT_KEY_CLICK_DISMISS = `click.dismiss${NAME_KEY}`;
44
+ const EVENT_KEY_BACKDROP_DISMISS = `mousedown.${NAME_KEY}.backdrop`;
45
+ const EVENT_KEY_DOM_LOADED_DATA_API = `DOMContentLoaded.${NAME_KEY}.data.api`;
46
+ const EVENT_KEY_POPSTATE_DATA_API = `popstate.${NAME_KEY}.data.api`;
47
+
48
+ class VGModal extends BaseModule {
49
+ constructor(element, params = {}) {
50
+ super(element, params);
51
+
52
+ this._params = this._getParams(element, mergeDeepObject({
67
53
  backdrop: true,
68
54
  persistent: false,
69
55
  focus: true,
70
56
  keyboard: true,
71
57
  fields: [],
72
58
  hash: false,
73
- centered: false,
74
- dismiss: true,
75
- resize: {
76
- enable: false,
77
- edgeSize: 8,
59
+ centered: false,
60
+ dismiss: true,
61
+ minimize: {
62
+ enable: false,
63
+ title: '',
64
+ text: '',
65
+ },
66
+ resize: {
67
+ enable: false,
68
+ edgeSize: 8,
78
69
  minWidth: 300,
79
70
  minHeight: 160,
80
71
  debug: false,
@@ -120,22 +111,22 @@ class VGModal extends BaseModule {
120
111
  }
121
112
  }, params));
122
113
 
123
- this._button = null;
124
- this._dialog = Selectors.find(SELECTOR_DIALOG, this._element);
125
- this._content = Selectors.find('.vg-modal-content', this._dialog);
126
- this._isShown = false;
127
- this._isTransitioning = false;
128
- this._scrollBar = new ScrollBarHelper();
129
- this._dragHandler = new VGModalDrag(this._element, this._dialog);
130
- this._resizeHandler = new VGModalResize(this._element, this._dialog);
131
- this._interactionConfig = this._resolveInteractionConfig();
132
- this._dragHandler.setOptions(this._interactionConfig.drag);
133
- this._resizeHandler.setOptions(this._interactionConfig.resize);
134
-
135
- this._addEventListeners();
136
- this._dismissElement();
137
-
138
- this._params.animation.delay = !this._params.animation.enable ? 0 : this._params.animation.delay;
114
+ this._button = null;
115
+ this._dialog = Selectors.find(SELECTOR_DIALOG, this._element);
116
+ this._content = Selectors.find('.vg-modal-content', this._dialog);
117
+ this._isShown = false;
118
+ this._isTransitioning = false;
119
+ this._scrollBar = new ScrollBarHelper();
120
+ this._backdropElement = null;
121
+ this._isBackdropOwner = false;
122
+ this._interaction = new VGModalInteraction(this._element, this._dialog, this._content, () => this._params);
123
+ this._minimized = new VGModalMinimized(this);
124
+
125
+ this._addEventListeners();
126
+ this._dismissElement();
127
+ this._minimized.setup();
128
+
129
+ this._params.animation.delay = !this._params.animation.enable ? 0 : this._params.animation.delay;
139
130
  this._animation(this._element, VGModal.NAME_KEY, this._params.animation);
140
131
  if (this._params.persistent) {
141
132
  this._element.setAttribute('data-vg-persistent', 'true');
@@ -148,50 +139,91 @@ class VGModal extends BaseModule {
148
139
  return NAME;
149
140
  }
150
141
 
151
- static get NAME_KEY() {
152
- return NAME_KEY;
153
- }
154
-
155
- static init(element, params, callback) {
156
- VGModal.build(element, params, callback);
157
- }
158
-
159
- static build(id, params, callback) {
160
- if (typeof id !== "string") return;
161
-
162
- let _element = document.createElement('div');
163
- _element.classList.add('vg-modal');
142
+ static get NAME_KEY() {
143
+ return NAME_KEY;
144
+ }
145
+
146
+ static init(element, params = {}, callback) {
147
+ return VGModal.build(element, params, callback);
148
+ }
149
+
150
+ static initAll(params = {}) {
151
+ return Selectors.findAll('.vg-modal').map((element) => {
152
+ return VGModal.getOrCreateInstance(element, params);
153
+ });
154
+ }
155
+
156
+ static build(id, params = {}, callback) {
157
+ if (typeof id !== "string") return;
158
+ if (!params || typeof params !== 'object') {
159
+ params = {};
160
+ }
161
+
162
+ const existed = document.getElementById(id);
163
+ if (existed) {
164
+ const modal = VGModal.getOrCreateInstance(existed, params);
165
+ execute(callback, [modal]);
166
+ return modal;
167
+ }
168
+
169
+ let _element = document.createElement('div');
170
+ _element.classList.add('vg-modal');
164
171
  _element.classList.add('fade');
165
172
  _element.id = id;
166
173
 
167
- let dialog = document.createElement('div');
168
- dialog.classList.add('vg-modal-dialog');
169
-
170
- if ('centered' in params && params.centered) {
171
- dialog.classList.add('vg-modal-dialog-centered');
172
- }
173
-
174
- let content = document.createElement('div');
175
- content.classList.add('vg-modal-content');
176
-
177
- if ('dismiss' in params && params.dismiss) {
178
- let btnClose = document.createElement('button');
179
- Manipulator.set(btnClose, 'type', 'button');
180
- Manipulator.set(btnClose, 'data-vg-dismiss', 'modal');
174
+ let dialog = document.createElement('div');
175
+ dialog.classList.add('vg-modal-dialog');
176
+
177
+ if (params.centered) {
178
+ dialog.classList.add('vg-modal-dialog-centered');
179
+ }
180
+
181
+ let content = document.createElement('div');
182
+ content.classList.add('vg-modal-content');
183
+
184
+ const hasDismiss = !Object.prototype.hasOwnProperty.call(params, 'dismiss') || params.dismiss;
185
+ if (hasDismiss) {
186
+ let btnClose = document.createElement('button');
187
+ Manipulator.set(btnClose, 'type', 'button');
188
+ Manipulator.set(btnClose, 'data-vg-dismiss', 'modal');
181
189
  Manipulator.set(btnClose, 'data-vg-target', '#' + id);
182
190
  Manipulator.set(btnClose, 'aria-label', 'close');
183
191
  btnClose.classList.add('vg-btn-close');
184
-
185
- content.append(btnClose);
186
- }
187
-
188
- let body = document.createElement('div');
189
- body.classList.add('vg-modal-body');
190
-
191
- content.append(body);
192
- dialog.append(content);
193
- _element.append(dialog);
194
-
192
+
193
+ content.append(btnClose);
194
+ }
195
+
196
+ if (params.title) {
197
+ let header = document.createElement('div');
198
+ header.classList.add('vg-modal-header');
199
+
200
+ let title = document.createElement('div');
201
+ title.classList.add('vg-modal-title');
202
+ VGModal._appendBuildContent(title, params.title, Boolean(params.html || params.titleHtml));
203
+
204
+ header.append(title);
205
+ content.append(header);
206
+ }
207
+
208
+ let body = document.createElement('div');
209
+ body.classList.add('vg-modal-body');
210
+ const bodyContent = Object.prototype.hasOwnProperty.call(params, 'body')
211
+ ? params.body
212
+ : (Object.prototype.hasOwnProperty.call(params, 'content') ? params.content : null);
213
+ VGModal._appendBuildContent(body, bodyContent, Boolean(params.html || params.bodyHtml || params.contentHtml));
214
+
215
+ content.append(body);
216
+
217
+ if (Object.prototype.hasOwnProperty.call(params, 'footer')) {
218
+ let footer = document.createElement('div');
219
+ footer.classList.add('vg-modal-footer');
220
+ VGModal._appendBuildContent(footer, params.footer, Boolean(params.html || params.footerHtml));
221
+ content.append(footer);
222
+ }
223
+
224
+ dialog.append(content);
225
+ _element.append(dialog);
226
+
195
227
  document.body.append(_element);
196
228
 
197
229
  const modal = VGModal.getOrCreateInstance(_element, params);
@@ -208,16 +240,45 @@ class VGModal extends BaseModule {
208
240
  }
209
241
 
210
242
  execute(callback, [modal]);
211
-
212
- return modal;
213
- }
214
-
215
- toggle(relatedTarget) {
216
- return !this._isShown ? this.show(relatedTarget) : this.hide();
217
- }
218
-
219
- show(relatedTarget) {
220
- if (isDisabled(this._element)) return;
243
+
244
+ return modal;
245
+ }
246
+
247
+ static _appendBuildContent(target, content, isHTML = false) {
248
+ if (!target || content === null || content === undefined) return;
249
+
250
+ if (Array.isArray(content)) {
251
+ content.forEach(item => VGModal._appendBuildContent(target, item, isHTML));
252
+ return;
253
+ }
254
+
255
+ if (content instanceof Node) {
256
+ target.append(content);
257
+ return;
258
+ }
259
+
260
+ if (isHTML) {
261
+ target.insertAdjacentHTML('beforeend', String(content));
262
+ return;
263
+ }
264
+
265
+ target.append(document.createTextNode(String(content)));
266
+ }
267
+
268
+ toggle(relatedTarget) {
269
+ if (this._minimized.isMinimized()) {
270
+ return this.restore(relatedTarget);
271
+ }
272
+
273
+ return !this._isShown ? this.show(relatedTarget) : this.hide();
274
+ }
275
+
276
+ show(relatedTarget) {
277
+ if (isDisabled(this._element)) return;
278
+ if (this._minimized.isMinimized()) {
279
+ return this.restore(relatedTarget);
280
+ }
281
+ if (this._isShown || this._isTransitioning) return;
221
282
 
222
283
  if (this._params.ajax.route && this._params.ajax.target && !this._params.ajax.once) {
223
284
  const ajaxTargetContent = Selectors.find(this._params.ajax.target, this._element);
@@ -228,41 +289,44 @@ class VGModal extends BaseModule {
228
289
  if (showEvent.defaultPrevented) return;
229
290
 
230
291
  this._isShown = true;
231
- this._isTransitioning = true;
232
-
233
- if (this._params.hash) {
234
- window.history.pushState(null, "vg-sidebar-open", "#" + this._element.id);
235
-
236
- EventHandler.on(window, EVENT_KEY_POPSTATE_DATA_API, () => {
237
- this.hide();
292
+ this._isTransitioning = true;
293
+
294
+ if (this._params.hash) {
295
+ if (window.location.hash !== `#${this._element.id}`) {
296
+ window.history.pushState(null, "vg-modal-open", "#" + this._element.id);
297
+ }
298
+
299
+ EventHandler.on(window, EVENT_KEY_POPSTATE_DATA_API, () => {
300
+ this.hide();
238
301
  });
239
302
  }
240
303
 
241
- this._scrollBar.hide();
304
+ if (this._params.backdrop) {
305
+ this._scrollBar.hide();
306
+ }
242
307
 
243
308
  document.body.classList.add(CLASS_NAME_OPEN);
244
309
 
245
310
  this._addFieldsInModal(relatedTarget);
246
- this._adjustDialog();
247
-
248
- if (this._params.backdrop) {
249
- Backdrop.show(() => {
250
- const backdrop = Selectors.find('.vg-backdrop');
251
- if (backdrop) {
252
- EventHandler.one(backdrop, 'mousedown.vg.backdrop', () => {
253
- this.hide();
254
- });
255
- }
256
-
257
- this._showElement(relatedTarget);
258
- });
259
- return;
260
- }
261
-
262
- this._showElement(relatedTarget);
263
- }
264
-
265
- hide(openedModals = [], isLeaveBackDrop = false) {
311
+ this._adjustDialog();
312
+
313
+ if (this._params.backdrop) {
314
+ this._showBackdrop(() => this._showElement(relatedTarget));
315
+ return;
316
+ }
317
+
318
+ this._showElement(relatedTarget);
319
+ }
320
+
321
+ minimize(relatedTarget) {
322
+ return this._minimized.minimize(relatedTarget);
323
+ }
324
+
325
+ restore(relatedTarget) {
326
+ return this._minimized.restore(relatedTarget);
327
+ }
328
+
329
+ hide(openedModals = [], isLeaveBackDrop = false) {
266
330
  if (!this._isShown || this._isTransitioning) return;
267
331
 
268
332
  const hideEvent = EventHandler.trigger(this._element, EVENT_KEY_HIDE);
@@ -277,13 +341,14 @@ class VGModal extends BaseModule {
277
341
  }, this._params.animation.delay);
278
342
  }
279
343
 
280
- _hideModal(openedModals, isLeaveBackDrop) {
281
- if (!isLeaveBackDrop) {
282
- this._saveInteractionState();
283
- this._disableInteractionHandlers();
284
- this._element.style.display = 'none';
285
- this._element.removeAttribute('aria-modal');
286
- this._element.removeAttribute('role');
344
+ _hideModal(openedModals, isLeaveBackDrop) {
345
+ if (!isLeaveBackDrop) {
346
+ this._saveInteractionState();
347
+ this._disableInteractionHandlers();
348
+ this._minimized.reset();
349
+ this._element.style.display = 'none';
350
+ this._element.removeAttribute('aria-modal');
351
+ this._element.removeAttribute('role');
287
352
  this._isTransitioning = false;
288
353
 
289
354
  const remainingOpenModals = Selectors.findAll(OPEN_SELECTOR).filter(modal => modal !== this._element);
@@ -298,24 +363,34 @@ class VGModal extends BaseModule {
298
363
  history.pushState("", document.title, window.location.pathname + window.location.search);
299
364
  }
300
365
 
301
- if (!this._params.backdrop) {
302
- this._resetAdjustments();
303
- this._scrollBar.reset();
304
-
305
- EventHandler.trigger(this._element, EVENT_KEY_HIDDEN);
306
- return;
366
+ if (!this._params.backdrop) {
367
+ this._resetAdjustments();
368
+ if (!Backdrop.isActive()) {
369
+ this._scrollBar.reset();
370
+ }
371
+
372
+ EventHandler.trigger(this._element, EVENT_KEY_HIDDEN);
373
+ return;
307
374
  }
308
375
 
309
- Backdrop.hide(() => {
310
- this._resetAdjustments();
311
- this._scrollBar.reset();
312
-
313
- EventHandler.trigger(this._element, EVENT_KEY_HIDDEN);
314
- })
315
- }
316
- }
317
-
318
- _showElement(relatedTarget) {
376
+ this._hideBackdrop(() => {
377
+ this._resetAdjustments();
378
+ if (!Backdrop.isActive()) {
379
+ this._scrollBar.reset();
380
+ }
381
+
382
+ EventHandler.trigger(this._element, EVENT_KEY_HIDDEN);
383
+ })
384
+ }
385
+ }
386
+
387
+ dispose() {
388
+ this._minimized.dispose();
389
+ this._interaction.dispose();
390
+ super.dispose();
391
+ }
392
+
393
+ _showElement(relatedTarget) {
319
394
  if (!document.body.contains(this._element)) {
320
395
  document.body.append(this._element);
321
396
  }
@@ -351,180 +426,83 @@ class VGModal extends BaseModule {
351
426
  });
352
427
  }
353
428
 
354
- this._queueCallback(transitionComplete, this._dialog, this._isAnimatedFade())
355
- }
356
-
357
- _bindInteractionHandlers() {
358
- this._dragHandler.setOptions(this._interactionConfig.drag);
359
- this._resizeHandler.setOptions(this._interactionConfig.resize);
360
- }
361
- _toggleInteractionHandlers() {
362
- this._interactionConfig = this._resolveInteractionConfig();
363
- this._bindInteractionHandlers();
364
-
365
- if (this._interactionConfig.drag.enable) {
366
- this._dragHandler.enable();
367
- } else {
368
- this._dragHandler.disable();
369
- }
370
-
371
- if (this._interactionConfig.resize.enable) {
372
- this._resizeHandler.enable();
373
- } else {
374
- this._resizeHandler.disable();
375
- }
376
- }
377
-
378
- _disableInteractionHandlers() {
379
- this._dragHandler.disable();
380
- this._resizeHandler.disable();
381
- }
382
-
383
- _syncInteractiveBounds() {
384
- if (this._interactionConfig.resize.enable) {
385
- this._resizeHandler.syncToViewport();
386
- }
387
-
388
- if (this._interactionConfig.drag.enable) {
389
- this._dragHandler.syncPosition();
390
- }
391
- }
392
-
393
- _resolveInteractionConfig() {
394
- return {
395
- drag: this._normalizeInteractionParams(this._params.drag, this._interactionDefaults.drag),
396
- resize: this._normalizeInteractionParams(this._params.resize, this._interactionDefaults.resize),
397
- };
398
- }
399
-
400
- _normalizeInteractionParams(paramsValue, defaults) {
401
- if (typeof paramsValue === 'boolean') {
402
- return {...defaults, enable: paramsValue};
403
- }
404
-
405
- if (paramsValue && typeof paramsValue === 'object') {
406
- const hasEnable = Object.prototype.hasOwnProperty.call(paramsValue, 'enable');
407
- return {
408
- ...defaults,
409
- ...paramsValue,
410
- enable: hasEnable ? Boolean(paramsValue.enable) : true,
411
- };
412
- }
413
-
414
- return {...defaults};
415
- }
416
-
417
- _getStateConfig() {
418
- return this._normalizeStateParams(this._params.state);
419
- }
420
-
421
- _normalizeStateParams(paramsValue, defaults = { enable: true, key: '' }) {
422
- if (typeof paramsValue === 'boolean') {
423
- return {...defaults, enable: paramsValue};
424
- }
425
-
426
- if (paramsValue && typeof paramsValue === 'object') {
427
- const hasEnable = Object.prototype.hasOwnProperty.call(paramsValue, 'enable');
428
- const key = typeof paramsValue.key === 'string' ? paramsValue.key.trim() : '';
429
- return {
430
- ...defaults,
431
- ...paramsValue,
432
- key,
433
- enable: hasEnable ? Boolean(paramsValue.enable) : true,
434
- };
435
- }
436
-
437
- return {...defaults};
438
- }
439
-
440
- _getStateStorageKey(stateConfig = this._getStateConfig()) {
441
- if (!stateConfig.enable) return '';
442
-
443
- if (typeof stateConfig.key === 'string' && stateConfig.key.trim()) {
444
- return stateConfig.key.trim();
445
- }
446
-
447
- if (!this._element || !this._element.id) return '';
448
-
449
- return `vg.modal.state:${window.location.pathname}:${this._element.id}`;
450
- }
451
-
452
- _captureInteractionState() {
453
- const dialogStyle = this._dialog ? this._dialog.style : null;
454
- const contentElement = this._content || Selectors.find('.vg-modal-content', this._dialog);
455
- const contentStyle = contentElement ? contentElement.style : null;
456
-
457
- return {
458
- dialog: dialogStyle ? {
459
- position: dialogStyle.position,
460
- margin: dialogStyle.margin,
461
- left: dialogStyle.left,
462
- top: dialogStyle.top,
463
- width: dialogStyle.width,
464
- height: dialogStyle.height,
465
- transform: dialogStyle.transform,
466
- maxWidth: dialogStyle.maxWidth,
467
- maxHeight: dialogStyle.maxHeight,
468
- minHeight: dialogStyle.minHeight,
469
- overflow: dialogStyle.overflow,
470
- pointerEvents: dialogStyle.pointerEvents,
471
- transition: dialogStyle.transition,
472
- willChange: dialogStyle.willChange,
473
- } : {},
474
- content: contentStyle ? {
475
- height: contentStyle.height,
476
- maxHeight: contentStyle.maxHeight,
477
- overflow: contentStyle.overflow,
478
- } : {},
479
- };
480
- }
481
-
482
- _applyInteractionState(state) {
483
- if (!state || typeof state !== 'object') return;
484
-
485
- const dialogState = state.dialog && typeof state.dialog === 'object' ? state.dialog : {};
486
- const contentState = state.content && typeof state.content === 'object' ? state.content : {};
487
- if (this._dialog) {
488
- Object.keys(dialogState).forEach(propertyName => {
489
- this._dialog.style[propertyName] = dialogState[propertyName] || '';
490
- });
491
- }
492
-
493
- const contentElement = this._content || Selectors.find('.vg-modal-content', this._dialog);
494
- if (contentElement) {
495
- Object.keys(contentState).forEach(propertyName => {
496
- contentElement.style[propertyName] = contentState[propertyName] || '';
497
- });
498
- }
499
- }
500
-
501
- _saveInteractionState() {
502
- const stateConfig = this._getStateConfig();
503
- const storageKey = this._getStateStorageKey(stateConfig);
504
- if (!stateConfig.enable || !storageKey || typeof window === 'undefined' || !window.localStorage) return;
505
-
506
- try {
507
- window.localStorage.setItem(storageKey, JSON.stringify(this._captureInteractionState()));
508
- } catch (error) {
509
- }
510
- }
511
-
512
- _restoreInteractionState() {
513
- const stateConfig = this._getStateConfig();
514
- const storageKey = this._getStateStorageKey(stateConfig);
515
- if (!stateConfig.enable || !storageKey || typeof window === 'undefined' || !window.localStorage) return false;
516
-
517
- try {
518
- const rawState = window.localStorage.getItem(storageKey);
519
- if (!rawState) return false;
520
-
521
- const parsedState = JSON.parse(rawState);
522
- this._applyInteractionState(parsedState);
523
- return true;
524
- } catch (error) {
525
- return false;
526
- }
527
- }
429
+ this._queueCallback(transitionComplete, this._dialog, this._isAnimatedFade())
430
+ }
431
+
432
+ _showBackdrop(callback) {
433
+ const activeBackdrop = Backdrop.getElement();
434
+ const activeBackdropOwner = activeBackdrop ? activeBackdrop.getAttribute(BACKDROP_OWNER_ATTR) : '';
435
+ if (activeBackdrop && activeBackdropOwner !== 'sidebar') {
436
+ if (!activeBackdropOwner) {
437
+ activeBackdrop.setAttribute(BACKDROP_OWNER_ATTR, BACKDROP_OWNER_VALUE);
438
+ }
439
+
440
+ this._backdropElement = activeBackdrop;
441
+ this._isBackdropOwner = true;
442
+ this._bindBackdropDismiss(activeBackdrop);
443
+ execute(callback);
444
+ return;
445
+ }
446
+
447
+ Backdrop.show((backdrop) => {
448
+ this._backdropElement = backdrop;
449
+ this._isBackdropOwner = true;
450
+ if (backdrop) {
451
+ backdrop.setAttribute(BACKDROP_OWNER_ATTR, BACKDROP_OWNER_VALUE);
452
+ }
453
+ this._bindBackdropDismiss(backdrop);
454
+ execute(callback);
455
+ });
456
+ }
457
+
458
+ _hideBackdrop(callback) {
459
+ if (!this._backdropElement || !this._isBackdropOwner) {
460
+ this._backdropElement = null;
461
+ this._isBackdropOwner = false;
462
+ execute(callback);
463
+ return;
464
+ }
465
+
466
+ Backdrop.hide(() => {
467
+ this._backdropElement = null;
468
+ this._isBackdropOwner = false;
469
+ execute(callback);
470
+ }, this._backdropElement);
471
+ }
472
+
473
+ _bindBackdropDismiss(backdrop) {
474
+ if (!backdrop) return;
475
+
476
+ EventHandler.off(backdrop, EVENT_KEY_BACKDROP_DISMISS);
477
+ EventHandler.one(backdrop, EVENT_KEY_BACKDROP_DISMISS, () => {
478
+ if (this._params.backdrop === 'static') {
479
+ this._triggerBackdropTransition();
480
+ return;
481
+ }
482
+
483
+ this.hide();
484
+ });
485
+ }
486
+
487
+ _toggleInteractionHandlers() {
488
+ this._interaction.toggleHandlers();
489
+ }
490
+
491
+ _disableInteractionHandlers() {
492
+ this._interaction.disableHandlers();
493
+ }
494
+
495
+ _syncInteractiveBounds() {
496
+ this._interaction.syncBounds();
497
+ }
498
+
499
+ _saveInteractionState() {
500
+ this._interaction.saveState();
501
+ }
502
+
503
+ _restoreInteractionState() {
504
+ return this._interaction.restoreState();
505
+ }
528
506
 
529
507
  _isAnimatedFade() {
530
508
  return this._element.classList.contains(CLASS_NAME_FADE)
@@ -656,19 +634,35 @@ dismissTrigger(VGModal);
656
634
  data.toggle(this);
657
635
  });
658
636
 
659
- EventHandler.on(document, EVENT_KEY_DOM_LOADED_DATA_API, function () {
660
- let targetHash = window.location.hash.slice(1);
661
- if (targetHash) {
662
- let target = Selectors.find('#' + targetHash);
663
- if (target && target.classList.contains('vg-modal')) {
664
- if (isDisabled(target)) {
665
- return;
666
- }
667
-
668
- const data = VGModal.getOrCreateInstance(target)
669
- data.toggle();
670
- }
671
- }
672
- })
673
-
674
- export default VGModal;
637
+ const showModalFromHash = () => {
638
+ let targetHash = window.location.hash.slice(1);
639
+ if (!targetHash) return;
640
+
641
+ try {
642
+ targetHash = decodeURIComponent(targetHash);
643
+ } catch (error) {
644
+ return;
645
+ }
646
+
647
+ const target = Selectors.findID(targetHash);
648
+ if (!target || !target.classList.contains('vg-modal') || isDisabled(target)) {
649
+ return;
650
+ }
651
+
652
+ const data = VGModal.getOrCreateInstance(target);
653
+ if (!data._params.hash || data._isShown) {
654
+ return;
655
+ }
656
+
657
+ data.show();
658
+ };
659
+
660
+ if (document.readyState === 'loading') {
661
+ EventHandler.on(document, EVENT_KEY_DOM_LOADED_DATA_API, showModalFromHash);
662
+ } else {
663
+ showModalFromHash();
664
+ }
665
+
666
+ window.addEventListener('hashchange', showModalFromHash);
667
+
668
+ export default VGModal;