Skip to content

Instantly share code, notes, and snippets.

@fabsor
Last active August 29, 2015 14:04
Show Gist options
  • Save fabsor/b96095c440d1982c5f92 to your computer and use it in GitHub Desktop.
Save fabsor/b96095c440d1982c5f92 to your computer and use it in GitHub Desktop.
combined patches for media
diff --git a/js/media.popups.js b/js/media.popups.js
index 46af675..9b2d634 100644
--- a/js/media.popups.js
+++ b/js/media.popups.js
@@ -181,6 +181,7 @@ Drupal.media.popups.mediaStyleSelector = function (mediaFile, onSelect, options)
dialogOptions.buttons[ok] = function () {
var formattedMedia = this.contentWindow.Drupal.media.formatForm.getFormattedMedia();
+ formattedMedia.options = $.extend({}, mediaFile.attributes, formattedMedia.options);
if (!formattedMedia) {
alert(notSelected);
return;
diff --git a/modules/media_wysiwyg/includes/media_wysiwyg.filter.inc b/modules/media_wysiwyg/includes/media_wysiwyg.filter.inc
index 8cc99c9..2b0fecf 100644
--- a/modules/media_wysiwyg/includes/media_wysiwyg.filter.inc
+++ b/modules/media_wysiwyg/includes/media_wysiwyg.filter.inc
@@ -166,18 +166,18 @@ function media_wysiwyg_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.
+ // that an inline macro can be generated when the WYSIWYG is detached.
+ // The WYSIWYG plugin is expecting this information in the
+ // Drupal.settings.mediaDataMap variable.
$element = media_wysiwyg_get_file_without_label($file, $tag_info['view_mode'], $settings);
- $data = drupal_json_encode(array(
+ $data = array(
'type' => 'media',
- 'fid' => $file->fid,
+ 'fid' => $file->fid,
'view_mode' => $tag_info['view_mode'],
'link_text' => $tag_info['link_text'],
- ));
- $element['#attributes']['data-file_info'] = urlencode($data);
+ );
+ drupal_add_js(array('mediaDataMap' => array($file->fid => $data)), 'setting');
+ $element['#attributes']['data-fid'] = $file->fid;
$element['#attributes']['class'][] = 'media-element';
}
else {
diff --git a/modules/media_wysiwyg/js/media_wysiwyg.filter.js b/modules/media_wysiwyg/js/media_wysiwyg.filter.js
index 7de50af..aa507fc 100644
--- a/modules/media_wysiwyg/js/media_wysiwyg.filter.js
+++ b/modules/media_wysiwyg/js/media_wysiwyg.filter.js
@@ -15,34 +15,44 @@
*/
replaceTokenWithPlaceholder: function(content) {
Drupal.media.filter.ensure_tagmap()
- var tagmap = Drupal.settings.tagmap,
- matches = content.match(/\[\[.*?\]\]/g),
- media_definition;
+ var matches = content.match(/\[\[.*?"type":"media".*?\]\]/g);
if (matches) {
- for (var macro in tagmap) {
- // We cant use indexOf because of IE.
- var index = $.inArray(macro, matches);
- if (index !== -1) {
- var media_json = macro.replace('[[', '').replace(']]', '');
-
- // Make sure that the media JSON is valid.
- try {
- media_definition = JSON.parse(media_json);
- }
- catch (err) {
- media_definition = null;
- }
- if (media_definition) {
- // Apply attributes.
- var element = Drupal.media.filter.create_element(tagmap[macro], media_definition);
- var markup = Drupal.media.filter.outerHTML(element);
+ for (var i = 0; i < matches.length; i++) {
+ var match = matches[i];
+
+ // Check if the macro exists in the tagmap. This ensures backwards
+ // compatibility with existing media and is moderately more efficient
+ // than re-building the element.
+ var media = Drupal.settings.tagmap[match];
+ var media_json = match.replace('[[', '').replace(']]', '');
+
+ // Ensure that the media JSON is valid.
+ try {
+ var media_definition = JSON.parse(media_json);
+ }
+ catch (err) {
+ // @todo: error logging.
+ // Content should be returned to prevent an empty editor.
+ return content;
+ }
- content = content.replace(macro, markup);
- }
+ // Re-build the media if the macro has changed from the tagmap.
+ if (!media && media_definition.fid) {
+ Drupal.media.filter.ensureSourceMap();
+ var source = Drupal.settings.mediaSourceMap[media_definition.fid];
+ media = document.createElement(source.tagName);
+ media.src = source.src;
}
+
+ // Apply attributes.
+ var element = Drupal.media.filter.create_element(media, media_definition);
+ var markup = Drupal.media.filter.outerHTML(element);
+
+ content = content.replace(match, markup);
}
}
+
return content;
},
@@ -52,27 +62,34 @@
*/
replacePlaceholderWithToken: function(content) {
Drupal.media.filter.ensure_tagmap();
- // Convert all xhtml markup to html for reliable matching/replacing.
- content = content.replace(/[\s]\/\>/g, '>');
- // Re-build the macros in case any element has changed in the editor.
- $('.media-element', content).each(function(i, element) {
- var markup = Drupal.media.filter.outerHTML($(element));
- macro = Drupal.media.filter.create_macro($(element));
+ // Rewrite the tagmap in case any of the macros have changed.
+ Drupal.settings.tagmap = {};
- // Store the macro => html for more efficient rendering in
- // replaceTokenWithPlaceholder().
- Drupal.settings.tagmap[macro] = markup;
- // Replace the media element with its macro.
- content = content.replace(markup, macro);
- });
+ // Wrap the content to be able to use replaceWith() and html().
+ content = $('<div>').append(content);
+ var media = $('.media-element', content);
- return content;
+ if (media.length) {
+ // Replace all media elements with their respective macros.
+ media.replaceWith(function() {
+ var el = $(this),
+ macro = Drupal.media.filter.create_macro(el);
+
+ // Store the markup for more efficient rendering later.
+ // @see replaceTokenWidthPlaceholder()
+ Drupal.settings.tagmap[macro] = Drupal.media.filter.outerHTML(el);
+
+ return macro;
+ });
+ }
+
+ return content.html();
},
/**
- * Serializes file information as a url-encoded JSON object and stores it as a
- * data attribute on the html element.
+ * 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.
@@ -80,13 +97,19 @@
* A object containing the media file information (fid, view_mode, etc).
*/
create_element: function (html, info) {
- if ($('<div></div>').append(html).text().length === html.length) {
- // Element is not an html tag. Surround it in a span element
- // so we can pass the file attributes.
+ if ($('<div>').append(html).text().length === html.length) {
+ // Element is not an html tag. Surround it in a span element so we can
+ // pass the file attributes.
html = '<span>' + html + '</span>';
}
var element = $(html);
+ // Parse out link wrappers. They will be re-applied when the image is
+ // rendered on the front-end.
+ if (element.is('a')) {
+ element = element.children();
+ }
+
// Move attributes from the file info array to the placeholder element.
if (info.attributes) {
$.each(Drupal.settings.media.wysiwyg_allowed_attributes, function(i, a) {
@@ -95,17 +118,28 @@
}
});
delete(info.attributes);
+
+ // Store information to rebuild the element later, if necessary.
+ Drupal.media.filter.ensureSourceMap();
+ Drupal.settings.mediaSourceMap[info.fid] = {
+ tagName: element[0].tagName,
+ src: element[0].src
+ }
}
- // 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)));
- // Adding media-element class so we can find markup element later.
+ // Store the data in the data map.
+ Drupal.media.filter.ensureDataMap();
+ Drupal.settings.mediaDataMap[info.fid] = info;
+
+ // Store the fid in the DOM to retrieve the data from the info map.
+ element.attr('data-fid', info.fid);
+
+ // Add media-element class so we can find markup element later.
var classes = ['media-element'];
- if(info.view_mode){
+ if (info.view_mode) {
classes.push('file-' + info.view_mode.replace(/_/g, '-'));
}
element.addClass(classes.join(' '));
@@ -134,27 +168,27 @@
* A media element with attached serialized file info.
*/
extract_file_info: function (element) {
- var file_json = $.data(element, 'file_info') || element.data('file_info'),
- file_info,
- value;
+ var fid, file_info, value;
- try {
- file_info = JSON.parse(decodeURIComponent(file_json));
- }
- catch (err) {
- file_info = null;
- }
+ if (fid = element.data('fid')) {
+ Drupal.media.filter.ensureDataMap();
- if (file_info) {
- file_info.attributes = {};
+ if (file_info = Drupal.settings.mediaDataMap[fid]) {
+ 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']);
+ // Extract whitelisted attributes.
+ $.each(Drupal.settings.media.wysiwyg_allowed_attributes, function(i, a) {
+ if (value = element.attr(a)) {
+ // Replace &quot; with " to avoid error with JSON format. Note
+ // that it will be JSON encoded later to \".
+ if (typeof value == 'string') {
+ value = value.replace(/&quot;/g, '"');
+ }
+
+ file_info.attributes[a] = value;
+ }
+ });
+ }
}
return file_info;
@@ -186,10 +220,6 @@
// Store macro/markup in the tagmap.
Drupal.media.filter.ensure_tagmap();
- var i = 1;
- for (var key in Drupal.settings.tagmap) {
- i++;
- }
Drupal.settings.tagmap[macro] = markup;
// Return the html code to insert in an editor and use it with
@@ -198,6 +228,22 @@
},
/**
+ * Ensures the src tracking has been initialized and returns it.
+ */
+ ensureSourceMap: function() {
+ Drupal.settings.mediaSourceMap = Drupal.settings.mediaSourceMap || {};
+ return Drupal.settings.mediaSourceMap;
+ },
+
+ /**
+ * Ensures the data tracking has been initialized and returns it.
+ */
+ ensureDataMap: function() {
+ Drupal.settings.mediaDataMap = Drupal.settings.mediaDataMap || {};
+ return Drupal.settings.mediaDataMap;
+ },
+
+ /**
* Ensures the tag map has been initialized and returns it.
*/
ensure_tagmap: function () {
@@ -205,4 +251,5 @@
return Drupal.settings.tagmap;
}
}
+
})(jQuery);
diff --git a/modules/media_wysiwyg/js/wysiwyg-media.js b/modules/media_wysiwyg/js/wysiwyg-media.js
index ac5bf4d..af99097 100644
--- a/modules/media_wysiwyg/js/wysiwyg-media.js
+++ b/modules/media_wysiwyg/js/wysiwyg-media.js
@@ -22,6 +22,7 @@ Drupal.wysiwyg.plugins.media = {
isNode: function(node) {
return $(node).is('img.media-element');
},
+
/**
* Execute the button.
*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment