问题
I want to be able to highlight (i.e. wrap in a span with a color, or some other way) all text that matches a regex in CKEditor. I'd probably add a button to do this, and a button to remove highlighting. My specific use case is to highlight all mustache variables in my HTML templates (make it really easy to see where there are mustache variables).
I've implemented a version where I replace a regex matching mustaches with a span and then the capture group. This appears to break on some templates when I test.
To remove the highlighting, I use editor.removeStyle, which doesn't seem to work in all cases.
Here is an example of what I've implemented:
editor.addCommand( 'highlightMustache', {
exec: function( editor ) {
editor.focus();
editor.document.$.execCommand( 'SelectAll', false, null );
var mustacheRegex = /{{\s?([^}]*)\s?}}/g;
var data = editor.getData().replace(mustacheRegex, '<span style="background-color: #FFFF00">{{ $1 }}</span>');
editor.setData( data );
}
});
// command to unhighlight mustache parameters
editor.addCommand( 'unhighlightMustache', {
exec: function( editor ) {
editor.focus();
editor.document.$.execCommand( 'SelectAll', false, null );
var style = new CKEDITOR.style( { element:'span', styles: { 'background-color': '#FFFF00' },type:CKEDITOR.STYLE_INLINE,alwaysRemoveElement:1 } );
editor.removeStyle( style );
editor.getSelection().removeAllRanges();
}
});
Thanks!
回答1:
The following approach worked for me in the past for a similar task:
Walk the DOM tree of the CKEditor document and combine all text nodes into a single string (let's call it
S
). Use CKEDITOR.dom.walker for that, this answer should help here. While walking the tree, build a collection of data structures (let's call itC
) to store each text node object and the position of where its text starts withinS
.Run your regex against
S
.If the match is not found, stop.
Otherwise, using
C
collection, locate the start text node (let's call itSN
), and offset within it, corresponding to the start character position of the match string insideS
.Using
C
collection, locate the end text node (let's call itEN
), and offset within it, corresponding to the end character position of the match string insideS
.Create a CKEDITOR.dom.range object and position it using
SN
as the start andEN
as the end (startContainer
/startOffset
/endContainer
/endOffset
).Use CKEDITOR.dom.selection.selectRanges() to select the range from the previous step.
回答2:
I wonder why don't you use a "reverse" Regex ofr the unhighlight command?
editor.addCommand( 'highlightMustache', {
exec: function( editor ) {
editor.focus();
editor.document.$.execCommand( 'SelectAll', false, null );
var mustacheRegex = /{{\s?([^}]*)\s?}}/g;
var data = editor.getData().replace(mustacheRegex, '<span style="background-color: #FFFF00">{{ $1 }}</span>');
editor.setData( data );
}
});
// command to unhighlight mustache parameters
editor.addCommand( 'unhighlightMustache', {
exec: function( editor ) {
editor.focus();
editor.document.$.execCommand( 'SelectAll', false, null );
var mustacheRegex = /<span style="background-color: #FFFF00">{{\s?([^}]*)\s?}}<\/span>/g;
var data = editor.getData().replace(mustacheRegex, '{{ $1 }}');
editor.setData( data );
}
});
It should work fine!
来源:https://stackoverflow.com/questions/18728103/how-can-i-highlight-elements-that-match-a-regex-in-ckeditor