diff --git a/includes/media.filter.inc b/includes/media.filter.inc
index 1a28dc1..28d2a68 100644
--- a/includes/media.filter.inc
+++ b/includes/media.filter.inc
@@ -99,39 +99,55 @@ function media_token_to_markup($match, $wysiwyg = FALSE) {
     // Track the fid of this file in the {media_filter_usage} table.
     media_filter_track_usage($file->fid);
 
-    $attributes = is_array($tag_info['attributes']) ? $tag_info['attributes'] : array();
-    $attribute_whitelist = media_variable_get('wysiwyg_allowed_attributes');
-    $settings['attributes'] = array_intersect_key($attributes, array_flip($attribute_whitelist));
-
-    // Many media formatters will want to apply width and height independently
-    // of the style attribute or the corresponding HTML attributes, so pull
-    // these two out into top-level settings. Different WYSIWYG editors have
-    // different behavior with respect to whether they store user-specified
-    // dimensions in the HTML attributes or the style attribute, so check both.
-    // Per http://www.w3.org/TR/html5/the-map-element.html#attr-dim-width, the
-    // HTML attributes are merely hints: CSS takes precedence.
-    if (isset($settings['attributes']['style'])) {
-      $css_properties = media_parse_css_declarations($settings['attributes']['style']);
-      foreach (array('width', 'height') as $dimension) {
-        if (isset($css_properties[$dimension]) && substr($css_properties[$dimension], -2) == 'px') {
-          $settings[$dimension] = substr($css_properties[$dimension], 0, -2);
-        }
-        elseif (isset($settings['attributes'][$dimension])) {
-          $settings[$dimension] = $settings['attributes'][$dimension];
+    if (!empty($tag_info['attributes']) && is_array($tag_info['attributes'])) {
+      $attribute_whitelist = media_variable_get('wysiwyg_allowed_attributes');
+      $settings['attributes'] = array_intersect_key($tag_info['attributes'], array_flip($attribute_whitelist));
+
+      // Many media formatters will want to apply width and height independently
+      // of the style attribute or the corresponding HTML attributes, so pull
+      // these two out into top-level settings. Different WYSIWYG editors have
+      // different behavior with respect to whether they store user-specified
+      // dimensions in the HTML attributes or the style attribute, so check both.
+      // Per http://www.w3.org/TR/html5/the-map-element.html#attr-dim-width, the
+      // HTML attributes are merely hints: CSS takes precedence.
+      if (isset($settings['attributes']['style'])) {
+        $css_properties = media_parse_css_declarations($settings['attributes']['style']);
+        foreach (array('width', 'height') as $dimension) {
+          if (isset($css_properties[$dimension]) && substr($css_properties[$dimension], -2) == 'px') {
+            $settings[$dimension] = substr($css_properties[$dimension], 0, -2);
+          }
+          elseif (isset($settings['attributes'][$dimension])) {
+            $settings[$dimension] = $settings['attributes'][$dimension];
+          }
         }
       }
     }
-
-    if ($wysiwyg) {
-      $settings['wysiwyg'] = $wysiwyg;
-    }
   }
   catch (Exception $e) {
     watchdog('media', 'Unable to render media from %tag. Error: %error', array('%tag' => $tag, '%error' => $e->getMessage()));
     return '';
   }
 
-  $element = media_get_file_without_label($file, $tag_info['view_mode'], $settings);
+  if ($wysiwyg) {
+    $settings['wysiwyg'] = $wysiwyg;
+    // If sending markup to a WYSIWYG, we need to pass the file infomation so
+    // that a inline macro can be generated when the WYSIWYG is detached.
+    // The WYSIWYG plugin is expecting this information in the format of a
+    // urlencoded JSON string stored in the data-file_info attribute of the
+    // element.
+    $element = media_get_file_without_label($file, $tag_info['view_mode'], $settings);
+    $data = drupal_json_encode(array(
+      'type' => 'media',
+      'fid' => $file->fid,
+      'view_mode' => $tag_info['view_mode'],
+    ));
+    $element['#attributes']['data-file_info'] = urlencode($data);
+    $element['#attributes']['class'][] = 'media-element';
+  }
+  else {
+    $element = media_get_file_without_label($file, $tag_info['view_mode'], $settings);
+  }
+
   drupal_alter('media_token_to_markup', $element, $tag_info, $settings);
   return drupal_render($element);
 }
@@ -366,6 +382,10 @@ function media_get_file_without_label($file, $view_mode, $settings = array()) {
     }
   }
 
+  if (!empty($element['#attributes']['class']) && !is_array($element['#attributes']['class'])) {
+    $element['#attributes']['class'] = array($element['#attributes']['class']);
+  }
+
   return $element;
 }
 
