I'm attempting to combine CodeMirror and At.js into a single "editor". I'm using At.js in a current version of the the editor to insert bits of HTML which represent certain aspects of a DSL.
So at.js basically handles the autocompletion part of the editor. This all works fine. However the editor needs some finetuning(linenumbers, better handling of input etc.).
CodeMirror provides this. However it does not play nicely with At.js. For some reason (which I can't find yet) At.js is not registering events or binding to the domElement I've bound CodeMirror to.
I've tried to manually make the CodeMirror events bubble up the DOM by catching the CM events and fixing the events and triggering those events on said domElement. No luck so far.
cm.on("keyup", function ( editor, e ) {
e = $.event.fix(e);
e.namespace = 'atwhoInner';
console.warn("cmUp", e);
$(self.domElement).trigger($.event.fix(e));
});
cm.on("keydown", function ( editor, e ) {
e = $.event.fix(e);
e.namespace = 'atwhoInner';
console.warn("cmDown", e);
$(self.domElement).trigger($.event.fix(e));
});
I can catch the event so I know it's working correctly.
I'll see if I can create a fiddle to mimic my situation exactly (which I will do after this). In the meanwhile it would be great if anyone can point me into a general direction.
My own guess is that CM prevents events from bubbling up or prevents At.js from attaching some HTML-elements it needs. Or that I need to bind A.js to a different element.
To give a quick overview of what I've got (not complete at all).
var domElement = $('#someid');
//Using domElement directly causes CodeMirror to flipout.
var cm = CodeMirror(domElement[0], {
mode: "htmlmixed",
extraKeys: { "Ctrl-Space": "autocomplete" },
value: ' <span></span>',
lineNumbers: true
});
cm.on("keyup", function ( editor, e ) {
e = $.event.fix(e);
e.namespace = 'atwhoInner';
console.warn("cmUp", e);
$(self.domElement).trigger($.event.fix(e));
});
cm.on("keydown", function ( editor, e ) {
e = $.event.fix(e);
e.namespace = 'atwhoInner';
console.warn("cmDown", e);
$(self.domElement).trigger($.event.fix(e));
});
domElement.atwho({
at: 'fancystuff.',
displayTpl: "${displayTpl}",
insertTpl: "${insertTpl}",
showTheAt: false,
limit: 100,
searchKey: "searchField",
suffix: "",
data: [{displayTpl:'some templating', insertTpl: 'some templating', searchField;'stuff to search'},
{displayTpl:'some templating', insertTpl: 'some templating', searchField;'stuff to search'}
]
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='someid' contenteditable='true'></div>
Turned out to be a silly problem. CodeMirror wraps itself around a <textarea>
and does nothing with the div it is actually placed in.
This bit of code solved my problem (kinda):
$('.CodeMirror',self.templateDomElement).find('textarea').atwho({stuff: "goeshere"});
I can get atWho to bind now, however it inserts the html as plaintext. Which is what you expect CodeMirror to do. However I need to insert actual HTML, not HTML as plain text. So I'll be looking into how to approach this.
Will get back to this question when I've solved it.
EDIT: Turns out it was nigh impossible to solve. At.js does some funky stuff with the dom to place a container with all the possible options. I ended up writing my own hinting function using default functionality from CodeMirror.