Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Several internal cleanups in chat app, e.g. replace document.createXYZ with simpler fossil.dom API. Eliminate assignment to innerHTML, which is widely considered unsafe. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
68da24594ff5cb7aa9ad3e9e2c4ffd59 |
| User & Date: | stephan 2020-12-23 23:27:35.577 |
Context
|
2020-12-24
| ||
| 03:34 | The /chat page now redirects to the login page if needed. ... (check-in: 77d3058600 user: drh tags: trunk) | |
| 01:04 | Bungled merge. Was: The /chat page redirects to the login page if the user does not have appropriate permissions to use chat. ... (Closed-Leaf check-in: fee74ce5e7 user: drh tags: mistake) | |
|
2020-12-23
| ||
| 23:27 | Several internal cleanups in chat app, e.g. replace document.createXYZ with simpler fossil.dom API. Eliminate assignment to innerHTML, which is widely considered unsafe. ... (check-in: 68da24594f user: stephan tags: trunk) | |
| 22:58 | chat: minor UI refinements. ... (check-in: 8eb01c314b user: stephan tags: trunk) | |
Changes
Changes to src/chat.c.
| ︙ | ︙ | |||
175 176 177 178 179 180 181 |
/* New chat messages get inserted immediately after this element */
@ <span id='message-inject-point'></span>
builtin_fossil_js_bundle_or("popupwidget", NULL);
/* Always in-line the javascript for the chat page */
@ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */
| | > | < > | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
/* New chat messages get inserted immediately after this element */
@ <span id='message-inject-point'></span>
builtin_fossil_js_bundle_or("popupwidget", NULL);
/* Always in-line the javascript for the chat page */
@ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */
/* We need an onload handler to ensure that window.fossil is
initialized before the chat init code runs. */
@ window.addEventListener('load', function(){
@ window.fossil.config.chatInitSize =
@ %d(db_get_int("chat-initial-history",50));
cgi_append_content(builtin_text("chat.js"),-1);
@ }, false);
@ </script>
style_finish_page();
}
|
| ︙ | ︙ |
Changes to src/chat.js.
1 2 |
(function(){
const form = document.querySelector('#chat-form');
| < < > > | > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
(function(){
const form = document.querySelector('#chat-form');
const F = window.fossil, D = F.dom;
const Chat = (function(){
const cs = {
me: F.user.name,
mxMsg: F.config.chatInitSize ? -F.config.chatInitSize : -50,
pageIsActive: !document.hidden,
onPageActive: function(){console.debug("Page active.")}, //override below
onPageInactive: function(){console.debug("Page inactive.")} //override below
};
document.addEventListener('visibilitychange', function(ev){
cs.pageIsActive = !document.hidden;
if(cs.pageIsActive) cs.onPageActive();
else cs.onPageInactive();
}, true);
return cs;
})();
/* State for paste and drag/drop */
const BlobXferState = {
dropDetails: document.querySelector('#chat-drop-details'),
blob: undefined
};
/** Updates the paste/drop zone with details of the pasted/dropped
data. The argument must be a Blob or Blob-like object (File) or
|
| ︙ | ︙ | |||
118 119 120 121 122 123 124 |
if(f.injectPoint.nextSibling){
f.injectPoint.parentNode.insertBefore(e, f.injectPoint.nextSibling);
}else{
f.injectPoint.parentNode.appendChild(e);
}
};
/* Returns a new TEXT node with the given text content. */
| < | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
if(f.injectPoint.nextSibling){
f.injectPoint.parentNode.insertBefore(e, f.injectPoint.nextSibling);
}else{
f.injectPoint.parentNode.appendChild(e);
}
};
/* Returns a new TEXT node with the given text content. */
/** Returns the local time string of Date object d, defaulting
to the current time. */
const localTimeString = function ff(d){
if(!ff.pad){
ff.pad = (x)=>(''+x).length>1 ? x : '0'+x;
}
d || (d = new Date());
|
| ︙ | ︙ | |||
177 178 179 180 181 182 183 |
}
f.popup.show(x, y);
};
/** Callback for poll() to inject new content into the page. */
function newcontent(jx){
var i;
for(i=0; i<jx.msgs.length; ++i){
| | < | > | < | < | | < | | | < | < | < | | | > | < | | | > | | | 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
}
f.popup.show(x, y);
};
/** Callback for poll() to inject new content into the page. */
function newcontent(jx){
var i;
for(i=0; i<jx.msgs.length; ++i){
const m = jx.msgs[i];
if( m.msgid>Chat.mxMsg ) Chat.mxMsg = m.msgid;
const eWho = D.create('legend'),
row = D.addClass(D.fieldset(eWho), 'message-row');
injectMessage(row);
eWho.dataset.timestamp = m.mtime;
eWho.addEventListener('click', handleLegendClicked, false);
if( m.xfrom==Chat.me && window.outerWidth<1000 ){
eWho.setAttribute('align', 'right');
row.style.justifyContent = "flex-end";
}else{
eWho.setAttribute('align', 'left');
}
eWho.style.backgroundColor = m.uclr;
eWho.classList.add('message-user');
let whoName = m.xfrom;
var d = new Date(m.mtime + "Z");
if( d.getMinutes().toString()!="NaN" ){
/* Show local time when we can compute it */
eWho.append(D.text(whoName+' @ '+
d.getHours()+":"+(d.getMinutes()+100).toString().slice(1,3)
))
}else{
/* Show UTC on systems where Date() does not work */
eWho.append(D.text(whoName+' @ '+m.mtime.slice(11,16)))
}
let eContent = D.addClass(D.div(),'message-content','chat-message');
eContent.style.backgroundColor = m.uclr;
row.appendChild(eContent);
if( m.fsize>0 ){
if( m.fmime && m.fmime.startsWith("image/") ){
eContent.appendChild(D.img("chat-download/" + m.msgid));
}else{
eContent.appendChild(D.a(
window.fossil.rootPath+
'chat-download/' + m.msgid+'/'+encodeURIComponent(m.fname),
// ^^^ add m.fname to URL to cause downloaded file to have that name.
"(" + m.fname + " " + m.fsize + " bytes)"
));
}
const br = D.br();
br.style.clear = "both";
eContent.appendChild(br);
}
if(m.xmsg){
try{D.moveChildrenTo(eContent, D.parseHtml(m.xmsg))}
catch(e){console.error(e)}
}
eContent.classList.add('chat-message');
}
}
async function poll(){
if(poll.running) return;
poll.running = true;
fetch("chat-poll?name=" + Chat.mxMsg)
.then(x=>x.json())
.then(y=>newcontent(y))
.catch(e=>console.error(e))
.finally(()=>poll.running=false)
}
poll();
setInterval(poll, 1000);
})();
|
Changes to src/default.css.
| ︙ | ︙ | |||
1461 1462 1463 1464 1465 1466 1467 | position: absolute !important; opacity: 0 !important; pointer-events: none !important; display: none !important; } /* Chat-related */ | | | | | | 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 |
position: absolute !important;
opacity: 0 !important;
pointer-events: none !important;
display: none !important;
}
/* Chat-related */
body.chat span.at-name { /* for @USERNAME references */
text-decoration: underline;
font-weight: bold;
}
/* A wrapper for a single single message (one row of the UI) */
body.chat .message-row {
margin-bottom: 0.5em;
border: none;
display: flex;
flex-direction: row;
justify-content: flex-start;
/*border: 1px solid rgba(0,0,0,0.2);
border-radius: 0.25em;
box-shadow: 0.2em 0.2em 0.2em rgba(0, 0, 0, 0.29);*/
border: none;
}
/* The content area of a message (the body element of a FIELDSET) */
body.chat .message-content {
display: inline-block;
border-radius: 0.25em;
border: 1px solid rgba(0,0,0,0.2);
box-shadow: 0.2em 0.2em 0.2em rgba(0, 0, 0, 0.29);
padding: 0.25em 1em;
margin-top: -0.75em;
min-width: 9em /*avoid unsightly "underlap" with the user name label*/;
}
/* User name for the post (a LEGEND element) */
body.chat .message-row .message-user {
border-radius: 0.25em 0.25em 0 0;
padding: 0 0.5em;
/*text-align: left; Firefox requires the 'align' attribute */
margin: 0 0.15em;
padding: 0 0.5em 0em 0.5em;
margin-bottom: 0.4em;
cursor: pointer;
|
| ︙ | ︙ |