Question

Can I apply a Code Mirror overlay outside the definition of a mode? The code below works but seems redundant and slow. I'm defining a mode for each editor/viewer on a page which could be zero to many. How can this be optimized?

Ideally, I would like to define the mode once and then apply the overlay as needed.

I have not been able to find an answer if I can. I want to define a mode (it highlights a search term (see this question)) and then I want to apply that mode to many editors/viewers on a page. Each editor/viewer has a different language and is set on the DOM element (e.g <pre class="sourcecode" language="javascript">code</pr>).

I think the solution would be something dealing with return CodeMirror.overlayMode(CodeMirror.getMode(config, mode),searchOverlay, true); but I've been unable to get it to work.

$('.sourcecode').each( function() {
        var value = $(this).text(),
            search = (typeof keyword === 'undefined') ? false : true,
            mode =  $(this).attr('language'),
            pre = $(this).get(0),
            line = ($(this).attr('firstLineNumber') == undefined) ? 1 : parseInt($(this).attr('firstLineNumber'), 10);

        // CodeMirror search highlighing

        // this seems redundent, slow, and messy
        if (search) {
            CodeMirror.defineMode("highlightSearch", function(config, parserConfig) {
              var searchOverlay = {
                token: function(stream, state) {
                    if (stream.match(keyword)) {
                        return "highlightSearch";
                    }

                    while (stream.next() != null && !stream.match(keyword, false)) {}
                    return null;
                }
              };
              return CodeMirror.overlayMode(CodeMirror.getMode(config, mode),searchOverlay, true);
            });
        }

        var viewer = CodeMirror(function(elt) {
            pre.parentNode.replaceChild(elt, pre);
        }, {
            value: value,
            lineNumbers: true,
            firstLineNumber: line,
            matchBrackets: true,
            lineWrapping: true,
            readOnly: true,
            mode: (search) ? 'highlightSearch' : mode,
        });
    });

Thank you for any help.

Était-ce utile?

La solution

This is unlikely to be very costly (unless you are creating hundreds of editors per second), but a more elegant solution would be to define your wrapping mode once, and read the inner mode (mode variable in your code) from its parserConfig object, say parserConfig.inner. You'd then simply pass {name: "highlightSearch", inner: mode} as your mode option.

Autres conseils

For completeness I defined the mode outside the .each. Within the mode definition I replaced

return CodeMirror.overlayMode(CodeMirror.getMode(config, mode),searchOverlay, true);

with

return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.inner),searchOverlay, true);

and replaced

mode: (search) ? 'highlightSearch' : mode,

with

mode: (search) ? {name: 'highlightSearch', inner: mode} : mode,
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top