diff options
author | dweller <dweller@cabin.digital> | 2024-02-26 11:47:32 +0200 |
---|---|---|
committer | dweller <dweller@cabin.digital> | 2024-02-26 11:47:32 +0200 |
commit | f0181813ecf9867f13a206d87fc46b15d295acbc (patch) | |
tree | b1b6f94e6a2318010cb322bbd119356b46076dd4 | |
parent | a87359aaacac66655af6baa80ced112ac842f651 (diff) |
wire up frontend with PHP, badly
-rw-r--r-- | common.php | 8 | ||||
-rw-r--r-- | index.php (renamed from index.html) | 36 | ||||
-rw-r--r-- | js/copy.js | 32 | ||||
-rw-r--r-- | js/lmmtfy.js | 32 | ||||
-rw-r--r-- | main.php | 0 | ||||
-rw-r--r-- | search.html | 94 | ||||
-rw-r--r-- | search.php | 124 | ||||
-rw-r--r-- | style/main.css | 29 | ||||
-rw-r--r-- | style/man.css | 2 | ||||
-rw-r--r-- | style/search.css | 16 |
10 files changed, 250 insertions, 123 deletions
diff --git a/common.php b/common.php new file mode 100644 index 0000000..b7b588d --- /dev/null +++ b/common.php @@ -0,0 +1,8 @@ +<?php + $root = (!empty($_SERVER['HTTPS']) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST']; + $manpath = "/usr/share/man"; + + $action = trim(urldecode($_GET['action'] ?? null)); + $query = trim(urldecode($_GET['query'] ?? null)); + $section = trim(urldecode($_GET['section'] ?? null)); +?> @@ -1,3 +1,6 @@ +<?php + require 'common.php'; +?> <!DOCTYPE html> <html lang="en"> <head> @@ -26,28 +29,37 @@ </header> <section id="logo"> <h1> - <span id="gc-let">Let</span> - <span id="gc-me">me</span> - <code id="gc-man">man</code> - <span id="gc-that">that</span> - <span id="gc-for">For</span> - <span id="gc-you">you</span> + <span id="logo-let">Let</span> + <span id="logo-me">me</span> + <code id="logo-man">man</code> + <span id="logo-that">that</span> + <span id="logo-for">For</span> + <span id="logo-you">you</span> </h1> - <div id="version_wrap"> - <span id="version">BETA!</span> + <div id="logo-ver_wrap"> + <span id="logo-ver">BETA!</span> </div> </section> <nav id="search_pane"> - <form> + <form action="/search.php"> <div id="query_wrap"> <div id="query_icon"></div> - <input id="query" type='search' value='' name='query' required autofocus/> + <input id="query" type='search' value='<?php if($action === 'lmmtfy') echo $query;?>' name='query' required autofocus/> + <button id="def" type='submit' value='man' name='action' class="btn-def" aria-hidden="true" tabindex="-1"></button> + <?php + if($action === 'lmmtfy') + echo '<input id="sect" type="hidden" value="' . $section . '" name= "section"/>'; + ?> </div> <div> <button id="mank" type='submit' value='apropos' name='action' title="apropos(1)">man -k</button> <button id="man" type='submit' value='man' name='action' title="Feeling lucky, punk?">man</button> </div> </form> + <?php + if($action === 'lmmtfy') + echo '<noscript class="center"><p>No JavaScript means you have to manually press the <code>man</code> button.</p></noscript>'; + ?> <p class="hint center">Write "man" if you have no idea what to do...</p> </nav> @@ -72,4 +84,8 @@ </nav> </div> </body> + +<?php + if($action === 'lmmtfy') echo '<script src="js/lmmtfy.js"></script>'; +?> </html> diff --git a/js/copy.js b/js/copy.js new file mode 100644 index 0000000..3bc7707 --- /dev/null +++ b/js/copy.js @@ -0,0 +1,32 @@ +const dom_lmmtfy = document.getElementById("lmmtfy_url"); +const dom_copy = document.getElementById("lmmtfy_copy"); + +dom_copy.onclick = lmmtfy_copy; + +function lmmtfy_copy() +{ + dom_lmmtfy.focus(); + dom_lmmtfy.select(); + + try + { + // TODO: deprecated -- https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand + if(document.execCommand('copy')) + dom_copy.innerHTML = "Copied!" + + setTimeout(() => + { + dom_copy.innerHTML = "Copy" + }, 3000); + + } + catch(err) + { + dom_copy.innerHTML = "Error :("; + console.log('Oops, unable to copy'); + } + + // This unfocuses the element, but W3C decided to be funny with + // the naming. + document.activeElement.blur(); +} diff --git a/js/lmmtfy.js b/js/lmmtfy.js new file mode 100644 index 0000000..d0410ab --- /dev/null +++ b/js/lmmtfy.js @@ -0,0 +1,32 @@ +const dom_query = document.getElementById("query"); +const dom_sect = document.getElementById("sect"); +const dom_man = document.getElementById("man"); + +const query = dom_query.value; +dom_query.value = ""; + +let i = 0, j = 0; +let elapsed = 0; +let actions = +[ + [250, () => { dom_query.focus(); }, 1], + [150, () => { dom_query.value += query[j++]; }, query.length], + [250, () => { dom_man.focus(); }, 1], + [250, () => { dom_man.click(); }, 1], +]; + +function do_stuff() +{ + elapsed += 50; + + if((elapsed % actions[i][0]) == 0) + { + actions[i][1](); + actions[i][2]--; + if(actions[i][2] <= 0) i++; + } + + setTimeout(do_stuff, 50); +} + +do_stuff(); diff --git a/main.php b/main.php deleted file mode 100644 index e69de29..0000000 --- a/main.php +++ /dev/null diff --git a/search.html b/search.html deleted file mode 100644 index 37031f3..0000000 --- a/search.html +++ /dev/null @@ -1,94 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> - <head> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"/> - - <title>Manup               Lonely MAN near You</title> - - <link rel="icon" type="image/png" sizes="128x128" href="imgs/logo-goog.png"/> - <link rel="icon" type="image/png" sizes="32x32" href="imgs/logo-goog32.png"/> - <link rel="icon" type="image/png" sizes="16x16" href="imgs/logo-goog16.png"/> - <!--<link rel="icon" type="image/x-icon" sizes="16x16" href="imgs/logo-goog16.ico"/>--> - - <link rel="stylesheet" href="style/normalize.css"/> - <link rel="stylesheet" href="style/main.css"/> - <link rel="stylesheet" href="style/search.css"/> - </head> - <body> - <div id="main"> - <header> - <a id="logo" href="/"> - <h1> - <span id="gc-let">L</span> - <span id="gc-me">m</span> - <code id="gc-man">m</code> - <span id="gc-that">t</span> - <span id="gc-for">F</span> - <span id="gc-you">y</span> - </h1> - <div id="version_wrap"> - <span id="version">BETA!</span> - </div> - </a> - <nav id="search_pane"> - <form> - <div id="query_wrap"> - <input id="query" type='searcg' value='man' name='query' required/> - <button id="mank" type='submit' value='apropos' name='action' title="apropos(1)">-k</button> - <button id="man" type='submit' value='man' name='action' title="Feeling lucky, punk?" class="btn-acc"> - <div id="query_icon"></div> - </button> - </div> - </form> - </nav> - <nav id="topnav"> - <a href="https://cabin.digital">Cabin</a> - <a href="#"><span id="topnav_icon"></span></a> - <button class="btn-acc">Man up</button> - </nav> - </header> - <section id="results"> - <p class="hint"> Found 14 results</p> - <dl> - <dt><a href="/page.html">man (1)</dt></a> - <dd>an interface to the system reference manuals</dd> - <dt><a href="#2">manconv (1)</dt></a> - <dd>convert manual page from one encoding to another</dd> - <dt><a href="#3">mandb (8)</dt></a> - <dd>create or update the manual page index caches</dd> - <dt><a href="#4">mandoc (1)</dt></a> - <dd>format manual pages</dd> - <dt><a href="#5">mandoc.db (5)</dt></a> - <dd>manual page database</dd> - <dt><a href="#6">mandoc_char (7)</dt></a> - <dd>mandoc special characters</dd> - <dt><a href="#7">mandoc_eqn (7)</dt></a> - <dd>eqn language reference for mandoc</dd> - <dt><a href="#8">mandoc_man (7)</dt></a> - <dd>legacy formatting language for manual pages</dd> - <dt><a href="#9">mandoc_mdoc (7)</dt></a> - <dd>semantic markup language for formatting manual pages</dd> - <dt><a href="#10">mandoc_roff (7)</dt></a> - <dd>roff language reference for mandoc</dd> - <dt><a href="#11">mandoc_tbl (7)</dt></a> - <dd>tbl language reference for mandoc</dd> - <dt><a href="#12">mandocd (8)</dt></a> - <dd>server process to format manual pages in batch mode</dd> - <dt><a href="#13">manpath (1)</dt></a> - <dd>determine search path for manual pages</dd> - <dt><a href="#14">manpath (5)</dt></a> - <dd>format of the /etc/manpath.config file</dd> - </dl> - </section> - <footer> - <p class="center"> - Copyleft <span class="copyleft">©</span> 2024 - <a href="mailto:manup@cabin.digital">dweller</a> from - <a href="https://cabin.digital">cabin.digital</a>. - All Wrongs Reserved. - </p> - </footer> - </div> - </body> -</html> diff --git a/search.php b/search.php new file mode 100644 index 0000000..a66fc41 --- /dev/null +++ b/search.php @@ -0,0 +1,124 @@ +<?php + require 'common.php'; +?> +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"/> + + <title>Manup               Lonely MAN near You</title> + + <link rel="icon" type="image/png" sizes="128x128" href="imgs/logo-goog.png"/> + <link rel="icon" type="image/png" sizes="32x32" href="imgs/logo-goog32.png"/> + <link rel="icon" type="image/png" sizes="16x16" href="imgs/logo-goog16.png"/> + <!--<link rel="icon" type="image/x-icon" sizes="16x16" href="imgs/logo-goog16.ico"/>--> + + <link rel="stylesheet" href="style/normalize.css"/> + <link rel="stylesheet" href="style/main.css"/> + <link rel="stylesheet" href="style/search.css"/> + <link rel="stylesheet" href="style/man.css"/> + </head> + <body> + <div id="main"> + <header> + <a id="logo" href="/"> + <h1> + <span id="logo-let">L</span> + <span id="logo-me">m</span> + <code id="logo-man">m</code> + <span id="logo-that">t</span> + <span id="logo-for">F</span> + <span id="logo-you">y</span> + </h1> + <div id="logo-ver_wrap"> + <span id="logo-ver">BETA!</span> + </div> + </a> + <nav id="search_pane"> + <form> + <div id="query_wrap"> + <input id="query" type='searcg' value='<?=$query;?>' name='query' required/> + <button id="def" type='submit' value='man' name='action' class="btn-def" aria-hidden="true" tabindex="-1"></button> + <button id="mank" type='submit' value='apropos' name='action' title="apropos(1)">-k</button> + <button id="man" type='submit' value='man' name='action' title="Feeling lucky, punk?" class="btn-acc"> + <div id="query_icon"></div> + </button> + </div> + </form> + </nav> + <nav id="topnav"> + <a href="https://cabin.digital">Cabin</a> + <a href="#"><span id="topnav_icon"></span></a> + <button class="btn-acc">Man up</button> + </nav> + </header> + <section id="results"> +<?php + $found_man = false; + if($action === "man") + { + $arg_section = ""; + if(!empty($section)) + $arg_section = "-s ". escapeshellarg($section); + + $res = exec("man -M $manpath -T html -O fragment $arg_section " + . escapeshellarg($query), $lines, $ret); + if($ret === 0) + { + $url = "$root/?query=". urlencode($query) ."&section=1&action=lmmtfy"; + + echo "<nav id='lmmtfy'><div><div>"; + echo " <label for='lmmtfy_url'>LmmtFy URL</label></div>"; + echo " <textarea id='lmmtfy_url' wrap='off' rows='1' readonly>".$url."</textarea>"; + echo " <button id='lmmtfy_copy' class='jsonly'>Copy</button></div><nav>"; + echo "<article class='manpage'>". implode(PHP_EOL, $lines) ."</article>"; + echo "<script src='/js/copy.js'></script>"; + + $found_man = true; + } + } + + if(($action === "apropos") || !$found_man) + { + $res = exec("man -M $manpath -k " . escapeshellarg($query), $lines, $ret); + if($ret === 0) + { + $n = count($lines); + $s = $n > 1 ? "s" : ""; + echo "<p class='hint'> Found $n result$s</p>"; + + foreach($lines as $line) + { + $split = explode(") - ", $line); + $full = $split[0]; + $desc = $split[1]; + + $split = explode("(", $full); + $name = explode(",", $split[0])[0]; + $sect = strtolower(explode(",", $split[1])[0]); + + $url = "$root/search.php?query=". urlencode($name) ."§ion=". urlencode($sect) + ."&action=man"; + + echo '<dl>'; + echo " <dt><a href='".$url."'>$full)</a></dt>"; + echo " <dd>$desc</dd>"; + echo '</dl>'; + } + } + else echo "<p class='hint'> No results.</p>"; + } +?> + </section> + <footer> + <p class="center"> + Copyleft <span class="copyleft">©</span> 2024 + <a href="mailto:manup@cabin.digital">dweller</a> from + <a href="https://cabin.digital">cabin.digital</a>. + All Wrongs Reserved. + </p> + </footer> + </div> + </body> +</html> diff --git a/style/main.css b/style/main.css index f373e37..0f76c33 100644 --- a/style/main.css +++ b/style/main.css @@ -190,14 +190,14 @@ a:hover { text-decoration: underline; } font-size: 32pt; } -#gc-let { color: var(--logo-a); font-size: 46pt; } -#gc-me { color: var(--logo-b); } -#gc-man { color: var(--logo-c); font-family: fn-code-logo, monospace; font-size: 30pt; } -#gc-that { color: var(--logo-a); } -#gc-for { color: var(--logo-d); font-size: 38pt; } -#gc-you { color: var(--logo-b); display: inline-block; transform: rotate(-2.5deg); } +#logo-let { color: var(--logo-a); font-size: 46pt; } +#logo-me { color: var(--logo-b); } +#logo-man { color: var(--logo-c); font-family: fn-code-logo, monospace; font-size: 30pt; } +#logo-that { color: var(--logo-a); } +#logo-for { color: var(--logo-d); font-size: 38pt; } +#logo-you { color: var(--logo-b); display: inline-block; transform: rotate(-2.5deg); } -@keyframes verscale +@keyframes logo-ver_scale { 0%, 100% { @@ -211,13 +211,13 @@ a:hover { text-decoration: underline; } } } -#version_wrap +#log-ver_wrap { display: block; min-height: 30pt; } -#version +#logo-ver { display: block; float: right; @@ -227,7 +227,7 @@ a:hover { text-decoration: underline; } color: var(--fg); - animation: verscale 3.5s ease infinite; + animation: logo-ver_scale 3.5s ease infinite; } #search_pane @@ -344,6 +344,15 @@ button:focus, input[type=submit]:focus border: 1px solid var(--abtn-brdf); } +.btn-def +{ + width: 0 !important; + height: 0 !important; + padding: 0 !important; + border: 0 !important; + margin: 0 !important; +} + .hint { color: var(--fg-light); } .center { text-align: center; } diff --git a/style/man.css b/style/man.css index b804d45..ee0cfa9 100644 --- a/style/man.css +++ b/style/man.css @@ -10,7 +10,7 @@ margin-top: 3em; margin-bottom: 1em; - width: min(100% - 3rem, 10in); + width: min(100% - 5rem, 10in); } #lmmtfy diff --git a/style/search.css b/style/search.css index 8412b76..73ed99c 100644 --- a/style/search.css +++ b/style/search.css @@ -14,12 +14,12 @@ #logo { font-size: 1rem; } #logo > h1 { font-size: 1.5rem; } -#gc-let { font-size: 1.25em; } -#gc-me { font-size: 1em; } -#gc-man { font-size: 0.9em; } -#gc-that { font-size: 1em; } -#gc-for { font-size: 1.15em; } -#gc-you { font-size: 1em; } +#logo-let { font-size: 1.25em; } +#logo-me { font-size: 1em; } +#logo-man { font-size: 0.9em; } +#logo-that { font-size: 1em; } +#logo-for { font-size: 1.15em; } +#logo-you { font-size: 1em; } #main { @@ -97,7 +97,7 @@ margin: 3pt 0 0 0; } -@keyframes verscale +@keyframes logo-ver_scale { 0%, 100% { transform: rotate(-10deg); } 50% { transform: rotate( 10deg); } @@ -162,5 +162,5 @@ } #query_wrap { width: min(42rem, 95dvw); } - #version_wrap { min-height: 15pt; } + #logo-ver_wrap { min-height: 15pt; } } |