Access keys

From Bjoern Hassler

Jump to: navigation, search


Contents

[edit] 1 Access modifier key vs. emacs/unix style key-bindings

This is probably only relevant to you if you use emacs/unix style key-bindings, and would like to have these in text input boxes.

However, there has been discussion both on the mediawiki mailing list, as well as on browser-related lists.

Being able to modify the access keys is really an accessibility feature as well! (This point is also made here: [1], [2] ).

My angle on this is that I am very used to using ctrl-a/e/d to edit, and if the browser does something else with these, it trips me up frequently. Also, I tend to swap ctrl and caps lock, which makes ctrl-a/e/d really very available, and, at least for me, prefereable to using anything else. Access-principles would have it that I should be able to have it my way - so let's see.

[edit] 1.1 The top two solutions

To save you reading the whole page, the top two solutions are:

  • If you are going to modify your mediawiki, to disable access keys on edit pages (bar submit) for all users/browsers on your wiki, then see Access keys#Solution_3.
  • If you want to do something client side, to disable access keys on all mediawikis that you work with (using Safari or Firefox), then see Access keys#Hacking_the_code:_Client_side.

[edit] 1.2 Wiki editing with firefox

If you are used to using unix ctrl-a and ctrl-e to go to start and end of lines, as well as ctrl-d for forward delete (and other unix-style key bindings), and you are using firefox, you may find it useful to set the access modifier key from ctrl to something else, e.g. to ctrl shift (or similar).

In Firefox, that's easily done: Type "about:config" into the address bar. Filter for ui.key.contentAccess, and set the value to 3 (for ctrl+shit). For details, see http://kb.mozillazine.org/Ui.key.contentAccess (Details of values).

Problem solved for Firefox, so Firefox users can stop reading. Except that you might not want to reassign your access modifier key (ctrl key) to something else just to avoid this issue. (Because you might be used to using a particular access modifier key already, and having to change that habit is also tricky.) If that's the case, read on.

[edit] 1.3 Wiki editing with Safari

Unfortunately, short of recompiling Safari it doesn't seem to be possible to change the access modififer key from ctrl (or ctrl-alt) to something else.

So Safari users are worse-off than Firefox users in this respect. However, we'll find a better solution for both Safari and Firefox below.

Update: Safari 4 now changed the modifier key to ctrl-alt, again apparently without a way to change this. Access keys are all about accessibility, aren't they? And shouldn't one be able to change the modifier key to whatever suits a particular user? Ho hum.

[edit] 2 Modify mediawiki

An alternative to modifying browser settings would be to modify mediawiki to disable certain access keys for edit pages. That's nice, because would then work for all browsers. On the downside, the change to mediawiki would have to propagate into a new version of mediawiki, so if you don't control the wiki concerned, it's a longer term solution.

[edit] 3 Modifying mediawiki: Changing access keys through Common.js

First approach would be to change the access keys through modifying the mediawiki javascript.

[edit] 3.1 List of access keys

list of access keys from http://www.mediawiki.org/wiki/Manual:Interface/Access_keys

[edit] 3.2 js

We'd want to disable access keys at least for "aedkyw".

These pages give some tips:

On the ICT4E wiki I couldn't get this to work.

[edit] 3.3 Changing and disabling access keys

Quote from http://en.wikipedia.org/wiki/Wikipedia:Keyboard_shortcuts:

Most of the access keys and tooltips are now defined in Mediawiki software, some are added by JavaScript in MediaWiki:Common.js. You can easily customize them by adding some code to your monobook.js file.

For example, this will change accesskey to '0':

ta['ca-nstab-main'] = new Array('0','View the content page');

To disable certain access keys can use the example above but specify some other access key (see this example)

Also you can use removeAccessKeys script.

Again, on the ICT4E wiki I couldn't get this to work.

[edit] 4 Hacking the code

The 'js' solution didn't work for me on v1.13. Also it might not be able to do this selectively just for edit key. So, we hack the mediawiki code.

[edit] 4.1 Solution 1: Globally changing the access key

One way to permanently change or remove access keys is through the appropriate language file: e.g.

languages/messages/MessagesEn.php

which contains

'accesskey-ca-delete'               => 'd', # do not translate or duplicate this message to other languages
'accesskey-ca-undelete'             => 'd', # do not translate or duplicate this message to other languages

and so the access key 'd' can be disabled globally.

This works, and just affects the language settings, so not too bad. But it's global, i.e. you loose that particular access key on all pages.

