Index: modules/filter/filter.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/filter/filter.admin.inc,v retrieving revision 1.25 diff -u -r1.25 filter.admin.inc --- modules/filter/filter.admin.inc 8 Mar 2009 21:25:18 -0000 1.25 +++ modules/filter/filter.admin.inc 23 Apr 2009 09:26:34 -0000 @@ -85,6 +85,7 @@ $output .= drupal_render_children($form); drupal_add_tabledrag('text-format-order', 'order', 'sibling', 'text-format-order-weight'); + drupal_add_popbox('#text-format-order td:last-child a'); return $output; } Index: modules/block/block.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/block/block.admin.inc,v retrieving revision 1.35 diff -u -r1.35 block.admin.inc --- modules/block/block.admin.inc 11 Feb 2009 03:38:46 -0000 1.35 +++ modules/block/block.admin.inc 23 Apr 2009 09:26:34 -0000 @@ -81,8 +81,11 @@ if ($block['module'] == 'block') { $form[$key]['delete'] = array( '#markup' => l(t('delete'), - 'admin/build/block/delete/' . $block['delta']), + 'admin/build/block/delete/' . $block['delta'], + array('attributes' => array('class' => 'delete')) + ), ); + drupal_add_popbox('#blocks .delete'); } } Index: themes/garland/page.tpl.php =================================================================== RCS file: /cvs/drupal/drupal/themes/garland/page.tpl.php,v retrieving revision 1.24 diff -u -r1.24 page.tpl.php --- themes/garland/page.tpl.php 18 Feb 2009 14:28:25 -0000 1.24 +++ themes/garland/page.tpl.php 23 Apr 2009 09:26:34 -0000 @@ -47,12 +47,12 @@
- > +

>

