Index: docroot/sites/extern/modules/patched/conditional_fields/conditional_fields.module
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- a/conditional_fields.module	(date 1544529574000)
+++ a/conditional_fields.module	(date 1544529797000)
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @file
  * Define dependencies between fields based on their states and values.
@@ -218,14 +219,15 @@
  * - Field dependencies data.
  */
 function conditional_fields_element_after_build($element, &$form_state) {
-  // Ensure that the element is a field.
-  if (isset($element['#field_name'])) {
-    $field = $element;
-  }
-  elseif (isset($element['#language'], $element[$element['#language']], $element[$element['#language']]['#field_name'])) {
-    // Some fields are wrapped in containers before processing.
+  // Some fields are wrapped in containers before processing. Wrapped data must
+  // take precedence over the container, because Entity Translation and
+  // possibly other modules add #field_name to the container as well.
+  if (isset($element['#language'], $element[$element['#language']], $element[$element['#language']]['#field_name'])) {
     $field = $element[$element['#language']];
   }
+  elseif (isset($element['#field_name'])) {
+    $field = $element;
+  }
   else {
     return $element;
   }
@@ -245,6 +247,9 @@
     $entity_type = $field['#entity_type'];
     $bundle = $field['#bundle'];
   }
+  elseif (isset($field[0]['#entity_type']) && $bundle = _conditional_fields_field_parent_bundle($field)) {
+    $entity_type = $field[0]['#entity_type'];
+  }
   elseif (isset($form['#entity_type'], $form['#bundle'])) {
     $entity_type = $form['#entity_type'];
     $bundle = $form['#bundle'];
@@ -259,11 +264,13 @@
     return $element;
   }
 
-  // Attach dependent.
-  if (isset($dependencies['dependents'][$field['#field_name']])) {
+  $field_parents_key = implode(':', $field['#field_parents']);
+
+  if (isset($dependencies['dependents'][$field['#field_name']])) {
+    // Attach dependent.
     foreach ($dependencies['dependents'][$field['#field_name']] as $id => $dependency) {
-      if (!isset($form['#conditional_fields'][$field['#field_name']]['dependees'][$id])) {
-        conditional_fields_attach_dependency($form, array('#field_name' => $dependency['dependee']), $field, $dependency['options'], $id);
+      if (!isset($form['#conditional_fields'][$field_parents_key][$field['#field_name']]['dependees'][$id])) {
+        conditional_fields_attach_dependency($form, array('#field_name' => $dependency['dependee']), $field, $dependency['options'], $id, $field_parents_key);
       }
     }
   }
@@ -274,8 +281,8 @@
   // define per-element sets of dependency values.
   if (isset($dependencies['dependees'][$field['#field_name']])) {
     foreach ($dependencies['dependees'][$field['#field_name']] as $id => $dependency) {
-      if (!isset($form['#conditional_fields'][$field['#field_name']]['dependents'][$id])) {
-        conditional_fields_attach_dependency($form, $field, array('#field_name' => $dependency['dependent']), $dependency['options'], $id);
+      if (!isset($form['#conditional_fields'][$field_parents_key][$field['#field_name']]['dependents'][$id])) {
+        conditional_fields_attach_dependency($form, $field, array('#field_name' => $dependency['dependent']), $dependency['options'], $id, $field_parents_key);
       }
     }
   }
@@ -301,6 +308,8 @@
  *   the array are #field_name and #field_parents.
  * @param $options
  *   An array of dependency options with the following key/value pairs:
+ *   (You don't need to manually set all these options, because default
+ *   settings are always provided.)
  *   - state: The state applied to the dependent when the dependency is
  *     triggered. See conditional_fields_states() for available states.
  *   - condition: The condition for the dependency to be triggered. See
@@ -346,14 +355,16 @@
  *     where the keys are role ids and the values are arrays with the same
  *     structure of 'element_edit'.
  *   - selector: (optional) Custom jQuery selector for the dependee.
+ *   Note that you don't need to manually set all these options, since default
+ *   settings are always provided.
  * @param $id
  *   (internal use) The identifier for the dependency. Omit this parameter when
  *   attaching a custom dependency.
- *
- *   Note that you don't need to manually set all these options, since default
- *   settings are always provided.
+ * @param $field_parents_key
+ *   (internal use) The field parents structure of the dependent field. Omit
+ *   this parameter when attaching a custom dependency.
  */
-function conditional_fields_attach_dependency(&$form, $dependee, $dependent, $options, $id = 0) {
+function conditional_fields_attach_dependency(&$form, $dependee, $dependent, $options, $id = 0, $field_parents_key = '') {
   $options += conditional_fields_dependency_default_options();
 
   // The absence of the $id parameter identifies a custom dependency.
@@ -378,14 +389,18 @@
       $id = $current_id;
       $current_id++;
     }
+
+    if (!$field_parents_key) {
+      $field_parents_key = implode(':', $dependent['#field_parents']);
+    }
   }
 
   // Attach dependee.
   // Use the #array_parents property of the dependee instead of #field_parents
   // since we will need access to the full structure of the widget.
   if (isset($dependee['#parents'])) {
-    $form['#conditional_fields'][$dependee['#field_name']]['parents'] = $dependee['#array_parents'];
-    $form['#conditional_fields'][$dependee['#field_name']]['dependents'][$id] = array(
+    $form['#conditional_fields'][$field_parents_key][$dependee['#field_name']]['parents'] = $dependee['#array_parents'];
+    $form['#conditional_fields'][$field_parents_key][$dependee['#field_name']]['dependents'][$id] = array(
       'dependent' => $dependent['#field_name'],
       'options'   => $options,
     );
@@ -399,8 +414,8 @@
     $dependent_parents = $dependent['#parents'];
   }
   if (isset($dependent_parents)) {
-    $form['#conditional_fields'][$dependent['#field_name']]['field_parents'] = $dependent_parents;
-    $form['#conditional_fields'][$dependent['#field_name']]['dependees'][$id] = array(
+    $form['#conditional_fields'][$field_parents_key][$dependent['#field_name']]['field_parents'] = $dependent_parents;
+    $form['#conditional_fields'][$field_parents_key][$dependent['#field_name']]['dependees'][$id] = array(
       'dependee' => $dependee['#field_name'],
       'options'  => $options,
     );
@@ -428,211 +443,216 @@
   $state_handlers = conditional_fields_states_handlers();
 
   // Cycle all dependents.
-  foreach ($form['#conditional_fields'] as $dependent => $dependent_info) {
-    $states = array();
+  foreach ($form['#conditional_fields'] as $parent_dependent_key => $parent_dependent_info) {
+    foreach ($parent_dependent_info as $dependent => $dependent_info) {
+      $states = array();
 
-    if (empty($dependent_info['dependees'])) {
-      continue;
-    }
+      if (empty($dependent_info['dependees'])) {
+        continue;
+      }
 
-    $dependent_location = array_merge($dependent_info['field_parents'], array($dependent));
-    $dependent_form_field = drupal_array_get_nested_value($form, $dependent_location);
+      $dependent_location = array_merge($dependent_info['field_parents'], array($dependent));
+      $dependent_form_field = drupal_array_get_nested_value($form, $dependent_location);
 
-    // Cycle the dependant's dependees.
-    foreach ($dependent_info['dependees'] as $dependency) {
-      $dependee = $dependency['dependee'];
+      // Cycle the dependant's dependees.
+      foreach ($dependent_info['dependees'] as $dependency) {
+        $dependee = $dependency['dependee'];
 
-      if (empty($form['#conditional_fields'][$dependee])) {
-        continue;
-      }
+        if (empty($form['#conditional_fields'][$parent_dependent_key][$dependee])) {
+          continue;
+        }
 
-      $dependee_info = $form['#conditional_fields'][$dependee];
-      $dependee_form_field = drupal_array_get_nested_value($form, $dependee_info['parents']);
-      $options = $dependency['options'];
+        $dependee_info = $form['#conditional_fields'][$parent_dependent_key][$dependee];
+        $dependee_form_field = drupal_array_get_nested_value($form, $dependee_info['parents']);
+        $options = $dependency['options'];
 
-      // Load field edit behaviors.
-      // If this dependent has multiple dependees, only the logic of the first
-      // dependency will be taken into account.
-      if (!isset($behaviors)) {
-        $behaviors = conditional_fields_field_behaviors('edit', $options);
-      }
+        // Load field edit behaviors.
+        // If this dependent has multiple dependees, only the logic of the first
+        // dependency will be taken into account.
+        if (!isset($behaviors)) {
+          $behaviors = conditional_fields_field_behaviors('edit', $options);
+        }
 
-      // Determine if the dependee is in the form.
-      if (empty($dependee_form_field) || (isset($dependee_form_field['#access']) && $dependee_form_field['#access'] == FALSE)) {
-        // Apply orphan dependent behaviors.
-        /*
-        if (in_array(CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_UNTRIGGERED_ORPHAN, $behaviors)) {
-          // TODO
-          $is_triggered = TRUE;
+        // Determine if the dependee is in the form.
+        if (empty($dependee_form_field) || (isset($dependee_form_field['#access']) && $dependee_form_field['#access'] == FALSE)) {
+          // Apply orphan dependent behaviors.
+          /*
+          if (in_array(CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_UNTRIGGERED_ORPHAN, $behaviors)) {
+            // TODO
+            $is_triggered = TRUE;
 
-          if ($is_orphan && !$is_triggered) {
-            $form[$dependent]['#access'] = FALSE;
-          }
-        }
-        */
-        if (in_array(CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_ORPHAN, $behaviors)) {
-          $dependent_form_field['#access'] = FALSE;
-        }
-        unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_UNTRIGGERED_ORPHAN]);
-        unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_ORPHAN]);
-        unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_RESET_UNTRIGGERED]);
-        continue;
-      }
+            if ($is_orphan && !$is_triggered) {
+              $form[$dependent]['#access'] = FALSE;
+            }
+          }
+          */
+          if (in_array(CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_ORPHAN, $behaviors)) {
+            $dependent_form_field['#access'] = FALSE;
+          }
+          unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_UNTRIGGERED_ORPHAN]);
+          unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_ORPHAN]);
+          unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_RESET_UNTRIGGERED]);
+          continue;
+        }
 
-      unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_UNTRIGGERED_ORPHAN]);
-      unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_ORPHAN]);
+        unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_UNTRIGGERED_ORPHAN]);
+        unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_ORPHAN]);
 
-      // Build a jQuery selector if it was not overridden by a custom value.
-      // Note that this may be overridden later by a state handler.
-      if (!$options['selector']) {
-        $options['selector'] = conditional_fields_field_selector($dependee_form_field);
-      }
-      else {
-        // Replace the language placeholder in the selector with current language.
-        $options['selector'] = str_replace('%lang', $dependee_form_field['#language'], $options['selector']);
-      }
+        // Build a jQuery selector if it was not overridden by a custom value.
+        // Note that this may be overridden later by a state handler.
+        if (!$options['selector']) {
+          $options['selector'] = conditional_fields_field_selector($dependee_form_field);
+        }
+        else {
+          // Replace the language placeholder in the selector with current language.
+          $options['selector'] = str_replace('%lang', $dependee_form_field['#language'], $options['selector']);
+        }
 
-      if ($options['condition'] != 'value') {
-        // Conditions different than "value" are always evaluated against TRUE.
-        $state = array($options['state'] => array($options['selector'] => array($options['condition'] => TRUE)));
-      }
-      else {
-        // Build the values that trigger the dependency.
-        $values = array();
+        if ($options['condition'] != 'value') {
+          // Conditions different than "value" are always evaluated against TRUE.
+          $state = array($options['state'] => array($options['selector'] => array($options['condition'] => TRUE)));
+        }
+        else {
+          // Build the values that trigger the dependency.
+          $values = array();
 
-        if ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_WIDGET) {
-          $values[$options['condition']] = $options['value_form'];
-        }
-        elseif ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_REGEX) {
-          $values[$options['condition']] = $options['value'];
-        }
-        elseif ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_AND) {
-          $values[$options['condition']] = count($options['values']) == 1 ? $options['values'][0] : $options['values'];
-        }
-        else {
-          if ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_XOR) {
-            // XOR behaves like OR with added 'xor' element.
-            $values[] = 'xor';
-          }
-          elseif ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_NOT) {
-            // NOT behaves like OR with switched state.
-            $options['state'] = strpos($options['state'], '!') === 0 ? drupal_substr($options['state'], 1) : '!' . $options['state'];
-          }
+          if ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_WIDGET) {
+            $values[$options['condition']] = $options['value_form'];
+          }
+          elseif ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_REGEX) {
+            $values[$options['condition']] = $options['value'];
+          }
+          elseif ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_AND) {
+            $values[$options['condition']] = count($options['values']) == 1 ? $options['values'][0] : $options['values'];
+          }
+          else {
+            if ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_XOR) {
+              // XOR behaves like OR with added 'xor' element.
+              $values[] = 'xor';
+            }
+            elseif ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_NOT) {
+              // NOT behaves like OR with switched state.
+              $options['state'] = strpos($options['state'], '!') === 0 ? drupal_substr($options['state'], 1) : '!' . $options['state'];
+            }
 
