Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Switch away from classic (bubbling-only) event handling to simplify management of temporary handlers, and to have the ESC key listener use a priority (capturing) handler, to prevent any other keydown handlers or default actions for the ESC key while the panel is open. This does not change the compatibility test results summarized here: https://fossil-scm.org/forum/forumpost/f425a1756c. (IE8 halts JS processing at JSON.parse in antiRobotDefense, anyway.) Also, for non-compatible browsers, there's a new fallback to transform the hamburger button into a simple (non-scripted) link to the sitemap. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | js-hamburger-menu |
Files: | files | file ages | folders |
SHA1: | e3376829e211a3f2d4fc566619423a30 |
User & Date: | florian 2018-10-12 16:16:55 |
Context
2018-10-12
| ||
16:18 | For consistency, HTMLize another TH1 variable, though not sure if this is required, see https://fossil-scm.org/forum/forumpost/bc0b6ce4a1. check-in: 5677271a user: florian tags: js-hamburger-menu | |
16:16 | Switch away from classic (bubbling-only) event handling to simplify management of temporary handlers, and to have the ESC key listener use a priority (capturing) handler, to prevent any other keydown handlers or default actions for the ESC key while the panel is open. This does not change the compatibility test results summarized here: https://fossil-scm.org/forum/forumpost/f425a1756c. (IE8 halts JS processing at JSON.parse in antiRobotDefense, anyway.) Also, for non-compatible browsers, there's a new fallback to transform the hamburger button into a simple (non-scripted) link to the sitemap. check-in: e3376829 user: florian tags: js-hamburger-menu | |
2018-10-11
| ||
16:36 | Cancel the timer to remove the border of the hamburger menu panel after the closing animation, if the menu is closed and immediately reopened by double-clicking the hamburger button. check-in: c73deeb6 user: florian tags: js-hamburger-menu | |
Changes
Changes to skins/default/js.txt.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 .. 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 ... 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 ... 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
******************************************************************************* ** ** This file contains the JS code specific to the Fossil default skin. ** Currently, the only thing this does is handle clicks on its hamburger ** menu button. */ (function() { if (!document.getElementById("hbbtn")) return; // no hamburger button var panel = document.getElementById("hbdrop"); if (!panel) return; // site admin might've nuked it if (!panel.style) return; // shouldn't happen, but be sure var panelBorder = panel.style.border; var panelInitialized = false; // reset if browser window is resized var panelResetBorderTimerID = 0; // used to cancel post-animation tasks ................................................................................ // header.txt by setting the "data-anim-ms" attribute of the panel. var animMS = panel.getAttribute("data-anim-ms"); if (animMS === "0") animate = false; // disable animation if "data-anim-ms" === "0" else if (!animMS || animMS>>0 !== Number(animMS) || animMS < 0) animMS = 400; // set default if missing, empty, non-integer, or negative var originalEventHandlers = { }; // original event handlers to be restored // Calculate panel height despite its being hidden at call time. // Based on https://stackoverflow.com/a/29047447/142454 var panelHeight; // computed on first panel display function calculatePanelHeight() { // Clear the max-height CSS property in case the panel size is recalculated // after the browser window was resized. ................................................................................ } setTimeout(function() { panel.style.maxHeight = panelHeight; panel.style.border = panelBorder; }, 40); // 25ms is insufficient with Firefox 62 } panel.style.display = 'block'; originalEventHandlers.onkeydown = document.onkeydown; document.onkeydown = function(event) { event = event || window.event; var key = event.which || event.keyCode; if (key == 27) { panelToggle(true); } }; originalEventHandlers.onclick = document.onclick; document.onclick = function(event) { event = event || window.event; if (!panel.contains(event.target)) { panelToggle(true); //return false; // prevent default action (i.e. open clicked links) } }; } // Return true if the panel is showing. function panelShowing() { if (animate) { return panel.style.maxHeight == panelHeight; } else { ................................................................................ childElement = childElement.nextSibling; } return false; } // Reset the state of the panel to uninitialized if the browser window is // resized, so the dimensions are recalculated the next time it's opened. originalEventHandlers.onresize = window.onresize; window.onresize = function(event) { panelInitialized = false; if (originalEventHandlers.onresize) { originalEventHandlers.onresize.call(window,event); } }; // Click handler for the hamburger button. document.getElementById("hbbtn").onclick = function(event) { // Break the event handler chain, or the handler for document.onclick // (about to be installed) may already be triggered by the current event. if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; panelToggle(false); return false; // prevent browser from acting on <a> click }; function panelToggle(suppressAnimation) { if (panelShowing()) { document.onkeydown = originalEventHandlers.onkeydown; document.onclick = originalEventHandlers.onclick; // Transition back to hidden state. if (animate) { if (suppressAnimation) { var transition = panel.style.transition; panel.style.transition = ''; panel.style.maxHeight = '0'; panel.style.border = 'none'; |
> | > > > > > < < | > > > | | | | > | | | < > | | | > > > | < | | < < | < < > | < < < > | < | < < > < < > > < < > > |
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 .. 43 44 45 46 47 48 49 50 51 52 53 54 55 56 ... 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 ... 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
******************************************************************************* ** ** This file contains the JS code specific to the Fossil default skin. ** Currently, the only thing this does is handle clicks on its hamburger ** menu button. */ (function() { var hbButton = document.getElementById("hbbtn"); if (!hbButton) return; // no hamburger button if (!document.addEventListener) { // Turn the button into a link to the sitemap for incompatible browsers. hbButton.href = "$home/sitemap"; return; } var panel = document.getElementById("hbdrop"); if (!panel) return; // site admin might've nuked it if (!panel.style) return; // shouldn't happen, but be sure var panelBorder = panel.style.border; var panelInitialized = false; // reset if browser window is resized var panelResetBorderTimerID = 0; // used to cancel post-animation tasks ................................................................................ // header.txt by setting the "data-anim-ms" attribute of the panel. var animMS = panel.getAttribute("data-anim-ms"); if (animMS === "0") animate = false; // disable animation if "data-anim-ms" === "0" else if (!animMS || animMS>>0 !== Number(animMS) || animMS < 0) animMS = 400; // set default if missing, empty, non-integer, or negative // Calculate panel height despite its being hidden at call time. // Based on https://stackoverflow.com/a/29047447/142454 var panelHeight; // computed on first panel display function calculatePanelHeight() { // Clear the max-height CSS property in case the panel size is recalculated // after the browser window was resized. ................................................................................ } setTimeout(function() { panel.style.maxHeight = panelHeight; panel.style.border = panelBorder; }, 40); // 25ms is insufficient with Firefox 62 } panel.style.display = 'block'; document.addEventListener('keydown',panelKeydown,/* useCapture == */true); document.addEventListener('click',panelClick,false); } var panelKeydown = function(event) { event = event || window.event; var key = event.which || event.keyCode; if (key == 27) { event.stopPropagation(); // ignore other keydown handlers panelToggle(true); } }; var panelClick = function(event) { event = event || window.event; if (!panel.contains(event.target)) { // Call event.preventDefault() to have clicks outside the opened panel // just close the panel, and swallow clicks on links or form elements. //event.preventDefault(); panelToggle(true); } }; // Return true if the panel is showing. function panelShowing() { if (animate) { return panel.style.maxHeight == panelHeight; } else { ................................................................................ childElement = childElement.nextSibling; } return false; } // Reset the state of the panel to uninitialized if the browser window is // resized, so the dimensions are recalculated the next time it's opened. window.addEventListener('resize',function(event) { panelInitialized = false; },false); // Click handler for the hamburger button. hbButton.addEventListener('click',function(event) { // Break the event handler chain, or the handler for document → click // (about to be installed) may already be triggered by the current event. event.stopPropagation(); event.preventDefault(); // prevent browser from acting on <a> click panelToggle(false); },false); function panelToggle(suppressAnimation) { if (panelShowing()) { document.removeEventListener('keydown',panelKeydown,/* useCapture == */true); document.removeEventListener('click',panelClick,false); // Transition back to hidden state. if (animate) { if (suppressAnimation) { var transition = panel.style.transition; panel.style.transition = ''; panel.style.maxHeight = '0'; panel.style.border = 'none'; |