Anki Forums

How to add javascript .js file in Note Editor window?

I am creating an addon which uses .js file. I have tried following but didn’t work any.

  1. web.stdHtml (viewed in editor.py)
folder = os.path.dirname(__file__)
def addCustomJS(buttons, editor):
    editor.web.stdHtml(
        "",
        css=[],
        js=[folder + "/index.js"],
        context=editor,
    )
  1. Reading content of file and calling function
from .code import js_code
def addCustomJS(buttons, editor):
    editor.web.evalWithCallback(js_code % text, cb)
  1. Adding content
from .code import js_code
js_code = "<script>" + js_code + "</script>"
gui_hooks.webview_will_set_content(js_code, aqt.editor.Editor)

There is a function in index.js. It will added to note editor. When I call the function it will return the result. First one didn’t work. But for second one there is % symbol in index.js which give error in python showing less arguments passed. It is working for file not containing %.
So, is there way to add index.js file to note editor?
Thanks

Error for second one:
1

1 Like

I managed to make it works.

  1. Create .py file add codes to file
js_code = """
console.log("JS Code added.");
"""
  1. Add this to _init _.py
def js_content_hook(js_content, context):
    from .asciimath import js_code
    js_code = "<script>" + f"{js_code}" + "</script>"
    js_content.head += js_code
gui_hooks.webview_will_set_content.append(js_content_hook)

For % using %% will escape the strings.

If your script file path is /web/script.js, below is the recommended way to insert your js script

def url_from_fname(file_name: str) -> str:
    addon_package = mw.addonManager.addonFromModule(__name__)
    return f"/_addons/{addon_package}/web/{file_name}"

def on_webview(web_content: aqt.webview.WebContent, context: Optional[Any]) -> None:
    if isinstance(context, Editor):
        web_content.js.append(url_from_fname("script.js"))

mw.addonManager.setWebExports(__name__, r"web/.*")
gui_hooks.webview_will_set_content.append(on_webview)

It’s essentially the same as your solution, but the benefit is that you can use syntax highlighting and linter for the js code. But it’s a bit more cumbersome if your js code need to know the value of some python variable, as you can’t just use string formatting.

Also, just a minor nitpick but using f"<script>{js_code}</script>" or "<script>" + js_code + "</script>" instead of "<script>" + f"{js_code}" + "</script>" saves you some typing :slight_smile:

5 Likes

Thanks