I think I've gotten my changes to the js-info reader to a state where it
can be checked in. See attachment.
In addition to the a "Hide sidebar"/"Show sidebar" button (lower left),
there is also magic to handle narrows screen better, including auto-hide
of the sidebar.
* js/info.js: Add button to show/hide sidebar. Other polishing.
(Sidebar): Create show/hide button.
(on_click): Handle clicks on show/hide button.
Also automatically hide sidebar on click when narrow.
(Sidebar): Copy _href property when copying ToC.
* js/info.css: Various adjustments and tricks to make it work.
This is the DomTerm manual with some extra DomTerm css style tweaks.
https://per.bothner.com/tmp/DomTerm-txjs/
This is the same manual with just the default styling from info.css:
https://per.bothner.com/tmp/DomTerm-txjs-plain
Please try with different window sizes.
Suggestions/comments about either style appreciated.
--
--Per Bothner
[email protected] http://per.bothner.com/
diff --git a/js/info.css b/js/info.css
index b36a1a0bde..dd93097f9f 100644
--- a/js/info.css
+++ b/js/info.css
@@ -6,16 +6,23 @@ body.in-iframe, div[node]#index {
padding: 0px 0.5em 0px 1em;
}
-div[node] {
- left: 25%;
- width: 75%;
+#sub-pages {
box-sizing: border-box;
+ left: 25%; width: 75%;
height: auto;
top: 0pt;
bottom: 0pt;
position: absolute;
+}
+
+div[node] {
+ height: 100%;
overflow: auto;
}
+body[show-sidebar="no"] div#sub-pages {
+ left: 0px;
+ width: 100%;
+}
div[node][hidden] {
display: none;
@@ -26,6 +33,17 @@ body.in-iframe {
margin: 0px;
}
+div.toc-sidebar {
+ bottom: 2.8ex;
+}
+
+.sidebar-hider {
+ bottom: 0px;
+ height: 2.8ex;
+ position: absolute;
+ text-align: start;
+}
+
/* Iframed sub pages */
iframe.node {
width: 100%;
@@ -50,17 +68,37 @@ iframe.node {
#slider {
position: fixed;
top: 0em;
- right: 25%;
bottom: 0em;
- left: 0em;
height: 100%;
width: 25%;
- overflow: auto;
- border: none;
margin: 0px;
padding: 0px;
}
+#slider, body[show-sidebar="yes"] .sidebar-hider {
+ box-sizing: border-box;
+ left: 0em;
+}
+body[show-sidebar="yes"] .sidebar-hider {
+ width: 100%;
+}
+body[show-sidebar="no"] #slider {
+ width: 0px; /* so mouse events don't get captured */
+}
+body[show-sidebar="no"] .sidebar-hider {
+ width: auto;
+ position: fixed;
+ padding: 3px 1.2em 1px 0.8em;
+}
+
+body[show-sidebar="no"] div.toc-sidebar { display: none }
+
+div.toc-sidebar {
+ position: absolute;
+ top: 0px;
+ overflow: auto;
+}
+
div.toc-sidebar header {
font-size: xx-large;
}
@@ -175,3 +213,20 @@ table#keyboard-shortcuts th {
.echo-area {
bottom: 0;
}
+#slider {
+ background: #f0f0f0c0;
+}
+div.toc-sidebar nav, div.toc-sidebar header, .sidebar-hider {
+ background: #f0f0f0d0;
+}
+body[show-sidebar="yes"] .sidebar-hider {
+ border-width: thin 0px 0px 0px;
+}
+body[show-sidebar="no"] .sidebar-hider {
+ border-width: thin;
+}
+@media (max-width: 60em) {
+ div#sub-pages { left: 0px; width: 100% }
+ body[show-sidebar="yes"] div#slider {width: 20em }
+ div.logo img { max-width: 80%; width: 2em; }
+}
diff --git a/js/info.js b/js/info.js
index 75f6e0c774..9fc7cfc891 100644
--- a/js/info.js
+++ b/js/info.js
@@ -33,6 +33,8 @@
MAIN_ANCHORS: ["Top"],
WARNING_TIMEOUT: 3000,
SCREEN_MIN_WIDTH: 700,
+ SHOW_SIDEBAR_HTML: "<span>Show sidebar</span>",
+ HIDE_SIDEBAR_HTML: "<span>Hide sidebar</span>",
// hooks:
/** Define a function called after 'DOMContentLoaded' event in
@@ -55,6 +57,7 @@
@typedef {function (Action): void} Action_consumer
@type {{dispatch: Action_consumer, state?: any, listeners?: any[]}}. */
var store;
+ var show_sidebar_button;
/** Create a Store that calls its listeners at each state change.
@arg {function (Object, Action): Object} reducer
@@ -683,14 +686,28 @@
function
Sidebar (contents_node)
{
- this.element = document.createElement ("div");
+ this.element = document.createElement ("div"); // FIXME unneeded?
this.element.setAttribute ("id", "slider");
var div = document.createElement ("div");
div.classList.add ("toc-sidebar");
var toc = document.querySelector ("#SEC_Contents");
toc.remove ();
- contents_node.appendChild(toc.cloneNode(true));
+ // Like n.cloneNode, but also copy _href
+ function cloneNode(n)
+ {
+ let r = n.cloneNode(false);
+ for (let c = n.firstChild; c; c = c.nextSibling)
+ {
+ let d = cloneNode(c);
+ let h = c._href;
+ if (h)
+ d._href = h;
+ r.appendChild(d);
+ }
+ return r;
+ }
+ contents_node.appendChild(cloneNode(toc));
/* Remove table of contents header. */
toc = toc.querySelector(".contents"); // skip ToC header
@@ -707,6 +724,13 @@
div$.appendChild (nav);
div.appendChild (div$);
this.element.appendChild (div);
+
+ let hider = document.createElement ("button");
+ //let hider = document.createElement ("div");
+ hider.classList.add ("sidebar-hider");
+ hider.innerHTML = config.HIDE_SIDEBAR_HTML;
+ show_sidebar_button = hider;
+ this.element.appendChild(hider);
}
/* Render 'sidebar' according to STATE which is a new state. */
@@ -995,6 +1019,7 @@
fix_links (document.links);
add_icons ();
document.body.classList.add ("mainbar");
+ document.body.setAttribute("show-sidebar", "yes");
/* Move contents of <body> into a a fresh <div> to let the components
treat the index page like other iframe page. */
@@ -1375,7 +1400,9 @@
{
for (var target = event.target; target !== null; target = target.parentNode)
{
- if ((target instanceof Element) && target.matches ("a"))
+ if (! (target instanceof Element))
+ continue;
+ if (target.matches ("a"))
{
var href = link_href(target);
if (href && !absolute_url_p (href)
@@ -1387,12 +1414,34 @@
store.dispatch (actions.set_current_url (linkid));
event.preventDefault ();
event.stopPropagation ();
+ let body = document.body;
+ if (body.getAttribute("show-sidebar") == "yes"
+ && is_narrow_window ())
+ show_sidebar (false)
return;
}
}
+ if (target.matches (".sidebar-hider"))
+ {
+ let body = document.body;
+ let show = body.getAttribute("show-sidebar");
+ show_sidebar(show==="no");
+ }
}
}
+ // Only valid when showing sidebar.
+ function is_narrow_window ()
+ {
+ return document.body.firstChild.offsetLeft == 0;
+ }
+
+ function show_sidebar (show)
+ {
+ document.body.setAttribute("show-sidebar", show ? "yes" : "no");
+ show_sidebar_button.innerHTML = show ? config.HIDE_SIDEBAR_HTML : config.SHOW_SIDEBAR_HTML;
+ }
+
/** Handle unload events. */
function
on_unload ()
@@ -1971,12 +2020,14 @@
/* Until we have a responsive design implemented, fallback to basic
HTML navigation for small screen. */
+ /*
if (window.screen.availWidth < config.SCREEN_MIN_WIDTH)
{
window.onload =
error ("screen width is too small to display the table of content");
return;
}
+*/
register_polyfills ();
/* Let the config provided by the user mask the default one. */