Index: hierarchical_select.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/hierarchical_select.module,v
retrieving revision 1.162
diff -u -F^f -r1.162 hierarchical_select.module
--- hierarchical_select.module	25 Jul 2009 10:27:59 -0000	1.162
+++ hierarchical_select.module	25 Jul 2009 14:48:19 -0000
@@ -367,7 +367,7 @@ function hierarchical_select_process($el
 
   // Set up Javascript and add settings specifically for the current
   // hierarchical select.
-  $config = $element['#config'];
+  $config = _hierarchical_select_inherit_default_config($element['#config']);
   _hierarchical_select_setup_js();
   drupal_add_js(
     array(
@@ -449,7 +449,7 @@ function hierarchical_select_process($el
       // the updated config.
       $element['#config']['dropbox']['status'] = 0;
 
-      $config = $element['#config'];
+      $config = _hierarchical_select_inherit_default_config($element['#config']);
 
       // When the form is first loaded, $db_selection contained the selection
       // selection that we checked for. Since we've now disabled the dropbox,
@@ -627,7 +627,9 @@ function hierarchical_select_process($el
   // Add a validate callback, which will:
   // - validate that the dropbox limit was not exceeded.
   // - set the return value of this form element.
-  $element['#element_validate'] = array('_hierarchical_select_validate');
+  // Also make sure it is the *first* validate callback.
+  $element['#element_validate'] = (isset($element['#element_validate'])) ? $element['#element_validate'] : array();
+  $element['#element_validate'] = array_merge(array('_hierarchical_select_validate'), $element['#element_validate']);
 
   if (HS_DEVELOPER_MODE) {
     $element['log'] = array('#type' => 'value', '#value' => _hierarchical_select_log(NULL, TRUE));
@@ -716,7 +718,7 @@ function hierarchical_select_after_build
 function _hierarchical_select_validate(&$element, &$form_state) {
   // If the dropbox is enabled and a dropbox limit is configured, check if
   // this limit is not exceeded.
-  $config = $element['#config'];
+  $config = _hierarchical_select_inherit_default_config($element['#config']);
   if ($config['dropbox']['status']) {
     if ($config['dropbox']['limit'] > 0) { // Zero as dropbox limit means no limit.
       // TRICKY: #element_validate is not called upon the initial rendering
@@ -795,7 +797,7 @@ function _hierarchical_select_submit($fo
  */
 function _hierarchical_select_process_get_hs_selection($element) {
   $hs_selection = array();
-  $config = $element['#config'];
+  $config = _hierarchical_select_inherit_default_config($element['#config']);
 
   if (count($element['#value']['hierarchical_select']['selects'])) {
     if ($config['save_lineage']) {
@@ -897,7 +899,7 @@ function _hierarchical_select_process_ca
   $hs_selection = array(); // hierarchical select selection
   $db_selection = array(); // dropbox selection
 
-  $config = $element['#config'];
+  $config = _hierarchical_select_inherit_default_config($element['#config']);
   $dropbox = (bool) $config['dropbox']['status'];
   $op = $element['#post']['op'];
 
@@ -1212,6 +1214,36 @@ function _hierarchical_select_process_ca
 // Private functions.
 
 /**
+ * Inherit the default config from Hierarchical Selects' hook_elements().
+ *
+ * @param $config
+ *   A config array with at least the following settings:
+ *   - module
+ *   - params
+ * @return
+ *   An updated config array.
+ */
+function _hierarchical_select_inherit_default_config($config, $defaults_override = array()) {
+  // Set defaults for unconfigured settings. Get the defaults from our
+  // hook_elements() implementation. Default properties from this hook are
+  // applied automatically, but properties inside properties, such as is the
+  // case for Hierarchical Select's #config property, aren't applied.
+  $type = hierarchical_select_elements();
+  $defaults = $type['hierarchical_select']['#config'];
+  // Don't inherit the module and params settings.
+  unset($defaults['module']);
+  unset($defaults['params']);
+
+  // Allow the defaults to be overridden.
+  $defaults = array_smart_merge($defaults, $defaults_override);
+
+  // Apply the defaults to the config.
+  $config = array_smart_merge($defaults, $config);
+
+  return $config;
+}
+
+/**
  * Helper function to add the required Javascript files and settings.
  */
 function _hierarchical_select_setup_js() {
@@ -2015,7 +2047,7 @@ function _hierarchical_select_dropbox_re
 
   foreach ($selection as $key => $item) {
     // Create new lineage if the item can be found in the root level.
-    if (in_array($item, array_keys($root_level))) {
+    if (array_key_exists($item, $root_level)) {
       $lineages[][0] = array('value' => $item, 'label' => $root_level[$item]);
       unset($selection[$key]);
     }
@@ -2098,3 +2130,22 @@ function _hierarchical_select_dropbox_li
 function _hierarchical_select_dropbox_lineage_item_get_value($item) {
   return $item['value'];
 }
+
+/**
+ * Smarter version of array_merge_recursive: overwrites scalar values.
+ *
+ * From: http://www.php.net/manual/en/function.array-merge-recursive.php#82976.
+ */
+function array_smart_merge($array, $override) {
+  if (is_array($array) && is_array($override)) {
+    foreach ($override as $k => $v) {
+      if (isset($array[$k]) && is_array($v) && is_array($array[$k])) {
+        $array[$k] = array_smart_merge($array[$k], $v);
+      }
+      else {
+        $array[$k] = $v;
+      }
+    }
+  }
+  return $array;
+}
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/includes/common.inc,v
retrieving revision 1.24
diff -u -F^f -r1.24 common.inc
--- includes/common.inc	25 Jul 2009 10:27:59 -0000	1.24
+++ includes/common.inc	25 Jul 2009 14:48:19 -0000
@@ -18,39 +18,7 @@
  */
 function hierarchical_select_common_config_get($config_id, $defaults_override = array()) {
   $config = variable_get('hs_config_'. $config_id, array());
-
-  // Set defaults for unconfigured settings.
-  $defaults = array(
-    'config_id' => $config_id,
-    'save_lineage'    => 0,
-    'enforce_deepest' => 0,
-    'entity_count'    => 0,
-    'require_entity'  => 0,
-    'resizable'       => 1,
-    'level_labels' => array(
-      'status' => 0,
-    ),
-    'dropbox' => array(
-      'status'   => 0,
-      'limit'    => 0,
-      'reset_hs' => 1,
-    ),
-    'editability' => array(
-      'status'           => 0,
-      'item_types'       => array(),
-      'allowed_levels'   => array(),
-      'allow_new_levels' => 0,
-      'max_levels'       => 3,
-    ),
-  );
-
-  // Allow new defaults to be set.
-  $defaults = array_smart_merge($defaults, $defaults_override);
-
-  // Set defaults for settings not yet set in the configuration.
-  $config = array_smart_merge($defaults, $config);
-
-  return $config;
+  return _hierarchical_select_inherit_default_config($config, $defaults_override);
 }
 
 /**
@@ -420,22 +388,3 @@ function _hierarchical_select_get_form_i
     return $form;
   }
 }
-
-/**
- * Smarter version of array_merge_recursive: overwrites scalar values.
- *
- * From: http://www.php.net/manual/en/function.array-merge-recursive.php#82976.
- */
-function array_smart_merge($array, $override) {
-  if (is_array($array) && is_array($override)) {
-    foreach ($override as $k => $v) {
-      if (isset($array[$k]) && is_array($v) && is_array($array[$k])) {
-        $array[$k] = array_smart_merge($array[$k], $v);
-      }
-      else {
-        $array[$k] = $v;
-      }
-    }
-  }
-  return $array;
-}
