Index: modules/system/system.css
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.css,v
retrieving revision 1.40
diff -u -r1.40 system.css
--- modules/system/system.css	16 Nov 2007 13:16:50 -0000	1.40
+++ modules/system/system.css	20 Nov 2007 02:02:46 -0000
@@ -537,3 +537,58 @@
 span.password-confirm span {
   font-weight: normal;
 }
+
+/*
+** Popup Dialog box styles
+*/
+
+#dialog-overlay {
+  position: fixed;
+  width: 100%;
+  height: 100%;
+/*  opacity: 0.4; */
+  background: black;
+  z-index: 9;  
+}
+
+#dialog-overlay .loading {
+    background: black url(../../misc/loading.gif) no-repeat;
+}  
+
+#dialog {
+  border: 1px solid black;
+  background: white;
+  position: absolute;
+  opacity: 1.0;
+  z-index: 10;  
+  color: black;
+  padding: 0.5em;
+}
+
+#dialog-title {
+  background: #222;
+  color: white;
+  padding: 0.2em;
+  margin: 0.2em;
+}
+
+#dialog-title div.title {
+  float:left;
+}
+
+#dialog-title #dialog-close {
+  float:right;
+}
+#dialog-title #dialog-close a {
+    color: red;  
+}
+#dialog-title div.clear {
+  clear:both;
+}  
+
+#dialog input {
+  margin: 0.1em;
+}
+
+
+
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.551
diff -u -r1.551 system.module
--- modules/system/system.module	11 Nov 2007 08:48:22 -0000	1.551
+++ modules/system/system.module	20 Nov 2007 02:02:47 -0000
@@ -451,10 +451,37 @@
     'access callback' => TRUE,
     'type' => MENU_CALLBACK,
     'file' => 'system.admin.inc',
-  );
+  ); 
+  
+  // Used for dialog popups
+  $items['get-raw'] = array(
+    'page callback' => 'system_get_raw_content',
+    'access arguments' => TRUE,
+    'type' => MENU_CALLBACK,
+  );  
+  
   return $items;
 }
 
+
+/*
+ * Return the content of a path as html, without the page's theming wrapper
+ * Used by dialogs.js for a popup with the content of a link
+ */  
+function system_get_raw_content() {
+  global $base_url;
+  $path = $_GET['path'];
+  $path = substr( $path, strlen($base_url) + 1 );
+  $content = menu_execute_active_handler( $path );
+  $title = '<div class="title">'. drupal_get_title() .'</div>';
+  
+  if( $content == MENU_NOT_FOUND ) {
+    $content .= "Path not found: $path ";
+  }
+  print $title . '<div class="content">'. $content .'</div>';
+}
+  
+
 function system_init() {
   // Use the administrative theme if the user is looking at a page in the admin/* path.
   if (arg(0) == 'admin' || (variable_get('node_admin_theme', '0') && arg(0) == 'node' && (arg(1) == 'add' || arg(2) == 'edit'))) {
@@ -1698,3 +1725,6 @@
   $image = theme('image', $image_path, t('Powered by Drupal, an open source content management system'), t('Powered by Drupal, an open source content management system'));
   return l($image, 'http://drupal.org', array('html' => TRUE, 'absolute' => TRUE, 'external' => TRUE));
 }
+
+
+
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.715
diff -u -r1.715 common.inc
--- includes/common.inc	16 Nov 2007 15:35:24 -0000	1.715
+++ includes/common.inc	20 Nov 2007 02:02:46 -0000
@@ -1411,6 +1411,14 @@
     $options['attributes']['title'] = strip_tags($options['attributes']['title']);
   }
 
+  if( isset($options['popup']) ) {
+    drupal_add_js('misc/jquery.form.js'); 
+    drupal_add_js('misc/dialogs.js'); 
+    drupal_add_basepath();    
+    $options['attributes']['popup'] = $options['popup'];
+  }
+
+
   return '<a href="'. check_url(url($path, $options)) .'"'. drupal_attributes($options['attributes']) .'>'. ($options['html'] ? $text : check_plain($text)) .'</a>';
 }
 
@@ -2039,6 +2047,18 @@
   drupal_add_js($settings, 'setting');
 }
 
