Skip to content

Instantly share code, notes, and snippets.

@matthewkastor
Last active June 1, 2017 12:12
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matthewkastor/5275437 to your computer and use it in GitHub Desktop.
Save matthewkastor/5275437 to your computer and use it in GitHub Desktop.
This class allows you to easily replace the source view in CKEditor with any web based code editor e.g. Ace, Code Mirror, etc.
/*jslint
indent: 4,
maxerr: 50,
white: true,
browser: true,
vars: true
*/
/*global
CKEDITOR
*/
/**
* CKEditor SourceViewReplacer Class.
* @author <a href="mailto:matthewkastor@gmail.com">
* Matthew Christopher Kastor-Inare III </a><br />
* ☭ Hial Atropa!! ☭
* @version 20130330
* @class CKEditor SourceViewReplacer Class.
* @param {CKEditor.editor} editor The ck editor instance.
* @param {object} highlighter An options object for setting up the code highlighter. It
* must have a parameter `url` pointing to a page containing a code highlighter
* which will be loaded into an iframe. This iframe will replace the plain
* text area in the source view. The highlighter must also have a method
* named `hook` which will take the window object of the iframe with your code
* highlighter loaded into it and return an object having both a `getValue` and
* `setValue` method which will get and set the contents of your source code
* highlighter.
* @example
* var highlighter = {
* 'url' : 'http://atropa-editors.net63.net/ACEeditor.html.html',
* 'hook' : function (frameWindow) {
* var out = {};
* out.getValue = function () {
* return frameWindow.editor.session.getValue();
* };
* out.setValue = function (val) {
* return frameWindow.editor.session.setValue(val);
* };
* return out;
* }
* };
*
* // given a textarea with the id "newFile"
*
* CKEDITOR.replace('newFile', {
* on: {
* 'instanceReady': function instanceReadyFn (evt) {
* "use strict";
* var sourceViewer = new SourceViewReplacer(evt.editor, highlighter);
* }
* }
* });
*/
function SourceViewReplacer (editor, highlighter) {
"use strict";
var my = this;
my.highlighter = highlighter || {
'url' : 'http://atropa-editors.net63.net/ACEeditor.html.html',
'hook' : function (frameWindow) {
var out = {};
out.getValue = function () {
return frameWindow.editor.session.getValue();
};
out.setValue = function (val) {
return frameWindow.editor.session.setValue(val);
};
return out;
}
};
function highlighterSetup(textarea) {
function l () {
textarea.value = my.codeHighlighter.getValue();
}
my.editor.on('mode', function () {
my.editor.removeListener('beforeCommandExec', l);
});
my.editor.on('beforeCommandExec', l);
my.codeHighlighter.setValue(textarea.value);
}
function sourceViewOverride() {
var hook;
var textarea = my.getSourceEditorTextarea();
textarea.style.cssText = textarea.style.cssText + ';display:none;';
my.codeHighlighter.frame = document.createElement('iframe');
my.codeHighlighter.frame.setAttribute('src', my.highlighter.url);
my.codeHighlighter.frame.setAttribute('style',
'padding: 0; margin: 0; border: none; ' +
'height: 100%; width: 100%; overflow: auto;'
);
textarea.parentNode.appendChild(my.codeHighlighter.frame);
function waitForHighlighter() {
try {
hook = my.highlighter.hook(my.codeHighlighter.frame.contentWindow);
my.codeHighlighter.getValue = hook.getValue;
my.codeHighlighter.setValue = hook.setValue;
highlighterSetup(textarea);
} catch (e) {
setTimeout(waitForHighlighter, 250);
}
}
waitForHighlighter();
}
function modeSwitch () {
if(my.editor.mode === 'source') {
sourceViewOverride();
}
}
this.getSourceEditorTextarea = function () {
return document.getElementsByClassName('cke_source')[0];
};
this.setEditorValue = function (value) {
my.editor.setData(value);
modeSwitch();
};
this.codeHighlighter = {
'highlighter' : {},
'getValue' : function () {
throw new Error('implement this on codeHighlighter ' +
'instantiation');
},
'setValue' : function () {
throw new Error('implement this on codeHighlighter ' +
'instantiation');
}
};
my.editor = editor;
my.editor.on('mode', modeSwitch);
modeSwitch();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment