add a hook to support extending external .html files

This commit is contained in:
Damien Elmes 2020-08-28 17:10:35 +10:00
parent b0a3861734
commit 67cb510c8e
3 changed files with 75 additions and 3 deletions

View File

@ -2844,6 +2844,54 @@ class _UndoStateDidChangeHook:
undo_state_did_change = _UndoStateDidChangeHook()
class _WebviewDidInjectStyleIntoPageHook:
'''Called after standard styling is injected into an external
html file, such as when loading the new graphs. You can use this hook to
mutate the DOM before the page is revealed.
For example:
def mytest(web: AnkiWebView):
page = os.path.basename(web.page().url().path())
if page != "graphs.html":
return
web.eval(
"""
div = document.createElement("div");
div.innerHTML = 'hello';
document.body.appendChild(div);
"""
)
gui_hooks.webview_did_inject_style_into_page.append(mytest)
'''
_hooks: List[Callable[[AnkiWebView], None]] = []
def append(self, cb: Callable[[AnkiWebView], None]) -> None:
"""(webview: AnkiWebView)"""
self._hooks.append(cb)
def remove(self, cb: Callable[[AnkiWebView], None]) -> None:
if cb in self._hooks:
self._hooks.remove(cb)
def count(self) -> int:
return len(self._hooks)
def __call__(self, webview: AnkiWebView) -> None:
for hook in self._hooks:
try:
hook(webview)
except:
# if the hook fails, remove it
self._hooks.remove(hook)
raise
webview_did_inject_style_into_page = _WebviewDidInjectStyleIntoPageHook()
class _WebviewDidReceiveJsMessageFilter:
"""Used to handle pycmd() messages sent from Javascript.

View File

@ -598,14 +598,15 @@ body {{ zoom: {zoom}; background: {background}; direction: {lang_dir}; {font} }}
def inject_dynamic_style_and_show(self):
"Add dynamic styling, and reveal."
css = self.standard_css()
def after_style(arg):
gui_hooks.webview_did_inject_style_into_page(self)
self.show()
self.evalWithCallback(
f"""
const style = document.createElement('style');
style.innerHTML = `{css}`;
document.head.appendChild(style);
""",
lambda arg: self.show(),
)
""", after_style)
def load_ts_page(self, name: str) -> None:
from aqt import mw

View File

@ -452,6 +452,29 @@ hooks = [
args=["webview: aqt.webview.AnkiWebView", "menu: QMenu"],
legacy_hook="AnkiWebView.contextMenuEvent",
),
Hook(
name="webview_did_inject_style_into_page",
args=["webview: AnkiWebView"],
doc='''Called after standard styling is injected into an external
html file, such as when loading the new graphs. You can use this hook to
mutate the DOM before the page is revealed.
For example:
def mytest(web: AnkiWebView):
page = os.path.basename(web.page().url().path())
if page != "graphs.html":
return
web.eval(
"""
div = document.createElement("div");
div.innerHTML = 'hello';
document.body.appendChild(div);
"""
)
gui_hooks.webview_did_inject_style_into_page.append(mytest)
'''),
# Main
###################
Hook(