http://www.perlmonks.org?node_id=700834


in reply to Re^3: Better keyboard-driven navigation, any? - yes...
in thread Better keyboard-driven navigation, any? - yes...

It seems like I have to explain a bit better how the navigation is implemented and why so...

As I wrote in the OP, links and inputs in a page are one long flat list which aren't necessary in the apparent visual order. The goal is to gather those links and get them into a logical order suitable for browsing with movement keys. For example, in 'Newest Nodes' each posting line contains a link to the post and to the home node of the author. Normal tab browsing those rows means advancing alternating between post and author: post, author, post, author, which isn't practical. So, the link list is divided into two, one list containing the posts, the other the authors. Those lists honour each other's index, so changing from author to post and back makes the cursor stay in the same line.

The list of post links in 'Newest Nodes' is pretty long, and while the movement keys support prefixing with a number to jump that much items, it seemed convenient to me to divide them into their respective monastic section as follows:

Links are organized into contexts - visual distinctive compartments, e.g. links in a post in a thread, with a single XPath expression (that might change if I find a way to merge multiple expressions in a maintainable way). Those compartments are accessible via keys (p for posts, n for nodelets etc), and they themselves are made into a list with it's own index. That's why the root post of a page is, while formally the same thing, different from posts in the reply section: they are visually different and it's components are selectable with different XPath expressions.

As said, each link collection of a visually distinct list of compartments is a different browsing context. Each context is accessible with a single key stroke, then browseable (right spelling?) with global movement keys. From that context sub-contexts can be accessed, and the parent context is accessible from within the sub-context with its access key. For convenience, selecting a context an subsequently pressing the same key advances the cursor in that context's list. There is only one 'up' key (to keep the list of keys short, but shift+key could be implemented as 'up'; comments?).

The access keys for each context are organized on the code level into a nested hash; their evaluated properties are:

desc - description of the key's context xpath - a function returning the XPath expression to retrieve this context's collection func - function bound to the key value - just a value that key returns (currently only used for up|down) coll - list of items to navigate (refreshed on context change) index - cursor (index into coll) focus - set focus on the element found by evaluating 'xpath' <c> - sub-hash (subcontext) entry (<c> is a single char)

In the keypress function, the 'func' key is checked first. Its existence in a hash clouds 'xpath'. Global keys (that in the root context) should be checked for after looking into the current context, but I'm afraid as for yet it is the other way round.

There are some keys which get added to the context root depending on the node_id of the page. These keys are global (available from any context) whether that makes sense or not. That keys have either a 'func' or 'focus' entry. Expanding they key-driven navigation consists in setting up a hash entry in the root context keyed with the <body> tag id value, and adding a test for... (now that I think about it, there could be a 'nodes' entry on each key having an array of body-id values of nodes for which this key is suitable, or a test function. Next release ;-)

Now to your post - thanks for the feedback! In what follows I'll address some or most of the issues you raised.

p - go to posts / replies section: ... if possible j should bring to the first reply as well, and k on the first reply should be an alias with m. If possible!

Hm well - 'm' is just a shortcut to invoke window.scroll(0,0) from any context without loosing the actual context and index. There's currently no key for 'go to root context and clear navigation info'. 'k' on the first item could be made into 'go to current parent context item', but 'j'... well, it seems that hashes in JavaScript don't lose order of definition, for empty collections that could be made into 'invoke first subkey'. I'll look into that.

update3: fixed. 'j' and 'k' now advance collections. Try on e.g. 'Newest Nodes'.

- - set -- vote for current post: here, I'm afraid I must tell you of the first actual bug

Check your version - that should work in $current (at least, "works for me"[tm] ;-) Also '+' and '0'. Update: acknowledged, once you are in the 'p' context you can't vote on the OP any more... update2: fixed. 'R' takes to root context, 'P' to parent/root node of current node. There's been a workaround -just go from posts context to nodelet, and voting works on the op again ;-)

j - down one post/nodelet: ... and k ended up not moving between posts but between links within a post, and no way to "escape."

See 'p' - 'j' could default on end of collection 'go to next collection in parent context'. As with "no way to escape" - hitting the access key for the parent context brings back to that. If it doesn't it's a bug ;)

From there, access links with the <Tab> key:
Currently all lists accessible with 'l' are a context which you can navigate with the up/down key, i.e. tab browsing is only necessary where the 'l' key doesn't respond.
t - jump to note composition text area: to be fair, I'm not sure what this is for.

That's for textareas where you enter text composing a node. If you leave the text area with 'tab', get up with 'm' or scroll about with page-up/page-down, hitting 't' returns to the text area where the cursor was left (initially it's at the bottom, after the signature). After leaving the textarea with <Tab> the focus sits on the 'Preview' button, so don't navigate with the space bar, since that invokes the button.

r - set focus on reply link: I must say that while for v it is very sensible to only set focus on the vote button, because one may change his mind, I would consider a very good idea to have this key actually open the reply link in a new window/tab and switch to it. If one changes her mind, then she can always close it.

That would go against all other link navigation, where a link is only focussed. I think that hitting return (or Ctrl-Return) on a link is far better than opening a window per default, only to have to close it afterwards.

Again, thanks for your feedback, it actually helped me to improve some things and made my hack clearer to myself by composing an answer :-)

--shmem

_($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                              /\_¯/(q    /
----------------------------  \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}