From 6f937745b0311ac3956a8ccba553006a57d85d7b Mon Sep 17 00:00:00 2001 From: Hamish Friedlander Date: Thu, 31 Jan 2013 16:35:48 +1300 Subject: [PATCH] FIX Not being able to remove, add or edit the caption on an image properly --- javascript/HtmlEditorField.js | 83 +++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 29 deletions(-) diff --git a/javascript/HtmlEditorField.js b/javascript/HtmlEditorField.js index 6d526be28..151358078 100644 --- a/javascript/HtmlEditorField.js +++ b/javascript/HtmlEditorField.js @@ -1047,44 +1047,69 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE; }; }, getHTML: function() { - var el, - attrs = this.getAttributes(), - extraData = this.getExtraData(), - // imgEl = $(''); - imgEl = $('').attr(attrs); - - if(extraData.CaptionText) { - el = $('

' + extraData.CaptionText + '

').prepend(imgEl); - } else { - el = imgEl; - } - return $('
').append(el).html(); // Little hack to get outerHTML string + /* NOP */ }, /** * Logic similar to TinyMCE 'advimage' plugin, insertAndClose() method. */ insertHTML: function(ed) { - var form = this.closest('form'), - node = form.getSelection(), captionNode = node.closest('.captionImage'); + var form = this.closest('form'), node = form.getSelection(), ed = form.getEditor(); - if(node && node.is('img')) { - // If the image exists, update it to avoid complications with inserting TinyMCE HTML content - var attrs = this.getAttributes(), extraData = this.getExtraData(); - node.attr(attrs); - // TODO Doesn't allow adding a caption to image after it was first added - if(captionNode.length) { - captionNode.find('.caption').text(extraData.CaptionText); - captionNode.css({width: attrs.width, height: attrs.height}).attr('class', attrs['class']); + // Get the attributes & extra data + var attrs = this.getAttributes(), extraData = this.getExtraData(); + + // Find the element we are replacing - either the img, it's wrapper parent, or nothing (if creating) + var replacee = (node && node.is('img')) ? node : null; + if (replacee && replacee.parent().is('.captionImage')) replacee = replacee.parent(); + + // Find the img node - either the existing img or a new one, and update it + var img = (node && node.is('img')) ? node : $(''); + img.attr(attrs); + + // Any existing figure or caption node + var container = img.parent('.captionImage'), caption = container.find('.caption'); + + // If we've got caption text, we need a wrapping div.captionImage and sibling p.caption + if (extraData.CaptionText) { + if (!container.length) { + container = $('
'); } - // Undo needs to be added manually as we're doing direct DOM changes - ed.addUndo(); - } else { - // Otherwise insert the whole HTML content - ed.repaint(); - ed.insertContent(this.getHTML(), {skip_undo : 1}); - ed.addUndo(); // Not sure why undo is separate here, replicating TinyMCE logic + + container.attr('class', 'captionImage '+attrs['class']); + + if (!caption.length) { + caption = $('

').appendTo(container); + } + + caption.attr('class', 'caption '+attrs['class']).css('width', attrs.width).text(extraData.CaptionText); + } + // Otherwise forget they exist + else { + container = caption = null; } + // The element we are replacing the replacee with + var replacer = container ? container : img; + + // If we're replacing something, and it's not with itself, do so + if (replacee && replacee.not(replacer).length) { + replacee.replaceWith(replacer); + } + + // If we have a wrapper element, make sure the img is the first child - img might be the + // replacee, and the wrapper the replacer, and we can't do this till after the replace has happened + if (container) { + container.prepend(img); + } + + // If we don't have a replacee, then we need to insert the whole HTML + if (!replacee) { + // Otherwise insert the whole HTML content + ed.repaint(); + ed.insertContent($('
').append(replacer).html(), {skip_undo : 1}); + } + + ed.addUndo(); ed.repaint(); }, updateFromNode: function(node) {