-          // OR, NOT and XOR conditions are obtained with a nested array.
-          foreach ($options['values'] as $value) {
-            $values[] = array($options['condition'] => $value);
-          }
-        }
+            // OR, NOT and XOR conditions are obtained with a nested array.
+            foreach ($options['values'] as $value) {
+              $values[] = array($options['condition'] => $value);
+            }
+          }
 
-        $state = array($options['state'] => array($options['selector'] => $values));
-        $dependee_form_state = isset($dependee_form_field['#field_parents'], $dependee_form_field['#field_name'], $dependee_form_field['#language']) ? field_form_get_state($dependee_form_field['#field_parents'], $dependee_form_field['#field_name'], $dependee_form_field['#language'], $form_state) : NULL;
+          $state = array($options['state'] => array($options['selector'] => $values));
+          $dependee_form_state = isset($dependee_form_field['#field_parents'], $dependee_form_field['#field_name'], $dependee_form_field['#language']) ? field_form_get_state($dependee_form_field['#field_parents'], $dependee_form_field['#field_name'], $dependee_form_field['#language'], $form_state) : NULL;
 
-        // Execute special handler for fields that need further processing.
-        // The handler has no return value. Modify the $state parameter by
-        // reference if needed.
-        foreach ($state_handlers as $handler => $handler_conditions) {
-          if (array_intersect_assoc($handler_conditions, $dependee_form_field) == $handler_conditions) {
-            $handler($dependee_form_field, $dependee_form_state, $options, $state);
+          // Execute special handler for fields that need further processing.
+          // The handler has no return value. Modify the $state parameter by
+          // reference if needed.
+          foreach ($state_handlers as $handler => $handler_conditions) {
+            if (array_intersect_assoc($handler_conditions, $dependee_form_field) == $handler_conditions) {
+              $handler($dependee_form_field, $dependee_form_state, $options, $state);
+            }
           }
         }
 
-        // Add validation callback to element.
-        _conditional_fields_element_add_property($dependent_form_field, '#element_validate', 'conditional_fields_dependent_validate', 'append');
-      }
+        // Add validation callback to element if the dependency can be evaluated.
+        if (in_array($options['condition'], array('value', 'empty', '!empty'))) {
+          _conditional_fields_element_add_property($dependent_form_field, '#element_validate', 'conditional_fields_dependent_validate', 'append');
+        }
 
