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