Index: includes/form.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/form.inc,v retrieving revision 1.349 diff -u -p -r1.349 form.inc --- includes/form.inc 7 Jul 2009 22:32:17 -0000 1.349 +++ includes/form.inc 13 Jul 2009 13:16:54 -0000 @@ -1014,8 +1014,9 @@ function form_builder($form_id, $element // The #after_build flag allows any piece of a form to be altered // after normal input parsing has been completed. - if (isset($element['#after_build']) && !isset($element['#after_build_done'])) { - foreach ($element['#after_build'] as $function) { + if ((isset($element['#after_build']) || isset($form_state['complete form']['#after_build_recursive'])) && !isset($element['#after_build_done'])) { + $functions = array_merge(isset($element['#after_build']) ? $element['#after_build'] : array(), isset($form_state['complete form']['#after_build_recursive']) ? $form_state['complete form']['#after_build_recursive'] : array()); + foreach ($functions as $function) { $element = $function($element, $form_state); $element['#after_build_done'] = TRUE; } Index: modules/overlay/overlay-child.js =================================================================== RCS file: modules/overlay/overlay-child.js diff -N modules/overlay/overlay-child.js --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/overlay/overlay-child.js 10 Jul 2009 07:51:33 -0000 @@ -0,0 +1,120 @@ +// $Id: child.js,v 1.1.4.3 2009/06/17 15:16:26 markuspetrux Exp $ + +(function ($) { + +/** + * Overlay object for child windows. + */ +Drupal.overlayChild = Drupal.overlayChild || { + processed: false, + behaviors: {} +}; + +/** + * Use a Drupal behavior to attach the child dialog behavior so that it will be + * automatically attached to new content. + */ +Drupal.behaviors.overlayChild = { + attach: function(context) { + Drupal.overlayChild.attachBehavior(context); + } +}; + +/** + * Attach child dialog behavior. + */ +Drupal.overlayChild.attachBehavior = function(context) { + var self = Drupal.overlayChild; + var settings = Drupal.settings.overlayChild || {}; + + // Make sure this behavior is not processed more than once. + if (self.processed) { + return; + } + self.processed = true; + + // If we cannot reach the parent window, then we have nothing else todo here. + if (!self.isObject(parent.Drupal) || !self.isObject(parent.Drupal.overlay)) { + return; + } + + // If a form has been submitted successfully, then the server side script + // may have decided to tell us the parent window to close the popup dialog. + if (settings.closeOverlay) { + parent.Drupal.overlay.bindChild(window, true); + // Close the child window from a separate thread because the current + // one is busy processing Drupal behaviors. + setTimeout(function() { parent.Drupal.overlay.close(settings.args, settings.statusMessages); }, 1); + return; + } + + // Ok, now we can tell the parent window we're ready. + parent.Drupal.overlay.bindChild(window); + + // Install onBeforeUnload callback, if module is present. + if (self.isObject(Drupal.onBeforeUnload) && !Drupal.onBeforeUnload.callbackExists('overlayChild')) { + Drupal.onBeforeUnload.addCallback('overlayChild', function() { + // Tell the parent window we're unloading. + parent.Drupal.overlay.unbindChild(window); + }); + } + + // Attach child related behaviors to the iframed document. + self.attachBehaviors(context); +}; + +/** + * Check if the given variable is an object. + */ +Drupal.overlayChild.isObject = function(something) { + return (something !== null && typeof something === 'object'); +}; + +/** + * Attach child related behaviors to the iframed document. + */ +Drupal.overlayChild.attachBehaviors = function(context) { + $.each(this.behaviors, function() { + this(context); + }); +}; + +/** + * Add target="_new" to all external URLs. + */ +Drupal.overlayChild.behaviors.parseLinks = function(context) { + $('a:not(.overlay-processed)', context).addClass('overlay-processed').each(function() { + // Do not process links that have the class "overlay-exclude". + if ($(this).hasClass('overlay-exclude')) { + return; + } + // Obtain the href attribute of the link. + var href = $(this).attr('href'); + // Do not process links with an empty href, or that only have the fragment. + if (href.length <= 0 || href.charAt(0) == '#') { + return; + } + if (href.indexOf('http') != 0 && href.indexOf('https') != 0) { + // Keep internal linked pages in the overlay. + href += (href.indexOf('?') > -1 ? '&' : '?') + 'render=overlay'; + $(this).attr('href', href); + } + else { + $(this).attr('target', '_new'); + } + }); + $('form:not(.overlay-processed)', context).addClass('overlay-processed').each(function() { + // Obtain the action attribute of the form. + var action = $(this).attr('action'); + if (action.indexOf('http') != 0 && action.indexOf('https') != 0) { + // Keep internal forms in the overlay. + action += (action.indexOf('?') > -1 ? '&' : '?') + 'render=overlay'; + $(this).attr('action', action); + } + else { + $(this).attr('target', '_new'); + } + }); +}; + +})(jQuery); Index: modules/overlay/overlay-parent.css =================================================================== RCS file: modules/overlay/overlay-parent.css diff -N modules/overlay/overlay-parent.css --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/overlay/overlay-parent.css 13 Jul 2009 12:08:52 -0000 @@ -0,0 +1,179 @@ +/* $Id$ */ + +/** + * jQuery UI Dialog classes. + */ +.overlay { + color: #000; + padding-right: 30px; +} + +.overlay .ui-dialog-titlebar { + position: relative; + height: 30px; + white-space: nowrap; + z-index: 2; +} + +.overlay .ui-dialog-title { + display: block; + position: absolute; + top: 0; + left: 0; + margin: 0.2em 0.5em; + padding: 0; + color: #fff; + font-size: 20px; +} + +.overlay .ui-dialog-titlebar-close { + display: block; + position: absolute; + right: -26px; + top: 30px; + margin: 0; + padding: 0; + width: 26px; + height: 26px; +} + +.overlay .ui-dialog-titlebar-close-bg { + background: transparent url(images/close.png) no-repeat; + width: 32px; + height: 36px; + position: absolute; + right: -32px; + top: 30px; + opacity: 0; + filter: alpha(opacity=0); +} + +.overlay .ui-dialog-titlebar-close span { + display: none; +} + +.overlay .ui-dialog-content { + color: #292929; + background-color: #f8f8f8; +} + +/** + * ui-dialog overlay. + */ +.ui-widget-overlay { + position: absolute; + top: 0; left: 0; + width: 100%; height: 100%; + background-color: #000; + opacity: 0.8; + filter: alpha(opacity=80); +} + +/** + * Overlay content and shadows. + */ +#overlay-container { + margin: 0; + padding: 0; + background: #fff url(images/loading.gif) no-repeat 50% 50%; +} + +#overlay-container div.overlay-shadow { + position: absolute; + z-index: 1; + opacity: 0; + filter: alpha(opacity=0); +} + +#overlay-container div.overlay-shadow-bottom { + height: 15px; + background: transparent url(images/ovrly-shdw-bt.png) repeat-x; + margin: -5px 0 0 15px; + position: relative; +} + +#overlay-element { + margin: 0; + padding: 0; + border: none; +} + +#overlay-container div.overlay-shadow-right { + top: 30px; + right: 15px; + width: 15px; + background: transparent url(images/ovrly-shdw-rt.png) repeat-y; +} + +#overlay-container div.overlay-shadow-bottom-right { + bottom: -15px; + left: 0px; + width: 15px; + height: 15px; + background: transparent url(images/ovrly-shdw-bt-rt.png) no-repeat; +} + +#overlay-container div.overlay-shadow-bottom-left { + top: 0px; + left: -15px; + width: 15px; + height: 15px; + background: transparent url(images/ovrly-shdw-bt-lt.png) no-repeat; +} + +/** + * Tabs on the overlay. + */ +.ui-dialog-titlebar ul { + float: right; + border-bottom: none; + margin: 0 20px 0 0; + padding: 9px 0 0; + line-height: normal; + text-transform: uppercase; + font-size: 12px; +} + +.ui-dialog-titlebar ul li { + display: inline; + list-style: none; + margin-left: 1px; +} + +.ui-dialog-titlebar ul li { + background: transparent url(images/tab_inactive_rt.png) no-repeat top right; + padding: 4px 8px 7px 0; +} + +.ui-dialog-titlebar ul li a, +.ui-dialog-titlebar ul li a.active, +.ui-dialog-titlebar ul li a:active, +.ui-dialog-titlebar ul li a:visited { + background: transparent url(images/tab_inactive_lt.png) no-repeat; + color: #000; + font-weight: bold; + padding: 4px 15px 7px 20px; + text-decoration: none; +} + +.ui-dialog-titlebar ul li.active { + background: transparent url(images/tab_active_rt.png) no-repeat top right; +} + +.ui-dialog-titlebar ul li.active a, +.ui-dialog-titlebar ul li.active a.active, +.ui-dialog-titlebar ul li.active a:active, +.ui-dialog-titlebar ul li.active a:visited { + background: transparent url(images/tab_active_lt.png) no-repeat; + color: #000; + font-weight: bold; + padding: 4px 15px 7px 20px; +} + +.ui-dialog-titlebar ul li a:hover { + color: #fff; +} + +.ui-dialog-titlebar ul li.active a:hover { + color: #000; +} Index: modules/overlay/overlay-parent.js =================================================================== RCS file: modules/overlay/overlay-parent.js diff -N modules/overlay/overlay-parent.js --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/overlay/overlay-parent.js 13 Jul 2009 12:08:52 -0000 @@ -0,0 +1,504 @@ +// $Id: parent.js,v 1.1.4.4 2009/06/19 15:32:57 markuspetrux Exp $ + +(function ($) { + +Drupal.behaviors.keepOverlay = { + attach: function(context) { + + // Attach on the .to-overlay class. + $('a.to-overlay:not(.overlay-processed)').addClass('overlay-processed').click(function() { + + // Remove the active class from where it was, and add the active class to + // this link, so the button keeps highlighting where we are. Only + // highlight active items in the shortcuts bar. + $('#toolbar a').each(function() { + $(this).removeClass('active'); + }); + if ($(this).parents('div.toolbar-shortcuts').length) { + $(this).addClass('active'); + } + + // Append render variable, so the server side can choose the right + // rendering and add child modal frame code to the page if needed. + var linkURL = $(this).attr('href'); + linkURL += (linkURL.indexOf('?') > -1 ? '&' : '?') + 'render=overlay'; + + // If the modal frame is already open, replace the loaded document with + // this new one. Keeps browser history. + if (Drupal.overlay.isOpen) { + Drupal.overlay.load(linkURL); + return false; + } + + // There is overlay opened yet, we should open a new one. + var toolbarHeight = $('#toolbar').height(); + var overlayOptions = { + url: linkURL, + width: $(window).width() - 40, + height: $(window).height() - 40 - toolbarHeight, + // Remove active class from all header buttons. + onOverlayClose: function() { $('#toolbar a').each(function() { $(this).removeClass('active'); }); } + }; + Drupal.overlay.open(overlayOptions); + + // Set position and styling to let the admin toolbar work. + $('.overlay').css('top', toolbarHeight + 20); + $('#toolbar').css('z-index', 2000); + + // Prevent default action of the link click event. + return false; + }); + } +}; + +/** + * Overlay object for parent windows. + */ +Drupal.overlay = Drupal.overlay || { + options: {}, + iframe: { $container: null, $element: null }, + isOpen: false +}; + +/** + * Open an overlay. + */ +Drupal.overlay.open = function(options) { + var self = this; + + // Just one overlay is allowed. + if (self.isOpen || $('#overlay-container').size()) { + return false; + } + + // Build overlay frame options structure. + self.options = { + url: options.url, + width: options.width, + height: options.height, + autoFit: (options.autoFit == undefined || options.autoFit), + onOverlayClose: options.onOverlayClose + }; + + // Create the dialog and related DOM elements. + self.create(options); + + // Open the dialog offscreen where we can set its size, etc. + self.iframe.$container.dialog('option', {position: ['-999em', '-999em']}).dialog('open'); + + return true; +}; + +/** + * Create the overlay. + */ +Drupal.overlay.create = function() { + var self = this; + + // Note: We use scrolling="yes" for IE as a workaround to yet another IE bug + // where the horizontal scrollbar is always rendered no matter how wide the + // iframe element is defined. + self.iframe.$element = $('