[edit] 4.2 Solution 2: Change access keys only when editing

[edit] 4.2.1 Solution 2, version 1

In Linker.php, near tooltipAndAccesskey, and tooltip, we add

       public function theAccesskey( $name ) {
               wfProfileIn( __METHOD__ );
               $accesskey = wfMsg( "accesskey-$name" );
               wfProfileOut( __METHOD__ );
               return $accesskey;
       }

And then in your skin (MonoBook.php) you make this change:

< 				 	&& in_array( $key, array( 'edit', 'watch', 'unwatch' ))) {
---
> 				 	&& (
> in_array( $key, array( 'edit', 'watch', 'unwatch' ))
> ||
> in_array($skin->theAccesskey( "ca-$key" ), array('d','y','a','e','k'))) ) {

[edit] 4.2.2 Solution 2, version 2

Another way, only modifying the skin, would have been to do a preg_match on tooltipAndAccesskey for /accesskey="[dyaek]"/ :

< 				 	&& in_array( $key, array( 'edit', 'watch', 'unwatch' ))) {
---
> 				 	&& (
> in_array( $key, array( 'edit', 'watch', 'unwatch' ))
> ||
> preg_match("/accesskey=\"[dyaek]\"/",$skin->tooltipAndAccesskey( "ca-$key" )) )) {

[edit] 4.3 Solution 2 continued

However (both versions of) solution 2 aren't complete: We then need to modify the personal tools and portlets similarly. For example:

< 				echo htmlspecialchars($item['href']) ?>"<?php echo $skin->tooltipAndAccesskey('pt-'.$key) ?><?php
---
> 				echo htmlspecialchars($item['href']) ?>"<?php 
> // echo $skin->tooltipAndAccesskey('pt-'.$key) 
>    if( in_array( $action, array( 'edit', 'submit' ) )
>                                         && (
> preg_match("/accesskey=\"[dyaek]\"/",$skin->tooltipAndAccesskey( "pt-$key" )) )) {
>                                                 echo $skin->tooltip( "pt-$key" );
>                                         } else {
>                                                 echo $skin->tooltipAndAccesskey( "pt-$key" );
>                                         }
> 
> ?><?php

So by the time you're done with all places where this needs changing, you've got quite a lot of modification, and becomes cumbersome.

[edit] 4.4 Solution 3

In 'includes/Linker.php', modify function tooltipAndAccesskey to know about exclusions for certain actions.

Add these lines to give the function access to $action

>                 global $wgRequest; 
>                 $action = $wgRequest->getText( 'action' );

and add an extra clause for $action != edit:

<  		if( $accesskey && $accesskey != '-' &&
< 		!wfEmptyMsg( "accesskey-$name", $accesskey ) ) {
---
>  		if( $accesskey && $accesskey != '-' &&
> 		!wfEmptyMsg( "accesskey-$name", $accesskey ) 
> 		    && $action != "edit") {

This removes most access keys while editing. Interstingly the submit buttons are constructred differently, so save still works.

You could further modify this to check for access key. The function already knows the access key:

               $accesskey = wfMsg( "accesskey-$name" );

and so you could add the following check to the above if statement:

               in_array($accesskey, array('d','y','a','e','k'))

Result. Now we'd have to put this in as a user preference, rather than make it apply for all users.

However, while this helps on a wiki that is under your control, it doesn't help with other mediawikis.

[edit] 5 Hacking the code: Client side

The best ad-hoc solution is probably to hack the code client-side. Rather than modifying the accesskey bindings via the mediawiki code, we can also do this client side.

Using Greasemonkey on Firefox or Greasekit for Safari, we can set up the following script:

(function () {
   if (document.location.href.match(/action=edit/)) {
   var a = document.getElementsByTagName('a');
   for (var i = 0; i < a.length; i++) {
	a[i].setAttribute("accesskey","");
   };
 } else {
 }
})();

and again, because the form buttons aren't generated with <a>, they are unaffected, so ctrl-s for save still works. Just what we wanted, and it will work for any mediawiki (and any other forms, provided that you pick out the relevant "document.location.href.match(/....edit.../)" ). (Installable version of the script to follow.)

If you want a more comprehensive greasemonkey solution for modifing access keys, you could have a look at http://juicystudio.com/article/greasemonkey-user-script-to-manage-access-keys.php which was also inspired by the aforementioned http://golem.ph.utexas.edu/~distler/blog/archives/000727.html . Same idea as done in the present script here [3]