From bf84ea2d73ad9605ab59994cae777d7b12c0e340 Mon Sep 17 00:00:00 2001 From: Yorhel Date: Wed, 18 Jul 2012 19:46:13 +0200 Subject: [PATCH] Remember display of nav bar when selecting different man versions This improves usability *a lot*. Too bad the code's quite ugly... --- www/index.pl | 5 +++- www/man.css | 5 +--- www/man.js | 82 ++++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 81 insertions(+), 11 deletions(-) diff --git a/www/index.pl b/www/index.pl index cb47300..8487741 100755 --- a/www/index.pl +++ b/www/index.pl @@ -449,6 +449,9 @@ sub man { return $self->resNotFound() if !@$m; my $man = getman($self, $name, $hash, $m); + my $view = $self->formValidate({get => 'v', regex => qr/^[a-z2-7]+$/}); + $view = $view->{_err} ? '' : $view->{v}; + $self->htmlHeader(title => $name); div id => 'nav', 'Sorry, this navigation menu won\'t display without Javascript. :-('; @@ -495,7 +498,7 @@ sub man { end; end; - $self->htmlFooter(js => { hash => substr($man->{hash}, 0, 8), name => $man->{name}, mans => manjslist($self, $m) }); + $self->htmlFooter(js => { hash => substr($man->{hash}, 0, 8), name => $man->{name}, view => $view, mans => manjslist($self, $m) }); } diff --git a/www/man.css b/www/man.css index 1225e16..e1925be 100644 --- a/www/man.css +++ b/www/man.css @@ -1,7 +1,4 @@ -/* TODO: - * - The linear-gradient() functions are fairly new - perhaps want to provide background images for those. - * - column-width is better done in Perl? (More like a column-count, then) - */ +/* TODO: column-width is better done in Perl? (More like a column-count, then) */ * { margin: 0; padding: 0; font-family: "Trebuchet MS", sans-serif; } html { background: #333; padding: 0 10px; } diff --git a/www/man.js b/www/man.js index 7e2ad8d..99a7145 100644 --- a/www/man.js +++ b/www/man.js @@ -310,8 +310,38 @@ dsInit(byId('q'), '/xml/search.xml?q=', function(item, tr) { ); -// TODO: Fix the 'pkg' link -// TODO: Keep same view when switching to different version of the same man page + +// Efficiently pack an array of booleans into a string. (Uses something like +// base32) Note: The resulting array after decoding may have a few more +// elements than it had before decoding. These will be false. +var bsCharacters = "abcdefghijklmnopqrstuvwxyz234567"; + +function bsEncode(a) { + var v = 0; + var b = 0; + var r = ''; + for(var i=0; i 0) + r += bsCharacters.charAt(v<<(5-b)); + return r; +} + +function bsDecode(s) { + var a = []; + for(var i=0; i= 97 ? 97 : 24; + a.push(!!((n>>4)&1), !!((n>>3)&1), !!((n>>2)&1), !!((n>>1)&1), !!(n&1)); + } + return a; +} + /* Structure of VARS.mans: [ @@ -336,6 +366,7 @@ navHasLocale = false; function navCreate(nav) { setText(nav, ''); + view = navSerialize(); navHasLocale = false; var dl = tag('dl', null); @@ -351,7 +382,7 @@ function navCreate(nav) { if(sys[4]) for(var j=0; j 0 && sys[3][n-1][0] == pkg[0]; @@ -393,7 +424,7 @@ function navCreatePkg(nav, dd, sys, n) { if(man[2] == VARS.hash || (navShowLocales || !man[1])) { if(i > 0) pdd.appendChild(tag(' ')); - pdd.appendChild(man[2] == VARS.hash ? tag('b', txt) : tag('a', {href:'/'+VARS.name+'/'+man[2]}, txt)); + pdd.appendChild(man[2] == VARS.hash ? tag('b', txt) : tag('a', {href:'/'+VARS.name+'/'+man[2]+'?v='+view}, txt)); mannum++; } } @@ -429,8 +460,47 @@ function navCreateLinks(nav) { } -if(byId('nav')) +// Serializes the current navigation view into a short string. The string is a +// bsEncode()ed bit array, creates as follows: +// array.push(navShowLocales); +// for(each system that has an expand button) +// array.push(is the butten expanded or not); +// for(each system) +// for(each package that has an expand button) +// array.push(is the button expanded or not); +// Obviously, this means that the serialized view depends on the number and +// order of systems and packages. The order is stable, the number may change +// with database updates. +function navSerialize() { + var a = [navShowLocales]; + for(var i=0; i 0 && VARS.mans[i-1][0] == VARS.mans[i][0]) + VARS.mans[i][4] = i > 1 && VARS.mans[i-2][0] == VARS.mans[i-1][0] ? VARS.mans[i-1][4] : !!a.shift(); + for(var i=0; i 0 && VARS.mans[i][3][j-1][0] == VARS.mans[i][3][j][0]) + VARS.mans[i][3][j][3] = j > 1 && VARS.mans[i][3][j-2][0] == VARS.mans[i][3][j-1][0] ? VARS.mans[i][3][j-1][3] : !!a.shift(); +} + + +if(byId('nav')) { + navLoad(VARS.view||''); navCreate(byId('nav')); +}