Fossil SCM

Allow the hamburger menu to be closed instantly by pressing ESC or by clicking outside. This is the patch initially submitted to [https://fossil-scm.org/forum/forumpost/2abe305c2d], with the interim changes incorporated.

florian 2018-10-11 16:36 UTC trunk
Commit a44fdd17de89debf29f3a940df02b18d40f4b746
1 file changed +48 -7
--- skins/default/js.txt
+++ skins/default/js.txt
@@ -28,10 +28,11 @@
2828
// We need this ugly calling form for old browsers that don't allow
2929
// panel.style.hasOwnProperty('transition'); catering to old browsers
3030
// is the whole point here.
3131
var animate = panel.style.transition !== null && (typeof(panel.style.transition) == "string");
3232
var animMS = 400;
33
+ var originalEventHandlers = { }; // original event handlers to be restored
3334
3435
// Calculate panel height despite its being hidden at call time.
3536
// Based on https://stackoverflow.com/a/29047447/142454
3637
var panelHeight; // computed on sitemap load
3738
function calculatePanelHeight() {
@@ -71,10 +72,26 @@
7172
}, 40); // 25ms is insufficient with Firefox 62
7273
}
7374
else {
7475
panel.style.display = 'block';
7576
}
77
+ originalEventHandlers.onkeydown = document.onkeydown;
78
+ document.onkeydown = function(event) {
79
+ event = event || window.event;
80
+ var key = event.which || event.keyCode;
81
+ if (key == 27) {
82
+ panelToggle(true);
83
+ }
84
+ };
85
+ originalEventHandlers.onclick = document.onclick;
86
+ document.onclick = function(event) {
87
+ event = event || window.event;
88
+ if (!panel.contains(event.target)) {
89
+ panelToggle(true);
90
+ //return false; // prevent default action (i.e. open clicked links)
91
+ }
92
+ };
7693
}
7794
7895
// Return true if the panel is showing.
7996
function panelShowing() {
8097
if (animate) {
@@ -85,20 +102,45 @@
85102
}
86103
}
87104
88105
// Click handler for the hamburger button.
89106
var needSitemapHTML = true;
90
- document.querySelector("div.mainmenu > a").onclick = function() {
107
+ document.querySelector("div.mainmenu > a").onclick = function(event) {
108
+ // Break the event handler chain, or the handler for document.onclick
109
+ // (about to be installed) may already be triggered by the current event.
110
+ if (event.stopPropagation)
111
+ event.stopPropagation();
112
+ else
113
+ event.cancelBubble = true;
114
+ panelToggle(false);
115
+ return false; // prevent browser from acting on <a> click
116
+ };
117
+ function panelToggle(suppressAnimation) {
91118
if (panelShowing()) {
119
+ document.onkeydown = originalEventHandlers.onkeydown;
120
+ document.onclick = originalEventHandlers.onclick;
92121
// Transition back to hidden state.
93122
if (animate) {
94
- panel.style.maxHeight = '0';
95
- setTimeout(function() {
96
- // Browsers show a 1px high border line when maxHeight == 0,
97
- // our "hidden" state, so hide the borders in that state, too.
123
+ if (suppressAnimation) {
124
+ var transition = window.getComputedStyle(panel).transition;
125
+ panel.style.transition = '';
126
+ panel.style.maxHeight = '0';
98127
panel.style.border = 'none';
99
- }, animMS);
128
+ setTimeout(function() {
129
+ // Make sure CSS transition won't take effect now, so restore it
130
+ // asynchronously. Outer variable 'transition' still valid here.
131
+ panel.style.transition = transition;
132
+ }, 40); // 25ms is insufficient with Firefox 62
133
+ }
134
+ else {
135
+ panel.style.maxHeight = '0';
136
+ setTimeout(function() {
137
+ // Browsers show a 1px high border line when maxHeight == 0,
138
+ // our "hidden" state, so hide the borders in that state, too.
139
+ panel.style.border = 'none';
140
+ }, animMS);
141
+ }
100142
}
101143
else {
102144
panel.style.display = 'none';
103145
}
104146
}
@@ -137,8 +179,7 @@
137179
xhr.send();
138180
}
139181
else {
140182
showPanel(); // just show what we built above
141183
}
142
- return false; // prevent browser from acting on <a> click
143184
}
144185
})();
145186
--- skins/default/js.txt
+++ skins/default/js.txt
@@ -28,10 +28,11 @@
28 // We need this ugly calling form for old browsers that don't allow
29 // panel.style.hasOwnProperty('transition'); catering to old browsers
30 // is the whole point here.
31 var animate = panel.style.transition !== null && (typeof(panel.style.transition) == "string");
32 var animMS = 400;
 
