/** * @file * Bootstrap Modals. * * @param {jQuery} $ * @param {Drupal} Drupal * @param {Drupal.bootstrap} Bootstrap * @param {Attributes} Attributes * @param {drupalSettings} drupalSettings */ (function ($, Drupal, Bootstrap, Attributes, drupalSettings) { 'use strict'; /** * Only process this once. */ Bootstrap.once('modal.jquery.ui.bridge', function (settings) { // RTL support. var rtl = document.documentElement.getAttribute('dir').toLowerCase() === 'rtl'; // Override drupal.dialog button classes. This must be done on DOM ready // since core/drupal.dialog technically depends on this file and has not // yet set their default settings. $(function () { drupalSettings.dialog.buttonClass = 'btn'; drupalSettings.dialog.buttonPrimaryClass = 'btn-primary'; }); // Create the "dialog" plugin bridge. Bootstrap.Dialog.Bridge = function (options) { var args = Array.prototype.slice.call(arguments); var $element = $(this); var type = options && options.dialogType || $element[0].dialogType || 'modal'; $element[0].dialogType = type; var handler = Bootstrap.Dialog.Handler.get(type); // When only options are passed, jQuery UI dialog treats this like a // initialization method. Destroy any existing Bootstrap modal and // recreate it using the contents of the dialog HTML. if (args.length === 1 && typeof options === 'object') { this.each(function () { handler.ensureModalStructure(this, options); }); // Proxy to the Bootstrap Modal plugin, indicating that this is a // jQuery UI dialog bridge. return handler.invoke(this, { dialogOptions: options, jQueryUiBridge: true }); } // Otherwise, proxy all arguments to the Bootstrap Modal plugin. var ret; try { ret = handler.invoke.apply(handler, [this].concat(args)); } catch (e) { Bootstrap.warn(e); } // If just one element and there was a result returned for the option passed, // then return the result. Otherwise, just return the jQuery object. return this.length === 1 && ret !== void 0 ? ret : this; }; // Assign the jQuery "dialog" plugin to use to the bridge. Bootstrap.createPlugin('dialog', Bootstrap.Dialog.Bridge); // Create the "modal" plugin bridge. Bootstrap.Modal.Bridge = function () { var Modal = this; return { DEFAULTS: { // By default, this option is disabled. It's only flagged when a modal // was created using $.fn.dialog above. jQueryUiBridge: false }, prototype: { /** * Handler for $.fn.dialog('close'). */ close: function () { var _this = this; this.hide.apply(this, arguments); // For some reason (likely due to the transition event not being // registered properly), the backdrop doesn't always get removed // after the above "hide" method is invoked . Instead, ensure the // backdrop is removed after the transition duration by manually // invoking the internal "hideModal" method shortly thereafter. setTimeout(function () { if (!_this.isShown && _this.$backdrop) { _this.hideModal(); } }, (Modal.TRANSITION_DURATION !== void 0 ? Modal.TRANSITION_DURATION : 300) + 10); }, /** * Creates any necessary buttons from dialog options. */ createButtons: function () { var handler = Bootstrap.Dialog.Handler.get(this.$element); this.$footer.find(handler.selectors.buttons).remove(); // jQuery UI supports both objects and arrays. Unfortunately // developers have misunderstood and abused this by simply placing // the objects that should be in an array inside an object with // arbitrary keys (likely to target specific buttons as a hack). var buttons = this.options.dialogOptions && this.options.dialogOptions.buttons || []; if (!Array.isArray(buttons)) { var array = []; for (var k in buttons) { // Support the proper object values: label => click callback. if (typeof buttons[k] === 'function') { array.push({ label: k, click: buttons[k], }); } // Support nested objects, but log a warning. else if (buttons[k].text || buttons[k].label) { Bootstrap.warn('Malformed jQuery UI dialog button: @key. The button object should be inside an array.', { '@key': k }); array.push(buttons[k]); } else { Bootstrap.unsupported('button', k, buttons[k]); } } buttons = array; } if (buttons.length) { var $buttons = $('