Index: theme/flag.tpl.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/flag/theme/Attic/flag.tpl.php,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 flag.tpl.php
--- theme/flag.tpl.php	10 Oct 2008 06:52:31 -0000	1.1.2.3
+++ theme/flag.tpl.php	20 Oct 2008 02:22:55 -0000
@@ -12,6 +12,7 @@
  *   following variables don't suffice.
  * - $flag_name_css: The flag name, with all "_" replaced with "-". For use in 'class'
  *   attributes.
+ * - $flag_classes: A space-separated list of CSS classes that should be applied to the link.
  *
  * - $action: The action the link is about to carry out, either "flag" or "unflag".
  * - $last_action: The action, as a passive English verb, either "flagged" or 
@@ -40,7 +41,7 @@
   }
 ?>
 <span class="flag-wrapper flag-<?php echo $flag_name_css; ?>">
-  <a href="<?php echo $link_href; ?>" title="<?php echo $link_title; ?>" class="flag <?php echo $action; ?>-action <?php echo $after_flagging ? $last_action : ''; ?>"><?php echo $link_text; ?></a><span class="flag-throbber">&nbsp;</span>
+  <a href="<?php echo $link_href; ?>" title="<?php echo $link_title; ?>" class="<?php print $flag_classes ?>"><?php echo $link_text; ?></a><span class="flag-throbber">&nbsp;</span>
   <?php if ($after_flagging): ?>
     <span class="flag-message flag-<?php echo $last_action; ?>-message">
       <?php echo $message_text; ?>
Index: theme/flag.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/flag/theme/Attic/flag.js,v
retrieving revision 1.1.2.4
diff -u -r1.1.2.4 flag.js
--- theme/flag.js	10 Oct 2008 06:52:31 -0000	1.1.2.4
+++ theme/flag.js	20 Oct 2008 02:22:55 -0000
@@ -91,7 +91,7 @@
     return false;
   }
 
-  $('a.flag:not(.flag-processed)').addClass('flag-processed').click(flagClick);
+  $('a.flag-link-toggle:not(.flag-processed)').addClass('flag-processed').click(flagClick);
 };
 
 
Index: flag.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/flag/Attic/flag.module,v
retrieving revision 1.11.2.48
diff -u -r1.11.2.48 flag.module
--- flag.module	13 Oct 2008 11:29:01 -0000	1.11.2.48
+++ flag.module	20 Oct 2008 02:22:55 -0000
@@ -60,6 +60,14 @@
     'access arguments' => array('access content'),
     'type' => MENU_CALLBACK,
   );
+  $items['flag/confirm'] = array(
+    'title' => 'Flag confirm',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('flag_confirm'),
+    'access callback' => 'user_access',
+    'access arguments' => array('access content'),
+    'type' => MENU_CALLBACK,
+  );
 
   return $items;
 }
@@ -488,11 +496,18 @@
     '#description' => t('The description of the "flag this" link. Usually displayed on mouseover.'),
   );
 
+  $form['flag_confirmation'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Flag confirmation message'),
+    '#default_value' => $flag->flag_confirmation,
+    '#description' => t('Message displayed if the user has clicked the "flag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to flag this content?"'),
+  );
+
   $form['flag_message'] = array(
     '#type' => 'textfield',
     '#title' => t('Flagged message'),
     '#default_value' => $flag->flag_message,
-    '#description' => t('Message displayed when the user has clicked the "flag this" link. If javascript is enabled, it will be displayed below the link. If not, it will be displayed in the message area.'),
+    '#description' => t('Message displayed after flagging content. If JavaScript is enabled, it will be displayed below the link. If not, it will be displayed in the message area.'),
   );
 
   $form['unflag_short'] = array(
@@ -510,11 +525,18 @@
     '#description' => t('The description of the "unflag this" link. Usually displayed on mouseover.'),
   );
 
