So I have a codemirror instance on the left of a document, and an iframe on the right. When the code is updated in the editor, it is written to the iframe.
During this rewrite, I add an index to each and every element that is created using jQuery's $.data function so that whenever the user hovers their mouse over the element it can be highlighted in the editor.
So far I have managed to pick out the required element's position in the editor in terms of where its generated <span class="cm-tag cm-bracket">
tag is and give it a class of cm-custom-highlight
.
My question is - is there any way to turn an instance of a source span tag into an actual selection within the editor?
Update: Answered my own question - see below! You can check out my resulting code here.
I answered my own question! How about that?
Turns out CodeMirror has a neat little list of nodes in its display
container. All I needed to do was loop through CodeMirror.display.renderedView[lineNumber].measure.map
and test each text node's parentNode
property to see if it was the same as the span
I had highlighted.
The map
array is structured like so:
[
0: 0
1: 1
2: text
3: 1
4: 5
...
]
Every text
node here refers to a piece of code in the editor and the numbers before and after refer to its character index, so it was pretty easy to find the index that I needed:
var span = $('span.cm-custom-highlight', CodeMirror.display.lineDiv),
lineNumber = span.closest('.CodeMirror-line').closest('div[style]').index(),
lineView = CodeMirror.display.renderedView[lineNumber].measure.map,
char = 0;
for(var i in lineView.measure.map)
{
if(!char &&
typeof lineView.measure.map[i] == 'object' &&
lineView.measure.map[i].parentNode && span[0] == lineView.measure.map[i].parentNode)
{
char = lineView.measure.map[i - 1];
}
}
Sure it's a little messy, but it gets the job done nicely.