33
34 // Calculate panel height despite its being hidden at call time.
35 // Based on https://stackoverflow.com/a/29047447/142454
36 var panelHeight; // computed on sitemap load
37 function calculatePanelHeight() {
@@ -71,10 +72,26 @@
71 }, 40); // 25ms is insufficient with Firefox 62
72 }
73 else {
74 panel.style.display = 'block';
75 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76 }
77
78 // Return true if the panel is showing.
79 function panelShowing() {
80 if (animate) {
@@ -85,20 +102,45 @@
85 }
86 }
87
88 // Click handler for the hamburger button.
89 var needSitemapHTML = true;
90 document.querySelector("div.mainmenu > a").onclick = function() {
 
 
 
 
 
 
 
 
 
 
91 if (panelShowing()) {
 
 
92 // Transition back to hidden state.
93 if (animate) {
94 panel.style.maxHeight = '0';
95 setTimeout(function() {
96 // Browsers show a 1px high border line when maxHeight == 0,
97 // our "hidden" state, so hide the borders in that state, too.
98 panel.style.border = 'none';
99 }, animMS);
 
 
 
 
 
 
 
 
 
 
 
 
 
100 }
101 else {
102 panel.style.display = 'none';
103 }
104 }
@@ -137,8 +179,7 @@
137 xhr.send();
138 }
139 else {
140 showPanel(); // just show what we built above
141 }
142 return false; // prevent browser from acting on <a> click
143 }
144 })();
145
--- skins/default/js.txt
+++ skins/default/js.txt
@@ -28,10 +28,11 @@
28 // We need this ugly calling form for old browsers that don't allow
29 // panel.style.hasOwnProperty('transition'); catering to old browsers
30 // is the whole point here.
31 var animate = panel.style.transition !== null && (typeof(panel.style.transition) == "string");
32 var animMS = 400;
33 var originalEventHandlers = { }; // original event handlers to be restored
34
35 // Calculate panel height despite its being hidden at call time.
36 // Based on https://stackoverflow.com/a/29047447/142454
37 var panelHeight; // computed on sitemap load
38 function calculatePanelHeight() {
@@ -71,10 +72,26 @@
72 }, 40); // 25ms is insufficient with Firefox 62
73 }
74 else {
75 panel.style.display = 'block';
76 }
77 originalEventHandlers.onkeydown = document.onkeydown;
78 document.onkeydown = function(event) {
79 event = event || window.event;
80 var key = event.which || event.keyCode;
81 if (key == 27) {
82 panelToggle(true);
83 }
84 };
85 originalEventHandlers.onclick = document.onclick;
86 document.onclick = function(event) {
87 event = event || window.event;
88 if (!panel.contains(event.target)) {
89 panelToggle(true);
90 //return false; // prevent default action (i.e. open clicked links)
91 }
92 };
93 }
94
95 // Return true if the panel is showing.
96 function panelShowing() {
97 if (animate) {
@@ -85,20 +102,45 @@
102 }
103 }
104
105 // Click handler for the hamburger button.
106 var needSitemapHTML = true;
107 document.querySelector("div.mainmenu > a").onclick = function(event) {
108 // Break the event handler chain, or the handler for document.onclick
109 // (about to be installed) may already be triggered by the current event.
110 if (event.stopPropagation)
111 event.stopPropagation();
112 else
113 event.cancelBubble = true;
114 panelToggle(false);
115 return false; // prevent browser from acting on <a> click
116 };
117 function panelToggle(suppressAnimation) {
118 if (panelShowing()) {
119 document.onkeydown = originalEventHandlers.onkeydown;
120 document.onclick = originalEventHandlers.onclick;
121 // Transition back to hidden state.
122 if (animate) {
123 if (suppressAnimation) {
124 var transition = window.getComputedStyle(panel).transition;
125 panel.style.transition = '';
126 panel.style.maxHeight = '0';
127 panel.style.border = 'none';
128 setTimeout(function() {
129 // Make sure CSS transition won't take effect now, so restore it
130 // asynchronously. Outer variable 'transition' still valid here.
131 panel.style.transition = transition;
132 }, 40); // 25ms is insufficient with Firefox 62
133 }
134 else {
135 panel.style.maxHeight = '0';
136 setTimeout(function() {
137 // Browsers show a 1px high border line when maxHeight == 0,
138 // our "hidden" state, so hide the borders in that state, too.
139 panel.style.border = 'none';
140 }, animMS);
141 }
142 }
143 else {
144 panel.style.display = 'none';
145 }
146 }
@@ -137,8 +179,7 @@
179 xhr.send();
180 }
181 else {
182 showPanel(); // just show what we built above
183 }
 
184 }
185 })();
186

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button