Fossil SCM
chat: reworked the auto-resize algorithm to account for elements which "incorrectly" report a height of 0. Experimentally removed the 2em bottom gap at the end of the message reportedly required by Safari.
Commit
cdc6dec7c78aedfa7c2cf5812514316c46f06ad4b211c1d48aa1b69a7e53b200
Parent
b3f2eee546f014e…
2 files changed
+24
-10
+1
-1
+24
-10
| --- src/chat.js | ||
| +++ src/chat.js | ||
| @@ -48,20 +48,34 @@ | ||
| 48 | 48 | We tried to use vh units to set the content area size for the |
| 49 | 49 | chat layout, but Safari chokes on that, so we calculate that |
| 50 | 50 | height here: 85% when in "normal" mode and 95% in chat-only |
| 51 | 51 | mode. Larger than ~95% is too big for Firefox on Android, |
| 52 | 52 | causing the input area to move off-screen. */ |
| 53 | - if(!f.eHead){ | |
| 54 | - f.eHead = document.querySelector('body > div.header'); | |
| 55 | - f.eMenu = document.querySelector('body > div.mainmenu'); | |
| 56 | - f.eFoot = document.querySelector('body > div.footer'); | |
| 53 | + if(!f.elemsToCount){ | |
| 54 | + f.elemsToCount = [ | |
| 55 | + document.querySelector('body > div.header'), | |
| 56 | + document.querySelector('body > div.mainmenu'), | |
| 57 | + document.querySelector('body > #hbdrop'), | |
| 58 | + document.querySelector('body > div.footer') | |
| 59 | + ]; | |
| 57 | 60 | f.contentArea = E1('div.content'); |
| 58 | 61 | f.extra = 0; |
| 59 | - f.measure = function(e){ | |
| 60 | - if(e){ | |
| 61 | - const m = window.getComputedStyle(e); | |
| 62 | - f.extra += parseFloat(m.height); | |
| 62 | + f.measure = function callee(e,depth){ | |
| 63 | + if(!e) return; | |
| 64 | + const m = e.getBoundingClientRect(); | |
| 65 | + //console.debug("level-"+depth+" rect",e.className,m.top,m.bottom); | |
| 66 | + if(0===depth){ | |
| 67 | + callee.top = m.top; | |
| 68 | + callee.bottom = m.bottom; | |
| 69 | + }else{ | |
| 70 | + callee.top = m.top ? Math.min(callee.top, m.top) : callee.top; | |
| 71 | + callee.bottom = Math.max(callee.bottom, m.bottom); | |
| 72 | + } | |
| 73 | + Array.prototype.forEach.call(e.children,(e)=>callee(e,depth+1)); | |
| 74 | + if(0===depth){ | |
| 75 | + //console.debug("measure() height:",e.className, callee.top, callee.bottom, (callee.bottom - callee.top)); | |
| 76 | + f.extra += callee.bottom - callee.top; | |
| 63 | 77 | } |
| 64 | 78 | }; |
| 65 | 79 | } |
| 66 | 80 | const bcl = document.body.classList; |
| 67 | 81 | const resized = function(){ |
| @@ -70,11 +84,11 @@ | ||
| 70 | 84 | var ht; |
| 71 | 85 | if(com){ |
| 72 | 86 | ht = wh; |
| 73 | 87 | }else{ |
| 74 | 88 | f.extra = 0; |
| 75 | - [f.eHead, f.eMenu, f.eFoot].forEach(f.measure); | |
| 89 | + f.elemsToCount.forEach((e)=>e ? f.measure(e,0) : false); | |
| 76 | 90 | ht = wh - f.extra; |
| 77 | 91 | } |
| 78 | 92 | f.contentArea.style.height = |
| 79 | 93 | f.contentArea.style.maxHeight = [ |
| 80 | 94 | "calc(", (ht>=100 ? ht : 100), "px", |
| @@ -92,11 +106,11 @@ | ||
| 92 | 106 | doit = setTimeout(resized, 100); |
| 93 | 107 | }, false); |
| 94 | 108 | resized(); |
| 95 | 109 | return resized; |
| 96 | 110 | })(); |
| 97 | - | |
| 111 | + fossil.FRK = ForceResizeKludge/*for debugging*/; | |
| 98 | 112 | const Chat = (function(){ |
| 99 | 113 | const cs = { |
| 100 | 114 | e:{/*map of certain DOM elements.*/ |
| 101 | 115 | messageInjectPoint: E1('#message-inject-point'), |
| 102 | 116 | pageTitle: E1('head title'), |
| 103 | 117 |
| --- src/chat.js | |
| +++ src/chat.js | |
| @@ -48,20 +48,34 @@ | |
| 48 | We tried to use vh units to set the content area size for the |
| 49 | chat layout, but Safari chokes on that, so we calculate that |
| 50 | height here: 85% when in "normal" mode and 95% in chat-only |
| 51 | mode. Larger than ~95% is too big for Firefox on Android, |
| 52 | causing the input area to move off-screen. */ |
| 53 | if(!f.eHead){ |
| 54 | f.eHead = document.querySelector('body > div.header'); |
| 55 | f.eMenu = document.querySelector('body > div.mainmenu'); |
| 56 | f.eFoot = document.querySelector('body > div.footer'); |
| 57 | f.contentArea = E1('div.content'); |
| 58 | f.extra = 0; |
| 59 | f.measure = function(e){ |
| 60 | if(e){ |
| 61 | const m = window.getComputedStyle(e); |
| 62 | f.extra += parseFloat(m.height); |
| 63 | } |
| 64 | }; |
| 65 | } |
| 66 | const bcl = document.body.classList; |
| 67 | const resized = function(){ |
| @@ -70,11 +84,11 @@ | |
| 70 | var ht; |
| 71 | if(com){ |
| 72 | ht = wh; |
| 73 | }else{ |
| 74 | f.extra = 0; |
| 75 | [f.eHead, f.eMenu, f.eFoot].forEach(f.measure); |
| 76 | ht = wh - f.extra; |
| 77 | } |
| 78 | f.contentArea.style.height = |
| 79 | f.contentArea.style.maxHeight = [ |
| 80 | "calc(", (ht>=100 ? ht : 100), "px", |
| @@ -92,11 +106,11 @@ | |
| 92 | doit = setTimeout(resized, 100); |
| 93 | }, false); |
| 94 | resized(); |
| 95 | return resized; |
| 96 | })(); |
| 97 | |
| 98 | const Chat = (function(){ |
| 99 | const cs = { |
| 100 | e:{/*map of certain DOM elements.*/ |
| 101 | messageInjectPoint: E1('#message-inject-point'), |
| 102 | pageTitle: E1('head title'), |
| 103 |
| --- src/chat.js | |
| +++ src/chat.js | |
| @@ -48,20 +48,34 @@ | |
| 48 | We tried to use vh units to set the content area size for the |
| 49 | chat layout, but Safari chokes on that, so we calculate that |
| 50 | height here: 85% when in "normal" mode and 95% in chat-only |
| 51 | mode. Larger than ~95% is too big for Firefox on Android, |
| 52 | causing the input area to move off-screen. */ |
| 53 | if(!f.elemsToCount){ |
| 54 | f.elemsToCount = [ |
| 55 | document.querySelector('body > div.header'), |
| 56 | document.querySelector('body > div.mainmenu'), |
| 57 | document.querySelector('body > #hbdrop'), |
| 58 | document.querySelector('body > div.footer') |
| 59 | ]; |
| 60 | f.contentArea = E1('div.content'); |
| 61 | f.extra = 0; |
| 62 | f.measure = function callee(e,depth){ |
| 63 | if(!e) return; |
| 64 | const m = e.getBoundingClientRect(); |
| 65 | //console.debug("level-"+depth+" rect",e.className,m.top,m.bottom); |
| 66 | if(0===depth){ |
| 67 | callee.top = m.top; |
| 68 | callee.bottom = m.bottom; |
| 69 | }else{ |
| 70 | callee.top = m.top ? Math.min(callee.top, m.top) : callee.top; |
| 71 | callee.bottom = Math.max(callee.bottom, m.bottom); |
| 72 | } |
| 73 | Array.prototype.forEach.call(e.children,(e)=>callee(e,depth+1)); |
| 74 | if(0===depth){ |
| 75 | //console.debug("measure() height:",e.className, callee.top, callee.bottom, (callee.bottom - callee.top)); |
| 76 | f.extra += callee.bottom - callee.top; |
| 77 | } |
| 78 | }; |
| 79 | } |
| 80 | const bcl = document.body.classList; |
| 81 | const resized = function(){ |
| @@ -70,11 +84,11 @@ | |
| 84 | var ht; |
| 85 | if(com){ |
| 86 | ht = wh; |
| 87 | }else{ |
| 88 | f.extra = 0; |
| 89 | f.elemsToCount.forEach((e)=>e ? f.measure(e,0) : false); |
| 90 | ht = wh - f.extra; |
| 91 | } |
| 92 | f.contentArea.style.height = |
| 93 | f.contentArea.style.maxHeight = [ |
| 94 | "calc(", (ht>=100 ? ht : 100), "px", |
| @@ -92,11 +106,11 @@ | |
| 106 | doit = setTimeout(resized, 100); |
| 107 | }, false); |
| 108 | resized(); |
| 109 | return resized; |
| 110 | })(); |
| 111 | fossil.FRK = ForceResizeKludge/*for debugging*/; |
| 112 | const Chat = (function(){ |
| 113 | const cs = { |
| 114 | e:{/*map of certain DOM elements.*/ |
| 115 | messageInjectPoint: E1('#message-inject-point'), |
| 116 | pageTitle: E1('head title'), |
| 117 |
+1
-1
| --- src/default.css | ||
| +++ src/default.css | ||
| @@ -1675,11 +1675,11 @@ | ||
| 1675 | 1675 | } |
| 1676 | 1676 | body.chat:not(.chat-only-mode) #chat-input-area{ |
| 1677 | 1677 | /* Safari user reports that 2em is necessary to keep the file selection |
| 1678 | 1678 | widget from overlapping the page footer, whereas a margin of 0 is fine |
| 1679 | 1679 | for FF/Chrome (and 2em is a *huge* waste of space for those). */ |
| 1680 | - margin-bottom: 2em; | |
| 1680 | + margin-bottom: 0; | |
| 1681 | 1681 | } |
| 1682 | 1682 | |
| 1683 | 1683 | /* Widget holding the chat message input field, send button, and |
| 1684 | 1684 | settings button. */ |
| 1685 | 1685 | body.chat #chat-input-line { |
| 1686 | 1686 |
| --- src/default.css | |
| +++ src/default.css | |
| @@ -1675,11 +1675,11 @@ | |
| 1675 | } |
| 1676 | body.chat:not(.chat-only-mode) #chat-input-area{ |
| 1677 | /* Safari user reports that 2em is necessary to keep the file selection |
| 1678 | widget from overlapping the page footer, whereas a margin of 0 is fine |
| 1679 | for FF/Chrome (and 2em is a *huge* waste of space for those). */ |
| 1680 | margin-bottom: 2em; |
| 1681 | } |
| 1682 | |
| 1683 | /* Widget holding the chat message input field, send button, and |
| 1684 | settings button. */ |
| 1685 | body.chat #chat-input-line { |
| 1686 |
| --- src/default.css | |
| +++ src/default.css | |
| @@ -1675,11 +1675,11 @@ | |
| 1675 | } |
| 1676 | body.chat:not(.chat-only-mode) #chat-input-area{ |
| 1677 | /* Safari user reports that 2em is necessary to keep the file selection |
| 1678 | widget from overlapping the page footer, whereas a margin of 0 is fine |
| 1679 | for FF/Chrome (and 2em is a *huge* waste of space for those). */ |
| 1680 | margin-bottom: 0; |
| 1681 | } |
| 1682 | |
| 1683 | /* Widget holding the chat message input field, send button, and |
| 1684 | settings button. */ |
| 1685 | body.chat #chat-input-line { |
| 1686 |