Common subdirectories: video_upload_original\images and video_upload_fid\images
Common subdirectories: video_upload_original\providers and video_upload_fid\providers
Common subdirectories: video_upload_original\tests and video_upload_fid\tests
diff -upN video_upload_original\video_upload.admin.inc video_upload_fid\video_upload.admin.inc
--- video_upload_original\video_upload.admin.inc	Fri Sep 04 22:51:16 2009
+++ video_upload_fid\video_upload.admin.inc	Mon May 03 21:04:05 2010
@@ -488,8 +488,8 @@ function _video_upload_query_videos($con
   $params[':video_status_field'] = $db_info['columns']['video_status']['column'];
   $params[':video_status_field_2'] = $db_info['columns']['video_status']['column'];
   $params[':video_status'] = $status;
-  $params[':filefield_2'] = $db_info['columns']['fid']['column'];
   $multiple = $config['multiple'] ? ', delta' : '';
-  return db_query("SELECT %s AS video_id, nid, %s AS fid, %s AS video_status" . $multiple . " FROM {" . $db_info['table'] . "} t WHERE %s = '%s' AND %s IS NOT NULL", $params);
+
+  return db_query("SELECT %s AS video_id, nid, %s AS fid, %s AS video_status" . $multiple . " FROM {" . $db_info['table'] . "} t WHERE %s = '%s'", $params);
 }
   
diff -upN video_upload_original\video_upload.browser.inc video_upload_fid\video_upload.browser.inc
--- video_upload_original\video_upload.browser.inc	Fri Oct 10 21:02:57 2008
+++ video_upload_fid\video_upload.browser.inc	Mon May 03 22:25:34 2010
@@ -1,357 +1,182 @@
 <?php
-
-// $Id: video_upload.browser.inc,v 1.1 2008/10/10 19:02:57 jhedstrom Exp $
+// $Id$
 
 /**
  * @file video_upload.browser.inc
- *   Provides functions for the Browser upload method.
- *   @todo (Works for 5.x, but not yet in 6.x)
+ * Provides functions for the Browser upload method.
  */
 
 /**
- * Prepare form for the browser upload method (video transmitted
- * directly to 3rd party from the browser).
+ * Implementation of hook_widget().
+ *
+ * Copied from filefield.module
  */
