Accesskeys for per-tiddler buttons?

7 views
Skip to first unread message

Derek Peschel

unread,
Oct 16, 2009, 2:50:59 PM10/16/09
to TiddlyWikiDev
I'm using Safari 3.2.3 on Mac OS X 10.5.7. Rather than moving the
mouse to one of the per-tiddler buttons ("close") it would be nice to
push a key. I propose "W" for close, "R" for close others, and "Y"
for close all. "E" for edit might be nice too.

Close-all is not currently a per-tiddler button. I'll get to that in
my next messge.

Adding accesskey: entries in the calls to merge(config.commands.blah)
doesn't work. With multiple tiddlers open, there's more than one
"close" button displayed, so presumably the merge approach _can't_
work. I guess accesskeys need to be set and unset as the current
focus changes. Am I on the right track?

Thanks,

-- Derek


FND

unread,
Oct 18, 2009, 12:20:17 PM10/18/09
to tiddly...@googlegroups.com
> I'm using Safari 3.2.3 on Mac OS X 10.5.7. Rather than moving the
> mouse to one of the per-tiddler buttons ("close") it would be nice to
> push a key.

While there's a ticket for this already*, it hasn't happened yet for a
variety of reasons - the obvious one being that nobody has submitted a
patch.
As you've pointed out, one problem is defining and determining what the
active tiddler is.

A while back I started on a TiddlyVi* plugin. However, that currently
only does primitive keyboard navigation (up/down through tiddlers in the
story), and I don't know when I'll get around to enhancing it (the idea
is to have Ex-like commands for triggering toolbar commands).

Any contributions in this area would be most welcome.


-- F.


[1] http://trac.tiddlywiki.org/ticket/452
[2]
http://svn.tiddlywiki.org/Trunk/contributors/FND/plugins/TiddlyViPlugin.js

Derek Peschel

unread,
Oct 19, 2009, 8:13:25 PM10/19/09
to TiddlyWikiDev, dpes...@eskimo.com
On Oct 18, 9:20 am, FND <F...@gmx.net> wrote:
> As you've pointed out, one problem is defining and determining what the
> active tiddler is.

Well, one solution is to set accessKey properties in a tiddler's
toolbar buttons when that tiddler gets the mouse focus, and unset them
when the tiddler loses the mouse focus. After enough digging I found
that the onTiddlerMouseOver and onTiddlerMouseOut functions are called
at the appropriate times and can be changed to call new code.

> Any contributions in this area would be most welcome.

A patch, using the solution I described, is copied below. I'm sure
some of these methods don't really belong to Story, and my
attributeNamed method may already exist in jQuery by another name.
Comments welcome.

--- Lingo.js.orig.20091019b 2009-10-19 16:16:04.000000000 -0700
+++ Lingo.js 2009-10-19 16:22:11.000000000 -0700
@@ -368,11 +368,13 @@

merge(config.commands.closeTiddler,{
text: "close",
- tooltip: "Close this tiddler"});
+ tooltip: "Close this tiddler"},
+ accessKey: "W");

merge(config.commands.closeOthers,{
text: "close others",
- tooltip: "Close all other tiddlers"});
+ tooltip: "Close all other tiddlers"},
+ accessKey: "R");

merge(config.commands.closeAll,{
text: "close all",
@@ -382,7 +384,8 @@
text: "edit",
tooltip: "Edit this tiddler",
readOnlyText: "view",
- readOnlyTooltip: "View the source of this tiddler"});
+ readOnlyTooltip: "View the source of this tiddler"},
+ accessKey: "E");

merge(config.commands.saveTiddler,{
text: "done",
--- Story.js.orig.20091019b 2009-10-18 14:37:46.000000000 -0700
+++ Story.js 2009-10-19 16:52:24.000000000 -0700
@@ -287,15 +287,72 @@
}
};

+//# In HTML terms, each tiddler has a child: <div class="toolbar">
+//# Return tiddler's first child "div" element with a class of
"toolbar"
+Story.prototype.findToolbar = function(e)
+{
+ var divs = e.getElementsByTagName("div");
+ for (var index = 0; index < divs.length; index++) {
+ var div = divs[index];
+ if (div.className == "toolbar") {
+ return div;
+ }
+ }
+ return null;
+}
+
+//# Unfortunately, instead of element.attribtes["href"] the DOM has
element.attributes[N].name=="commandname" and element.attributes
[N].value for some numerical N
+//# This makes the syntax a little more like element.attributes
["href"]
+Story.prototype.attributeNamed = function(e, name)
+{
+ var attribs = e.attributes;
+ for (var index = 0; index < attribs.length; index++) {
+ var attrib = attribs[index];
+ if (attrib.name == name) {
+ return attrib.value;
+ }
+ }
+ return null;
+}
+
+//Activate toolbar-button access keys when a tiddler gets mouse focus
+//# In HTML terms, each toolbar has a series of buttons: <a
href="javascript:;" title="Close this tiddler" class="button
command_closeTiddler" commandname="closeTiddler"
tiddler="GettingStarted">close</a>
+//# The buttons contain a commandname attribute, corresponding to a
member of config.commands
+//# Look up the accessKey field from that member, and copy it to the
buttons' accesskey property
+Story.prototype.addToolbarAccessKeys = function(e)
+{
+ var buttons = e.childNodes;
+ for (var index = 0; index < buttons.length; index++) {
+ var button = buttons[index];
+ var commandname = story.attributeNamed(button, "commandname");
+ button.accessKey = config.commands[commandname].accessKey;
+ }
+ }
+}
+
+// Deactivate toolbar-button access keys when a tiddler loses mouse
focus
+//# Easiest to remove all access keys
+Story.prototype.removeToolbarAccessKeys = function(e)
+{
+ var buttons = e.childNodes;
+ for (var index = 0; index < buttons.length; index++) {
+ var button = buttons[index];
+ button.accessKey = "";
+ }
+ }
+}
+
//# Default tiddler onmouseover/out event handlers
Story.prototype.onTiddlerMouseOver = function(e)
{
addClass(this, "selected");
+ story.addToolbarAccessKeys(story.findToolbar(this));
};

