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