Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Merged in trunk for latest changes. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | markdown-tagrefs |
| Files: | files | file ages | folders |
| SHA3-256: |
09f86815c6ca0f27903440aba7052bf5 |
| User & Date: | stephan 2021-09-29 16:50:40.151 |
Context
|
2021-10-04
| ||
| 19:48 | Merged in trunk for latest (and conflicting) /chat changes. ... (check-in: 7cae4c0981 user: stephan tags: markdown-tagrefs) | |
|
2021-09-29
| ||
| 16:50 | Merged in trunk for latest changes. ... (check-in: 09f86815c6 user: stephan tags: markdown-tagrefs) | |
| 16:45 | Consolidated /wikiedit, /pikchrshow, /fileedit, and /chat to use shift-enter to run preview mode. The former 3 previously used ctrl-enter but it was poorly documented and probably not widely used like ctrl-enter is in chat (to send a message). ... (check-in: 13fabf3f4d user: stephan tags: trunk) | |
|
2021-09-28
| ||
| 11:22 | /chat: experimental HTML5 history support for using the back button to return to a message from which a #nnn message ID was clicked. ... (check-in: 9df3fc6b0f user: stephan tags: markdown-tagrefs) | |
Changes
Changes to src/chat.c.
| ︙ | ︙ | |||
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
**
** Other /chat-OP pages are used by XHR requests from this page to
** send new chat message, delete older messages, or poll for changes.
*/
void chat_webpage(void){
char *zAlert;
char *zProjectName;
login_check_credentials();
if( !g.perm.Chat ){
login_needed(g.anon.Chat);
return;
}
zAlert = mprintf("%s/builtin/%s", g.zBaseURL,
db_get("chat-alert-sound","alerts/plunk.wav"));
zProjectName = db_get("project-name","Unnamed project");
style_set_current_feature("chat");
style_header("Chat");
@ <div id='chat-input-area'>
@ <div id='chat-input-line' class='single-line'>
@ <input type="text" name="msg" id="chat-input-single" \
| > > > > > > > | | | | | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
**
** Other /chat-OP pages are used by XHR requests from this page to
** send new chat message, delete older messages, or poll for changes.
*/
void chat_webpage(void){
char *zAlert;
char *zProjectName;
const char * zInputPlaceholder1 = /* Placeholder for 1-line input */
"Enter sends and Shift-Enter previews.";
const char * zInputPlaceholder2 = /* Placeholder for textarea input*/
"Ctrl-Enter sends and Shift-Enter previews.";
char * zInputPlaceholder0; /* Common text input placeholder value */
login_check_credentials();
if( !g.perm.Chat ){
login_needed(g.anon.Chat);
return;
}
zAlert = mprintf("%s/builtin/%s", g.zBaseURL,
db_get("chat-alert-sound","alerts/plunk.wav"));
zProjectName = db_get("project-name","Unnamed project");
zInputPlaceholder0 =
mprintf("Type markdown-formatted message for %h.", zProjectName);
style_set_current_feature("chat");
style_header("Chat");
@ <div id='chat-input-area'>
@ <div id='chat-input-line' class='single-line'>
@ <input type="text" name="msg" id="chat-input-single" \
@ placeholder="%h(zInputPlaceholder0) %h(zInputPlaceholder1)" \
@ autocomplete="off">
@ <textarea rows="8" id="chat-input-multi" \
@ placeholder="%h(zInputPlaceholder0) %h(zInputPlaceholder2)" \
@ class="hidden"></textarea>
@ <div id='chat-edit-buttons'>
@ <button id="chat-preview-button" \
@ title="Preview message (Shift-Enter)">👁</button>
@ <button id="chat-settings-button" \
@ title="Configure chat">⚙</button>
@ <button id="chat-message-submit" \
@ title="Send message (Ctrl-Enter)">📤</button>
@ </div>
@ </div>
@ <div id='chat-input-file-area'>
@ <div class='file-selection-wrapper'>
@ <div class='help-buttonlet'>
@ Select a file to upload, drag/drop a file into this spot,
@ or paste an image from the clipboard if supported by
|
| ︙ | ︙ | |||
208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
@ <button>Close Settings</button>
@ </div>
@ <div id='chat-messages-wrapper' class='chat-view'>
/* New chat messages get inserted immediately after this element */
@ <span id='message-inject-point'></span>
@ </div>
fossil_free(zProjectName);
builtin_fossil_js_bundle_or("popupwidget", "storage", "fetch",
"pikchr", "confirmer", 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(){
| > | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
@ <button>Close Settings</button>
@ </div>
@ <div id='chat-messages-wrapper' class='chat-view'>
/* New chat messages get inserted immediately after this element */
@ <span id='message-inject-point'></span>
@ </div>
fossil_free(zProjectName);
fossil_free(zInputPlaceholder0);
builtin_fossil_js_bundle_or("popupwidget", "storage", "fetch",
"pikchr", "confirmer", 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(){
|
| ︙ | ︙ |
Changes to src/default.css.
| ︙ | ︙ | |||
551 552 553 554 555 556 557 |
vertical-align: top;
padding: 0;
overflow: hidden /*work around inner PRE slight overflow/overlap*/;
}
table.diff pre {
margin: 0 0 0 0;
padding: 0 0.5em;
| | | 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 |
vertical-align: top;
padding: 0;
overflow: hidden /*work around inner PRE slight overflow/overlap*/;
}
table.diff pre {
margin: 0 0 0 0;
padding: 0 0.5em;
line-height: 1.275/*for mobile: forum post e6f4ee7de98b55c0*/;
text-size-adjust: none
/* ^^^ attempt to keep mobile from inflating some text */;
}
table.diff pre > ins,
table.diff pre > del {
/* Fill platform-dependent color gaps caused by
inflated line-height */;
|
| ︙ | ︙ |
Changes to src/fossil.diff.js.
| ︙ | ︙ | |||
446 447 448 449 450 451 452 |
this.pos.next.startRhs -= lines.length;
this.pos.next.startLhs -= lines.length;
const selector = '.difflnr > pre';
td = tr.querySelector(selector);
const lineNoTxt = lineno.join('\n')+'\n';
lineno.length = 0;
td.innerHTML = lineNoTxt + td.innerHTML;
| | | 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 |
this.pos.next.startRhs -= lines.length;
this.pos.next.startLhs -= lines.length;
const selector = '.difflnr > pre';
td = tr.querySelector(selector);
const lineNoTxt = lineno.join('\n')+'\n';
lineno.length = 0;
td.innerHTML = lineNoTxt + td.innerHTML;
if(this.pos.endLhs<1
|| lines.length < (urlParam.to - urlParam.from)){
/* No more data. */
this.destroy();
}else{
this.maybeReplaceButtons();
this.updatePosDebug();
}
|
| ︙ | ︙ | |||
502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 |
This is an async operation. While it is in transit, any calls
to this function will have no effect except (possibly) to emit
a warning. Returns this object.
*/
fetchChunk: function(fetchType){
if( !this.$fetchQueue ) return this; // HACKHACK: are we destroyed?
if( fetchType==this.FetchType.ProcessQueue ){
if( this.$fetchQueue.length==0 ) return this;
//console.log('fetchChunk: processing queue ...');
}
else{
this.$fetchQueue.push(fetchType);
if( this.$fetchQueue.length!=1 ) return this;
//console.log('fetchChunk: processing user input ...');
}
fetchType = this.$fetchQueue[0];
/* Forewarning, this is a bit confusing: when fetching the
previous lines, we're doing so on behalf of the *next* diff
chunk (this.pos.next), and vice versa. */
if(fetchType===this.FetchType.NextUp && !this.pos.next
|| fetchType===this.FetchType.PrevDown && !this.pos.prev){
console.error("Attempt to fetch diff lines but don't have any.");
return this;
}
this.msg(false,"Fetching diff chunk...");
const self = this;
const fOpt = {
urlParams:{
name: this.fileHash, from: 0, to: 0
},
aftersend: ()=>this.msg(false),
onload: function(list){
self.injectResponse(fetchType,up,list);
if( !self.$fetchQueue || self.$fetchQueue.length==0 ) return;
| > > > > > > > > > | | 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 |
This is an async operation. While it is in transit, any calls
to this function will have no effect except (possibly) to emit
a warning. Returns this object.
*/
fetchChunk: function(fetchType){
if( !this.$fetchQueue ) return this; // HACKHACK: are we destroyed?
if( fetchType==this.FetchType.ProcessQueue ){
this.$fetchQueue.shift();
if( this.$fetchQueue.length==0 ) return this;
//console.log('fetchChunk: processing queue ...');
}
else{
this.$fetchQueue.push(fetchType);
if( this.$fetchQueue.length!=1 ) return this;
//console.log('fetchChunk: processing user input ...');
}
fetchType = this.$fetchQueue[0];
if( fetchType==this.FetchType.ProcessQueue ){
/* Unexpected! Clear queue so recovery (manual restart) is possible. */
this.$fetchQueue.length = 0;
return this;
}
/* Forewarning, this is a bit confusing: when fetching the
previous lines, we're doing so on behalf of the *next* diff
chunk (this.pos.next), and vice versa. */
if(fetchType===this.FetchType.NextUp && !this.pos.next
|| fetchType===this.FetchType.PrevDown && !this.pos.prev){
console.error("Attempt to fetch diff lines but don't have any.");
return this;
}
this.msg(false,"Fetching diff chunk...");
const self = this;
const fOpt = {
urlParams:{
name: this.fileHash, from: 0, to: 0
},
aftersend: ()=>this.msg(false),
onload: function(list){
self.injectResponse(fetchType,up,list);
if( !self.$fetchQueue || self.$fetchQueue.length==0 ) return;
/* Keep queue length > 0, or clicks stalled during (unusually lengthy)
injectResponse() may sneak in as soon as setTimeout() allows, find
an empty queue, and therefore start over with queue processing. */
self.$fetchQueue[0] = self.FetchType.ProcessQueue;
setTimeout(self.fetchChunk.bind(self,self.FetchType.ProcessQueue));
}
};
const up = fOpt.urlParams;
if(fetchType===this.FetchType.FillGap){
/* Easiest case: filling a whole gap. */
up.from = this.pos.startLhs;
|
| ︙ | ︙ |
Changes to src/fossil.page.chat.js.
| ︙ | ︙ | |||
216 217 218 219 220 221 222 |
mh1 = m.clientHeight;
D.addClass(old, 'hidden');
D.removeClass(this.e.inputCurrent, 'hidden');
const mh2 = m.clientHeight;
m.scrollTo(0, sTop + (mh1-mh2));
this.e.inputCurrent.value = old.value;
old.value = '';
| < | 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
mh1 = m.clientHeight;
D.addClass(old, 'hidden');
D.removeClass(this.e.inputCurrent, 'hidden');
const mh2 = m.clientHeight;
m.scrollTo(0, sTop + (mh1-mh2));
this.e.inputCurrent.value = old.value;
old.value = '';
return this;
},
/**
If passed true or no arguments, switches to multi-line mode
if currently in single-line mode. If passed false, switches
to single-line mode if currently in multi-line mode. Returns
this.
|
| ︙ | ︙ | |||
1373 1374 1375 1376 1377 1378 1379 |
}
}
});
BlobXferState.clear();
Chat.inputValue("").inputFocus();
};
| | | > | | | | < < | | > > | | | | | > > > | > > | 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 |
}
}
});
BlobXferState.clear();
Chat.inputValue("").inputFocus();
};
const inputWidgetKeydown = function(ev){
if(13 === ev.keyCode){
if(ev.shiftKey){
ev.preventDefault();
ev.stopPropagation();
Chat.e.btnPreview.click();
return false;
}else if((Chat.e.inputSingle===ev.target)
|| (ev.ctrlKey && Chat.e.inputMulti===ev.target)){
/* ^^^ note that it is intended that both ctrl-enter and enter
work for single-line input mode. */
ev.preventDefault();
ev.stopPropagation();
Chat.submitMessage();
return false;
}
}
};
Chat.e.inputSingle
.addEventListener('keydown', inputWidgetKeydown, false);
Chat.e.inputMulti
.addEventListener('keydown', inputWidgetKeydown, false);
Chat.e.btnSubmit.addEventListener('click',(e)=>{
e.preventDefault();
Chat.submitMessage();
return false;
});
(function(){/*Set up #chat-settings-button */
|
| ︙ | ︙ |
Changes to src/fossil.page.fileedit.js.
| ︙ | ︙ | |||
722 723 724 725 726 727 728 |
}
}
);
////////////////////////////////////////////////////////////
// Trigger preview on Ctrl-Enter. This only works on the built-in
// editor widget, not a client-provided one.
P.e.taEditor.addEventListener('keydown',function(ev){
| | | | 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 |
}
}
);
////////////////////////////////////////////////////////////
// Trigger preview on Ctrl-Enter. This only works on the built-in
// editor widget, not a client-provided one.
P.e.taEditor.addEventListener('keydown',function(ev){
if(ev.shiftKey && 13 === ev.keyCode){
ev.preventDefault();
ev.stopPropagation();
P.e.taEditor.blur(/*force change event, if needed*/);
P.tabs.switchToTab(P.e.tabs.preview);
if(!P.e.cbAutoPreview.checked){/* If NOT in auto-preview mode, trigger an update. */
P.preview();
}
return false;
}
}, false);
// If we're in the preview tab, have ctrl-enter switch back to the editor.
document.body.addEventListener('keydown',function(ev){
if(ev.shiftKey && 13 === ev.keyCode){
if(currentTab === P.e.tabs.preview){
ev.preventDefault();
ev.stopPropagation();
P.tabs.switchToTab(P.e.tabs.content);
P.e.taEditor.focus(/*doesn't work for client-supplied editor widget!
And it's slow as molasses for long docs, as focus()
forces a document reflow.*/);
|
| ︙ | ︙ |
Changes to src/fossil.page.pikchrshow.js.
| ︙ | ︙ | |||
96 97 98 99 100 101 102 |
P.e.previewModeToggle,
'\u00a0',
P.e.previewCopyButton,
P.e.previewModeLabel,
P.e.markupAlignWrapper );
////////////////////////////////////////////////////////////
| | | | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
P.e.previewModeToggle,
'\u00a0',
P.e.previewCopyButton,
P.e.previewModeLabel,
P.e.markupAlignWrapper );
////////////////////////////////////////////////////////////
// Trigger preview on Shift-Enter.
P.e.taContent.addEventListener('keydown',function(ev){
if(ev.shiftKey && 13 === ev.keyCode){
ev.preventDefault();
ev.stopPropagation();
P.preview();
return false;
}
}, false);
|
| ︙ | ︙ | |||
388 389 390 391 392 393 394 395 396 397 398 399 400 401 |
this.response.raw;
console.error("svg parsed HTML nodes:",childs);
}
D.append(D.clearElement(preTgt), this.e.taPreviewText);
break;
}
this.e.previewModeLabel.innerText = label;
};
/**
Fetches the preview from the server and updates the preview to
the rendered SVG content or error report.
*/
P.preview = function fp(){
| > | 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 |
this.response.raw;
console.error("svg parsed HTML nodes:",childs);
}
D.append(D.clearElement(preTgt), this.e.taPreviewText);
break;
}
this.e.previewModeLabel.innerText = label;
this.e.taContent.focus(/*not sure why this gets lost on preview!*/);
};
/**
Fetches the preview from the server and updates the preview to
the rendered SVG content or error report.
*/
P.preview = function fp(){
|
| ︙ | ︙ |
Changes to src/fossil.page.wikiedit.js.
| ︙ | ︙ | |||
912 913 914 915 916 917 918 |
}
}
);
////////////////////////////////////////////////////////////
// Trigger preview on Ctrl-Enter. This only works on the built-in
// editor widget, not a client-provided one.
P.e.taEditor.addEventListener('keydown',function(ev){
| | | | 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 |
}
}
);
////////////////////////////////////////////////////////////
// Trigger preview on Ctrl-Enter. This only works on the built-in
// editor widget, not a client-provided one.
P.e.taEditor.addEventListener('keydown',function(ev){
if(ev.shiftKey && 13 === ev.keyCode){
ev.preventDefault();
ev.stopPropagation();
P.e.taEditor.blur(/*force change event, if needed*/);
P.tabs.switchToTab(P.e.tabs.preview);
if(!P.e.cbAutoPreview.checked){/* If NOT in auto-preview mode, trigger an update. */
P.preview();
}
}
}, false);
// If we're in the preview tab, have ctrl-enter switch back to the editor.
document.body.addEventListener('keydown',function(ev){
if(ev.shiftKey && 13 === ev.keyCode){
if(currentTab === P.e.tabs.preview){
ev.preventDefault();
ev.stopPropagation();
P.tabs.switchToTab(P.e.tabs.content);
P.e.taEditor.focus(/*doesn't work for client-supplied editor widget!
And it's slow as molasses for long docs, as focus()
forces a document reflow. */);
|
| ︙ | ︙ |
Changes to src/pikchrshow.c.
| ︙ | ︙ | |||
333 334 335 336 337 338 339 |
"margin-right: 0.5em; vertical-align: middle;"
"}\n");
CX("body.pikchrshow .v-align-middle{"
"vertical-align: middle"
"}\n");
CX(".dragover {border: 3px dotted rgba(0,255,0,0.6)}\n");
} CX("</style>");
| | | 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 |
"margin-right: 0.5em; vertical-align: middle;"
"}\n");
CX("body.pikchrshow .v-align-middle{"
"vertical-align: middle"
"}\n");
CX(".dragover {border: 3px dotted rgba(0,255,0,0.6)}\n");
} CX("</style>");
CX("<div>Input pikchr code and tap Preview (or Shift-Enter) to render "
"it:</div>");
CX("<div id='sbs-wrapper'>"); {
CX("<div id='pikchrshow-form'>"); {
CX("<textarea id='content' name='content' rows='15'>"
"%s</textarea>",zContent/*safe-for-%s*/);
CX("<div id='pikchrshow-controls'>"); {
CX("<button id='pikchr-submit-preview'>Preview</button>");
|
| ︙ | ︙ |
Changes to src/style.fileedit.css.
| ︙ | ︙ | |||
68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
padding: 0;
}
body.fileedit #fileedit-tabs {
margin: 0.5em 0 0 0;
}
body.fileedit #fileedit-tab-preview-wrapper {
overflow: auto;
}
body.fileedit #fileedit-tab-fileselect > h1 {
margin: 0;
}
body.fileedit .fileedit-options.commit-message > div {
display: flex;
flex-direction: column;
| > > > | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
padding: 0;
}
body.fileedit #fileedit-tabs {
margin: 0.5em 0 0 0;
}
body.fileedit #fileedit-tab-preview-wrapper {
overflow: auto;
}
body.fileedit #fileedit-tab-preview-wrapper > pre {
margin: 0;
}
body.fileedit #fileedit-tab-fileselect > h1 {
margin: 0;
}
body.fileedit .fileedit-options.commit-message > div {
display: flex;
flex-direction: column;
|
| ︙ | ︙ |
Changes to src/url.c.
| ︙ | ︙ | |||
194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
if( c==':' ){
pUrlData->port = 0;
i++;
while( (c = zUrl[i])!=0 && fossil_isdigit(c) ){
pUrlData->port = pUrlData->port*10 + c - '0';
i++;
}
pUrlData->hostname = mprintf("%s:%d", pUrlData->name, pUrlData->port);
}else{
pUrlData->port = pUrlData->dfltPort;
pUrlData->hostname = pUrlData->name;
}
dehttpize(pUrlData->name);
pUrlData->path = mprintf("%s", &zUrl[i]);
| > | 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
if( c==':' ){
pUrlData->port = 0;
i++;
while( (c = zUrl[i])!=0 && fossil_isdigit(c) ){
pUrlData->port = pUrlData->port*10 + c - '0';
i++;
}
if( c!=0 && c!='/' ) fossil_fatal("url missing '/' after port number");
pUrlData->hostname = mprintf("%s:%d", pUrlData->name, pUrlData->port);
}else{
pUrlData->port = pUrlData->dfltPort;
pUrlData->hostname = pUrlData->name;
}
dehttpize(pUrlData->name);
pUrlData->path = mprintf("%s", &zUrl[i]);
|
| ︙ | ︙ | |||
674 675 676 677 678 679 680 |
if( sqlite3_strnicmp(zTail, "www.", 4)==0 && strchr(zTail+4,'.')!=0 ){
/* Remove the "www." prefix if there are more "." characters later.
** But don't remove the "www." prefix if what follows is the suffix.
** forum:/forumpost/74e111a2ee */
zTail += 4;
}
if( zTail[0]==0 ) return 0;
| | > | 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 |
if( sqlite3_strnicmp(zTail, "www.", 4)==0 && strchr(zTail+4,'.')!=0 ){
/* Remove the "www." prefix if there are more "." characters later.
** But don't remove the "www." prefix if what follows is the suffix.
** forum:/forumpost/74e111a2ee */
zTail += 4;
}
if( zTail[0]==0 ) return 0;
for(i=0; zTail[i] && zTail[i]!='.' && zTail[i]!='?' &&
zTail[i]!=':' && zTail[i]!='/'; i++){}
if( i==0 ) return 0;
return mprintf("%.*s", i, zTail);
}
/*
** COMMAND: test-url-basename
** Usage: %fossil test-url-basenames URL ...
|
| ︙ | ︙ |
Changes to src/wiki.c.
| ︙ | ︙ | |||
2426 2427 2428 2429 2430 2431 2432 |
const int fTechnote = find_option("technote","t",0)!=0;
const int showIds = find_option("show-technote-ids","s",0)!=0;
verify_all_options();
if (fTechnote==0){
db_prepare(&q, listAllWikiPages/*works-like:""*/);
}else{
db_prepare(&q,
| | | 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 |
const int fTechnote = find_option("technote","t",0)!=0;
const int showIds = find_option("show-technote-ids","s",0)!=0;
verify_all_options();
if (fTechnote==0){
db_prepare(&q, listAllWikiPages/*works-like:""*/);
}else{
db_prepare(&q,
"SELECT datetime(e.mtime), substr(t.tagname,7), e.objid"
" FROM event e, tag t"
" WHERE e.type='e'"
" AND e.tagid IS NOT NULL"
" AND t.tagid=e.tagid"
" ORDER BY e.mtime DESC /*sort*/"
);
}
|
| ︙ | ︙ |
Changes to www/changes.wiki.
| ︙ | ︙ | |||
43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
selection of notification sounds via unversioned files].
* The [/help?cmd=/chat|/chat] messages now use fossil's full complement of
markdown features, instead of the prior small subset of markup it
previously supported. This retroactively applies to all chat messages,
as they are markdown-processed when they are sent instead of when they
are saved. Added a preview mode so messages can be previewed before
being sent. See [./chat.md#usage|the chat docs] for more details.
<h2 id='v2_16'>Changes for Version 2.16 (2021-07-02)</h2>
* <b>Security:</b> Fix the client-side TLS so that it verifies that the
server hostname matches its certificate.
* The default "ssh" command on Windows is changed to "ssh" instead of the
legacy "plink", as ssh is now generally available on Windows systems.
Installations that still need to use the legacy "plink" can make that
| > > > > > | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
selection of notification sounds via unversioned files].
* The [/help?cmd=/chat|/chat] messages now use fossil's full complement of
markdown features, instead of the prior small subset of markup it
previously supported. This retroactively applies to all chat messages,
as they are markdown-processed when they are sent instead of when they
are saved. Added a preview mode so messages can be previewed before
being sent. See [./chat.md#usage|the chat docs] for more details.
* The hotkey to activate preview mode in [/help?cmd=/wikiedit|/wikiedit],
[/help?cmd=/fileedit|/fileedit], and [/help?cmd=/pikchrshow|/pikchrshow]
was changed from ctrl-enter to shift-enter in order to align with
[/help?cmd=/chat|/chat]'s new preview feature and related future
changes.
<h2 id='v2_16'>Changes for Version 2.16 (2021-07-02)</h2>
* <b>Security:</b> Fix the client-side TLS so that it verifies that the
server hostname matches its certificate.
* The default "ssh" command on Windows is changed to "ssh" instead of the
legacy "plink", as ssh is now generally available on Windows systems.
Installations that still need to use the legacy "plink" can make that
|
| ︙ | ︙ |