diff --git a/imagefield_focus.css b/imagefield_focus.css
index 7de3fe6..babd3cc 100644
--- a/imagefield_focus.css
+++ b/imagefield_focus.css
@@ -8,7 +8,23 @@
   border: 2px solid #999;
 }
 
-.imagefield-focus.focus-box
-{
-  min-width: 500px;
+#imagefield-focus-media-form-wrapper {
+  width: 40%;
+  position: fixed;
+  right: 10px;
+  top: 77px;
+  padding: 0 10px;
+  margin: 0 10px 0 0;
+  background-color: #f7ecc8;
+  border: 1px solid #CCC;
+  overflow: auto;
+}
+
+#imagefield-focus-media-form-wrapper .close-button {
+  color: #999;
+  cursor: pointer;
+  right: .1em;
+  font-size: 2em;
+  position: absolute;
+  top: .1em;
 }
diff --git a/imagefield_focus.info b/imagefield_focus.info
index b5b83a5..9622238 100644
--- a/imagefield_focus.info
+++ b/imagefield_focus.info
@@ -3,3 +3,4 @@ description = Allows to scale and crop images focusing on their important portio
 dependencies[] = image
 ; package = CCK
 core = 7.x
+
diff --git a/imagefield_focus.js b/imagefield_focus.js
deleted file mode 100644
index 31fafb2..0000000
--- a/imagefield_focus.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * @file
- * Written by Henri MEDOT <henri.medot[AT]absyx[DOT]fr>
- * http://www.absyx.fr
- */
-
-(function($) {
-
-  // Helper functions.
-  var valToSel = function(val) {
-    var sel = val.split(',');
-    if (sel.length != 4) {
-      return null;
-    }
-
-    for (var i = 0; i < 4; i++) {
-      var v = Number(sel[i]);
-      if (isNaN(v)) {
-        return null;
-      }
-      sel[i] = Math.round(v);
-    }
-
-    if ((sel[0] < 0) || (sel[1] < 0) || (sel[2] <= 0) || (sel[3] <= 0)) {
-      return null;
-    }
-
-    return sel;
-  };
-
-  var selToVal = function(sel) {
-    return (sel) ? sel.join(',') : '';
-  };
-  //~Helper functions.
-
-
-
-  // Drupal behavior.
-  Drupal.behaviors.imagefield_focus = {
-    attach: function(context) {
-      $('.imagefield-focus.focus-box', context).once('imagefield_focus', function() {
-        var $this = $(this);
-        var img = $('> img', $this);
-        var inputs = $('input.imagefield-focus', $this.parent());
-        var fieldName = inputs.attr('name').replace(/^([a-z0-9_]+)\[.+$/, '$1');
-        var settings = Drupal.settings.imagefield_focus[fieldName];
-
-        var minSize, ratio;
-        if (settings.min_width && settings.min_height) {
-          minSize = [settings.min_width, settings.min_height];
-          ratio = settings.lock_ratio;
-        }
-
-        var options = {
-          boxSize: $this.width() || parseInt($this.css('min-width')),
-          realSize: img.attr('alt').split('x'),
-          minSize: minSize
-        };
-        img.css('display', 'block').imgfocus(options);
-
-        inputs.focus(function(e, init) {
-          img.unbind('change.imagefield-focus');
-          var input = $(this).addClass('active');
-          var other = inputs.eq((inputs.index(input) + 1) % 2).removeClass('active');
-          var otherSel = valToSel(other.val());
-          var options = (input.hasClass('crop-rect')) ? {
-            ratio: 0,
-            minRect: otherSel,
-            maxRect: null
-          } : {
-            ratio: ratio,
-            minRect: null,
-            maxRect: otherSel
-          };
-          img.imgfocus('options', options).imgfocus('selection', valToSel(input.val()));
-          img.bind('change.imagefield-focus', function() {
-            input.val(selToVal(img.imgfocus('selection')));
-          });
-
-          if (init) {
-            e.stopPropagation();
-            e.preventDefault();
-            return false;
-          }
-        }).change(function() {
-          $(this).val(selToVal(img.imgfocus('selection', valToSel($(this).val())).imgfocus('selection')));
-        });
-
-        inputs.eq(0).trigger('focus', [true]);
-      });
-    }
-  };
-  //~Drupal behavior.
-
-})(jQuery);
diff --git a/imagefield_focus.module b/imagefield_focus.module
index ec05312..40072b6 100644
--- a/imagefield_focus.module
+++ b/imagefield_focus.module
@@ -8,7 +8,27 @@
 
 require_once dirname(__FILE__) .'/imagefield_focus.effects.inc';
 
+/**
+ * Implements hook_menu().
+ */
+function imagefield_focus_menu() {
+  $items['imagefield_focus/file/%file/%'] = array(
+    'description' => t('AJAX callback that returns the crop and focus form.'),
+    'page callback' => 'imagefield_focus_get_crop_focus_form',
+    'page arguments' => array(2, 3),
+    'access arguments' => array('view'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['imagefield_focus/file/%file/save'] = array(
+    'description' => t('AJAX callback for saving crop and focus information for the given file.'),
+    'page callback' => 'imagefield_focus_crop_focus_submit',
+    'page arguments' => array(2),
+    'access arguments' => array('view'),
+    'type' => MENU_CALLBACK,
+  );
 
+  return $items;
+}
 
 /**
  * Implementation of hook_field_info_alter().
@@ -21,102 +41,142 @@ function imagefield_focus_field_info_alter(&$info) {
   );
 }
 
-
-
 /**
- * Implementation of hook_form_FORM_ID_alter(); alter field_ui_field_edit_form.
+ * Implementation of hook_form_FORM_ID_alter().
  */
 function imagefield_focus_form_field_ui_field_edit_form_alter(&$form, &$form_state, $form_id) {
+  // Add imagefield_focus settings to the field settings form if the field is an
+  // image and has a "process" function.
   if (($form['#field']['type'] == 'image') && imagefield_focus_widget_support($form['#instance']['widget']['type'])) {
-    $settings = $form['#instance']['settings'];
-
-    $additions['focus_settings'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Focus settings'),
-      '#collapsible' => TRUE,
-      '#collapsed' => empty($settings['focus']),
-      '#parents' => array('instance', 'settings'),
-      '#weight' => 17,
-    );
+    $fields = imagefield_focus_settings_form_fields($form, $form_state, $form['#instance']['settings']);
+    $form['instance']['settings'] += $fields;
+  }
+}
 
-    $additions['focus_settings']['focus'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Enable focus'),
-      '#default_value' => (!empty($settings['focus'])) ? $settings['focus'] : 0,
-      '#description' => t('Enable user-defined focus and crop rectangles for images.'),
-    );
+/**
+ * Implementation of hook_form_FORM_ID_alter().
+ */
+function imagefield_focus_form_media_admin_config_browser_alter(&$form, &$form_state) {
+  // Add imagefield_focus settings to the media browser settings form.
+  $fields = imagefield_focus_settings_form_fields($form, $form_state, variable_get('imagefield_focus_media_browser_settings', array()));
+  $form += $fields;
+  $form['#submit'][] = 'imagefield_focus_settings_media_form_submit';
+}
 
-    $focus_min_size = explode('x', $settings['focus_min_size']) + array('', '');
-    $additions['focus_settings']['focus_min_size'] = array(
-      '#type' => 'item',
-      '#title' => t('Minimum size'),
-      '#element_validate' => array('_image_field_resolution_validate', '_imagefield_focus_focus_min_size_validate'),
-      '#field_prefix' => '<div class="container-inline">',
-      '#field_suffix' => '</div>',
-      '#description' => t('The minimum allowed focus rectangle size expressed as WIDTHxHEIGHT (e.g. 100x75). Leave empty for no restriction.'),
-    );
-    $additions['focus_settings']['focus_min_size']['x'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Minimum width'),
-      '#title_display' => 'invisible',
-      '#default_value' => $focus_min_size[0],
-      '#size' => 5,
-      '#maxlength' => 5,
-      '#field_suffix' => ' x ',
-    );
-    $additions['focus_settings']['focus_min_size']['y'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Minimum height'),
-      '#title_display' => 'invisible',
-      '#default_value' => $focus_min_size[1],
-      '#size' => 5,
-      '#maxlength' => 5,
-      '#field_suffix' => ' '. t('pixels'),
-    );
+/**
+ * Returns the fields used by the focus settings form.
+ */
+function imagefield_focus_settings_form_fields($form, $form_state, $values) {
+  $values += array(
+    'focus' => 0,
+    'focus_min_size' => '',
+    'focus_lock_ratio' => 0,
+  );
 
-    $additions['focus_settings']['focus_lock_ratio'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Lock ratio'),
-      '#default_value' => (!empty($settings['focus_lock_ratio'])) ? $settings['focus_lock_ratio'] : 0,
-      '#description' => 'Whether focus rectangle aspect ratio should be maintained based on the minimum size specified above. Checking this box has no effect if no minimum size is specified.',
-    );
+  $fields['focus_settings'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Focus settings'),
+    '#collapsible' => TRUE,
+    '#collapsed' => empty($values['focus']),
+    '#parents' => array('instance', 'settings'),
+    '#weight' => 17,
+  );
+
+  $fields['focus_settings']['focus'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Enable focus'),
+    '#default_value' => (!empty($values['focus'])) ? $values['focus'] : 0,
+    '#description' => t('Enable user-defined focus and crop rectangles for images.'),
+  );
+
+  $focus_min_size = explode('x', $values['focus_min_size']) + array('', '');
+  $fields['focus_settings']['focus_min_size'] = array(
+    '#type' => 'item',
+    '#title' => t('Minimum size'),
+    '#element_validate' => array('_image_field_resolution_validate', '_imagefield_focus_focus_min_size_validate'),
+    '#field_prefix' => '<div class="container-inline">',
+    '#field_suffix' => '</div>',
+    '#description' => t('The minimum allowed focus rectangle size expressed as WIDTHxHEIGHT (e.g. 100x75). Leave empty for no restriction.'),
+  );
+  $fields['focus_settings']['focus_min_size']['x'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Minimum width'),
+    '#title_display' => 'invisible',
+    '#default_value' => $focus_min_size[0],
+    '#size' => 5,
+    '#maxlength' => 5,
+    '#field_suffix' => ' x ',
+  );
+  $fields['focus_settings']['focus_min_size']['y'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Minimum height'),
+    '#title_display' => 'invisible',
+    '#default_value' => $focus_min_size[1],
+    '#size' => 5,
+    '#maxlength' => 5,
+    '#field_suffix' => ' '. t('pixels'),
+  );
+
+  $fields['focus_settings']['focus_lock_ratio'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Lock ratio'),
+    '#default_value' => (!empty($values['focus_lock_ratio'])) ? $values['focus_lock_ratio'] : 0,
+    '#description' => 'Whether focus rectangle aspect ratio should be maintained based on the minimum size specified above. Checking this box has no effect if no minimum size is specified.',
+  );
+
+  return $fields;
+}
 
-    $form['instance']['settings'] += $additions;
+/**
+ * Form submit function that handles focus settings for the media module.
+ */
+function imagefield_focus_settings_media_form_submit($form, $form_state) {
+  // Create an array of all focus settings and save them as a variable.
+  if ($form_state['values']['focus']) {
+    $focus_settings = array(
+      'focus_lock_ratio' => $form_state['values']['focus_lock_ratio'],
+      'focus_min_size' => $form_state['values']['focus_min_size'],
+    );
   }
+  else {
+    $focus_settings = array();
+  }
+
+  variable_set('imagefield_focus_media_browser_settings', $focus_settings);
 }
 
 /**
  * Element validation function; validate focus_min_size.
  */
 function _imagefield_focus_focus_min_size_validate($element, &$form_state, $form) {
-  $min_resolution_element = $form['instance']['settings']['min_resolution'];
-  if (!form_get_error($element['x']) && !form_get_error($element['y'])
-   && !form_get_error($min_resolution_element['x']) && !form_get_error($min_resolution_element['y'])) {
-    $value = $form_state['values']['instance']['settings']['focus_min_size'];
-    if (!empty($value)) {
-      $dimensions = explode('x', $value);
-      $min_resolution_value = $form_state['values']['instance']['settings']['min_resolution'];
-      if (empty($min_resolution_value)) {
-        $error_element = $min_resolution_element['x'];
-      }
-      else {
-        $min_resolution_dimensions = explode('x', $min_resolution_value);
-        if ($min_resolution_dimensions[0] < $dimensions[0]) {
+  if (isset($form['instance']['settings']['min_resolution'])) {
+    $min_resolution_element = $form['instance']['settings']['min_resolution'];
+    if (!form_get_error($element['x']) && !form_get_error($element['y'])
+     && !form_get_error($min_resolution_element['x']) && !form_get_error($min_resolution_element['y'])) {
+      $value = $form_state['values']['instance']['settings']['focus_min_size'];
+      if (!empty($value)) {
+        $dimensions = explode('x', $value);
+        $min_resolution_value = $form_state['values']['instance']['settings']['min_resolution'];
+        if (empty($min_resolution_value)) {
           $error_element = $min_resolution_element['x'];
         }
-        elseif ($min_resolution_dimensions[1] < $dimensions[1]) {
-          $error_element = $min_resolution_element['y'];
+        else {
+          $min_resolution_dimensions = explode('x', $min_resolution_value);
+          if ($min_resolution_dimensions[0] < $dimensions[0]) {
+            $error_element = $min_resolution_element['x'];
+          }
+          elseif ($min_resolution_dimensions[1] < $dimensions[1]) {
+            $error_element = $min_resolution_element['y'];
+          }
+        }
+        if (isset($error_element)) {
+          form_error($error_element, t('Minimum resolution must be set and be greater or equal to focus minimum size, i.e. %focus_min_size.', array('%focus_min_size' => $value)));
         }
-      }
-      if (isset($error_element)) {
-        form_error($error_element, t('Minimum resolution must be set and be greater or equal to focus minimum size, i.e. %focus_min_size.', array('%focus_min_size' => $value)));
       }
     }
   }
 }
 
-
-
 /**
  * Implementation of hook_field_widget_form_alter().
  */
@@ -133,70 +193,113 @@ function imagefield_focus_field_widget_form_alter(&$element, &$form_state, $cont
  * Element #process callback function; process widget type image_image.
  */
 function imagefield_focus_widget_image_image_process($element, &$form_state, $form) {
-  static $added;
+  $added = &drupal_static(__FUNCTION__);
 
   $item = $element['#value'];
+  $item['key'] = $element['#field_name'];
   $field_name = $element['#field_name'];
   $instance = field_widget_instance($element, $form_state);
-  $settings = $instance['settings'];
-
-  // Add JS and CSS.
-  $path = drupal_get_path('module', 'imagefield_focus');
-  drupal_add_js( $path .'/imgfocus/jquery.imgfocus.min.js');
-  drupal_add_js( $path .'/imagefield_focus.js');
-  drupal_add_css($path .'/imgfocus/jquery.imgfocus.css');
-  drupal_add_css($path .'/imagefield_focus.css');
-
-  // Add settings.
-  if (!isset($added[$field_name])) {
-    list($w, $h) = explode('x', $settings['focus_min_size']) + array('', '');
-    drupal_add_js(array(
-      'imagefield_focus' => array(
-        $field_name => array(
-          'min_width' => intval($w),
-          'min_height' => intval($h),
-          'lock_ratio' => !empty($settings['focus_lock_ratio']),
-        ),
-      ),
-    ), 'setting');
-    $added[$field_name] = TRUE;
+
+  if ($element['#file']) {
+    // Add JS and CSS.
+    $path = drupal_get_path('module', 'imagefield_focus');
+    drupal_add_js( $path . '/imgfocus/jquery.imgfocus.min.js');
+    drupal_add_js( $path . '/js/imagefield_focus.js');
+    drupal_add_css($path . '/imgfocus/jquery.imgfocus.css');
+    drupal_add_css($path . '/imagefield_focus.css');
+
+    // Add JS settings.
+    $settings = _imagefield_focus_build_js_settings($field_name, $instance['settings']);
+    drupal_add_js($settings, 'setting');
+
+    $crop_focus_form = imagefield_focus_crop_focus_form_fields($element['#file']->uri, $item);
+    $element += $crop_focus_form;
+    $element['#element_validate'][] = 'imagefield_focus_widget_validate';
+  }
+
+  return $element;
+}
+
+/**
+ * Crop and focus form function.
+ */
+function imagefield_focus_crop_focus_form($form, $form_state, $file) {
+  $item = (array) $file;
+  $form = imagefield_focus_crop_focus_form_fields($file->uri, $item);
+
+  $form['focus_box']['#weight'] = -10;
+  $form['form-title'] = array(
+    '#markup' => '<h3>' . t('Image focus and crop') . '</h3>' . '<div class="description">' . t('Focus and crop information is automatically saved.') . '</div>',
+    '#weight' => -20,
+  );
+  $form['close-button'] = array(
+    '#markup' => '<span class="close-button">&#9746;</span>',
+    '#weight' => 100,
+  );
+  return $form;
+}
+
+/**
+ * Imlpements hook_form_FORM_ID_alter().
+ *
+ * Alter the media browser upload form to add a "upload and set focus" button.
+ */
+function imagefield_focus_form_media_add_upload_alter(&$form, &$form_state) {
+  $form['#submit'][] = 'imagefield_focus_media_add_upload_submit';
+  $form['set_focus'] = array(
+    '#type' => 'submit',
+    '#value' => t('Upload and Set Focus'),
+  );
+}
+
+/**
+ * Submit function for the media browser upload form.
+ */
+function imagefield_focus_media_add_upload_submit($form, &$form_state) {
+  if ($form_state['clicked_button']['#value'] == t('Upload and Set Focus')) {
+    $form_state['redirect'] = array('media/browser', array('fragment' => 'media-tab-library', 'query' => array(
+      'render' => 'media-popup',
+      'imagefield_focus_fid' => isset($form_state['values']['upload']->fid) ? $form_state['values']['upload']->fid : '',
+    )));
   }
+}
 
-  // Add focus fields.
-  $element['focus_rect'] = array(
+/**
+ * Build the focus and crop form.
+ */
+function imagefield_focus_crop_focus_form_fields($uri, $item) {
+  $info = image_get_info($uri);
+
+  $form['focus_rect'] = array(
     '#type' => 'textfield',
     '#title' => t('Focus rectangle'),
     '#default_value' => isset($item['focus_rect']) ? $item['focus_rect'] : '',
     '#description' => t('The important portion of the image to set focus to and that should <strong>never</strong> be cut. It is recommended to keep it as small as possible for best results.'),
-    '#attributes' => array('class' => array('imagefield-focus', 'focus-rect')),
+    '#attributes' => array(
+      'class' => array('imagefield-focus', 'focus-rect'),
+      'data-key' => isset($item['key']) ? $item['key'] : '',
+    ),
     '#access' => (bool) $item['fid'],
   );
-  $element['crop_rect'] = array(
+  $form['crop_rect'] = array(
     '#type' => 'textfield',
     '#title' => t('Crop rectangle'),
     '#default_value' => isset($item['crop_rect']) ? $item['crop_rect'] : '',
     '#description' => t('When set, the portions of the image outside this area will <strong>always</strong> be cut out.'),
-    '#attributes' => array('class' => array('imagefield-focus', 'crop-rect')),
+    '#attributes' => array(
+      'class' => array('imagefield-focus', 'crop-rect'),
+      'data-key' => isset($item['key']) ? $item['key'] : '',
+    ),
     '#access' => (bool) $item['fid'],
   );
 
-  // Add focus box.
-  if ($element['#file']) {
-    $uri = $element['#file']->uri;
-    $info = (isset($element['#value']['width']) && isset($element['#value']['height'])) ? array(
-      'width'  => $element['#value']['width'],
-      'height' => $element['#value']['height'],
-    ) : image_get_info($uri);
-
-    if (is_array($info)) {
-      $element['focus_box'] = array(
-        '#markup' => '<div class="imagefield-focus focus-box"><img src="'. file_create_url($uri) .'" alt="'. $info['width'] .'x'. $info['height'] .'" style="display:none;" /></div>',
-      );
-    }
+  if (is_array($info)) {
+    $form['focus_box'] = array(
+      '#markup' => '<div class="imagefield-focus focus-box"><img src="'. file_create_url($uri) .'" alt="'. $info['width'] .'x'. $info['height'] .'" style="display:none;" /></div>',
+    );
   }
 
-  $element['#element_validate'][] = 'imagefield_focus_widget_validate';
-  return $element;
+  return $form;
 }
 
 /**
@@ -213,8 +316,6 @@ function imagefield_focus_widget_validate($element, &$form_state, $form) {
   }
 }
 
-
-
 /**
  * Implementation of hook_field_attach_insert().
  */
@@ -247,8 +348,6 @@ function imagefield_focus_field_attach_update($entity_type, $entity) {
   imagefield_focus_field_attach_insert($entity_type, $entity);
 }
 
-
-
 /**
  * Implementation of hook_file_insert().
  */
@@ -270,18 +369,15 @@ function imagefield_focus_file_delete($file) {
   _imagefield_focus_file_delete($file);
 }
 
-
-
 /**
- * Implementation of hook_query_TAG_alter(); alter queries tagged with file_load_multiple.
+ * Implementation of hook_query_TAG_alter().
+ * Alter queries tagged with file_load_multiple.
  */
 function imagefield_focus_query_file_load_multiple_alter(QueryAlterableInterface $query) {
   $query->fields('iff', array('focus_rect', 'crop_rect'));
   $query->leftJoin('imagefield_focus_file', 'iff', 'iff.fid = base.fid');
 }
 
-
-
 /**
  * Save focus data.
  */
@@ -305,8 +401,6 @@ function _imagefield_focus_file_save($file) {
   }
 }
 
-
-
 /**
  * Delete focus data.
  */
@@ -314,11 +408,9 @@ function _imagefield_focus_file_delete($file) {
   return db_delete('imagefield_focus_file')->condition('fid', $file->fid)->execute();
 }
 
-
-
 /**
  * Parse a rectangle from a given string.
- * 
+ *
  * @return
  *   A rectangle array or FALSE.
  */
@@ -349,7 +441,53 @@ function imagefield_focus_parse($rect) {
   return $rect;
 }
 
+/**
+ * AJAX callback. Returns a JSON object containing the crop and focus form.
+ */
+function imagefield_focus_get_crop_focus_form($file, $key = '') {
+  $file->key = $key;
+  $form = drupal_get_form('imagefield_focus_crop_focus_form', $file);
+  drupal_json_output(array('form' => drupal_render($form)));
+  exit();
+}
 
+/**
+ * Submit function for the crop and focus form when submitted via AJAX.
+ */
+function imagefield_focus_crop_focus_submit($file) {
+  // Sanitize the crop and focus submissions just to be safe.
+  $crop_rect = isset($_POST['crop_rect']) ? check_plain($_POST['crop_rect']) : '';
+  $focus_rect = isset($_POST['focus_rect']) ? check_plain($_POST['focus_rect']) : '';
+
+  // If valid, save the crop and focus values.
+  if ((strlen($crop_rect) == 0 || imagefield_focus_parse($crop_rect)) && (strlen($focus_rect) == 0 || imagefield_focus_parse($focus_rect))) {
+    $file->crop_rect = $crop_rect;
+    $file->focus_rect = $focus_rect;
+    _imagefield_focus_file_save($file);
+  }
+}
+
+/**
+ * Implements hook_media_browser_plugins_alter().
+ */
+function imagefield_focus_media_browser_plugins_alter(&$plugins) {
+  // Include the imagefield_focus js & css files whenever the media browser is
+  // opened focus is enabled in the media browser settings form and the
+  // "library" plugin is present.
+  $settings = _imagefield_focus_build_js_settings('media_browser', variable_get('imagefield_focus_media_browser_settings', array()));
+  if (isset($plugins['library']) && !empty($settings['imagefield_focus']['media_browser'])) {
+    $path = drupal_get_path('module', 'imagefield_focus');
+    $plugins['library']['#attached']['js'][] = $path . '/imgfocus/jquery.imgfocus.min.js';
+    $plugins['library']['#attached']['js'][] = $path . '/js/imagefield_focus.js';
+    $plugins['library']['#attached']['js'][] = $path . '/js/imagefield_focus.media.js';
+    $plugins['library']['#attached']['css'][] = $path . '/imgfocus/jquery.imgfocus.css';
+    $plugins['library']['#attached']['css'][] = $path . '/imagefield_focus.css';
+    $plugins['library']['#attached']['js'][] = array(
+      'data' => $settings,
+      'type' => 'setting',
+    );
+  }
+}
 
 /**
  * Return whether ImageField Focus has support for the given widget.
@@ -357,3 +495,54 @@ function imagefield_focus_parse($rect) {
 function imagefield_focus_widget_support($type) {
   return function_exists('imagefield_focus_widget_'. $type .'_process');
 }
+
+/**
+ * Helper function to build a javascript settings array. The array returned has
+ * two keys: 'new' and 'settings'. 'New' is true if this is settings array has
+ * not previously been built.
+ *
+ * @param  string $key
+ *   The unique string identifiying this settings array.
+ *
+ * @param  array $focus_settings
+ *   The raw settings array including the following keys: 'focus_lock_ratio' and
+ *   'focus_min_size'.
+ *
+ * @param  boolean $force_return
+ *   If true, the settings array will be returned wether or not it is new. If
+ *   false, it will only be returned if it is new.
+ *
+ * @return array
+ *   If this is a newly added array, the settings array is returned. Otherwise
+ *   an emprt array is returned
+ */
+function _imagefield_focus_build_js_settings($key, $focus_settings, $force_return = FALSE) {
+  $settings = &drupal_static(__FUNCTION__);
+
+  if (!isset($settings[$key])) {
+    if (!empty($focus_settings)) {
+      list($w, $h) = explode('x', $focus_settings['focus_min_size']) + array('', '');
+      $settings[$key] = array(
+        'min_width' => intval($w),
+        'min_height' => intval($h),
+        'lock_ratio' => !empty($focus_settings['focus_lock_ratio']),
+      );
+    }
+    else {
+      $settings[$key] = array();
+    }
+  }
+  else {
+    if (!$force_return) {
+      return array();
+    }
+  }
+
+  $return = array(
+    'imagefield_focus' => array(
+      $key => $settings[$key]
+    ),
+  );
+
+  return $return;
+}
diff --git a/imgfocus/jquery.imgfocus.min.js b/imgfocus/jquery.imgfocus.min.js
index 3441172..c6b0da4 100644
--- a/imgfocus/jquery.imgfocus.min.js
+++ b/imgfocus/jquery.imgfocus.min.js
@@ -24,4 +24,5 @@ d),j=[],m=0;m<8;m++)j[m]=n().addClass("imgfocus-resize imgfocus-handle imgfocus-
 c)}b.imgfocus("options",a)})},options:function(a){a=a||{};return this.each(function(){var b=h(this).data("imgfocus"),c=h.extend(b.options,a),d=b.size,e=c.boxSize||[d[0],d[1]],g=c.realSize||[d[0],d[1]];e.pop||(e=[e,e]);e=(new l(0,0,e[0],e[1])).ratio(g[0]/g[1]);var i=e.clone();d=[e.width,e.height];g=b.scale=[d[0]/g[0],d[1]/g[1]];var f={};f.maxRect=e=(new l(c.maxRect)).scale(g).intersection(e).ifEmpty(e);f.maxSize=c.maxSize?[Math.max(0,Math.min(e.width,c.maxSize[0]*g[0])),Math.max(0,Math.min(e.height,
 c.maxSize[1]*g[1]))]:[e.width,e.height];f.minRect=(new l(c.minRect)).scale(g).intersection(e);var j=f.minRect.size();if(f.minRect.isEmpty()){f.minRect=null;j=[0,0]}f.minSize=j=c.minSize?[Math.min(e.width,Math.max(j[0],c.minSize[0]*g[0])),Math.min(e.height,Math.max(j[1],c.minSize[1]*g[1]))]:j;f.ratio=c.ratio&&!f.minRect?j[0]>0&&j[1]>0?j[0]/j[1]:c.ratio*g[0]/g[1]:0;f.minSize=[Math.max(f.minSize[0],1),Math.max(f.minSize[1],1)];b.rules=f;b.wrapper.width(d[0]).height(d[1]);f.maxRect.equals(i)?b.maxBox.hide():
 f.maxRect.applyTo(b.maxBox.show());f.minRect?f.minRect.applyTo(b.minBox.show()):b.minBox.hide();f.ratio?b.sides.hide():b.sides.show();b.selRect&&b.selRect.constraint(b.constraints());b.repaint().setIdle()})},selection:function(a){return a===undefined?this.data("imgfocus").getSel():this.each(function(){h(this).data("imgfocus").setSel(a)})}};h.fn.imgfocus=function(a){if(u[a])return u[a].apply(this,Array.prototype.slice.call(arguments,1));else if(typeof a=="object"||!a)return u._init.apply(this,arguments);
-else throw"Method "+a+" does not exist on jQuery.imgfocus.";}})(jQuery);
\ No newline at end of file
+else throw"Method "+a+" does not exist on jQuery.imgfocus.";}})(jQuery);
+
diff --git a/js/imagefield_focus.js b/js/imagefield_focus.js
new file mode 100644
index 0000000..6dcab0c
--- /dev/null
+++ b/js/imagefield_focus.js
@@ -0,0 +1,95 @@
+/**
+ * @file
+ * Written by Henri MEDOT <henri.medot[AT]absyx[DOT]fr>
+ * http://www.absyx.fr
+ */
+
+(function($) {
+
+  // Helper functions.
+  var valToSel = function(val) {
+    var sel = val.split(',');
+    if (sel.length != 4) {
+      return null;
+    }
+
+    for (var i = 0; i < 4; i++) {
+      var v = Number(sel[i]);
+      if (isNaN(v)) {
+        return null;
+      }
+      sel[i] = Math.round(v);
+    }
+
+    if ((sel[0] < 0) || (sel[1] < 0) || (sel[2] <= 0) || (sel[3] <= 0)) {
+      return null;
+    }
+
+    return sel;
+  };
+
+  var selToVal = function(sel) {
+    return (sel) ? sel.join(',') : '';
+  };
+  //~Helper functions.
+
+
+
+  // Drupal behavior.
+  Drupal.behaviors.imagefield_focus = {
+    attach: function(context) {
+      $('.imagefield-focus.focus-box', context).once('imagefield_focus', function() {
+        var $this = $(this);
+        var img = $('> img', $this);
+        var inputs = $('input.imagefield-focus', $this.parent());
+        var key = inputs.attr('data-key');
+        var settings = Drupal.settings.imagefield_focus[key];
+
+        var minSize, ratio;
+        if (settings.min_width && settings.min_height) {
+          minSize = [settings.min_width, settings.min_height];
+          ratio = settings.lock_ratio;
+        }
+
+        var options = {
+          boxSize: $this.width() || parseInt($this.css('min-width')),
+          realSize: img.attr('alt').split('x'),
+          minSize: minSize
+        };
+        img.css('display', 'block').imgfocus(options);
+
+        inputs.focus(function(e, init) {
+          img.unbind('change.imagefield-focus');
+          var input = $(this).addClass('active');
+          var other = inputs.eq((inputs.index(input) + 1) % 2).removeClass('active');
+          var otherSel = valToSel(other.val());
+          var options = (input.hasClass('crop-rect')) ? {
+            ratio: 0,
+            minRect: otherSel,
+            maxRect: null
+          } : {
+            ratio: ratio,
+            minRect: null,
+            maxRect: otherSel
+          };
+          img.imgfocus('options', options).imgfocus('selection', valToSel(input.val()));
+          img.bind('change.imagefield-focus', function() {
+            input.val(selToVal(img.imgfocus('selection')));
+          });
+
+          if (init) {
+            e.stopPropagation();
+            e.preventDefault();
+            return false;
+          }
+        }).change(function() {
+          $(this).val(selToVal(img.imgfocus('selection', valToSel($(this).val())).imgfocus('selection')));
+        });
+
+        inputs.eq(0).trigger('focus', [true]);
+      });
+    }
+  };
+  //~Drupal behavior.
+
+})(jQuery);
diff --git a/js/imagefield_focus.media.js b/js/imagefield_focus.media.js
new file mode 100644
index 0000000..46cdb95
--- /dev/null
+++ b/js/imagefield_focus.media.js
@@ -0,0 +1,108 @@
+(function ($) {
+  namespace('Drupal.media.browser');
+
+  // Helper code & functions.
+  // Get querystring as an array split on "&"
+  var querystring = location.search.replace('?', '').split('&');
+  var queryObj = {};
+  // Loop through each name-value pair and populate object
+  for (var i=0; i < querystring.length; i++) {
+    queryObj[querystring[i].split('=')[0]] = querystring[i].split('=')[1];
+  }
+
+  var selToVal = function(sel) {
+    return (sel) ? sel.join(',') : '';
+  };
+
+  var isNumericString = function(val) {
+    return (parseInt(val) + "" == val);
+  }
+  //~Helper functions.
+
+  var render = Drupal.media.browser.library.prototype.render;
+  Drupal.media.browser.library.prototype.render = function() {
+    var that = this;
+
+    // Call the default function provided by media.
+    render.apply(this, Array.prototype.slice.call(arguments));
+
+    var mediaList = $('#media-browser-library-list', Drupal.media.browser.library.renderElement);
+    // If the list doesn't exist, bail.
+    if (mediaList.length === 0) {
+      throw('Cannot continue, list element is missing');
+    }
+
+    // Add a click event to all items in the media list.
+    $('#media-browser-library-list li').bind('click', this.focus);
+
+    // Add a wrapping div in which to place the crop and focus form.
+    if (this.mediaFiles.length > 0) {
+      $('<div></div>').insertAfter(mediaList)
+        .attr('id', 'imagefield-focus-media-form-wrapper')
+        .hide();
+    }
+
+    // If a query string exists, auto select the given file.
+    console.log(queryObj);
+    if (isNumericString(queryObj['imagefield_focus_fid'])) {
+      console.log($('media-item-' + queryObj['imagefield_focus_fid']));
+      $('#media-item-' + queryObj['imagefield_focus_fid']).click();
+    }
+
+  }
+
+  Drupal.media.browser.library.prototype.focus = function() {
+    var fid = $(this).attr('id').split('-').pop();
+
+    // Display the crop and focus form in the correct location.
+    var gotFocusForm = function (data, status) {
+      // Add the html for the form and adjust some styles.
+      var h = $('#scrollbox').innerHeight();
+      $('#scrollbox').css({'padding-right' : '45%', 'position' : 'relative'});
+      $('#imagefield-focus-media-form-wrapper').html(data.form).height(h-2).slideDown();
+
+      // Setup the close button.
+      $('#imagefield-focus-media-form-wrapper .close-button').click(function(){
+        $('#imagefield-focus-media-form-wrapper').slideUp(function(){
+          $('#scrollbox').css({'padding-right' : '0'});
+        });
+      });
+
+      // Whenever the crop or focus data changes, save the change. This is a
+      // more streamlined workflow when working within the media module.
+      $('#imagefield-focus-media-form-wrapper .focus-box > img').bind('change.focus-box', function() {
+        var cropRect = $(this).closest('form').find('input[name="crop_rect"]');
+        var focusRect = $(this).closest('form').find('input[name="focus_rect"]');
+        var postData = {
+          'crop_rect' : cropRect.hasClass('active') ? selToVal($(this).imgfocus('selection')) : cropRect.val(),
+          'focus_rect' : focusRect.hasClass('active') ? selToVal($(this).imgfocus('selection')) : focusRect.val()
+        };
+
+        $.ajax({
+          url: '/imagefield_focus/file/' + fid + '/save',
+          data: postData,
+          type: 'POST',
+          error: function() { alert(Drupal.t('The focus and crop settings could not be saved.')); }
+        });
+      });
+
+      // Make sure all imagefield_focus behaviors have been instantiated. We
+      // cannot use Drupal.attachBehaviors() because hte media module will
+      // incorrectly re-add buttons. @see media.js ~line 64
+      Drupal.behaviors.imagefield_focus.attach();
+    };
+
+    // Display an error if the crop and focus form could not be loaded.
+    var errorCallback = function () {
+      alert(Drupal.t('Error loading the image focus form.'));
+    };
+
+    $.ajax({
+      url: '/imagefield_focus/file/' + fid + '/media_browser', //imagefield_focus/form/%fid/%key
+      type: 'GET',
+      error: errorCallback,
+      success: gotFocusForm
+    });
+  }
+
+}(jQuery));
