Fossil SCM

Ported /chat from window.fetch to fossil.fetch, as FF versions as recently as 2017 fail with window.fetch. Needs more testing before merge but seems to work.

stephan 2021-03-21 18:25 trunk
Commit c97364320972ec702c1f602154b57f04518d3cd12e876cdd5672387b5195942c
+1 -1
--- src/chat.c
+++ src/chat.c
@@ -186,11 +186,11 @@
186186
@ <div id='chat-messages-wrapper'>
187187
/* New chat messages get inserted immediately after this element */
188188
@ <span id='message-inject-point'></span>
189189
@ </div>
190190
191
- builtin_fossil_js_bundle_or("popupwidget", "storage", NULL);
191
+ builtin_fossil_js_bundle_or("popupwidget", "storage", "fetch", NULL);
192192
/* Always in-line the javascript for the chat page */
193193
@ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */
194194
/* We need an onload handler to ensure that window.fossil is
195195
initialized before the chat init code runs. */
196196
@ window.addEventListener('load', function(){
197197
--- src/chat.c
+++ src/chat.c
@@ -186,11 +186,11 @@
186 @ <div id='chat-messages-wrapper'>
187 /* New chat messages get inserted immediately after this element */
188 @ <span id='message-inject-point'></span>
189 @ </div>
190
191 builtin_fossil_js_bundle_or("popupwidget", "storage", NULL);
192 /* Always in-line the javascript for the chat page */
193 @ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */
194 /* We need an onload handler to ensure that window.fossil is
195 initialized before the chat init code runs. */
196 @ window.addEventListener('load', function(){
197
--- src/chat.c
+++ src/chat.c
@@ -186,11 +186,11 @@
186 @ <div id='chat-messages-wrapper'>
187 /* New chat messages get inserted immediately after this element */
188 @ <span id='message-inject-point'></span>
189 @ </div>
190
191 builtin_fossil_js_bundle_or("popupwidget", "storage", "fetch", NULL);
192 /* Always in-line the javascript for the chat page */
193 @ <script nonce="%h(style_nonce())">/* chat.c:%d(__LINE__) */
194 /* We need an onload handler to ensure that window.fossil is
195 initialized before the chat init code runs. */
196 @ window.addEventListener('load', function(){
197
+82 -63
--- src/chat.js
+++ src/chat.js
@@ -397,10 +397,12 @@
397397
this.playNewMessageSound.uri = uri;
398398
this.settings.set('audible-alert', !!uri);
399399
return this;
400400
}
401401
};
402
+ F.fetch.beforesend = ()=>cs.ajaxStart();
403
+ F.fetch.aftersend = ()=>cs.ajaxEnd();
402404
cs.e.inputCurrent = cs.e.inputSingle;
403405
/* Install default settings... */
404406
Object.keys(cs.settings.defaults).forEach(function(k){
405407
const v = cs.settings.get(k,cs);
406408
if(cs===v) cs.settings.set(k,cs.settings.defaults[k]);
@@ -538,18 +540,15 @@
538540
e = this.getMessageElemById(id);
539541
}
540542
if(!(e instanceof HTMLElement)) return;
541543
if(this.userMayDelete(e)){
542544
this.ajaxStart();
543
- fetch("chat-delete/" + id)
544
- .then(function(response){
545
- if(!response.ok) throw cs._newResponseError(response);
546
- return response;
547
- })
548
- .then(()=>this.deleteMessageElem(e))
549
- .catch(err=>this.reportErrorAsMessage(err))
550
- .finally(()=>this.ajaxEnd());
545
+ F.fetch("chat-delete/" + id, {
546
+ responseType: 'json',
547
+ onload:(r)=>this.deleteMessageElem(r),
548
+ onerror:(err)=>this.reportErrorAsMessage(err)
549
+ });
551550
}else{
552551
this.deleteMessageElem(id);
553552
}
554553
};
555554
document.addEventListener('visibilitychange', function(ev){
@@ -878,27 +877,25 @@
878877
const file = BlobXferState.blob || this.e.inputFile.files[0];
879878
if(file) fd.set("file", file);
880879
if( !msg && !file ) return;
881880
const self = this;
882881
fd.set("lmtime", localTime8601(new Date()));
883
- fetch("chat-send",{
884
- method: 'POST',
885
- body: fd
886
- }).then((x)=>{
887
- if(x.ok) return x.text();
888
- else throw Chat._newResponseError(x);
889
- }).then(function(txt){
882
+ F.fetch("chat-send",{
883
+ payload: fd,
884
+ responseType: 'text',
885
+ onerror:(err)=>this.reportErrorAsMessage(err),
886
+ onload:function(txt){
890887
if(!txt) return/*success response*/;
891888
try{
892889
const json = JSON.parse(txt);
893890
self.newContent({msgs:[json]});
894891
}catch(e){
895892
self.reportError(e);
896893
return;
897894
}
898
- })
899
- .catch((e)=>this.reportErrorAsMessage(e));
895
+ }
896
+ });
900897
BlobXferState.clear();
901898
Chat.inputValue("").inputFocus();
902899
};
903900
904901
Chat.e.inputSingle.addEventListener('keydown',function(ev){
@@ -1155,35 +1152,36 @@
11551152
D.fieldset(loadLegend), "id", "load-msg-toolbar"
11561153
);
11571154
Chat.disableDuringAjax.push(toolbar);
11581155
/* Loads the next n oldest messages, or all previous history if n is negative. */
11591156
const loadOldMessages = function(n){
1160
- Chat.ajaxStart();
11611157
Chat.e.messagesWrapper.classList.add('loading');
11621158
Chat._isBatchLoading = true;
1163
- var gotMessages = false;
11641159
const scrollHt = Chat.e.messagesWrapper.scrollHeight,
11651160
scrollTop = Chat.e.messagesWrapper.scrollTop;
1166
- fetch("chat-poll?before="+Chat.mnMsg+"&n="+n)
1167
- .then(Chat._fetchJsonOrError)
1168
- .then(function(x){
1169
- gotMessages = x.msgs.length;
1161
+ F.fetch("chat-poll",{
1162
+ urlParams:{
1163
+ before: Chat.mnMsg,
1164
+ n: n
1165
+ },
1166
+ responseType: 'json',
1167
+ onerror:function(err){
1168
+ Chat.reportErrorAsMessage(err);
1169
+ Chat._isBatchLoading = false;
1170
+ },
1171
+ onload:function(x){
1172
+ let gotMessages = x.msgs.length;
11701173
newcontent(x,true);
1171
- })
1172
- .catch(e=>Chat.reportErrorAsMessage(e))
1173
- .finally(function(){
11741174
Chat._isBatchLoading = false;
1175
- Chat.e.messagesWrapper.classList.remove('loading');
1176
- Chat.ajaxEnd();
11771175
if(Chat._gotServerError){
1178
- F.toast.error("Got an error response from the server. ",
1179
- "See message for details.");
1176
+ Chat._gotServerError = false;
11801177
return;
1181
- }else if(n<0/*we asked for all history*/
1178
+ }
1179
+ if(n<0/*we asked for all history*/
11821180
|| 0===gotMessages/*we found no history*/
11831181
|| (n>0 && gotMessages<n /*we got fewer history entries than requested*/)
1184
- || (false!==gotMessages && n===0 && gotMessages<Chat.loadMessageCount
1182
+ || (n===0 && gotMessages<Chat.loadMessageCount
11851183
/*we asked for default amount and got fewer than that.*/)){
11861184
/* We've loaded all history. Permanently disable the
11871185
history-load toolbar and keep it from being re-enabled
11881186
via the ajaxStart()/ajaxEnd() mechanism... */
11891187
const div = Chat.e.loadOlderToolbar.querySelector('div');
@@ -1199,11 +1197,16 @@
11991197
was requested, per user request */
12001198
Chat.e.messagesWrapper.scrollTo(
12011199
0, Chat.e.messagesWrapper.scrollHeight - scrollHt + scrollTop
12021200
);
12031201
}
1204
- });
1202
+ },
1203
+ aftersend:function(){
1204
+ Chat.e.messagesWrapper.classList.remove('loading');
1205
+ Chat.ajaxEnd();
1206
+ }
1207
+ });
12051208
};
12061209
const wrapper = D.div(); /* browsers don't all properly handle >1 child in a fieldset */;
12071210
D.append(toolbar, wrapper);
12081211
var btn = D.button("Previous "+Chat.loadMessageCount+" messages");
12091212
D.append(wrapper, btn);
@@ -1213,47 +1216,63 @@
12131216
btn.addEventListener('click',()=>loadOldMessages(-1));
12141217
D.append(Chat.e.messagesWrapper, toolbar);
12151218
toolbar.disabled = true /*will be enabled when msg load finishes */;
12161219
})()/*end history loading widget setup*/;
12171220
1218
- async function poll(isFirstCall){
1221
+ const afterFetch = function(isFirstCall){
1222
+ if(isFirstCall){
1223
+ Chat.ajaxEnd();
1224
+ Chat.e.messagesWrapper.classList.remove('loading');
1225
+ setTimeout(function(){
1226
+ Chat.scrollMessagesTo(1);
1227
+ }, 250);
1228
+ }
1229
+ if(Chat._gotServerError && Chat.intervalTimer){
1230
+ clearInterval(Chat.intervalTimer);
1231
+ Chat.reportErrorAsMessage(
1232
+ "Shutting down chat poller due to server-side error. ",
1233
+ "Reload this page to reactivate it.");
1234
+ delete Chat.intervalTimer;
1235
+ }
1236
+ poll.running = false;
1237
+ };
1238
+ const poll = async function(){
12191239
if(poll.running) return;
12201240
poll.running = true;
1221
- if(isFirstCall){
1241
+ if(0===poll.runCount++){
12221242
Chat.ajaxStart();
12231243
Chat.e.messagesWrapper.classList.add('loading');
12241244
}
1225
- Chat._isBatchLoading = isFirstCall;
1226
- var p = fetch("chat-poll?name=" + Chat.mxMsg);
1227
- p.then(Chat._fetchJsonOrError)
1228
- .then(y=>newcontent(y))
1229
- .catch(e=>console.error(e))
1230
- /* ^^^ we don't use Chat.reportError(e) here b/c the polling
1231
- fails exepectedly when it times out, but is then immediately
1232
- resumed, and reportError() produces a loud error message. */
1233
- .finally(function(){
1234
- if(isFirstCall){
1235
- Chat._isBatchLoading = false;
1236
- Chat.ajaxEnd();
1237
- Chat.e.messagesWrapper.classList.remove('loading');
1238
- setTimeout(function(){
1239
- Chat.scrollMessagesTo(1);
1240
- }, 250);
1241
- }
1242
- if(Chat._gotServerError && Chat.intervalTimer){
1243
- clearInterval(Chat.intervalTimer);
1244
- delete Chat.intervalTimer;
1245
- }
1246
- poll.running=false;
1247
- });
1248
- }
1245
+ Chat._isBatchLoading = (1===poll.runCount);
1246
+ F.fetch("chat-poll",{
1247
+ timeout: 420 * 1000/*FIXME: get the value from the server*/,
1248
+ urlParams:{
1249
+ name: Chat.mxMsg
1250
+ },
1251
+ responseType: "json",
1252
+ // Disable the ajax start/end handling for this long-polling op:
1253
+ beforesend: function(){},
1254
+ aftersend: function(){},
1255
+ onerror:function(err){
1256
+ Chat._isBatchLoading = false;
1257
+ console.error(err);
1258
+ /* ^^^ we don't use Chat.reportError() here b/c the polling
1259
+ fails exepectedly when it times out, but is then immediately
1260
+ resumed, and reportError() produces a loud error message. */
1261
+ afterFetch(1===poll.runCount);
1262
+ },
1263
+ onload:function(y){
1264
+ newcontent(y);
1265
+ Chat._isBatchLoading = false;
1266
+ afterFetch(1===poll.runCount);
1267
+ }
1268
+ });
1269
+ };
1270
+ poll.runCount = 0;
12491271
Chat._gotServerError = poll.running = false;
1250
- poll(true);
1251
- if(!Chat._gotServerError){
1252
- Chat.intervalTimer = setInterval(poll, 1000);
1253
- }
1272
+ Chat.intervalTimer = setInterval(poll, 1000);
12541273
if( window.fossil.config.chat.fromcli ){
12551274
Chat.chatOnlyMode(true);
12561275
}
12571276
12581277
F.page.chat = Chat/* enables testing the APIs via the dev tools */;
12591278
})();
12601279
--- src/chat.js
+++ src/chat.js
@@ -397,10 +397,12 @@
397 this.playNewMessageSound.uri = uri;
398 this.settings.set('audible-alert', !!uri);
399 return this;
400 }
401 };
 
 
402 cs.e.inputCurrent = cs.e.inputSingle;
403 /* Install default settings... */
404 Object.keys(cs.settings.defaults).forEach(function(k){
405 const v = cs.settings.get(k,cs);
406 if(cs===v) cs.settings.set(k,cs.settings.defaults[k]);
@@ -538,18 +540,15 @@
538 e = this.getMessageElemById(id);
539 }
540 if(!(e instanceof HTMLElement)) return;
541 if(this.userMayDelete(e)){
542 this.ajaxStart();
543 fetch("chat-delete/" + id)
544 .then(function(response){
545 if(!response.ok) throw cs._newResponseError(response);
546 return response;
547 })
548 .then(()=>this.deleteMessageElem(e))
549 .catch(err=>this.reportErrorAsMessage(err))
550 .finally(()=>this.ajaxEnd());
551 }else{
552 this.deleteMessageElem(id);
553 }
554 };
555 document.addEventListener('visibilitychange', function(ev){
@@ -878,27 +877,25 @@
878 const file = BlobXferState.blob || this.e.inputFile.files[0];
879 if(file) fd.set("file", file);
880 if( !msg && !file ) return;
881 const self = this;
882 fd.set("lmtime", localTime8601(new Date()));
883 fetch("chat-send",{
884 method: 'POST',
885 body: fd
886 }).then((x)=>{
887 if(x.ok) return x.text();
888 else throw Chat._newResponseError(x);
889 }).then(function(txt){
890 if(!txt) return/*success response*/;
891 try{
892 const json = JSON.parse(txt);
893 self.newContent({msgs:[json]});
894 }catch(e){
895 self.reportError(e);
896 return;
897 }
898 })
899 .catch((e)=>this.reportErrorAsMessage(e));
900 BlobXferState.clear();
901 Chat.inputValue("").inputFocus();
902 };
903
904 Chat.e.inputSingle.addEventListener('keydown',function(ev){
@@ -1155,35 +1152,36 @@
1155 D.fieldset(loadLegend), "id", "load-msg-toolbar"
1156 );
1157 Chat.disableDuringAjax.push(toolbar);
1158 /* Loads the next n oldest messages, or all previous history if n is negative. */
1159 const loadOldMessages = function(n){
1160 Chat.ajaxStart();
1161 Chat.e.messagesWrapper.classList.add('loading');
1162 Chat._isBatchLoading = true;
1163 var gotMessages = false;
1164 const scrollHt = Chat.e.messagesWrapper.scrollHeight,
1165 scrollTop = Chat.e.messagesWrapper.scrollTop;
1166 fetch("chat-poll?before="+Chat.mnMsg+"&n="+n)
1167 .then(Chat._fetchJsonOrError)
1168 .then(function(x){
1169 gotMessages = x.msgs.length;
 
 
 
 
 
 
 
 
1170 newcontent(x,true);
1171 })
1172 .catch(e=>Chat.reportErrorAsMessage(e))
1173 .finally(function(){
1174 Chat._isBatchLoading = false;
1175 Chat.e.messagesWrapper.classList.remove('loading');
1176 Chat.ajaxEnd();
1177 if(Chat._gotServerError){
1178 F.toast.error("Got an error response from the server. ",
1179 "See message for details.");
1180 return;
1181 }else if(n<0/*we asked for all history*/
 
1182 || 0===gotMessages/*we found no history*/
1183 || (n>0 && gotMessages<n /*we got fewer history entries than requested*/)
1184 || (false!==gotMessages && n===0 && gotMessages<Chat.loadMessageCount
1185 /*we asked for default amount and got fewer than that.*/)){
1186 /* We've loaded all history. Permanently disable the
1187 history-load toolbar and keep it from being re-enabled
1188 via the ajaxStart()/ajaxEnd() mechanism... */
1189 const div = Chat.e.loadOlderToolbar.querySelector('div');
@@ -1199,11 +1197,16 @@
1199 was requested, per user request */
1200 Chat.e.messagesWrapper.scrollTo(
1201 0, Chat.e.messagesWrapper.scrollHeight - scrollHt + scrollTop
1202 );
1203 }
1204 });
 
 
 
 
 
1205 };
1206 const wrapper = D.div(); /* browsers don't all properly handle >1 child in a fieldset */;
1207 D.append(toolbar, wrapper);
1208 var btn = D.button("Previous "+Chat.loadMessageCount+" messages");
1209 D.append(wrapper, btn);
@@ -1213,47 +1216,63 @@
1213 btn.addEventListener('click',()=>loadOldMessages(-1));
1214 D.append(Chat.e.messagesWrapper, toolbar);
1215 toolbar.disabled = true /*will be enabled when msg load finishes */;
1216 })()/*end history loading widget setup*/;
1217
1218 async function poll(isFirstCall){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1219 if(poll.running) return;
1220 poll.running = true;
1221 if(isFirstCall){
1222 Chat.ajaxStart();
1223 Chat.e.messagesWrapper.classList.add('loading');
1224 }
1225 Chat._isBatchLoading = isFirstCall;
1226 var p = fetch("chat-poll?name=" + Chat.mxMsg);
1227 p.then(Chat._fetchJsonOrError)
1228 .then(y=>newcontent(y))
1229 .catch(e=>console.error(e))
1230 /* ^^^ we don't use Chat.reportError(e) here b/c the polling
1231 fails exepectedly when it times out, but is then immediately
1232 resumed, and reportError() produces a loud error message. */
1233 .finally(function(){
1234 if(isFirstCall){
1235 Chat._isBatchLoading = false;
1236 Chat.ajaxEnd();
1237 Chat.e.messagesWrapper.classList.remove('loading');
1238 setTimeout(function(){
1239 Chat.scrollMessagesTo(1);
1240 }, 250);
1241 }
1242 if(Chat._gotServerError && Chat.intervalTimer){
1243 clearInterval(Chat.intervalTimer);
1244 delete Chat.intervalTimer;
1245 }
1246 poll.running=false;
1247 });
1248 }
 
 
1249 Chat._gotServerError = poll.running = false;
1250 poll(true);
1251 if(!Chat._gotServerError){
1252 Chat.intervalTimer = setInterval(poll, 1000);
1253 }
1254 if( window.fossil.config.chat.fromcli ){
1255 Chat.chatOnlyMode(true);
1256 }
1257
1258 F.page.chat = Chat/* enables testing the APIs via the dev tools */;
1259 })();
1260
--- src/chat.js
+++ src/chat.js
@@ -397,10 +397,12 @@
397 this.playNewMessageSound.uri = uri;
398 this.settings.set('audible-alert', !!uri);
399 return this;
400 }
401 };
402 F.fetch.beforesend = ()=>cs.ajaxStart();
403 F.fetch.aftersend = ()=>cs.ajaxEnd();
404 cs.e.inputCurrent = cs.e.inputSingle;
405 /* Install default settings... */
406 Object.keys(cs.settings.defaults).forEach(function(k){
407 const v = cs.settings.get(k,cs);
408 if(cs===v) cs.settings.set(k,cs.settings.defaults[k]);
@@ -538,18 +540,15 @@
540 e = this.getMessageElemById(id);
541 }
542 if(!(e instanceof HTMLElement)) return;
543 if(this.userMayDelete(e)){
544 this.ajaxStart();
545 F.fetch("chat-delete/" + id, {
546 responseType: 'json',
547 onload:(r)=>this.deleteMessageElem(r),
548 onerror:(err)=>this.reportErrorAsMessage(err)
549 });
 
 
 
550 }else{
551 this.deleteMessageElem(id);
552 }
553 };
554 document.addEventListener('visibilitychange', function(ev){
@@ -878,27 +877,25 @@
877 const file = BlobXferState.blob || this.e.inputFile.files[0];
878 if(file) fd.set("file", file);
879 if( !msg && !file ) return;
880 const self = this;
881 fd.set("lmtime", localTime8601(new Date()));
882 F.fetch("chat-send",{
883 payload: fd,
884 responseType: 'text',
885 onerror:(err)=>this.reportErrorAsMessage(err),
886 onload:function(txt){
 
 
887 if(!txt) return/*success response*/;
888 try{
889 const json = JSON.parse(txt);
890 self.newContent({msgs:[json]});
891 }catch(e){
892 self.reportError(e);
893 return;
894 }
895 }
896 });
897 BlobXferState.clear();
898 Chat.inputValue("").inputFocus();
899 };
900
901 Chat.e.inputSingle.addEventListener('keydown',function(ev){
@@ -1155,35 +1152,36 @@
1152 D.fieldset(loadLegend), "id", "load-msg-toolbar"
1153 );
1154 Chat.disableDuringAjax.push(toolbar);
1155 /* Loads the next n oldest messages, or all previous history if n is negative. */
1156 const loadOldMessages = function(n){
 
1157 Chat.e.messagesWrapper.classList.add('loading');
1158 Chat._isBatchLoading = true;
 
1159 const scrollHt = Chat.e.messagesWrapper.scrollHeight,
1160 scrollTop = Chat.e.messagesWrapper.scrollTop;
1161 F.fetch("chat-poll",{
1162 urlParams:{
1163 before: Chat.mnMsg,
1164 n: n
1165 },
1166 responseType: 'json',
1167 onerror:function(err){
1168 Chat.reportErrorAsMessage(err);
1169 Chat._isBatchLoading = false;
1170 },
1171 onload:function(x){
1172 let gotMessages = x.msgs.length;
1173 newcontent(x,true);
 
 
 
1174 Chat._isBatchLoading = false;
 
 
1175 if(Chat._gotServerError){
1176 Chat._gotServerError = false;
 
1177 return;
1178 }
1179 if(n<0/*we asked for all history*/
1180 || 0===gotMessages/*we found no history*/
1181 || (n>0 && gotMessages<n /*we got fewer history entries than requested*/)
1182 || (n===0 && gotMessages<Chat.loadMessageCount
1183 /*we asked for default amount and got fewer than that.*/)){
1184 /* We've loaded all history. Permanently disable the
1185 history-load toolbar and keep it from being re-enabled
1186 via the ajaxStart()/ajaxEnd() mechanism... */
1187 const div = Chat.e.loadOlderToolbar.querySelector('div');
@@ -1199,11 +1197,16 @@
1197 was requested, per user request */
1198 Chat.e.messagesWrapper.scrollTo(
1199 0, Chat.e.messagesWrapper.scrollHeight - scrollHt + scrollTop
1200 );
1201 }
1202 },
1203 aftersend:function(){
1204 Chat.e.messagesWrapper.classList.remove('loading');
1205 Chat.ajaxEnd();
1206 }
1207 });
1208 };
1209 const wrapper = D.div(); /* browsers don't all properly handle >1 child in a fieldset */;
1210 D.append(toolbar, wrapper);
1211 var btn = D.button("Previous "+Chat.loadMessageCount+" messages");
1212 D.append(wrapper, btn);
@@ -1213,47 +1216,63 @@
1216 btn.addEventListener('click',()=>loadOldMessages(-1));
1217 D.append(Chat.e.messagesWrapper, toolbar);
1218 toolbar.disabled = true /*will be enabled when msg load finishes */;
1219 })()/*end history loading widget setup*/;
1220
1221 const afterFetch = function(isFirstCall){
1222 if(isFirstCall){
1223 Chat.ajaxEnd();
1224 Chat.e.messagesWrapper.classList.remove('loading');
1225 setTimeout(function(){
1226 Chat.scrollMessagesTo(1);
1227 }, 250);
1228 }
1229 if(Chat._gotServerError && Chat.intervalTimer){
1230 clearInterval(Chat.intervalTimer);
1231 Chat.reportErrorAsMessage(
1232 "Shutting down chat poller due to server-side error. ",
1233 "Reload this page to reactivate it.");
1234 delete Chat.intervalTimer;
1235 }
1236 poll.running = false;
1237 };
1238 const poll = async function(){
1239 if(poll.running) return;
1240 poll.running = true;
1241 if(0===poll.runCount++){
1242 Chat.ajaxStart();
1243 Chat.e.messagesWrapper.classList.add('loading');
1244 }
1245 Chat._isBatchLoading = (1===poll.runCount);
1246 F.fetch("chat-poll",{
1247 timeout: 420 * 1000/*FIXME: get the value from the server*/,
1248 urlParams:{
1249 name: Chat.mxMsg
1250 },
1251 responseType: "json",
1252 // Disable the ajax start/end handling for this long-polling op:
1253 beforesend: function(){},
1254 aftersend: function(){},
1255 onerror:function(err){
1256 Chat._isBatchLoading = false;
1257 console.error(err);
1258 /* ^^^ we don't use Chat.reportError() here b/c the polling
1259 fails exepectedly when it times out, but is then immediately
1260 resumed, and reportError() produces a loud error message. */
1261 afterFetch(1===poll.runCount);
1262 },
1263 onload:function(y){
1264 newcontent(y);
1265 Chat._isBatchLoading = false;
1266 afterFetch(1===poll.runCount);
1267 }
1268 });
1269 };
1270 poll.runCount = 0;
1271 Chat._gotServerError = poll.running = false;
1272 Chat.intervalTimer = setInterval(poll, 1000);
 
 
 