-      // Add the $state into the correct logic group in $states.
-      foreach ($state as $key => $constraints) {
-        if (empty($states[$key][$options['grouping']])) {
-          $states[$key][$options['grouping']] = $constraints;
-        }
-        else {
-          $states[$key][$options['grouping']] = array_merge($states[$key][$options['grouping']], $constraints);
-        }
-      }
+        if (isset($state)) {
+          // Add the $state into the correct logic group in $states.
+          foreach ($state as $key => $constraints) {
+            foreach ($constraints as $selector => $constraint) {
+              // Add the constraint in an array to avoid overwriting other
+              // dependencies' states with the same selector.
+              $states[$key][$options['grouping']][$selector][] = $constraint;
+            }
 
-      // Build effect settings for effects with options.
-      // TODO: add dependee key to allow different effects on the same selector.
-      if ($options['effect'] && $options['effect'] != 'show') {
-        $selector = conditional_fields_field_selector(drupal_array_get_nested_value($form, array($dependent_location[0])));
-        // Convert numeric strings to numbers.
-        foreach ($options['effect_options'] as &$effect_option) {
-          if (is_numeric($effect_option)) {
-            $effect_option += 0;
-          }
-        }
-        $effects[$selector] = array(
-          'effect' => $options['effect'],
-          'options' => $options['effect_options'],
-        );
-      }
+            // Build effect settings for effects with options.
+            // TODO: add dependee key to allow different effects on the same selector.
+            if ($options['effect'] && $options['effect'] != 'show') {
+              $selector = conditional_fields_field_selector(drupal_array_get_nested_value($form, array($dependent_location[0])));
+              // Convert numeric strings to numbers.
+              foreach ($options['effect_options'] as &$effect_option) {
+                if (is_numeric($effect_option)) {
+                  $effect_option += 0;
+                }
+              }
+              $effects[$selector] = array(
+                'effect' => $options['effect'],
+                'options' => $options['effect_options'],
+              );
+            }
 
-      // Apply reset dependent to default if untriggered behavior.
-      if (in_array(CONDITIONAL_FIELDS_FIELD_EDIT_RESET_UNTRIGGERED, $behaviors)) {
-        // Add property to element so conditional_fields_dependent_validate() can
-        // pick it up.
-        $dependent_form_field['#conditional_fields_reset_if_untriggered'] = TRUE;
-        unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_RESET_UNTRIGGERED]);
-      }
-    }
+            // Apply reset dependent to default if untriggered behavior.
+            if (in_array(CONDITIONAL_FIELDS_FIELD_EDIT_RESET_UNTRIGGERED, $behaviors)) {
+              // Add property to element so conditional_fields_dependent_validate() can
+              // pick it up.
+              $dependent_form_field['#conditional_fields_reset_if_untriggered'] = TRUE;
+              unset($behaviors[CONDITIONAL_FIELDS_FIELD_EDIT_RESET_UNTRIGGERED]);
+            }
+          }
+        }
+      }
 
