git: cf170cee3d - main - man.cgi: enable new responsive design

From: Wolfram Schneider <wosch_at_FreeBSD.org>
Date: Tue, 29 Sep 2026 11:49:39 UTC
The branch main has been updated by wosch:

URL: https://cgit.FreeBSD.org/doc/commit/?id=cf170cee3d47ebf6e5d9d6bea2a30063d0962a43

commit cf170cee3d47ebf6e5d9d6bea2a30063d0962a43
Author:     Wolfram Schneider <wosch@FreeBSD.org>
AuthorDate: 2026-09-29 11:48:51 +0000
Commit:     Wolfram Schneider <wosch@FreeBSD.org>
CommitDate: 2026-09-29 11:48:51 +0000

    man.cgi: enable new responsive design
    
    Implement and enable new design for man.cgi, based on c9c518d9db
    
    Reviewed by: ziaee
---
 website/content/en/cgi/man.cgi | 193 +++++++++++++++++++++++++----------------
 1 file changed, 117 insertions(+), 76 deletions(-)

diff --git a/website/content/en/cgi/man.cgi b/website/content/en/cgi/man.cgi
index 26f6b5c8a6..db4e5bf9cc 100755
--- a/website/content/en/cgi/man.cgi
+++ b/website/content/en/cgi/man.cgi
@@ -44,7 +44,7 @@
 # Use standard FreeBSD CGI Style if available.
 # Otherwise print simple HTML design.
 package cgi_style;
-use constant HAS_FREEBSD_CGI_STYLE => eval { require "./cgi-style.pl"; };
+use constant HAS_FREEBSD_CGI_STYLE => eval { require "./cgi-style-responsive.pl"; };
 
 package main;
 
