Reputation: 6652
I want to add a custom entry to the context menu in a Vexi application.
I tried adding a contextActions
function but it throws an error:
<textarea>
thisbox.contextmenu.contextActions = function() {
return [{
text: "Foo",
action: function(v) { cascade = v; vexi.log.info("foo"); },
enabled: enabled
}]);
}
</textarea>
How do I do this?
Upvotes: 4
Views: 375
Reputation: 6652
To extend the existing textarea context menu implementation in a re-usable way, create a template that preapplies vexi.widget.textarea
and put a read trap on the contextActions
property. We can use cascade
to invoke a read from that property - i.e. call the existing implementation - which returns an array. We simply add to that array:
<vexi xmlns="vexi.widget">
<textarea>
// overlays the trap specified in the inherited
// org.vexi.lib.text.contextmenu by textarea
thisbox.contextActions ++= function() {
var actions = cascade;
actions.push(
new .menuitem({
text: "Foo",
action: function(v) { cascade = v; vexi.log.info("foo"); },
enabled: enabled
}));
return actions;
}
</textarea>
</vexi>
Background
The key to extending an existing textarea is understanding both Traps and how the <textarea>
widget inherits via preapplied templates (and the templates they preapply, etc). You can go through the widget hierarchy, starting at src/vexi/widget/textarea.t
then looking up the relevant preapplies. You will eventually see that org.vexi.lib.widget.textarea
preapplies org.vexi.lib.text.contextmenu
and there we can see the default context menu implementation with copy/cut/paste etc.
Upvotes: 3