Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Refactored the calc-elem-effective-height routine into the fossil.dom API for reuse elsewhere. Fixed (arguably) a minor layout quirk in the chat input field in multi-line mode. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
299fd6905f52c9c24898dc5121e63bed |
| User & Date: | stephan 2020-12-27 21:22:26.035 |
Context
|
2020-12-27
| ||
| 22:01 | chat: when toggling between single/multi-line mode, retain the message area scroll position, insofar as its size allows for (e.g. might not work if the history is too short to scroll). ... (check-in: 423ee8101a user: stephan tags: trunk) | |
| 21:22 | Refactored the calc-elem-effective-height routine into the fossil.dom API for reuse elsewhere. Fixed (arguably) a minor layout quirk in the chat input field in multi-line mode. ... (check-in: 299fd6905f user: stephan tags: trunk) | |
| 21:00 | Put the <form> outside of the chat-input-area <div>. Safari requires this. ... (check-in: ca60df9238 user: drh tags: trunk) | |
Changes
Changes to src/chat.js.
| ︙ | ︙ | |||
54 55 56 57 58 59 60 |
f.elemsToCount = [
document.querySelector('body > div.header'),
document.querySelector('body > div.mainmenu'),
document.querySelector('body > #hbdrop'),
document.querySelector('body > div.footer')
];
f.contentArea = E1('div.content');
| < < < < < < < < < < < < < < < < < < > < | | > > > | | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
f.elemsToCount = [
document.querySelector('body > div.header'),
document.querySelector('body > div.mainmenu'),
document.querySelector('body > #hbdrop'),
document.querySelector('body > div.footer')
];
f.contentArea = E1('div.content');
}
const bcl = document.body.classList;
const resized = function(){
const wh = window.innerHeight,
com = bcl.contains('chat-only-mode');
var ht;
var extra = 0;
if(com){
ht = wh;
}else{
f.elemsToCount.forEach((e)=>e ? extra += D.effectiveHeight(e) : false);
ht = wh - extra;
}
f.contentArea.style.height =
f.contentArea.style.maxHeight = [
"calc(", (ht>=100 ? ht : 100), "px",
" - 1em"/*fudge value*/,")"
/* ^^^^ hypothetically not needed, but both Chrome/FF on
Linux will force scrollbars on the body if this value is
too small (<0.75em in my tests). */
].join('');
if(false){
console.debug("resized.",wh, extra, ht,
window.getComputedStyle(f.contentArea).maxHeight,
f.contentArea);
}
};
var doit;
window.addEventListener('resize',function(ev){
clearTimeout(doit);
|
| ︙ | ︙ | |||
242 243 244 245 246 247 248 |
}else{
D.append(holder,e);
this.e.newestMessage = e;
}
if(!atEnd && !this.isBatchLoading
&& e.dataset.xfrom!==this.me
&& (prevMessage
| | | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
}else{
D.append(holder,e);
this.e.newestMessage = e;
}
if(!atEnd && !this.isBatchLoading
&& e.dataset.xfrom!==this.me
&& (prevMessage
? !this.messageIsInView(prevMessage)
: false)){
/* If a new non-history message arrives while the user is
scrolled elsewhere, do not scroll to the latest
message, but gently alert the user that a new message
has arrived. */
F.toast.message("New message has arrived.");
}else if(!this.isBatchLoading && e.dataset.xfrom===Chat.me){
|
| ︙ | ︙ | |||
339 340 341 342 343 344 345 346 347 348 349 350 351 352 |
(yes==false), or toggle them (no arguments). Returns this. */
toggleNavButtons: function(yes){
const e = [this.e.btnMsgHome, this.e.btnMsgEnd], c = 'hidden';
if(0===arguments.length) D.toggleClass(e, c);
else if(!arguments[0]) D.addClass(e, c);
else D.removeClass(e, c);
},
settings:{
get: (k,dflt)=>F.storage.get(k,dflt),
getBool: (k,dflt)=>F.storage.getBool(k,dflt),
set: (k,v)=>F.storage.set(k,v),
defaults:{
"images-inline": !!F.config.chat.imagesInline,
"monospace-messages": false
| > > > | 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 |
(yes==false), or toggle them (no arguments). Returns this. */
toggleNavButtons: function(yes){
const e = [this.e.btnMsgHome, this.e.btnMsgEnd], c = 'hidden';
if(0===arguments.length) D.toggleClass(e, c);
else if(!arguments[0]) D.addClass(e, c);
else D.removeClass(e, c);
},
messageIsInView: function(e){
return e ? overlapsElemView(e, this.e.messagesWrapper) : false;
},
settings:{
get: (k,dflt)=>F.storage.get(k,dflt),
getBool: (k,dflt)=>F.storage.getBool(k,dflt),
set: (k,v)=>F.storage.set(k,v),
defaults:{
"images-inline": !!F.config.chat.imagesInline,
"monospace-messages": false
|
| ︙ | ︙ |
Changes to src/default.css.
| ︙ | ︙ | |||
1682 1683 1684 1685 1686 1687 1688 |
/* Widget holding the chat message input field, send button, and
settings button. */
body.chat #chat-input-line {
display: flex;
flex-direction: row;
margin-bottom: 0.25em;
| | | 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 |
/* Widget holding the chat message input field, send button, and
settings button. */
body.chat #chat-input-line {
display: flex;
flex-direction: row;
margin-bottom: 0.25em;
align-items: self-start;
}
body.chat #chat-input-line > input[type=submit],
body.chat #chat-input-line > #chat-settings-button,
body.chat #chat-input-line > button {
flex: 1 5 auto;
max-width: 6em;
margin: 0 0.25em;
|
| ︙ | ︙ |
Changes to src/fossil.dom.js.
| ︙ | ︙ | |||
721 722 723 724 725 726 727 728 729 730 731 732 733 734 |
let k;
for(k in style){
if(style.hasOwnProperty(k)) e.style[k] = style[k];
}
}
return e;
};
/**
Parses a string as HTML.
Usages:
Array (htmlString)
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 |
let k;
for(k in style){
if(style.hasOwnProperty(k)) e.style[k] = style[k];
}
}
return e;
};
/**
Given a DOM element, this routine measures its "effective
height", which is the bounding top/bottom range of this element
and all of its children, recursively. For some DOM structure
cases, a parent may have a reported height of 0 even though
children have non-0 sizes.
Returns 0 if !e or if the element really has no height.
*/
dom.effectiveHeight = function f(e){
if(!e) return 0;
if(!f.measure){
f.measure = function callee(e, depth){
if(!e) return;
const m = e.getBoundingClientRect();
if(0===depth){
callee.top = m.top;
callee.bottom = m.bottom;
}else{
callee.top = m.top ? Math.min(callee.top, m.top) : callee.top;
callee.bottom = Math.max(callee.bottom, m.bottom);
}
Array.prototype.forEach.call(e.children,(e)=>callee(e,depth+1));
if(0===depth){
//console.debug("measure() height:",e.className, callee.top, callee.bottom, (callee.bottom - callee.top));
f.extra += callee.bottom - callee.top;
}
return f.extra;
};
}
f.extra = 0;
f.measure(e,0);
return f.extra;
};
/**
Parses a string as HTML.
Usages:
Array (htmlString)
|
| ︙ | ︙ |