Javascript GWT 中的模块函数与 JsInterop
Javascript module function in GWT with JsInterop
希望这比我做的更容易 - 我是一名 Java 编码员,一些内部 Java 脚本方面对我来说有点陌生。
尝试将出色的 CodeJar library 嵌入到 GWT 面板中。 CodeJar 有一个漂亮的 nice/simple 示例:
<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>
模块函数本身如下所示:
export function CodeJar(editor, highlight, opt = {}) { ... }
'editor'是一个Div引用,'highlight'是处理代码高亮的回调库函数。
我正在努力解决的问题是使 Javascript 模块与 GWT 一起工作的 JsInterop 标记和代码。上面有几个方面我正在努力解决
- 替换“导入”以便 GWT 可以使用 javascript 模块代码。显然我可以只在我的顶层导入 js index.html,但据我了解,JS 模块不会成为全局命名空间的一部分,它们只能从导入它们的 JS 模块中使用。在我的例子中,大概需要是 GWT 代码。
- 在 GWT 中重新编码上述内容时如何传递回调函数
- 如何获取自己的'jar'引用来做自己的文字set/get(代替使用本地存储)
要加载脚本并使其可供 GWT 使用,您有(至少)3 种可能性:
- 在
<script type=module>
中使用静态 import
,然后将 CodeJar
函数分配给 window
属性 以使其全局可用(即可能是另一个 global 对象而不是 window
实际上)
- 使用来自 GWT 的动态
import()
,使用 JsInterop 和可能的 elemental2-promise
- 使用 Rollup/Webpack/whatever 将 CodeJar 模块转换为 non-module 脚本,这样您就可以以不同的方式使用它
接下来,您需要创建 JsInterop 绑定,以便您可以从 GWT 调用它;类似的东西(假设你让 CodeJar 在全球可用 window.CodeJar
,并使用 elemental2-dom 作为 HTMLElement
,但 com.google.gwt.dom.client.Element
也可以工作):
@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);
}
使用上面的代码,您应该能够使用类似以下内容创建编辑器:
CodeJar jar = CodeJar.newInstance(editor, MyHighlighter::highlight);
如果您使用动态 import()
,请在表示从 promise 接收的模块的 @JsType
接口中用实例方法替换静态方法。
希望这比我做的更容易 - 我是一名 Java 编码员,一些内部 Java 脚本方面对我来说有点陌生。
尝试将出色的 CodeJar library 嵌入到 GWT 面板中。 CodeJar 有一个漂亮的 nice/simple 示例:
<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>
模块函数本身如下所示:
export function CodeJar(editor, highlight, opt = {}) { ... }
'editor'是一个Div引用,'highlight'是处理代码高亮的回调库函数。
我正在努力解决的问题是使 Javascript 模块与 GWT 一起工作的 JsInterop 标记和代码。上面有几个方面我正在努力解决
- 替换“导入”以便 GWT 可以使用 javascript 模块代码。显然我可以只在我的顶层导入 js index.html,但据我了解,JS 模块不会成为全局命名空间的一部分,它们只能从导入它们的 JS 模块中使用。在我的例子中,大概需要是 GWT 代码。
- 在 GWT 中重新编码上述内容时如何传递回调函数
- 如何获取自己的'jar'引用来做自己的文字set/get(代替使用本地存储)
要加载脚本并使其可供 GWT 使用,您有(至少)3 种可能性:
- 在
<script type=module>
中使用静态import
,然后将CodeJar
函数分配给window
属性 以使其全局可用(即可能是另一个 global 对象而不是window
实际上) - 使用来自 GWT 的动态
import()
,使用 JsInterop 和可能的 elemental2-promise - 使用 Rollup/Webpack/whatever 将 CodeJar 模块转换为 non-module 脚本,这样您就可以以不同的方式使用它
接下来,您需要创建 JsInterop 绑定,以便您可以从 GWT 调用它;类似的东西(假设你让 CodeJar 在全球可用 window.CodeJar
,并使用 elemental2-dom 作为 HTMLElement
,但 com.google.gwt.dom.client.Element
也可以工作):
@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);
}
使用上面的代码,您应该能够使用类似以下内容创建编辑器:
CodeJar jar = CodeJar.newInstance(editor, MyHighlighter::highlight);
如果您使用动态 import()
,请在表示从 promise 接收的模块的 @JsType
接口中用实例方法替换静态方法。