From f89924f7a19871e26d5805a6c1863903c6e474bf Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Sun, 2 Dec 2018 18:38:27 +0300 Subject: set use strict on JS modules; remove some mostly useless stuff like get_minified_js() --- js/common.js | 493 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 493 insertions(+) create mode 100755 js/common.js (limited to 'js/common.js') diff --git a/js/common.js b/js/common.js new file mode 100755 index 000000000..b63257099 --- /dev/null +++ b/js/common.js @@ -0,0 +1,493 @@ +'use strict' +/* global dijit, __ */ + +let init_params = {}; +let _label_base_index = -1024; +let loading_progress = 0; +let notify_hide_timerid = false; + +Ajax.Base.prototype.initialize = Ajax.Base.prototype.initialize.wrap( + function (callOriginal, options) { + + if (getInitParam("csrf_token") != undefined) { + Object.extend(options, options || { }); + + if (Object.isString(options.parameters)) + options.parameters = options.parameters.toQueryParams(); + else if (Object.isHash(options.parameters)) + options.parameters = options.parameters.toObject(); + + options.parameters["csrf_token"] = getInitParam("csrf_token"); + } + + return callOriginal(options); + } +); + +/* xhr shorthand helpers */ + +function xhrPost(url, params, complete) { + console.log("xhrPost:", params); + return new Ajax.Request(url, { + parameters: params, + onComplete: complete + }); +} + +function xhrJson(url, params, complete) { + return xhrPost(url, params, (reply) => { + try { + const obj = JSON.parse(reply.responseText); + complete(obj); + } catch (e) { + console.error("xhrJson", e, reply); + complete(null); + } + + }) +} + +/* add method to remove element from array */ +Array.prototype.remove = function(s) { + for (let i=0; i < this.length; i++) { + if (s == this[i]) this.splice(i, 1); + } +}; + +const Lists = { + onRowChecked: function(elem) { + const checked = elem.domNode ? elem.attr("checked") : elem.checked; + // account for dojo checkboxes + elem = elem.domNode || elem; + + const row = elem.up("li"); + + if (row) + checked ? row.addClassName("Selected") : row.removeClassName("Selected"); + } +}; + +// noinspection JSUnusedGlobalSymbols +const Tables = { + onRowChecked: function(elem) { + // account for dojo checkboxes + const checked = elem.domNode ? elem.attr("checked") : elem.checked; + elem = elem.domNode || elem; + + const row = elem.up("tr"); + + if (row) + checked ? row.addClassName("Selected") : row.removeClassName("Selected"); + + }, + select: function(elemId, selected) { + $(elemId).select("tr").each((row) => { + const checkNode = row.select(".dijitCheckBox,input[type=checkbox]")[0]; + if (checkNode) { + const widget = dijit.getEnclosingWidget(checkNode); + + if (widget) { + widget.attr("checked", selected); + } else { + checkNode.checked = selected; + } + + this.onRowChecked(widget); + } + }); + }, + getSelected: function(elemId) { + const rv = []; + + $(elemId).select("tr").each((row) => { + if (row.hasClassName("Selected")) { + // either older prefix-XXX notation or separate attribute + const rowId = row.getAttribute("data-row-id") || row.id.replace(/^[A-Z]*?-/, ""); + + if (!isNaN(rowId)) + rv.push(parseInt(rowId)); + } + }); + + return rv; + } +}; + +function report_error(message, filename, lineno, colno, error) { + exception_error(error, null, filename, lineno); +} + +function exception_error(e, e_compat, filename, lineno, colno) { + if (typeof e == "string") e = e_compat; + + if (!e) return; // no exception object, nothing to report. + + try { + console.error(e); + const msg = e.toString(); + + try { + xhrPost("backend.php", + {op: "rpc", method: "log", + file: e.fileName ? e.fileName : filename, + line: e.lineNumber ? e.lineNumber : lineno, + msg: msg, context: e.stack}, + (transport) => { + console.warn(transport.responseText); + }); + + } catch (e) { + console.error("Exception while trying to log the error.", e); + } + + let content = "

" + msg + "

"; + + if (e.stack) { + content += "
Stack trace:
" + + ""; + } + + content += "
"; + + content += "
"; + + content += ""; + content += "
"; + + if (dijit.byId("exceptionDlg")) + dijit.byId("exceptionDlg").destroyRecursive(); + + const dialog = new dijit.Dialog({ + id: "exceptionDlg", + title: "Unhandled exception", + style: "width: 600px", + content: content}); + + dialog.show(); + + } catch (ei) { + console.error("Exception while trying to report an exception:", ei); + console.error("Original exception:", e); + + alert("Exception occured while trying to report an exception.\n" + + ei.stack + "\n\nOriginal exception:\n" + e.stack); + } + +} + +function param_escape(arg) { + return encodeURIComponent(arg); +} + +function notify_real(msg, no_hide, n_type) { + + const n = $("notify"); + + if (!n) return; + + if (notify_hide_timerid) { + window.clearTimeout(notify_hide_timerid); + } + + if (msg == "") { + if (n.hasClassName("visible")) { + notify_hide_timerid = window.setTimeout(function() { + n.removeClassName("visible") }, 0); + } + return; + } + + /* types: + + 1 - generic + 2 - progress + 3 - error + 4 - info + + */ + + msg = " " + __(msg) + ""; + + if (n_type == 2) { + msg = "" + msg; + no_hide = true; + } else if (n_type == 3) { + msg = "" + msg; + } else if (n_type == 4) { + msg = "" + msg; + } + + msg += " "; + + n.innerHTML = msg; + + window.setTimeout(function() { + // goddamnit firefox + if (n_type == 2) { + n.className = "notify notify_progress visible"; + } else if (n_type == 3) { + n.className = "notify notify_error visible"; + msg = "" + msg; + } else if (n_type == 4) { + n.className = "notify notify_info visible"; + } else { + n.className = "notify visible"; + } + + if (!no_hide) { + notify_hide_timerid = window.setTimeout(function() { + n.removeClassName("visible") }, 5*1000); + } + + }, 10); + +} + +function notify(msg, no_hide) { + notify_real(msg, no_hide, 1); +} + +function notify_progress(msg, no_hide) { + notify_real(msg, no_hide, 2); +} + +function notify_error(msg, no_hide) { + notify_real(msg, no_hide, 3); + +} + +function notify_info(msg, no_hide) { + notify_real(msg, no_hide, 4); +} + +function setCookie(name, value, lifetime, path, domain, secure) { + + let d = false; + + if (lifetime) { + d = new Date(); + d.setTime(d.getTime() + (lifetime * 1000)); + } + + console.log("setCookie: " + name + " => " + value + ": " + d); + + int_setCookie(name, value, d, path, domain, secure); + +} + +function int_setCookie(name, value, expires, path, domain, secure) { + document.cookie= name + "=" + escape(value) + + ((expires) ? "; expires=" + expires.toGMTString() : "") + + ((path) ? "; path=" + path : "") + + ((domain) ? "; domain=" + domain : "") + + ((secure) ? "; secure" : ""); +} + +function delCookie(name, path, domain) { + if (getCookie(name)) { + document.cookie = name + "=" + + ((path) ? ";path=" + path : "") + + ((domain) ? ";domain=" + domain : "" ) + + ";expires=Thu, 01-Jan-1970 00:00:01 GMT"; + } +} + + +function getCookie(name) { + + const dc = document.cookie; + const prefix = name + "="; + let begin = dc.indexOf("; " + prefix); + if (begin == -1) { + begin = dc.indexOf(prefix); + if (begin != 0) return null; + } + else { + begin += 2; + } + let end = document.cookie.indexOf(";", begin); + if (end == -1) { + end = dc.length; + } + return unescape(dc.substring(begin + prefix.length, end)); +} + +// noinspection JSUnusedGlobalSymbols +function displayIfChecked(checkbox, elemId) { + if (checkbox.checked) { + Effect.Appear(elemId, {duration : 0.5}); + } else { + Effect.Fade(elemId, {duration : 0.5}); + } +} + +// noinspection JSUnusedGlobalSymbols +function closeInfoBox() { + const dialog = dijit.byId("infoBox"); + + if (dialog) dialog.hide(); + + return false; +} + +function getInitParam(key) { + return init_params[key]; +} + +function setInitParam(key, value) { + init_params[key] = value; +} + +function fatalError(code, msg, ext_info) { + if (code == 6) { + window.location.href = "index.php"; + } else if (code == 5) { + window.location.href = "public.php?op=dbupdate"; + } else { + + if (msg == "") msg = "Unknown error"; + + if (ext_info) { + if (ext_info.responseText) { + ext_info = ext_info.responseText; + } + } + + /* global ERRORS */ + if (ERRORS && ERRORS[code] && !msg) { + msg = ERRORS[code]; + } + + let content = "
Error code: " + code + "
" + + "

" + msg + "

"; + + if (ext_info) { + content = content + "
Additional information:
" + + ""; + } + + const dialog = new dijit.Dialog({ + title: "Fatal error", + style: "width: 600px", + content: content}); + + dialog.show(); + + } + + return false; + +} + +/* function strip_tags(s) { + return s.replace(/<\/?[^>]+(>|$)/g, ""); +} */ + +// noinspection JSUnusedGlobalSymbols +function uploadIconHandler(rc) { + switch (rc) { + case 0: + notify_info("Upload complete."); + if (App.isPrefs()) { + Feeds.reload(); + } else { + setTimeout('Feeds.reload(false, false)', 50); + } + break; + case 1: + notify_error("Upload failed: icon is too big."); + break; + case 2: + notify_error("Upload failed."); + break; + } +} + +// noinspection JSUnusedGlobalSymbols +function removeFeedIcon(id) { + if (confirm(__("Remove stored feed icon?"))) { + + notify_progress("Removing feed icon...", true); + + const query = { op: "pref-feeds", method: "removeicon", feed_id: id }; + + xhrPost("backend.php", query, () => { + notify_info("Feed icon removed."); + if (App.isPrefs()) { + Feeds.reload(); + } else { + setTimeout('Feeds.reload(false, false)', 50); + } + }); + } + + return false; +} + +// noinspection JSUnusedGlobalSymbols +function uploadFeedIcon() { + const file = $("icon_file"); + + if (file.value.length == 0) { + alert(__("Please select an image file to upload.")); + } else if (confirm(__("Upload new icon for this feed?"))) { + notify_progress("Uploading, please wait...", true); + return true; + } + + return false; +} + +// noinspection JSUnusedGlobalSymbols +function label_to_feed_id(label) { + return _label_base_index - 1 - Math.abs(label); +} + +// noinspection JSUnusedGlobalSymbols +function feed_to_label_id(feed) { + return _label_base_index - 1 + Math.abs(feed); +} + +// http://stackoverflow.com/questions/6251937/how-to-get-selecteduser-highlighted-text-in-contenteditable-element-and-replac +function getSelectionText() { + let text = ""; + + if (typeof window.getSelection != "undefined") { + const sel = window.getSelection(); + if (sel.rangeCount) { + const container = document.createElement("div"); + for (let i = 0, len = sel.rangeCount; i < len; ++i) { + container.appendChild(sel.getRangeAt(i).cloneContents()); + } + text = container.innerHTML; + } + } else if (typeof document.selection != "undefined") { + if (document.selection.type == "Text") { + text = document.selection.createRange().textText; + } + } + + return text.stripTags(); +} + +// noinspection JSUnusedGlobalSymbols +function popupOpenUrl(url) { + const w = window.open(""); + + w.opener = null; + w.location = url; +} + +// noinspection JSUnusedGlobalSymbols +function popupOpenArticle(id) { + const w = window.open("", + "ttrss_article_popup", + "height=900,width=900,resizable=yes,status=no,location=no,menubar=no,directories=no,scrollbars=yes,toolbar=no"); + + w.opener = null; + w.location = "backend.php?op=article&method=view&mode=raw&html=1&zoom=1&id=" + id + "&csrf_token=" + getInitParam("csrf_token"); +} -- cgit v1.2.3-54-g00ecf From d9c5c93cef313127b9b5010fbe279fdbddedadec Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Sun, 2 Dec 2018 20:07:57 +0300 Subject: move some more stuff out of common.js rework client-side cookie functions a bit limit dojo cachebust based on server scripts modification time remove param_escape() --- classes/dlg.php | 10 ++-- classes/pref/feeds.php | 4 +- include/functions.php | 12 +++++ index.php | 2 +- js/Article.js | 2 +- js/CommonDialogs.js | 34 ++++++++++++ js/CommonFilters.js | 4 +- js/Feeds.js | 2 +- js/PrefFilterTree.js | 2 +- js/PrefLabelTree.js | 2 +- js/PrefUsers.js | 2 +- js/Utils.js | 2 +- js/common.js | 126 ++++++++++--------------------------------- js/tt-rss.js | 32 +++++------ plugins/af_psql_trgm/init.js | 2 +- plugins/mail/mail.js | 2 +- plugins/mailto/init.js | 2 +- plugins/note/note.js | 2 +- plugins/share/share.js | 2 +- prefs.php | 2 +- 20 files changed, 111 insertions(+), 137 deletions(-) (limited to 'js/common.js') diff --git a/classes/dlg.php b/classes/dlg.php index 7e66c4b5e..32c41ee34 100644 --- a/classes/dlg.php +++ b/classes/dlg.php @@ -52,7 +52,7 @@ class Dlg extends Handler_Protected { print " "; - print ""; print ""; @@ -85,7 +85,7 @@ class Dlg extends Handler_Protected { print "
"; - print ""; print "
"; @@ -150,7 +150,7 @@ class Dlg extends Handler_Protected { print "
"; print ""; print "
"; @@ -179,7 +179,7 @@ class Dlg extends Handler_Protected { print " "; - print ""; print ""; @@ -195,7 +195,7 @@ class Dlg extends Handler_Protected { print " "; print ""; print ""; } diff --git a/classes/pref/feeds.php b/classes/pref/feeds.php index 3b949073c..7ae7a04c1 100755 --- a/classes/pref/feeds.php +++ b/classes/pref/feeds.php @@ -745,9 +745,9 @@ class Pref_Feeds extends Handler_Protected { - - "; diff --git a/include/functions.php b/include/functions.php index baed6fb20..dcb2e7518 100755 --- a/include/functions.php +++ b/include/functions.php @@ -2566,3 +2566,15 @@ function arr_qmarks($arr) { return str_repeat('?,', count($arr) - 1) . '?'; } + + function get_scripts_timestamp() { + $files = glob("js/*.js"); + $ts = 0; + + foreach ($files as $file) { + $file_ts = filemtime($file); + if ($file_ts > $ts) $ts = $file_ts; + } + + return $ts; + } \ No newline at end of file diff --git a/index.php b/index.php index 4a85ff236..6035ac186 100644 --- a/index.php +++ b/index.php @@ -91,7 +91,7 @@ "; return; } diff --git a/js/CommonDialogs.js b/js/CommonDialogs.js index cac4f9be1..cf21370d6 100644 --- a/js/CommonDialogs.js +++ b/js/CommonDialogs.js @@ -1,11 +1,30 @@ 'use strict' /* global __, ngettext */ define(["dojo/_base/declare"], function (declare) { + // noinspection JSUnusedGlobalSymbols return declare("fox.CommonDialogs", null, { closeInfoBox: function() { const dialog = dijit.byId("infoBox"); if (dialog) dialog.hide(); }, + uploadIconHandler: function(rc) { + switch (rc) { + case 0: + Notify.info("Upload complete."); + if (App.isPrefs()) { + Feeds.reload(); + } else { + setTimeout('Feeds.reload(false, false)', 50); + } + break; + case 1: + Notify.error("Upload failed: icon is too big."); + break; + case 2: + Notify.error("Upload failed."); + break; + } + }, removeFeedIcon: function(id) { if (confirm(__("Remove stored feed icon?"))) { Notify.progress("Removing feed icon...", true); diff --git a/js/common.js b/js/common.js index ec6381e31..1da3e6d1b 100755 --- a/js/common.js +++ b/js/common.js @@ -343,27 +343,6 @@ function fatalError(code, msg, ext_info) { return s.replace(/<\/?[^>]+(>|$)/g, ""); } */ -// noinspection JSUnusedGlobalSymbols -function uploadIconHandler(rc) { - switch (rc) { - case 0: - Notify.info("Upload complete."); - if (App.isPrefs()) { - Feeds.reload(); - } else { - setTimeout('Feeds.reload(false, false)', 50); - } - break; - case 1: - Notify.error("Upload failed: icon is too big."); - break; - case 2: - Notify.error("Upload failed."); - break; - } -} - - // noinspection JSUnusedGlobalSymbols function label_to_feed_id(label) { return _label_base_index - 1 - Math.abs(label); -- cgit v1.2.3-54-g00ecf From ac8361e6f6e81e25d3c17e14b973af53a9b93885 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Sun, 2 Dec 2018 21:52:50 +0300 Subject: add AppBase as a shared ancestor for main and prefs app objects remove event.observe stuff from startup, unneeded --- index.php | 6 - js/AppBase.js | 35 ++ js/FeedTree.js | 2 +- js/Feeds.js | 30 +- js/Headlines.js | 24 +- js/Utils.js | 16 +- js/common.js | 38 +-- js/prefs.js | 249 +++++++------- js/tt-rss.js | 989 ++++++++++++++++++++++++++++---------------------------- prefs.php | 7 - 10 files changed, 698 insertions(+), 698 deletions(-) create mode 100644 js/AppBase.js (limited to 'js/common.js') diff --git a/index.php b/index.php index 6035ac186..f574eb4d6 100644 --- a/index.php +++ b/index.php @@ -135,12 +135,6 @@ - - diff --git a/js/AppBase.js b/js/AppBase.js new file mode 100644 index 000000000..8987d115e --- /dev/null +++ b/js/AppBase.js @@ -0,0 +1,35 @@ +'use strict' +/* global __, ngettext */ +define(["dojo/_base/declare"], function (declare) { + return declare("fox.AppBase", null, { + _initParams: [], + getInitParam: function(k) { + return this._initParams[k]; + }, + setInitParam: function(k, v) { + this._initParams[k] = v; + }, + constructor: function(args) { + // + }, + enableCsrfSupport: function() { + Ajax.Base.prototype.initialize = Ajax.Base.prototype.initialize.wrap( + function (callOriginal, options) { + + if (App.getInitParam("csrf_token") != undefined) { + Object.extend(options, options || { }); + + if (Object.isString(options.parameters)) + options.parameters = options.parameters.toQueryParams(); + else if (Object.isHash(options.parameters)) + options.parameters = options.parameters.toObject(); + + options.parameters["csrf_token"] = App.getInitParam("csrf_token"); + } + + return callOriginal(options); + } + ); + } + }); +}); diff --git a/js/FeedTree.js b/js/FeedTree.js index 4a28bd2b0..37e3de2d1 100755 --- a/js/FeedTree.js +++ b/js/FeedTree.js @@ -123,7 +123,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dijit/Tree", "dijit/Menu"], postCreate: function() { this.connect(this.model, "onChange", "updateCounter"); this.connect(this, "_expandNode", function() { - this.hideRead(getInitParam("hide_read_feeds"), getInitParam("hide_read_shows_special")); + this.hideRead(App.getInitParam("hide_read_feeds"), App.getInitParam("hide_read_shows_special")); }); this.inherited(arguments); diff --git a/js/Feeds.js b/js/Feeds.js index 8b6f6a707..d5371779f 100644 --- a/js/Feeds.js +++ b/js/Feeds.js @@ -83,7 +83,7 @@ define(["dojo/_base/declare"], function (declare) { if (id > 0) { if (has_img) { this.setIcon(id, false, - getInitParam("icons_url") + "/" + id + ".ico?" + has_img); + App.getInitParam("icons_url") + "/" + id + ".ico?" + has_img); } else { this.setIcon(id, false, 'images/blank_icon.gif'); } @@ -91,7 +91,7 @@ define(["dojo/_base/declare"], function (declare) { } } - this.hideOrShowFeeds(getInitParam("hide_read_feeds") == 1); + this.hideOrShowFeeds(App.getInitParam("hide_read_feeds") == 1); this._counters_prev = elems; }, reloadCurrent: function(method) { @@ -132,7 +132,7 @@ define(["dojo/_base/declare"], function (declare) { let query = {op: "rpc", method: "getAllCounters", seq: Utils.next_seq()}; if (!force) - query.last_article_id = getInitParam("last_article_id"); + query.last_article_id = App.getInitParam("last_article_id"); xhrPost("backend.php", query, (transport) => { Utils.handleRpcJson(transport); @@ -160,7 +160,7 @@ define(["dojo/_base/declare"], function (declare) { const treeModel = new fox.FeedStoreModel({ store: store, query: { - "type": getInitParam('enable_feed_cats') == 1 ? "category" : "feed" + "type": App.getInitParam('enable_feed_cats') == 1 ? "category" : "feed" }, rootId: "root", rootLabel: "Feeds", @@ -221,9 +221,9 @@ define(["dojo/_base/declare"], function (declare) { this.open({feed: this.getActive(), is_cat: this.activeIsCat()}); } - this.hideOrShowFeeds(getInitParam("hide_read_feeds") == 1); + this.hideOrShowFeeds(App.getInitParam("hide_read_feeds") == 1); - if (getInitParam("is_default_pw")) { + if (App.getInitParam("is_default_pw")) { console.warn("user password is at default value"); const dialog = new dijit.Dialog({ @@ -246,7 +246,7 @@ define(["dojo/_base/declare"], function (declare) { } // bw_limit disables timeout() so we request initial counters separately - if (getInitParam("bw_limit") == "1") { + if (App.getInitParam("bw_limit") == "1") { this.requestCounters(true); } else { setTimeout(() => { @@ -281,18 +281,18 @@ define(["dojo/_base/declare"], function (declare) { if (tree) return tree.selectFeed(feed, is_cat); }, toggleUnread: function() { - const hide = !(getInitParam("hide_read_feeds") == "1"); + const hide = !(App.getInitParam("hide_read_feeds") == "1"); xhrPost("backend.php", {op: "rpc", method: "setpref", key: "HIDE_READ_FEEDS", value: hide}, () => { this.hideOrShowFeeds(hide); - setInitParam("hide_read_feeds", hide); + App.setInitParam("hide_read_feeds", hide); }); }, hideOrShowFeeds: function(hide) { const tree = dijit.byId("feedTree"); if (tree) - return tree.hideRead(hide, getInitParam("hide_read_shows_special")); + return tree.hideRead(hide, App.getInitParam("hide_read_shows_special")); }, open: function(params) { const feed = params.feed; @@ -366,7 +366,7 @@ define(["dojo/_base/declare"], function (declare) { if (viewfeed_debug) { window.open("backend.php?" + dojo.objectToQuery( - Object.assign({debug: 1, csrf_token: getInitParam("csrf_token")}, query) + Object.assign({debug: 1, csrf_token: App.getInitParam("csrf_token")}, query) )); } @@ -389,7 +389,7 @@ define(["dojo/_base/declare"], function (declare) { catchupAll: function() { const str = __("Mark all articles as read?"); - if (getInitParam("confirm_feed_catchup") != 1 || confirm(str)) { + if (App.getInitParam("confirm_feed_catchup") != 1 || confirm(str)) { Notify.progress("Marking all feeds as read..."); @@ -448,7 +448,7 @@ define(["dojo/_base/declare"], function (declare) { str = str.replace("%s", fn) .replace("%w", mark_what); - if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) { + if (App.getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) { return; } @@ -463,7 +463,7 @@ define(["dojo/_base/declare"], function (declare) { xhrPost("backend.php", catchup_query, (transport) => { Utils.handleRpcJson(transport); - const show_next_feed = getInitParam("on_catchup_show_next_feed") == "1"; + const show_next_feed = App.getInitParam("on_catchup_show_next_feed") == "1"; if (show_next_feed) { const nuf = this.getNextUnread(feed, is_cat); @@ -486,7 +486,7 @@ define(["dojo/_base/declare"], function (declare) { const str = __("Mark all articles in %s as read?").replace("%s", title); - if (getInitParam("confirm_feed_catchup") != 1 || confirm(str)) { + if (App.getInitParam("confirm_feed_catchup") != 1 || confirm(str)) { const rows = $$("#headlines-frame > div[id*=RROW][data-orig-feed-id='" + id + "']"); diff --git a/js/Headlines.js b/js/Headlines.js index 68dda8d3e..1bcd35896 100755 --- a/js/Headlines.js +++ b/js/Headlines.js @@ -12,13 +12,13 @@ define(["dojo/_base/declare"], function (declare) { if (App.isCombinedMode()) { - if (!in_body && (event.ctrlKey || id == Article.getActive() || getInitParam("cdm_expanded"))) { + if (!in_body && (event.ctrlKey || id == Article.getActive() || App.getInitParam("cdm_expanded"))) { Article.openInNewWindow(id); } Article.setActive(id); - if (!getInitParam("cdm_expanded")) + if (!App.getInitParam("cdm_expanded")) Article.cdmScrollToId(id); return in_body; @@ -81,7 +81,7 @@ define(["dojo/_base/declare"], function (declare) { // set topmost child in the buffer as active, but not if we're at the beginning (to prevent auto marking // first article as read all the time) if ($("headlines-frame").scrollTop != 0 && - getInitParam("cdm_expanded") && getInitParam("cdm_auto_catchup") == 1) { + App.getInitParam("cdm_expanded") && App.getInitParam("cdm_auto_catchup") == 1) { const rows = $$("#headlines-frame > div[id*=RROW]"); @@ -113,7 +113,7 @@ define(["dojo/_base/declare"], function (declare) { } } - if (getInitParam("cdm_auto_catchup") == 1) { + if (App.getInitParam("cdm_auto_catchup") == 1) { let rows = $$("#headlines-frame > div[id*=RROW][class*=Unread]"); @@ -139,7 +139,7 @@ define(["dojo/_base/declare"], function (declare) { console.log("we seem to be at an end"); - if (getInitParam("on_catchup_show_next_feed") == "1") { + if (App.getInitParam("on_catchup_show_next_feed") == "1") { Feeds.openNextUnread(); } } @@ -150,7 +150,7 @@ define(["dojo/_base/declare"], function (declare) { } }, updateFloatingTitle: function(unread_only) { - if (!App.isCombinedMode()/* || !getInitParam("cdm_expanded")*/) return; + if (!App.isCombinedMode()/* || !App.getInitParam("cdm_expanded")*/) return; const hf = $("headlines-frame"); const elems = $$("#headlines-frame > div[id*=RROW]"); @@ -201,7 +201,7 @@ define(["dojo/_base/declare"], function (declare) { } }, unpackVisible: function() { - if (!App.isCombinedMode() || !getInitParam("cdm_expanded")) return; + if (!App.isCombinedMode() || !App.getInitParam("cdm_expanded")) return; const rows = $$("#headlines-frame div[id*=RROW][data-content]"); const threshold = $("headlines-frame").scrollTop + $("headlines-frame").offsetHeight + 600; @@ -714,7 +714,7 @@ define(["dojo/_base/declare"], function (declare) { str = str.replace("%d", rows.length); str = str.replace("%s", fn); - if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) { + if (App.getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) { return; } @@ -839,7 +839,7 @@ define(["dojo/_base/declare"], function (declare) { str = str.replace("%d", rows.length); str = str.replace("%s", fn); - if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) { + if (App.getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) { return; } @@ -869,7 +869,7 @@ define(["dojo/_base/declare"], function (declare) { str = str.replace("%d", rows.length); str = str.replace("%s", fn); - if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) { + if (App.getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) { return; } @@ -952,7 +952,7 @@ define(["dojo/_base/declare"], function (declare) { } else { const msg = ngettext("Mark %d article as read?", "Mark %d articles as read?", ids_to_mark.length).replace("%d", ids_to_mark.length); - if (getInitParam("confirm_feed_catchup") != 1 || confirm(msg)) { + if (App.getInitParam("confirm_feed_catchup") != 1 || confirm(msg)) { for (var i = 0; i < ids_to_mark.length; i++) { var e = $("RROW-" + ids_to_mark[i]); @@ -1090,7 +1090,7 @@ define(["dojo/_base/declare"], function (declare) { })); - const labels = getInitParam("labels"); + const labels = App.getInitParam("labels"); if (labels && labels.length) { diff --git a/js/Utils.js b/js/Utils.js index 1050cf018..d1de08b2c 100644 --- a/js/Utils.js +++ b/js/Utils.js @@ -28,7 +28,7 @@ define(["dojo/_base/declare"], function (declare) { }, keyeventToAction: function(event) { - const hotkeys_map = getInitParam("hotkeys"); + const hotkeys_map = App.getInitParam("hotkeys"); const keycode = event.which; const keychar = String.fromCharCode(keycode).toLowerCase(); @@ -191,7 +191,7 @@ define(["dojo/_base/declare"], function (declare) { if (message == "UPDATE_COUNTERS") { console.log("need to refresh counters..."); - setInitParam("last_article_id", -1); + App.setInitParam("last_article_id", -1); Feeds.requestCounters(true); } @@ -228,9 +228,6 @@ define(["dojo/_base/declare"], function (declare) { return false; }, parseRuntimeInfo: function(data) { - - //console.log("parsing runtime info..."); - for (const k in data) { if (data.hasOwnProperty(k)) { const v = data[k]; @@ -258,13 +255,13 @@ define(["dojo/_base/declare"], function (declare) { } if (k == "max_feed_id" || k == "num_feeds") { - if (init_params[k] != v) { + if (App.getInitParam(k) != v) { console.log("feed count changed, need to reload feedlist."); Feeds.reload(); } } - init_params[k] = v; + App.setInitParam(k, v); } } @@ -315,13 +312,12 @@ define(["dojo/_base/declare"], function (declare) { } console.log("IP:", k, "=>", params[k]); + App.setInitParam(k, params[k]); } } - init_params = params; - // PluginHost might not be available on non-index pages - window.PluginHost && PluginHost.run(PluginHost.HOOK_PARAMS_LOADED, init_params); + window.PluginHost && PluginHost.run(PluginHost.HOOK_PARAMS_LOADED, App._initParams); } App.initSecondStage(); diff --git a/js/common.js b/js/common.js index 1da3e6d1b..de6d13a78 100755 --- a/js/common.js +++ b/js/common.js @@ -1,28 +1,8 @@ 'use strict' /* global dijit, __ */ -let init_params = {}; let _label_base_index = -1024; let loading_progress = 0; -let notify_hide_timerid = false; - -Ajax.Base.prototype.initialize = Ajax.Base.prototype.initialize.wrap( - function (callOriginal, options) { - - if (getInitParam("csrf_token") != undefined) { - Object.extend(options, options || { }); - - if (Object.isString(options.parameters)) - options.parameters = options.parameters.toQueryParams(); - else if (Object.isHash(options.parameters)) - options.parameters = options.parameters.toObject(); - - options.parameters["csrf_token"] = getInitParam("csrf_token"); - } - - return callOriginal(options); - } -); /* xhr shorthand helpers */ @@ -239,15 +219,15 @@ const Notify = { switch (kind) { case this.KIND_INFO: notify.addClassName("notify_info") - icon = getInitParam("icon_information"); + icon = App.getInitParam("icon_information"); break; case this.KIND_ERROR: notify.addClassName("notify_error"); - icon = getInitParam("icon_alert"); + icon = App.getInitParam("icon_alert"); break; case this.KIND_PROGRESS: notify.addClassName("notify_progress"); - icon = getInitParam("icon_indicator_white") + icon = App.getInitParam("icon_indicator_white") break; } @@ -255,7 +235,7 @@ const Notify = { msgfmt += (" ") - .replace("%s", getInitParam("icon_cross")); + .replace("%s", App.getInitParam("icon_cross")); notify.innerHTML = msgfmt; notify.addClassName("visible"); @@ -289,14 +269,6 @@ function displayIfChecked(checkbox, elemId) { } } -function getInitParam(key) { - return init_params[key]; -} - -function setInitParam(key, value) { - init_params[key] = value; -} - function fatalError(code, msg, ext_info) { if (code == 6) { window.location.href = "index.php"; @@ -390,5 +362,5 @@ function popupOpenArticle(id) { "height=900,width=900,resizable=yes,status=no,location=no,menubar=no,directories=no,scrollbars=yes,toolbar=no"); w.opener = null; - w.location = "backend.php?op=article&method=view&mode=raw&html=1&zoom=1&id=" + id + "&csrf_token=" + getInitParam("csrf_token"); + w.location = "backend.php?op=article&method=view&mode=raw&html=1&zoom=1&id=" + id + "&csrf_token=" + App.getInitParam("csrf_token"); } diff --git a/js/prefs.js b/js/prefs.js index a1866f478..75f285b38 100755 --- a/js/prefs.js +++ b/js/prefs.js @@ -1,64 +1,67 @@ 'use strict' /* global dijit, __ */ +let App; let Utils; let CommonDialogs; let Filters; let Users; let Prefs; -const App = { - init: function() { - window.onerror = function (message, filename, lineno, colno, error) { - report_error(message, filename, lineno, colno, error); - }; - - require(["dojo/_base/kernel", - "dojo/ready", - "dojo/parser", - "dojo/_base/loader", - "dojo/_base/html", - "dijit/ColorPalette", - "dijit/Dialog", - "dijit/form/Button", - "dijit/form/CheckBox", - "dijit/form/DropDownButton", - "dijit/form/FilteringSelect", - "dijit/form/MultiSelect", - "dijit/form/Form", - "dijit/form/RadioButton", - "dijit/form/ComboButton", - "dijit/form/Select", - "dijit/form/SimpleTextarea", - "dijit/form/TextBox", - "dijit/form/ValidationTextBox", - "dijit/InlineEditBox", - "dijit/layout/AccordionContainer", - "dijit/layout/AccordionPane", - "dijit/layout/BorderContainer", - "dijit/layout/ContentPane", - "dijit/layout/TabContainer", - "dijit/Menu", - "dijit/ProgressBar", - "dijit/Toolbar", - "dijit/Tree", - "dijit/tree/dndSource", - "dojo/data/ItemFileWriteStore", - "lib/CheckBoxStoreModel", - "lib/CheckBoxTree", - "fox/Utils", - "fox/CommonDialogs", - "fox/CommonFilters", - "fox/PrefUsers", - "fox/PrefHelpers", - "fox/PrefFeedStore", - "fox/PrefFilterStore", - "fox/PrefFeedTree", - "fox/PrefFilterTree", - "fox/PrefLabelTree"], function (dojo, ready, parser) { - - ready(function () { - try { +require(["dojo/_base/kernel", + "dojo/_base/declare", + "dojo/ready", + "dojo/parser", + "fox/AppBase", + "dojo/_base/loader", + "dojo/_base/html", + "dijit/ColorPalette", + "dijit/Dialog", + "dijit/form/Button", + "dijit/form/CheckBox", + "dijit/form/DropDownButton", + "dijit/form/FilteringSelect", + "dijit/form/MultiSelect", + "dijit/form/Form", + "dijit/form/RadioButton", + "dijit/form/ComboButton", + "dijit/form/Select", + "dijit/form/SimpleTextarea", + "dijit/form/TextBox", + "dijit/form/ValidationTextBox", + "dijit/InlineEditBox", + "dijit/layout/AccordionContainer", + "dijit/layout/AccordionPane", + "dijit/layout/BorderContainer", + "dijit/layout/ContentPane", + "dijit/layout/TabContainer", + "dijit/Menu", + "dijit/ProgressBar", + "dijit/Toolbar", + "dijit/Tree", + "dijit/tree/dndSource", + "dojo/data/ItemFileWriteStore", + "lib/CheckBoxStoreModel", + "lib/CheckBoxTree", + "fox/Utils", + "fox/CommonDialogs", + "fox/CommonFilters", + "fox/PrefUsers", + "fox/PrefHelpers", + "fox/PrefFeedStore", + "fox/PrefFilterStore", + "fox/PrefFeedTree", + "fox/PrefFilterTree", + "fox/PrefLabelTree"], function (dojo, declare, ready, parser, AppBase) { + + ready(function () { + try { + const _App = declare("fox.App", AppBase, { + constructor: function() { + window.onerror = function (message, filename, lineno, colno, error) { + report_error(message, filename, lineno, colno, error); + }; + Utils = fox.Utils(); CommonDialogs = fox.CommonDialogs(); Filters = fox.CommonFilters(); @@ -73,81 +76,87 @@ const App = { const params = {op: "rpc", method: "sanityCheck", clientTzOffset: clientTzOffset}; xhrPost("backend.php", params, (transport) => { - Utils.backendSanityCallback(transport); + try { + Utils.backendSanityCallback(transport); + } catch (e) { + exception_error(e); + } }); + }, + initSecondStage: function() { + document.onkeydown = () => { App.hotkeyHandler(event) }; + Utils.setLoadingProgress(50); + Notify.close(); - } catch (e) { - exception_error(e); - } - }); - }); - }, - initSecondStage: function() { - document.onkeydown = () => { App.hotkeyHandler(event) }; - Utils.setLoadingProgress(50); - Notify.close(); - - let tab = Utils.urlParam('tab'); - - if (tab) { - tab = dijit.byId(tab + "Tab"); - if (tab) { - dijit.byId("pref-tabs").selectChild(tab); - - switch (Utils.urlParam('method')) { - case "editfeed": - window.setTimeout(function () { - CommonDialogs.editFeed(Utils.urlParam('methodparam')) - }, 100); - break; - default: - console.warn("initSecondStage, unknown method:", Utils.urlParam("method")); - } - } - } else { - let tab = localStorage.getItem("ttrss:prefs-tab"); + let tab = Utils.urlParam('tab'); + + if (tab) { + tab = dijit.byId(tab + "Tab"); + if (tab) { + dijit.byId("pref-tabs").selectChild(tab); + + switch (Utils.urlParam('method')) { + case "editfeed": + window.setTimeout(function () { + CommonDialogs.editFeed(Utils.urlParam('methodparam')) + }, 100); + break; + default: + console.warn("initSecondStage, unknown method:", Utils.urlParam("method")); + } + } + } else { + let tab = localStorage.getItem("ttrss:prefs-tab"); + + if (tab) { + tab = dijit.byId(tab); + if (tab) { + dijit.byId("pref-tabs").selectChild(tab); + } + } + } + + dojo.connect(dijit.byId("pref-tabs"), "selectChild", function (elem) { + localStorage.setItem("ttrss:prefs-tab", elem.id); + }); - if (tab) { - tab = dijit.byId(tab); - if (tab) { - dijit.byId("pref-tabs").selectChild(tab); + }, + hotkeyHandler: function (event) { + if (event.target.nodeName == "INPUT" || event.target.nodeName == "TEXTAREA") return; + + const action_name = Utils.keyeventToAction(event); + + if (action_name) { + switch (action_name) { + case "feed_subscribe": + CommonDialogs.quickAddFeed(); + return false; + case "create_label": + CommonDialogs.addLabel(); + return false; + case "create_filter": + Filters.quickAddFilter(); + return false; + case "help_dialog": + Utils.helpDialog("main"); + return false; + default: + console.log("unhandled action: " + action_name + "; keycode: " + event.which); + } + } + }, + isPrefs: function() { + return true; } - } - } + }); - dojo.connect(dijit.byId("pref-tabs"), "selectChild", function (elem) { - localStorage.setItem("ttrss:prefs-tab", elem.id); - }); + App = new _App(); - }, - hotkeyHandler: function (event) { - if (event.target.nodeName == "INPUT" || event.target.nodeName == "TEXTAREA") return; - - const action_name = Utils.keyeventToAction(event); - - if (action_name) { - switch (action_name) { - case "feed_subscribe": - CommonDialogs.quickAddFeed(); - return false; - case "create_label": - CommonDialogs.addLabel(); - return false; - case "create_filter": - Filters.quickAddFilter(); - return false; - case "help_dialog": - Utils.helpDialog("main"); - return false; - default: - console.log("unhandled action: " + action_name + "; keycode: " + event.which); - } + } catch (e) { + exception_error(e); } - }, - isPrefs: function() { - return true; - } -}; + }); +}); function opmlImportComplete(iframe) { if (!iframe.contentDocument.body.innerHTML) return false; diff --git a/js/tt-rss.js b/js/tt-rss.js index 481386114..ec52755a1 100644 --- a/js/tt-rss.js +++ b/js/tt-rss.js @@ -1,6 +1,7 @@ 'use strict' /* global dijit,__ */ +let App; let Utils; let CommonDialogs; let Filters; @@ -9,63 +10,63 @@ let Headlines; let Article; let ArticleCache; -const App = { - global_unread: -1, - _widescreen_mode: false, - hotkey_actions: {}, - init: function() { - - window.onerror = function (message, filename, lineno, colno, error) { - report_error(message, filename, lineno, colno, error); - }; - - require(["dojo/_base/kernel", - "dojo/ready", - "dojo/parser", - "dojo/_base/loader", - "dojo/_base/html", - "dojo/query", - "dijit/ProgressBar", - "dijit/ColorPalette", - "dijit/Dialog", - "dijit/form/Button", - "dijit/form/ComboButton", - "dijit/form/CheckBox", - "dijit/form/DropDownButton", - "dijit/form/FilteringSelect", - "dijit/form/Form", - "dijit/form/RadioButton", - "dijit/form/Select", - "dijit/form/MultiSelect", - "dijit/form/SimpleTextarea", - "dijit/form/TextBox", - "dijit/form/ComboBox", - "dijit/form/ValidationTextBox", - "dijit/InlineEditBox", - "dijit/layout/AccordionContainer", - "dijit/layout/BorderContainer", - "dijit/layout/ContentPane", - "dijit/layout/TabContainer", - "dijit/PopupMenuItem", - "dijit/Menu", - "dijit/Toolbar", - "dijit/Tree", - "dijit/tree/dndSource", - "dijit/tree/ForestStoreModel", - "dojo/data/ItemFileWriteStore", - "fox/Utils", - "fox/CommonDialogs", - "fox/CommonFilters", - "fox/Feeds", - "fox/Headlines", - "fox/Article", - "fox/ArticleCache", - "fox/FeedStoreModel", - "fox/FeedTree"], function (dojo, ready, parser) { - - ready(function () { - - try { +require(["dojo/_base/kernel", + "dojo/_base/declare", + "dojo/ready", + "dojo/parser", + "fox/AppBase", + "dojo/_base/loader", + "dojo/_base/html", + "dojo/query", + "dijit/ProgressBar", + "dijit/ColorPalette", + "dijit/Dialog", + "dijit/form/Button", + "dijit/form/ComboButton", + "dijit/form/CheckBox", + "dijit/form/DropDownButton", + "dijit/form/FilteringSelect", + "dijit/form/Form", + "dijit/form/RadioButton", + "dijit/form/Select", + "dijit/form/MultiSelect", + "dijit/form/SimpleTextarea", + "dijit/form/TextBox", + "dijit/form/ComboBox", + "dijit/form/ValidationTextBox", + "dijit/InlineEditBox", + "dijit/layout/AccordionContainer", + "dijit/layout/BorderContainer", + "dijit/layout/ContentPane", + "dijit/layout/TabContainer", + "dijit/PopupMenuItem", + "dijit/Menu", + "dijit/Toolbar", + "dijit/Tree", + "dijit/tree/dndSource", + "dijit/tree/ForestStoreModel", + "dojo/data/ItemFileWriteStore", + "fox/Utils", + "fox/CommonDialogs", + "fox/CommonFilters", + "fox/Feeds", + "fox/Headlines", + "fox/Article", + "fox/ArticleCache", + "fox/FeedStoreModel", + "fox/FeedTree"], function (dojo, declare, ready, parser, AppBase) { + + ready(function () { + try { + const _App = declare("fox.App", AppBase, { + global_unread: -1, + _widescreen_mode: false, + hotkey_actions: {}, + constructor: function () { + window.onerror = function (message, filename, lineno, colno, error) { + report_error(message, filename, lineno, colno, error); + }; + Utils = fox.Utils(); CommonDialogs = fox.CommonDialogs(); Filters = fox.CommonFilters(); @@ -76,11 +77,11 @@ const App = { parser.parse(); - if (!App.genericSanityCheck()) - return false; + if (!this.genericSanityCheck()) + return; Utils.setLoadingProgress(30); - App.initHotkeyActions(); + this.initHotkeyActions(); const a = document.createElement('audio'); const hasAudio = !!a.canPlayType; @@ -99,483 +100,483 @@ const App = { try { Utils.backendSanityCallback(transport); } catch (e) { - console.error(e); + exception_error(e); } }); + }, + initSecondStage: function () { + this.enableCsrfSupport(); - } catch (e) { - exception_error(e); - } + Feeds.reload(); + Article.close(); - }); + if (parseInt(Cookie.get("ttrss_fh_width")) > 0) { + dijit.byId("feeds-holder").domNode.setStyle( + {width: Cookie.get("ttrss_fh_width") + "px"}); + } + dijit.byId("main").resize(); - }); - }, - initSecondStage: function () { - Feeds.reload(); - Article.close(); + dojo.connect(dijit.byId('feeds-holder'), 'resize', + function (args) { + if (args && args.w >= 0) { + Cookie.set("ttrss_fh_width", args.w, App.getInitParam("cookie_lifetime")); + } + }); - if (parseInt(Cookie.get("ttrss_fh_width")) > 0) { - dijit.byId("feeds-holder").domNode.setStyle( - {width: Cookie.get("ttrss_fh_width") + "px"}); - } + dojo.connect(dijit.byId('content-insert'), 'resize', + function (args) { + if (args && args.w >= 0 && args.h >= 0) { + Cookie.set("ttrss_ci_width", args.w, App.getInitParam("cookie_lifetime")); + Cookie.set("ttrss_ci_height", args.h, App.getInitParam("cookie_lifetime")); + } + }); - dijit.byId("main").resize(); + Cookie.delete("ttrss_test"); - dojo.connect(dijit.byId('feeds-holder'), 'resize', - function (args) { - if (args && args.w >= 0) { - Cookie.set("ttrss_fh_width", args.w, getInitParam("cookie_lifetime")); - } - }); + const toolbar = document.forms["main_toolbar_form"]; - dojo.connect(dijit.byId('content-insert'), 'resize', - function (args) { - if (args && args.w >= 0 && args.h >= 0) { - Cookie.set("ttrss_ci_width", args.w, getInitParam("cookie_lifetime")); - Cookie.set("ttrss_ci_height", args.h, getInitParam("cookie_lifetime")); - } - }); + dijit.getEnclosingWidget(toolbar.view_mode).attr('value', + App.getInitParam("default_view_mode")); - Cookie.delete("ttrss_test"); + dijit.getEnclosingWidget(toolbar.order_by).attr('value', + App.getInitParam("default_view_order_by")); - const toolbar = document.forms["main_toolbar_form"]; + const hash_feed_id = hash_get('f'); + const hash_feed_is_cat = hash_get('c') == "1"; - dijit.getEnclosingWidget(toolbar.view_mode).attr('value', - getInitParam("default_view_mode")); + if (hash_feed_id != undefined) { + Feeds.setActive(hash_feed_id, hash_feed_is_cat); + } - dijit.getEnclosingWidget(toolbar.order_by).attr('value', - getInitParam("default_view_order_by")); + Utils.setLoadingProgress(50); - const hash_feed_id = hash_get('f'); - const hash_feed_is_cat = hash_get('c') == "1"; + ArticleCache.clear(); - if (hash_feed_id != undefined) { - Feeds.setActive(hash_feed_id, hash_feed_is_cat); - } + this._widescreen_mode = App.getInitParam("widescreen"); + this.switchPanelMode(this._widescreen_mode); - Utils.setLoadingProgress(50); + Headlines.initScrollHandler(); - ArticleCache.clear(); + if (App.getInitParam("simple_update")) { + console.log("scheduling simple feed updater..."); + window.setInterval(() => { Feeds.updateRandom() }, 30 * 1000); + } - this._widescreen_mode = getInitParam("widescreen"); - this.switchPanelMode(this._widescreen_mode); + console.log("second stage ok"); + }, + genericSanityCheck: function() { + Cookie.set("ttrss_test", "TEST"); - Headlines.initScrollHandler(); + if (Cookie.get("ttrss_test") != "TEST") { + return fatalError(2); + } - if (getInitParam("simple_update")) { - console.log("scheduling simple feed updater..."); - window.setInterval(() => { Feeds.updateRandom() }, 30 * 1000); - } + return true; + }, + updateTitle: function() { + let tmp = "Tiny Tiny RSS"; - console.log("second stage ok"); - }, - genericSanityCheck: function() { - Cookie.set("ttrss_test", "TEST"); + if (this.global_unread > 0) { + tmp = "(" + this.global_unread + ") " + tmp; + } - if (Cookie.get("ttrss_test") != "TEST") { - return fatalError(2); - } + document.title = tmp; + }, + onViewModeChanged: function() { + ArticleCache.clear(); + return Feeds.reloadCurrent(''); + }, + isCombinedMode: function() { + return App.getInitParam("combined_display_mode"); + }, + hotkeyHandler(event) { + if (event.target.nodeName == "INPUT" || event.target.nodeName == "TEXTAREA") return; + + const action_name = Utils.keyeventToAction(event); + + if (action_name) { + const action_func = this.hotkey_actions[action_name]; + + if (action_func != null) { + action_func(); + event.stopPropagation(); + return false; + } + } + }, + switchPanelMode: function(wide) { + if (App.isCombinedMode()) return; - return true; - }, - updateTitle: function() { - let tmp = "Tiny Tiny RSS"; + const article_id = Article.getActive(); - if (this.global_unread > 0) { - tmp = "(" + this.global_unread + ") " + tmp; - } + if (wide) { + dijit.byId("headlines-wrap-inner").attr("design", 'sidebar'); + dijit.byId("content-insert").attr("region", "trailing"); - document.title = tmp; - }, - onViewModeChanged: function() { - ArticleCache.clear(); - return Feeds.reloadCurrent(''); - }, - isCombinedMode: function() { - return getInitParam("combined_display_mode"); - }, - hotkeyHandler(event) { - if (event.target.nodeName == "INPUT" || event.target.nodeName == "TEXTAREA") return; - - const action_name = Utils.keyeventToAction(event); - - if (action_name) { - const action_func = this.hotkey_actions[action_name]; - - if (action_func != null) { - action_func(); - event.stopPropagation(); - return false; - } - } - }, - switchPanelMode: function(wide) { - if (App.isCombinedMode()) return; + dijit.byId("content-insert").domNode.setStyle({width: '50%', + height: 'auto', + borderTopWidth: '0px' }); - const article_id = Article.getActive(); + if (parseInt(Cookie.get("ttrss_ci_width")) > 0) { + dijit.byId("content-insert").domNode.setStyle( + {width: Cookie.get("ttrss_ci_width") + "px" }); + } - if (wide) { - dijit.byId("headlines-wrap-inner").attr("design", 'sidebar'); - dijit.byId("content-insert").attr("region", "trailing"); + $("headlines-frame").setStyle({ borderBottomWidth: '0px' }); + $("headlines-frame").addClassName("wide"); - dijit.byId("content-insert").domNode.setStyle({width: '50%', - height: 'auto', - borderTopWidth: '0px' }); + } else { - if (parseInt(Cookie.get("ttrss_ci_width")) > 0) { - dijit.byId("content-insert").domNode.setStyle( - {width: Cookie.get("ttrss_ci_width") + "px" }); - } + dijit.byId("content-insert").attr("region", "bottom"); - $("headlines-frame").setStyle({ borderBottomWidth: '0px' }); - $("headlines-frame").addClassName("wide"); + dijit.byId("content-insert").domNode.setStyle({width: 'auto', + height: '50%', + borderTopWidth: '0px'}); - } else { + if (parseInt(Cookie.get("ttrss_ci_height")) > 0) { + dijit.byId("content-insert").domNode.setStyle( + {height: Cookie.get("ttrss_ci_height") + "px" }); + } - dijit.byId("content-insert").attr("region", "bottom"); + $("headlines-frame").setStyle({ borderBottomWidth: '1px' }); + $("headlines-frame").removeClassName("wide"); - dijit.byId("content-insert").domNode.setStyle({width: 'auto', - height: '50%', - borderTopWidth: '0px'}); + } - if (parseInt(Cookie.get("ttrss_ci_height")) > 0) { - dijit.byId("content-insert").domNode.setStyle( - {height: Cookie.get("ttrss_ci_height") + "px" }); - } + Article.close(); - $("headlines-frame").setStyle({ borderBottomWidth: '1px' }); - $("headlines-frame").removeClassName("wide"); + if (article_id) Article.view(article_id); - } + xhrPost("backend.php", {op: "rpc", method: "setpanelmode", wide: wide ? 1 : 0}); + }, + initHotkeyActions: function() { + this.hotkey_actions["next_feed"] = function () { + const rv = dijit.byId("feedTree").getNextFeed( + Feeds.getActive(), Feeds.activeIsCat()); - Article.close(); - - if (article_id) Article.view(article_id); - - xhrPost("backend.php", {op: "rpc", method: "setpanelmode", wide: wide ? 1 : 0}); - }, - initHotkeyActions: function() { - this.hotkey_actions["next_feed"] = function () { - const rv = dijit.byId("feedTree").getNextFeed( - Feeds.getActive(), Feeds.activeIsCat()); - - if (rv) Feeds.open({feed: rv[0], is_cat: rv[1], delayed: true}) - }; - this.hotkey_actions["prev_feed"] = function () { - const rv = dijit.byId("feedTree").getPreviousFeed( - Feeds.getActive(), Feeds.activeIsCat()); - - if (rv) Feeds.open({feed: rv[0], is_cat: rv[1], delayed: true}) - }; - this.hotkey_actions["next_article"] = function () { - Headlines.move('next'); - }; - this.hotkey_actions["prev_article"] = function () { - Headlines.move('prev'); - }; - this.hotkey_actions["next_article_noscroll"] = function () { - Headlines.move('next', true); - }; - this.hotkey_actions["prev_article_noscroll"] = function () { - Headlines.move('prev', true); - }; - this.hotkey_actions["next_article_noexpand"] = function () { - Headlines.move('next', true, true); - }; - this.hotkey_actions["prev_article_noexpand"] = function () { - Headlines.move('prev', true, true); - }; - this.hotkey_actions["search_dialog"] = function () { - Feeds.search(); - }; - this.hotkey_actions["toggle_mark"] = function () { - Headlines.selectionToggleMarked(); - }; - this.hotkey_actions["toggle_publ"] = function () { - Headlines.selectionTogglePublished(); - }; - this.hotkey_actions["toggle_unread"] = function () { - Headlines.selectionToggleUnread({no_error: 1}); - }; - this.hotkey_actions["edit_tags"] = function () { - const id = Article.getActive(); - if (id) { - Article.editTags(id); - } - }; - this.hotkey_actions["open_in_new_window"] = function () { - if (Article.getActive()) { - Article.openInNewWindow(Article.getActive()); - } - }; - this.hotkey_actions["catchup_below"] = function () { - Headlines.catchupRelativeTo(1); - }; - this.hotkey_actions["catchup_above"] = function () { - Headlines.catchupRelativeTo(0); - }; - this.hotkey_actions["article_scroll_down"] = function () { - Article.scroll(40); - }; - this.hotkey_actions["article_scroll_up"] = function () { - Article.scroll(-40); - }; - this.hotkey_actions["close_article"] = function () { - if (App.isCombinedMode()) { - Article.cdmUnsetActive(); - } else { - Article.close(); - } - }; - this.hotkey_actions["email_article"] = function () { - if (typeof emailArticle != "undefined") { - emailArticle(); - } else if (typeof mailtoArticle != "undefined") { - mailtoArticle(); - } else { - alert(__("Please enable mail plugin first.")); - } - }; - this.hotkey_actions["select_all"] = function () { - Headlines.select('all'); - }; - this.hotkey_actions["select_unread"] = function () { - Headlines.select('unread'); - }; - this.hotkey_actions["select_marked"] = function () { - Headlines.select('marked'); - }; - this.hotkey_actions["select_published"] = function () { - Headlines.select('published'); - }; - this.hotkey_actions["select_invert"] = function () { - Headlines.select('invert'); - }; - this.hotkey_actions["select_none"] = function () { - Headlines.select('none'); - }; - this.hotkey_actions["feed_refresh"] = function () { - if (Feeds.getActive() != undefined) { - Feeds.open({feed: Feeds.getActive(), is_cat: Feeds.activeIsCat()}); - } - }; - this.hotkey_actions["feed_unhide_read"] = function () { - Feeds.toggleUnread(); - }; - this.hotkey_actions["feed_subscribe"] = function () { - CommonDialogs.quickAddFeed(); - }; - this.hotkey_actions["feed_debug_update"] = function () { - if (!Feeds.activeIsCat() && parseInt(Feeds.getActive()) > 0) { - window.open("backend.php?op=feeds&method=update_debugger&feed_id=" + Feeds.getActive() + - "&csrf_token=" + getInitParam("csrf_token")); - } else { - alert("You can't debug this kind of feed."); - } - }; - - this.hotkey_actions["feed_debug_viewfeed"] = function () { - Feeds.open({feed: Feeds.getActive(), is_cat: Feeds.activeIsCat(), viewfeed_debug: true}); - }; - - this.hotkey_actions["feed_edit"] = function () { - if (Feeds.activeIsCat()) - alert(__("You can't edit this kind of feed.")); - else - CommonDialogs.editFeed(Feeds.getActive()); - }; - this.hotkey_actions["feed_catchup"] = function () { - if (Feeds.getActive() != undefined) { - Feeds.catchupCurrent(); - } - }; - this.hotkey_actions["feed_reverse"] = function () { - Headlines.reverse(); - }; - this.hotkey_actions["feed_toggle_vgroup"] = function () { - xhrPost("backend.php", {op: "rpc", method: "togglepref", key: "VFEED_GROUP_BY_FEED"}, () => { - Feeds.reloadCurrent(); - }) - }; - this.hotkey_actions["catchup_all"] = function () { - Feeds.catchupAll(); - }; - this.hotkey_actions["cat_toggle_collapse"] = function () { - if (Feeds.activeIsCat()) { - dijit.byId("feedTree").collapseCat(Feeds.getActive()); - } - }; - this.hotkey_actions["goto_all"] = function () { - Feeds.open({feed: -4}); - }; - this.hotkey_actions["goto_fresh"] = function () { - Feeds.open({feed: -3}); - }; - this.hotkey_actions["goto_marked"] = function () { - Feeds.open({feed: -1}); - }; - this.hotkey_actions["goto_published"] = function () { - Feeds.open({feed: -2}); - }; - this.hotkey_actions["goto_tagcloud"] = function () { - Utils.displayDlg(__("Tag cloud"), "printTagCloud"); - }; - this.hotkey_actions["goto_prefs"] = function () { - document.location.href = "prefs.php"; - }; - this.hotkey_actions["select_article_cursor"] = function () { - const id = Article.getUnderPointer(); - if (id) { - const row = $("RROW-" + id); - - if (row) { - const cb = dijit.getEnclosingWidget( - row.select(".rchk")[0]); - - if (cb) { - if (!row.hasClassName("active")) - cb.attr("checked", !cb.attr("checked")); - - Headlines.onRowChecked(cb); - return false; - } - } - } - }; - this.hotkey_actions["create_label"] = function () { - CommonDialogs.addLabel(); - }; - this.hotkey_actions["create_filter"] = function () { - Filters.quickAddFilter(); - }; - this.hotkey_actions["collapse_sidebar"] = function () { - Feeds.reloadCurrent(); - }; - this.hotkey_actions["toggle_embed_original"] = function () { - if (typeof embedOriginalArticle != "undefined") { - if (Article.getActive()) - embedOriginalArticle(Article.getActive()); - } else { - alert(__("Please enable embed_original plugin first.")); - } - }; - this.hotkey_actions["toggle_widescreen"] = function () { - if (!App.isCombinedMode()) { - App._widescreen_mode = !App._widescreen_mode; - - // reset stored sizes because geometry changed - Cookie.set("ttrss_ci_width", 0); - Cookie.set("ttrss_ci_height", 0); - - App.switchPanelMode(App._widescreen_mode); - } else { - alert(__("Widescreen is not available in combined mode.")); - } - }; - this.hotkey_actions["help_dialog"] = function () { - Utils.helpDialog("main"); - }; - this.hotkey_actions["toggle_combined_mode"] = function () { - Notify.progress("Loading, please wait..."); - - const value = App.isCombinedMode() ? "false" : "true"; - - xhrPost("backend.php", {op: "rpc", method: "setpref", key: "COMBINED_DISPLAY_MODE", value: value}, () => { - setInitParam("combined_display_mode", - !getInitParam("combined_display_mode")); - - Article.close(); - Feeds.reloadCurrent(); - }) - }; - this.hotkey_actions["toggle_cdm_expanded"] = function () { - Notify.progress("Loading, please wait..."); - - const value = getInitParam("cdm_expanded") ? "false" : "true"; - - xhrPost("backend.php", {op: "rpc", method: "setpref", key: "CDM_EXPANDED", value: value}, () => { - setInitParam("cdm_expanded", !getInitParam("cdm_expanded")); - Feeds.reloadCurrent(); - }); - }; - }, - onActionSelected: function(opid) { - switch (opid) { - case "qmcPrefs": - document.location.href = "prefs.php"; - break; - case "qmcLogout": - document.location.href = "backend.php?op=logout"; - break; - case "qmcTagCloud": - Utils.displayDlg(__("Tag cloud"), "printTagCloud"); - break; - case "qmcSearch": - Feeds.search(); - break; - case "qmcAddFeed": - CommonDialogs.quickAddFeed(); - break; - case "qmcDigest": - window.location.href = "backend.php?op=digest"; - break; - case "qmcEditFeed": - if (Feeds.activeIsCat()) - alert(__("You can't edit this kind of feed.")); - else - CommonDialogs.editFeed(Feeds.getActive()); - break; - case "qmcRemoveFeed": - const actid = Feeds.getActive(); - - if (!actid) { - alert(__("Please select some feed first.")); - return; - } + if (rv) Feeds.open({feed: rv[0], is_cat: rv[1], delayed: true}) + }; + this.hotkey_actions["prev_feed"] = function () { + const rv = dijit.byId("feedTree").getPreviousFeed( + Feeds.getActive(), Feeds.activeIsCat()); - if (Feeds.activeIsCat()) { - alert(__("You can't unsubscribe from the category.")); - return; - } + if (rv) Feeds.open({feed: rv[0], is_cat: rv[1], delayed: true}) + }; + this.hotkey_actions["next_article"] = function () { + Headlines.move('next'); + }; + this.hotkey_actions["prev_article"] = function () { + Headlines.move('prev'); + }; + this.hotkey_actions["next_article_noscroll"] = function () { + Headlines.move('next', true); + }; + this.hotkey_actions["prev_article_noscroll"] = function () { + Headlines.move('prev', true); + }; + this.hotkey_actions["next_article_noexpand"] = function () { + Headlines.move('next', true, true); + }; + this.hotkey_actions["prev_article_noexpand"] = function () { + Headlines.move('prev', true, true); + }; + this.hotkey_actions["search_dialog"] = function () { + Feeds.search(); + }; + this.hotkey_actions["toggle_mark"] = function () { + Headlines.selectionToggleMarked(); + }; + this.hotkey_actions["toggle_publ"] = function () { + Headlines.selectionTogglePublished(); + }; + this.hotkey_actions["toggle_unread"] = function () { + Headlines.selectionToggleUnread({no_error: 1}); + }; + this.hotkey_actions["edit_tags"] = function () { + const id = Article.getActive(); + if (id) { + Article.editTags(id); + } + }; + this.hotkey_actions["open_in_new_window"] = function () { + if (Article.getActive()) { + Article.openInNewWindow(Article.getActive()); + } + }; + this.hotkey_actions["catchup_below"] = function () { + Headlines.catchupRelativeTo(1); + }; + this.hotkey_actions["catchup_above"] = function () { + Headlines.catchupRelativeTo(0); + }; + this.hotkey_actions["article_scroll_down"] = function () { + Article.scroll(40); + }; + this.hotkey_actions["article_scroll_up"] = function () { + Article.scroll(-40); + }; + this.hotkey_actions["close_article"] = function () { + if (App.isCombinedMode()) { + Article.cdmUnsetActive(); + } else { + Article.close(); + } + }; + this.hotkey_actions["email_article"] = function () { + if (typeof emailArticle != "undefined") { + emailArticle(); + } else if (typeof mailtoArticle != "undefined") { + mailtoArticle(); + } else { + alert(__("Please enable mail plugin first.")); + } + }; + this.hotkey_actions["select_all"] = function () { + Headlines.select('all'); + }; + this.hotkey_actions["select_unread"] = function () { + Headlines.select('unread'); + }; + this.hotkey_actions["select_marked"] = function () { + Headlines.select('marked'); + }; + this.hotkey_actions["select_published"] = function () { + Headlines.select('published'); + }; + this.hotkey_actions["select_invert"] = function () { + Headlines.select('invert'); + }; + this.hotkey_actions["select_none"] = function () { + Headlines.select('none'); + }; + this.hotkey_actions["feed_refresh"] = function () { + if (Feeds.getActive() != undefined) { + Feeds.open({feed: Feeds.getActive(), is_cat: Feeds.activeIsCat()}); + } + }; + this.hotkey_actions["feed_unhide_read"] = function () { + Feeds.toggleUnread(); + }; + this.hotkey_actions["feed_subscribe"] = function () { + CommonDialogs.quickAddFeed(); + }; + this.hotkey_actions["feed_debug_update"] = function () { + if (!Feeds.activeIsCat() && parseInt(Feeds.getActive()) > 0) { + window.open("backend.php?op=feeds&method=update_debugger&feed_id=" + Feeds.getActive() + + "&csrf_token=" + App.getInitParam("csrf_token")); + } else { + alert("You can't debug this kind of feed."); + } + }; - const fn = Feeds.getName(actid); + this.hotkey_actions["feed_debug_viewfeed"] = function () { + Feeds.open({feed: Feeds.getActive(), is_cat: Feeds.activeIsCat(), viewfeed_debug: true}); + }; - if (confirm(__("Unsubscribe from %s?").replace("%s", fn))) { - CommonDialogs.unsubscribeFeed(actid); - } - break; - case "qmcCatchupAll": - Feeds.catchupAll(); - break; - case "qmcShowOnlyUnread": - Feeds.toggleUnread(); - break; - case "qmcToggleWidescreen": - if (!App.isCombinedMode()) { - App._widescreen_mode = !App._widescreen_mode; - - // reset stored sizes because geometry changed - Cookie.set("ttrss_ci_width", 0); - Cookie.set("ttrss_ci_height", 0); - - App.switchPanelMode(App._widescreen_mode); - } else { - alert(__("Widescreen is not available in combined mode.")); + this.hotkey_actions["feed_edit"] = function () { + if (Feeds.activeIsCat()) + alert(__("You can't edit this kind of feed.")); + else + CommonDialogs.editFeed(Feeds.getActive()); + }; + this.hotkey_actions["feed_catchup"] = function () { + if (Feeds.getActive() != undefined) { + Feeds.catchupCurrent(); + } + }; + this.hotkey_actions["feed_reverse"] = function () { + Headlines.reverse(); + }; + this.hotkey_actions["feed_toggle_vgroup"] = function () { + xhrPost("backend.php", {op: "rpc", method: "togglepref", key: "VFEED_GROUP_BY_FEED"}, () => { + Feeds.reloadCurrent(); + }) + }; + this.hotkey_actions["catchup_all"] = function () { + Feeds.catchupAll(); + }; + this.hotkey_actions["cat_toggle_collapse"] = function () { + if (Feeds.activeIsCat()) { + dijit.byId("feedTree").collapseCat(Feeds.getActive()); + } + }; + this.hotkey_actions["goto_all"] = function () { + Feeds.open({feed: -4}); + }; + this.hotkey_actions["goto_fresh"] = function () { + Feeds.open({feed: -3}); + }; + this.hotkey_actions["goto_marked"] = function () { + Feeds.open({feed: -1}); + }; + this.hotkey_actions["goto_published"] = function () { + Feeds.open({feed: -2}); + }; + this.hotkey_actions["goto_tagcloud"] = function () { + Utils.displayDlg(__("Tag cloud"), "printTagCloud"); + }; + this.hotkey_actions["goto_prefs"] = function () { + document.location.href = "prefs.php"; + }; + this.hotkey_actions["select_article_cursor"] = function () { + const id = Article.getUnderPointer(); + if (id) { + const row = $("RROW-" + id); + + if (row) { + const cb = dijit.getEnclosingWidget( + row.select(".rchk")[0]); + + if (cb) { + if (!row.hasClassName("active")) + cb.attr("checked", !cb.attr("checked")); + + Headlines.onRowChecked(cb); + return false; + } + } + } + }; + this.hotkey_actions["create_label"] = function () { + CommonDialogs.addLabel(); + }; + this.hotkey_actions["create_filter"] = function () { + Filters.quickAddFilter(); + }; + this.hotkey_actions["collapse_sidebar"] = function () { + Feeds.reloadCurrent(); + }; + this.hotkey_actions["toggle_embed_original"] = function () { + if (typeof embedOriginalArticle != "undefined") { + if (Article.getActive()) + embedOriginalArticle(Article.getActive()); + } else { + alert(__("Please enable embed_original plugin first.")); + } + }; + this.hotkey_actions["toggle_widescreen"] = function () { + if (!App.isCombinedMode()) { + App._widescreen_mode = !App._widescreen_mode; + + // reset stored sizes because geometry changed + Cookie.set("ttrss_ci_width", 0); + Cookie.set("ttrss_ci_height", 0); + + App.switchPanelMode(App._widescreen_mode); + } else { + alert(__("Widescreen is not available in combined mode.")); + } + }; + this.hotkey_actions["help_dialog"] = function () { + Utils.helpDialog("main"); + }; + this.hotkey_actions["toggle_combined_mode"] = function () { + Notify.progress("Loading, please wait..."); + + const value = App.isCombinedMode() ? "false" : "true"; + + xhrPost("backend.php", {op: "rpc", method: "setpref", key: "COMBINED_DISPLAY_MODE", value: value}, () => { + App.setInitParam("combined_display_mode", + !App.getInitParam("combined_display_mode")); + + Article.close(); + Feeds.reloadCurrent(); + }) + }; + this.hotkey_actions["toggle_cdm_expanded"] = function () { + Notify.progress("Loading, please wait..."); + + const value = App.getInitParam("cdm_expanded") ? "false" : "true"; + + xhrPost("backend.php", {op: "rpc", method: "setpref", key: "CDM_EXPANDED", value: value}, () => { + App.setInitParam("cdm_expanded", !App.getInitParam("cdm_expanded")); + Feeds.reloadCurrent(); + }); + }; + }, + onActionSelected: function(opid) { + switch (opid) { + case "qmcPrefs": + document.location.href = "prefs.php"; + break; + case "qmcLogout": + document.location.href = "backend.php?op=logout"; + break; + case "qmcTagCloud": + Utils.displayDlg(__("Tag cloud"), "printTagCloud"); + break; + case "qmcSearch": + Feeds.search(); + break; + case "qmcAddFeed": + CommonDialogs.quickAddFeed(); + break; + case "qmcDigest": + window.location.href = "backend.php?op=digest"; + break; + case "qmcEditFeed": + if (Feeds.activeIsCat()) + alert(__("You can't edit this kind of feed.")); + else + CommonDialogs.editFeed(Feeds.getActive()); + break; + case "qmcRemoveFeed": + const actid = Feeds.getActive(); + + if (!actid) { + alert(__("Please select some feed first.")); + return; + } + + if (Feeds.activeIsCat()) { + alert(__("You can't unsubscribe from the category.")); + return; + } + + const fn = Feeds.getName(actid); + + if (confirm(__("Unsubscribe from %s?").replace("%s", fn))) { + CommonDialogs.unsubscribeFeed(actid); + } + break; + case "qmcCatchupAll": + Feeds.catchupAll(); + break; + case "qmcShowOnlyUnread": + Feeds.toggleUnread(); + break; + case "qmcToggleWidescreen": + if (!App.isCombinedMode()) { + App._widescreen_mode = !App._widescreen_mode; + + // reset stored sizes because geometry changed + Cookie.set("ttrss_ci_width", 0); + Cookie.set("ttrss_ci_height", 0); + + App.switchPanelMode(App._widescreen_mode); + } else { + alert(__("Widescreen is not available in combined mode.")); + } + break; + case "qmcHKhelp": + Utils.helpDialog("main"); + break; + default: + console.log("quickMenuGo: unknown action: " + opid); + } + }, + isPrefs: function() { + return false; } - break; - case "qmcHKhelp": - Utils.helpDialog("main"); - break; - default: - console.log("quickMenuGo: unknown action: " + opid); + }); + + App = new _App(); + } catch (e) { + exception_error(e); } - }, - isPrefs: function() { - return false; - } -}; + }); +}); function hash_get(key) { const kv = window.location.hash.substring(1).toQueryParams(); diff --git a/prefs.php b/prefs.php index 93773103f..a3d7c8b1b 100644 --- a/prefs.php +++ b/prefs.php @@ -100,13 +100,6 @@ - - - -- cgit v1.2.3-54-g00ecf From 71fc6d45bd761a9d2715faa68f2b8c0271ee7169 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Mon, 3 Dec 2018 13:38:13 +0300 Subject: refactor error reporting to AppBase; keep exception_error() for now as a shim --- include/login_form.php | 41 +++++----------- js/AppBase.js | 70 +++++++++++++++++++++++++-- js/Article.js | 4 +- js/CommonDialogs.js | 2 +- js/CommonFilters.js | 6 +-- js/FeedTree.js | 4 +- js/Feeds.js | 6 +-- js/common.js | 75 ++++------------------------- js/prefs.js | 8 +--- js/tt-rss.js | 8 +--- plugins/embed_original/init.js | 86 ++++++++++++++++------------------ plugins/import_export/import_export.js | 6 +-- plugins/mail/mail.js | 83 +++++++++++++++----------------- plugins/mailto/init.js | 37 +++++++-------- plugins/nsfw/init.js | 11 ++--- plugins/shorten_expanded/init.js | 22 +++------ register.php | 6 +-- 17 files changed, 215 insertions(+), 260 deletions(-) (limited to 'js/common.js') diff --git a/include/login_form.php b/include/login_form.php index 1eb5d26d4..cdf70803b 100644 --- a/include/login_form.php +++ b/include/login_form.php @@ -42,41 +42,26 @@ require(['dojo/parser', "dojo/ready", 'dijit/form/Button','dijit/form/CheckBox', }); function fetchProfiles() { - try { - var query = "op=getProfiles&login=" + encodeURIComponent(document.forms["loginForm"].login.value); - - if (query) { - new Ajax.Request("public.php", { - parameters: query, - onComplete: function(transport) { - if (transport.responseText.match("select")) { - $('profile_box').innerHTML = transport.responseText; - //dojo.parser.parse('profile_box'); - } - } }); - } - - } catch (e) { - exception_error("fetchProfiles", e); - } + const query = "op=getProfiles&login=" + encodeURIComponent(document.forms["loginForm"].login.value); + + new Ajax.Request("public.php", { + parameters: query, + onComplete: function(transport) { + if (transport.responseText.match("select")) { + $('profile_box').innerHTML = transport.responseText; + //dojo.parser.parse('profile_box'); + } + } }); } - function gotoRegForm() { window.location.href = "register.php"; return false; } function bwLimitChange(elem) { - try { - var limit_set = elem.checked; - - setCookie("ttrss_bwlimit", limit_set, - ); - - } catch (e) { - exception_error("bwLimitChange", e); - } + Cookie.set("ttrss_bwlimit", elem.checked, + ); } @@ -139,7 +124,7 @@ function bwLimitChange(elem) {
- +
0) { ?> diff --git a/js/AppBase.js b/js/AppBase.js index ce040e8c9..9ab2f507e 100644 --- a/js/AppBase.js +++ b/js/AppBase.js @@ -7,15 +7,15 @@ define(["dojo/_base/declare"], function (declare) { hotkey_prefix: 0, hotkey_prefix_pressed: false, hotkey_prefix_timeout: 0, + constructor: function() { + window.onerror = this.Error.onWindowError; + }, getInitParam: function(k) { return this._initParams[k]; }, setInitParam: function(k, v) { this._initParams[k] = v; }, - constructor: function(args) { - // - }, enableCsrfSupport: function() { Ajax.Base.prototype.initialize = Ajax.Base.prototype.initialize.wrap( function (callOriginal, options) { @@ -176,7 +176,7 @@ define(["dojo/_base/declare"], function (declare) { if (callback) callback(transport); } catch (e) { - exception_error(e); + this.Error.report(e); } }); @@ -355,5 +355,67 @@ define(["dojo/_base/declare"], function (declare) { explainError: function(code) { return this.displayDlg(__("Error explained"), "explainError", code); }, + Error: { + report: function(error, params) { + params = params || {}; + + if (!error) return; + + console.error("[Error.report]", error, params); + + const message = params.message ? params.message : error.toString(); + + try { + xhrPost("backend.php", + {op: "rpc", method: "log", + file: params.filename ? params.filename : error.fileName, + line: params.lineno ? params.lineno : error.lineNumber, + msg: message, + context: error.stack}, + (transport) => { + console.warn("[Error.report] log response", transport.responseText); + }); + } catch (re) { + console.error("[Error.report] exception while saving logging error on server", re); + } + + try { + if (dijit.byId("exceptionDlg")) + dijit.byId("exceptionDlg").destroyRecursive(); + + let content = "

" + message + "

"; + + if (error.stack) + content += "
Stack trace:
" + + ""; + + content += "
"; + + content += ""; + content += "
"; + + const dialog = new dijit.Dialog({ + id: "exceptionDlg", + title: "Unhandled exception", + style: "width: 600px", + content: content + }); + + dialog.show(); + } catch (de) { + console.error("[Error.report] exception while showing error dialog", de); + + alert(error.stack ? error.stack : message); + } + + }, + onWindowError: function (message, filename, lineno, colno, error) { + // called without context (this) from window.onerror + App.Error.report(error, + {message: message, filename: filename, lineno: lineno, colno: colno}); + }, + } }); }); diff --git a/js/Article.js b/js/Article.js index d3ae8eed7..04cba8ab7 100644 --- a/js/Article.js +++ b/js/Article.js @@ -168,7 +168,7 @@ define(["dojo/_base/declare"], function (declare) { Notify.close(); } catch (e) { - exception_error(e); + App.Error.report(e); } }) } @@ -206,7 +206,7 @@ define(["dojo/_base/declare"], function (declare) { if (tooltip) tooltip.attr('label', data.content_full); } } catch (e) { - exception_error(e); + App.Error.report(e); } }); } diff --git a/js/CommonDialogs.js b/js/CommonDialogs.js index b9cee8873..81ad2ffce 100644 --- a/js/CommonDialogs.js +++ b/js/CommonDialogs.js @@ -152,7 +152,7 @@ define(["dojo/_base/declare"], function (declare) { } catch (e) { console.error(transport.responseText); - exception_error(e); + App.Error.report(e); } }); } diff --git a/js/CommonFilters.js b/js/CommonFilters.js index d2a3e6317..97a676c98 100644 --- a/js/CommonFilters.js +++ b/js/CommonFilters.js @@ -67,7 +67,7 @@ define(["dojo/_base/declare"], function (declare) { parentNode.appendChild(li); } } catch (e) { - exception_error(e); + App.Error.report(e); } }); }, @@ -117,7 +117,7 @@ define(["dojo/_base/declare"], function (declare) { } } catch (e) { - exception_error(e); + App.Error.report(e); } }); }, @@ -238,7 +238,7 @@ define(["dojo/_base/declare"], function (declare) { console.log("getTestResults: dialog closed, bailing out."); } } catch (e) { - exception_error(e); + App.Error.report(e); } }); diff --git a/js/FeedTree.js b/js/FeedTree.js index 37e3de2d1..75d1c901b 100755 --- a/js/FeedTree.js +++ b/js/FeedTree.js @@ -207,7 +207,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dijit/Tree", "dijit/Menu"], } } } catch (e) { - exception_error(e); + App.Error.report(e); } }, findNodeParentsAndExpandThem: function(feed, is_cat, root, parents) { @@ -242,7 +242,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dijit/Tree", "dijit/Menu"], this.expandParentNodes(feed, is_cat, parents.slice(0)); } } catch (e) { - exception_error(e); + App.Error.report(e); } }, selectFeed: function(feed, is_cat) { diff --git a/js/Feeds.js b/js/Feeds.js index eb9a468ad..fbcb56150 100644 --- a/js/Feeds.js +++ b/js/Feeds.js @@ -198,13 +198,13 @@ define(["dojo/_base/declare"], function (declare) { Feeds.init(); App.setLoadingProgress(25); } catch (e) { - exception_error(e); + App.Error.report(e); } }); tree.startup(); } catch (e) { - exception_error(e); + App.Error.report(e); } }, init: function() { @@ -380,7 +380,7 @@ define(["dojo/_base/declare"], function (declare) { Headlines.onLoaded(transport, offset); PluginHost.run(PluginHost.HOOK_FEED_LOADED, [feed, is_cat]); } catch (e) { - exception_error(e); + App.Error.report(e); } }); }); diff --git a/js/common.js b/js/common.js index de6d13a78..427e3034c 100755 --- a/js/common.js +++ b/js/common.js @@ -4,6 +4,16 @@ let _label_base_index = -1024; let loading_progress = 0; +/* error reporting shim */ + +// TODO: deprecated; remove +function exception_error(e, e_compat, filename, lineno, colno) { + if (typeof e == "string") + e = e_compat; + + App.Error.report(e, {filename: filename, lineno: lineno, colno: colno}); +} + /* xhr shorthand helpers */ function xhrPost(url, params, complete) { @@ -118,71 +128,6 @@ const Cookie = { } }; -/* error reporting */ - -function report_error(message, filename, lineno, colno, error) { - exception_error(error, null, filename, lineno); -} - -function exception_error(e, e_compat, filename, lineno, colno) { - if (typeof e == "string") e = e_compat; - - if (!e) return; // no exception object, nothing to report. - - try { - console.error(e); - const msg = e.toString(); - - try { - xhrPost("backend.php", - {op: "rpc", method: "log", - file: e.fileName ? e.fileName : filename, - line: e.lineNumber ? e.lineNumber : lineno, - msg: msg, context: e.stack}, - (transport) => { - console.warn(transport.responseText); - }); - - } catch (e) { - console.error("Exception while trying to log the error.", e); - } - - let content = "

" + msg + "

"; - - if (e.stack) { - content += "
Stack trace:
" + - ""; - } - - content += "
"; - - content += "
"; - - content += ""; - content += "
"; - - if (dijit.byId("exceptionDlg")) - dijit.byId("exceptionDlg").destroyRecursive(); - - const dialog = new dijit.Dialog({ - id: "exceptionDlg", - title: "Unhandled exception", - style: "width: 600px", - content: content}); - - dialog.show(); - - } catch (ei) { - console.error("Exception while trying to report an exception:", ei); - console.error("Original exception:", e); - - alert("Exception occured while trying to report an exception.\n" + - ei.stack + "\n\nOriginal exception:\n" + e.stack); - } -} - /* runtime notifications */ const Notify = { diff --git a/js/prefs.js b/js/prefs.js index dafdbcdee..c89c0494f 100755 --- a/js/prefs.js +++ b/js/prefs.js @@ -58,10 +58,6 @@ require(["dojo/_base/kernel", try { const _App = declare("fox.App", AppBase, { constructor: function() { - window.onerror = function (message, filename, lineno, colno, error) { - report_error(message, filename, lineno, colno, error); - }; - parser.parse(); this.setLoadingProgress(50); @@ -73,7 +69,7 @@ require(["dojo/_base/kernel", try { this.backendSanityCallback(transport); } catch (e) { - exception_error(e); + this.Error.report(e); } }); }, @@ -149,7 +145,7 @@ require(["dojo/_base/kernel", App = new _App(); } catch (e) { - exception_error(e); + this.Error.report(e); } }); }); \ No newline at end of file diff --git a/js/tt-rss.js b/js/tt-rss.js index 97d34fbc1..8931e9860 100644 --- a/js/tt-rss.js +++ b/js/tt-rss.js @@ -65,10 +65,6 @@ require(["dojo/_base/kernel", _widescreen_mode: false, hotkey_actions: {}, constructor: function () { - window.onerror = function (message, filename, lineno, colno, error) { - report_error(message, filename, lineno, colno, error); - }; - parser.parse(); this.setLoadingProgress(30); @@ -91,7 +87,7 @@ require(["dojo/_base/kernel", try { App.backendSanityCallback(transport); } catch (e) { - exception_error(e); + App.Error.report(e); } }); }, @@ -555,7 +551,7 @@ require(["dojo/_base/kernel", App = new _App(); } catch (e) { - exception_error(e); + App.Error.report(e); } }); }); diff --git a/plugins/embed_original/init.js b/plugins/embed_original/init.js index 6f797556b..1e9fcb253 100644 --- a/plugins/embed_original/init.js +++ b/plugins/embed_original/init.js @@ -1,60 +1,56 @@ function embedOriginalArticle(id) { - try { - const hasSandbox = "sandbox" in document.createElement("iframe"); + const hasSandbox = "sandbox" in document.createElement("iframe"); - if (!hasSandbox) { - alert(__("Sorry, your browser does not support sandboxed iframes.")); - return; - } + if (!hasSandbox) { + alert(__("Sorry, your browser does not support sandboxed iframes.")); + return; + } - let c = false; + let c = false; + + if (App.isCombinedMode()) { + c = $$("div#RROW-" + id + " div[class=content-inner]")[0]; + } else if (id == Article.getActive()) { + c = $$(".post .content")[0]; + } + + if (c) { + const iframe = c.parentNode.getElementsByClassName("embeddedContent")[0]; + + if (iframe) { + Element.show(c); + c.parentNode.removeChild(iframe); + + if (App.isCombinedMode()) { + Article.cdmScrollToId(id, true); + } - if (App.isCombinedMode()) { - c = $$("div#RROW-" + id + " div[class=content-inner]")[0]; - } else if (id == Article.getActive()) { - c = $$(".post .content")[0]; + return; } + } - if (c) { - const iframe = c.parentNode.getElementsByClassName("embeddedContent")[0]; + const query = { op: "pluginhandler", plugin: "embed_original", method: "getUrl", id: id }; - if (iframe) { - Element.show(c); - c.parentNode.removeChild(iframe); + xhrJson("backend.php", query, (reply) => { + if (reply) { + const iframe = new Element("iframe", { + class: "embeddedContent", + src: reply.url, + width: (c.parentNode.offsetWidth - 5) + 'px', + height: (c.parentNode.parentNode.offsetHeight - c.parentNode.firstChild.offsetHeight - 5) + 'px', + style: "overflow: auto; border: none; min-height: " + (document.body.clientHeight / 2) + "px;", + sandbox: 'allow-scripts', + }); + + if (c) { + Element.hide(c); + c.parentNode.insertBefore(iframe, c); if (App.isCombinedMode()) { Article.cdmScrollToId(id, true); } - - return; } } + }); - const query = { op: "pluginhandler", plugin: "embed_original", method: "getUrl", id: id }; - - xhrJson("backend.php", query, (reply) => { - if (reply) { - const iframe = new Element("iframe", { - class: "embeddedContent", - src: reply.url, - width: (c.parentNode.offsetWidth - 5) + 'px', - height: (c.parentNode.parentNode.offsetHeight - c.parentNode.firstChild.offsetHeight - 5) + 'px', - style: "overflow: auto; border: none; min-height: " + (document.body.clientHeight / 2) + "px;", - sandbox: 'allow-scripts', - }); - - if (c) { - Element.hide(c); - c.parentNode.insertBefore(iframe, c); - - if (App.isCombinedMode()) { - Article.cdmScrollToId(id, true); - } - } - } - }); - - } catch (e) { - exception_error("embedOriginalArticle", e); - } } diff --git a/plugins/import_export/import_export.js b/plugins/import_export/import_export.js index 56a2a5c3e..8dc5f7570 100644 --- a/plugins/import_export/import_export.js +++ b/plugins/import_export/import_export.js @@ -50,7 +50,7 @@ function exportData() { "Error occured, could not export data."; } } catch (e) { - exception_error("exportData", e, transport.responseText); + App.Error.report(e); } Notify.close(); @@ -71,7 +71,7 @@ function exportData() { } catch (e) { - exception_error("exportData", e); + App.Error.report(e); } } @@ -100,7 +100,7 @@ function dataImportComplete(iframe) { dialog.show(); } catch (e) { - exception_error("dataImportComplete", e); + App.Error.report(e); } } diff --git a/plugins/mail/mail.js b/plugins/mail/mail.js index b72289c2a..87e354b42 100644 --- a/plugins/mail/mail.js +++ b/plugins/mail/mail.js @@ -1,57 +1,52 @@ function emailArticle(id) { - try { - if (!id) { - var ids = Headlines.getSelected(); + if (!id) { + let ids = Headlines.getSelected(); - if (ids.length == 0) { - alert(__("No articles selected.")); - return; - } - - id = ids.toString(); + if (ids.length == 0) { + alert(__("No articles selected.")); + return; } - if (dijit.byId("emailArticleDlg")) - dijit.byId("emailArticleDlg").destroyRecursive(); - - var query = "backend.php?op=pluginhandler&plugin=mail&method=emailArticle¶m=" + encodeURIComponent(id); - - dialog = new dijit.Dialog({ - id: "emailArticleDlg", - title: __("Forward article by email"), - style: "width: 600px", - execute: function() { - if (this.validate()) { - xhrJson("backend.php", this.attr('value'), (reply) => { - if (reply) { - const error = reply['error']; - - if (error) { - alert(__('Error sending email:') + ' ' + error); - } else { - Notify.info('Your message has been sent.'); - dialog.hide(); - } + id = ids.toString(); + } + if (dijit.byId("emailArticleDlg")) + dijit.byId("emailArticleDlg").destroyRecursive(); + + const query = "backend.php?op=pluginhandler&plugin=mail&method=emailArticle¶m=" + encodeURIComponent(id); + + const dialog = new dijit.Dialog({ + id: "emailArticleDlg", + title: __("Forward article by email"), + style: "width: 600px", + execute: function() { + if (this.validate()) { + xhrJson("backend.php", this.attr('value'), (reply) => { + if (reply) { + const error = reply['error']; + + if (error) { + alert(__('Error sending email:') + ' ' + error); + } else { + Notify.info('Your message has been sent.'); + dialog.hide(); } - }); - } - }, - href: query}); - /* var tmph = dojo.connect(dialog, 'onLoad', function() { - dojo.disconnect(tmph); + } + }); + } + }, + href: query}); - new Ajax.Autocompleter('emailArticleDlg_destination', 'emailArticleDlg_dst_choices', - "backend.php?op=pluginhandler&plugin=mail&method=completeEmails", - { tokens: '', paramName: "search" }); - }); */ + /* var tmph = dojo.connect(dialog, 'onLoad', function() { + dojo.disconnect(tmph); - dialog.show(); + new Ajax.Autocompleter('emailArticleDlg_destination', 'emailArticleDlg_dst_choices', + "backend.php?op=pluginhandler&plugin=mail&method=completeEmails", + { tokens: '', paramName: "search" }); + }); */ - } catch (e) { - exception_error("emailArticle", e); - } + dialog.show(); } diff --git a/plugins/mailto/init.js b/plugins/mailto/init.js index dacff725e..92a90f8e9 100644 --- a/plugins/mailto/init.js +++ b/plugins/mailto/init.js @@ -1,32 +1,27 @@ function mailtoArticle(id) { - try { - if (!id) { - const ids = Headlines.getSelected(); + if (!id) { + const ids = Headlines.getSelected(); - if (ids.length == 0) { - alert(__("No articles selected.")); - return; - } - - id = ids.toString(); + if (ids.length == 0) { + alert(__("No articles selected.")); + return; } - if (dijit.byId("emailArticleDlg")) - dijit.byId("emailArticleDlg").destroyRecursive(); + id = ids.toString(); + } - const query = "backend.php?op=pluginhandler&plugin=mailto&method=emailArticle¶m=" + encodeURIComponent(id); + if (dijit.byId("emailArticleDlg")) + dijit.byId("emailArticleDlg").destroyRecursive(); - dialog = new dijit.Dialog({ - id: "emailArticleDlg", - title: __("Forward article by email"), - style: "width: 600px", - href: query}); + const query = "backend.php?op=pluginhandler&plugin=mailto&method=emailArticle¶m=" + encodeURIComponent(id); - dialog.show(); + const dialog = new dijit.Dialog({ + id: "emailArticleDlg", + title: __("Forward article by email"), + style: "width: 600px", + href: query}); - } catch (e) { - exception_error("emailArticle", e); - } + dialog.show(); } diff --git a/plugins/nsfw/init.js b/plugins/nsfw/init.js index 40ad2b0ba..adb6d43c0 100644 --- a/plugins/nsfw/init.js +++ b/plugins/nsfw/init.js @@ -1,12 +1,7 @@ function nsfwShow(elem) { - try { - content = elem.parentNode.getElementsBySelector("div.nswf.content")[0]; + let content = elem.parentNode.getElementsBySelector("div.nswf.content")[0]; - if (content) { - Element.toggle(content); - } - - } catch (e) { - exception_error("nswfSHow", e); + if (content) { + Element.toggle(content); } } diff --git a/plugins/shorten_expanded/init.js b/plugins/shorten_expanded/init.js index d9995e8ac..a5424ea38 100644 --- a/plugins/shorten_expanded/init.js +++ b/plugins/shorten_expanded/init.js @@ -1,29 +1,20 @@ var _shorten_expanded_threshold = 1.5; //window heights function expandSizeWrapper(id) { - try { - const row = $(id); + const row = $(id); - console.log(row); + if (row) { + const content = row.select(".contentSizeWrapper")[0]; + const link = row.select(".expandPrompt")[0]; - if (row) { - const content = row.select(".contentSizeWrapper")[0]; - const link = row.select(".expandPrompt")[0]; - - if (content) content.removeClassName("contentSizeWrapper"); - if (link) Element.hide(link); - - } - } catch (e) { - exception_error("expandSizeWrapper", e); + if (content) content.removeClassName("contentSizeWrapper"); + if (link) Element.hide(link); } return false; - } require(['dojo/_base/kernel', 'dojo/ready'], function (dojo, ready) { - ready(function() { PluginHost.register(PluginHost.HOOK_ARTICLE_RENDERED_CDM, function(row) { window.setTimeout(function() { @@ -48,5 +39,4 @@ require(['dojo/_base/kernel', 'dojo/ready'], function (dojo, ready) { return true; }); }); - }); diff --git a/register.php b/register.php index 6c76eed5a..1bd1b2544 100644 --- a/register.php +++ b/register.php @@ -135,13 +135,13 @@ f.sub_btn.disabled = true; } } catch (e) { - exception_error("checkUsername_callback", e); + App.Error.report(e); } } }); } catch (e) { - exception_error("checkUsername", e); + App.Error.report(e); } return false; @@ -171,7 +171,7 @@ return true; } catch (e) { - exception_error("validateRegForm", e); + alert(e.stack); return false; } } -- cgit v1.2.3-54-g00ecf