Index: popups.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/popups/popups.js,v
retrieving revision 1.9.2.17
diff -u -r1.9.2.17 popups.js
--- popups.js	19 Nov 2008 08:35:45 -0000	1.9.2.17
+++ popups.js	19 Nov 2008 23:45:14 -0000
@@ -238,6 +238,7 @@
   Drupal.popups.removePopup();
   Drupal.popups.removeLoading();
   Drupal.popups.removeOverlay();
+  Drupal.settings = Drupal.popups.originalSettings;
   return false;
 };
 
@@ -326,8 +327,50 @@
     dataType: 'json',
     data: {destination: Drupal.settings.popups.originalPath}, // Set the destination to the original page.
     beforeSend: Drupal.popups.beforeSend,
-    success: function(json) { 
-      Drupal.popups.openContent(json.title, json.messages + json.content, options);
+    success: function(json) {
+      // Add additional CSS to the page.
+      for (var type in json.css) {
+        for (var file in json.css[type]) {
+          if (!Drupal.settings.popups.css[type][file]) {
+            $('head').append(json.css[type][file]);
+          }
+        }
+      }
+
+      // Add additional JS to the page.
+      var scripts = [];
+      var inlines = [];
+      for (var type in json.js) {
+        if (!Drupal.settings.popups.js[type]) {
+          Drupal.settings.popups.js[type] = {};
+        }
+        for (var file in json.js[type]) {
+          if (type != 'setting' && !Drupal.settings.popups.js[type][file]) {
+            if (type == 'inline') {
+              inlines.push($(json.js[type][file]).text());
+            }
+            else {
+              scripts.push(Drupal.settings.basePath + file);
+            }
+          }
+        }
+      }
+
+      // Add new JS settings to the page, needed for #ahah properties to work.
+      Drupal.popups.originalSettings = Drupal.settings;
+      Drupal.settings = json.js.setting;
+
+      // As an exception, keep the popups settings in place until the popup is closed.
+      Drupal.settings.popups = Drupal.popups.originalSettings.popups;
+
+      function jsDoneLoading() {
+        Drupal.popups.openContent(json.title, json.messages + json.content, options);
+        $('body').css("cursor", "auto"); // Return the cursor to normal state.
+      }
+
+      // Load JavaScript asynchronisly. Then open the popup.
+      Drupal.popups.loadJavaScript(scripts, inlines, jsDoneLoading);
+
     },
     complete: function() {
       $('body').css("cursor", "auto"); // Return the cursor to normal state.      
@@ -521,3 +564,44 @@
   $form.ajaxSubmit(ajaxOptions); // Submit the form. 
 };
 
+
+/**
+ * Load additional JavaScript from the popup onto the main page.
+ *
+ * This function needs to be called recursively because it needs to load in a
+ * synchronis manner (in the order it's declared). Otherwise problems arise
+ * when a JS file that was meant to loas last is loaded before another
+ * file it is dependent upon.
+ *
+ * @param scripts
+ *   An array of external JavaScript files that will be loaded.
+ * @param inlines
+ *   An array of inline JavaScript that will be loaded.
+ * @param callback
+ *   A function reference that will be executed when all files are loaded.
+ */
+Drupal.popups.loadJavaScript = function(scripts, inlines, callback) {
+  var files_total = scripts.length;
+
+  function loadInlines() {
+    for (var n in inlines) {
+      eval(inlines[n]);
+    }
+  }
+
+  // Recursively called to load files in order.
+  function loadExternal(current_file) {
+    if (current_file == files_total) {
+      loadInlines();
+      callback.call();
+      return;
+    }
+
+    $.get(scripts[current_file], function(response) {
+      eval(response);
+      loadExternal(current_file + 1);
+    });
+  }
+
+  loadExternal(0);
+}
Index: popups_admin.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/popups/Attic/popups_admin.module,v
retrieving revision 1.1.4.5
diff -u -r1.1.4.5 popups_admin.module
--- popups_admin.module	19 Nov 2008 08:35:45 -0000	1.1.4.5
+++ popups_admin.module	19 Nov 2008 23:45:14 -0000
@@ -27,9 +27,7 @@
   return array(
     'admin/build/block' => array( // Blocks admin page.
       '#tabs-wrapper a[href$=admin/build/block/add]', // Add Block
-      '#blocks a[href~=admin/build/block/configure]'  => array(  // configure
-        'additionalJavascript' => array('misc/collapse.js'),
-      ),
+      '#blocks a[href~=admin/build/block/configure]', // configure
       '#blocks a[href~=admin/build/block/delete]', // delete
     ),
     'admin/build/path' => array( // URL aliases admin page.
@@ -41,36 +39,29 @@
       // TODO: If there are not more than one items to start with, d-n-d files aren't loaded into page.
       // This causes trouble when the 2nd item is added, no d-n-d.
       // Might be bug in taxonomy table building (or at least inconsistancy).
-      '#tabs-wrapper a[href$=admin/content/taxonomy/add/vocabulary]' => array( // Add vocabulary
-        'additionalJavascript' => array('misc/tabledrag.js'),
-      ),       
+      '#tabs-wrapper a[href$=admin/content/taxonomy/add/vocabulary]', // Add vocabulary
       '#taxonomy-overview-vocabularies td a:contains('. t('edit vocabulary') .')', // edit vocabulary
       '#taxonomy-overview-vocabularies td a:contains('. t('list terms') .')' => array( // list terms
+        // TODO: Drag and drop would work here, but the term table and taxonomy
+        // overview table both have the ID "taxonomy", so DnD isn't added to the
+        // taxonomy term table in the popup.
         'noUpdate' => TRUE,
-        'additionalJavascript' => array('misc/tabledrag.js'),
       ),
       '#taxonomy-overview-vocabularies td a:contains('. t('add terms') .')' => array(  // add terms
         'noUpdate' => TRUE,
-        'additionalJavascript' => array('misc/collapse.js'),
       ),
     ),
     'admin/content/types' => array( // Content Type admin page
-      '#tabs-wrapper a[href$=admin/content/types/add]' => array(  // Add content type
-        'additionalJavascript' => array('misc/collapse.js'),
-      ),
+      '#tabs-wrapper a[href$=admin/content/types/add]', // Add content type
       'table td:nth-child(4) a, table td:nth-child(5) a, table td:nth-child(7) a' // edit, add field, delete
     ),
     'admin/content/types/list' => array( // Content Type admin page
-      '#tabs-wrapper a[href$=admin/content/types/add]' => array(  // Add content type
-        'additionalJavascript' => array('misc/collapse.js'),
-      ),
+      '#tabs-wrapper a[href$=admin/content/types/add]', // Add content type
       'table td:nth-child(4) a, table td:nth-child(5) a, table td:nth-child(7) a' // edit, add field, delete
     ),
     'admin/content/node' => array( // Existing Content admin page
       '#node-admin-content td a:contains('. t('edit') .')' => array( // edit
-        'additionalJavascript' => array('misc/collapse.js'),
-        // TODO: teaser.js not working: Drupal.settings.teaser has no properties
-        // 'additionalJavascript' => array('misc/collapse.js', 'misc/teaser.js'),
+        // TODO: teaser.js not working.
       )      
     ),
     'page_node_form' => array( // Node edit form
@@ -84,9 +75,7 @@
         'noUpdate' => TRUE,
         'additionalCss' => array(), //TODO: needs some custom css to get #comments to stay in the popup (no -25px margin).
       ),
-      '#comment-admin-overview td a:contains('. t('edit') .')' => array( // edit
-        'additionalJavascript' => array('misc/collapse.js'),
-      ),
+      '#comment-admin-overview td a:contains('. t('edit') .')', // Edit comment
     ),
     'admin/user/rules' => array( // Access rules admin page.
       '#tabs-wrapper a[href$=admin/user/rules/add]', // Add rule
@@ -97,10 +86,7 @@
     ),
     'admin/user/user' => array( // Manage all users admin page.
       //Add user (TODO: Can't test, keeps crashing apache!)
-      '#tabs-wrapper a[href$=admin/user/user/create]' => array(
-        // TODO: "translate has no properties" user.js line 16.
-        'additionalJavascript' => array(drupal_get_path('module', 'user') .'/user.js'),
-      ),
+      '#tabs-wrapper a[href$=admin/user/user/create]', // Create user
       '#user-admin-account td:nth-child(2) a' => array( // View the user
         'noUpdate' => TRUE,
       ),
@@ -120,7 +106,6 @@
       'div#tabs-wrapper a:eq(0)' => array( // Edit - ISSUE: returns to different page.
         'updateTitle' => TRUE,
         'noUpdate' => TRUE,
-        'additionalJavascript' => array('misc/collapse.js'),
         'forceReturn' => 'admin/content', // If workflow goes to 'admin/content', treat it as success. 
       ),
       'div#tabs-wrapper a:eq(2)' => array( // Display fields
Index: popups.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/popups/popups.module,v
retrieving revision 1.11.2.18
diff -u -r1.11.2.18 popups.module
--- popups.module	19 Nov 2008 08:35:45 -0000	1.11.2.18
+++ popups.module	19 Nov 2008 23:45:14 -0000
@@ -127,11 +127,29 @@
   );
 }
 
+/**
+ * Implementation of hook_preprocess_page().
+ *
+ * Get the current list of JS and CSS files that are going to be used on the
+ * loaded page. Save this list in a JS variable. This preprocess function is
+ * absolutely the very latest in the display cycle we can get a list of JS files
+ * and add it to the page.
+ */
+function popups_preprocess_page(&$vars) {
+  $js = popups_get_js();
+  $css = popups_get_css();
+
+  drupal_add_js(array('popups' => array('css' => $css, 'js' => $js)), 'setting');
+  $vars['scripts'] = drupal_get_js();
+}
+
 function popups_render_as_json($content) { 
   $path = $_GET['q']; // Get current path from params.
   return drupal_json(array(
     'title' => drupal_get_title(),
     'messages' => theme('status_messages'),
+    'js' => popups_get_js(),
+    'css' => popups_get_css(),
     'path' => $path,
     'content' => $content,
   ));
@@ -288,6 +306,88 @@
 
 }
 
+
+/**
+ * Get the added JS in a format that is readable by popups.js.
+ */
+function popups_get_js() {
+  $js = array_merge_recursive(drupal_add_js(), drupal_add_js(NULL, NULL, 'footer'));
+  $popup_js = array();
+
+  foreach ($js as $type => $data) {
+    if (!$data) continue;
+    switch ($type) {
+      case 'setting':
+        $popup_js['setting'] = call_user_func_array('array_merge_recursive', $data);
+        break;
+      case 'inline':
+        foreach ($data as $info) {
+          $popup_js['inline'][] = '<script type="text/javascript"' . ($info['defer'] ? ' defer="defer"' : '') . '>' . $info['code'] . "</script>\n";
+        }
+        break;
+      default:
+        foreach ($data as $path => $info) {
+          $popup_js[$type][$path] = '<script type="text/javascript"'. ($info['defer'] ? ' defer="defer"' : '') .' src="'. base_path() . $path ."\"></script>\n";
+        }
+        break;
+    }
+  }
+
+  // A special exception, never include the popups settings in the JS array.
+  unset($popup_js['setting']['popups']);
+
+  return $popup_js;
+}
+
+/**
+ * Get the added JS in a format that is readable by popups.js.
+ */
+function popups_get_css() {
+  $css = drupal_add_css();
+  $popup_css = array();
+
+  $query_string = '?'. substr(variable_get('css_js_query_string', '0'), 0, 1);
+
+  // Only process styles added to "all".
+  $media = 'all';
+  foreach ($css[$media] as $type => $files) {
+    if ($type == 'module') {
+      // Setup theme overrides for module styles.
+      $theme_styles = array();
+      foreach (array_keys($css[$media]['theme']) as $theme_style) {
+        $theme_styles[] = basename($theme_style);
+      }
+    }
+    foreach($css[$media][$type] as $file => $preprocess) {
+      // If the theme supplies its own style using the name of the module style, skip its inclusion.
+      // This includes any RTL styles associated with its main LTR counterpart.
+      if ($type == 'module' && in_array(str_replace('-rtl.css', '.css', basename($file)), $theme_styles)) {
+        // Unset the file to prevent its inclusion when CSS aggregation is enabled.
+        unset($css[$media][$type][$file]);
+        continue;
+      }
+      // Only include the stylesheet if it exists.
+      if (file_exists($file)) {
+        // If a CSS file is not to be preprocessed and it's a module CSS file, it needs to *always* appear at the *top*,
+        // regardless of whether preprocessing is on or off.
+        if ($type == 'module') {
+          $popup_css['module'][$file] = '<link type="text/css" rel="stylesheet" media="'. $media .'" href="'. base_path() . $file . $query_string .'" />'."\n";
+        }
+        // If a CSS file is not to be preprocessed and it's a theme CSS file, it needs to *always* appear at the *bottom*,
+        // regardless of whether preprocessing is on or off.
+        else if ($type == 'theme') {
+          $popup_css['theme'][$file] = '<link type="text/css" rel="stylesheet" media="'. $media .'" href="'. base_path() . $file . $query_string .'" />'."\n";
+        }
+        else {
+          $popup_css['unknown'][$file] = '<link type="text/css" rel="stylesheet" media="'. $media .'" href="'. base_path() . $file . $query_string .'" />'."\n";
+        }
+      }
+    }
+  }
+
+  return $popup_css;
+}
+
 /**
  * hook_popups
  * 
