Alrighty, after spending a few days fiddling with context menus (and definitely too much time playing around with CSS transition effects that were ultimately scrapped), I’m in a spot where I’m quite happy with how they turned out. After some refactoring there is not much code to it, and I even got submenus to work.
The $eventcatcher
and macro are pretty much as above.
The template for the popup also is not very complicated and mostly sets all the passed variables:
\whitespace trim
<$let stateTiddlerBase="$:/state/popup/contextmenu"
contextmenu={{{ [<stateTiddlerBase>addsuffix[/dom-data-contextmenu]get[text]else[Tiddler]] }}}
contextmenutiddler={{{ [<stateTiddlerBase>addsuffix[/dom-data-contextmenutiddler]get[text]] }}}
menuItemsTag={{{ [[$:/mwi/tags/ContextMenu]addsuffix<contextmenu>] }}}
auxData={{{ [<stateTiddlerBase>addsuffix[/dom-data-contextmenuaux]get[text]] }}}
parentTiddler={{{ [<stateTiddlerBase>addsuffix[/dom-data-contextmenuparent]get[text]] }}}
tv-config-toolbar-text="yes" >
<$reveal type="popup" state=<<stateTiddlerBase>> updatePopupPosition="yes">
<div class="tc-drop-down mwi-contextmenu">
<$tiddler tiddler=<<contextmenutiddler>> >
<$reveal tag="button" class="tc-btn-invisible mwi-contextmenu-heading" type="nomatch" text="TOCItem" default=<<contextmenu>> >
<span class="tc-btn-text">
<$text text=<<currentTiddler>> />
</span>
</$reveal>
<$list filter="[all[shadows+tiddlers]tag<menuItemsTag>!has[draft.of]]" variable="listItem">
<$transclude tiddler=<<listItem>>/>
</$list>
</$tiddler>
</div>
</$reveal>
</$let>
The identifier passed from the DOM attribute data-contextmenu via a state tiddler into the variable contextmenu
is used to build the tag name menuItemsTag which controls which buttons appear in the context menu for that identifier.
The buttons don’t have to be very complicated, e.g. an edit-button:
\define button-actions()
<!-- wenn Tiddler nur transcluded ist, muss er erst geöffnet werden -->
<$list filter="[<parentTiddler>!is[blank]]" variable="void">
<$list filter="[<tv-story-list>!contains<currentTiddler>]" variable="void">
<$action-listops $tiddler=<<tv-story-list>> $subfilter="+[insertbefore:parentTiddler<currentTiddler>move<currentTiddler>]"/>
</$list>
<$action-navigate />
</$list>
<$action-sendmessage $message="tm-edit-tiddler" />
\end
<$button class="tc-btn-invisible mwi-btn-meta-toolbar" actions=<<button-actions>> >
{{$:/core/images/edit-button}}
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text">
Tiddler bearbeiten
</span>
</$list>
</$button>
Most of the buttons do somewhat more complicated actions unique to this wiki. But, they were already implemented and their buttons were littered around the UI. All it took (mostly) was to assign them the respective tag(s).
If there are relevant tiddlers higher up in the hierarchy, a submenu for those is also shown, implemented as just another context menu button with the respective tag:
<!-- wenn es einen parentTiddler gibt, zeigen wir das Menü für den Haupt-Tiddler an (wenn wir nicht schon in einem Untermenüpunkt sind) -->
<$reveal type="nomatch" text="2" default=<<menuLevel>> tag="button" class="tc-btn-invisible">
<$tiddler tiddler={{$:/HistoryList!!current-tiddler}} >
<$let parentTiddler=""
contextmenu="Tiddler"
menuItemsTag={{{ [[$:/mwi/tags/ContextMenu]addsuffix<contextmenu>] }}}
menuLevel="2" >
{{$:/mwi/images/escalator-warning}}
<span class="tc-btn-text">
<$text text=<<currentTiddler>> />
</span>
<span class="mwi-hotkey">
{{$:/core/images/right-arrow}}
</span>
<div class="mwi-contextsubmenu">
<$list filter="[all[shadows+tiddlers]tag<menuItemsTag>!has[draft.of]]" variable="listItem">
<$transclude tiddler=<<listItem>>/>
</$list>
</div>
</$let>
</$tiddler>
</$reveal>
To complete the UI cleanup, I will consider if it makes sense to move the whole View Toolbar into the context menu (except for the Close button). Some of it is already there, and the rest is rarely used.
Maybe this will inspire someone to try their own hand at crafting a bespoke context menu (except maybe for @saqimtiaz who probably does stuff like this before breakfast).
Have a nice day
Yaisog
PS: Sorry for all the German text. I don’t have the time right now for a translation. Pretty much all of it should not be relevant to understand the principle of the thing.
PPS: The submenus maybe only make sense when considering the general tiddler structure in the wiki: A major topic can have a tabbed table of contents, and each of those TOC entries may have a list of journal tiddlers which are collected together in a nested tabbed TOC. So, a journal tiddler may have a parent that is a contents pane of a toc-tabbed, which again then has a parent tiddler that is the root tiddler of the zoomin view. Nothing for small screens, but very efficient for finding information quickly.