Remember display of nav bar when selecting different man versions
This improves usability *a lot*. Too bad the code's quite ugly...
This commit is contained in:
parent
2622fad2d9
commit
bf84ea2d73
3 changed files with 81 additions and 11 deletions
|
|
@ -449,6 +449,9 @@ sub man {
|
||||||
return $self->resNotFound() if !@$m;
|
return $self->resNotFound() if !@$m;
|
||||||
my $man = getman($self, $name, $hash, $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);
|
$self->htmlHeader(title => $name);
|
||||||
div id => 'nav', 'Sorry, this navigation menu won\'t display without Javascript. :-(';
|
div id => 'nav', 'Sorry, this navigation menu won\'t display without Javascript. :-(';
|
||||||
|
|
||||||
|
|
@ -495,7 +498,7 @@ sub man {
|
||||||
end;
|
end;
|
||||||
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) });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
/* TODO:
|
/* TODO: column-width is better done in Perl? (More like a column-count, then) */
|
||||||
* - 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)
|
|
||||||
*/
|
|
||||||
|
|
||||||
* { margin: 0; padding: 0; font-family: "Trebuchet MS", sans-serif; }
|
* { margin: 0; padding: 0; font-family: "Trebuchet MS", sans-serif; }
|
||||||
html { background: #333; padding: 0 10px; }
|
html { background: #333; padding: 0 10px; }
|
||||||
|
|
|
||||||
82
www/man.js
82
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<a.length; i++) {
|
||||||
|
v = (v<<1) + (a[i]?1:0);
|
||||||
|
if(++b == 5) {
|
||||||
|
r += bsCharacters.charAt(v);
|
||||||
|
v = b = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!a.length || b > 0)
|
||||||
|
r += bsCharacters.charAt(v<<(5-b));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bsDecode(s) {
|
||||||
|
var a = [];
|
||||||
|
for(var i=0; i<s.length; i++) {
|
||||||
|
var n = s.charCodeAt(i);
|
||||||
|
n -= n >= 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:
|
/* Structure of VARS.mans:
|
||||||
[
|
[
|
||||||
|
|
@ -336,6 +366,7 @@ navHasLocale = false;
|
||||||
function navCreate(nav) {
|
function navCreate(nav) {
|
||||||
setText(nav, '');
|
setText(nav, '');
|
||||||
|
|
||||||
|
view = navSerialize();
|
||||||
navHasLocale = false;
|
navHasLocale = false;
|
||||||
var dl = tag('dl', null);
|
var dl = tag('dl', null);
|
||||||
|
|
||||||
|
|
@ -351,7 +382,7 @@ function navCreate(nav) {
|
||||||
|
|
||||||
if(sys[4])
|
if(sys[4])
|
||||||
for(var j=0; j<sys[3].length; j++)
|
for(var j=0; j<sys[3].length; j++)
|
||||||
if(navCreatePkg(nav, dd, sys, j))
|
if(navCreatePkg(nav, view, dd, sys, j))
|
||||||
pkgnum++;
|
pkgnum++;
|
||||||
|
|
||||||
if(!isold || sys[4])
|
if(!isold || sys[4])
|
||||||
|
|
@ -376,7 +407,7 @@ function navCreate(nav) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function navCreatePkg(nav, dd, sys, n) {
|
function navCreatePkg(nav, view, dd, sys, n) {
|
||||||
var pkg = sys[3][n];
|
var pkg = sys[3][n];
|
||||||
|
|
||||||
var isold = n > 0 && sys[3][n-1][0] == pkg[0];
|
var isold = n > 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(man[2] == VARS.hash || (navShowLocales || !man[1])) {
|
||||||
if(i > 0)
|
if(i > 0)
|
||||||
pdd.appendChild(tag(' '));
|
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++;
|
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<VARS.mans.length; i++)
|
||||||
|
if(i+1 < VARS.mans.length && VARS.mans[i+1][0] == VARS.mans[i][0] && (i == 0 || VARS.mans[i-1][0] != VARS.mans[i][0]))
|
||||||
|
a.push(!!VARS.mans[i+1][4]);
|
||||||
|
for(var i=0; i<VARS.mans.length; i++)
|
||||||
|
for(var j=0; j<VARS.mans[i][3].length; j++)
|
||||||
|
if(j+1 < VARS.mans[i][3].length && VARS.mans[i][3][j+1][0] == VARS.mans[i][3][j][0] && (j == 0 || VARS.mans[i][3][j-1][0] != VARS.mans[i][3][j][0]))
|
||||||
|
a.push(!!VARS.mans[i][3][j+1][3]);
|
||||||
|
return bsEncode(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
// And the reverse of the above.
|
||||||
|
function navLoad(s) {
|
||||||
|
var a = bsDecode(s);
|
||||||
|
navShowLocales = !!a.shift();
|
||||||
|
for(var i=0; i<VARS.mans.length; i++)
|
||||||
|
if(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<VARS.mans.length; i++)
|
||||||
|
for(var j=0; j<VARS.mans[i][3].length; j++)
|
||||||
|
if(j > 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'));
|
navCreate(byId('nav'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue