';
}
$description .= drupal_render($form['description'][$key]);
if (isset($form['status']['#incompatible_modules_core'][$key])) {
Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.272
diff -u -r1.272 form.inc
--- includes/form.inc 6 May 2008 12:18:45 -0000 1.272
+++ includes/form.inc 8 May 2008 01:23:25 -0000
@@ -435,7 +435,9 @@
// however, we'll skip this and let the calling function examine
// the resulting $form_state bundle itself.
if (!$form['#programmed'] && empty($form_state['rebuild']) && empty($form_state['storage'])) {
- drupal_redirect_form($form, $form_state['redirect']);
+ global $request_mode;
+ // TODO - more comments here, and update the above comments.
+ module_invoke_all('after_process_form', $request_mode, $form, $form_state);
}
}
}
@@ -608,8 +610,13 @@
* @param $redirect
* An optional value containing the destination path to redirect
* to if none is specified by the form.
+ * @param $do_goto
+ * Boolean flag.
+ * If true, call to drupal_goto to do the redirect.
+ * If false, return the URL of the redirect, but don't go there. This allows
+ * for alternal flows of control, such as AJAX or webservices.
*/
-function drupal_redirect_form($form, $redirect = NULL) {
+function drupal_redirect_form($form, $redirect = NULL, $do_goto = TRUE) {
$goto = NULL;
if (isset($redirect)) {
$goto = $redirect;
@@ -617,17 +624,31 @@
if ($goto !== FALSE && isset($form['#redirect'])) {
$goto = $form['#redirect'];
}
- if (!isset($goto) || ($goto !== FALSE)) {
- if (isset($goto)) {
- if (is_array($goto)) {
- call_user_func_array('drupal_goto', $goto);
+ if (!isset($goto) || ($goto !== FALSE)) {
+ // If $do_goto is set, call drupal_goto and do the redirect & exit.
+ if ($do_goto) {
+ if (isset($goto)) {
+ if (is_array($goto)) {
+ call_user_func_array('drupal_goto', $goto);
+ }
+ else {
+ drupal_goto($goto);
+ }
}
- else {
- drupal_goto($goto);
+ drupal_goto($_GET['q']);
+ }
+ else { // If $do_goto is false, just calculate and return the next url.
+ if (isset($goto)) {
+ if (is_array($goto)) {
+ return call_user_func_array('drupal_get_goto_url', $goto);
+ }
+ else {
+ return drupal_get_goto_url($goto);
+ }
}
+ return drupal_get_goto_url($_GET['q']);
}
- drupal_goto($_GET['q']);
- }
+ }
}
/**
Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.inc,v
retrieving revision 1.422
diff -u -r1.422 theme.inc
--- includes/theme.inc 6 May 2008 12:18:45 -0000 1.422
+++ includes/theme.inc 8 May 2008 01:23:25 -0000
@@ -465,7 +465,7 @@
}
/**
- * Generate the themed output.
+ * Generate the themed output for the current rendering mode.
*
* All requests for theme hooks must go through this function. It examines
* the request and routes it to the appropriate theme function. The theme
@@ -549,9 +549,41 @@
* @param ...
* Additional arguments to pass along to the theme function.
* @return
- * An HTML string that generates the themed output.
+ * An string that generates the themed output according to the current render
+ * mode. HTML is the default output.
*/
function theme() {
+ global $render_mode;
+ $args = func_get_args();
+
+ // Check if we're using a custom render mode.
+ if ($render_mode != 'xhtml/plain') {
+ static $theme_renderers;
+ if (!isset($theme_renderers)) {
+ $theme_renderers = module_invoke_all('theme_modes');
+ }
+ $theme_renderer = isset($theme_renderers[$render_mode]) ? $theme_renderers[$render_mode] : NULL;
+
+ // If a different theme rendering system is available, call it instead of the default.
+ if (function_exists($theme_renderer)) {
+ return call_user_func_array($theme_renderer, $args);
+ }
+ }
+
+ // If not using a custom render mode, use the default renderer.
+ return call_user_func_array('theme_render', $args);
+}
+
+/**
+ * The default theme mode renderer. Generates the HTML output for most requests.
+ *
+ * Invokes the theme system and generates the page layout when making a normal
+ * page request. This function is called by theme() when using the default
+ * rendering mode.
+ *
+ * @see theme()
+ */
+function theme_render() {
$args = func_get_args();
$hook = array_shift($args);
@@ -1451,7 +1483,7 @@
* Returns code that emits the 'more help'-link.
*/
function theme_more_help_link($url) {
- return '
' . l(t('More information about formatting options'), 'filter/tips') . '
';
+ return '
' . l(t('More information about formatting options'), 'filter/tips', array('attributes' => array('class' => 'popup'))) . '
';
}
/**
Index: modules/node/content_types.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/content_types.inc,v
retrieving revision 1.52
diff -u -r1.52 content_types.inc
--- modules/node/content_types.inc 14 Apr 2008 17:48:38 -0000 1.52
+++ modules/node/content_types.inc 8 May 2008 01:23:25 -0000
@@ -10,6 +10,7 @@
* Displays the content type admin overview page.
*/
function node_overview_types() {
+ drupal_add_popup();
$types = node_get_types();
$names = node_get_types('names');
$header = array(t('Name'), t('Type'), t('Description'), array('data' => t('Operations'), 'colspan' => '2'));
@@ -29,7 +30,7 @@
// Set the delete column.
if ($type->custom) {
- $row[] = array('data' => l(t('delete'), 'admin/content/node-type/' . $type_url_str . '/delete'));
+ $row[] = array('data' => l(t('delete'), 'admin/content/node-type/' . $type_url_str . '/delete', array('attributes' => array('class' => 'popup-form'))));
}
else {
$row[] = array('data' => '');
Index: modules/path/path.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/path/path.admin.inc,v
retrieving revision 1.8
diff -u -r1.8 path.admin.inc
--- modules/path/path.admin.inc 14 Apr 2008 17:48:38 -0000 1.8
+++ modules/path/path.admin.inc 8 May 2008 01:23:25 -0000
@@ -41,7 +41,12 @@
$rows = array();
$destination = drupal_get_destination();
while ($data = db_fetch_object($result)) {
- $row = array(check_plain($data->dst), check_plain($data->src), l(t('edit'), "admin/build/path/edit/$data->pid", array('query' => $destination)), l(t('delete'), "admin/build/path/delete/$data->pid", array('query' => $destination)));
+ $row = array(
+ check_plain($data->dst),
+ check_plain($data->src),
+ l(t('edit'), "admin/build/path/edit/$data->pid", array('query' => $destination)),
+ l(t('delete'), "admin/build/path/delete/$data->pid", array('query' => $destination, 'attributes' => array('class' => 'popup-form')))
+ );
if ($multilanguage) {
$row[4] = $row[3];
$row[3] = $row[2];
Index: modules/block/block.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.admin.inc,v
retrieving revision 1.16
diff -u -r1.16 block.admin.inc
--- modules/block/block.admin.inc 16 Apr 2008 11:35:51 -0000 1.16
+++ modules/block/block.admin.inc 8 May 2008 01:23:25 -0000
@@ -30,6 +30,7 @@
// Add CSS
drupal_add_css(drupal_get_path('module', 'block') . '/block.css', 'module', 'all', FALSE);
+ drupal_add_popup();
// If non-default theme configuration has been selected, set the custom theme.
$custom_theme = isset($theme) ? $theme : variable_get('theme_default', 'garland');
@@ -71,7 +72,7 @@
);
$form[$key]['configure'] = array('#value' => l(t('configure'), 'admin/build/block/configure/' . $block['module'] . '/' . $block['delta']));
if ($block['module'] == 'block') {
- $form[$key]['delete'] = array('#value' => l(t('delete'), 'admin/build/block/delete/' . $block['delta']));
+ $form[$key]['delete'] = array('#value' => l(t('delete'), 'admin/build/block/delete/' . $block['delta'], array('attributes' => array('class' => 'popup-form'))));
}
}
Index: modules/menu/menu.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/menu/menu.admin.inc,v
retrieving revision 1.30
diff -u -r1.30 menu.admin.inc
--- modules/menu/menu.admin.inc 14 Apr 2008 17:48:37 -0000 1.30
+++ modules/menu/menu.admin.inc 8 May 2008 01:23:25 -0000
@@ -61,6 +61,7 @@
*/
function _menu_overview_tree_form($tree) {
static $form = array('#tree' => TRUE);
+ drupal_add_popup();
foreach ($tree as $data) {
$title = '';
$item = $data['link'];
@@ -97,11 +98,11 @@
$operations['edit'] = l(t('edit'), 'admin/build/menu/item/' . $item['mlid'] . '/edit');
// Only items created by the menu module can be deleted.
if ($item['module'] == 'menu' || $item['updated'] == 1) {
- $operations['delete'] = l(t('delete'), 'admin/build/menu/item/' . $item['mlid'] . '/delete');
+ $operations['delete'] = l(t('delete'), 'admin/build/menu/item/' . $item['mlid'] . '/delete', array('attributes' => array('class' => 'popup-form')));
}
// Set the reset column.
elseif ($item['module'] == 'system' && $item['customized']) {
- $operations['reset'] = l(t('reset'), 'admin/build/menu/item/' . $item['mlid'] . '/reset');
+ $operations['reset'] = l(t('reset'), 'admin/build/menu/item/' . $item['mlid'] . '/reset', array('attributes' => array('class' => 'popup-form')));
}
$form[$mlid]['operations'] = array();
Index: misc/popup.js
===================================================================
RCS file: misc/popup.js
diff -N misc/popup.js
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ misc/popup.js 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,461 @@
+// $Id:$
+
+/**
+ * Popup Modal Dialog API
+ *
+ * Provide an API for building and displaying JavaScript, in-page, popup modal dialogs.
+ * Modality is provided by a fixed, semi-opaque div, positioned in front of the page contents.
+ *
+ */
+
+/**
+ * Attach the popup bevior to the all the requested links on the page.
+ *
+ * @param context
+ * The jQuery object to apply the behaviors to.
+ */
+Drupal.behaviors.popup = function(context) {
+ var $body = $('body');
+ if(!$body.hasClass('popup-processed')) {
+ $(document).bind('keydown', Drupal.popup.keyHandle);
+ $body.addClass('popup-processed');
+ }
+ Drupal.popup.attach(context, 'a.popup', {});
+ Drupal.popup.attach(context, 'a.popup-form', {updatePage: true});
+ Drupal.popup.attach(context, 'a.popup-nonmodal', {nonModal: true});
+};
+
+/**
+ * Create the popup object/namespace.
+ */
+Drupal.popup = function() {};
+
+/**
+ * Attach the popup behavior to a particular link.
+ *
+ * @param selector
+ * jQuery selector for links to attach popup behavior to.
+ * @param options
+ * Hash of options associated with these links.
+ */
+Drupal.popup.attach = function(context, selector, options) {
+ $(selector, context).not('.popup-processed').each( function() {
+ var $link = $(this);
+ $link.click( function(e){
+ var a = this;
+ // If the option is distructive, check if the page is already modified, and offer to save.
+ var pageIsDirty = $('span.tabledrag-changed').size() > 0;
+ var willModifyOriginal = options.updatePage;
+ if( pageIsDirty && willModifyOriginal ) {
+ // The user will lose modifications, so popup dialog offering to save current state.
+ $.getJSON(Drupal.settings.basePath + 'popup/save_dialog', function(json) {
+ // Attach behaviors to the buttons in the save-if-modified dialog.
+ var buttons = {
+ 'popup_save': {title: json.buttons.save, func: function(){Drupal.popup.savePage(a, options);}},
+ 'popup_submit': {title: json.buttons.submit, func: function(){Drupal.popup.removePopup(); Drupal.popup.openPath(a, options);}},
+ 'popup_cancel': {title: json.buttons.cancel, func: Drupal.popup.close}
+ };
+ Drupal.popup.open(json.title, json.content, buttons);
+ });
+ return false;
+ }
+ else {
+ return Drupal.popup.openPath(a, options);
+ }
+ });
+ var title = $link.attr('title') || '';
+ $link.attr('title', title + Drupal.t('[Popup]')); // Append note to link title.
+ $link.addClass('popup-processed');
+ });
+};
+
+
+/**
+ * Generic dialog builder.
+ */
+Drupal.popup.open = function(title, body, buttons) {
+
+ Drupal.popup.addOverlay(); // TODO - nonModal option.
+ var $popup = $(Drupal.theme('popupDialog', title, body, buttons));
+ // Start with dialog off the side. Making it invisible causes flash in FF2.
+ $popup.css('left', '-9999px');
+ $('body').append( $popup ); // Add the popup to the DOM.
+
+ // Adding button functions
+ if (buttons) {
+ for (var id in buttons) {
+ if (buttons[id]) { // to make jslint happy.
+ var func = buttons[id].func;
+ $('#'+id).click( func );
+ }
+ }
+ }
+ $('#popup-close').click( Drupal.popup.close );
+ $('a.popup-close').click( Drupal.popup.close );
+
+ // center on the screen, adding in offsets if the window has been scrolled
+ var popupWidth = $popup.width();
+ var windowWidth = $(window).width();
+ var left = (windowWidth / 2) - (popupWidth / 2) + Drupal.popup.scrollLeft();
+
+ // Get popup's height on the page.
+ // Causes flash in FF2 if popup is not visible!
+ var popupHeight = $popup.height();
+ var windowHeight = $(window).height();
+ if (popupHeight > (0.9 * windowHeight) ) { // Must fit in 90% of window.
+ popupHeight = 0.9 * windowHeight;
+ $popup.height(popupHeight);
+ }
+ var top = (windowHeight / 2) - (popupHeight / 2) + Drupal.popup.scrollTop();
+
+ $popup.css('top', top).css('left', left); // Position the popup to be visible.
+
+ this.refocus(); // TODO: capture the focus when it leaves the dialog.
+ Drupal.popup.removeLoading(); // Remove the loading img.
+
+ return false;
+};
+
+/**
+ * Simple popup that functions like the browser's alert box.
+ */
+Drupal.popup.message = function(message, body) {
+ body = body || '';
+ var buttons = {
+ 'popup_ok': { title: Drupal.t('OK'), func: Drupal.popup.close }
+ };
+ Drupal.popup.open( message, body, buttons );
+};
+
+/**
+ * Handle any special keys when popup is active.
+ */
+Drupal.popup.keyHandle = function(e) {
+ if (!e) {
+ e = window.event;
+ }
+ switch (e.keyCode) {
+ case 27: // esc
+ Drupal.popup.close();
+ break;
+ case 191: // '?' key, show help.
+ if (e.shiftKey && e.ctrlKey) {
+ var $help = $('a.popup.more-help');
+ if ($help.size()) {
+ $help.click();
+ }
+ else {
+ Drupal.popup.message(Drupal.t("Sorry, there is no additional help for this page"));
+ }
+ }
+ break;
+ }
+};
+
+/*****************************************************************************
+ * Appearence Functions (overlay, loading graphic, remove popup) *********
+ *****************************************************************************/
+
+Drupal.popup.removePopup = function() {
+ $('#popup').remove();
+};
+
+Drupal.popup.addOverlay = function() {
+ var $overlay = $('#popup-overlay');
+ if (!$overlay.size()) { // Overlay does not already exist, so create it.
+ $overlay = $(Drupal.theme('popupOverlay'));
+ $overlay.css('opacity', '0.4'); // for ie6(?)
+ $body = $('body');
+ // Doing absolute positioning, so make overlay's size equal the entire body.
+ $overlay.width($body.width()).height($body.height());
+ $overlay.click(Drupal.popup.close);
+ $body.prepend($overlay);
+ }
+// return $overlay;
+};
+
+//Drupal.popup.getOverlay = function() {
+// return $('#popup-overlay');
+//};
+
+Drupal.popup.removeOverlay = function() {
+ $('#popup-overlay').remove();
+};
+
+Drupal.popup.addLoading = function() {
+ var $loading = $('#popup-loading');
+ if (!$loading.size()) { // Overlay does not already exist, so create it.
+ var waitImageSize = 100;
+ var left = ($(window).width() / 2) - (waitImageSize / 2) + Drupal.popup.scrollLeft();
+ var top = ($(window).height() / 2) - (waitImageSize / 2) + Drupal.popup.scrollTop();
+ $loading = $( Drupal.theme('popupLoading', left, top) );
+ $('body').prepend($loading);
+ }
+};
+
+Drupal.popup.removeLoading = function() {
+ $('#popup-loading').remove();
+};
+
+/**
+ * Remove everything.
+ */
+Drupal.popup.close = function() {
+ Drupal.popup.removePopup();
+ Drupal.popup.removeLoading();
+ Drupal.popup.removeOverlay();
+};
+
+/**
+ * Set the focus on the popup to the first visible form element, or the first button, or the close link.
+ */
+Drupal.popup.refocus = function() {
+ $focus = $('#popup input:visible:eq(0)');
+ if (!focus) {
+ $focus = $('#popup-close'); // Doesn't seem to work.
+ }
+ $focus.focus();
+};
+
+/****************************************************************************
+ * Theme Functions ********************************************************
+ ****************************************************************************/
+
+Drupal.theme.prototype.popupLoading = function(left, top) {
+ var loading = '
';
+ loading += '
';
+ loading += '';
+ loading += '
';
+ return loading;
+};
+
+Drupal.theme.prototype.popupOverlay = function() {
+ return '';
+};
+
+Drupal.theme.prototype.popupButton = function(title, id) {
+ return '';
+};
+
+Drupal.theme.prototype.popupDialog = function(title, body, buttons) {
+ var template = Drupal.settings.popup.template;
+ var popup = template.replace('%title', title).replace('%body', body);
+
+ var themedButtons = '';
+ for ( var id in buttons) {
+ if (buttons[id]) {
+ themedButtons += Drupal.theme('popupButton', buttons[id].title, id);
+ }
+ }
+ popup = popup.replace('%buttons', themedButtons);
+ return popup;
+};
+
+/****************************************************************************
+ * Utility scroll functions taken from: ***
+ * http://www.softcomplex.com/docs/get_window_size_and_scrollbar_position.html
+ ****************************************************************************/
+
+// FROM jQuery offset
+// elem = this[0];
+// doc = elem.ownerDocument;
+// add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
+// box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));
+
+Drupal.popup.scrollLeft = function() {
+ return Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);
+// return Drupal.popup.filterResults (
+// window.pageXOffset ? window.pageXOffset : 0,
+// document.documentElement ? document.documentElement.scrollLeft : 0,
+// document.body ? document.body.scrollLeft : 0 );
+};
+
+Drupal.popup.scrollTop = function() {
+ return Math.max(document.documentElement.scrollTop, document.body.scrollTop);
+// return Drupal.popup.filterResults (
+// window.pageYOffset ? window.pageYOffset : 0,
+// document.documentElement ? document.documentElement.scrollTop : 0,
+// document.body ? document.body.scrollTop : 0 );
+};
+
+Drupal.popup.filterResults = function(win, docel, body) {
+ var result = win ? win : 0;
+ if (docel && (!result || (result > docel))) {
+ result = docel;
+ }
+ return body && (!result || (result > body)) ? body : result;
+};
+
+
+/****************************************************************************
+ * Page & Form in popup functions ***
+ ****************************************************************************/
+
+/**
+ * Use Ajax to open the link in a popup window.
+ *
+ * @param a
+ * Link that was clicked to open the popup.
+ * @param options
+ * Hash of options controlling how the popup interacts with the underlying page.
+ */
+Drupal.popup.openPath = function(a, options) {
+ // let the user know something is happening
+ $('body').css("cursor", "wait");
+
+ // TODO - get nonmodal working.
+ if (!options.nonModal) {
+ Drupal.popup.addOverlay();
+ }
+ Drupal.popup.addLoading();
+
+ // Set custom headers for all following requests.
+ $.ajaxSetup({
+ beforeSend: function(xhr) {
+ xhr.setRequestHeader("X-Drupal-Render-Mode", 'json/popup');
+ }
+ });
+
+ $.getJSON(a.href, function(json) {
+ Drupal.popup.openContent(json.title, json.messages + json.content, options);
+ $('body').css("cursor", "auto"); // Return the cursor to normal state.
+ });
+
+ return false;
+};
+
+/**
+ * Open content in an ajax popup.
+ *
+ * @param title
+ * String title of the popup.
+ * @param content
+ * HTML to show in the popup.
+ * @param options
+ * Hash of options controlling how the popup interacts with the underlying page.
+ */
+Drupal.popup.openContent = function(title, content, options) {
+ Drupal.popup.open(title, content);
+ // Add behaviors to content in popup.
+ // TODO: d-n-d: need to click to let go of selection.
+ Drupal.attachBehaviors($('#popup-body'));
+ // Adding collapse moves focus.
+ Drupal.popup.refocus();
+
+ // If the popup contains a form, capture submits.
+ var $form = $('form', '#popup-body');
+ $form.ajaxForm({
+ dataType: 'json',
+ beforeSubmit: Drupal.popup.beforeSubmit,
+ success: function(response, status) {
+ Drupal.popup.formSuccess(response, options);
+ }
+ });
+};
+
+/**
+ * Do before the form in the popup is submitted.
+ */
+Drupal.popup.beforeSubmit = function(formData, $form, options) {
+ Drupal.popup.removePopup(); // Remove just the dialog, but not the overlay.
+ Drupal.popup.addLoading();
+};
+
+/**
+ * The form in the popup was successfully submitted
+ * Update the originating page.
+ * Show any messages in a popup (TODO - make this a configurable option).
+ *
+ * @param response
+ * JSON object from server with status of form submission.
+ * @param options
+ * Hash of options controlling how the popup interacts with the underlying page.
+ * //noReload: bool, does the popup effect the underlying page.
+ * updatePage: bool, does the popup effect the underlying page.
+ * updateTitle: bool, does the popup change the title of the page.
+ * nonModal: bool, does the popup block access to the underlying page.
+ * targetSelector: jQuery selector, overrides defaultTargetSelector.
+ */
+Drupal.popup.formSuccess = function(response, options) {
+ if (response.status != 'redirect') { // something went wrong
+ Drupal.popup.message( "Error: " + response.messages + response.content);
+ }
+ else { // Got a good response back from the server.
+ $.getJSON(response.path, function(data) {
+ // Determine if we are at an end point, or just moving from one popup to another.
+ if (!location.href.match(data.path)) { // Not done yet, so show results in new popup.
+ Drupal.popup.removeLoading();
+ Drupal.popup.openContent(data.title, data.messages + data.content, options);
+ }
+ else { // Done, so show messages in dialog and embed the results in the original page.
+ if (data.messages) {
+ Drupal.popup.message(data.messages);
+ // Also insert the message into the page above the content.
+ // Might not be the standard spot, but it is the easiest to find.
+ var $next = $(Drupal.settings.popup.defaultTargetSelector);
+ $next.parent().find('div.messages').remove(); // Remove the current messages.
+ $next.before(data.messages);
+ }
+
+ // Update the entire content area (defined by 'target selector').
+ if (options.updatePage) {
+ var target = options.targetSelector;
+ if (!target) {
+ target = Drupal.settings.popup.defaultTargetSelector;
+ }
+ // Update the original page.
+ var $c = $(target).html(data.content); // Inject the new content into the page.
+ Drupal.attachBehaviors($c);
+ }
+
+ // Update the title of the page.
+ if (options.updateTitle) {
+ $(Drupal.settings.popup.defaultTitleSelector).html(data.title);
+ document.title = data.title; // Also update the browser page title (TODO: include site name?).
+ }
+
+ // Done with changes to the original page, remove effects.
+ Drupal.popup.removeLoading();
+ if (!data.messages) {
+ // If there is not a messages popup remove the overlay.
+ Drupal.popup.removeOverlay();
+ }
+ } // End of updating original page.
+ }); // End of good response.
+ }
+};
+
+/**
+ * Submit the page and reload the results, before popping up the real dialog.
+ *
+ * @param a
+ * Link that was clicked to open the popup.
+ * @param options
+ * Hash of options controlling how the popup interacts with the underlying page.
+ */
+Drupal.popup.savePage = function(a, options) {
+ var target = Drupal.settings.popup.defaultTargetSelector;
+ var $form = $('form', target);
+ var ajaxOptions = {
+ dataType: 'json',
+ beforeSubmit: Drupal.popup.beforeSubmit,
+ success: function(response, status) {
+ // Sync up the current page contents with the submit.
+ $.ajax({
+ url: response.path,
+ dataType: 'json',
+ beforeSend: function(xhr) {
+ xhr.setRequestHeader("X-Drupal-Render-Mode", 'json/popup');
+ },
+ success: function(json) {
+ // Update the original page.
+ var $c = $(target).html(json.content); // Inject the new content into the page.
+ Drupal.attachBehaviors($c);
+ // The form has been saved and the page reloaded, now safe to open the clicked link in a popup.
+ Drupal.popup.openPath(a, options);
+ }
+ });
+ }
+ };
+ $form.ajaxSubmit(ajaxOptions); // Submit the form.
+};
Index: modules/system/popup.tpl.php
===================================================================
RCS file: modules/system/popup.tpl.php
diff -N modules/system/popup.tpl.php
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/system/popup.tpl.php 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,13 @@
+
+