Story.prototype.onTiddlerMouseOut = function(e)
{
removeClass(this,"selected");
+ story.removeToolbarAccessKeys(story.findToolbar(this));
};

//# Default tiddler ondblclick event handler

Derek Peschel

unread,
Oct 20, 2009, 3:36:53 AM10/20/09
to TiddlyWikiDev
Aargh, again I was too cavalier in posting this patch. I'll be more
systematic in the future. I've fixed some major typos that prevented
the patch from working, and also followed the coding-style guidelines
this time around.

Index: Story.js
===================================================================
--- Story.js (revision 10958)
+++ Story.js (working copy)
@@ -287,15 +287,70 @@
}
};

+//# In HTML terms, each tiddler has a child: <div class="toolbar">
+//# Return tiddler's first child "div" element with a class of
"toolbar"
+Story.prototype.findToolbar = function(e)
+{
+ var divs = e.getElementsByTagName("div");
+ for(var index=0; index<divs.length; index++) {
+ var div = divs[index];
+ if(div.className == "toolbar") {
+ return div;
+ }
+ }
+ return null;
+};
+
+//# Unfortunately, instead of element.attribtes["href"] the DOM has
element.attributes[N].name=="commandname" and element.attributes
[N].value for some numerical N
+//# This makes the syntax a little more like element.attributes
["href"]
+Story.prototype.attributeNamed = function(e, name)
+{
+ var attribs = e.attributes;
+ for(var index=0; index<attribs.length; index++) {
+ var attrib = attribs[index];
+ if(attrib.name == name) {
+ return attrib.value;
+ }
+ }
+ return null;
+};
+
+//Activate toolbar-button access keys when a tiddler gets mouse focus
+//# In HTML terms, each toolbar has a series of buttons: <a
href="javascript:;" title="Close this tiddler" class="button
command_closeTiddler" commandname="closeTiddler"
tiddler="GettingStarted">close</a>
+//# The buttons contain a commandname attribute, corresponding to a
member of config.commands
+//# Look up the accessKey field from that member, and copy it to the
buttons' accesskey property
+Story.prototype.addToolbarAccessKeys = function(e)
+{
+ var buttons = e.childNodes;
+ for(var index=0; index<buttons.length; index++) {
+ var button = buttons[index];
+ var commandname = story.attributeNamed(button, "commandname");
+ button.accessKey = config.commands[commandname].accessKey;
+ }
+};
+
+// Deactivate toolbar-button access keys when a tiddler loses mouse
focus
+//# Easiest to remove all access keys
+Story.prototype.removeToolbarAccessKeys = function(e)
+{
+ var buttons = e.childNodes;
+ for(var index=0; index<buttons.length; index++) {
+ var button = buttons[index];
+ button.accessKey = "";
+ }
+};
+
//# Default tiddler onmouseover/out event handlers
Story.prototype.onTiddlerMouseOver = function(e)
{
addClass(this, "selected");
+ story.addToolbarAccessKeys(story.findToolbar(this));
};

Story.prototype.onTiddlerMouseOut = function(e)
{
removeClass(this,"selected");
+ story.removeToolbarAccessKeys(story.findToolbar(this));
};

//# Default tiddler ondblclick event handler
Index: Lingo.js
===================================================================
--- Lingo.js (revision 10978)
+++ Lingo.js (working copy)
@@ -367,17 +367,20 @@

merge(config.commands.closeTiddler,{
text: "close",
- tooltip: "Close this tiddler"});
+ tooltip: "Close this tiddler",
+ accessKey: "W"});

merge(config.commands.closeOthers,{
text: "close others",
- tooltip: "Close all other tiddlers"});
+ tooltip: "Close all other tiddlers",
+ accessKey: "R"});

merge(config.commands.editTiddler,{

Eric Shulman

unread,
Oct 20, 2009, 4:25:47 AM10/20/09
to TiddlyWikiDev
> +Story.prototype.findToolbar = function(e)

This function is assuming that there is only *one* toolbar DIV within
a tiddler. This is not always the case: some themes and plugins use
modified ViewTemplate/EditTemlate definitions, to add their own
additional toolbars.

> +Story.prototype.attributeNamed = function(e, name)

Rather than writing your own accessor function, why not just use the
native DOM function:
var val=e.getAttribute(name);

enjoy,
-e


Derek Peschel

unread,
Oct 20, 2009, 5:02:50 PM10/20/09
to TiddlyWikiDev, dpes...@eskimo.com
On Oct 20, 1:25 am, Eric Shulman <elsdes...@gmail.com> wrote:
> a tiddler.  This is not always the case: some themes and plugins use
> modified ViewTemplate/EditTemlate definitions, to add their own
> additional toolbars.

So it would be better to search all toolbars. How deeply do I need to
search?
(Can toolbars contain toolbars?) Do any plugins currently add
accessKeys
to toolbar buttons? That might make it dangerous for the core to
remove keys
that it didn't add. However, if the data (potential accessKey
assignments) is
kept separate from the code (assigning and deassigning accessKeys to
tool-
bar buttons) I think the idea could still work.

> Rather than writing your own accessor function, why not just use the
> native DOM function:
>    var val=e.getAttribute(name);

Thanks, I'll do that. I missed that function in the DOM tutorial page
I was using.

-- Derek

Reply all
Reply to author
Forward
0 new messages