mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 16:56:36 -04:00
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:
commit
c5156a0f6b
4 changed files with 198 additions and 10 deletions
|
@ -5,6 +5,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import aqt
|
import aqt
|
||||||
|
@ -32,6 +33,22 @@ class DeckBrowserBottomBar:
|
||||||
self.deck_browser = deck_browser
|
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:
|
class DeckBrowser:
|
||||||
_dueTree: Any
|
_dueTree: Any
|
||||||
|
|
||||||
|
@ -112,10 +129,14 @@ class DeckBrowser:
|
||||||
gui_hooks.deck_browser_did_render(self)
|
gui_hooks.deck_browser_did_render(self)
|
||||||
|
|
||||||
def __renderPage(self, offset):
|
def __renderPage(self, offset):
|
||||||
tree = self._renderDeckTree(self._dueTree)
|
content = DeckBrowserContent(
|
||||||
stats = self._renderStats()
|
tree=self._renderDeckTree(self._dueTree),
|
||||||
|
stats=self._renderStats(),
|
||||||
|
countwarn=self._countWarn(),
|
||||||
|
)
|
||||||
|
gui_hooks.deck_browser_will_render_content(self, content)
|
||||||
self.web.stdHtml(
|
self.web.stdHtml(
|
||||||
self._body % dict(tree=tree, stats=stats, countwarn=self._countWarn()),
|
self._body % content.__dict__,
|
||||||
css=["deckbrowser.css"],
|
css=["deckbrowser.css"],
|
||||||
js=["jquery.js", "jquery-ui.js", "deckbrowser.js"],
|
js=["jquery.js", "jquery-ui.js", "deckbrowser.js"],
|
||||||
context=self,
|
context=self,
|
||||||
|
|
|
@ -435,6 +435,63 @@ class _DeckBrowserDidRenderHook:
|
||||||
deck_browser_did_render = _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:
|
class _DeckBrowserWillShowOptionsMenuHook:
|
||||||
_hooks: List[Callable[[QMenu, int], None]] = []
|
_hooks: List[Callable[[QMenu, int], None]] = []
|
||||||
|
|
||||||
|
@ -772,6 +829,55 @@ class _OverviewDidRefreshHook:
|
||||||
overview_did_refresh = _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:
|
class _ProfileDidOpenHook:
|
||||||
_hooks: List[Callable[[], None]] = []
|
_hooks: List[Callable[[], None]] = []
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
import aqt
|
import aqt
|
||||||
from anki.lang import _
|
from anki.lang import _
|
||||||
from aqt import gui_hooks
|
from aqt import gui_hooks
|
||||||
|
@ -17,6 +19,24 @@ class OverviewBottomBar:
|
||||||
self.overview = overview
|
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:
|
class Overview:
|
||||||
"Deck overview."
|
"Deck overview."
|
||||||
|
|
||||||
|
@ -141,14 +161,15 @@ class Overview:
|
||||||
shareLink = '<a class=smallLink href="review">Reviews and Updates</a>'
|
shareLink = '<a class=smallLink href="review">Reviews and Updates</a>'
|
||||||
else:
|
else:
|
||||||
shareLink = ""
|
shareLink = ""
|
||||||
|
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.web.stdHtml(
|
||||||
self._body
|
self._body % content.__dict__,
|
||||||
% dict(
|
|
||||||
deck=deck["name"],
|
|
||||||
shareLink=shareLink,
|
|
||||||
desc=self._desc(deck),
|
|
||||||
table=self._table(),
|
|
||||||
),
|
|
||||||
css=["overview.css"],
|
css=["overview.css"],
|
||||||
js=["jquery.js", "overview.js"],
|
js=["jquery.js", "overview.js"],
|
||||||
context=self,
|
context=self,
|
||||||
|
|
|
@ -25,11 +25,51 @@ hooks = [
|
||||||
doc="""Allow to update the overview window. E.g. add the deck name in the
|
doc="""Allow to update the overview window. E.g. add the deck name in the
|
||||||
title.""",
|
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(
|
Hook(
|
||||||
name="deck_browser_did_render",
|
name="deck_browser_did_render",
|
||||||
args=["deck_browser: aqt.deckbrowser.DeckBrowser"],
|
args=["deck_browser: aqt.deckbrowser.DeckBrowser"],
|
||||||
doc="""Allow to update the deck browser window. E.g. change its title.""",
|
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(
|
Hook(
|
||||||
name="reviewer_did_show_question",
|
name="reviewer_did_show_question",
|
||||||
args=["card: Card"],
|
args=["card: Card"],
|
||||||
|
|
Loading…
Reference in a new issue