annotate core/misc/dialog/dialog.position.es6.js @ 4:a9cd425dd02b

Update, including to Drupal core 8.6.10
author Chris Cannam
date Thu, 28 Feb 2019 13:11:55 +0000
parents c75dbcec494b
children 12f9dff5fda9
rev   line source
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@4 12 (function($, Drupal, drupalSettings, debounce, displace) {
Chris@0 13 // autoResize option will turn off resizable and draggable.
Chris@4 14 drupalSettings.dialog = $.extend(
Chris@4 15 { autoResize: true, maxHeight: '95%' },
Chris@4 16 drupalSettings.dialog,
Chris@4 17 );
Chris@4 18
Chris@4 19 /**
Chris@4 20 * Position the dialog's center at the center of displace.offsets boundaries.
Chris@4 21 *
Chris@4 22 * @function Drupal.dialog~resetPosition
Chris@4 23 *
Chris@4 24 * @param {object} options
Chris@4 25 * Options object.
Chris@4 26 *
Chris@4 27 * @return {object}
Chris@4 28 * Altered options object.
Chris@4 29 */
Chris@4 30 function resetPosition(options) {
Chris@4 31 const offsets = displace.offsets;
Chris@4 32 const left = offsets.left - offsets.right;
Chris@4 33 const top = offsets.top - offsets.bottom;
Chris@4 34
Chris@4 35 const leftString = `${(left > 0 ? '+' : '-') +
Chris@4 36 Math.abs(Math.round(left / 2))}px`;
Chris@4 37 const topString = `${(top > 0 ? '+' : '-') +
Chris@4 38 Math.abs(Math.round(top / 2))}px`;
Chris@4 39 options.position = {
Chris@4 40 my: `center${left !== 0 ? leftString : ''} center${
Chris@4 41 top !== 0 ? topString : ''
Chris@4 42 }`,
Chris@4 43 of: window,
Chris@4 44 };
Chris@4 45 return options;
Chris@4 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@4 64 const positionOptions = [
Chris@4 65 'width',
Chris@4 66 'height',
Chris@4 67 'minWidth',
Chris@4 68 'minHeight',
Chris@4 69 'maxHeight',
Chris@4 70 'maxWidth',
Chris@4 71 'position',
Chris@4 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@4 83 if (
Chris@4 84 typeof optionValue === 'string' &&
Chris@4 85 /%$/.test(optionValue) &&
Chris@4 86 /height/i.test(option)
Chris@4 87 ) {
Chris@0 88 // Take offsets in account.
Chris@0 89 windowHeight -= displace.offsets.top + displace.offsets.bottom;
Chris@4 90 adjustedValue = parseInt(
Chris@4 91 0.01 * parseInt(optionValue, 10) * windowHeight,
Chris@4 92 10,
Chris@4 93 );
Chris@0 94 // Don't force the dialog to be bigger vertically than needed.
Chris@4 95 if (
Chris@4 96 option === 'height' &&
Chris@4 97 event.data.$element.parent().outerHeight() < adjustedValue
Chris@4 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@4 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@4 121 .dialog('widget')
Chris@4 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@4 126 $(document).on(
Chris@4 127 'drupalViewportOffsetChange.dialogResize',
Chris@4 128 eventData,
Chris@4 129 autoResize,
Chris@4 130 );
Chris@0 131 }
Chris@0 132 },
Chris@4 133 'dialog:beforeclose': function(event, dialog, $element) {
Chris@0 134 $(window).off('.dialogResize');
Chris@0 135 $(document).off('.dialogResize');
Chris@0 136 },
Chris@0 137 });
Chris@4 138 })(jQuery, Drupal, drupalSettings, Drupal.debounce, Drupal.displace);