1

希望这比我做的要容易 - 我是一名 Java 编码员,一些内部 Javascript 方面对我来说有点陌生。

尝试将出色的CodeJar 库嵌入GWT 面板中。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>

模块函数本身如下所示:

export function CodeJar(editor, highlight, opt = {}) { ... }

'editor' 是一个 Div 引用,'highlight' 是一个用于处理代码高亮的回调库函数。

我正在与 JsInterop 标记和代码作斗争,以使 Javascript 模块与 GWT 一起工作。以上有一些我正在与之抗争的方面

  • 替换“导入”,以便 GWT 可以使用 javascript 模块代码。Obvioulsy 我可以在我的顶级 index.html 中导入 js,但据我了解,JS 模块不会成为全局命名空间的一部分,它们只能从导入它们的 JS 模块中使用。在我的情况下,大概需要是 GWT 代码。
  • 在 GWT 中重新编码上述内容时如何传递回调函数
  • 如何获取我自己的“jar”引用来设置/获取自己的文本(替换使用本地存储)
4

1 回答 1

3

要加载脚本并使其可供 GWT 使用,您(至少)有 3 种可能性:

  • import在 a 中使用 static <script type=module>,然后将该CodeJar函数分配给一个window属性以使其全局可用(这可能是另一个全局对象而不是window实际)
  • 使用import()GWT 的动态,使用 JsInterop 和可能的 elemental2-promise
  • 使用 Rollup/Webpack/whatever 将 CodeJar 模块转换为非模块脚本,以便您可以不同地使用它

接下来,您需要创建 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()方法,请将接口中的静态方法替换为实例方法,该@JsType接口表示从 Promise 接收到的模块。

于 2020-11-02T14:52:30.180 回答