-
+
Index: modules/menu/menu.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/menu/menu.admin.inc,v retrieving revision 1.45 diff -u -r1.45 menu.admin.inc --- modules/menu/menu.admin.inc 21 Apr 2009 09:31:31 -0000 1.45 +++ modules/menu/menu.admin.inc 23 Apr 2009 09:26:34 -0000 @@ -112,6 +112,7 @@ // 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'); + drupal_add_popbox('#menu-overview tbody tr td:last-child a'); } // Set the reset column. elseif ($item['module'] == 'system' && $item['customized']) { @@ -288,6 +289,7 @@ '#submit' => array('menu_item_delete_submit'), '#weight' => 10, ); + drupal_add_popbox('#edit-delete'); } else { $form['menu']['_path'] = array( Index: modules/node/node.pages.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.pages.inc,v retrieving revision 1.60 diff -u -r1.60 node.pages.inc --- modules/node/node.pages.inc 15 Apr 2009 13:28:08 -0000 1.60 +++ modules/node/node.pages.inc 23 Apr 2009 09:26:34 -0000 @@ -275,6 +275,7 @@ '#weight' => 15, '#submit' => array('node_form_delete_submit'), ); + drupal_add_popbox('#edit-delete'); } $form['#validate'][] = 'node_form_validate'; $form['#theme'] = array($node->type . '_node_form', 'node_form'); Index: modules/node/content_types.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/node/content_types.inc,v retrieving revision 1.64 diff -u -r1.64 content_types.inc --- modules/node/content_types.inc 26 Jan 2009 14:08:43 -0000 1.64 +++ modules/node/content_types.inc 23 Apr 2009 09:26:34 -0000 @@ -38,6 +38,7 @@ $rows[] = array(array('data' => t('No content types available.'), 'colspan' => '5', 'class' => 'message')); } + drupal_add_popbox('#content-area tbody tr td:last-child a'); return theme('table', $header, $rows); } Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.878 diff -u -r1.878 common.inc --- includes/common.inc 22 Apr 2009 09:45:02 -0000 1.878 +++ includes/common.inc 23 Apr 2009 09:26:34 -0000 @@ -2759,6 +2759,41 @@ drupal_add_js($settings, 'setting'); } +/* + * Attach the popbox behavior to the page. + */ +function drupal_add_popbox($selector = 'popbox', $options = array()) { + static $added = FALSE; + if (!$added & variable_get('popboxes_toggle', 1)) { + drupal_add_js('misc/jquery.form.js'); + drupal_add_js('misc/popbox.js'); + drupal_add_css('misc/popbox.css'); + + // Look in the current theme for popbox.js to override js themed elements. + global $custom_theme; + $theme = $custom_theme; + if (!$theme) { + $theme = variable_get('theme_default','none'); + } + $filepath = drupal_get_path('theme', $theme) . '/popbox.js'; + if (file_exists($filepath)) { + drupal_add_js($filepath); + } + + $added = TRUE; + } + static $added_selectors = array(); + if (!isset($added_selectors[$selector])) { + $settings = array( + 'popbox' => array( + $selector => $options, + ), + ); + drupal_add_js($settings, 'setting'); + $added_selectors[$selector] = TRUE; + } +} + /** * Aggregate JS files, putting them in the files directory. * Index: misc/popbox.css =================================================================== RCS file: misc/popbox.css diff -N misc/popbox.css --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ misc/popbox.css 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,41 @@ +/* $Id$ */ + +/** + * Ajax popbox dialog box styles + */ +#popbox-overlay { + position: absolute; + background: black; + z-index: 9; + top: 0; +} +#popbox-loading { + z-index: 10; + opacity: 0.75; + position: absolute; + background: url('progress.gif') repeat; + width: 300px; + height: 50px; + display: none; + border: 1px solid; +} +#popbox { + border: 1px solid black; + background: white; + position: absolute; + z-index: 10; + padding: 0.5em; + width: 600px; + overflow: auto; +} +#popbox-close { + float: right; +} + +/* Allow messages to be used as the title of the popbox */ +#popbox div.messages { + background: transparent; + border: none; + padding: 0; + margin: 0; +} Index: misc/popbox.js =================================================================== RCS file: misc/popbox.js diff -N misc/popbox.js --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ misc/popbox.js 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,401 @@ +// $Id$ +( function($) { + +/** + * popbox Modal Dialog API + * + * Provide an API for building and displaying JavaScript, in-page, popbox + * modal dialogs (lightbox style). Modality is provided by a fixed, + * semi-opaque div, positioned in front of the page contents. + * + * popboxes xhtml is themeable, but the outter most element must have + * id="popbox". + */ + +/** + * Create the popbox object/namespace. + */ +Drupal.popbox = function() {}; + +/** + * The theme must wrap its page content. + */ +Drupal.popbox.contentSelector = '#content-area'; + +/** + * The theme must wrap its page title. + */ +Drupal.popbox.titleSelector = '#page-title'; + +/** + * Attach the popbox behavior to the all the requested links on the page. + * + * @param context + * The jQuery object to apply the behaviors to. + * @param settings + * The local settings passed through the behavior. + */ +Drupal.behaviors.popbox = { + attach : function(context, settings) { + // Add keybinding to close popbox. + var $body = $('body'); + if (!$body.hasClass('popbox-processed')) { + $body.addClass('popbox-processed'); + $(document).bind('keydown', Drupal.popbox.keyHandle); + + // If we are on the status report page, run the selector test and report + // the result. + status = 'admin/reports/status'; + current = window.location.href; + if (current.substring(current.length - status.length) === status) { + Drupal.popbox.testContentSelector(); + } + } + + // Process all requested popboxes. + jQuery.each(settings.popbox, function(selector, options) { + // Only process an element once. + $(selector, context).not('.popbox-processed').each( function() { + var element = $(this).addClass('popbox-processed'); + // Determine whether to process it as a button or a link. + if (element.is('input')) { + // Attach ajaxForm submission to form. + var form = element.parents('form'); + form.ajaxForm({ + success: function(response, status) { + $title = $(Drupal.popbox.titleSelector, response); + $content = $(Drupal.popbox.contentSelector, response); + Drupal.popbox.showPopbox($title.html(), $content.html(), null, options.width); + } + }); + + // If submit button is NOT the popbox button, remove the ajaxForm submit. + // We need to do it this way so the submit button value is submitted with rest of form. + $('input:submit', form).not('.popbox-processed').click(function(e) { + form.ajaxFormUnbind(); + }); + } + else { + // Append note to link title (will show on hover). + var title = element.attr('title') || ''; + element.attr('title', title + Drupal.t('[popbox]')); + + // Attach the on-click popbox behavior to the element. + element.click(function(e) { + return Drupal.popbox.openPath(this, options); + }); + } + }); + }); + } +}; + +/** + * Generic dialog builder. Add a popbox to the page. + */ +Drupal.popbox.showPopbox = function(title, body, buttons, width) { + Drupal.popbox.addOverlay(); + var $popbox = $(Drupal.theme('popboxDialog', title, body, buttons)); + // Start with dialog off the side. Hiding it with display:none causes flash + // in FF2. + $popbox.css('left', '-9999px'); + if (width) { + $popbox.css('width', width); + } + $('body').append($popbox); // Add the popbox to the DOM. + + // Adding button functions + if (buttons) { + jQuery.each(buttons, function(id, button) { + $('#' + id).click(button.func); + }); + } + $('#popbox-close').click(Drupal.popbox.close); + $('.popbox-close').click( function() { + Drupal.popbox.close(); + return false; + }); + + // Center on the screen, adding in offsets if the window has been scrolled + var popboxWidth = $popbox.width(); + var windowWidth = $(window).width(); + var left = (windowWidth / 2) - (popboxWidth / 2) + Drupal.popbox.scrollLeft(); + + // Get popbox's height on the page. + // Need to do it this way, since we get visible flash in FF2 if popbox is + // not visible! + var popboxHeight = $popbox.height(); + var windowHeight = $(window).height(); + if (popboxHeight > (0.9 * windowHeight)) { // Must fit in 90% of window. + popboxHeight = 0.9 * windowHeight; + $popbox.height(popboxHeight); + } + var top = (windowHeight / 2) - (popboxHeight / 2) + Drupal.popbox.scrollTop(); + + // Position the popbox to be visible. + $popbox.css('top', top).css('left', left); + + // Focus on the first input element in the popbox window. + this.refocus(); + + // Remove the loading image. + Drupal.popbox.removeLoading(); + + return false; +}; + +/** + * Closes and removes the popbox. + */ +Drupal.popbox.removePopbox = function() { + $('#popbox').remove(); +}; + +/** + * Use Ajax to open the URL inside a popbox window. + * + * @param element + * Element that was clicked to open the popbox. + * @param options + * Hash of options controlling how the popbox interacts with the underlying page. + */ +Drupal.popbox.openPath = function(element, options) { + if (!Drupal.popbox.testContentSelector()) { + return false; + } + + // Let the user know something is happening + $('body').css("cursor", "wait"); + + Drupal.popbox.addOverlay(); + Drupal.popbox.addLoading(); + + // Broadcast popbox open path event. + var href = options.href ? options.href : element.href; + $(document).trigger('popbox_open_path', [ element, href ]); + + ajaxOptions = { + url: href, + success: function(page) { + $title = $(Drupal.popbox.titleSelector, page); + $content = $(Drupal.popbox.contentSelector, page); + Drupal.popbox.showPopbox($title.html(), $content.html(), null, + options.width); + }, + complete: function() { + // Return the cursor to normal state. + $('body').css("cursor", "auto"); + }, + error: function() { + Drupal.popbox.message("Unable to open: " + href); + } + }; + $.ajax(ajaxOptions); + + return false; +}; + +/** + * Simple popbox that functions like the browser's alert box. + */ +Drupal.popbox.message = function(title, message) { + message = message || ''; + var buttons = { + 'popbox_ok': { + title :Drupal.t('OK'), + func :Drupal.popbox.close + } + }; + Drupal.popbox.showPopbox(title, message, buttons); +}; + +/** + * Handle any special keys when popbox is active. + */ +Drupal.popbox.keyHandle = function(e) { + if (!e) { + e = window.event; + } + // Process the ESC key. + if (e.keyCode === 27) { + Drupal.popbox.close(); + } +}; + +/** + * Overlays the page content. + */ +Drupal.popbox.addOverlay = function() { + // Make sure that the overlay is only created once. + var $overlay = $('#popbox-overlay'); + if ($overlay.length === 0) { + // Create the overlay. + $overlay = $(Drupal.theme('popboxOverlay')); + $overlay.css('opacity', '0.4'); + + // Doing absolute positioning, so make overlay's size equal the entire body. + $doc = $(document); + $overlay.width($doc.width()).height($doc.height()); + $('body').prepend($overlay); + + // Close the popbox when the overlay is clicked. + $overlay.click(Drupal.popbox.close); + } +}; + +/** + * Removes the overlay element. + */ +Drupal.popbox.removeOverlay = function() { + $('#popbox-overlay').remove(); +}; + +/** + * Creates the loading graphic. + */ +Drupal.popbox.addLoading = function() { + // Only create the loading state if it doesn't already exist. + var $loading = $('#popbox-loading'); + if ($loading.length === 0) { + // Inject the loading markup. + $loading = $(Drupal.theme('popboxLoading')); + $('body').prepend($loading); + + // Center the loading graphic. + var width = $loading.width(); + var height = $loading.height(); + var left = ($(window).width() / 2) - (width / 2) + Drupal.popbox.scrollLeft(); + var top = ($(window).height() / 2) - (height / 2) + Drupal.popbox.scrollTop(); + $loading.css( { + 'top': top, + 'left': left, + 'display': 'block' + }); + } +}; + +/** + * Removes the loading state. + */ +Drupal.popbox.removeLoading = function() { + $('#popbox-loading').remove(); +}; + +/** + * Remove the Popbox, the loading state and the overlay. + */ +Drupal.popbox.close = function() { + Drupal.popbox.removePopbox(); + Drupal.popbox.removeLoading(); + Drupal.popbox.removeOverlay(); + return false; +}; + +/** + * Set the focus on the popbox to the first visible form element. + */ +Drupal.popbox.refocus = function() { + $focus = $('#popbox :input:visible:enabled:first'); + if ($focus.length === 0) { + $focus = $('#popbox-close a'); + } + $focus.focus(); +}; + +/** + * Get current position of the left side of the browser window. + * + * Copied from jQuery offset. + */ +Drupal.popbox.scrollLeft = function() { + return Math.max(document.documentElement.scrollLeft, document.body.scrollLeft); +}; + +/** + * Get current position of the top of the browser window. + * + * Copied from jQuery offset. + */ +Drupal.popbox.scrollTop = function() { + return Math.max(document.documentElement.scrollTop, document.body.scrollTop); +}; + +/** + * Warn the user if ajax will not work with the current theme. + */ +Drupal.popbox.testContentSelector = function() { + var error = ''; + if ($(Drupal.popbox.titleSelector).length !== 1) { + error += '
  • ' + Drupal.t('The page title must be wrapped in an element with id of "@titleSelector".', {'@titleSelector': Drupal.popbox.titleSelector}) + '
  • '; + } + if ($(Drupal.popbox.contentSelector).length !== 1) { + error += '
  • ' + Drupal.t('The page content must be wrapped in an element with id of "@contentSelector".', {'@contentSelector': Drupal.popbox.contentSelector}) + '
  • '; + } + if (error) { + title = Drupal.t('Popboxes not supported by theme'); + body = '

    ' + Drupal.t('You must do one of the following:') + '

    '; + Drupal.popbox.showPopbox(title, body); + return false; + } + return true; +}; + +/** + * Creates the popbox loading graphic markup. + */ +Drupal.theme.prototype.popboxLoading = function() { + return '
    '; +}; + +/** + * Creates the overlay markup. + */ +Drupal.theme.prototype.popboxOverlay = function() { + return '
    '; +}; + +Drupal.theme.prototype.popboxButton = function(title, id) { + return ''; +}; + +/** + * Creates the markup for the popbox dialog. + */ +Drupal.theme.prototype.popboxDialog = function(title, body, buttons) { + // var template = Drupal.settings.popbox.template; + var template = Drupal.theme('popboxTemplate'); + var popbox = template.replace('%title', title).replace('%body', body); + + var themedButtons = ''; + if (buttons) { + jQuery.each(buttons, function(id, button) { + themedButtons += Drupal.theme('popboxButton', button.title, id); + }); + } + popbox = popbox.replace('%buttons', themedButtons); + return popbox; +}; + +/** + * You can add all the elements you want to the basic theme, but only + * popbox-footer can be removed and still have functioning dialog boxes. + */ +Drupal.theme.prototype.popboxTemplate = function() { + var template; + template += '
    '; + template += '
    '; + template += ' '; + template += '

    %title

    '; + template += '
    '; + template += '
    %body
    '; + template += '
    %buttons
    '; + template += ' '; + template += '
    '; + return template; +}; + +})(jQuery);