@@ -1452,10 +1452,8 @@ sub html_footer {
     print qq[| <a href="$www{'cgi_man'}/help.html">help</a>\n] if !$args{'no_help_link'};
     print qq[</span>\n\n];
 
-    print &input_autofocus_at_end;
-
     if (cgi_style::HAS_FREEBSD_CGI_STYLE) {
-        print q{<hr noshade="noshade" />};
+        print q{<hr noshade="noshade">};
         print &cgi_style::html_footer;
     }
     else {
@@ -1466,39 +1464,95 @@ sub html_footer {
 sub html_header {
     my ( $title, $base ) = @_;
 
-    my $html_meta = q|
-<meta name="robots" content="nofollow" />
-<meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type" />
-<link rel="search" type="application/opensearchdescription+xml" href="https://www.freebsd.org/opensearch/man.xml" title="FreeBSD Man" />
-<link rel="search" type="application/opensearchdescription+xml" href="https://www.freebsd.org/opensearch/man-freebsd-release-ports.xml" title="FreeBSD Man+P" />
+    my $html_meta = <<'EOF';
+<meta name="robots" content="nofollow">
+<link rel="search" type="application/opensearchdescription+xml" href="https://www.freebsd.org/opensearch/man.xml" title="FreeBSD Man">
+<link rel="search" type="application/opensearchdescription+xml" href="https://www.freebsd.org/opensearch/man-freebsd-release-ports.xml" title="FreeBSD Man+P">
+
+<style>
+span.footer_links { font-size: .9em; margin-left: .5em; }
+
+div#section_links, div#permalink, div#footer { margin-left: 1em; }
+hr { margin-left: 0em; max-width: 50em; margin-top: 0px; }
 
-<style type="text/css">
-span.footer_links { font-size: small; }
-span.space { font-size: xx-small; }
-form#man > input, form#man > button { font-size: large; }
-form#man > input[name='query'] { text-align: center; }
-p#section_links, div#footer { max-width: 50em; }
-hr { margin-left: 0em; max-width: 50em; }
 a:link  { text-decoration:none; }
 a:hover { text-decoration:underline; }
 
-@media only screen and (max-height: 640px), (max-width: 760px) {
-  /* hide logo color top */
-  body { background: #fff !important; } 
-
-  /* hide menu top */
-  div#header, div#menu { display: none !important; }
-  // div#content { padding-top: 4.9em; }
-  span.spaces { display: none; }
+form#man > input[name='query'] { text-align: center; }
+form#man > input[name='query'] { width: 18em; }
+form#man > input, form#man > button, form#man > select { margin-left: 0.2em; }
+form#man > input, form#man > button                    { font-size: large; }
+form#man > button { margin-top: .8em; }
+form#man > select { margin-top: .8em; font-size: 100%; }
+form#man { padding-bottom: .7em; margin-top: .2em; }
+
+div#content { padding-top: 0.4em; }
+
+/* mobile device - portrait mode */
+@media screen and (orientation: portrait) and (max-width: 950px) {
+  #content pre {
+    font-size: clamp(11px, 2.9vw, 13px) !important;
+    line-height: 1.35 !important;
+
+    white-space: pre-wrap !important;
+    word-wrap: break-word !important;
+
+    overflow-x: auto !important;
+    -webkit-overflow-scrolling: touch;
+
+    -webkit-text-size-adjust: 100% !important;
+    text-size-adjust: 100% !important;
+  }
+}
 
-  /* larger search form */
-  form#man > input, button { font-size: 150%; }
-  form#man > button { font-size: 150%; }
-  form#man > input[name='query'] { width: 20em; }
-  form#man > select { font-size: 120%; }
+/* mobile device - landscape mode */
+@media screen and (orientation: landscape) and (max-width: 950px) {
+  #content pre {
+    /* scales with viewport width; tweak the 2.0vw multiplier if 84 cols still doesn't fit */
+    font-size: clamp(9px, 2.0vw, 14px) !important;
+    line-height: 1.35 !important;
+
+    /* keep the original column alignment intact — do NOT let it wrap */
+    white-space: pre !important;
+    word-wrap: normal !important;
+
+    /* fallback: if a line is still too wide, scroll it instead of breaking layout */
+    overflow-x: auto !important;
+    -webkit-overflow-scrolling: touch;
+
+    /* stop iOS from auto-boosting the font size on top of your setting */
+    -webkit-text-size-adjust: 100% !important;
+    text-size-adjust: 100% !important;
+  }
+  header { display: none; }
 }
+
+/* small devices or laptops */
+@media screen and (max-width: 1300px) {
+  .logo-menu-bars-container { padding: 0px; }
+
+  footer { margin-top: -1.2em; }
+  hr { margin-top: 0px; margin-bottom: 0px; }
+  h3 { padding-top: .2em; }
+} 
 </style>
-|;
+
+<script>
+function input_autofocus_at_end () {
+  const input = document.querySelector('#query'); 
+  if (input) {
+    // XXX: don't open keyboard on Android
+    input.setAttribute('readonly', 'readonly');
+    input.focus({ preventScroll: true });
+    setTimeout(function () {
+      input.removeAttribute('readonly');
+      input.setSelectionRange(input.value.length, input.value.length);
+    }, 50);
+  }
+}
+document.addEventListener('DOMContentLoaded', input_autofocus_at_end);
+</script>
+EOF
 
     return &html_header2( $title, $html_meta )
       if !cgi_style::HAS_FREEBSD_CGI_STYLE;
@@ -1507,7 +1561,7 @@ a:hover { text-decoration:underline; }
       s,</head>,$html_meta\n</head>,s;
 
     $header =~ s,^Content-type:\s+\S+\s+,,s;
-    $header =~ s,<head>,<head>\n<base href="$base" />,s if $base;
+    $header =~ s,<head>,<head>\n<base href="$base">,s if $base;
     return $header;
 }
 
@@ -1711,7 +1765,6 @@ sub apropos {
 
     &http_header("text/html");
     print &html_header("Apropos $title - $manpath Manual Pages");
-    print "<br/>\n";
 
     $section = $sektion;
     &formquery;
@@ -1758,14 +1811,14 @@ sub apropos {
 
     if ( !$acounter ) {
         if ($query eq '') {
-           print "<hr/>Empty input. Please type a manual page and search again.\n<hr/>\n";
+           print "<hr>Empty input. Please type a manual page and search again.\n<hr>\n";
         } else {
            my $apropos_query = $query . ($sektion ? "($sektion)" : "");
            print "Sorry, no apropos results found for `$apropos_query'.\n";
            print qq{Please try a <a href="$BASE?apropos=1&amp;manpath=$manpath&amp;query=$query">keyword search</a>.\n} if $sektion;
-           print "<br/><br/>\n";
+           print "<br><br>\n";
            print qq{You can start a <a href="$www{'cgi_man'}">new search</a> or look for other }
-          . qq{<a href="https://www.freebsd.org/search/">FreeBSD Search Services</a>.<br/><hr/>\n};
+          . qq{<a href="https://www.freebsd.org/search/">FreeBSD Search Services</a>.<br><hr>\n};
         }
     }
     &html_footer;
@@ -1838,8 +1891,7 @@ sub man {
     if ( $format eq "html" ) {
         &http_header("text/html");
         print &html_header("$title - $manpath Manual Pages");
-        print "<br/>\n";
-        print "<h1>$www{'head'}</h1>\n\n" if !$www{'head'};
+        print "<h3>$www{'head'}</h3>\n\n" if !$www{'head'};
         &formquery;
         print "<pre>\n";
     }
@@ -1878,9 +1930,9 @@ sub man {
     $html_section = &encode_data($section);
 
     if ( $name =~ /^\s*$/ ) {
-	print "</pre><hr/>";
+	print "</pre><hr>";
         print "Empty input. Please type a manual page and search again.\n";
-	print "<hr/>\n";
+	print "<hr>\n";
         &html_footer;
         return;
     }
@@ -1978,7 +2030,7 @@ sub man {
         print
 qq{Please try a <a href="$BASE?apropos=1&amp;manpath=$manpath&amp;query=$html_name">keyword search</a>.\n};
         print qq{<p>You can start a <a href="$www{'cgi_man'}">new search</a> or look for other }
-          . qq{<a href="https://www.freebsd.org/search/">FreeBSD Search Services</a>.</p><hr/>\n};
+          . qq{<a href="https://www.freebsd.org/search/">FreeBSD Search Services</a>.</p><hr>\n};
         &html_footer;
         return;
     }
@@ -2070,15 +2122,15 @@ qq{Please try a <a href="$BASE?apropos=1&amp;manpath=$manpath&amp;query=$html_na
             $i = $_;
             $j = &encode_url($i);
             $j =~ s/\+/_/g;
-            $_ = qq{<a name="$j" href="#end"><b>$i</b></a>\n};
+            $_ = qq{<a id="$j" href="#end"><b>$i</b></a>\n};
             push( @sect, $i );
         }
         print;
     }
     close(MAN);
-    print qq{</pre>\n<a name="end" />\n<hr />\n};
+    print qq{</pre>\n<span id="end"></span>\n<hr>\n};
 
-    print qq{\n<p id="section_links">\n};
+    print qq{\n<div id="section_links">\n<p>\n};
     for ( $i = 0 ; $i <= $#sect ; $i++ ) {
         $j = &encode_url( $sect[$i] );
         $j =~ s/\+/_/g;
@@ -2087,15 +2139,15 @@ qq{Please try a <a href="$BASE?apropos=1&amp;manpath=$manpath&amp;query=$html_na
           . qq{">$sect[$i]</a>}
           . ( $i < $#sect ? " |\n" : "\n" );
     }
-    print qq{</p>\n\n};
+    print qq{</p>\n</div>\n};
 
     if ($want_to_link_to_this_page) {
         my $url = qq{$full_url?query=$html_name};
         $url .= qq{&amp;sektion=$html_section} if $html_section != 0;
         $url .= qq{&amp;manpath=} . &encode_url($manpath);
 
-        print qq{<p align="left">Want to link to this manual page? };
-        print qq{Use this URL:<br/>&lt;<a href="$url">$url</a>&gt;</p>\n};
+        print qq{<div id="permalink">\n<p>\nWant to link to this manual page? };
+        print qq{Use this URL:<br>&lt;<a href="$url">$url</a>&gt;</p>\n</div>\n};
     }
 
     &html_footer;
@@ -2104,17 +2156,6 @@ qq{Please try a <a href="$BASE?apropos=1&amp;manpath=$manpath&amp;query=$html_na
     select undef, undef, undef, 0.35;
 }
 
-sub input_autofocus_at_end {
-    return <<EOF;
-
-<script type="text/javascript">
-const input = document.querySelector('#query'); 
-input.focus();
-input.setSelectionRange(input.value.length, input.value.length);
-</script>
-EOF
-}
-
 #
 # You may need to precreate some mdoc.local files for every system you
 # support (every collection of man pages), maybe like:
@@ -2381,7 +2422,7 @@ sub encode_data {
 sub indexpage {
     &http_header("text/html");
     print &html_header("$www{'title'}");
-    print "<br/>\n<h1>$www{'head'}</h1>\n\n"; 
+    print "<h3>$www{'head'}</h3>\n\n"; 
 
     # print &intro;
     &formquery;
@@ -2401,19 +2442,13 @@ sub formquery {
         $bstring = q{ checked="checked"};
     }
 
-    # set focus if the input field is empty 
-    my $autofocus = $query ? "" : "autofocus";
-
     print <<ETX;
 <form id="man" method="get" action="$BASE">
 <!-- Manual Page or Keyword Search: -->
-<span class="spaces">&nbsp;&nbsp;</span>
-<input type="text" id="query" value="$query" name="query" size="36" autocapitalize="none" $autofocus />
+<input type="text" id="query" value="$query" name="query" size="36" autocapitalize="none">
 <button type="submit" name="apropos" value="0">man</button>
 <button type="submit" name="apropos" value="1">apropos</button>
-<br/>
-<span class="space">&nbsp;</span><br/>
-<span class="spaces">&nbsp;&nbsp;</span>
+<br>
 ETX
 
     print qq{<select name="sektion">\n};
@@ -2482,14 +2517,13 @@ ETX
 </select>
 </form>
 
-<br/>
 <span class="footer_links">
   <a href="$www{'cgi_man'}">home</a> |
   <a href="$www{'cgi_man'}/help.html">help</a>
 </span>
 ETX
     if ($query) {
-	print "<hr/>\n";
+	print "<hr>\n";
     }
 }
 
@@ -2552,7 +2586,7 @@ much smaller.
 <li>socket(2) manpage: <a href="https://man.freebsd.org/socket/2">https://man.freebsd.org/socket/2</a></li>
 </ul>
 
-<p />
+<p></p>
 
 <ul>
 <li>socket manpage: <a href="$full_url?socket">$full_url?socket</a></li>
@@ -2623,8 +2657,15 @@ e.g., "netbsd" always points to the latest NetBSD release.
 
 <h2>Copyright</h2>
 <p>
-Copyright (c) 1996-2026 <a href="$mailtoURL">Wolfram Schneider</a><br/>
-Copyright (c) 1993-1995 Berkeley Software Design, Inc.<br/>
+Copyright (c) 1996-2026 <a href="$mailtoURL">Wolfram Schneider</a><br>
+Copyright (c) 1993-1995 Berkeley Software Design, Inc.
+</p>
+
+<p>
+Copyright (c) for manual pages by OS vendors:
+<p>
+Copyright (c) 1996-2026 <a href="$mailtoURL">Wolfram Schneider</a><br>
+Copyright (c) 1993-1995 Berkeley Software Design, Inc.<br>
 </p>
 
 <p>
@@ -2658,7 +2699,7 @@ Copyright (c) for manual pages by OS vendors:
 <a href="https://en.wikipedia.org/wiki/Version_7_Unix">Unix Seventh Edition</a>,
 <a href="https://www.x.org">X11R6</a>,
 <a href="https://www.xfree86.org">XFree86</a>
-<br/>
+<br>
 </span>
 </p>
 };
@@ -2667,7 +2708,7 @@ Copyright (c) for manual pages by OS vendors:
 
 sub intro {
     return qq{\
-<p />
+<p/>
 <i>Man Page Lookup</i> searches for man pages name and section as
 given in the selection menu and the query dialog.  <i>Apropos
 Keyword Search</i> searches the database for the string given in
@@ -2676,15 +2717,15 @@ as short-cuts to various queries:  <i>Section Indexes</i> is apropos
 listings of all man pages by section.  <i>Explanations of Man
 Sections</i> contains pointers to the intro pages for various man
 sections.
-<p />
+<p/>
 };
 }
 
 sub faq_output {
     &http_header("text/html");
     print &html_header( "$www{'head'} Help", '/cgi/' );
-    print "<br/>\n<h1>$www{'head'} Help</h1>\n";
-    print &faq . "<br/>\n";
+    print "<br>\n<h1>$www{'head'} Help</h1>\n";
+    print &faq . "<br>\n";
     &html_footer('no_help_link' => 1);
 }