-    // Execute custom behaviors callbacks.
-    if (!empty($behaviors)) {
-      foreach ($behaviors as $behavior) {
-        $behavior($form, $form_state, $dependent, $dependent_info);
-      }
-    }
+      // Execute custom behaviors callbacks.
+      if (!empty($behaviors)) {
+        foreach ($behaviors as $behavior) {
+          $behavior($form, $form_state, $dependent, $dependent_info);
+        }
+      }
 
-    unset($behaviors);
+      unset($behaviors);
 
-    if (empty($states)) {
-      continue;
-    }
+      if (empty($states)) {
+        continue;
+      }
 
-    // Save the modified field back into the form.
-    drupal_array_set_nested_value($form, $dependent_location, $dependent_form_field);
+      // Save the modified field back into the form.
+      drupal_array_set_nested_value($form, $dependent_location, $dependent_form_field);
 
-    // Map the states based on the conjunctions.
-    $states_new = array();
-    foreach ($states as $state_key => $value) {
-      // As the main object is ANDed together we can add the AND items directly.
-      if (!empty($states[$state_key]['AND'])) {
-        $states_new[$state_key] = $states[$state_key]['AND'];
-      }
-      // The OR and XOR groups are moved into a sub-array that has numeric keys
-      // so that we get a JSON array and not an object, as required by the States
-      // API for OR and XOR groupings.
-      if (!empty($states[$state_key]['OR'])) {
-        $or = array();
-        foreach ($states[$state_key]['OR'] as $constraint_key => $constraint_value) {
-          $or[] = array($constraint_key => $constraint_value);
-        }
-        // '1' as a string so that we get an object (which means logic groups
-        // are ANDed together).
-        $states_new[$state_key]['1'] = $or;
-      }
-      if (!empty($states[$state_key]['XOR'])) {
-        $xor = array('xor');
-        foreach ($states[$state_key]['XOR'] as $constraint_key => $constraint_value) {
-          $xor[] = array($constraint_key => $constraint_value);
-        }
-        // '2' as a string so that we get an object.
-        $states_new[$state_key]['2'] = $xor;
-      }
-    }
-    $states = $states_new;
+      // Map the states based on the conjunctions.
+      $states_new = array();
+      foreach ($states as $state_key => $value) {
+        // As the main object is ANDed together we can add the AND items directly.
+        if (!empty($states[$state_key]['AND'])) {
+          $states_new[$state_key] = $states[$state_key]['AND'];
+        }
+        // The OR and XOR groups are moved into a sub-array that has numeric keys
+        // so that we get a JSON array and not an object, as required by the States
+        // API for OR and XOR groupings.
+        if (!empty($states[$state_key]['OR'])) {
+          $or = array();
+          foreach ($states[$state_key]['OR'] as $constraint_key => $constraint_value) {
+            $or[] = array($constraint_key => $constraint_value);
+          }
+          // '1' as a string so that we get an object (which means logic groups
+          // are ANDed together).
+          $states_new[$state_key]['1'] = $or;
+        }
+        if (!empty($states[$state_key]['XOR'])) {
+          $xor = array('xor');
+          foreach ($states[$state_key]['XOR'] as $constraint_key => $constraint_value) {
+            $xor[] = array($constraint_key => $constraint_value);
+          }
+          // '2' as a string so that we get an object.
+          $states_new[$state_key]['2'] = $xor;
+        }
+      }
+      $states = $states_new;
 