+  $form['unflag_confirmation'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Unflag confirmation message'),
+    '#default_value' => $flag->unflag_confirmation,
+    '#description' => t('Message displayed if the user has clicked the "unflag this" link and confirmation is required. Usually presented in the form of a question such as, "Are you sure you want to unflag this content?"'),
+  );
+
   $form['unflag_message'] = array(
     '#type' => 'textfield',
     '#title' => t('Unflagged message'),
     '#default_value' => $flag->unflag_message,
-    '#description' => t('Message displayed when the user has clicked the "unflag this" link. If javascript is enabled, it will be displayed below the link. If not, it will be displayed in the message area.'),
+    '#description' => t('Message displayed after content has been unflagged. If JavaScript is enabled, it will be displayed below the link. If not, it will be displayed in the message area.'),
   );
 
   if (module_exists('token')) {
@@ -564,6 +586,18 @@
     '#tree' => FALSE,
   );
 
+  $form['display']['link_type'] = array(
+    '#type' => 'radios',
+    '#title' => t('Link type'),
+    '#options' => array(
+      'toggle' => t('JavaScript toggle'),
+      'normal' => t('Normal link'),
+      'confirm' => t('Confirmation form'),
+    ),
+    '#default_value' => $this->link_type,
+    '#weight' => 2,
+  );
+
   $form['submit'] = array(
     '#type' => 'submit',
     '#value' => t('Submit'),
@@ -581,8 +615,20 @@
  * Add/Edit flag form validate.
  */
 function flag_form_validate($form, &$form_state) {
+  $form_values = $form_state['values'];
+
+  if ($form_values['link_type'] == 'confirm') {
+    if (empty($form_values['flag_confirmation'])) {
+      form_set_error('flag_confirmation', t('A flag confirmation message is required when using the confirmation link type.'));
+    }
+    if (empty($form_values['unflag_confirmation'])) {
+      form_set_error('unflag_confirmation', t('An unflag confirmation message is required when using the confirmation link type.'));
+    }
+  }
+
+
   $flag = $form['#flag'];
-  $flag->form_input($form_state['values']);
+  $flag->form_input($form_values);
   $flag->validate();
 }
 
@@ -649,8 +695,9 @@
  *
  * Used both for the regular callback as well as the JS version.
  */
-function flag_page($action, $flag_name, $content_id, $token) {
+function flag_page($action, $flag_name, $content_id) {
   $js = isset($_REQUEST['js']);
+  $token = $_REQUEST['token'];
 
   // Check the flag token, then perform the flagging.
   if (!flag_check_token($token, $content_id)) {
@@ -684,6 +731,7 @@
   if ($js) {
     drupal_set_header('Content-Type: text/javascript; charset=utf-8');
     $flag = flag_get_flag($flag_name);
+    $flag->link_type = 'toggle';
     print drupal_to_js(array(
       'status' => TRUE,
       'newLink' => $flag->theme($flag->is_flagged($content_id) ? 'unflag' : 'flag', $content_id, TRUE),
@@ -698,6 +746,37 @@
 }
 
 /**
+ * Form for confirming the (un)flagging of a piece of content.
+ */
+function flag_confirm(&$form_state, $action = 'flag', $flag_name, $content_id = '') {
+  $form = array();
+
+  $form['action'] = array(
+    '#type' => 'value',
+    '#value' => $action,
+  );
+  $form['flag_name'] = array(
+    '#type' => 'value',
+    '#value' => $flag_name,
+  );
+  $form['content_id'] = array(
+    '#type' => 'value',
+    '#value' => $content_id,
+  );
+
+  $flag = flag_get_flag($flag_name);
+  $question = $flag->get_label($action .'_confirmation', $content_id);
+  $path = isset($_GET['destination']) ? $_GET['destination'] : '<front>';
+  $yes = $flag->get_label($action .'_short', $content_id);
+
+  return confirm_form($form, $question, $path, '', $yes);
+}
+
+function flag_confirm_submit(&$form, &$form_state) {
+  flag_page($form_state['values']['action'], $form_state['values']['flag_name'], $form_state['values']['content_id']);
+}
+
+/**
  * Flags, on unflags, an item.
  *
  * @param $account
@@ -827,18 +906,29 @@
   $action = $variables['action'];
   $content_id = $variables['content_id'];
 
-  $variables['setup'] = $first_time;
-  $first_time = FALSE;
+  if ($flag->link_type == 'toggle' && $first_time) {
+    $variables['setup'] = $first_time;
+    $first_time = FALSE;
+  }
+
   $token = flag_get_token($content_id);
-  $variables['link_href'] = check_url(url("flag/$action/$flag->name/$content_id/$token", array('query' => drupal_get_destination())));
+  $variables['link_href'] = check_url(url("flag/". ($flag->link_type == 'confirm' ? 'confirm/' : '') ."$action/$flag->name/$content_id", array('query' => drupal_get_destination() .'&token='. $token)));
   $variables['link_text'] = strip_tags($flag->get_label($action . '_short', $content_id), '<em><strong><img>');
   $variables['link_title'] = strip_tags($flag->get_label($action . '_long', $content_id));
   $variables['flag_name_css'] = str_replace('_', '-', $flag->name);
   $variables['last_action'] = ($action == 'flag' ? 'unflagged' : 'flagged');
+  $variables['flag_classes_array'] = array();
+  $variables['flag_classes_array'][] = 'flag';
+  $variables['flag_classes_array'][] = $variables['action'] .'-action';
+  $variables['flag_classes_array'][] = 'flag-link-'. $flag->link_type;
+
   if ($variables['after_flagging']) {
     $inverse_action = ($action == 'flag' ? 'unflag' : 'flag');
     $variables['message_text'] = $flag->get_label($inverse_action . '_message', $content_id);
+    $variables['flag_classes_array'][] = $variables['last_action'];
   }
+
+  $variables['flag_classes'] = implode(' ', $variables['flag_classes_array']);
 }
 
 /**
Index: flag.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/flag/Attic/flag.inc,v
retrieving revision 1.1.2.19
diff -u -r1.1.2.19 flag.inc
--- flag.inc	16 Oct 2008 16:13:00 -0000	1.1.2.19
+++ flag.inc	20 Oct 2008 02:22:55 -0000
@@ -166,9 +166,12 @@
       'flag_short' => '',
       'flag_long' => '',
       'flag_message' => '',
+      'flag_confirmation' => '',
       'unflag_short' => '',
       'unflag_long' => '',
       'unflag_message' => '',
+      'unflag_confirmation' => '',
+      'link_type' => 'toggle',
     );
   }
 
Index: includes/flag_handler_field_ops.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/flag/includes/Attic/flag_handler_field_ops.inc,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 flag_handler_field_ops.inc
--- includes/flag_handler_field_ops.inc	18 Sep 2008 15:37:47 -0000	1.1.2.2
+++ includes/flag_handler_field_ops.inc	20 Oct 2008 02:22:55 -0000
@@ -34,6 +34,22 @@
     }
   }
 
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
+    $form['link_type'] = array(
+      '#type' => 'radios',
+      '#title' => t('Link type'),
+      '#options' => array(
+        '' => t('Use flag link settings'),
+        'toggle' => t('JavaScript toggle'),
+        'normal' => t('Normal link'),
+        'confirm' => t('Confirmation form'),
+      ),
+      '#default_value' => $this->options['link_type'],
+    );
+  }
+
   /**
    * Override base ::query(). The purpose here is to make it possible for the
    * render() method to know two things: what's the content ID, and whether
@@ -110,7 +126,10 @@
       // Flag does not apply to this content.
       return;
     }
-    
+
+    if (!empty($this->options['link_type'])) {
+      $flag->link_type = $this->options['link_type'];
+    }
     return $flag->theme($is_flagged ? 'unflag' : 'flag', $content_id);
   }
 }
