texinfo-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

branch master updated: * js/info.js: Add button to show/hide sidebar. Ot


From: Per Bothner
Subject: branch master updated: * js/info.js: Add button to show/hide sidebar. Other polishing.
Date: Wed, 24 Feb 2021 15:36:16 -0500

This is an automated email from the git hooks/post-receive script.

bothner pushed a commit to branch master
in repository texinfo.

The following commit(s) were added to refs/heads/master by this push:
     new 3338e66  * js/info.js: Add button to show/hide sidebar.  Other 
polishing.
3338e66 is described below

commit 3338e66611c4cb9460d9db20bd675b75521314e7
Author: Per Bothner <per@bothner.com>
AuthorDate: Wed Feb 24 12:35:37 2021 -0800

    * 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.
---
 ChangeLog   | 15 +++++++++++---
 js/info.css | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 js/info.js  | 57 +++++++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 128 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 449e556..157f6aa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2021-02-24  Per Bothner  <per@bothner.com>
+
+       * 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.
+
 2021-02-23  Patrice Dumas  <pertusus@free.fr>
 
        * tp/Texinfo/Common.pm (%default_customization_values),
@@ -8,12 +17,12 @@
        * tp/Texinfo/ParserNonXS.pm (%parser_default_configuration),
        * tp/texi2any.pl:
        split %default_customization_values in two, as
-       %default_parser_customization_values and 
+       %default_parser_customization_values and
        %default_structure_customization_values differentiating
        parser options and options for Texinfo::Structuring.
        * tp/Texinfo/Structuring.pm (_complete_check_menus_directions),
        (complete_node_tree_with_menus, nodes_tree),
-       * tp/t/test_utils.pl (test), tp/texi2any.pl: rename 
+       * tp/t/test_utils.pl (test), tp/texi2any.pl: rename
        _complete_check_menus_directions() as complete_node_tree_with_menus(),
        call _check_referenced_nodes in that function and do not call
        _complete_check_menus_directions in nodes_tree.
@@ -31,7 +40,7 @@
        * configure.ac, util/texi2dvi, util/texi2pdf: Version.
        * info/info.c (main), install-info/install-info.c (main): 2021
        * README-hacking: Edit release instructions.
-       
+
        * info/dir.c (dir_entry_of_infodir): Do not call
        info_check_compressed with a null argument.
 
diff --git a/js/info.css b/js/info.css
index b36a1a0..dd93097 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 75f6e0c..9fc7cfc 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.  */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]