-function _video_upload_browser_method_widget(&$form, &$form_state, $field, $items, $delta) {
-  // set form class (the jquery depends on this), and encoding type
-  $form['#attributes'] = array(
-    'class' => 'video-upload',
-    'enctype' => 'multipart/form-data',
+function _video_upload_browser_method_widget(&$form, &$form_state, $field, $items, $delta = 0) {
+  $item = array('list' => $field['list_default'], 'data' => array('description' => ''));
+  if (isset($items[$delta])) {
+    $item = array_merge($item, $items[$delta]);
+  }
+  
+  $element = array(
+    '#type' => 'video_upload_browser_method_widget',
+    '#default_value' => $item,
+    '#upload_validators' => array(),
   );
 
-  $element = _video_upload_browser_widget_form($form['#node'], $field, $items);
   return $element;
-  switch ($op) {
-    case 'prepare form values' :
-      _video_upload_widget_browser_prepare_form_values($node, $field, $items);
-      break;
-
-    case 'process form values':
-      _video_upload_widget_browser_process_form_values($node, $field, $items);
-      break;
-
-    case 'form' :
-      return _video_upload_browser_widget_form($node, $field, $items);
-
-    case 'validate' :
-      // this doesn't work yet
-      _video_upload_browser_widget_validate($node, $field, $items);
-      break;
-
-    case 'submit' :
-      break;
-
-    case 'default value' :
-      return array(
-        array(
-          'id' => '0',
-          'status' => VIDEO_UPLOAD_STATUS_UNKNOWN,
-          'status_ts' => '',
-          'fid' => '',
-          // @todo see other inline delete todo items
-          // 'delete' => 0,
-        ),
-      );
-      break;
-  }
-  return;
 }
 
-/**
- * Depending on if $node_field contains a YouTube ID or not, the form returned
- * will be drastically different.
- * @param boolean $save
- *   This is only passed when rendering the form from 
- */
-function _video_upload_browser_widget_form(&$node, $field, &$items) {
-  $field_name = $field['field_name'];
-
-  // this will be set to false if a video already exists on the field,
-  // and multiple uploads aren't allowed.
-  $generate_upload_form = true;
-
-  $form[$field_name] = array(
-    '#type' => 'fieldset',
-    '#title' => t($field['widget']['label']),
-    '#weight' => $field['widget']['weight'],
-    '#description' => t('<strong>Note</strong>: Uploaded videos will not be saved until this post has been saved.'),
-    '#collapsible' => TRUE,
-    '#collapsed' => FALSE,
-    '#tree' => TRUE,
-    '#prefix' => '<div id="'. form_clean_id($field_name . '-attach-wrapper') . '" >',
-    '#suffix' => '</div>',
-  );
-
-  $form[$field_name][0]['id'] = array(
-    '#type' => 'hidden',
-    '#value' => $items[0]['id'],
-  );
-
-  // Attempt a preview (won't show much on adding) for videos
-  // that have an id, and have been confirmed
-  if ($items[0]['id']) {
-    if ($items[0]['status'] > VIDEO_UPLOAD_STATUS_UNKNOWN) {
-      $form[$field_name][0]['preview'] = array(
-        '#type' => 'markup',
-        '#value' => theme('video_upload_video', $items[0]['id'], $field['widget']['display']['small_width'], $field['widget']['display']['small_height']),
-        '#suffix' => t('Use the form below to replace this video with a different one.'),
-      );
-    }
-    elseif ($items[0]['status'] === VIDEO_UPLOAD_STATUS_UNKNOWN) {
-      $form[$field_name][0]['preview'] = array(
-        '#type' => 'markup',
-        '#value' => '<div class="messages">' . t('Video is processing...') . '</div>',
-      );
-    }
-    // @todo make this work (see todo in form processing step for
-    // some initial work
-
-    // $form[$field_name][0]['delete'] = array(
-    //   '#type' => 'checkbox',
-    //   '#title' => t('Delete video ID %id from YouTube', array('%id' => $items[0]['id'])),
-    // );
-  }
-
-  // include Drupal js for dynamic upload handling
-  //  drupal_add_js('misc/progress.js');
-  // drupal_add_js('misc/upload.js');
-  drupal_add_js(drupal_get_path('module', 'video_upload') . '/video_upload.js');
-
-  $form[$field_name]['new'] = array(
-    '#tree' => FALSE,
-    '#prefix' => '<div id="' . form_clean_id($field_name .'-attach-hide') . '">',
-    '#suffix' => '</div>',
-    '#weight' => 100,
-  );
-
-  // youtube expects the POST variable to be named "file"
-  if (!empty($field['widget']['file_extensions'])) {
-    $allowed_extensions = t('<br />Allowed file types: <strong>@types</strong>', array('@types' => $field['widget']['file_extensions']));
-    // format for accept attribute below, the attribute gets used
-    // by video_upload.js as a regex pattern, thus the '|' separator
-    $allowed_types = implode('|', array_filter(explode(' ', $field['widget']['file_extensions'])));
-  }
-  
-  // overwrite warning
-  if (!$field['multiple'] && $items[0]['id']) {
-    $overwrite_warning = t('<strong>WARNING</strong>: Uploading another video will overwrite the above video (and be rejected if it is a duplicate).');
 
-    // @todo the delete widget must work first
-    // $generate_upload_form = FALSE;
+// Just like video_upload_widget_value, only without calling filefield (no upload to save)
+function video_upload_browser_method_widget_value($element, $edit = FALSE) {
+  if ($edit) {
+    $item['video_status'] = isset($edit['video_status']) ? $edit['video_status'] : VIDEO_UPLOAD_STATUS_UPLOAD_PENDING;
+    $item['video_status_ts'] = isset($edit['video_status_ts']) ? $edit['video_status_ts'] : $_SERVER['REQUEST_TIME'];
   }
-
-  
-  // If the browser upload method is being used, we construct an upload form
-  // to YouTube
-  if ($generate_upload_form && $field['widget']['use_browser_upload_method']) {
-    
-    drupal_add_js(drupal_get_path('module', 'video_upload') . '/video_upload_browser.js');
-    
-    // authenticate to youtube
-    if ($http_client = _video_upload_authenticate_youtube()) {
-      
-      // The following is taken and modified from
-      // http://code.google.com/apis/youtube/developers_guide_php.html
-      // @todo perhaps store in SESSION...perhaps not
-      $yt = _video_upload_youtube($http_client);
-      
-      // create a Zend_Gdata_YouTube_VideoEntry
-      $video = _video_upload_video_entry();
-      
-      // set up media group
-      _video_upload_construct_media_group($yt, $video, $node, $field);
-      
-      $token_array = _video_upload_get_token_array($yt, $video);
-      
-      // Set action to YouTube @todo this will need to be done in order for
-      // this to work w/o js enabled and then have the js re-construct the
-      // action back to this site 
-      // $form['#action'] = url($token_array['url'], 'nexturl=' . _video_upload_get_next_url());
-      
-      if ($token_array) {
-        // Set youtube as the upload destination, which will then redirect to
-        // the js callback url. The dynamic behavior is triggered by setting
-        // the class to "upload"
-        
-        // token
-        $form[$field_name]['new']['token'] = array(
-          '#type' => 'hidden',
-          // YouTube requires the name to be 'token'
-          '#name' => 'token',
-          '#value' => $token_array['token'],
-        );
-        // this gets changed, as YouTube redirects to the video_upload ajax
-        // handler
-        $ajax_form_submit_url = url($token_array['url'], array('query' => 'nexturl=' . urlencode(_video_upload_get_next_url($field_name, $node))));
-      }
-      else {
-        // can't generate upload form w/o a token
-        $generate_upload_form = false;
-        $auth_error = true;
-        watchdog('video_upload', t('Authentication to YouTube succeeded, but failed to generate a token'), WATCHDOG_ERROR);
-      }
-    }
-    else {
-      // auth error will provide a warning
-      $auth_error = true;
-      $generate_upload_form = false;
-    }
-
-    if ($auth_error) {
-      $form[$field_name]['holder'] = array(
-        '#type' => 'markup',
-        '#value' => t('Video Uploads currently unavailable. Please try back soon'),
-      );
-    }
+  else {
+    $item['video_status'] = VIDEO_UPLOAD_STATUS_UPLOAD_PENDING;
+    $item['video_status_ts'] = $_SERVER['REQUEST_TIME'];
   }
-  elseif ($generate_upload_form) {
-    // The Direct Upload method transfers the file here first
 
-    // Submission to YouTube is handled later, send file here
-    $ajax_form_submit_url = _video_upload_get_next_url($field_name, $node);
-
-    foreach ($items as $delta => $item) {
-      if ($item['fid']) {
-        $form[$field_name][$delta]['fid'] = array(
-          '#type' => 'hidden',
-          '#value' => $item['fid'],
-        );
-      }
-    }  
-  }
+  return $item;
+}
 
-  if ($generate_upload_form) {
-    // Note, youtube requires that this field be called 'file', but the Drupal
-    // Form API doesn't work with renaming of this field. Since Browser
-    // uploads only work with js enabled, this field is renamed properly
-    // client side when the user attempts a YouTube upload.
-    $form[$field_name]['new'][$field_name . '_file'] = array(
-      '#type' => 'file',
-      '#description' =>  $overwrite_warning . $field['widget']['description'] . $allowed_extensions,
-      '#title' => t('File'),
-      '#tree' => FALSE,
-      '#attributes' => array(
-        'class' => 'video-upload-file video-upload video-upload-' . form_clean_id($field_name),
-        // browsers tend not to enforce this, but some javascript can
-        'accept' => $allowed_types,
-        'id' => 'blaz',
-      ),
+//  Build the element.
+function video_upload_browser_method_widget_process($element, $edit, &$form_state, $form) {
+  if (!$element['#value']['video_id']) { // just the upload button
+    $element['video_browser_upload'] = array(
+      '#type' => 'button',
+      '#value' => t('Launch the Uploader'),
+      '#attributes' => array('class' => 'video-upload-browser-upload'),
     );
   }
-
-  if ($generate_upload_form) {
-    // The dynamic behavior of the form is triggered by the 'upload' and
-    // 'video-upload-url' classes.
-    $form[$field_name .'-attach-url'] = array(
-      '#type' => 'hidden', 
-      '#value' => $ajax_form_submit_url, 
-      '#attributes' => array('class' => 'upload video-upload-url')
-    );
-  
-    // button
-    $form[$field_name]['new']['submit'] = array(
-      '#type' => 'button',
-      '#value' => t('Upload Video File'),
-      '#id' => form_clean_id($field_name . '-attach-button'),
-      '#attributes' => array(
-      'class' => 'video-upload video-upload-submit',
-      ),
+  else { // video thumbnail, status, remove button
+    $element['video_item'] = array(
+      '#type' => 'markup',
+      '#value' => _video_upload_browser_method_form_item($element['#value'], $element['#id']),
     );
   }
+  
+  $element['video_status'] = array(
+    '#type' => 'hidden',
+    '#default_value' => $element['#default_value']['video_status'],
+  );
+  $element['video_status_ts'] = array(
+    '#type' => 'hidden',
+    '#default_value' => $element['#default_value']['video_status_ts'],
+  );
+  $element['video_id'] = array(
+    '#type' => 'hidden',
+    '#default_value' => $element['#default_value']['video_id'],
+  );
 
-  return $form;
+  return $element;
 }
 
 /**
- * Validate a set of items
+ * Here we render a video widget,
  */
-function _video_upload_browser_widget_validate(&$node, $field, &$items) {
-  if ($field['required']) {
-    if ($field['widget']['use_browser_upload_method']) {
-      // if using the browser upload method, we need a YouTube ID
-      if (!$items[0]['id']) {
-        $error = true;
-      }
-    }
-    else {
-      // for the direct upload method, we need a file
-      if (!$items[0]['fid']) {
-        $error = true;
-      }
-    }
-    if ($error) {
-      form_set_error($field['field_name'], t('@field is required. Please select a video and hit the <em>Upload Video File</em> button.', array('@field' => $field['widget']['label'])));
-    }
-  }
+function _video_upload_browser_method_form_item($item, $element_id) {  
+  $fake_field = array(
+    'widget' => array(
+      'display' => array(
+        'thumb_width' => 120,
+        'thumb_height' => 74
+      )
+    )
+  );
+  
+  $status_text = theme('video_upload_status_text', $item['video_status']);
+  $thumb = theme('video_upload_video_thumb', $fake_field, $item, 0, FALSE);
+  
+  $markup = '<div id="' . $element_id . '-browser-item" class="video-upload-browser-item">';
+  
+  $markup .= '<div class="video-upload-browser-item-left">';
+  $markup .= '<a href="http://www.youtube.com/v/' . $item['video_id'] . '">' . $thumb . '</a>';
+  $markup .= '</div>';
+  
+  $markup .= '<div class="video-upload-browser-item-right">';
+  $markup .= 'Status: ' . $status_text;
+  $markup .= '<br /> <button class="form-submit video-upload-browser-delete" id="' . $element_id . '-video-browser-delete">Remove</button>';
+  $markup .= '</div>';
+  $markup .= '<div class="video-upload-clearer">&nbsp</div>';
+  
+  $markup .= '</div>';
+  
+  return $markup;
 }
 
-/**
- * Prepare data for form
- */
-function _video_upload_browser_widget_prepare_form_values(&$node, $field, &$items) {
-  if (!count($_POST)) {
-    // start fresh if no post datas
-    video_upload_clear_session_data();
-  }
-
-  $field_name = $field['field_name'];
-
-  // @fixme - This need to be reviewed. The reason this is required
-  //          is that the Drupal Form API doesn't allow js to change
-  //          the values of hidden variables, so it must be done here.
-  //          Supposedly it is dangerous to do so, thus the need for a
-  //          review.
-  // @fixme - This won't work once multiple items are in play
-  if ($_POST[$field_name][0]['id']) {
-    $node->{$field_name}[0]['id'] = $_POST[$field_name][0]['id'];
-    $items[0]['id'] = $node->{$field_name}[0]['id'];
-  }
+function theme_video_upload_browser_method_widget(&$element) {
+  drupal_add_js('misc/jquery.form.js');
+  drupal_add_js(drupal_get_path('module', 'video_upload') .'/video_upload_browser.js');
+  drupal_add_css(drupal_get_path('module', 'video_upload') .'/video_upload_browser.css');
+  
+  jquery_ui_add(array('ui.dialog', 'ui.draggable'));
+  drupal_add_css(drupal_get_path('module', 'jquery_ui') ."/jquery.ui/themes/default/ui.all.css");
+  
+  return theme('video_upload_widget', $element);
+}
 
-  // Check for file uploaded to local server
-  if ($file = file_check_upload($field_name . '_file')) {
-    $valid = _video_upload_widget_validate_video_file($node, $field, $items, $file);
-    if ($valid) {
-      _video_upload_upload_video_file($node, $field, $items, $file);
-    }
-    else {
-      // @todo delete the invalid image
-    }
-  }
+function theme_video_upload_browser_method_widget_preview($item = NULL) {
+  return theme('video_upload_widget_preview', $item);
 }
 
 /**
- * Convert back to native storage
+ * Callback. This is the page that youtube redirects to.
+ * The reponse goes to an iframe and gets parsed.
  */
-function _video_upload_browser_widget_process_form_values(&$node, $field, &$items) {
-  foreach ($items as $delta => $item) {
-
-    if ($item['id'] && !$item['status']) {
-      // @todo make this work
-      if (false && $item['delete'] && $item['id']) {
-        // delete video from youtube
-        _video_upload_delete(array($item), $field);
-        $item['id'] = '';
-        $item['delete'] = 0;
-      }
-      if ($status = video_upload_youtube_validate($item['id'], $node)) {
-        $item['status'] = $status->status;
-        $item['status_ts'] = time();
-      }
-      $items[$delta] = $item;
-    }
-  }
+function video_upload_browser_method_success() {
+  $value = array('video_id' => $_GET['id'],
+                 'video_status' => 'unkown');
+  
+  $status = array('id' => $_GET['id'],
+                  'success' => ($_GET['status'] == '200') ? TRUE : FALSE,
+                  'field' => _video_upload_browser_method_form_item($value, '$element_id'),
+                  );
+  
+  print drupal_to_js($status);
+  exit;
 }
 
-/**
- * Get the url that youtube will redirect to
- * @param string $field_name
- * @param object $node
- * @return string
- */
-function _video_upload_get_next_url($field_name, $node) {
-  global $base_url;
-  // the field name is passed as part of the path because the YouTube API
-  // doesn't handle encoded urls, and submitting a ? in the url doesn't work
-  // properly
-  return url('video-upload/js/' . $field_name . '/' . $node->type, array('absolute' => TRUE));
+function video_upload_browser_method_dialog() {
+  echo drupal_get_form('video_upload_browser_method_upload_form');
+  exit;
 }
+
+function video_upload_browser_method_upload_form() {
+  $element_id = arg(2);
+  
+  video_upload_initialize_provider();
+  
+  // authenticate to youtube
+  $http_client = _video_upload_authenticate_youtube();
+  
+  $youtube = _video_upload_youtube($http_client);
+  $video = _video_upload_video_entry();
+  _video_upload_construct_media_group($youtube, $video, array(), array());
+  
+  $token_array = _video_upload_get_token_array($youtube, $video);
+  
+  $form['#action'] = $token_array['url'] .= '?nexturl=' . url('video-upload/success', array('absolute' => TRUE));
+  $form['#attributes']['enctype'] = 'multipart/form-data';
+  
+  $form['element_id'] = array(
+    '#type' => 'hidden',
+    '#value' => $element_id,
+  );
+  
+  // youtube upload token
+  $form['token'] = array(
+    '#type' => 'hidden',
+    '#name' => 'token',
+    '#value' => $token_array['token'],
+  );
+  
+  $form['upload'] = array(
+    '#type' => 'file',
+    '#title' => t('Please select'),
+    '#size' => 35,
+  );
+
+  return $form;
+}
\ No newline at end of file
diff -upN video_upload_original\video_upload.info video_upload_fid\video_upload.info
--- video_upload_original\video_upload.info	Thu Apr 15 00:21:48 2010
+++ video_upload_fid\video_upload.info	Thu Apr 15 00:23:55 2010
@@ -5,4 +5,5 @@ core = 6.x
 package = CCK
 php = 5.1
 dependencies[] = content
-dependencies[] = filefield
\ No newline at end of file
+dependencies[] = filefield
+dependencies[] = jquery_ui
diff -upN video_upload_original\video_upload.module video_upload_fid\video_upload.module
--- video_upload_original\video_upload.module	Mon May 03 22:39:35 2010
+++ video_upload_fid\video_upload.module	Mon May 03 18:52:12 2010
@@ -31,7 +31,8 @@ define('VIDEO_UPLOAD_SYNC_APPEND', 2);
  * Implementation of hook_init().
  */
 function video_upload_init() {
-  module_load_include('inc', 'video_upload', 'video_upload_widget');
+  require_once(dirname(__FILE__) . '/video_upload_widget.inc');
+  require_once(dirname(__FILE__) . '/video_upload.browser.inc');
 }
 
 /**
@@ -73,10 +74,18 @@ function video_upload_theme() {
       'arguments' => array('element' => NULL),
       'file' => 'video_upload_widget.inc',
     ),
+    'video_upload_browser_method_widget' => array(
+      'arguments' => array('element' => NULL),
+      'file' => 'video_upload_browser.inc',
+    ),
     'video_upload_widget_preview' => array(
       'arguments' => array('item' => NULL),
       'file' => 'video_upload_widget.inc',
     ),
+    'video_upload_browser_method_widget_preview' => array(
+      'arguments' => array('item' => NULL),
+      'file' => 'video_upload_browser.inc',
+    ),
   );
 
   // CCK formatters.
@@ -130,6 +139,23 @@ function video_upload_menu() {
     'file' => 'video_upload.admin.inc',
     'description' => t('Manage all uploaded videos.'),
   );
+  
+  // Browser method callbacks
+  $items['video-upload/dialog'] = array(
+    'title' => 'Get the form for the browser upload dialog',
+    'page callback' => 'video_upload_browser_method_dialog',
+    'access arguments' => array('administer uploaded videos'),
+    'file' => 'video_upload.browser.inc',
+    'type' => MENU_CALLBACK,
+  );
+    
+  $items['video-upload/success'] = array(
+    'title' => 'YouTube Browser Upload final callback',
+    'page callback' => 'video_upload_browser_method_success',
+    'access arguments' => array('administer uploaded videos'),
+    'file' => 'video_upload.browser.inc',
+    'type' => MENU_CALLBACK,
+  );
 
   return $items;
 }
@@ -154,6 +180,12 @@ function video_upload_elements() {
   // Video upload contains additional file meta-data, so requires a separate
   // value callback.
   $elements['video_upload_widget']['#value_callback'] = 'video_upload_widget_value';
+  
+  $elements['video_upload_browser_method_widget'] = array(
+    '#input' => TRUE,
+    '#process' => array('video_upload_browser_method_widget_process'),
+    '#value_callback' => array('video_upload_browser_method_widget_value')
+  );
 
   return $elements;
 }
@@ -441,14 +473,6 @@ function video_upload_widget(&$form, &$f
     $form['#validate'][] = 'video_upload_node_form_validate';
   }
   
-  if ($field['widget']['use_browser_upload_method']) {
-    // The browser upload method is sufficiently different from direct upload
-    // that it warrants entirely separate logic.
-    // @todo
-    module_load_include('browser.inc', 'video_upload');
-    return _video_upload_browser_method_widget($form, $form_state, $field, $items, $delta);
-  }
-
   if (empty($items[$delta])) {
     $items[$delta] = array(
       'video_id' => '',
@@ -456,11 +480,18 @@ function video_upload_widget(&$form, &$f
       'video_status_ts' => $_SERVER['REQUEST_TIME'],
     );
   }
+  
+  if ($field['widget']['use_browser_upload_method']) {
+    // The browser upload method is sufficiently different from direct upload
+    // that it warrants entirely separate logic.
+    module_load_include('browser.inc', 'video_upload');
+    return _video_upload_browser_method_widget($form, $form_state, $field, $items, $delta);
+  }
+
   $element = filefield_widget($form, $form_state, $field, $items, $delta);
 
   return $element;
 }
-
 
 /**
  * Additional #validate handler for the node form.
diff -upN video_upload_original\video_upload_browser.css video_upload_fid\video_upload_browser.css
--- video_upload_original\video_upload_browser.css	Thu Jan 01 01:00:00 1970
+++ video_upload_fid\video_upload_browser.css	Mon May 03 22:07:41 2010
@@ -0,0 +1,45 @@
+/* $Id$ */
+
+/**
+ * @file
+ * CSS for the Video Upload Browser method.
+ */
+.video-upload-browser-item-left {
+  float: left;
+}
+
+.video-upload-browser-item-right {
+  float: left;
+  margin-left: 15px;
+  height: 74px;
+}
+
+.video-upload-clearer {
+  clear:both;
+  height:0;
+}
+
+.video-upload-browser-upload {
+  margin: 0.5em 0.5em 0.5em 0 !important;
+}
+
+.video-upload-browser-delete {
+  margin-top: 5px;
+  margin-top: 30px !important;
+}
+
+/* Line up the message next to the throbber */
+.video-upload-dialog .upload-validation-message {
+  color: red;
+  line-height:150%;
+  font-size: 0.85em;
+}
+
+.video-upload-dialog {
+  padding-top: 0.5em !important;
+}
+
+/* The throbber we place inside the "Upload" button */
+.video-upload-throbber {
+  margin: 0 5px 0 0 !important;
+}
\ No newline at end of file
diff -upN video_upload_original\video_upload_browser.js video_upload_fid\video_upload_browser.js
--- video_upload_original\video_upload_browser.js	Fri Oct 10 21:02:57 2008
+++ video_upload_fid\video_upload_browser.js	Mon May 03 22:26:08 2010
@@ -1,231 +1,194 @@
-// $Id: video_upload_browser.js,v 1.5 2008/10/10 19:02:57 jhedstrom Exp $
+// $Id$
+/**
+ * JS functionality for the Video Upload Browser method.
+ */
 
 /**
- * Rename file field name to YouTube requirements on submit
+ * Implementation of the "Remove" button.
  */
-Drupal.behaviors.videoUploadAutoAttach = function() {
-  // change form input name to "file", as required by youtube
-  $("input[@type='file'].video-upload-file").attr('name', 'file');
-  alert('foo');
-  // add upload-module-like behavior to the *form* submit/preview buttons
-  $('form.video-upload #edit-preview, form.video-upload #edit-submit').each(function() {
-    var upload = new Drupal.videoUpload(this);
-  })
+Drupal.behaviors.videoUploadAttachDelete = function(context) {
+  $('.video-upload-browser-delete', context).click(function() {
+	var elementId = this.id;
+	elementId = elementId.replace('-video-browser-delete', '');
+	
+	// Remove the video thumb and status text, reset the hidden fields.
+	$('#' + elementId + '-browser-item').remove();
+	$('#' + elementId + '-video-status').attr('value', 'upload-pending');
+	$('#' + elementId + '-video-id').attr('value', '');
+	
+	var elementWrapper = $('#' + elementId + '-wrapper');
+	var uploadButton = '<input type="submit" class="form-submit video-upload-browser-upload" value="Launch the Uploader" id="' + elementId + '-video-browser-upload" name="op">';
+	
+	if ($('label', elementWrapper).length > 0) { // case when number of values in field is 1
+	  $('label', elementWrapper).after(uploadButton);
+	} else { // case when number of values is more than 1
+	  elementWrapper.prepend(uploadButton);
+	}
+	
+	// Reattach the JS callback
+	Drupal.behaviors.videoUploadAttachUpload(elementWrapper);
+	
+	return false;
+  });
 }
 
 /**
- * Double-submit behavior for submit and preview buttons
- * The following is based on Drupal.redirectFormButton()
- * in drupal.js
+ * Implementation of the "Upload" button (launches the upload dialog)
  */
-Drupal.videoUpload = function(button) {
-  // Trap the button
-  button.onmouseover = button.onfocus = function() {
-    button.onclick = function() {
-
-      // @todo loop through all video upload file fields
-      var upFile = $("input[@type='file'].video-upload-file");
-      if (upFile.val().length > 0 && Drupal.videoUploadValidateFile(upFile.get(0))) {
-
-	// Insert progressbar and stretch to take the same space.
-	var progress = new Drupal.progressBar('uploadprogress');
-	progress.setProgress(-1, 'Uploading video. This may take some time...');
-
-	var el = progress.element;
-	var offset = $('#edit-submit').get(0).offsetHeight;
-
-	$(el).css({
-          width: '28em',
-	  height: offset +'px',
-	  paddingTop: '10px',
-          display: 'none'
+Drupal.behaviors.videoUploadAttachUpload = function(context) {
+  $('.video-upload-browser-upload', context).click(function() {
+	var elementId = this.id;
+	elementId = elementId.replace('-video-browser-upload', '');
+	var dialogId = 'dialog-' + elementId;
+	
+	Drupal.videoUpload.fields.push(elementId);
+	
+	// insert the dialog div with the Loading... text into the DOM
+	$('body').prepend('<div id="' + dialogId + '" class="video-upload-dialog"><br />' + Drupal.t('Loading...') + '</div>');
+	
+	// fetch the upload form from the server, attach the handlers, inject into the dialog
+	$('#' + dialogId).load(Drupal.settings.basePath + 'video-upload/dialog/' + elementId, function(content) {
+	  $(this).html(content);
+	  
+	  // Initialize JQuery Form
+	  Drupal.videoUpload.attachDialogBehaviour(this);
+	  
+	  // Show the Upload button.
+	  var buttonContext = $(this).parent().parent()[0];
+	  $('.ui-dialog-buttonpane', buttonContext).show();
 	});
-
-	$('#edit-submit').after(el);
-	$(el).fadeIn('slow');
-        $('#edit-submit, #edit-preview, #edit-delete, .video-upload-submit').fadeOut('slow');
-	// end progress bar
-
-        Drupal.videoUpload.sendVideo(button);
-      }
-      else {
-        // no file in place, submit normally
-        return true;
-      }
-    }
-  }
-
-  button.onmouseout = button.onblur = function() {
-    button.onclick = null;
-  }
+	
+	// everything is ready, launch the dialog.
+	Drupal.videoUpload.initializeDialog(dialogId);
+		
+	return false;
+  });
 }
 
-Drupal.videoUpload.sendVideo = function(button) {
-  // @fixme: this won't work with multiple YouTube posts. It needs to
-  // pass the associated uri with the file, which will be looped
-  var control = $('.video-upload-url').get(0);
-  var base = control.id.substring(5,control.id.length - 4);
-  var uri = control.value;
-  var wrapper = '#' + base + '-wrapper';
-
-  // get the current action and target
-  var oldAction = button.form.action;
-  var oldTarget = button.form.target;
-
-  // Redirect form submission to iframe
-  button.form.action = uri;
-  button.form.target = 'redirect-target';
-
-  // Create target iframe
-  Drupal.createIframe();
-
-  // Set iframe handler for later
-  window.iframeHandler = function () {
-      var iframe = $('#redirect-target').get(0);
-    // Restore form submission
-    button.form.action = oldAction;
-    button.form.target = oldTarget;
-
-    // Get response from iframe body
-    try {
-      response = (iframe.contentWindow || iframe.contentDocument || iframe).document.body.innerHTML;
-      // Firefox 1.0.x hack: Remove (corrupted) control characters
-      response = response.replace(/[\f\n\r\t]/g, ' ');
-      if (window.opera) {
-        // Opera-hack: it returns innerHTML sanitized.
-        response = response.replace(/&quot;/g, '"');
-      }
-
-    }
-    catch (e) {
-      response = null;
-    }
-
-    response = Drupal.parseJson(response);
-    // Check response code
-    if (response.status == 0) {
-      Drupal.videoUpload.sendVideo.onerror(response.data);
-      return false;
-    }
-    Drupal.videoUpload.sendVideo.oncomplete(response.data, wrapper);
-
-    // now submit form normally
-    button.click();
+Drupal.videoUpload = function() {};
 
-    return true;
-  }
-
-  return true;
-}
+/**
+ * A stack containing the field ids of widgets from which we launched dialogs.
+ * This is needed because when an upload finishes, we don't actually know
+ * which dialog finished (and we don't care), we just kill one, and fill one
+ * empty space in the node add/edit form.
+ *
+ * This is done this way because we can't pass any params to the YouTube $nextUrl
+ * and have them provided there (as a POST or GET param), which sucks.
+ */
+Drupal.videoUpload.fields = new Array();
 
 /**
- * Error handling function
+ * Initialize the JQuery UI Dialog.
  */
-Drupal.videoUpload.sendVideo.onerror = function(data) {
-    alert('An error has occurred:\n\n' + data);
+Drupal.videoUpload.initializeDialog = function(dialogId) {
+  $('#' + dialogId).dialog({
+	title: Drupal.t('Upload a file to YouTube'),
+	resizable: true,
+	maximize: false,
+	draggable: true,
+	height: 160,
+	width: 400,
+	close: function(event, ui) {
+	  var dialogId = $(this).attr('id');
+	  var elementId = dialogId.replace('dialog-', '');
+	  var elementPos = jQuery.inArray(elementId, Drupal.videoUpload.fields);
+	  
+	  Drupal.videoUpload.fields.remove(elementPos);
+	},
+	buttons: {
+	  "Upload": function() {
+		$('form', this).submit();
+	  }
+	}
+  });
+  
+  var buttonContext = $('#' + dialogId).parent().parent()[0];
+  
+  // Hide the Upload button (shown when the upload form loads)
+  $('.ui-dialog-buttonpane', buttonContext).css('display', 'none');
 }
 
-Drupal.videoUpload.sendVideo.oncomplete = function(data, wrapper) {
-  // Remove old form
-  Drupal.freezeHeight(); // Avoid unnecessary scrolling
-  $(wrapper).html('');
-
-  // Place HTML into temporary div
-  var div = document.createElement('div');
-  $(div).html(data)
-
-  $(div).hide();
-  $(wrapper).append(div);
-  $(div).fadeIn('slow');
-
-  Drupal.uploadAutoAttach();
-
-  Drupal.unfreezeHeight();
-  return;
-}
 
 /**
- * Modified handler for the form redirection submission. Taken from
- * /misc/upload.js. This function hides the submit/preview/delete
- * buttons while the video is being sent to YouTube.
+ * Initialize JQuery Form and attach it to the form in the dialog.
  */
-Drupal.videoUpload.sendVideo.onsubmit = function () {
-  // Insert progressbar and stretch to take the same space.
-  this.progress = new Drupal.progressBar('uploadprogress');
+Drupal.videoUpload.attachDialogBehaviour = function(context) {  
+  var elementId = $('#edit-element-id', context).attr('value');
 
-  if ($(this.button).is('.video-upload')) {
-    // If this is a video upload, hide preview/submit/delete buttons
-    $('#edit-submit, #edit-preview, #edit-delete').fadeOut('slow');    
-    // Change the message
-    this.progress.setProgress(-1, 'Uploading video, this may take some time...');
-  }
-  else {
-    // Default Drupal upload message
-    this.progress.setProgress(-1, 'Uploading file');
-  }  
-
-  var hide = this.hide;
-  var el = this.progress.element;
-  var offset = $(hide).get(0).offsetHeight;
-  $(el).css({
-    width: '28em',
-    height: offset +'px',
-    paddingTop: '10px',
-    display: 'none'
-  });
-  $(hide).css('position', 'absolute');
-
-  $(hide).after(el);
-  $(el).fadeIn('slow');
-  $(hide).fadeOut('slow');
+  var options = {
+	context: context,
+	elementId: elementId,
+	beforeSubmit:  Drupal.videoUpload.beforeSubmit, 
+	success:       Drupal.videoUpload.completeUpload
+  };
+  
+  $('form', context).ajaxForm(options);
+}
+
+// JQuery Form presubmit handler
+Drupal.videoUpload.beforeSubmit = function(formData, jqForm, options) {    
+  // Remove previous error message, if any
+  $('.upload-validation-message', options.context).remove();
+  
+  if ($('input[type=file]', options.context).attr('value') == "") {
+	var errorMessage = Drupal.t('No file selected.');
+	$('#edit-upload-wrapper', options.context).append('<div class="upload-validation-message">' + errorMessage + '</div>');
+	
+	return false;
+  }
+  
+  var buttonContext = $('#dialog-' + options.elementId).parent().parent()[0];
+  
+  var button = 'Uploading...';
+  
+  /*
+    For browsers that are not IE6/7 we insert a throbber.
+    The throbber looks like crap on IE6/IE7, so we have to can't use it.
+  */
+  if(!$.browser.msie || $.browser.version > 7) {
+	button = '<div class="ahah-progress ahah-progress-throbber">' +
+             '<div class="throbber video-upload-throbber">&nbsp;</div>' +
+			 '</div>' + button;
+  }
+		
+  $('button', buttonContext).html(button);
+  
+  return true;
 }
 
 /**
- * Modified handler for the form redirection completion. Taken from
- * /misc/upload.js. This function must re-display the
- * submit/preview/delete buttons hidden by the onsubmit handler.
+ * JQuery Form postsubmit handler.
+ * Parses the response, closes the dialog, updates the widget on the
+ * node add/edit page.
  */
-Drupal.videoUpload.sendVideo.oncomplete = function (data) {
-  if ($(this.button).is('.video-upload')) {
-    // If this is a video upload, hide preview/submit/delete buttons
-    $('#edit-submit, #edit-preview, #edit-delete').fadeIn('slow');    
-  }
-
-  // Remove old form
-  Drupal.freezeHeight(); // Avoid unnecessary scrolling
-  $(this.wrapper).html('');
-
-  // Place HTML into temporary div
-  var div = document.createElement('div');
-  $(div).html(data);
-
-  // If uploading the first attachment fade in everything
-  if ($('tr', div).size() == 2) {
-    // Replace form and re-attach behaviour
-    $(div).hide();
-    $(this.wrapper).append(div);
-    $(div).fadeIn('slow');
-    Drupal.uploadAutoAttach();
-  }
-  // Else fade in only the last table row
-  else {
-    // Hide form and last table row
-    $('table tr:last-of-type td', div).hide();
-
-    // Note: workaround because jQuery's #id selector does not work outside of 'document'
-    // Should be: $(this.hide, div).hide();
-    var hide = this.hide;
-    $('div', div).each(function() {
-      if (('#'+ this.id) == hide) {
-        this.style.display = 'none';
-      }
-    });
-
-    // Replace form, fade in items and re-attach behaviour
-    $(this.wrapper).append(div);
-    $('table tr:last-of-type td', div).fadeIn('slow');
-    $(this.hide, div).fadeIn('slow');
-    Drupal.uploadAutoAttach();
-  }
-  Drupal.unfreezeHeight();
-}
+Drupal.videoUpload.completeUpload = function(responseText) {
+  var response = Drupal.parseJson(responseText);
+  var elementId = Drupal.videoUpload.fields.shift();
+  
+  response.field = response.field.replace(/\$element\_id/g, elementId);
+  
+  $('#dialog-' + elementId).dialog('destroy');
+  
+  // remove the upload button, update the hidden fields
+  $('#' + elementId + '-video-browser-upload').remove();
+  $('#' + elementId + '-video-status').attr('value', 'unknown');
+  $('#' + elementId + '-video-id').attr('value', response.id);
+  
+  if ($('#' + elementId + '-wrapper label', elementWrapper).length > 0) { // case when number of values in field is 1
+	$('#' + elementId + '-wrapper label').after(response.field);
+  } else { // case when number of values is more than 1
+	$('#' + elementId + '-wrapper').prepend(response.field);
+  }
+  
+  // reattach the js handler for the Remove button
+  var elementWrapper = $('#' + elementId + '-wrapper')[0];
+  Drupal.behaviors.videoUploadAttachDelete(elementWrapper);
+}
+
+// Array Remove - By John Resig (MIT Licensed)
+Array.prototype.remove = function(from, to) {
+  var rest = this.slice((to || from) + 1 || this.length);
+  this.length = from < 0 ? this.length + from : from;
+  return this.push.apply(this, rest);
+};
\ No newline at end of file
diff -upN video_upload_original\video_upload_widget.inc video_upload_fid\video_upload_widget.inc
--- video_upload_original\video_upload_widget.inc	Fri Sep 04 22:51:16 2009
+++ video_upload_fid\video_upload_widget.inc	Fri Apr 30 21:00:17 2010
@@ -37,15 +37,10 @@ function video_upload_widget_settings_fo
   );
 
   $form['use_browser_upload_method'] = array(
-    '#type' => 'hidden',
-    '#value' => FALSE,
-
-    // @todo once the browser upload method is working, this option
-    //       should be enabled.
-    // '#type' => 'checkbox',
-    // '#title' => t('Use Browser Upload Method'),
-    // '#default_value' => isset($widget['use_browser_upload_method']) ? $widget['use_browser_upload_method'] : true,
-    // '#description' => t('The <a href="!url">Browser Upload Method</a> sends video files directly to YouTube, instead of touching the Drupal server. This saves on storage and bandwidth', array('!url' => url('http://code.google.com/apis/youtube/developers_guide_php.html#BrowserUpload'))),
+    '#type' => 'checkbox',
+    '#title' => t('Use the Browser Upload method'),
+    '#default_value' => isset($widget['use_browser_upload_method']) ? $widget['use_browser_upload_method'] : TRUE,
+    '#description' => t('The <a href="!url">Browser Upload method</a> sends video files directly to YouTube, instead of touching the Drupal server. This saves on storage and bandwidth', array('!url' => url('http://code.google.com/apis/youtube/developers_guide_php.html#BrowserUpload'))),
   );
 
   // Maintenance.
@@ -296,6 +291,7 @@ function _video_upload_widget_validate_s
  * filefield_widget_value and filefield_widget_process callbacks.  They will
  * be called after the filefield callbacks and their return values will be
  * merged with the filefield callback's.
+ *
  */
 function video_upload_widget_value($element, $edit = FALSE) {
   $item = filefield_widget_value($element, $edit);
Common subdirectories: video_upload_original\views and video_upload_fid\views
