drupal/core/modules/overlay/overlay-child.js

192 lines
6.4 KiB
JavaScript

/**
* @file
* Attaches the behaviors for the Overlay child pages.
*/
(function ($) {
"use strict";
/**
* Attach the child dialog behavior to new content.
*/
Drupal.behaviors.overlayChild = {
attach: function (context, settings) {
// Make sure this behavior is not processed more than once.
if (this.processed) {
return;
}
this.processed = true;
// If we cannot reach the parent window, break out of the overlay.
if (!parent.Drupal || !parent.Drupal.overlay) {
window.location = window.location.href.replace(/([?&]?)render=overlay&?/g, '$1').replace(/\?$/, '');
}
settings = settings.overlayChild || {};
// If the entire parent window should be refreshed when the overlay is
// closed, pass that information to the parent window.
if (settings.refreshPage) {
parent.Drupal.overlay.refreshPage = true;
}
// If a form has been submitted successfully, then the server side script
// may have decided to tell the parent window to close the popup dialog.
if (settings.closeOverlay) {
parent.Drupal.overlay.bindChild(window, true);
// Use setTimeout to close the child window from a separate thread,
// because the current one is busy processing Drupal behaviors.
setTimeout(function () {
if (typeof settings.redirect === 'string') {
parent.Drupal.overlay.redirect(settings.redirect);
}
else {
parent.Drupal.overlay.close();
}
}, 1);
return;
}
// If one of the regions displaying outside the overlay needs to be
// reloaded immediately, let the parent window know.
if (settings.refreshRegions) {
parent.Drupal.overlay.refreshRegions(settings.refreshRegions);
}
// Ok, now we can tell the parent window we're ready.
parent.Drupal.overlay.bindChild(window);
// IE8 crashes on certain pages if this isn't called; reason unknown.
window.scrollTo(window.scrollX, window.scrollY);
// Attach child related behaviors to the iframe document.
Drupal.overlayChild.attachBehaviors(context, settings);
// There are two links within the message that informs people about the
// overlay and how to disable it. Make sure both links are visible when
// either one has focus and add a class to the wrapper for styling purposes.
$(context).find('#overlay-disable-message')
.focusin(function () {
$(this).addClass('overlay-disable-message-focused')
.find('a.focusable').removeClass('visually-hidden');
})
.focusout(function () {
$(this).removeClass('overlay-disable-message-focused')
.find('a.focusable').addClass('visually-hidden');
});
}
};
/**
* Overlay object for child windows.
*/
Drupal.overlayChild = Drupal.overlayChild || {
behaviors: {}
};
Drupal.overlayChild.prototype = {};
/**
* Attach child related behaviors to the iframe document.
*/
Drupal.overlayChild.attachBehaviors = function (context, settings) {
var behavior, behaviors = this.behaviors;
for (behavior in behaviors) {
if (behaviors.hasOwnProperty(behavior)) {
behaviors[behavior](context, settings);
}
}
};
/**
* Capture and handle clicks.
*
* Instead of binding a click event handler to every link we bind one to the
* document and handle events that bubble up. This also allows other scripts
* to bind their own handlers to links and also to prevent overlay's handling.
*/
Drupal.overlayChild.behaviors.addClickHandler = function (context, settings) {
$(document).bind('click.drupal-overlay mouseup.drupal-overlay', $.proxy(parent.Drupal.overlay, 'eventhandlerOverrideLink'));
};
/**
* Modify forms depending on their relation to the overlay.
*
* By default, forms are assumed to keep the flow in the overlay. Thus their
* action attribute get a ?render=overlay suffix.
*/
Drupal.overlayChild.behaviors.parseForms = function (context, settings) {
$(context).find('form').once('overlay', function () {
// Obtain the action attribute of the form.
var action = $(this).attr('action');
// Keep internal forms in the overlay.
if (typeof action === 'undefined' || (action.indexOf('http') !== 0 && action.indexOf('https') !== 0)) {
action += (action.indexOf('?') > -1 ? '&' : '?') + 'render=overlay';
$(this).attr('action', action);
}
// Submit external forms into a new window.
else {
$(this).attr('target', '_new');
}
});
};
/**
* Replace the overlay title with a message while loading another page.
*/
Drupal.overlayChild.behaviors.loading = function (context, settings) {
var $title;
var text = Drupal.t('Loading');
var dots = '';
$(document).bind('drupalOverlayBeforeLoad.drupal-overlay.drupal-overlay-child-loading', function () {
$title = $('#overlay-title').text(text);
setInterval(function () {
dots = (dots.length > 10) ? '' : dots + '.';
$title.text(text + dots);
}, 500);
});
};
/**
* Switch active tab immediately.
*/
Drupal.overlayChild.behaviors.tabs = function (context, settings) {
var $tabsLinks = $('#overlay-tabs > li > a');
$('#overlay-tabs > li > a').bind('click.drupal-overlay', function () {
var active_tab = Drupal.t('(active tab)');
$tabsLinks.parent().siblings().removeClass('active').find('visually-hidden:contains(' + active_tab + ')').appendTo(this);
$(this).parent().addClass('active');
});
};
/**
* If the shortcut add/delete button exists, move it to the overlay titlebar.
*/
Drupal.overlayChild.behaviors.shortcutAddLink = function (context, settings) {
// Remove any existing shortcut button markup from the titlebar.
$('#overlay-titlebar').find('.add-or-remove-shortcuts').remove();
// If the shortcut add/delete button exists, move it to the titlebar.
var $addToShortcuts = $('.add-or-remove-shortcuts');
if ($addToShortcuts.length) {
$addToShortcuts.insertAfter('#overlay-title');
}
$(document).bind('drupalOverlayBeforeLoad.drupal-overlay.drupal-overlay-child-loading', function () {
$('#overlay-titlebar').find('.add-or-remove-shortcuts').remove();
});
};
Drupal.overlayChild.behaviors.bindDrupalViewportOffsetChangeEvent = function (context, settings) {
// Workaround because of the way jQuery events works.
// jQuery from the parent frame needs to be used to catch this event.
parent.jQuery(parent.document).on('drupalViewportOffsetChange', function (event, offsets) {
// Fires an event that the child iframe can listen to.
$(document).trigger('drupalViewportOffsetChange', offsets);
});
};
})(jQuery);