1273 if( window.fossil.config.chat.fromcli ){
1274 Chat.chatOnlyMode(true);
1275 }
1276
1277 F.page.chat = Chat/* enables testing the APIs via the dev tools */;
1278 })();
1279
--- src/fossil.fetch.js
+++ src/fossil.fetch.js
@@ -86,11 +86,11 @@
8686
- timeout: integer in milliseconds specifying the XHR timeout
8787
duration. Default = fossil.fetch.timeout.
8888
8989
When an options object does not provide
9090
onload/onerror/beforesend/aftersend handlers of its own, this
91
- function falls to defaults which are member properties of this
91
+ function falls back to defaults which are member properties of this
9292
function with the same name, e.g. fossil.fetch.onload(). The
9393
default onload/onerror implementations route the data through the
9494
dev console and (for onerror()) through fossil.error(). The default
9595
beforesend/aftersend are no-ops. Individual pages may overwrite
9696
those members to provide default implementations suitable for the
9797
--- src/fossil.fetch.js
+++ src/fossil.fetch.js
@@ -86,11 +86,11 @@
86 - timeout: integer in milliseconds specifying the XHR timeout
87 duration. Default = fossil.fetch.timeout.
88
89 When an options object does not provide
90 onload/onerror/beforesend/aftersend handlers of its own, this
91 function falls to defaults which are member properties of this
92 function with the same name, e.g. fossil.fetch.onload(). The
93 default onload/onerror implementations route the data through the
94 dev console and (for onerror()) through fossil.error(). The default
95 beforesend/aftersend are no-ops. Individual pages may overwrite
96 those members to provide default implementations suitable for the
97
--- src/fossil.fetch.js
+++ src/fossil.fetch.js
@@ -86,11 +86,11 @@
86 - timeout: integer in milliseconds specifying the XHR timeout
87 duration. Default = fossil.fetch.timeout.
88
89 When an options object does not provide
90 onload/onerror/beforesend/aftersend handlers of its own, this
91 function falls back to defaults which are member properties of this
92 function with the same name, e.g. fossil.fetch.onload(). The
93 default onload/onerror implementations route the data through the
94 dev console and (for onerror()) through fossil.error(). The default
95 beforesend/aftersend are no-ops. Individual pages may overwrite
96 those members to provide default implementations suitable for the
97

Keyboard Shortcuts

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