Fossil SCM

Merged in trunk for latest /chat features.

stephan 2021-10-05 18:44 markdown-tagrefs merge
Commit 49689e1c70ca5a919dffac94ebb190a4125e100c181ef7969ac52fe61d9d6826
--- src/fossil.page.chat.js
+++ src/fossil.page.chat.js
@@ -63,61 +63,69 @@
6363
/* This can inadvertently influence our flexbox layouts, so move
6464
it out of the way. */
6565
D.append(document.body,dbg);
6666
}
6767
})();
68
- const ForceResizeKludge = 0 ? function(){} : (function f(){
68
+ const ForceResizeKludge = (function(){
6969
/* Workaround for Safari mayhem regarding use of vh CSS units....
7070
We tried to use vh units to set the content area size for the
7171
chat layout, but Safari chokes on that, so we calculate that
7272
height here: 85% when in "normal" mode and 95% in chat-only
7373
mode. Larger than ~95% is too big for Firefox on Android,
74
- causing the input area to move off-screen. */
75
- if(!f.elemsToCount){
76
- f.elemsToCount = [
77
- document.querySelector('body > div.header'),
78
- document.querySelector('body > div.mainmenu'),
79
- document.querySelector('body > #hbdrop'),
80
- document.querySelector('body > div.footer')
81
- ];
82
- f.contentArea = E1('div.content');
83
- }
84
- const resized = function(){
74
+ causing the input area to move off-screen.
75
+
76
+ While we're here, we also use this to cap the max-height
77
+ of the input field so that pasting huge text does not scroll
78
+ the upper area of the input widget off-screen. */
79
+ const elemsToCount = [
80
+ document.querySelector('body > div.header'),
81
+ document.querySelector('body > div.mainmenu'),
82
+ document.querySelector('body > #hbdrop'),
83
+ document.querySelector('body > div.footer')
84
+ ];
85
+ const contentArea = E1('div.content');
86
+ const resized = function f(){
87
+ if(f.$disabled) return;
8588
const wh = window.innerHeight,
8689
com = document.body.classList.contains('chat-only-mode');
8790
var ht;
8891
var extra = 0;
8992
if(com){
9093
ht = wh;
9194
}else{
92
- f.elemsToCount.forEach((e)=>e ? extra += D.effectiveHeight(e) : false);
95
+ elemsToCount.forEach((e)=>e ? extra += D.effectiveHeight(e) : false);
9396
ht = wh - extra;
9497
}
95
- f.contentArea.style.height =
96
- f.contentArea.style.maxHeight = [
98
+ f.chat.e.inputField.style.maxHeight = (ht/2)+"px";
99
+ /* ^^^^ this is a middle ground between having no size cap
100
+ on the input field and having a fixed arbitrary cap. */;
101
+ contentArea.style.height =
102
+ contentArea.style.maxHeight = [
97103
"calc(", (ht>=100 ? ht : 100), "px",
98104
" - 0.75em"/*fudge value*/,")"
99105
/* ^^^^ hypothetically not needed, but both Chrome/FF on
100106
Linux will force scrollbars on the body if this value is
101107
too small (<0.75em in my tests). */
102108
].join('');
103109
if(false){
104110
console.debug("resized.",wh, extra, ht,
105
- window.getComputedStyle(f.contentArea).maxHeight,
106
- f.contentArea);
111
+ window.getComputedStyle(contentArea).maxHeight,
112
+ contentArea);
113
+ console.debug("Set input max height to: ",
114
+ f.chat.e.inputField.style.maxHeight);
107115
}
108116
};
109117
var doit;
110118
window.addEventListener('resize',function(ev){
111119
clearTimeout(doit);
112120
doit = setTimeout(resized, 100);
113121
}, false);
114
- resized();
115122
return resized;
116123
})();
124
+ ForceResizeKludge.$disabled = true/*gets deleted when setup is finished*/;
117125
fossil.FRK = ForceResizeKludge/*for debugging*/;
118
- const Chat = (function(){
126
+ const Chat = ForceResizeKludge.chat = (function(){
119127
const cs = {
120128
verboseErrors: false /* if true then certain, mostly extraneous,
121129
error messages may be sent to the console. */,
122130
e:{/*map of certain DOM elements.*/
123131
messageInjectPoint: E1('#message-inject-point'),
@@ -1168,18 +1176,33 @@
11681176
self.hide();
11691177
Chat.deleteMessage(eMsg);
11701178
}
11711179
});
11721180
}
1181
+ const toolbar3 = D.addClass(D.div(), 'toolbar');
1182
+ D.append(this.e, toolbar3);
1183
+ D.append(toolbar3, D.button(
1184
+ "Locally remove all previous messages",
1185
+ function(){
1186
+ self.hide();
1187
+ Chat.mnMsg = +eMsg.dataset.msgid;
1188
+ var e = eMsg.previousElementSibling;
1189
+ while(e && e.classList.contains('message-widget')){
1190
+ const n = e.previousElementSibling;
1191
+ D.remove(e);
1192
+ e = n;
1193
+ }
1194
+ eMsg.scrollIntoView();
1195
+ }
1196
+ ));
11731197
const toolbar2 = D.addClass(D.div(), 'toolbar');
11741198
D.append(this.e, toolbar2);
1175
- const btnToggleText = D.button("Toggle text mode");
1176
- btnToggleText.addEventListener('click', function(){
1177
- self.hide();
1178
- Chat.toggleTextMode(eMsg);
1179
- },false);
1180
- D.append(toolbar2, btnToggleText);
1199
+ D.append(toolbar2, D.button(
1200
+ "Toggle text mode", function(){
1201
+ self.hide();
1202
+ Chat.toggleTextMode(eMsg);
1203
+ }));
11811204
if(eMsg.dataset.xfrom){
11821205
/* Add a link to the /timeline filtered on this user. */
11831206
const timelineLink = D.attr(
11841207
D.a(F.repoUrl('timeline',{
11851208
u: eMsg.dataset.xfrom,
@@ -1992,9 +2015,11 @@
19922015
const flip = (ev)=>Chat.animate(ev.target,'anim-flip-h');
19932016
document.querySelectorAll('#chat-buttons-wrapper .cbutton').forEach(function(e){
19942017
e.addEventListener('click',flip, false);
19952018
});
19962019
}
1997
- setTimeout( ()=>Chat.inputFocus(), 0 );
2020
+ delete ForceResizeKludge.$disabled;
2021
+ ForceResizeKludge();
19982022
Chat.animate.$disabled = false;
2023
+ setTimeout( ()=>Chat.inputFocus(), 0 );
19992024
F.page.chat = Chat/* enables testing the APIs via the dev tools */;
20002025
});
20012026
--- src/fossil.page.chat.js
+++ src/fossil.page.chat.js
@@ -63,61 +63,69 @@
63 /* This can inadvertently influence our flexbox layouts, so move
64 it out of the way. */
65 D.append(document.body,dbg);
66 }
67 })();
68 const ForceResizeKludge = 0 ? function(){} : (function f(){
69 /* Workaround for Safari mayhem regarding use of vh CSS units....
70 We tried to use vh units to set the content area size for the
71 chat layout, but Safari chokes on that, so we calculate that
72 height here: 85% when in "normal" mode and 95% in chat-only
73 mode. Larger than ~95% is too big for Firefox on Android,
74 causing the input area to move off-screen. */
75 if(!f.elemsToCount){
76 f.elemsToCount = [
77 document.querySelector('body > div.header'),
78 document.querySelector('body > div.mainmenu'),
79 document.querySelector('body > #hbdrop'),
80 document.querySelector('body > div.footer')
81 ];
82 f.contentArea = E1('div.content');
83 }
84 const resized = function(){
 
 
 
85 const wh = window.innerHeight,
86 com = document.body.classList.contains('chat-only-mode');
87 var ht;
88 var extra = 0;
89 if(com){
90 ht = wh;
91 }else{
92 f.elemsToCount.forEach((e)=>e ? extra += D.effectiveHeight(e) : false);
93 ht = wh - extra;
94 }
95 f.contentArea.style.height =
96 f.contentArea.style.maxHeight = [
 
 
 
97 "calc(", (ht>=100 ? ht : 100), "px",
98 " - 0.75em"/*fudge value*/,")"
99 /* ^^^^ hypothetically not needed, but both Chrome/FF on
100 Linux will force scrollbars on the body if this value is
101 too small (<0.75em in my tests). */
102 ].join('');
103 if(false){
104 console.debug("resized.",wh, extra, ht,
105 window.getComputedStyle(f.contentArea).maxHeight,
106 f.contentArea);
 
 
107 }
108 };
109 var doit;
110 window.addEventListener('resize',function(ev){
111 clearTimeout(doit);
112 doit = setTimeout(resized, 100);
113 }, false);
114 resized();
115 return resized;
116 })();
 
117 fossil.FRK = ForceResizeKludge/*for debugging*/;
118 const Chat = (function(){
119 const cs = {
120 verboseErrors: false /* if true then certain, mostly extraneous,
121 error messages may be sent to the console. */,
122 e:{/*map of certain DOM elements.*/
123 messageInjectPoint: E1('#message-inject-point'),
@@ -1168,18 +1176,33 @@
1168 self.hide();
1169 Chat.deleteMessage(eMsg);
1170 }
1171 });
1172 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1173 const toolbar2 = D.addClass(D.div(), 'toolbar');
1174 D.append(this.e, toolbar2);
1175 const btnToggleText = D.button("Toggle text mode");
1176 btnToggleText.addEventListener('click', function(){
1177 self.hide();
1178 Chat.toggleTextMode(eMsg);
1179 },false);
1180 D.append(toolbar2, btnToggleText);
1181 if(eMsg.dataset.xfrom){
1182 /* Add a link to the /timeline filtered on this user. */
1183 const timelineLink = D.attr(
1184 D.a(F.repoUrl('timeline',{
1185 u: eMsg.dataset.xfrom,
@@ -1992,9 +2015,11 @@
1992 const flip = (ev)=>Chat.animate(ev.target,'anim-flip-h');
1993 document.querySelectorAll('#chat-buttons-wrapper .cbutton').forEach(function(e){
1994 e.addEventListener('click',flip, false);
1995 });
1996 }
1997 setTimeout( ()=>Chat.inputFocus(), 0 );
 
1998 Chat.animate.$disabled = false;
 
1999 F.page.chat = Chat/* enables testing the APIs via the dev tools */;
2000 });
2001
--- src/fossil.page.chat.js
+++ src/fossil.page.chat.js
@@ -63,61 +63,69 @@
63 /* This can inadvertently influence our flexbox layouts, so move
64 it out of the way. */
65 D.append(document.body,dbg);
66 }
67 })();
68 const ForceResizeKludge = (function(){
69 /* Workaround for Safari mayhem regarding use of vh CSS units....
70 We tried to use vh units to set the content area size for the
71 chat layout, but Safari chokes on that, so we calculate that
72 height here: 85% when in "normal" mode and 95% in chat-only
73 mode. Larger than ~95% is too big for Firefox on Android,
74 causing the input area to move off-screen.
75
76 While we're here, we also use this to cap the max-height
77 of the input field so that pasting huge text does not scroll
78 the upper area of the input widget off-screen. */
79 const elemsToCount = [
80 document.querySelector('body > div.header'),
81 document.querySelector('body > div.mainmenu'),
82 document.querySelector('body > #hbdrop'),
83 document.querySelector('body > div.footer')
84 ];
85 const contentArea = E1('div.content');
86 const resized = function f(){
87 if(f.$disabled) return;
88 const wh = window.innerHeight,
89 com = document.body.classList.contains('chat-only-mode');
90 var ht;
91 var extra = 0;
92 if(com){
93 ht = wh;
94 }else{
95 elemsToCount.forEach((e)=>e ? extra += D.effectiveHeight(e) : false);
96 ht = wh - extra;
97 }
98 f.chat.e.inputField.style.maxHeight = (ht/2)+"px";
99 /* ^^^^ this is a middle ground between having no size cap
100 on the input field and having a fixed arbitrary cap. */;
101 contentArea.style.height =
102 contentArea.style.maxHeight = [
103 "calc(", (ht>=100 ? ht : 100), "px",
104 " - 0.75em"/*fudge value*/,")"
105 /* ^^^^ hypothetically not needed, but both Chrome/FF on
106 Linux will force scrollbars on the body if this value is
107 too small (<0.75em in my tests). */
108 ].join('');
109 if(false){
110 console.debug("resized.",wh, extra, ht,
111 window.getComputedStyle(contentArea).maxHeight,
112 contentArea);
113 console.debug("Set input max height to: ",
114 f.chat.e.inputField.style.maxHeight);
115 }
116 };
117 var doit;
118 window.addEventListener('resize',function(ev){
119 clearTimeout(doit);
120 doit = setTimeout(resized, 100);
121 }, false);
 
122 return resized;
123 })();
124 ForceResizeKludge.$disabled = true/*gets deleted when setup is finished*/;
125 fossil.FRK = ForceResizeKludge/*for debugging*/;
126 const Chat = ForceResizeKludge.chat = (function(){
127 const cs = {
128 verboseErrors: false /* if true then certain, mostly extraneous,
129 error messages may be sent to the console. */,
130 e:{/*map of certain DOM elements.*/
131 messageInjectPoint: E1('#message-inject-point'),
@@ -1168,18 +1176,33 @@
1176 self.hide();
1177 Chat.deleteMessage(eMsg);
1178 }
1179 });
1180 }
1181 const toolbar3 = D.addClass(D.div(), 'toolbar');
1182 D.append(this.e, toolbar3);
1183 D.append(toolbar3, D.button(
1184 "Locally remove all previous messages",
1185 function(){
1186 self.hide();
1187 Chat.mnMsg = +eMsg.dataset.msgid;
1188 var e = eMsg.previousElementSibling;
1189 while(e && e.classList.contains('message-widget')){
1190 const n = e.previousElementSibling;
1191 D.remove(e);
1192 e = n;
1193 }
1194 eMsg.scrollIntoView();
1195 }
1196 ));
1197 const toolbar2 = D.addClass(D.div(), 'toolbar');
1198 D.append(this.e, toolbar2);
1199 D.append(toolbar2, D.button(
1200 "Toggle text mode", function(){
1201 self.hide();
1202 Chat.toggleTextMode(eMsg);
1203 }));
 
1204 if(eMsg.dataset.xfrom){
1205 /* Add a link to the /timeline filtered on this user. */
1206 const timelineLink = D.attr(
1207 D.a(F.repoUrl('timeline',{
1208 u: eMsg.dataset.xfrom,
@@ -1992,9 +2015,11 @@
2015 const flip = (ev)=>Chat.animate(ev.target,'anim-flip-h');
2016 document.querySelectorAll('#chat-buttons-wrapper .cbutton').forEach(function(e){
2017 e.addEventListener('click',flip, false);
2018 });
2019 }
2020 delete ForceResizeKludge.$disabled;
2021 ForceResizeKludge();
2022 Chat.animate.$disabled = false;
2023 setTimeout( ()=>Chat.inputFocus(), 0 );
2024 F.page.chat = Chat/* enables testing the APIs via the dev tools */;
2025 });
2026
--- src/fossil.page.chat.js
+++ src/fossil.page.chat.js
@@ -63,61 +63,69 @@
6363
/* This can inadvertently influence our flexbox layouts, so move
6464
it out of the way. */
6565
D.append(document.body,dbg);
6666
}
6767
})();
68
- const ForceResizeKludge = 0 ? function(){} : (function f(){
68
+ const ForceResizeKludge = (function(){
6969
/* Workaround for Safari mayhem regarding use of vh CSS units....
7070
We tried to use vh units to set the content area size for the
7171
chat layout, but Safari chokes on that, so we calculate that
7272
height here: 85% when in "normal" mode and 95% in chat-only
7373
mode. Larger than ~95% is too big for Firefox on Android,
74
- causing the input area to move off-screen. */
75
- if(!f.elemsToCount){
76
- f.elemsToCount = [
77
- document.querySelector('body > div.header'),
78
- document.querySelector('body > div.mainmenu'),
79
- document.querySelector('body > #hbdrop'),
80
- document.querySelector('body > div.footer')
81
- ];
82
- f.contentArea = E1('div.content');
83
- }
84
- const resized = function(){
74
+ causing the input area to move off-screen.
75
+
76
+ While we're here, we also use this to cap the max-height
77
+ of the input field so that pasting huge text does not scroll
78
+ the upper area of the input widget off-screen. */
79
+ const elemsToCount = [
80
+ document.querySelector('body > div.header'),
81
+ document.querySelector('body > div.mainmenu'),
82
+ document.querySelector('body > #hbdrop'),
83
+ document.querySelector('body > div.footer')
84
+ ];
85
+ const contentArea = E1('div.content');
86
+ const resized = function f(){
87
+ if(f.$disabled) return;
8588
const wh = window.innerHeight,
8689
com = document.body.classList.contains('chat-only-mode');
8790
var ht;
8891
var extra = 0;
8992
if(com){
9093
ht = wh;
9194
}else{
92
- f.elemsToCount.forEach((e)=>e ? extra += D.effectiveHeight(e) : false);
95
+ elemsToCount.forEach((e)=>e ? extra += D.effectiveHeight(e) : false);
9396
ht = wh - extra;
9497
}
95
- f.contentArea.style.height =
96
- f.contentArea.style.maxHeight = [
98
+ f.chat.e.inputField.style.maxHeight = (ht/2)+"px";
99
+ /* ^^^^ this is a middle ground between having no size cap
100
+ on the input field and having a fixed arbitrary cap. */;
101
+ contentArea.style.height =
102
+ contentArea.style.maxHeight = [
97103
"calc(", (ht>=100 ? ht : 100), "px",
98104
" - 0.75em"/*fudge value*/,")"
99105
/* ^^^^ hypothetically not needed, but both Chrome/FF on
100106
Linux will force scrollbars on the body if this value is
101107
too small (<0.75em in my tests). */
102108
].join('');
103109
if(false){
104110
console.debug("resized.",wh, extra, ht,
105
- window.getComputedStyle(f.contentArea).maxHeight,
106
- f.contentArea);
111
+ window.getComputedStyle(contentArea).maxHeight,
112
+ contentArea);
113
+ console.debug("Set input max height to: ",
114
+ f.chat.e.inputField.style.maxHeight);
107115
}
108116
};
109117
var doit;
110118
window.addEventListener('resize',function(ev){
111119
clearTimeout(doit);
112120
doit = setTimeout(resized, 100);
113121
}, false);
114
- resized();
115122
return resized;
116123
})();
124
+ ForceResizeKludge.$disabled = true/*gets deleted when setup is finished*/;
117125
fossil.FRK = ForceResizeKludge/*for debugging*/;
118
- const Chat = (function(){
126
+ const Chat = ForceResizeKludge.chat = (function(){
119127
const cs = {
120128
verboseErrors: false /* if true then certain, mostly extraneous,
121129
error messages may be sent to the console. */,
122130
e:{/*map of certain DOM elements.*/
123131
messageInjectPoint: E1('#message-inject-point'),
@@ -1168,18 +1176,33 @@
11681176
self.hide();
11691177
Chat.deleteMessage(eMsg);
11701178
}
11711179
});
11721180
}
1181
+ const toolbar3 = D.addClass(D.div(), 'toolbar');
1182
+ D.append(this.e, toolbar3);
1183
+ D.append(toolbar3, D.button(
1184
+ "Locally remove all previous messages",
1185
+ function(){
1186
+ self.hide();
1187
+ Chat.mnMsg = +eMsg.dataset.msgid;
1188
+ var e = eMsg.previousElementSibling;
1189
+ while(e && e.classList.contains('message-widget')){
1190
+ const n = e.previousElementSibling;
1191
+ D.remove(e);
1192
+ e = n;
1193
+ }
1194
+ eMsg.scrollIntoView();
1195
+ }
1196
+ ));
11731197
const toolbar2 = D.addClass(D.div(), 'toolbar');
11741198
D.append(this.e, toolbar2);
1175
- const btnToggleText = D.button("Toggle text mode");
1176
- btnToggleText.addEventListener('click', function(){
1177
- self.hide();
1178
- Chat.toggleTextMode(eMsg);
1179
- },false);
1180
- D.append(toolbar2, btnToggleText);
1199
+ D.append(toolbar2, D.button(
1200
+ "Toggle text mode", function(){
1201
+ self.hide();
1202
+ Chat.toggleTextMode(eMsg);
1203
+ }));
11811204
if(eMsg.dataset.xfrom){
11821205
/* Add a link to the /timeline filtered on this user. */
11831206
const timelineLink = D.attr(
11841207
D.a(F.repoUrl('timeline',{
11851208
u: eMsg.dataset.xfrom,
@@ -1992,9 +2015,11 @@
19922015
const flip = (ev)=>Chat.animate(ev.target,'anim-flip-h');
19932016
document.querySelectorAll('#chat-buttons-wrapper .cbutton').forEach(function(e){
19942017
e.addEventListener('click',flip, false);
19952018
});
19962019
}
1997
- setTimeout( ()=>Chat.inputFocus(), 0 );
2020
+ delete ForceResizeKludge.$disabled;
2021
+ ForceResizeKludge();
19982022
Chat.animate.$disabled = false;
2023
+ setTimeout( ()=>Chat.inputFocus(), 0 );
19992024
F.page.chat = Chat/* enables testing the APIs via the dev tools */;
20002025
});
20012026
--- src/fossil.page.chat.js
+++ src/fossil.page.chat.js
@@ -63,61 +63,69 @@
63 /* This can inadvertently influence our flexbox layouts, so move
64 it out of the way. */
65 D.append(document.body,dbg);
66 }
67 })();
68 const ForceResizeKludge = 0 ? function(){} : (function f(){
69 /* Workaround for Safari mayhem regarding use of vh CSS units....
70 We tried to use vh units to set the content area size for the
71 chat layout, but Safari chokes on that, so we calculate that
72 height here: 85% when in "normal" mode and 95% in chat-only
73 mode. Larger than ~95% is too big for Firefox on Android,
74 causing the input area to move off-screen. */
75 if(!f.elemsToCount){
76 f.elemsToCount = [
77 document.querySelector('body > div.header'),
78 document.querySelector('body > div.mainmenu'),
79 document.querySelector('body > #hbdrop'),
80 document.querySelector('body > div.footer')
81 ];
82 f.contentArea = E1('div.content');
83 }
84 const resized = function(){
 
 
 
85 const wh = window.innerHeight,
86 com = document.body.classList.contains('chat-only-mode');
87 var ht;
88 var extra = 0;
89 if(com){
90 ht = wh;
91 }else{
92 f.elemsToCount.forEach((e)=>e ? extra += D.effectiveHeight(e) : false);
93 ht = wh - extra;
94 }
95 f.contentArea.style.height =
96 f.contentArea.style.maxHeight = [
 
 
 
97 "calc(", (ht>=100 ? ht : 100), "px",
98 " - 0.75em"/*fudge value*/,")"
99 /* ^^^^ hypothetically not needed, but both Chrome/FF on
100 Linux will force scrollbars on the body if this value is
101 too small (<0.75em in my tests). */
102 ].join('');
103 if(false){
104 console.debug("resized.",wh, extra, ht,
105 window.getComputedStyle(f.contentArea).maxHeight,
106 f.contentArea);
 
 
107 }
108 };
109 var doit;
110 window.addEventListener('resize',function(ev){
111 clearTimeout(doit);
112 doit = setTimeout(resized, 100);
113 }, false);
114 resized();
115 return resized;
116 })();
 
117 fossil.FRK = ForceResizeKludge/*for debugging*/;
118 const Chat = (function(){
119 const cs = {
120 verboseErrors: false /* if true then certain, mostly extraneous,
121 error messages may be sent to the console. */,
122 e:{/*map of certain DOM elements.*/
123 messageInjectPoint: E1('#message-inject-point'),
@@ -1168,18 +1176,33 @@
1168 self.hide();
1169 Chat.deleteMessage(eMsg);
1170 }
1171 });
1172 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1173 const toolbar2 = D.addClass(D.div(), 'toolbar');
1174 D.append(this.e, toolbar2);
1175 const btnToggleText = D.button("Toggle text mode");
1176 btnToggleText.addEventListener('click', function(){
1177 self.hide();
1178 Chat.toggleTextMode(eMsg);
1179 },false);
1180 D.append(toolbar2, btnToggleText);
1181 if(eMsg.dataset.xfrom){
1182 /* Add a link to the /timeline filtered on this user. */
1183 const timelineLink = D.attr(
1184 D.a(F.repoUrl('timeline',{
1185 u: eMsg.dataset.xfrom,
@@ -1992,9 +2015,11 @@
1992 const flip = (ev)=>Chat.animate(ev.target,'anim-flip-h');
1993 document.querySelectorAll('#chat-buttons-wrapper .cbutton').forEach(function(e){
1994 e.addEventListener('click',flip, false);
1995 });
1996 }
1997 setTimeout( ()=>Chat.inputFocus(), 0 );
 
1998 Chat.animate.$disabled = false;
 
1999 F.page.chat = Chat/* enables testing the APIs via the dev tools */;
2000 });
2001
--- src/fossil.page.chat.js
+++ src/fossil.page.chat.js
@@ -63,61 +63,69 @@
63 /* This can inadvertently influence our flexbox layouts, so move
64 it out of the way. */
65 D.append(document.body,dbg);
66 }
67 })();
68 const ForceResizeKludge = (function(){
69 /* Workaround for Safari mayhem regarding use of vh CSS units....
70 We tried to use vh units to set the content area size for the
71 chat layout, but Safari chokes on that, so we calculate that
72 height here: 85% when in "normal" mode and 95% in chat-only
73 mode. Larger than ~95% is too big for Firefox on Android,
74 causing the input area to move off-screen.
75
76 While we're here, we also use this to cap the max-height
77 of the input field so that pasting huge text does not scroll
78 the upper area of the input widget off-screen. */
79 const elemsToCount = [
80 document.querySelector('body > div.header'),
81 document.querySelector('body > div.mainmenu'),
82 document.querySelector('body > #hbdrop'),
83 document.querySelector('body > div.footer')
84 ];
85 const contentArea = E1('div.content');
86 const resized = function f(){
87 if(f.$disabled) return;
88 const wh = window.innerHeight,
89 com = document.body.classList.contains('chat-only-mode');
90 var ht;
91 var extra = 0;
92 if(com){
93 ht = wh;
94 }else{
95 elemsToCount.forEach((e)=>e ? extra += D.effectiveHeight(e) : false);
96 ht = wh - extra;
97 }
98 f.chat.e.inputField.style.maxHeight = (ht/2)+"px";
99 /* ^^^^ this is a middle ground between having no size cap
100 on the input field and having a fixed arbitrary cap. */;
101 contentArea.style.height =
102 contentArea.style.maxHeight = [
103 "calc(", (ht>=100 ? ht : 100), "px",
104 " - 0.75em"/*fudge value*/,")"
105 /* ^^^^ hypothetically not needed, but both Chrome/FF on
106 Linux will force scrollbars on the body if this value is
107 too small (<0.75em in my tests). */
108 ].join('');
109 if(false){
110 console.debug("resized.",wh, extra, ht,
111 window.getComputedStyle(contentArea).maxHeight,
112 contentArea);
113 console.debug("Set input max height to: ",
114 f.chat.e.inputField.style.maxHeight);
115 }
116 };
117 var doit;
118 window.addEventListener('resize',function(ev){
119 clearTimeout(doit);
120 doit = setTimeout(resized, 100);
121 }, false);
 
122 return resized;
123 })();
124 ForceResizeKludge.$disabled = true/*gets deleted when setup is finished*/;
125 fossil.FRK = ForceResizeKludge/*for debugging*/;
126 const Chat = ForceResizeKludge.chat = (function(){
127 const cs = {
128 verboseErrors: false /* if true then certain, mostly extraneous,
129 error messages may be sent to the console. */,
130 e:{/*map of certain DOM elements.*/
131 messageInjectPoint: E1('#message-inject-point'),
@@ -1168,18 +1176,33 @@
1176 self.hide();
1177 Chat.deleteMessage(eMsg);
1178 }
1179 });
1180 }
1181 const toolbar3 = D.addClass(D.div(), 'toolbar');
1182 D.append(this.e, toolbar3);
1183 D.append(toolbar3, D.button(
1184 "Locally remove all previous messages",
1185 function(){
1186 self.hide();
1187 Chat.mnMsg = +eMsg.dataset.msgid;
1188 var e = eMsg.previousElementSibling;
1189 while(e && e.classList.contains('message-widget')){
1190 const n = e.previousElementSibling;
1191 D.remove(e);
1192 e = n;
1193 }
1194 eMsg.scrollIntoView();
1195 }
1196 ));
1197 const toolbar2 = D.addClass(D.div(), 'toolbar');
1198 D.append(this.e, toolbar2);
1199 D.append(toolbar2, D.button(
1200 "Toggle text mode", function(){
1201 self.hide();
1202 Chat.toggleTextMode(eMsg);
1203 }));
 
1204 if(eMsg.dataset.xfrom){
1205 /* Add a link to the /timeline filtered on this user. */
1206 const timelineLink = D.attr(
1207 D.a(F.repoUrl('timeline',{
1208 u: eMsg.dataset.xfrom,
@@ -1992,9 +2015,11 @@
2015 const flip = (ev)=>Chat.animate(ev.target,'anim-flip-h');
2016 document.querySelectorAll('#chat-buttons-wrapper .cbutton').forEach(function(e){
2017 e.addEventListener('click',flip, false);
2018 });
2019 }
2020 delete ForceResizeKludge.$disabled;
2021 ForceResizeKludge();
2022 Chat.animate.$disabled = false;
2023 setTimeout( ()=>Chat.inputFocus(), 0 );
2024 F.page.chat = Chat/* enables testing the APIs via the dev tools */;
2025 });
2026

Keyboard Shortcuts

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