I use react-ace
to create a CSS text editor in my React app.
That looks something like...
import Ace from 'react-ace'
...
<Ace
mode="css"
value={value}
onChange={onValueChange}
onValidate={onValidate}
...
/>
...
This works fine and dandy—highlighting CSS syntax errors and warnings. Also, the onValidate
returns the error/warning "annotations" data structure.
However there is a need, elsewhere in the application, to run the same validator used in this React Ace component, but outside of the context of this Component. Essentially I need to pass the content in value
through the error/warning annotation system, but can't instantiate this react element.
I've tried the following:
import { EditSession } from 'brace'; # "brace" is the "module" compatible version of the ace editor that our "react-ace" uses
import 'brace/mode/css';
export const getCssAnnotations = (value)=> {
const editSession = new EditSession(value);
editSession.setMode('ace/mode/css');
const annotations = editSession.getAnnotations();
return annotations;
};
However, the annotations returned by this function are always []
! I assume this is because I'm just accessing the annotation setter/getter interface, and not actually running the annotations creator. But I can't figure out what actually does the annotations work normally.
I've looked at docs on Creating a Syntax Highlighter for Ace, but don't understand if/why a web worker would need to be involved here.
Thanks!
This doesn't work, because editSession uses web worker to generate annotations which is async:
editSession.on('changeAnnotation', () => {
let annotations = editSession.getAnnotations();
callback(null, annotations)
});
Note that currently each editSession creates a new worker, so it is better to use setValue on an existing instance of editSession, or call editSession.destroy() before calling the callback
So a full solution might look like:
const getAnnotationsPromise = (value, mode)=> {
const editSession = new EditSession(value);
editSession.setMode(`ace/mode/${mode}`);
return new Promise((resolve)=> {
editSession.on('changeAnnotation', () => {
const annotations = editSession.getAnnotations();
editSession.removeAllListeners('changeAnnotation');
editSession.destroy();
resolve(annotations);
});
});
};