Skip to content

Commit

Permalink
Use postMessage to communicate between the iframe and TinyMCE.
Browse files Browse the repository at this point in the history
This gets around cross-origin issues on the CDN.

Delete plugin.min.js as the Jake command will minimize into the full file.
  • Loading branch information
cahrens committed Apr 2, 2014
1 parent fe84772 commit 9c1a42b
Show file tree
Hide file tree
Showing 4 changed files with 302 additions and 221 deletions.
20 changes: 10 additions & 10 deletions common/lib/xmodule/xmodule/js/src/html/edit.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ class @HTMLEditingDescriptor
ed.on('EditImage', @editImage)
ed.on('SaveLink', @saveLink)
ed.on('EditLink', @editLink)
ed.on('ShowCodeMirror', @showCodeEditor)
ed.on('SaveCodeMirror', @saveCodeEditor)
ed.on('ShowCodeEditor', @showCodeEditor)
ed.on('SaveCodeEditor', @saveCodeEditor)

editImage: (data) =>
# Called when the image plugin will be shown. Input arg is the JSON version of the image data.
Expand All @@ -86,17 +86,17 @@ class @HTMLEditingDescriptor
if data['href']
data['href'] = rewriteStaticLinks(data['href'], '/static/', @base_asset_url)

showCodeEditor: (codeEditor) =>
showCodeEditor: (source) =>
# Called when the CodeMirror Editor is displayed to convert links to show static prefix.
# The input argument is the CodeMirror instance.
content = rewriteStaticLinks(codeEditor.getValue(), @base_asset_url, '/static/')
codeEditor.setValue(content)
# The input argument is a dict with the text content.
content = rewriteStaticLinks(source.content, @base_asset_url, '/static/')
source.content = content

saveCodeEditor: (codeEditor) =>
saveCodeEditor: (source) =>
# Called when the CodeMirror Editor is saved to convert links back to the full form.
# The input argument is the CodeMirror instance.
content = rewriteStaticLinks(codeEditor.getValue(), '/static/', @base_asset_url)
codeEditor.setValue(content)
# The input argument is a dict with the text content.
content = rewriteStaticLinks(source.content, '/static/', @base_asset_url)
source.content = content

initInstanceCallback: (visualEditor) =>
visualEditor.setContent(rewriteStaticLinks(visualEditor.getContent({no_events: 1}), '/static/', @base_asset_url))
Expand Down
120 changes: 105 additions & 15 deletions common/static/js/vendor/tiny_mce/plugins/codemirror/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,114 @@ tinymce.PluginManager.add('codemirror', function(editor, url) {
editor.selection.collapse(true);
editor.selection.setContent('<span class="CmCaReT" style="display:none">&#0;</span>');

// Determine the origin of the window that will host the code editor.
// If tinyMCE's baseURL is relative, then static files are hosted in the
// same origin as the containing page. If it is not relative, then we know that
// the origin of the iframe hosting the code editor will match the origin
// of tinyMCE's baseURL, as they are both hosted on the CDN.
var codeEditorOrigin;
var index = tinyMCE.baseURL.indexOf("/static/");
if (index > 0) {
codeEditorOrigin = tinyMCE.baseURL.substring(0, index);
}
else {
codeEditorOrigin = window.location.origin;
}

// Send the path location for CodeMirror and the parent origin to use in postMessage.
var sourceHtmlParams = "?CodeMirrorPath=" + editor.settings.codemirror.path +
"&ParentOrigin=" + window.location.origin;

// Open editor window
var win = editor.windowManager.open({
title: 'HTML source code',
url: url + '/source.html',
width: 800,
height: 550,
resizable : true,
maximizable : true,
buttons: [
{ text: 'Ok', subtype: 'primary', onclick: function(){
var doc = document.querySelectorAll('.mce-container-body>iframe')[0];
doc.contentWindow.submit();
win.close();
}},
{ text: 'Cancel', onclick: 'close' }
]
});
};
url: url + '/source.html' + sourceHtmlParams,
width: 800,
height: 550,
resizable: true,
maximizable: true,
buttons: [
{ text: 'OK', subtype: 'primary', onclick: function () {
postToCodeEditor({type: "save"});
}},
{ text: 'Cancel', onclick: function () {
postToCodeEditor({type: "cancel"});
}}
]

});

// The master version of TinyMCE has a win.getContentWindow() method. This is its implementation.
var codeWindow = win.getEl().getElementsByTagName('iframe')[0].contentWindow;

var postToCodeEditor = function (data) {
codeWindow.postMessage(data, codeEditorOrigin);
};

var messageListener = function (event) {
// Check that the message came from the code editor.
if (codeEditorOrigin !== event.origin) {
return;
}

var source;
if (event.data.type === "init") {
source = {content: editor.getContent({source_view: true})};
// Post an event to allow rewriting of static links on the content.
editor.fire("ShowCodeEditor", source);

postToCodeEditor(
{
type: "init",
content: source.content
}
);
editor.dom.remove(editor.dom.select('.CmCaReT'));
}
else if (event.data.type === "setText") {
source = {content: event.data.text};
var isDirty = event.data.isDirty;

// Post an event to allow rewriting of static links on the content.
editor.fire('SaveCodeEditor', source);

editor.setContent(source.content);

// Set cursor:
var el = editor.dom.select('span#CmCaReT')[0];
if (el) {
editor.selection.scrollIntoView(el);
editor.selection.setCursorLocation(el,0);
editor.dom.remove(el);
}
// EDX: added because CmCaReT span was getting left in when caret was within a style tag.
// Make sure to strip it out (and accept that caret will not be in the correct place).
else {
var content = editor.getContent();
var strippedContent = content.replace('<span id="CmCaReT"></span>', '');
if (content !== strippedContent) {
editor.setContent(strippedContent);
}
}

// EDX: moved block of code from original location since we may change content in bug fix code above.
editor.isNotDirty = !isDirty;
if (isDirty) {
editor.nodeChanged();
}
}
else if (event.data.type === "closeWindow") {
win.close();
}
};

win.on("close", function() {
window.removeEventListener("message", messageListener);
});

window.addEventListener("message", messageListener, false);

}

// Add a button to the button bar
// EDX changed to show "HTML" on toolbar button
Expand Down

This file was deleted.

Loading

0 comments on commit 9c1a42b

Please sign in to comment.