diff options
Diffstat (limited to 'cgi-bin')
-rw-r--r-- | cgi-bin/css/lxrng.css | 105 | ||||
-rw-r--r-- | cgi-bin/js/lxrng-funcs.js | 88 | ||||
-rwxr-xr-x | cgi-bin/lxr | 96 |
3 files changed, 210 insertions, 79 deletions
diff --git a/cgi-bin/css/lxrng.css b/cgi-bin/css/lxrng.css index 637c774..f6a13dc 100644 --- a/cgi-bin/css/lxrng.css +++ b/cgi-bin/css/lxrng.css @@ -1,4 +1,14 @@ -/* http://devnull.tagsoup.com/fixed/horizontal.html */ +body { + font-family: sans-serif; + margin-top: 3px; + margin-left: 3px; + margin-right: 3px; +} + +span.lxr_title { + float: left; + vertical-align: middle; +} span.lxr_l { text-transform: uppercase; @@ -19,13 +29,10 @@ span.lxr_r { border-width: 1px; } -span.lxr_title { - float: left; -} - span.lxr_menu { /* float: right; */ } + div.lxr_menu { float: right; } @@ -35,9 +42,18 @@ span.lxr_search { margin-left: 5px; padding-left: 5px; margin-right: 5px; -/* border-left: solid; - border-width: 1px; */ + border-left: solid; + border-width: 1px; +} + +span.lxr_search input#search { + width: 8em; +} + +span.lxr_search button { + border: solid 1px; } + span.lxr_prefs { font-weight: normal; margin-left: 5px; @@ -57,6 +73,7 @@ span.lxr_version { body.full div.search_results { background: #F0F0F0; z-index: 3; +/* position: absolute; */ position: fixed; right: 3px; top: 35px; @@ -87,34 +104,54 @@ span.close-button { margin-right: 3px; } -a.line:before { +/* a.line:before { content: attr(id); -} +} */ a.line { position: absolute; top: auto; left: 0px; - width: 4.5ex; + height: 2ex; + width: 5.5ex; text-align: right; - background: #e0e0e0; border: solid; border-width: 1px; border-color: #000000; margin-left: 3px; - padding-right: 5px; } -body { - margin-top: 3px; - margin-left: 3px; - margin-right: 3px; - overflow: scroll; +a.line span { + position: absolute; + top: auto; + height: 2ex; + left: 0px; + background: #6c6c6c; + filter: alpha(opacity=10); + moz-opacity: .10; + opacity: .10; + width: 5.5ex; +} + + +pre#file_contents li { + color: blue; +} + +span.line { + position: absolute; + left: 7ex; + color: black; + white-space: pre; } pre { - margin-left: 6ex; + margin-left: 1.5ex; +} + +a img { + border: 0px; } div.headingtop { @@ -156,19 +193,6 @@ button.print { background: #F0F0F0; } - -table.query { - width: 100%; -} - -table.params { - width: 100%; -} - -table.directory { - width: 100%; -} - table.directory td.name { width: 30ex; } @@ -208,7 +232,7 @@ span.comment { span.string { font-style: italic; - color: red; + color: green; } div.find { @@ -282,3 +306,20 @@ div.error { form { display: inline; } + +div.footer { + margin-top: 30px; + border-top: solid; + border-width: 1px; + padding-top: 10px; + font-style: italic; + text-align: center; + font-size: 80%; +} + +div.subfooter { + font-style: italic; + text-align: center; + font-size: 80%; +} + diff --git a/cgi-bin/js/lxrng-funcs.js b/cgi-bin/js/lxrng-funcs.js index 614879e..90129fe 100644 --- a/cgi-bin/js/lxrng-funcs.js +++ b/cgi-bin/js/lxrng-funcs.js @@ -1,17 +1,18 @@ function popup_search(searchform) { searchform = document.getElementById(searchform); - searchform.target = window.name + '-popup'; + searchform.target = 'popup_' + window.name; searchform.navtarget.value = window.name; - window.open('', window.name + '-popup', - 'width=400,height=600,menubar=yes,status=yes,scrollbars=yes'); + window.open('about:blank', 'popup_' + window.name, + 'resizable,width=400,height=600,menubar=yes,status=yes,scrollbars=yes'); return true; } function popup_anchor() { var anchor = this; - window.open('', window.name + '-popup', - 'width=400,height=600,menubar=yes,status=yes,scrollbars=yes'); - anchor.target = window.name + '-popup'; + window.open('about:blank', 'popup_' + window.name, + 'resizable,width=400,height=600,location=no,menubar=yes,scrollbars=yes'); + + anchor.target = 'popup_' + window.name; if (anchor.href.indexOf("navtarget=") >= 0) return true; @@ -33,7 +34,7 @@ function navigate_here(searchform) { function window_unique(serial) { if (!window.name) - window.name = 'lxr-source-' + serial; + window.name = 'lxr_source_' + serial; } function do_search(form) { @@ -43,15 +44,15 @@ function do_search(form) { res.innerHTML = '<div class="progress">Searching...</div>'; pjx_search(['type__search', - 'search', 'v', 'tree__' + loaded_tree], + 'search', 'v', 'tree__' + loaded_tree, 'NO_CACHE'], ['search_results']); return false; } else if (use_popup_navigation) { - form.target = window.name + '-popup'; + form.target = 'popup_' + window.name; form.navtarget.value = window.name; - reswin = window.open('', window.name + '-popup', - 'width=400,height=600,menubar=yes,status=yes,scrollbars=yes'); + reswin = window.open('about:blank', 'popup_' + window.name, + 'resizable,width=400,height=600,location=no,menubar=yes,scrollbars=yes'); } return true; } @@ -118,7 +119,6 @@ function check_hash_navigation() { hash_check = setTimeout('check_hash_navigation()', 50); } else { - // alert(location.hash + ' / ' + loaded_hash); load_content(); } } @@ -136,10 +136,16 @@ function load_file(tree, file, ver, line) { clearTimeout(hash_check); } + if ((pending_tree == tree) && (pending_file == file)) { + location.hash = location.hash.replace(/\#L\d+$/, '') + + '#L' + line; + check_hash_navigation(); + return false; + } + + var res = document.getElementById('content'); - // TODO: check if file already loaded and perform only line - // location update. res.innerHTML = '<div class="progress">Loading...</div>'; pending_line = line; pending_tree = tree; @@ -150,8 +156,13 @@ function load_file(tree, file, ver, line) { else { pending_ver = ''; } - - pjx_load_file(['tree__' + tree, 'file__' + file, 'v__' + ver, 'line__' + line], + + if (!file) + file = '/'; + if (line < 1) + line = 1; + pjx_load_file(['tree__' + tree, 'file__' + file, 'v__' + ver, + 'line__' + line, 'NO_CACHE'], [load_file_finalize]); return false; } @@ -183,10 +194,22 @@ function load_file_finalize(content) { var pre = document.getElementById('file_contents'); if (pre && pre.className == 'partial') { pjx_load_file(['tree__' + pending_tree, 'file__' + pending_file, - 'v__' + pending_ver, 'full__1'], + 'v__' + pending_ver, 'full__1', 'NO_CACHE'], [load_file_finalize]); } + var print = document.getElementById('lxr_print'); + var dirlist = document.getElementById('content_dir'); + if (dirlist) { + print.style.display = 'none'; + } + else { + var pform = document.getElementById('print_form'); + pform.action = '../' + full_tree + '/+print=' + + pending_file.replace(/^\/?/, ''); + print.style.display = 'inline'; + } + if (hash_check) { clearTimeout(hash_check); } @@ -211,7 +234,6 @@ function load_file_finalize(content) { loaded_ver = pending_ver; hash_check = setTimeout('check_hash_navigation()', 50); -// return; // TODO: This really takes oodles of time. Consider coding into html. var i; for (i = 0; i < document.links.length; i++) { @@ -231,6 +253,9 @@ function load_file_finalize(content) { } function load_content() { + if (!use_ajax_navigation) { + return false; + } var tree = location.hash.split('/', 1); tree = tree[0].split(/[+]/); var ver = tree[1] || ''; @@ -238,17 +263,16 @@ function load_content() { var file = location.hash.replace(/^[^\/]*\/?/, ''); var line = file.replace(/.*\#L(\d+)/, '$1'); file = file.replace(/\#L\d+$/, ''); - load_file(tree, file, ver, line); - pjx_releases(['tree__' + tree], + pjx_releases(['tree__' + tree, 'NO_CACHE'], [load_content_finalize]); } function load_content_finalize(content) { var res = document.getElementById('ver_select'); res.innerHTML = content; - var verlist = document.getElementById('ver_list'); + var verlist = document.getElementById('v'); verlist.value = pending_ver; } @@ -274,6 +298,24 @@ function update_version(verlist, base_url, tree, defversion, path) { } } +function next_version() { + var verlist = document.getElementById('v'); + if (verlist.selectedIndex > 0) { + verlist.selectedIndex = verlist.selectedIndex - 1; + update_version(verlist, '', '', '', ''); + } + return false; +} + +function previous_version() { + var verlist = document.getElementById('v'); + if (verlist.selectedIndex < verlist.length - 1) { + verlist.selectedIndex = verlist.selectedIndex + 1; + update_version(verlist, '', '', '', ''); + } + return false; +} + function popup_prepare(serial) { window_unique(serial); var i; @@ -293,8 +335,6 @@ function ajax_lookup_anchor(event, anchor) { if (!anchor) anchor = this; - // TODO: Fix -// lookup = anchor.href.replace(/^(http:.*?lxr\/[+]ajax\/|)/, ''); lookup = anchor.href.replace(/^(http:.*?\/.*?[+][*]\/|)/, ''); var lvar = document.getElementById('ajax_lookup'); @@ -304,7 +344,7 @@ function ajax_lookup_anchor(event, anchor) { res.style.display = 'block'; res.innerHTML = '<div class="progress">Searching...</div>'; - pjx_search(['ajax_lookup', 'v', 'tree__' + loaded_tree], + pjx_search(['ajax_lookup', 'v', 'tree__' + loaded_tree, 'NO_CACHE'], ['search_results']); return false; } diff --git a/cgi-bin/lxr b/cgi-bin/lxr index a0c0f6e..f71d061 100755 --- a/cgi-bin/lxr +++ b/cgi-bin/lxr @@ -10,7 +10,7 @@ use IO::Handle; use LXRng ROOT => "$FindBin::Bin/.."; use LXRng::Context; -use LXRng::Lang qw(C); +use LXRng::Lang; use LXRng::Parse::Simple; use LXRng::Markup::File; use LXRng::Markup::Dir; @@ -84,19 +84,21 @@ sub print_markedup_file { my $focus = $context->param('line') || 0; $focus = 0 if $context->param('full'); my $class = $focus ? 'partial' : 'full'; - print("<pre id=\"file_contents\" class=\"$class\">"); + my $start = $focus > 5 ? " start=".($focus - 5) : ""; + print("<pre id=\"file_contents\" class=\"$class\"><ol$start><span>"); while (<$cache>) { next if $focus and $. < $focus - 5; print($_); last if $focus and $. > $focus + 70; } - print("</pre>"); + print("</span></ol></pre>"); close($cache); } else { my $cache; open($cache, '>', $cfile) if $cfile; my $handle = $node->handle(); + LXRng::Lang->init($context); my $lang = LXRng::Lang->new($node); my $parse = LXRng::Parse::Simple->new($handle, 8, @{$lang->parsespec}); @@ -109,18 +111,26 @@ sub print_markedup_file { # time it's needed, but requires a bit of fiddling with # perlio and the streams to get right. Also messes up # partial transfers. - print("<pre id=\"file_contents\" class=\"full\">"); + print("<pre id=\"file_contents\" class=\"full\"><ol><span>"); while (1) { my @frags = $markup->markupfile($subst, $parse); last unless @frags; print(@frags); print($cache @frags) if $cache; } - print("</pre>\n"); + print("</span></ol></pre>\n"); } } } +sub print_tree_list { + my ($context, $template) = @_; + + $template->process('tree_list.tt2', + {'context' => $context}) + or die $template->error(); +} + sub print_release_list { my ($context, $template) = @_; @@ -147,40 +157,74 @@ sub source { print($query->header(-type => 'text/html', -charset => 'utf-8')); - my $base = $context->base_url(1); - $base =~ s,/*$,/ajax+*/,; - - $template->process('main.tt2', - {'context' => $context, - 'base_url' => $base, - 'javascript' => $pjx->show_javascript(), - 'is_ajax' => 1}) - or die $template->error(); + if ($context->release eq 'trees') { + print_tree_list($context, $template); + } + else { + my $base = $context->base_url(1); + $base =~ s,/*$,/ajax+*/,; + + $template->process('main.tt2', + {'context' => $context, + 'base_url' => $base, + 'javascript' => $pjx->show_javascript(), + 'is_ajax' => 1}) + or die $template->error(); + } } return; } + if ($context->tree eq '') { + print($query->header(-type => 'text/html', + -charset => 'utf-8')); + print_tree_list($context, $template); + return; + } + + + my $ver = $context->release; + my $rep = $context->config->{'repository'}; + die "No tree given" unless $rep; + + my $node = $rep->node($context->path, $ver); + die "Node not found: ".$context->path." ($ver)" unless $node; + my $gzip = do_compress_response($query); - # history cookie + my @history = $query->cookie('lxr_history_'.$context->tree); + if ($node->isa('LXRng::Repo::File')) { + my $h = $context->path.'+'.$ver; + @history = ($h, grep { $_ ne $h } @history); + splice(@history, 15) if @history > 15; + } + + my $lxr_hist = $query->cookie(-name => 'lxr_history_'.$context->tree, + -values => \@history, + -expires => '+1y'); print($query->header(-type => 'text/html', -charset => 'utf-8', + -cookie => $lxr_hist, $gzip ? (-content_encoding => 'gzip') : ())); binmode(\*STDOUT, ":gzip") if $gzip; - my $ver = $context->release; - my $rep = $context->config->{'repository'}; - die "No tree given" unless $rep; + my @rels = @{$context->all_releases()}; + unshift(@rels, $rels[0]); + while (@rels > 2 and $rels[1] ne $context->release) { + shift(@rels); + } - my $node = $rep->node($context->path, $ver); - die "Node not found: ".$context->path." ($ver)" unless $node; + my $ver_next = @rels > 1 ? $rels[0] : $context->release; + my $ver_prev = @rels > 2 ? $rels[2] : $context->release; my %template_args = (%{$template_extra_args || {}}, 'context' => $context, 'tree' => $context->tree, 'node' => $node, + 'ver_prev' => $ver_prev, + 'ver_next' => $ver_next, 'base_url' => $context->base_url, 'javascript' => $pjx->show_javascript()); @@ -293,7 +337,7 @@ sub search { $$ident[1] = $LXRng::Lang::deftypes{$$ident[1]}; $$ident[5] &&= $LXRng::Lang::deftypes{$$ident[5]}; - use Data::Dumper; + # use Data::Dumper; # warn Dumper($symname, $symid, $ident, $refs); $template_args{'ident_res'} = {'query' => $symname, 'ident' => $ident, @@ -359,8 +403,10 @@ sub handle_ajax_request { my ($query, $context, $template) = @_; my $gzip = do_compress_response($query); + $query->no_cache(1); print($query->header(-type => 'text/html', -charset => 'utf-8', + -cache-control => 'no-store, no-cache, must-revalidate', $gzip ? (-content_encoding => 'gzip') : ())); binmode(\*STDOUT, ":gzip") if $gzip; @@ -458,6 +504,7 @@ sub generate_pdf { '~' => '\~{}', '<' => "\$<\$", '>' => "\$>\$", "\\" => "\$\\backslash\$", '-' => '\dash{}', +# These are latin1-replacements, and interact badly with utf8... "\242" => '?', "\244" => '?', "\245" => '?', "\246" => '?', "\252" => "\$\252\$", "\254" => "\$\254\$", @@ -465,7 +512,8 @@ sub generate_pdf { "\261" => "\$\261\$", "\262" => "\$\262\$", "\263" => "\$\263\$", "\265" => "\$\265\$", "\271" => "\$\271\$", "\272" => "\$\272\$", - "\327" => "\$\327\$", "\367" => "\$\367\$"); + "\327" => "\$\327\$", "\367" => "\$\367\$", + ); my $tspecials = join('', map { quotemeta($_) } keys(%tspecials)); @@ -476,6 +524,7 @@ sub generate_pdf { die "No such file" unless $node; my $handle = $node->handle(); + LXRng::Lang->init($context); my $lang = LXRng::Lang->new($node); my $parse = LXRng::Parse::Simple->new($handle, 8, @{$lang->parsespec}); @@ -543,7 +592,8 @@ sub generate_pdf { $cont = 1; } - $part =~ s/([$tspecials])/$tspecials{$1}/ge; + $part =~ s(([$tspecials\0-\010\013\014\016-\037\200-\240])) + (exists $tspecials{$1} ? $tspecials{$1} : '?')ge; if ($btype eq 'code') { $part =~ s/$resre/\\textbf{$1}/g if $resre; |