]> git.wh0rd.org - tt-rss.git/blame - tt-rss.js
fix sql syntax error when exporting opml w/o cats
[tt-rss.git] / tt-rss.js
CommitLineData
1cd17194 1var xmlhttp = false;
76798ff3 2var total_unread = 0;
525116d4 3var first_run = true;
8143ae1f 4var display_tags = false;
806a3d14 5var global_unread = -1;
21703604 6var active_title_text = "";
21703604 7var current_subtitle = "";
c6784aea 8var daemon_enabled = false;
0d51e25d 9var daemon_refresh_only = false;
15da5cc1 10var _qfd_deleted_feed = 0;
2bf6e0a8 11var firsttime_update = true;
c441662f 12var last_refetch = 0;
76b4eae1 13var cookie_lifetime = 0;
33d13e72 14var active_feed_id = 0;
0a6c4846 15var active_feed_is_cat = false;
9e397d0f 16var number_of_feeds = 0;
15da5cc1 17
a58069db 18var xmlhttp = Ajax.getTransport();
abbe0154 19var xmlhttp_ctr = Ajax.getTransport();
1cd17194 20
1035fcec 21var init_params = new Object();
3ac2b520 22
8143ae1f
AD
23function toggleTags() {
24 display_tags = !display_tags;
25
26 var p = document.getElementById("dispSwitchPrompt");
27
28 if (display_tags) {
29 p.innerHTML = "display feeds";
30 } else {
31 p.innerHTML = "display tags";
32 }
33
807f452a
AD
34 notify("Loading, please wait...");
35
8143ae1f
AD
36 updateFeedList();
37}
38
6de5d056 39function dlg_frefresh_callback() {
abbe0154 40 if (xmlhttp.readyState == 4) {
a58d997c 41// notify(xmlhttp.responseText);
abbe0154
AD
42
43 if (getActiveFeedId() == _qfd_deleted_feed) {
44 var h = document.getElementById("headlines-frame");
45 if (h) {
46 h.innerHTML = "<div class='whiteBox'>No feed selected.</div>";
47 }
48 }
49
0e9dd1ba 50 setTimeout('updateFeedList(false, false)', 50);
eff4997c 51 closeInfoBox();
c0e5a40e 52 }
1cd17194 53}
e2f8f7b4 54
8158c57a 55function refetch_callback() {
abbe0154 56 if (xmlhttp_ctr.readyState == 4) {
7719618b 57 try {
310da49d 58
c441662f
AD
59 var date = new Date();
60
61 last_refetch = date.getTime() / 1000;
62
abbe0154 63 if (!xmlhttp_ctr.responseXML) {
0530ddd8 64 notify("refetch_callback: backend did not return valid XML", true, true);
7719618b
AD
65 return;
66 }
67
abbe0154 68 var reply = xmlhttp_ctr.responseXML.firstChild;
262bd8ea 69
7719618b 70 if (!reply) {
0530ddd8 71 notify("refetch_callback: backend did not return expected XML object", true, true);
e2cb4c6d 72 updateTitle("");
7719618b
AD
73 return;
74 }
262bd8ea 75
7719618b
AD
76 var error_code = reply.getAttribute("error-code");
77
78 if (error_code && error_code != 0) {
af106b0e 79 return fatalError(error_code, reply.getAttribute("error-msg"));
7719618b 80 }
f54f515f
AD
81
82 var counters = reply.firstChild;
7719618b 83
f54f515f 84 parse_counters(counters, true);
c6784aea 85
71ad883b
AD
86 var runtime_info = counters.nextSibling;
87
88 parse_runtime_info(runtime_info);
89
0ee1d1a0
AD
90 debug("refetch_callback: done");
91
0d51e25d 92 if (!daemon_enabled && !daemon_refresh_only) {
c6784aea 93 notify("All feeds updated.");
5a180505 94 updateTitle("");
4c059b7b
AD
95 } else {
96 notify("");
c6784aea 97 }
7719618b
AD
98 } catch (e) {
99 exception_error("refetch_callback", e);
e2cb4c6d 100 updateTitle("");
7719618b 101 }
090e250b
AD
102 }
103}
1a66d16e 104
295f9b42
AD
105function backend_sanity_check_callback() {
106
107 if (xmlhttp.readyState == 4) {
295f9b42 108
7719618b
AD
109 try {
110
111 if (!xmlhttp.responseXML) {
462a192b 112 fatalError(3, "[D001, Received reply is not XML]: " + xmlhttp.responseText);
7719618b
AD
113 return;
114 }
295f9b42 115
3ac2b520 116 var reply = xmlhttp.responseXML.firstChild.firstChild;
7719618b
AD
117
118 if (!reply) {
af106b0e 119 fatalError(3, "[D002, Invalid RPC reply]: " + xmlhttp.responseText);
7719618b
AD
120 return;
121 }
122
123 var error_code = reply.getAttribute("error-code");
124
125 if (error_code && error_code != 0) {
af106b0e 126 return fatalError(error_code, reply.getAttribute("error-msg"));
7719618b
AD
127 }
128
0ee1d1a0
AD
129 debug("sanity check ok");
130
3ac2b520
AD
131 var params = reply.nextSibling;
132
133 if (params) {
134 debug('reading init-params...');
135 var param = params.firstChild;
136
137 while (param) {
138 var k = param.getAttribute("key");
139 var v = param.getAttribute("value");
140 debug(k + " => " + v);
141 init_params[k] = v;
142 param = param.nextSibling;
143 }
144 }
145
7719618b 146 init_second_stage();
295f9b42 147
7719618b
AD
148 } catch (e) {
149 exception_error("backend_sanity_check_callback", e);
150 }
295f9b42
AD
151 }
152}
153
cb246176 154function scheduleFeedUpdate(force) {
525116d4 155
0d51e25d 156 if (!daemon_enabled && !daemon_refresh_only) {
4d4200a8 157 notify("Updating feeds, please wait.", true);
c6784aea
AD
158 updateTitle("Updating");
159 }
55193822 160
cb246176
AD
161 var query_str = "backend.php?op=rpc&subop=";
162
163 if (force) {
c3b81db0 164 query_str = query_str + "forceUpdateAllFeeds";
cb246176 165 } else {
c3b81db0 166 query_str = query_str + "updateAllFeeds";
cb246176 167 }
525116d4 168
9826bd2e
AD
169 var omode;
170
b6104dee 171 if (firsttime_update && !navigator.userAgent.match("Opera")) {
2bf6e0a8
AD
172 firsttime_update = false;
173 omode = "T";
9826bd2e 174 } else {
2bf6e0a8
AD
175 if (display_tags) {
176 omode = "t";
177 } else {
178 omode = "flc";
179 }
9826bd2e 180 }
2bf6e0a8 181
9826bd2e 182 query_str = query_str + "&omode=" + omode;
78ea1de0 183 query_str = query_str + "&uctr=" + global_unread;
9826bd2e 184
0ee1d1a0 185 debug("in scheduleFeedUpdate");
2bf6e0a8 186
c441662f
AD
187 var date = new Date();
188
abbe0154 189 if (!xmlhttp_ready(xmlhttp_ctr) && last_refetch < date.getTime() / 1000 - 60) {
a7565293 190 debug("<b>xmlhttp seems to be stuck, aborting</b>");
abbe0154 191 xmlhttp_ctr.abort();
c441662f
AD
192 }
193
52db9978
AD
194 debug("REFETCH query: " + query_str);
195
abbe0154
AD
196 if (xmlhttp_ready(xmlhttp_ctr)) {
197 xmlhttp_ctr.open("GET", query_str, true);
198 xmlhttp_ctr.onreadystatechange=refetch_callback;
199 xmlhttp_ctr.send(null);
525116d4 200 } else {
abbe0154 201 debug("xmlhttp_ctr busy");
bed0f18f 202 //printLockingError();
c0e5a40e 203 }
525116d4 204}
1cd17194 205
525116d4 206function updateFeedList(silent, fetch) {
c0e5a40e 207
1a66d16e
AD
208// if (silent != true) {
209// notify("Loading feed list...");
210// }
82baad4a 211
331900c6
AD
212 var query_str = "backend.php?op=feeds";
213
8143ae1f
AD
214 if (display_tags) {
215 query_str = query_str + "&tags=1";
216 }
217
5c365f60 218 if (getActiveFeedId() && !activeFeedIsCat()) {
86741347 219 query_str = query_str + "&actid=" + getActiveFeedId();
175847de
AD
220 }
221
59b8192f
AD
222 if (navigator.userAgent.match("Opera")) {
223 var date = new Date();
224 var timestamp = Math.round(date.getTime() / 1000);
225 query_str = query_str + "&ts=" + timestamp
226 }
227
1a66d16e 228 if (fetch) query_str = query_str + "&fetch=yes";
e1123aee 229
6b4163cb
AD
230// var feeds_frame = document.getElementById("feeds-frame");
231// feeds_frame.src = query_str;
232
0e9dd1ba 233 debug("updateFeedList Q=" + query_str);
6b4163cb
AD
234
235 if (xmlhttp_ready(xmlhttp)) {
236 xmlhttp.open("GET", query_str, true);
237 xmlhttp.onreadystatechange=feedlist_callback;
238 xmlhttp.send(null);
239 } else {
240 debug("xmlhttp busy");
241 //printLockingError();
242 }
e1123aee 243
1a66d16e 244}
175847de 245
476cac42 246function catchupAllFeeds() {
076682aa 247
476cac42
AD
248 var query_str = "backend.php?op=feeds&subop=catchupAll";
249
250 notify("Marking all feeds as read...");
251
1a66d16e
AD
252 var feeds_frame = document.getElementById("feeds-frame");
253
254 feeds_frame.src = query_str;
476cac42 255
fc69e641 256 global_unread = 0;
21703604 257 updateTitle("");
fc69e641 258
476cac42 259}
1cd17194 260
767e2486 261function viewCurrentFeed(subop) {
1a66d16e 262
ec6e2fd3
AD
263// if (getActiveFeedId()) {
264 if (getActiveFeedId() != undefined) {
767e2486 265 viewfeed(getActiveFeedId(), subop);
033e47e0
AD
266 } else {
267 disableContainerChildren("headlinesToolbar", false, document);
ec6e2fd3 268// viewfeed(-1, subop); // FIXME
f0601b87 269 }
164f4738 270 return false; // block unneeded form submits
f0601b87
AD
271}
272
767e2486 273function viewfeed(feed, subop) {
db8d6f67 274 var f = window.frames["feeds-frame"];
767e2486 275 f.viewfeed(feed, subop);
9cfc649a
AD
276}
277
40d13c28 278function timeout() {
05732aa0 279 scheduleFeedUpdate(false);
f5de0d8d 280
3ac2b520 281 var refresh_time = getInitParam("feeds_frame_refresh");
f5de0d8d 282
3ac2b520 283 if (!refresh_time) refresh_time = 600;
f5de0d8d
AD
284
285 setTimeout("timeout()", refresh_time*1000);
ac53063a
AD
286}
287
c374a3fe 288function resetSearch() {
64c620ce
AD
289 var searchbox = document.getElementById("searchbox")
290
86741347 291 if (searchbox.value != "" && getActiveFeedId()) {
64c620ce 292 searchbox.value = "";
767e2486 293 viewfeed(getActiveFeedId(), "");
ac43eba1 294 }
c374a3fe 295}
ac53063a 296
86b682ce
AD
297function searchCancel() {
298 closeInfoBox(true);
299}
300
f0601b87 301function search() {
eff4997c 302 closeInfoBox();
4ce19859 303 viewCurrentFeed(0, "");
76798ff3 304}
1cd17194 305
13ad9102
AD
306function localPiggieFunction(enable) {
307 if (enable) {
308 var query_str = "backend.php?op=feeds&subop=piggie";
309
c0e5a40e 310 if (xmlhttp_ready(xmlhttp)) {
13ad9102
AD
311
312 xmlhttp.open("GET", query_str, true);
313 xmlhttp.onreadystatechange=feedlist_callback;
314 xmlhttp.send(null);
315 }
316 }
317}
318
806a3d14
AD
319// if argument is undefined, current subtitle is not updated
320// use blank string to clear subtitle
fc69e641
AD
321function updateTitle(s) {
322 var tmp = "Tiny Tiny RSS";
21703604 323
5a494a0b 324 if (s != undefined) {
21703604
AD
325 current_subtitle = s;
326 }
327
fc69e641
AD
328 if (global_unread > 0) {
329 tmp = tmp + " (" + global_unread + ")";
330 }
331
5a494a0b 332 if (current_subtitle) {
21703604 333 tmp = tmp + " - " + current_subtitle;
fc69e641 334 }
21703604
AD
335
336 if (active_title_text.length > 0) {
337 tmp = tmp + " > " + active_title_text;
338 }
339
fc69e641
AD
340 document.title = tmp;
341}
342
22a93ad8 343function genericSanityCheck() {
ac43eba1 344
295f9b42
AD
345 if (!xmlhttp) fatalError(1);
346
347 setCookie("ttrss_vf_test", "TEST");
348
349 if (getCookie("ttrss_vf_test") != "TEST") {
350 fatalError(2);
351 }
352
22a93ad8
AD
353 return true;
354}
355
356function init() {
357
7719618b 358 try {
fe2f1970 359
97dcd654
AD
360 // this whole shebang is based on http://www.birnamdesigns.com/misc/busted2.html
361
362 if (arguments.callee.done) return;
363 arguments.callee.done = true;
364
7719618b 365 disableContainerChildren("headlinesToolbar", true);
70830c87 366
86b682ce
AD
367 Form.disable("main_toolbar_form");
368
7719618b
AD
369 if (!genericSanityCheck())
370 return;
ac43eba1 371
0ee1d1a0
AD
372 if (getURLParam('debug')) {
373 document.getElementById('debug_output').style.display = 'block';
374 debug('debug mode activated');
375 }
376
7719618b
AD
377 xmlhttp.open("GET", "backend.php?op=rpc&subop=sanityCheck", true);
378 xmlhttp.onreadystatechange=backend_sanity_check_callback;
379 xmlhttp.send(null);
47179952 380
7719618b
AD
381 } catch (e) {
382 exception_error("init", e);
a8d28f48 383 }
7719618b 384}
86741347 385
7719618b 386function init_second_stage() {
295f9b42 387
7719618b 388 try {
2f587484 389
76b4eae1
AD
390 cookie_lifetime = getCookie("ttrss_cltime");
391
392 delCookie("ttrss_vf_test");
7719618b 393
7719618b 394 document.onkeydown = hotkey_handler;
1b0809ae 395
f31673f7
AD
396 var tb = parent.document.forms["main_toolbar_form"];
397
9f10e152
AD
398// dropboxSelect(tb.view_mode, getInitParam("toolbar_view_mode"));
399// dropboxSelect(tb.limit, getInitParam("toolbar_limit"));
c6784aea 400
0d51e25d
AD
401 daemon_enabled = getInitParam("daemon_enabled") == 1;
402 daemon_refresh_only = getInitParam("daemon_refresh_only") == 1;
5f136c9a 403
0e9dd1ba 404 setTimeout('updateFeedList(false, false)', 50);
0ee1d1a0
AD
405
406 debug("second stage ok");
7719618b 407
7719618b
AD
408 } catch (e) {
409 exception_error("init_second_stage", e);
2f587484 410 }
1cd17194 411}
ac43eba1 412
c09ec856 413function quickMenuChange() {
cbe45fa8 414 var chooser = document.getElementById("quickMenuChooser");
86b682ce 415 var opid = chooser[chooser.selectedIndex].value;
e2f8f7b4 416
c09ec856
AD
417 chooser.selectedIndex = 0;
418 quickMenuGo(opid);
419}
420
421function quickMenuGo(opid) {
bb3423cf 422 try {
c09ec856 423
bb3423cf
AD
424 if (opid == "qmcPrefs") {
425 gotoPreferences();
426 }
427
428 if (opid == "qmcSearch") {
0a6c4846 429 displayDlg("search", getActiveFeedId() + ":" + activeFeedIsCat());
6de5d056
AD
430 return;
431 }
bb3423cf
AD
432
433 if (opid == "qmcAddFeed") {
434 displayDlg("quickAddFeed");
435 return;
69668465 436 }
6de5d056 437
bb3423cf
AD
438 if (opid == "qmcRemoveFeed") {
439 var actid = getActiveFeedId();
440
5c365f60 441 if (!actid || activeFeedIsCat()) {
0530ddd8 442 alert("Please select some feed first.");
bb3423cf
AD
443 return;
444 }
64a2875d
AD
445
446 var fn = getFeedName(actid);
bb3423cf 447
64a2875d 448 if (confirm("Unsubscribe from " + fn + "?")) {
bb3423cf
AD
449 qfdDelete(actid);
450 }
451
452 return;
453 }
454
455 if (opid == "qmcUpdateFeeds") {
456 scheduleFeedUpdate(true);
457 return;
458 }
459
460 if (opid == "qmcCatchupAll") {
461 catchupAllFeeds();
462 return;
463 }
464
465 if (opid == "qmcShowOnlyUnread") {
466 toggleDispRead();
467 return;
468 }
469
470 if (opid == "qmcAddFilter") {
471 displayDlg("quickAddFilter", getActiveFeedId());
472 }
473 } catch (e) {
474 exception_error("quickMenuGo", e);
a24f525c 475 }
e2f8f7b4
AD
476}
477
6de5d056
AD
478function qfdDelete(feed_id) {
479
480 notify("Removing feed...");
481
7f123cda
AD
482 if (!xmlhttp_ready(xmlhttp)) {
483 printLockingError();
484 return
485 }
486
15da5cc1
AD
487 _qfd_deleted_feed = feed_id;
488
69668465 489 xmlhttp.open("GET", "backend.php?op=pref-feeds&quiet=1&subop=remove&ids=" + feed_id);
6de5d056
AD
490 xmlhttp.onreadystatechange=dlg_frefresh_callback;
491 xmlhttp.send(null);
7bc4f251
AD
492
493 return false;
6de5d056 494}
033e47e0 495
3745788e 496
21703604
AD
497function updateFeedTitle(t) {
498 active_title_text = t;
499 updateTitle();
500}
501
3745788e 502function toggleDispRead() {
7f123cda 503 try {
3745788e 504
7f123cda
AD
505 if (!xmlhttp_ready(xmlhttp)) {
506 printLockingError();
507 return
508 }
3745788e 509
e8bd0da9 510 var hide_read_feeds = (getInitParam("hide_read_feeds") == "1");
3745788e 511
7f123cda 512 hide_read_feeds = !hide_read_feeds;
e8bd0da9
AD
513
514 debug("toggle_disp_read => " + hide_read_feeds);
515
516 hideOrShowFeeds(getFeedsContext().document, hide_read_feeds);
517
7f123cda
AD
518 var query = "backend.php?op=rpc&subop=setpref" +
519 "&key=HIDE_READ_FEEDS&value=" + param_escape(hide_read_feeds);
3745788e 520
e8bd0da9
AD
521 storeInitParam("hide_read_feeds", hide_read_feeds, true);
522
523 new Ajax.Request(query);
7f123cda
AD
524
525 } catch (e) {
526 exception_error("toggleDispRead", e);
3745788e 527 }
3745788e 528}
295f9b42 529
71ad883b
AD
530function parse_runtime_info(elem) {
531 var param = elem.firstChild;
532
52db9978 533 debug("parse_runtime_info: " + param);
1cb7492d 534
71ad883b
AD
535 while (param) {
536 var k = param.getAttribute("key");
537 var v = param.getAttribute("value");
3ac2b520 538
1cb7492d
AD
539 debug("RI: " + k + " => " + v);
540
71ad883b
AD
541 var w = document.getElementById("noDaemonWarning");
542
543 if (w) {
544 if (k == "daemon_is_running" && v != 1) {
545 w.style.display = "block";
546 } else {
547 w.style.display = "none";
548 }
549 }
550 param = param.nextSibling;
551 }
552}
fce24838
AD
553
554function catchupCurrentFeed() {
555
234e467c 556 var fn = getFeedName(getActiveFeedId(), active_feed_is_cat);
fce24838 557
234e467c
AD
558 var str = "Mark all articles in " + fn + " as read?";
559
560/* if (active_feed_is_cat) {
561 str = "Mark all articles in this category as read?";
562 } */
563
f6d6e22f 564 if (getInitParam("confirm_feed_catchup") != 1 || confirm(str)) {
28de3732 565 return viewCurrentFeed('MarkAllRead')
fce24838
AD
566 }
567}
88040f57 568
461766f3
AD
569function userSwitch() {
570 var chooser = document.getElementById("userSwitch");
571 var user = chooser[chooser.selectedIndex].value;
572 window.location = "tt-rss.php?swu=" + user;
573}
6e6504bc
AD
574
575