Merge pull request #449 from glutanimate/html-content-section-hooks

Add hooks for modifying HTML body sections in the deck browser and overview screens
This commit is contained in:
Damien Elmes 2020-02-18 08:20:01 +10:00 committed by GitHub
commit c5156a0f6b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 198 additions and 10 deletions

View file

@ -5,6 +5,7 @@
from __future__ import annotations
from copy import deepcopy
from dataclasses import dataclass
from typing import Any
import aqt
@ -32,6 +33,22 @@ class DeckBrowserBottomBar:
self.deck_browser = deck_browser
@dataclass
class DeckBrowserContent:
"""Stores sections of HTML content that the deck browser will be
populated with.
Attributes:
tree {str} -- HTML of the deck tree section
stats {str} -- HTML of the stats section
countwarn {str} -- HTML of the deck count warning section
"""
tree: str
stats: str
countwarn: str
class DeckBrowser:
_dueTree: Any
@ -112,10 +129,14 @@ class DeckBrowser:
gui_hooks.deck_browser_did_render(self)
def __renderPage(self, offset):
tree = self._renderDeckTree(self._dueTree)
stats = self._renderStats()
content = DeckBrowserContent(
tree=self._renderDeckTree(self._dueTree),
stats=self._renderStats(),
countwarn=self._countWarn(),
)
gui_hooks.deck_browser_will_render_content(self, content)
self.web.stdHtml(
self._body % dict(tree=tree, stats=stats, countwarn=self._countWarn()),
self._body % content.__dict__,
css=["deckbrowser.css"],
js=["jquery.js", "jquery-ui.js", "deckbrowser.js"],
context=self,

View file

@ -435,6 +435,63 @@ class _DeckBrowserDidRenderHook:
deck_browser_did_render = _DeckBrowserDidRenderHook()
class _DeckBrowserWillRenderContentHook:
"""Used to modify HTML content sections in the deck browser body
'content' contains the sections of HTML content the deck browser body
will be updated with.
When modifying the content of a particular section, please make sure your
changes only perform the minimum required edits to make your add-on work.
You should avoid overwriting or interfering with existing data as much
as possible, instead opting to append your own changes, e.g.:
def on_deck_browser_will_render_content(deck_browser, content):
content.stats += "
<div>my html</div>"
"""
_hooks: List[
Callable[
["aqt.deckbrowser.DeckBrowser", "aqt.deckbrowser.DeckBrowserContent"], None
]
] = []
def append(
self,
cb: Callable[
["aqt.deckbrowser.DeckBrowser", "aqt.deckbrowser.DeckBrowserContent"], None
],
) -> None:
"""(deck_browser: aqt.deckbrowser.DeckBrowser, content: aqt.deckbrowser.DeckBrowserContent)"""
self._hooks.append(cb)
def remove(
self,
cb: Callable[
["aqt.deckbrowser.DeckBrowser", "aqt.deckbrowser.DeckBrowserContent"], None
],
) -> None:
if cb in self._hooks:
self._hooks.remove(cb)
def __call__(
self,
deck_browser: aqt.deckbrowser.DeckBrowser,
content: aqt.deckbrowser.DeckBrowserContent,
) -> None:
for hook in self._hooks:
try:
hook(deck_browser, content)
except:
# if the hook fails, remove it
self._hooks.remove(hook)
raise
deck_browser_will_render_content = _DeckBrowserWillRenderContentHook()
class _DeckBrowserWillShowOptionsMenuHook:
_hooks: List[Callable[[QMenu, int], None]] = []
@ -772,6 +829,55 @@ class _OverviewDidRefreshHook:
overview_did_refresh = _OverviewDidRefreshHook()
class _OverviewWillRenderContentHook:
"""Used to modify HTML content sections in the overview body
'content' contains the sections of HTML content the overview body
will be updated with.
When modifying the content of a particular section, please make sure your
changes only perform the minimum required edits to make your add-on work.
You should avoid overwriting or interfering with existing data as much
as possible, instead opting to append your own changes, e.g.:
def on_overview_will_render_content(overview, content):
content.table += "
<div>my html</div>"
"""
_hooks: List[
Callable[["aqt.overview.Overview", "aqt.overview.OverviewContent"], None]
] = []
def append(
self,
cb: Callable[["aqt.overview.Overview", "aqt.overview.OverviewContent"], None],
) -> None:
"""(overview: aqt.overview.Overview, content: aqt.overview.OverviewContent)"""
self._hooks.append(cb)
def remove(
self,
cb: Callable[["aqt.overview.Overview", "aqt.overview.OverviewContent"], None],
) -> None:
if cb in self._hooks:
self._hooks.remove(cb)
def __call__(
self, overview: aqt.overview.Overview, content: aqt.overview.OverviewContent
) -> None:
for hook in self._hooks:
try:
hook(overview, content)
except:
# if the hook fails, remove it
self._hooks.remove(hook)
raise
overview_will_render_content = _OverviewWillRenderContentHook()
class _ProfileDidOpenHook:
_hooks: List[Callable[[], None]] = []

View file

@ -4,6 +4,8 @@
from __future__ import annotations
from dataclasses import dataclass
import aqt
from anki.lang import _
from aqt import gui_hooks
@ -17,6 +19,24 @@ class OverviewBottomBar:
self.overview = overview
@dataclass
class OverviewContent:
"""Stores sections of HTML content that the overview will be
populated with.
Attributes:
deck {str} -- Plain text deck name
shareLink {str} -- HTML of the share link section
desc {str} -- HTML of the deck description section
table {str} -- HTML of the deck stats table section
"""
deck: str
shareLink: str
desc: str
table: str
class Overview:
"Deck overview."
@ -141,14 +161,15 @@ class Overview:
shareLink = '<a class=smallLink href="review">Reviews and Updates</a>'
else:
shareLink = ""
self.web.stdHtml(
self._body
% dict(
content = OverviewContent(
deck=deck["name"],
shareLink=shareLink,
desc=self._desc(deck),
table=self._table(),
),
)
gui_hooks.overview_will_render_content(self, content)
self.web.stdHtml(
self._body % content.__dict__,
css=["overview.css"],
js=["jquery.js", "overview.js"],
context=self,

View file

@ -25,11 +25,51 @@ hooks = [
doc="""Allow to update the overview window. E.g. add the deck name in the
title.""",
),
Hook(
name="overview_will_render_content",
args=[
"overview: aqt.overview.Overview",
"content: aqt.overview.OverviewContent",
],
doc="""Used to modify HTML content sections in the overview body
'content' contains the sections of HTML content the overview body
will be updated with.
When modifying the content of a particular section, please make sure your
changes only perform the minimum required edits to make your add-on work.
You should avoid overwriting or interfering with existing data as much
as possible, instead opting to append your own changes, e.g.:
def on_overview_will_render_content(overview, content):
content.table += "\n<div>my html</div>"
""",
),
Hook(
name="deck_browser_did_render",
args=["deck_browser: aqt.deckbrowser.DeckBrowser"],
doc="""Allow to update the deck browser window. E.g. change its title.""",
),
Hook(
name="deck_browser_will_render_content",
args=[
"deck_browser: aqt.deckbrowser.DeckBrowser",
"content: aqt.deckbrowser.DeckBrowserContent",
],
doc="""Used to modify HTML content sections in the deck browser body
'content' contains the sections of HTML content the deck browser body
will be updated with.
When modifying the content of a particular section, please make sure your
changes only perform the minimum required edits to make your add-on work.
You should avoid overwriting or interfering with existing data as much
as possible, instead opting to append your own changes, e.g.:
def on_deck_browser_will_render_content(deck_browser, content):
content.stats += "\n<div>my html</div>"
""",
),
Hook(
name="reviewer_did_show_question",
args=["card: Card"],