-    // Add the #states property to the dependent field.
-    drupal_array_set_nested_value($form, array_merge($dependent_location, array('#states')), $states);
+      // Add the #states property to the dependent field.
+      drupal_array_set_nested_value($form, array_merge($dependent_location, array('#states')), $states);
 
-    $has_states = TRUE;
+      $has_states = TRUE;
+    }
   }
 
   if (empty($has_states)) {
     return $form;
   }
 
-  $form['#attached']['js'][] = drupal_get_path('module', 'conditional_fields') . '/js/conditional_fields.js';
+  $form['#attached']['library'][] = array('conditional_fields', 'conditional_fields');
 
   // Add effect settings to the form.
   if ($effects) {
@@ -680,7 +700,6 @@
   // have been validated to avoid collision between dependencies.
   $form_state_addition['parents'] = $dependent['#array_parents'];
 
-
   // Optional behavior: reset the field to its default values.
   // Default values are always valid, so it's safe to skip validation.
   if (!empty($element['#conditional_fields_reset_if_untriggered'])) {
@@ -712,13 +731,13 @@
 }
 
 /**
- * Extracts submitted field values during form validation.
+ * Extracts field values from a field element of a submitted form.
  *
  * @return
  *   The requested field values parent. Actual field vales are stored under the
  *   key $element['#field_name'].
  */
-function conditional_fields_form_field_get_values($element, $form_state) {
+function conditional_fields_field_get_values($element, $form_state) {
   // Fall back to #parents to support custom dependencies.
   $parents = !empty($element['#field_parents']) ? $element['#field_parents'] : $element['#parents'];
   return drupal_array_get_nested_value($form_state['values'], $parents);
@@ -743,7 +762,7 @@
 
   foreach ($form_state['conditional_fields_untriggered_dependents'] as $field) {
     $dependent = drupal_array_get_nested_value($form, $field['parents']);
-    $field_values_location = conditional_fields_form_field_get_values($dependent, $form_state);
+    $field_values_location = conditional_fields_field_get_values($dependent, $form_state);
 
     // If we couldn't find a location for the field's submitted values, let the
     // validation errors pass through to avoid security holes.
@@ -998,31 +1017,48 @@
  *   The field form element in the current language.
  */
 function conditional_fields_evaluate_dependencies($dependent, $form, $form_state) {
-  $dependencies = $form['#conditional_fields'][$dependent['#field_name']]['dependees'];
+  $field_parents_key = implode(':', $dependent['#field_parents']);
+  $dependencies = $form['#conditional_fields'][$field_parents_key][$dependent['#field_name']]['dependees'];
   $evaluated_dependees = array();
 
   foreach ($dependencies as $dependency_id => $dependency) {
-    // Extract field values from submitted values.
-    $dependee = $dependency['dependee'];
-    $dependee_parents = $form['#conditional_fields'][$dependee]['parents'];
+    // Skip dependencies that can't be evaluated.
+    if (!in_array($dependency['options']['condition'], array('value', 'empty', '!empty'))) {
+      continue;
+    }
+
+    $values = conditional_fields_field_form_get_values($field_parents_key, $dependency['dependee'], $form, $form_state);
+
+    $evaluated_dependees[$dependent['#field_name']][$dependency['options']['grouping']][] = conditional_fields_evaluate_dependency('edit', $values, $dependency['options']);
+  }
+
+  return conditional_fields_evaluate_grouping($evaluated_dependees[$dependent['#field_name']]);
+}
+
+/**
+ * Extracts field values from a submitted form.
+ */
+function conditional_fields_field_form_get_values($field_parents_key, $field_name, $form, $form_state) {
+  if (empty($form['#conditional_fields'][$field_parents_key][$field_name])) {
+    return array();
+  }
+
+  $field_parents = $form['#conditional_fields'][$field_parents_key][$field_name]['parents'];
 
-    // We have the parents of the field, but depending on the entity type and
-    // the widget type, they may include additional elements that are actually
-    // part of the value. So we find the depth of the field inside the form
-    // structure and use the parents only up to that depth.
-    $dependee_parents_keys = array_flip($dependee_parents);
-    $dependee_parent = drupal_array_get_nested_value($form, array_slice($dependee_parents, 0, $dependee_parents_keys[$dependee]));
-    $values = conditional_fields_form_field_get_values($dependee_parent[$dependee], $form_state);
+  // We have the parents of the field, but depending on the entity type and
+  // the widget type, they may include additional elements that are actually
+  // part of the value. So we find the depth of the field inside the form
+  // structure and use the parents only up to that depth.
+  $field_parents_keys = array_flip($field_parents);
+  $field_parent = drupal_array_get_nested_value($form, array_slice($field_parents, 0, $field_parents_keys[$field_name]));
+  $values = conditional_fields_field_get_values($field_parent[$field_name], $form_state);
 
-    // Remove the language key.
-    if (isset($dependee_parent[$dependee]['#language'], $values[$dependee_parent[$dependee]['#language']])) {
-      $values = $values[$dependee_parent[$dependee]['#language']];
-    }
-
-    $evaluated_dependees[$dependent['#field_name']][$dependency['options']['grouping']][] = conditional_fields_evaluate_dependency('edit', $values, $dependency['options']);
+  // Remove the language key.
+  if (isset($field_parent[$field_name]['#language'], $values[$field_parent[$field_name]['#language']])) {
+    $values = $values[$field_parent[$field_name]['#language']];
   }
 
-  return conditional_fields_evaluate_grouping($evaluated_dependees[$dependent['#field_name']]);
+  return $values;
 }
 
 /**
@@ -1033,6 +1069,15 @@
  *   $values are extracted from an entity.
  */
 function conditional_fields_evaluate_dependency($context, $values, $options) {
+  if ($options['condition'] == 'empty') {
+    $options['values_set'] = CONDITIONAL_FIELDS_DEPENDENCY_VALUES_AND;
+    $options['values'] = array('');
+  }
+  elseif ($options['condition'] == '!empty') {
+    $options['values_set'] = CONDITIONAL_FIELDS_DEPENDENCY_VALUES_NOT;
+    $options['values'] = array('');
+  }
+
   if ($options['values_set'] == CONDITIONAL_FIELDS_DEPENDENCY_VALUES_WIDGET) {
     $dependency_values = $context == 'view' ? $options['value'] : $options['value_form'];
 
@@ -1427,6 +1472,24 @@
   );
 }
 
+/**
+ * Implements hook_library().
+ */
+function conditional_fields_library() {
+  return array(
+    'conditional_fields' => array(
+      'tile' => 'Conditional Fields',
+      'version' => '1.0.0',
+      'js' => array(
+        drupal_get_path('module', 'conditional_fields') . '/js/conditional_fields.js' => array('group' => JS_DEFAULT),
+      ),
+      'dependencies' => array(
+        array('system', 'drupal.states'),
+      ),
+    ),
+  );
+}
+
 /**
  * Builds a list of supported states that may be applied to a dependent field.
  */
@@ -1601,7 +1664,7 @@
   $behaviors = array(
     'edit' => array(
       CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_ORPHAN => t('Hide the dependent if the dependee is not in the form'),
-      CONDITIONAL_FIELDS_FIELD_EDIT_RESET_UNTRIGGERED => t('Reset the dependent to its default values when the form is submitted if the dependency is not triggered.') . '<br /><em>' . t('Note: This setting only applies if the condition is "Value" and may not work with some field types. Also, ensure that the default values are valid, since they will not be validated.') . '</em>',
+      CONDITIONAL_FIELDS_FIELD_EDIT_RESET_UNTRIGGERED => t('Reset the dependent to its default values when the form is submitted if the dependency is not triggered.') . '<br /><em>' . t('Note: This setting only applies if the condition is "Value", "Empty", or "Filled" and may not work with some field types. Also, ensure that the default values are valid, since they will not be validated.') . '</em>',
       // TODO: Implement. Settings are imported from D6 though, they just do nothing for now.
       /*
       CONDITIONAL_FIELDS_FIELD_EDIT_HIDE_UNTRIGGERED_ORPHAN => t('Hide the dependent if the dependee is not in the form and the dependency is not triggered.') . '<br /><em>' . t('Note: This setting is not currently not implemented and has no effect.') . '</em>',
@@ -1986,3 +2049,19 @@
     ),
   );
 }
+
+/**
+ * Returns a field's immediate parent bundle.
+ *
+ * @param  array $field A field structure extracted from a form array
+ * @return string|bool  The parent's bundle or FALSE if not found
+ */
+function _conditional_fields_field_parent_bundle($field) {
+  $languages = array_keys(language_list());
+  foreach (array_reverse($field[0]['#field_parents']) as $parent) {
+    if (!is_numeric($parent) && $parent != LANGUAGE_NONE && !in_array($parent, $languages)) {
+      return $parent;
+    }
+  }
+  return FALSE;
+}

