diff --git a/includes/media.filter.inc b/includes/media.filter.inc
index 0f0a254..234a915 100644
--- a/includes/media.filter.inc
+++ b/includes/media.filter.inc
@@ -131,28 +131,29 @@ function media_token_to_markup($match, $wysiwyg = FALSE) {
$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()));
@@ -160,17 +161,28 @@ function media_token_to_markup($match, $wysiwyg = FALSE) {
}
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 {
// Display the field elements.
$element = array();
- $element['content']['#prefix'] = '
';
$element['content']['file'] = media_get_file_without_label($file, $tag_info['view_mode'], $settings);
field_attach_prepare_view('file', array($file->fid => $file), $tag_info['view_mode']);
entity_prepare_view('file', array($file->fid => $file));
$element['content'] += field_attach_view('file', $file, $tag_info['view_mode']);
- $element['content']['#suffix'] = '
';
}
drupal_alter('media_token_to_markup', $element, $tag_info, $settings);
return drupal_render($element);
diff --git a/js/wysiwyg-media.js b/js/wysiwyg-media.js
index bbcaac0..152e469 100644
--- a/js/wysiwyg-media.js
+++ b/js/wysiwyg-media.js
@@ -8,153 +8,89 @@
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 $('').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
![]()
- * instead of just
![]()
, for now though, we're going to remove all the stuff surrounding the images.
- *
- * @param String formattedMedia
- * Element containing the image
- *
- * @return HTML of
![]()
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;
+ ensure_tagmap();
+
+ var tagmap = Drupal.settings.tagmap,
+ matches = content.match(/\[\[.*?\]\]/g),
+ media_definition;
+
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
..
![]()
-
- var _tag = inlineTag;
- _tag = _tag.replace('[[','');
- _tag = _tag.replace(']]','');
+ 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 +101,186 @@ 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