Fossil SCM

Add some link-tester docs and tweak the resize handler to get a slightly better fit.

stephan 2025-06-20 14:37 trunk
Commit aef937dab525ca37e8c2867ddb6b54d77dc4cfc82601ff59b09944cc9f8f8016
--- test/link-tester.html
+++ test/link-tester.html
@@ -17,18 +17,17 @@
1717
padding: 0;
1818
display: flex;
1919
flex-direction: column;
2020
}
2121
header {
22
- margin: 0.5em 0.25em 0 0.25em;
23
- padding: 0;
22
+ margin: 0.5em 0 0 0;
23
+ padding: 0 1em 0 1em;
24
+ z-index: 1;
2425
}
2526
#controlWrapper {
2627
display: flex;
2728
flex-direction: row;
28
- z-index: 1;
29
- background: white /*do not bleed iframe through */;
3029
border-bottom: 2px dotted;
3130
padding-bottom: 0.5em;
3231
}
3332
#controlWrapper > button {
3433
flex-grow: 1;
3534
--- test/link-tester.html
+++ test/link-tester.html
@@ -17,18 +17,17 @@
17 padding: 0;
18 display: flex;
19 flex-direction: column;
20 }
21 header {
22 margin: 0.5em 0.25em 0 0.25em;
23 padding: 0;
 
24 }
25 #controlWrapper {
26 display: flex;
27 flex-direction: row;
28 z-index: 1;
29 background: white /*do not bleed iframe through */;
30 border-bottom: 2px dotted;
31 padding-bottom: 0.5em;
32 }
33 #controlWrapper > button {
34 flex-grow: 1;
35
--- test/link-tester.html
+++ test/link-tester.html
@@ -17,18 +17,17 @@
17 padding: 0;
18 display: flex;
19 flex-direction: column;
20 }
21 header {
22 margin: 0.5em 0 0 0;
23 padding: 0 1em 0 1em;
24 z-index: 1;
25 }
26 #controlWrapper {
27 display: flex;
28 flex-direction: row;
 
 
29 border-bottom: 2px dotted;
30 padding-bottom: 0.5em;
31 }
32 #controlWrapper > button {
33 flex-grow: 1;
34
--- test/link-tester.js
+++ test/link-tester.js
@@ -43,13 +43,10 @@
4343
//console.log(urlTop, aLoc);
4444
for( const o of eSelect.options ){
4545
o.value = urlTop + (o.value || o.innerText);
4646
}
4747
48
- const eBtnPrev = E('#btn-prev');
49
- const eBtnNext = E('#btn-next');
50
-
5148
const updateUrl = function(opt){
5249
if( opt ){
5350
let url = (opt.value || opt.innerText);
5451
eCurrentUrl.innerText = url.replace(urlTop,'');
5552
eCurrentUrl.setAttribute('href', url);
@@ -64,18 +61,21 @@
6461
eIframe.setAttribute('src', so.value || so.innerText);
6562
updateUrl(so);
6663
}
6764
});
6865
66
+ /** Select the entry at the given ndx and fire a change event. */
6967
const selectEntry = function(ndx){
7068
if( ndx>=0 ){
7169
eSelect.selectedIndex = ndx;
7270
eSelect.dispatchEvent(new Event('change',{target:eSelect}));
7371
}
7472
};
7573
76
- const cycleLink = function(dir){
74
+ /* Cycle to the next link in the list, accounting for separators and
75
+ wrapping around at either end. */
76
+ const cycleLink = function(dir/*<0 = prev, >0 = next*/){
7777
let n = eSelect.selectedIndex + dir;
7878
if( n < 0 ) n = eSelect.options.length-1;
7979
else if( n>=eSelect.options.length ){
8080
n = 0;
8181
}
@@ -87,12 +87,12 @@
8787
}else{
8888
selectEntry(n);
8989
}
9090
};
9191
92
- eBtnPrev.addEventListener('click', ()=>cycleLink(-1), false);
93
- eBtnNext.addEventListener('click', ()=>cycleLink(1), false);
92
+ E('#btn-prev').addEventListener('click', ()=>cycleLink(-1), false);
93
+ E('#btn-next').addEventListener('click', ()=>cycleLink(1), false);
9494
9595
/**
9696
We have to adjust the iframe's size dynamically to account for
9797
other widgets around it. iframes don't simply like to fill up all
9898
available space without some help. If #controlWrapper only
@@ -99,12 +99,12 @@
9999
contained the one SELECT element, CSS would be sufficient, but
100100
once we add text around it, #controlWrapper's size becomes
101101
unpredictable and we need JS to calculate it. We do this every
102102
time the window size changes.
103103
*/
104
- // Copied from fossil.dom.js
105104
const effectiveHeight = function f(e){
105
+ // Copied from fossil.dom.js
106106
if(!e) return 0;
107107
if(!f.measure){
108108
f.measure = function callee(e, depth){
109109
if(!e) return;
110110
const m = e.getBoundingClientRect();
@@ -126,12 +126,14 @@
126126
f.extra = 0;
127127
f.measure(e,0);
128128
return f.extra;
129129
};
130130
131
- // Copied from fossil.bootstrap.js
131
+ /* Helper for the window-resized event handler below, to avoid
132
+ handling the resize until after it's finished. */
132133
const debounce = function f(func, waitMs, immediate) {
134
+ // Copied from fossil.bootstrap.js
133135
var timeoutId;
134136
if(!waitMs) waitMs = f.$defaultDelay;
135137
return function() {
136138
const context = this, args = Array.prototype.slice.call(arguments);
137139
const later = function() {
@@ -143,28 +145,26 @@
143145
timeoutId = setTimeout(later, waitMs);
144146
if(callNow) func.apply(context, args);
145147
};
146148
};
147149
150
+ /**
151
+ Resize eConstrained (the ifame element) so that it fits within
152
+ the page space not occupied by the list of elements eToAvoid.
153
+ */
148154
const ForceResizeKludge = (function(eToAvoid, eConstrained){
149155
const resized = function f(){
150156
if( f.$disabled ) return;
151157
const wh = window.innerHeight;
152158
let ht;
153159
let extra = 0;
154160
eToAvoid.forEach((e)=>e ? extra += effectiveHeight(e) : false);
155161
ht = wh - extra;
156162
if( ht < 100 ) ht = 100;
157
- eConstrained.style.top = 'calc('+extra+'px + 1.5em)';
163
+ eConstrained.style.top = 'calc('+extra+'px + 2em)';
158164
eConstrained.style.height =
159
- eConstrained.style.maxHeight = [
160
- "calc(", ht, "px",
161
- " - 0.65em"/*fudge value*/,")"
162
- /* ^^^^ hypothetically not needed, but both Chrome/FF on
163
- Linux will force scrollbars on the body if this value is
164
- too small; current value is empirically selected. */
165
- ].join('');
165
+ eConstrained.style.maxHeight = "calc("+ ht+ "px - 2em)";
166166
};
167167
resized.$disabled = true/* gets deleted later */;
168168
window.addEventListener('resize', debounce(resized, 250), false);
169169
return resized;
170170
})(
171171
--- test/link-tester.js
+++ test/link-tester.js
@@ -43,13 +43,10 @@
43 //console.log(urlTop, aLoc);
44 for( const o of eSelect.options ){
45 o.value = urlTop + (o.value || o.innerText);
46 }
47
48 const eBtnPrev = E('#btn-prev');
49 const eBtnNext = E('#btn-next');
50
51 const updateUrl = function(opt){
52 if( opt ){
53 let url = (opt.value || opt.innerText);
54 eCurrentUrl.innerText = url.replace(urlTop,'');
55 eCurrentUrl.setAttribute('href', url);
@@ -64,18 +61,21 @@
64 eIframe.setAttribute('src', so.value || so.innerText);
65 updateUrl(so);
66 }
67 });
68
 
69 const selectEntry = function(ndx){
70 if( ndx>=0 ){
71 eSelect.selectedIndex = ndx;
72 eSelect.dispatchEvent(new Event('change',{target:eSelect}));
73 }
74 };
75
76 const cycleLink = function(dir){
 
 
77 let n = eSelect.selectedIndex + dir;
78 if( n < 0 ) n = eSelect.options.length-1;
79 else if( n>=eSelect.options.length ){
80 n = 0;
81 }
@@ -87,12 +87,12 @@
87 }else{
88 selectEntry(n);
89 }
90 };
91
92 eBtnPrev.addEventListener('click', ()=>cycleLink(-1), false);
93 eBtnNext.addEventListener('click', ()=>cycleLink(1), false);
94
95 /**
96 We have to adjust the iframe's size dynamically to account for
97 other widgets around it. iframes don't simply like to fill up all
98 available space without some help. If #controlWrapper only
@@ -99,12 +99,12 @@
99 contained the one SELECT element, CSS would be sufficient, but
100 once we add text around it, #controlWrapper's size becomes
101 unpredictable and we need JS to calculate it. We do this every
102 time the window size changes.
103 */
104 // Copied from fossil.dom.js
105 const effectiveHeight = function f(e){
 
106 if(!e) return 0;
107 if(!f.measure){
108 f.measure = function callee(e, depth){
109 if(!e) return;
110 const m = e.getBoundingClientRect();
@@ -126,12 +126,14 @@
126 f.extra = 0;
127 f.measure(e,0);
128 return f.extra;
129 };
130
131 // Copied from fossil.bootstrap.js
 
132 const debounce = function f(func, waitMs, immediate) {
 
133 var timeoutId;
134 if(!waitMs) waitMs = f.$defaultDelay;
135 return function() {
136 const context = this, args = Array.prototype.slice.call(arguments);
137 const later = function() {
@@ -143,28 +145,26 @@
143 timeoutId = setTimeout(later, waitMs);
144 if(callNow) func.apply(context, args);
145 };
146 };
147
 
 
 
 
148 const ForceResizeKludge = (function(eToAvoid, eConstrained){
149 const resized = function f(){
150 if( f.$disabled ) return;
151 const wh = window.innerHeight;
152 let ht;
153 let extra = 0;
154 eToAvoid.forEach((e)=>e ? extra += effectiveHeight(e) : false);
155 ht = wh - extra;
156 if( ht < 100 ) ht = 100;
157 eConstrained.style.top = 'calc('+extra+'px + 1.5em)';
158 eConstrained.style.height =
159 eConstrained.style.maxHeight = [
160 "calc(", ht, "px",
161 " - 0.65em"/*fudge value*/,")"
162 /* ^^^^ hypothetically not needed, but both Chrome/FF on
163 Linux will force scrollbars on the body if this value is
164 too small; current value is empirically selected. */
165 ].join('');
166 };
167 resized.$disabled = true/* gets deleted later */;
168 window.addEventListener('resize', debounce(resized, 250), false);
169 return resized;
170 })(
171
--- test/link-tester.js
+++ test/link-tester.js
@@ -43,13 +43,10 @@
43 //console.log(urlTop, aLoc);
44 for( const o of eSelect.options ){
45 o.value = urlTop + (o.value || o.innerText);
46 }
47
 
 
 
48 const updateUrl = function(opt){
49 if( opt ){
50 let url = (opt.value || opt.innerText);
51 eCurrentUrl.innerText = url.replace(urlTop,'');
52 eCurrentUrl.setAttribute('href', url);
@@ -64,18 +61,21 @@
61 eIframe.setAttribute('src', so.value || so.innerText);
62 updateUrl(so);
63 }
64 });
65
66 /** Select the entry at the given ndx and fire a change event. */
67 const selectEntry = function(ndx){
68 if( ndx>=0 ){
69 eSelect.selectedIndex = ndx;
70 eSelect.dispatchEvent(new Event('change',{target:eSelect}));
71 }
72 };
73
74 /* Cycle to the next link in the list, accounting for separators and
75 wrapping around at either end. */
76 const cycleLink = function(dir/*<0 = prev, >0 = next*/){
77 let n = eSelect.selectedIndex + dir;
78 if( n < 0 ) n = eSelect.options.length-1;
79 else if( n>=eSelect.options.length ){
80 n = 0;
81 }
@@ -87,12 +87,12 @@
87 }else{
88 selectEntry(n);
89 }
90 };
91
92 E('#btn-prev').addEventListener('click', ()=>cycleLink(-1), false);
93 E('#btn-next').addEventListener('click', ()=>cycleLink(1), false);
94
95 /**
96 We have to adjust the iframe's size dynamically to account for
97 other widgets around it. iframes don't simply like to fill up all
98 available space without some help. If #controlWrapper only
@@ -99,12 +99,12 @@
99 contained the one SELECT element, CSS would be sufficient, but
100 once we add text around it, #controlWrapper's size becomes
101 unpredictable and we need JS to calculate it. We do this every
102 time the window size changes.
103 */
 
104 const effectiveHeight = function f(e){
105 // Copied from fossil.dom.js
106 if(!e) return 0;
107 if(!f.measure){
108 f.measure = function callee(e, depth){
109 if(!e) return;
110 const m = e.getBoundingClientRect();
@@ -126,12 +126,14 @@
126 f.extra = 0;
127 f.measure(e,0);
128 return f.extra;
129 };
130
131 /* Helper for the window-resized event handler below, to avoid
132 handling the resize until after it's finished. */
133 const debounce = function f(func, waitMs, immediate) {
134 // Copied from fossil.bootstrap.js
135 var timeoutId;
136 if(!waitMs) waitMs = f.$defaultDelay;
137 return function() {
138 const context = this, args = Array.prototype.slice.call(arguments);
139 const later = function() {
@@ -143,28 +145,26 @@
145 timeoutId = setTimeout(later, waitMs);
146 if(callNow) func.apply(context, args);
147 };
148 };
149
150 /**
151 Resize eConstrained (the ifame element) so that it fits within
152 the page space not occupied by the list of elements eToAvoid.
153 */
154 const ForceResizeKludge = (function(eToAvoid, eConstrained){
155 const resized = function f(){
156 if( f.$disabled ) return;
157 const wh = window.innerHeight;
158 let ht;
159 let extra = 0;
160 eToAvoid.forEach((e)=>e ? extra += effectiveHeight(e) : false);
161 ht = wh - extra;
162 if( ht < 100 ) ht = 100;
163 eConstrained.style.top = 'calc('+extra+'px + 2em)';
164 eConstrained.style.height =
165 eConstrained.style.maxHeight = "calc("+ ht+ "px - 2em)";
 
 
 
 
 
 
166 };
167 resized.$disabled = true/* gets deleted later */;
168 window.addEventListener('resize', debounce(resized, 250), false);
169 return resized;
170 })(
171
--- test/link-tester.json
+++ test/link-tester.json
@@ -9,7 +9,8 @@
99
1010
"Admin",
1111
["Users", "/setup_ulist"],
1212
1313
"Misc.",
14
- ["/skins"]
14
+ ["/skins"],
15
+ ["/chat"]
1516
]
1617
--- test/link-tester.json
+++ test/link-tester.json
@@ -9,7 +9,8 @@
9
10 "Admin",
11 ["Users", "/setup_ulist"],
12
13 "Misc.",
14 ["/skins"]
 
15 ]
16
--- test/link-tester.json
+++ test/link-tester.json
@@ -9,7 +9,8 @@
9
10 "Admin",
11 ["Users", "/setup_ulist"],
12
13 "Misc.",
14 ["/skins"],
15 ["/chat"]
16 ]
17

Keyboard Shortcuts

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