diff --git a/javascript/HtmlEditorField.js b/javascript/HtmlEditorField.js index 79793ba68..3bca93b3b 100644 --- a/javascript/HtmlEditorField.js +++ b/javascript/HtmlEditorField.js @@ -1057,44 +1057,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) { diff --git a/thirdparty/tinymce_ssbuttons/editor_plugin_src.js b/thirdparty/tinymce_ssbuttons/editor_plugin_src.js index 43e71cc52..6169922c6 100644 --- a/thirdparty/tinymce_ssbuttons/editor_plugin_src.js +++ b/thirdparty/tinymce_ssbuttons/editor_plugin_src.js @@ -38,7 +38,20 @@ ed.addCommand('ssmedia', function(ed) { jQuery('#' + this.id).entwine('ss').openMediaDialog(); }); - + + // Replace the mceAdvLink and mceLink commands with the sslink command, and + // the mceAdvImage and mceImage commands with the ssmedia command + ed.onBeforeExecCommand.add(function(ed, cmd, ui, val, a){ + if (cmd == 'mceAdvLink' || cmd == 'mceLink'){ + ed.execCommand('sslink', ui, val, a); + a.terminate = true; + } + else if (cmd == 'mceAdvImage' || cmd == 'mceImage'){ + ed.execCommand('ssmedia', ui, val, a); + a.terminate = true; + } + }); + // Disable link button when no link is selected ed.onNodeChange.add(function(ed, cm, n, co) { cm.setDisabled('sslink', co && n.nodeName != 'A');