I made a proof-of-concept for a flexible context menu that uses the $eventcatcher
.
It’s probably not (easily) doable as a plug-in as it touches a few templates. But not everything must be a plug-in and the templates that were changed are all custom in my wikis anyway. So, take it or leave it, but it can be done (and I will definitely use it to clean up all the buttons that litter my wikis).
First, place the $eventcatcher
. I tried to put it in the ViewTemplate, but there it was difficult to make the popup appear at the clicked spot. So it went into the PageTemplate (which is already customized with a $messagecatcher
to trigger additional actions on navigation messages):
<$eventcatcher $contextmenu={{{ [{$:/mwi/config/ContextMenuEnable}match[yes]then<contextmenu>else[]] }}} selector=".tc-tiddler-frame, [contextmenu], a">
I put it inside the $dropzone
. Since with this approach I cannot use Ctrl
to alternatively show the browser context menu, I’ll put a toggle somewhere in the UI to switch between wiki and browser popup, controlled by the config setting $:/mwi/config/ContextMenuEnable
. The selector attribute is set to allow for context menus on a tiddler itself, any link and any DOM element with a contextmenu attribute (I’ll show below what that is useful for).
The macro contextmenu
that called from the $eventcatcher
is defined as
\define contextmenu()
<$action-log />
<$action-popup $state="$:/state/popup/contextmenu" $coords={{{ [[(]] [<event-fromcatcher-posx>] [[,]] [<event-fromcatcher-posy>] [[,0,0)]] +[join[]] }}} />
<$action-setfield $tiddler="$:/state/popup/contextmenu/dom-class" $value={{{ [<dom-class>!is[blank]else[]] }}} />
<$action-setfield $tiddler="$:/state/popup/contextmenu/dom-href" $value={{{ [<dom-href>!is[blank]else[]] }}} />
<$action-setfield $tiddler="$:/state/popup/contextmenu/dom-contextmenu" $value={{{ [<dom-contextmenu>!is[blank]else[]] }}} />
<$action-setfield $tiddler="$:/state/popup/contextmenu/dom-contextmenutiddler" $value={{{ [<dom-contextmenutiddler>!is[blank]else<dom-data-tiddler-title>!is[blank]else{$:/HistoryList!!current-tiddler}] }}} />
<$action-setfield $tiddler="$:/state/popup/contextmenu/dom-contextmenuparent" $value={{{ [<dom-contextmenuparent>!is[blank]else[]] }}} />
\end
The only way I found to pass information about the DOM element that the context menu was called upon is by putting into into HTML attributes. class and href are set automatically, contextmenu, contextmenutiddler and contextparent are set in the various templates where I need it. By putting it into e.g. the tc-tabbed-table-of-contents-content
element, I can call a different context menu for the contents pane of a tabbed-toc which knows about the tiddler shown in the contents pane as well as the tiddler containing the tabbed-toc if needed. The contextmenu attribute can be used to differentiate between the popup types, to make processing easier.
Since the only way to pass information from this page-level macro to the context menu popup is by storing that information in the wiki, a couple of $action-setfield
s are called.
The popup template looks like this:
<$reveal type="popup" state="$:/state/popup/contextmenu">
<div class="tc-drop-down mwi-contextmenu">
Clicked item dom-classes:<br>
<$list filter="[enlist{$:/state/popup/contextmenu/dom-class}decodeuricomponent[]]" >
<$text text=<<currentTiddler>>/><br>
</$list>
href is //<$text text={{{ [{$:/state/popup/contextmenu/dom-href}decodeuricomponent[]] }}}/>//<br>
contextmenu(type) is //<$text text={{$:/state/popup/contextmenu/dom-contextmenu}}/>//<br>
contextmenutiddler is //<$text text={{$:/state/popup/contextmenu/dom-contextmenutiddler}}/>//<br>
contextmenuparent is //<$text text={{$:/state/popup/contextmenu/dom-contextmenuparent}}/>//
</div>
</$reveal>
It’s tagged with $:/tags/PageTemplate
and at the moment only shows debugging information. This will be extended along the lines of @saqimtiaz’ tag-based and thus easily configurable collection of items.
Next up I need to move all my buttons into the context menus, to clean up the UI.
Have fun with it
Yaisog
PS: The ability for unique context menus for parts of tiddlers could also come in handy in conjunction with section editors and such.