Index: webform/includes/webform.conditionals.inc
===================================================================
--- webform/includes/webform.conditionals.inc	(revision 36404)
+++ webform/includes/webform.conditionals.inc	(working copy)
@@ -60,6 +60,7 @@
       '#actions' => array(
         'hide' => t('hide'),
         'show' => t('show'),
+        'skip-to' => t('skip to'),
       ),
       '#targets' => $target_list,
       '#weight' => $weight,
Index: webform/webform.module
===================================================================
--- webform/webform.module	(revision 36464)
+++ webform/webform.module	(working copy)
@@ -73,7 +73,7 @@
       $output .= '<p>' . t('Click on any existing component\'s name to edit its settings.') . '</p>';
       break;
     case 'node/%/webform/conditionals':
-      $output .= '<p>' . t('Conditionals may be used to hide or show certain components (or entire pages!) based on the value of other components.') . '</p>';
+      $output .= '<p>' . t('Conditionals may be used to hide or show certain components (or entire pages!) based on the value of other components.') . ' ' . t ('Note that a skip-to rule should point to a page break, not a question.') . '</p>';
       break;
     case 'node/%/submission/%/resend':
       $output .= '<p>' . t('This form may be used to resend e-mails configured for this webform. Check the e-mails that need to be sent and click <em>Resend e-mails</em> to send these e-mails again.') . '</p>';
@@ -2252,6 +2252,58 @@
     $operators = webform_conditional_operators();
     $conditionals = $target_map[$component['cid']];
     foreach ($conditionals as $conditional) {
+      if ($conditional['action'] == 'skip-to')
+        continue;
+      $conditional_result = _webform_evaluate_conditional ($node, $page_num, $conditional, $input_values, $format, $operators);
+
+      if ($conditional_result == WEBFORM_CONDITIONAL_SAME_PAGE) {
+        $show_component = WEBFORM_CONDITIONAL_SAME_PAGE;
+        break;
+      }
+
+      // Flip the result of the action is to hide.
+      if ($conditional['action'] == 'hide') {
+        $show_component = !$conditional_result;
+      }
+      else {
+        $show_component = $conditional_result;
+      }
+      // BdB: why don't we jump out of the look when $show_component is false?
+    }
+  }
+
+  // If our component can be skipped, check the conditionals as well
+  // Note that because of the page number checks, one must specify
+  // the preceding page break, not the next question is the component to
+  // skip to. That's not intuitive, but other methods evaluate far more
+  // components than necessary.
+  if ($show_component && ($page_num == 0 || $component['page_num'] == $page_num)) {
+    $conditionals = _webform_skip_conditionals ($node->webform, $target_map, $component);
+    if ($conditionals) {
+      module_load_include('inc', 'webform', 'includes/webform.conditionals');
+      $operators = webform_conditional_operators();
+      foreach ($conditionals as $conditional) {
+        $conditional_result = _webform_evaluate_conditional ($node, $page_num, $conditional, $input_values, $format, $operators);
+        // As we're skipping the component, negate result
+        $show_component = ! $conditional_result;
+        // BdB: why don't we jump out of the look when $show_component is false?
+      }
+    }
+  }
+
+  // Convert the result to our defined constants.
+  if (is_bool($show_component)) {
+    $show_component = $show_component ? WEBFORM_CONDITIONAL_INCLUDE : WEBFORM_CONDITIONAL_EXCLUDE;
+  }
+
+  return $show_component;
+}
+
+
+/**
+ * Result of evaluating given conditional
+ */
+function _webform_evaluate_conditional ($node, $page_num, $conditional, $input_values, $format, $operators) {
       $conditional_result = TRUE;
 
       // Execute each comparison callback.
@@ -2269,8 +2321,7 @@
         // component is needed, so we return the same page constant, which
         // evaluates to TRUE (a value of 2).
         if ($format === 'form' && $source_component['page_num'] == $page_num) {
-          $show_component = WEBFORM_CONDITIONAL_SAME_PAGE;
-          break 2;
+      return WEBFORM_CONDITIONAL_SAME_PAGE;
         }
 
         $source_values = array();
@@ -2295,24 +2346,52 @@
       else {
         $conditional_result = count($filtered_results) === count($conditional_results);
       }
+  return $conditional_result;
+}
 
-      // Flip the result of the action is to hide.
-      if ($conditional['action'] == 'hide') {
-        $show_component = !$conditional_result;
+
+/**
+ * All the conditionals that could cause the given component to be skipped.
+ */
+function _webform_skip_conditionals ($webform, $target_map, $component) {
+  $conditionals_to_evaluate = array();
+  foreach ($target_map as $cid => $conditionals) {
+    foreach ($conditionals as $conditional) {
+      if ($conditional['action'] == 'skip-to' && _webform_is_component_before_component ($webform, $component['cid'], $cid) && _webform_is_component_after_last_source ($webform, $component['cid'], $conditional)) {
+        $conditionals_to_evaluate[] = $conditional;
       }
-      else {
-        $show_component = $conditional_result;
       }
     }
+  return $conditionals_to_evaluate;
   }
 
-  // Convert the result to our defined constants.
-  if (is_bool($show_component)) {
-    $show_component = $show_component ? WEBFORM_CONDITIONAL_INCLUDE : WEBFORM_CONDITIONAL_EXCLUDE;
+
+/**
+ * Is component $cid ranked before $before_cid?
+ */
+function _webform_is_component_before_component ($webform, $cid, $before_cid) {
+  $order = array_keys ($webform['components']);
+  $pos1 = array_search ($cid, $order);
+  $pos2 = array_search ($before_cid, $order);
+  return $pos1 < $pos2;
   }
 
-  return $show_component;
+
+/**
+ * Does component $cid come after any of the sources mentioned in the $conditionals?
+ */
+function _webform_is_component_after_last_source ($webform, $cid, $conditional) {
+  $order = array_keys ($webform['components']);
+  $pos1 = array_search ($cid, $order);
+  $max_pos = -1;
+  foreach ($conditional['rules'] as $rule) {
+    $pos = array_search ($rule['source'], $order);
+    if ($pos > $max_pos)
+      $max_pos = $pos;
 }
+  return $pos1 > $max_pos;
+}
+
 
 /**
  * Add a component to a renderable array. Called recursively for fieldsets.
