Hoping this is way easier than I'm making it - I'm a Java coder, some inner Javascript aspects are a tad unfamiliar to me.
Trying to embed the great CodeJar library inside a GWT panel. There's a pretty nice/simple example for CodeJar:
<script type="module">
import {CodeJar} from './codejar.js'
import {withLineNumbers} from './linenumbers.js';
const editor = document.querySelector('.editor')
const highlight = editor => {
// highlight.js does not trim old tags,
// let's do it by this hack.
editor.textContent = editor.textContent
hljs.highlightBlock(editor)
}
const jar = CodeJar(editor, withLineNumbers(highlight), {
indentOn: /[(\[{]$/
})
jar.updateCode(localStorage.getItem('code'))
jar.onUpdate(code => {
localStorage.setItem('code', code)
})
</script>
The module function itself looks like this:
export function CodeJar(editor, highlight, opt = {}) { ... }
'editor' is a Div reference, and 'highlight' is a callback library function for handling code highlighting.
What I'm battling with is the JsInterop markup and code to make Javascript modules work with GWT. The above has a few aspects which I'm battling with
To load the script and have it available for GWT consumption, you have (at least) 3 possibilities:
import
in a <script type=module>
, and then assign the CodeJar
function to a window
property to make it available globally (that could be another global object than window
actually)import()
from GWT, using JsInterop and possibly elemental2-promiseNext, you need to create JsInterop bindings so you can call it from GWT; something like that (assuming you made CodeJar available globally as window.CodeJar
, and using elemental2-dom for HTMLElement
, but com.google.gwt.dom.client.Element
would work just as well):
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "?")
interface CodeJar {
@JsMethod(namespace = JsPackage.GLOBAL, name = "CodeJar")
static native CodeJar newInstance(HTMLElement element, HighlightFn highlight);
@JsMethod(namespace = JsPackage.GLOBAL, name = "CodeJar")
static native CodeJar newInstance(HTMLElement element, HighlightFn highlight, Options opts);
void updateOptions(Options options);
void updateCode(String code);
void onUpdate(UpdateFn cb);
void destroy();
}
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
class Options {
public String tab;
public JsRegExp indentOn;
public boolean spellcheck;
public boolean addClosing;
}
@JsFunction
@FunctionalInterface
interface HighlightFn {
void highlight(HTMLElement e);
}
@JsFunction
@FunctionalInterface
interface UpdateFn {
void onUpdate(String code);
}
With the above code, you should be able to create an editor using something like:
CodeJar jar = CodeJar.newInstance(editor, MyHighlighter::highlight);
If you use a dynamic import()
, replace the static methods with instance ones in a @JsType
interface representing the module received from the promise.