jonathanasdf

Serious Dabbler

Running javascript from within GWT-CKEditor

leave a comment »

I’ve recently been using the gwt port of CKEditor as a WYSIWYG editor for an app for a school project, and ran into a bit of a problem. The visual mode is very good, but it doesn’t seem to support javascript! For example, the following code produces some text which when clicked should show an alert. But if you actually tried clicking it, nothing happens.

CKEditor e = new CKEditor();
richTextArea.setHTML("<p onclick='alert(\"test\");'>test</p>");

After some messing around, I came up with a solution: throw the javascript in an iframe, and throw the iframe in the editor!

But I didn’t want to create an actual html page on the server for every small bit of javascript I want to have running in there. What I want instead is to inject the html into the iframe directly.

After some more messing around, I finally got it to work. The main work lies in this JSNI function, which works for gwt-ckeditor-0.5.jar

private native void injectToIframeInCKEditor(Element CKEditor, String iframeName, String contents) /*-{
	var editorName = CKEditor.firstChild.firstChild.name;
	var editorIframe = $doc.getElementById("cke_contents_" + editorName).firstChild;
	if (editorIframe.contentDocument) editorIframe = editorIframe.contentDocument;
	else editorIframe = editorIframe.contentWindow.document;

	var ourIframe = editorIframe.getElementById(iframeName);
	if (ourIframe.contentDocument) ourIframe = ourIframe.contentDocument;
	else ourIframe = ourIframe.contentWindow.document;

	ourIframe.open();
	ourIframe.writeln(contents);
	ourIframe.close();
}-*/;

Usage example:
Note: you must wait until the CKEditor has actually been added to the document! Also, this won’t work in source code view (of course)

CKEditor e = new CKEditor();
e.setHTML("<iframe id=\"test\" />");
injectToIframeInCKEditor(e.getElement(), "test", "<body onload='alert(\"Hello World\");'><p onclick='alert(\"test\");'>test</p></body>");

The downside of this is that you will need to have your own buttons that generate iframe code; that is, the built in CKEditor toolbar buttons won’t generate stuff inside the iframe. Also, whenever the iframe is reloaded, either because it was dragged around in the editor or because you went to the source view and back or whatever other reason, it will be reset, and you will have to reinject the data. That would mean adding handlers to check when it would be reset, and possibly autosaving the state of whatever is happening in the iframe.

But, at the very least, you can now run javascript in the editor, which opens the door to a lot more interesting rich editing experiences.

Advertisements

Written by jonathanasdf

November 13, 2011 at 11:43 PM

Posted in GWT, Tutorials

Tagged with ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s