diff --git a/js/wysiwyg-media.js b/js/wysiwyg-media.js
index 97697f0..ebc0b3e 100644
--- a/js/wysiwyg-media.js
+++ b/js/wysiwyg-media.js
@@ -7,154 +7,89 @@
 (function ($) {
 
 Drupal.media = Drupal.media || {};
-
-// Define the behavior.
+/**
+ * Register the plugin with WYSIWYG.
+ */
 Drupal.wysiwyg.plugins.media = {
 
   /**
-   * Initializes the tag map.
+   * Determine whether a DOM element belongs to this plugin.
+   *
+   * @param node
+   *   A DOM element.
    */
-  initializeTagMap: function () {
-    if (typeof Drupal.settings.tagmap == 'undefined') {
-      Drupal.settings.tagmap = { };
-    }
+  isNode: function(node) {
+    return $(node).is('img.media-element');
   },
   /**
    * Execute the button.
-   * @TODO: Debug calls from this are never called. What's its function?
+   *
+   * @param data
+   *   An object containing data about the current selection:
+   *   - format: 'html' when the passed data is HTML content, 'text' when the
+   *     passed data is plain-text content.
+   *   - node: When 'format' is 'html', the focused DOM element in the editor.
+   *   - content: The textual representation of the focused/selected editor
+   *     content.
+   * @param settings
+   *   The plugin settings, as provided in the plugin's PHP include file.
+   * @param instanceId
+   *   The ID of the current editor instance.
    */
   invoke: function (data, settings, instanceId) {
     if (data.format == 'html') {
-      Drupal.media.popups.mediaBrowser(function (mediaFiles) {
-        Drupal.wysiwyg.plugins.media.mediaBrowserOnSelect(mediaFiles, instanceId);
-      }, settings['global']);
-    }
-  },
-
-  /**
-   * Respond to the mediaBrowser's onSelect event.
-   * @TODO: Debug calls from this are never called. What's its function?
-   */
-  mediaBrowserOnSelect: function (mediaFiles, instanceId) {
-    var mediaFile = mediaFiles[0];
-    var options = {};
-    Drupal.media.popups.mediaStyleSelector(mediaFile, function (formattedMedia) {
-      Drupal.wysiwyg.plugins.media.insertMediaFile(mediaFile, formattedMedia.type, formattedMedia.html, formattedMedia.options, Drupal.wysiwyg.instances[instanceId]);
-    }, options);
-
-    return;
-  },
-
-  insertMediaFile: function (mediaFile, viewMode, formattedMedia, options, wysiwygInstance) {
-
-    this.initializeTagMap();
-    // @TODO: the folks @ ckeditor have told us that there is no way
-    // to reliably add wrapper divs via normal HTML.
-    // There is some method of adding a "fake element"
-    // But until then, we're just going to embed to img.
-    // This is pretty hacked for now.
-    //
-    var imgElement = $(this.stripDivs(formattedMedia));
-    this.addImageAttributes(imgElement, mediaFile.fid, viewMode, options);
-
-    var toInsert = this.outerHTML(imgElement);
-    // Create an inline tag
-    var inlineTag = Drupal.wysiwyg.plugins.media.createTag(imgElement);
-    // Add it to the tag map in case the user switches input formats
-    Drupal.settings.tagmap[inlineTag] = toInsert;
-    wysiwygInstance.insert(toInsert);
-  },
-
-  /**
-   * Gets the HTML content of an element
-   *
-   * @param jQuery element
-   */
-  outerHTML: function (element) {
-    return $('<div>').append( element.eq(0).clone() ).html();
-  },
-
-  addImageAttributes: function (imgElement, fid, view_mode, additional) {
-    //    imgElement.attr('fid', fid);
-    //    imgElement.attr('view_mode', view_mode);
-    // Class so we can find this image later.
-    imgElement.addClass('media-image');
-    this.forceAttributesIntoClass(imgElement, fid, view_mode, additional);
-    if (additional) {
-      for (k in additional) {
-        if (additional.hasOwnProperty(k)) {
-          if (k === 'attr') {
-            imgElement.attr(k, additional[k]);
-          }
-        }
+      var insert = new InsertMedia(instanceId);
+      if (this.isNode(data.node)) {
+        // Change the view mode for already-inserted media.
+        var media_file = extract_file_info($(data.node));
+        insert.onSelect([media_file]);
+      }
+      else {
+        // Insert new media.
+        insert.prompt(settings.global);
       }
     }
   },
 
   /**
-   * Due to problems handling wrapping divs in ckeditor, this is needed.
-   *
-   * Going forward, if we don't care about supporting other editors
-   * we can use the fakeobjects plugin to ckeditor to provide cleaner
-   * transparency between what Drupal will output <div class="field..."><img></div>
-   * instead of just <img>, for now though, we're going to remove all the stuff surrounding the images.
-   *
-   * @param String formattedMedia
-   *  Element containing the image
-   *
-   * @return HTML of <img> tag inside formattedMedia
-   */
-  stripDivs: function (formattedMedia) {
-    // Check to see if the image tag has divs to strip
-    var stripped = null;
-    if ($(formattedMedia).is('img')) {
-      stripped = this.outerHTML($(formattedMedia));
-    } else {
-      stripped = this.outerHTML($('img', $(formattedMedia)));
-    }
-    // This will fail if we pass the img tag without anything wrapping it, like we do when re-enabling WYSIWYG
-    return stripped;
-  },
-
-  /**
    * Attach function, called when a rich text editor loads.
    * This finds all [[tags]] and replaces them with the html
    * that needs to show in the editor.
    *
+   * This finds all JSON macros and replaces them with the HTML placeholder
+   * that will show in the editor.
    */
   attach: function (content, settings, instanceId) {
-    var matches = content.match(/\[\[.*?\]\]/g);
-    this.initializeTagMap();
-    var tagmap = Drupal.settings.tagmap;
-    if (matches) {
-      var inlineTag = "";
-      for (i = 0; i < matches.length; i++) {
-        inlineTag = matches[i];
-        if (tagmap[inlineTag]) {
-          // This probably needs some work...
-          // We need to somehow get the fid propogated here.
-          // We really want to
-          var tagContent = tagmap[inlineTag];
-          var mediaMarkup = this.stripDivs(tagContent); // THis is <div>..<img>
+    ensure_tagmap();
 
-          var _tag = inlineTag;
-          _tag = _tag.replace('[[','');
-          _tag = _tag.replace(']]','');
+    var tagmap = Drupal.settings.tagmap,
+        matches = content.match(/\[\[.*?\]\]/g),
+        media_definition;
+
+    if (matches) {
+      for (var index in matches) {
+        var macro = matches[index];
+
+        if (tagmap[macro]) {
+          var media_json = macro.replace('[[', '').replace(']]', '');
+
+          // Make sure that the media JSON is valid.
           try {
-            mediaObj = JSON.parse(_tag);
+            media_definition = JSON.parse(media_json);
           }
-          catch(err) {
-            mediaObj = null;
+          catch (err) {
+            media_definition = null;
           }
-          if(mediaObj) {
-            var imgElement = $(mediaMarkup);
-            this.addImageAttributes(imgElement, mediaObj.fid, mediaObj.view_mode);
-            var toInsert = this.outerHTML(imgElement);
-            content = content.replace(inlineTag, toInsert);
+          if (media_definition) {
+            // Apply attributes.
+            var element = create_element(tagmap[macro], media_definition);
+            var markup = outerHTML(element);
+
+            content = content.replace(macro, markup);
           }
         }
         else {
-          debug.debug("Could not find content for " + inlineTag);
+          debug.debug("Could not find content for " + macro);
         }
       }
     }
@@ -165,221 +100,187 @@ Drupal.wysiwyg.plugins.media = {
    * Detach function, called when a rich text editor detaches
    */
   detach: function (content, settings, instanceId) {
-    // Replace all Media placeholder images with the appropriate inline json
-    // string. Using a regular expression instead of jQuery manipulation to
-    // prevent <script> tags from being displaced.
-    // @see http://drupal.org/node/1280758.
-    if (matches = content.match(/<img[^>]+class=([\'"])media-image[^>]*>/gi)) {
-      for (var i = 0; i < matches.length; i++) {
-        var imageTag = matches[i];
-        var inlineTag = Drupal.wysiwyg.plugins.media.createTag($(imageTag));
-        Drupal.settings.tagmap[inlineTag] = imageTag;
-        content = content.replace(imageTag, inlineTag);
+    ensure_tagmap();
+    var tagmap = Drupal.settings.tagmap,
+        i = 0,
+        markup,
+        macro;
+
+    // Replace all media placeholders with their JSON macro representations.
+    //
+    // There are issues with using jQuery to parse the WYSIWYG content (see
+    // http://drupal.org/node/1280758), and parsing HTML with regular
+    // expressions is a terrible idea (see http://stackoverflow.com/a/1732454/854985)
+    //
+    // WYSIWYG editors act wacky with complex placeholder markup anyway, so an
+    // image is the most reliable and most usable anyway: images can be moved by
+    // dragging and dropping, and can be resized using interactive handles.
+    //
+    // Media requests a WYSIWYG place holder rendering of the file by passing
+    // the wysiwyg => 1 flag in the settings array when calling
+    // media_get_file_without_label().
+    var matches = content.match(/<img[^>]+class=[\'"]([^"']+ )?media-element[^>]*>/gi);
+    if (matches) {
+      for (i = 0; i < matches.length; i++) {
+        markup = matches[i];
+        macro = create_macro($(markup));
+        tagmap[macro] = markup;
+        content = content.replace(markup, macro);
       }
     }
+
     return content;
+  }
+};
+/**
+ * Defining InsertMedia object to manage the sequence of actions involved in
+ * inserting a media element into the WYSIWYG.
+ * Keeps track of the WYSIWYG instance id.
+ */
+var InsertMedia = function (instance_id) {
+  this.instanceId = instance_id;
+  return this;
+};
+
+InsertMedia.prototype = {
+  /**
+   * Prompt user to select a media item with the media browser.
+   *
+   * @param settings
+   *    Settings object to pass on to the media browser.
+   *    TODO: Determine if this is actually necessary.
+   */
+  prompt: function (settings) {
+    Drupal.media.popups.mediaBrowser($.proxy(this, 'onSelect'), settings);
   },
 
   /**
-   * @param jQuery imgNode
-   *  Image node to create tag from
+   * On selection of a media item, display item's display configuration form.
    */
-  createTag: function (imgNode) {
-    // Currently this is the <img> itself
-    // Collect all attribs to be stashed into tagContent
-    var mediaAttributes = {};
-    var imgElement = imgNode[0];
-    var sorter = [];
+  onSelect: function (media_files) {
+    this.mediaFile = media_files[0];
+    Drupal.media.popups.mediaStyleSelector(this.mediaFile, $.proxy(this, 'insert'), {});
+  },
 
-    // @todo: this does not work in IE, width and height are always 0.
-    for (i=0; i< imgElement.attributes.length; i++) {
-      var attr = imgElement.attributes[i];
-      if (attr.specified == true) {
-        if (attr.name !== 'class') {
-          sorter.push(attr);
-        }
-        else {
-          // Exctract expando properties from the class field.
-          var attributes = this.getAttributesFromClass(attr.value);
-          for (var name in attributes) {
-            if (attributes.hasOwnProperty(name)) {
-              var value = attributes[name];
-              if (value.type && value.type === 'attr') {
-                sorter.push(value);
-              }
-            }
-          }
-        }
-      }
-    }
+  /**
+   * When display config has been set, insert the placeholder markup into the
+   * wysiwyg and generate its corresponding json macro pair to be added to the
+   * tagmap.
+   */
+  insert: function (formatted_media) {
+    var element = create_element(formatted_media.html, {
+          fid: this.mediaFile.fid,
+          view_mode: formatted_media.type
+        });
 
-    sorter.sort(this.sortAttributes);
+    var markup = outerHTML(element),
+        macro = create_macro(element);
 
-    for (var prop in sorter) {
-      mediaAttributes[sorter[prop].name] = sorter[prop].value;
-    }
+    // Insert placeholder markup into wysiwyg.
+    Drupal.wysiwyg.instances[this.instanceId].insert(markup);
 
-    // The following 5 ifs are dedicated to IE7
-    // If the style is null, it is because IE7 can't read values from itself
-    if (jQuery.browser.msie && jQuery.browser.version == '7.0') {
-      if (mediaAttributes.style === "null") {
-        var imgHeight = imgNode.css('height');
-        var imgWidth = imgNode.css('width');
-        mediaAttributes.style = {
-          height: imgHeight,
-          width: imgWidth
-        }
-        if (!mediaAttributes['width']) {
-          mediaAttributes['width'] = imgWidth;
-        }
-        if (!mediaAttributes['height']) {
-          mediaAttributes['height'] = imgHeight;
-        }
-      }
-      // If the attribute width is zero, get the CSS width
-      if (Number(mediaAttributes['width']) === 0) {
-        mediaAttributes['width'] = imgNode.css('width');
-      }
-      // IE7 does support 'auto' as a value of the width attribute. It will not
-      // display the image if this value is allowed to pass through
-      if (mediaAttributes['width'] === 'auto') {
-        delete mediaAttributes['width'];
-      }
-      // If the attribute height is zero, get the CSS height
-      if (Number(mediaAttributes['height']) === 0) {
-        mediaAttributes['height'] = imgNode.css('height');
-      }
-      // IE7 does support 'auto' as a value of the height attribute. It will not
-      // display the image if this value is allowed to pass through
-      if (mediaAttributes['height'] === 'auto') {
-        delete mediaAttributes['height'];
-      }
-    }
+    // Store macro/markup pair in the tagmap.
+    ensure_tagmap();
+    Drupal.settings.tagmap[macro] = markup;
+  }
+};
 
-   // Convert style-based floating of images to classes. Note we leave the
-   // the attribute so that the WYSIWYG editor will remember the setting.
-   // First, remove any previous left/right classes, note that class will
-   // contain at least 'media-image'
-   mediaAttributes['class'] = mediaAttributes['class'].replace(/\s*media-image-(left|right)\s*/g, ' ');
+/** Helper functions */
 
-   // Add appropriate left/right class to the <img> tag.
-   if (mediaAttributes['style']) {
-     if (-1 != mediaAttributes['style'].indexOf('float: right;')) {
-       mediaAttributes['class'] += ' media-image-right';
-    }
-    if (-1 != mediaAttributes['style'].indexOf('float: left;')) {
-      mediaAttributes['class'] += ' media-image-left';
-     }
-   }
+/**
+ * Ensures the tag map has been initialized.
+ */
+function ensure_tagmap () {
+  Drupal.settings.tagmap = Drupal.settings.tagmap || {};
+}
 
-    // Remove elements from attribs using the blacklist
-    for (var blackList in Drupal.settings.media.blacklist) {
-      delete mediaAttributes[Drupal.settings.media.blacklist[blackList]];
-    }
-    tagContent = {
-      "type": 'media',
-      // @todo: This will be selected from the format form
-      "view_mode": attributes['view_mode'].value,
-      "fid" : attributes['fid'].value,
-      "attributes": mediaAttributes
-    };
-    return '[[' + JSON.stringify(tagContent) + ']]';
-  },
+/**
+ * Serializes file information as a url-encoded JSON object and stores it as a
+ * data attribute on the html element.
+ *
+ * @param html (string)
+ *    A html element to be used to represent the inserted media element.
+ * @param info (object)
+ *    A object containing the media file information (fid, view_mode, etc).
+ */
+function create_element (html, info) {
+  var element = $(html);
 
-  /**
-   * Forces custom attributes into the class field of the specified image.
-   *
-   * Due to a bug in some versions of Firefox
-   * (http://forums.mozillazine.org/viewtopic.php?f=9&t=1991855), the
-   * custom attributes used to share information about the image are
-   * being stripped as the image markup is set into the rich text
-   * editor.  Here we encode these attributes into the class field so
-   * the data survives.
-   *
-   * @param imgElement
-   *   The image
-   * @fid
-   *   The file id.
-   * @param view_mode
-   *   The view mode.
-   * @param additional
-   *   Additional attributes to add to the image.
-   */
-  forceAttributesIntoClass: function (imgElement, fid, view_mode, additional) {
-    var wysiwyg = imgElement.attr('wysiwyg');
-    if (wysiwyg) {
-      imgElement.addClass('attr__wysiwyg__' + wysiwyg);
-    }
-    var format = imgElement.attr('format');
-    if (format) {
-      imgElement.addClass('attr__format__' + format);
-    }
-    var typeOf = imgElement.attr('typeof');
-    if (typeOf) {
-      imgElement.addClass('attr__typeof__' + typeOf);
-    }
-    if (fid) {
-      imgElement.addClass('img__fid__' + fid);
-    }
-    if (view_mode) {
-      imgElement.addClass('img__view_mode__' + view_mode);
-    }
-    if (additional) {
-      for (var name in additional) {
-        if (additional.hasOwnProperty(name)) {
-          if (name !== 'alt') {
-            imgElement.addClass('attr__' + name + '__' + additional[name]);
-          }
-        }
+  // Move attributes from the file info array to the placeholder element.
+  if (info.attributes) {
+    $.each(Drupal.settings.media.wysiwyg_allowed_attributes, function(i, a) {
+      if (info.attributes[a]) {
+        element.attr(a, info.attributes[a]);
       }
-    }
-  },
+    });
+    delete(info.attributes);
+  }
 
-  /**
-   * Retrieves encoded attributes from the specified class string.
-   *
-   * @param classString
-   *   A string containing the value of the class attribute.
-   * @return
-   *   An array containing the attribute names as keys, and an object
-   *   with the name, value, and attribute type (either 'attr' or
-   *   'img', depending on whether it is an image attribute or should
-   *   be it the attributes section)
-   */
-  getAttributesFromClass: function (classString) {
-    var actualClasses = [];
-    var otherAttributes = [];
-    var classes = classString.split(' ');
-    var regexp = new RegExp('^(attr|img)__([^\S]*)__([^\S]*)$');
-    for (var index = 0; index < classes.length; index++) {
-      var matches = classes[index].match(regexp);
-      if (matches && matches.length === 4) {
-        otherAttributes[matches[2]] = {name: matches[2], value: matches[3], type: matches[1]};
-      }
-      else {
-        actualClasses.push(classes[index]);
-      }
-    }
-    if (actualClasses.length > 0) {
-      otherAttributes['class'] = {name: 'class', value: actualClasses.join(' '), type: 'attr'};
-    }
-    return otherAttributes;
-  },
+  // Important to url-encode the file information as it is being stored in an
+  // html data attribute.
+  info.type = info.type || "media";
+  element.attr('data-file_info', encodeURI(JSON.stringify(info)));
 
-  /*
-   *
-   */
-  sortAttributes: function (a, b) {
-    var nameA = a.name.toLowerCase();
-    var nameB = b.name.toLowerCase();
-    if (nameA < nameB) {
-      return -1;
-    }
-    if (nameA > nameB) {
-      return 1;
-    }
-    return 0;
+  // Adding media-element class so we can find markup element later.
+  element.addClass('media-element');
+
+  return element;
+}
+
+/**
+ * Create a macro representation of the inserted media element.
+ *
+ * @param element (jQuery object)
+ *    A media element with attached serialized file info.
+ */
+function create_macro (element) {
+  var file_info = extract_file_info(element);
+  if (file_info) {
+    return '[[' + JSON.stringify(file_info) + ']]';
   }
-};
+  return false;
+}
+
+/**
+ * Extract the file info from a WYSIWYG placeholder element as JSON.
+ *
+ * @param element (jQuery object)
+ *    A media element with attached serialized file info.
+ */
+function extract_file_info (element) {
+  var file_json = $.data(element, 'file_info') || element.data('file_info'),
+      file_info,
+      value;
+
+  try {
+    file_info = JSON.parse(decodeURIComponent(file_json));
+  }
+  catch (err) {
+    file_info = null;
+  }
+
+  if (file_info) {
+    file_info.attributes = {};
+
+    // Extract whitelisted attributes.
+    $.each(Drupal.settings.media.wysiwyg_allowed_attributes, function(i, a) {
+      if (value = element.attr(a)) {
+        file_info.attributes[a] = value;
+      }
+    });
+    delete(file_info.attributes['data-file_info']);
+  }
+
+  return file_info;
+}
+
+/**
+ * Gets the HTML content of an element.
+ *
+ * @param element (jQuery object)
+ */
+function outerHTML (element) {
+  return $('<div>').append(element.eq(0).clone()).html();
+}
 
 })(jQuery);
diff --git a/wysiwyg_plugins/media.inc b/wysiwyg_plugins/media.inc
index e0e2c0d..597598b 100644
--- a/wysiwyg_plugins/media.inc
+++ b/wysiwyg_plugins/media.inc
@@ -63,7 +63,7 @@ function media_include_browser_js() {
     }
   }
   // Add wysiwyg-specific settings.
-  $settings = array('blacklist' => array('src', 'fid', 'view_mode', 'format'));
+  $settings = array('wysiwyg_allowed_attributes' => media_variable_get('wysiwyg_allowed_attributes'));
   drupal_add_js(array('media' => $settings), 'setting');
 }
 