+/*
+ * Provide base_path for javascript.  Needed for many Ajax calls
+ */
+function drupal_add_basepath() {
+  static $bathpath_added = FALSE;
+  if (!$bathpath_added) {
+    drupal_add_js( array( 'base_path' => base_path() ), 'setting' );
+    $bathpath_added = TRUE;
+  }
+}
+
+
 /**
  * Aggregate JS files, putting them in the files directory.
  *
Index: modules/block/block.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.admin.inc,v
retrieving revision 1.11
diff -u -r1.11 block.admin.inc
--- modules/block/block.admin.inc	14 Nov 2007 09:49:30 -0000	1.11
+++ modules/block/block.admin.inc	20 Nov 2007 02:02:46 -0000
@@ -74,7 +74,7 @@
     if ($throttle) {
       $form[$key]['throttle'] = array('#type' => 'checkbox', '#default_value' => isset($block['throttle']) ? $block['throttle'] : FALSE);
     }
-    $form[$key]['configure'] = array('#value' => l(t('configure'), 'admin/build/block/configure/'. $block['module'] .'/'. $block['delta']));
+    $form[$key]['configure'] = array('#value' => l(t('configure'), 'admin/build/block/configure/'. $block['module'] .'/'. $block['delta'], array( 'popup' => true )));
     if ($block['module'] == 'block') {
       $form[$key]['delete'] = array('#value' => l(t('delete'), 'admin/build/block/delete/'. $block['delta']));
     }
Index: modules/block/block.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.js,v
retrieving revision 1.1
diff -u -r1.1 block.js
--- modules/block/block.js	14 Nov 2007 09:49:30 -0000	1.1
+++ modules/block/block.js	20 Nov 2007 02:02:46 -0000
@@ -17,6 +17,7 @@
 
   // A custom message for the blocks page specifically.
   Drupal.theme.tableDragChangedWarning = function () {
+    Drupal.markPageUnsaved('edit-submit'); //add warning popup to all links
     return '<div class="warning">' + Drupal.theme('tableDragChangedMarker') + ' ' + Drupal.t("The changes to these blocks will not be saved until the <em>Save blocks</em> button is clicked.") + '</div>';
   };
 
Index: misc/drupal.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/drupal.js,v
retrieving revision 1.40
diff -u -r1.40 drupal.js
--- misc/drupal.js	5 Oct 2007 09:35:08 -0000	1.40
+++ misc/drupal.js	20 Nov 2007 02:02:46 -0000
@@ -273,3 +273,17 @@
     return '<em>' + Drupal.checkPlain(str) + '</em>';
   }
 };
+
+/*
+ *  Called when there is unsaved data on the page
+ *  Warn users when the click links that they could lose their changes
+ *
+ *  @param submit_id
+ *    the id of the submit button to page the page
+ */
+Drupal.markPageUnsaved = function(submit_id) {
+  dialog = new Drupal.dialog();
+  $('a[href!=#]').addClass('unsaved-warning');
+  $('a[href!=#]').click( function(){ return dialog.open_unsaved(this, submit_id); } );
+};
+
Index: misc/dialogs.js
===================================================================
RCS file: misc/dialogs.js
diff -N misc/dialogs.js
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ misc/dialogs.js	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,178 @@
+// $Id $
+
+
+// remove /**/ for debugging
+var console = {};
+console.log = function() {};
+
+
+
+Drupal.behaviors.dialog = function(context) {
+  var dialog = new Drupal.dialog();
+  $('a[popup]', context).click( function(){ return dialog.open_path(this, 800); } );
+};
+
+Drupal.dialog = function() {
+  this.default_width = 480;
+};
+
+
+Drupal.dialog.prototype.add_overlay = function() {
+  var overlay = $( Drupal.theme('dialogsOverlay') );
+
+  overlay.css( 'opacity', '0.4' ); // for ie
+  $('body').prepend( overlay );
+  return overlay;
+};
+
+Drupal.dialog.prototype.open = function( title, body, buttons, width, overlay ) {
+  if( !width ) {
+    width = this.default_width;
+  }
+
+  if( !overlay ) {
+    overlay = this.add_overlay();
+  }
+    
+  // center on the screen, add in offsets if the window has been scrolled
+  var overlay_width = overlay.width();
+  var overlay_height = overlay.height();
+  var left = ( overlay_width / 2 ) - ( width / 2 ) + f_scrollLeft();
+  var top = 0; // we will reposition after adding to page
+  var dialog = Drupal.theme('dialogsDialog', left, top, width, title, body, buttons);
+
+  overlay.before( dialog ); // dialog is added, but still hidden.  
+
+  // Adding button functions
+  for ( var id in buttons) {
+    var func = buttons[id].func;
+    $('#'+id).click( func );
+  }
+  $('#dialog-close').click( this.close );
+  
+  //Get dialog's height on the page, and center vertically before showing.
+  var dialog_height = $('#dialog').height();
+  console.log( "height: " + dialog_height );
+  console.log( "window: " + overlay_height );
+  if( dialog_height < overlay_height ) {
+    top = ( overlay_height / 2 ) - ( dialog_height / 2 ) + f_scrollTop();
+  }
+  else { // dialog is too big to fit on screen
+    top = 20  + f_scrollTop();
+  }
+  $('#dialog').css('top', top);
+  $('#dialog').css('display', 'block'); // center and reveal
+  
+  return false;
+};
+
+
+Drupal.dialog.prototype.open_unsaved = function( a, submit_id ) {
+  var body = Drupal.t("There are unsaved changes on this page. If you click away from this page, you will lose those changes.");
+  var popup = this;
+  var buttons = {
+    'dialog_save': { 
+      title: Drupal.t('Save Changes'), 
+      func: function(){
+        popup.close(); 
+        // $('#block-admin-display-form').submit(); // doesn't work at all, don't know why
+        // $('#block-admin-display-form').ajaxForm( {success: function(){alert('form')}} ); // works, but only when submit is click manually 
+        // $('#block-admin-display-form').ajaxSubmit( {success: function(){alert('submit')}} ); // doesn't work - doesn't send back hiddens or op 
+        $('#'+submit_id).click(); // works but reloads
+        //  window.location = a.href; // race condition, kills the saving ~50% of the time
+      }
+    },
+    'dialog_submit': { 
+      title: Drupal.t('Discard Changes'), 
+      func: function(){
+        popup.close(); 
+        window.location = a.href;
+      } 
+    },
+    'dialog_cancel': { 
+      title: Drupal.t('Cancel'), 
+      func: function(){ popup.close(); } }
+  };
+
+  this.open( "Warning - Please Confirm", body, buttons );
+  return false;
+};
+
+Drupal.dialog.prototype.open_path = function( a, width, height ) {
+  if( $(a).is('.unsaved-warning') ) {
+    return false; // don't do popup on unsaved-warning links
+  }
+  var url = a.href;
+  var popup = this;
+  // let the user know something is happening
+  $('body').css("cursor", "wait");
+  var overlay = this.add_overlay(); 
+
+  // loaded the link's path into the dialog, instead going to new page  
+  $.get(Drupal.settings.base_path+ "get-raw?path="+url, function(data) {
+     var title = $(data).eq(0).html();
+     var body = $(data).slice(1).html();
+     popup.open( title, body, null, 600, overlay );
+    $('body').css("cursor", "auto");
+   });        
+  return false;         
+}
+
+Drupal.dialog.prototype.close = function() {
+  $('#dialog').remove();
+  $('#dialog-overlay').remove();
+};
+
+
+Drupal.theme.prototype.dialogsOverlay = function () {
+  return '<div id="dialog-overlay"></div>';
+};
+
+Drupal.theme.prototype.dialogsDialog = function(left, top, width, title, body, buttons) {
+  var dialog = '<div  id="dialog" style="display:none; left:'+ left +'px; top:'+ top +'px;';
+  dialog += ' width:'+ width +'px;';
+  dialog += '" >';
+  dialog += '<div id="dialog-title">'+
+            '  <div class="title">' + title +'</div>'+
+            '  <div id="dialog-close"><a>close [X]</a></div>'+
+            '  <div class="clear"></div>'+
+            '</div>';
+  dialog += '<div id="dialog-body">' + body +'</div>';
+  dialog += '  <div id="dialog-buttons">';
+
+  for ( id in buttons) {
+    button = buttons[id];
+    dialog += '<input type="button" value="'+ button.title +'" id="'+ id +'" />';
+  }
+  
+  dialog += '  </div>'; // end buttons
+  dialog +=  '</div>'; // close dialog
+  return dialog;
+};
+
+/**
+ *
+ * Utility functions taken from http://www.softcomplex.com/docs/get_window_size_and_scrollbar_position.html
+ *
+ */
+
+function f_scrollLeft() {
+  return f_filterResults (
+    window.pageXOffset ? window.pageXOffset : 0,
+    document.documentElement ? document.documentElement.scrollLeft : 0,
+    document.body ? document.body.scrollLeft : 0
+  );
+};
+function f_scrollTop() {
+  return f_filterResults (
+    window.pageYOffset ? window.pageYOffset : 0,
+    document.documentElement ? document.documentElement.scrollTop : 0,
+    document.body ? document.body.scrollTop : 0
+  );
+};
+function f_filterResults(n_win, n_docel, n_body) {
+  var n_result = n_win ? n_win : 0;
+  if (n_docel && (!n_result || (n_result > n_docel)))
+    n_result = n_docel;
+  return n_body && (!n_result || (n_result > n_body)) ? n_body : n_result;
+};
