1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
/**
* @file
* Positioning extensions for dialogs.
*/
/**
* Triggers when content inside a dialog changes.
*
* @event dialogContentResize
*/
(function ($, Drupal, drupalSettings, debounce, displace) {
// autoResize option will turn off resizable and draggable.
drupalSettings.dialog = $.extend(
{ autoResize: true, maxHeight: '95%' },
drupalSettings.dialog,
);
/**
* Position the dialog's center at the center of displace.offsets boundaries.
*
* @function Drupal.dialog~resetPosition
*
* @param {object} options
* Options object.
*
* @return {object}
* Altered options object.
*/
function resetPosition(options) {
const offsets = displace.offsets;
const left = offsets.left - offsets.right;
const top = offsets.top - offsets.bottom;
const leftString = `${
(left > 0 ? '+' : '-') + Math.abs(Math.round(left / 2))
}px`;
const topString = `${
(top > 0 ? '+' : '-') + Math.abs(Math.round(top / 2))
}px`;
options.position = {
my: `center${left !== 0 ? leftString : ''} center${
top !== 0 ? topString : ''
}`,
of: window,
};
return options;
}
/**
* Resets the current options for positioning.
*
* This is used as a window resize and scroll callback to reposition the
* jQuery UI dialog. Although not a built-in jQuery UI option, this can
* be disabled by setting autoResize: false in the options array when creating
* a new {@link Drupal.dialog}.
*
* @function Drupal.dialog~resetSize
*
* @param {jQuery.Event} event
* The event triggered.
*
* @fires event:dialogContentResize
*/
function resetSize(event) {
const positionOptions = [
'width',
'height',
'minWidth',
'minHeight',
'maxHeight',
'maxWidth',
'position',
];
let adjustedOptions = {};
let windowHeight = $(window).height();
let option;
let optionValue;
let adjustedValue;
for (let n = 0; n < positionOptions.length; n++) {
option = positionOptions[n];
optionValue = event.data.settings[option];
if (optionValue) {
// jQuery UI does not support percentages on heights, convert to pixels.
if (
typeof optionValue === 'string' &&
optionValue.endsWith('%') &&
/height/i.test(option)
) {
// Take offsets in account.
windowHeight -= displace.offsets.top + displace.offsets.bottom;
adjustedValue = parseInt(
0.01 * parseInt(optionValue, 10) * windowHeight,
10,
);
// Don't force the dialog to be bigger vertically than needed.
if (
option === 'height' &&
Math.round(event.data.$element.parent().outerHeight()) <
adjustedValue
) {
adjustedValue = 'auto';
}
adjustedOptions[option] = adjustedValue;
}
}
}
// Offset the dialog center to be at the center of Drupal.displace.offsets.
if (!event.data.settings.modal) {
adjustedOptions = resetPosition(adjustedOptions);
}
event.data.$element.dialog('option', adjustedOptions);
event.data.$element
?.get(0)
?.dispatchEvent(
new CustomEvent('dialogContentResize', { bubbles: true }),
);
}
window.addEventListener('dialog:aftercreate', (e) => {
const autoResize = debounce(resetSize, 20);
const $element = $(e.target);
const { settings } = e;
const eventData = { settings, $element };
if (settings.autoResize === true || settings.autoResize === 'true') {
const uiDialog = $element
.dialog('option', { resizable: false, draggable: false })
.dialog('widget');
uiDialog[0].style.position = 'fixed';
$(window)
.on('resize.dialogResize scroll.dialogResize', eventData, autoResize)
.trigger('resize.dialogResize');
$(document).on(
'drupalViewportOffsetChange.dialogResize',
eventData,
autoResize,
);
}
});
window.addEventListener('dialog:beforeclose', () => {
$(window).off('.dialogResize');
$(document).off('.dialogResize');
});
})(jQuery, Drupal, drupalSettings, Drupal.debounce, Drupal.displace);
|