Index: jstools.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/jstools/jstools.js,v
retrieving revision 1.16
diff -u -r1.16 jstools.js
--- jstools.js	5 May 2007 22:42:20 -0000	1.16
+++ jstools.js	12 May 2007 17:11:31 -0000
@@ -55,13 +55,11 @@
   }
 }
 
+/**
+ * Return the Drupal path portion of an href.
+ */
 Drupal.getPath = function (href) {
-  // Remove e.g. http:// if present.
-  var protocol = window.location.protocol;
-  if (href.substring(0, protocol.length) == protocol) {
-    // 2 is the length of the '//' that normally follows the protocol
-    href = href.substring(href.indexOf('/', protocol.length + 2));
-  }
+  href = Drupal.pathPortion(href);
   // 3 is the length of the '?q=' added to the url without clean urls.
   href = href.substring(Drupal.settings.jstools.basePath.length + (Drupal.settings.jstools.cleanurls ? 0 : 3), href.length);
   var chars = ['#', '?', '&'];
@@ -77,6 +75,13 @@
  * Add a segment to the beginning of a path.
  */
 Drupal.prependPath = function (href, segment) {
+  href = Drupal.pathPortion(href);
+  // Remove e.g. http://example.com if present.
+  var protocol = window.location.protocol;
+  if (href.substring(0, protocol.length) == protocol) {
+    // 2 is the length of the '//' that normally follows the protocol
+    href = href.substring(href.indexOf('/', protocol.length + 2));
+  }
   // 3 is the length of the '?q=' added to the url without clean urls.
   var baseLength = Drupal.settings.jstools.basePath.length + (Drupal.settings.jstools.cleanurls ? 0 : 3);
   var base = href.substring(0, baseLength);
@@ -84,6 +89,19 @@
 }
 
 /**
+ * Strip off the protocol plus domain from an href.
+ */
+Drupal.pathPortion = function (href) {
+  // Remove e.g. http://example.com if present.
+  var protocol = window.location.protocol;
+  if (href.substring(0, protocol.length) == protocol) {
+    // 2 is the length of the '//' that normally follows the protocol
+    href = href.substring(href.indexOf('/', protocol.length + 2));
+  }
+  return href
+}
+
+/**
  * Redirects a form submission to a hidden iframe and displays the result
  * in a given wrapper. The iframe should contain a call to
  * window.parent.iframeHandler() after submission.
Index: activeedit/activeedit.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/jstools/activeedit/activeedit.js,v
retrieving revision 1.4
diff -u -r1.4 activeedit.js
--- activeedit/activeedit.js	6 Mar 2007 22:03:09 -0000	1.4
+++ activeedit/activeedit.js	11 Mar 2007 04:48:06 -0000
@@ -170,7 +170,7 @@
       // Create a dummy to hold the place of the loaded window. This is needed to remove the actual form being loaded
       // from this place in the DOM, in case we're already in a form.
       $(elt).after('<div id="activeedit-dummy"></div>');
-      $('body').append('<div id="activeedit-window"><div id="activeedit-message">' + (response.data.message ? response.data.message : '') + '</div>' +response.data.content + '<button id="activeedit-cancel">Cancel</button></div>');
+      $('body').append('<div id="activeedit-window"><div id="activeedit-message">' + (response.data.message ? response.data.message : '') + '</div>' + response.data.content + '<button id="activeedit-cancel">Cancel</button></div>');
       // Attach collapse behavior to newly-loaded form content.
       Drupal.collapseAutoAttach();
       $('#activeedit-cancel').click(function() {
Index: activemenu/activemenu.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/jstools/activemenu/activemenu.js,v
retrieving revision 1.24
diff -u -r1.24 activemenu.js
--- activemenu/activemenu.js	5 May 2007 22:48:57 -0000	1.24
+++ activemenu/activemenu.js	12 May 2007 04:55:49 -0000
@@ -1,8 +1,23 @@
 // $Id: activemenu.js,v 1.24 2007/05/05 22:48:57 nedjo Exp $
 
 Drupal.activemenuAutoAttach = function () {
+
+  $(Drupal.settings.activemenu.selectors.primary_links + ':not(.activemenu-processed)')
+    .each(function () {
+      var i = 0;
+      $(this)
+        .addClass('activemenu-processed')
+        .addClass('nav')
+        .find('li')
+        .each(function () {
+          $(this).append(Drupal.settings.activemenu.primaryLinks[i]);
+          i++;
+        })
+        .end()
+        .superfish();
+    })
   // The elements supported. Each can designate a different uri.
-  var menus = Drupal.settings.activemenu;
+  var menus = Drupal.settings.activemenu.menus;
 
   for (var menu in menus) {
     $(menu + ' li.expanded:not(.activemenu-processed)').each(function () {
Index: activemenu/activemenu.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/jstools/activemenu/activemenu.module,v
retrieving revision 1.21
diff -u -r1.21 activemenu.module
--- activemenu/activemenu.module	14 Mar 2007 01:58:11 -0000	1.21
+++ activemenu/activemenu.module	14 Mar 2007 15:31:31 -0000
@@ -23,31 +23,12 @@
       'callback' => 'activemenu_js'
     );
   }
-  else {
-    jstools_modules_includes('activemenu');
-    activemenu_load();
-  }
+
   $items = array_merge($items, module_invoke_all('activemenu_menu', $may_cache));
   return $items;
 }
 
 /**
- * Load needed files.
- */
-function activemenu_load() {
-  static $loaded = FALSE;
-  if (!$loaded) {
-    $path = drupal_get_path('module', 'activemenu');
-    jstools_add_js($path . '/activemenu.js');
-    $activemenu = module_invoke_all('activemenu');
-    if (count($activemenu)) {
-      drupal_add_js(array('activemenu' => $activemenu), 'setting');
-    }
-    $loaded = TRUE;
-  }
-}
-
-/**
  * Menu callback. Output a themed menu tree for a requested menu item.
  */
 function activemenu_js() {
@@ -67,14 +48,76 @@
 function activemenu_footer() {
   global $theme;
 
-  $file = drupal_get_path('module', 'activemenu') .'/theme/'. $theme .'.css';
-  if (file_exists($file)) {
-    drupal_add_css($file);
+  static $loaded = FALSE;
+  if (!$loaded) {
+
+    $file = drupal_get_path('module', 'activemenu') .'/theme/'. $theme .'.css';
+    if (file_exists($file)) {
+      drupal_add_css($file);
+    }
+    else {
+      drupal_add_css(drupal_get_path('module', 'activemenu') .'/activemenu.css', 'theme');
+    }
+
+    jstools_modules_includes('activemenu');
+    $path = drupal_get_path('module', 'activemenu');
+    jstools_add_js($path . '/activemenu.js');
+    jstools_add_js($path . '/superfish.js');
+    drupal_add_css($path . '/superfish.css');
+    // Load data for block-style menus.
+    $activemenu = module_invoke_all('activemenu');
+    // Load data for primary links.
+    $child_menus = activemenu_primary_links_menus();
+    // Set default selectors.
+    $selectors = array(
+      'primary_links' => 'ul.primary-links',
+    );
+    // Override defaults with theme-specific selectors.
+    if ($theme_selectors = jstools_theme_data('activemenu')) {
+      $selectors = array_merge($selectors, $theme_selectors);
+    }
+    if (count($activemenu) || $child_menus) {
+      drupal_add_js(array('activemenu' => array('menus' => $activemenu, 'primaryLinks' => $child_menus, 'selectors' => $selectors)), 'setting');
+    }
+    $loaded = TRUE;
   }
-  else {
-    drupal_add_css(drupal_get_path('module', 'activemenu') .'/activemenu.css', 'theme');
+}
+
+/**
+ * Return an array containing the primary links's child items.
+ */
+function activemenu_primary_links_menus() {
+  if (!module_exists('menu')) {
+    return NULL;
   }
+  $pid = variable_get('menu_primary_menu', 0);
+  if (!$pid) {
+    return NULL;
+  }
+
+  $menu = menu_get_menu();
+  $child_menus = array();
+  if ($pid && is_array($menu['visible'][$pid]) && isset($menu['visible'][$pid]['children'])) {
+    foreach ($menu['visible'][$pid]['children'] as $cid) {
+      _activemenu_expand($cid);
+      $child_menus[] = theme('menu_tree', $cid);
+    }
+  }
+
+  return $child_menus;
+}
 
+/**
+ * Helper function to expand child menu items.
+ */
+function _activemenu_expand($pid) {
+  global $_menu;
+  if ($_menu['visible'][$pid]['children']) {
+    foreach ($_menu['visible'][$pid]['children'] as $cid) {
+      $_menu['visible'][$cid]['type'] = $_menu['visible'][$cid]['type'] | MENU_EXPANDED;
+      _activemenu_expand($cid);
+    }
+  }
 }
 
 /**
Index: dynamicload/dynamicload.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/jstools/dynamicload/dynamicload.install,v
retrieving revision 1.3
diff -u -r1.3 dynamicload.install
--- dynamicload/dynamicload.install	22 Feb 2007 16:11:36 -0000	1.3
+++ dynamicload/dynamicload.install	12 Mar 2007 23:41:45 -0000
@@ -13,6 +13,7 @@
         delta varchar(32) NOT NULL,
         refresh int NOT NULL default '0',
         refresh_interval int NOT NULL default '0',
+        scroll int NOT NULL default '0',
         apply int NOT NULL default '0',
         target varchar(128) NOT NULL default '',
         PRIMARY KEY (module, delta)
@@ -24,6 +25,7 @@
         delta varchar(32) NOT NULL,
         refresh int NOT NULL default '0',
         refresh_interval int NOT NULL default '0',
+        scroll int NOT NULL default '0',
         apply int NOT NULL default '0',
         target varchar(128) NOT NULL default '',
         PRIMARY KEY (module, delta)
@@ -53,4 +55,19 @@
 
   }
   return $ret;
+}
+
+function dynamicload_update_3() {
+  $ret = array();
+  switch ($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      $ret[] = update_sql("ALTER TABLE {dynamicload_blocks} ADD scroll int NOT NULL default '0'");
+      break;
+    case 'pgsql':
+      db_add_column($ret, 'dynamicload_blocks', 'scroll', 'int', array('not null' => TRUE, 'default' => 0));
+      break;
+
+  }
+  return $ret;
 }
\ No newline at end of file
Index: dynamicload/dynamicload.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/jstools/dynamicload/dynamicload.js,v
retrieving revision 1.20
diff -u -r1.20 dynamicload.js
--- dynamicload/dynamicload.js	20 Apr 2007 01:45:21 -0000	1.20
+++ dynamicload/dynamicload.js	12 May 2007 04:55:49 -0000
@@ -113,9 +113,54 @@
     success: function(response){
       response = Drupal.parseJson(response);
       if (response.result) {
-        $(selector)
-          .after(response.content)
-          .remove();
+        // If there are list items, fade in the new ones.
+        var count = $(selector + ' div.item-list li').size();
+        if (Drupal.settings.dynamicload.settings[module + '_' + delta].scroll && count) {
+          var firstHref = $(selector + ' div.item-list li:first a:first').attr('href');
+          var isNew = true;
+          var newElts = [];
+          $(selector)
+            .attr('id', 'dynamicload-old')
+            .after(response.content)
+            .next('div.block')
+            .hide()
+            .find('div.item-list ul:first > li')
+            .each(function () {
+              if (isNew && ($(this).find('a:first').attr('href') != firstHref)) {
+                newElts.push($(this).clone());
+              }
+              else {
+                isNew = false;
+              }
+            })
+            .end()
+            .end()
+            .find('div.item-list:first ul:first')
+            .each(function () {
+              for (var i in newElts) {
+                // Append and fade in the new content.
+                $(this).prepend(newElts[i]);
+                $(newElts[i]).fadeIn('slow');
+                // Remove the old content.
+                // If it's the last old content to be removed, replace the old block with the new one.
+                if (i == (newElts.length - 1)) {
+                  $(this).find('li:last-child').fadeOut('slow', function () {
+                    $('#dynamicload-old').remove();
+                    $(selector).show();
+                  });
+                }
+                else {
+                  $(this).find('li:last-child').fadeOut('slow', function () {$(this).remove()});
+                }                
+              }
+            });
+        }
+        // Otherwise simply replace the existing block.
+        else {
+          $(selector)
+            .after(response.content)
+            .remove();
+        }
       }
     }
   });
Index: dynamicload/dynamicload.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/jstools/dynamicload/dynamicload.module,v
retrieving revision 1.28
diff -u -r1.28 dynamicload.module
--- dynamicload/dynamicload.module	12 Mar 2007 17:16:50 -0000	1.28
+++ dynamicload/dynamicload.module	12 Mar 2007 23:39:58 -0000
@@ -120,13 +120,19 @@
       '#title' => t('Automatically refresh this block'),
       '#default_value' => $settings['refresh'] ? 1 : 0
     );
-  $form['dynamicload']['dynamicload_refresh_interval'] = array(
+    $form['dynamicload']['dynamicload_refresh_interval'] = array(
       '#type' => 'select',
       '#title' => t('Block refresh interval'),
       '#description' => t('Select the interval at which this block should refresh.'),
       '#default_value' => $settings['refresh_interval'] ? $settings['refresh_interval'] : 30000,
       '#options' => array(5000 => t('five seconds'), 10000 => t('ten seconds'), 30000 => t('thirty seconds'), 60000 => t('one minute'), 120000 => t('two minutes'), 180000 => t('three minutes'), 300000 => t('five minutes'), 600000 => t('ten minutes')),
     );
+    $form['dynamicload']['dynamicload_scroll'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Scroll in new items'),
+      '#description' => t('Check if you want new items for this block to fade in ticker-style as they arrive (with the oldest item fading out). If this option is not checked, the whole block will refresh.'),
+      '#default_value' => $settings['scroll'] ? 1 : 0
+    );
   }
 }
 
@@ -135,11 +141,11 @@
  */
 function dynamicload_submit($form_id, $form_values) {
   if (db_num_rows(db_query("SELECT * FROM {dynamicload_blocks} WHERE module = '%s' AND delta = %d", $form_values['module'], $form_values['delta']))) {
-    db_query("UPDATE {dynamicload_blocks} SET refresh = %d, refresh_interval = %d, apply = %d, target = '%s' WHERE module = '%s' AND delta = %d", $form_values['dynamicload_refresh'], $form_values['dynamicload_refresh_interval'], $form_values['dynamicload_apply'], $form_values['dynamicload_target'], $form_values['module'], $form_values['delta']);
+    db_query("UPDATE {dynamicload_blocks} SET refresh = %d, refresh_interval = %d, scroll = %d, apply = %d, target = '%s' WHERE module = '%s' AND delta = %d", $form_values['dynamicload_refresh'], $form_values['dynamicload_refresh_interval'], $form_values['dynamicload_scroll'], $form_values['dynamicload_apply'], $form_values['dynamicload_target'], $form_values['module'], $form_values['delta']);
     drupal_set_message(t('Dynamic loading block data updated.'));
   }
   else {
-    db_query("INSERT INTO {dynamicload_blocks} (module, delta, refresh, refresh_interval, apply, target) VALUES ('%s', %d, %d, %d, %d, '%s')", $form_values['module'], $form_values['delta'], $form_values['dynamicload_refresh'], $form_values['dynamicload_refresh_interval'], $form_values['dynamicload_apply'], $form_values['dynamicload_target']);
+    db_query("INSERT INTO {dynamicload_blocks} (module, delta, refresh, refresh_interval, apply, target) VALUES ('%s', %d, %d, %d, %d, '%s')", $form_values['module'], $form_values['delta'], $form_values['dynamicload_refresh'], $form_values['dynamicload_refresh_interval'], $form_values['dynamicload_scroll'], $form_values['dynamicload_apply'], $form_values['dynamicload_target']);
     drupal_set_message(t('Dynamic loading block data saved.'));
   }
 }
Index: jscalendar/jscalendar.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/jstools/jscalendar/jscalendar.module,v
retrieving revision 1.15
diff -u -r1.15 jscalendar.module
--- jscalendar/jscalendar.module	25 Jan 2007 19:53:06 -0000	1.15
+++ jscalendar/jscalendar.module	14 Feb 2007 15:02:30 -0000
@@ -71,6 +71,7 @@
  * Menu callback for admin settings.
  */
 function jscalendar_admin_settings() {
+  $form = array();
   $form['jscalendar_css'] = array(
     '#type' => 'select',
     '#title' => t('JSCalendar style'),
