From 049a37aa0e7d37cafd979e7d470c7649700b5010 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Sat, 1 Dec 2018 17:05:28 +0300 Subject: WIP reshuffling of JS global context into separate logical objects --- classes/article.php | 2 +- classes/dlg.php | 2 +- classes/feeds.php | 16 ++++++++-------- classes/pref/feeds.php | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) (limited to 'classes') diff --git a/classes/article.php b/classes/article.php index 50a61a019..bc2e76537 100755 --- a/classes/article.php +++ b/classes/article.php @@ -877,7 +877,7 @@ class Article extends Handler_Protected { $tags_str = ""; for ($i = 0; $i < $maxtags; $i++) { - $tags_str .= "" . $tags[$i] . ", "; + $tags_str .= "" . $tags[$i] . ", "; } $tags_str = mb_substr($tags_str, 0, mb_strlen($tags_str)-2); diff --git a/classes/dlg.php b/classes/dlg.php index 9ac5cd12f..d73a53618 100644 --- a/classes/dlg.php +++ b/classes/dlg.php @@ -139,7 +139,7 @@ class Dlg extends Handler_Protected { $key_escaped = str_replace("'", "\\'", $key); - echo "' . $key . ' '; } diff --git a/classes/feeds.php b/classes/feeds.php index b548205ed..93e44e3bb 100755 --- a/classes/feeds.php +++ b/classes/feeds.php @@ -51,7 +51,7 @@ class Feeds extends Handler_Protected { $reply .= " + onclick=\"Utils.displayDlg('".__("View as RSS")."','generatedFeed', '$feed_id:$is_cat:$rss_link')\"> "; @@ -137,7 +137,7 @@ class Feeds extends Handler_Protected { //$reply .= ""; - $reply .= ""; + $reply .= ""; $reply .= ""; @@ -392,7 +392,7 @@ class Feeds extends Handler_Protected { $reply['content'] .= "
". "
$feed_icon_img
". - "". + "". $line["feed_title"]." $vf_catchup_link
"; @@ -434,7 +434,7 @@ class Feeds extends Handler_Protected { if (@$line["feed_title"]) { $rgba = @$rgba_cache[$feed_id]; - $reply['content'] .= "". + $reply['content'] .= "". truncate_string($line["feed_title"],30).""; } } @@ -451,7 +451,7 @@ class Feeds extends Handler_Protected { if ($line["feed_title"] && !$vfeed_group_enabled) { - $reply['content'] .= " $feed_icon_img"; @@ -488,7 +488,7 @@ class Feeds extends Handler_Protected { $reply['content'] .= "
". "
$feed_icon_img
". - "". + "". $line["feed_title"]." $vf_catchup_link
"; } @@ -547,7 +547,7 @@ class Feeds extends Handler_Protected { $tmp_content .= ""; } @@ -561,7 +561,7 @@ class Feeds extends Handler_Protected { if (!get_pref("VFEED_GROUP_BY_FEED") && $line["feed_title"]) { $tmp_content .= "$feed_icon_img"; + onclick=\"Feeds.viewfeed({feed:$feed_id})\">$feed_icon_img
"; } $tmp_content .= ""; //score wrapper2 diff --git a/classes/pref/feeds.php b/classes/pref/feeds.php index 43570c740..23e9baee9 100755 --- a/classes/pref/feeds.php +++ b/classes/pref/feeds.php @@ -1174,7 +1174,7 @@ class Pref_Feeds extends Handler_Protected { print "
-
"; @@ -1306,7 +1306,7 @@ class Pref_Feeds extends Handler_Protected { print_warning("Published OPML does not include your Tiny Tiny RSS settings, feeds that require authentication or feeds hidden from Popular feeds."); - print " "; PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION, @@ -1323,7 +1323,7 @@ class Pref_Feeds extends Handler_Protected { print "

"; - print " "; print ""; if (!(defined('_DISABLE_FEED_BROWSER') && _DISABLE_FEED_BROWSER)) { - print ""; + print ""; } print " diff --git a/classes/pref/feeds.php b/classes/pref/feeds.php index 23e9baee9..c061243ee 100755 --- a/classes/pref/feeds.php +++ b/classes/pref/feeds.php @@ -1149,7 +1149,7 @@ class Pref_Feeds extends Handler_Protected { if ($num_errors > 0) { $error_button = ""; } @@ -1190,7 +1190,7 @@ class Pref_Feeds extends Handler_Protected { print "

". "" . __('Feeds').""; print "
"; - print "
".__('Subscribe to feed')."
"; print "
".__('Edit selected feeds')."
"; diff --git a/js/feedlist.js b/js/feedlist.js index ddef1a586..f2f5e60ba 100644 --- a/js/feedlist.js +++ b/js/feedlist.js @@ -190,7 +190,7 @@ const Feeds = { try { Feeds.init(); - setLoadingProgress(25); + Utils.setLoadingProgress(25); } catch (e) { exception_error(e); } @@ -204,7 +204,7 @@ const Feeds = { init: function() { console.log("in feedlist init"); - setLoadingProgress(50); + Utils.setLoadingProgress(50); document.onkeydown = App.hotkeyHandler; setInterval(hotkeyPrefixTimeout, 3 * 1000); @@ -602,5 +602,35 @@ const Feeds = { if (nuf) return tree.model.store.getValue(nuf, 'bare_id'); - } + }, + search: function() { + const query = "backend.php?op=feeds&method=search¶m=" + + param_escape(Feeds.getActiveFeedId() + ":" + Feeds.activeFeedIsCat()); + + if (dijit.byId("searchDlg")) + dijit.byId("searchDlg").destroyRecursive(); + + const dialog = new dijit.Dialog({ + id: "searchDlg", + title: __("Search"), + style: "width: 600px", + execute: function () { + if (this.validate()) { + Feeds._search_query = this.attr('value'); + this.hide(); + Feeds.viewCurrentFeed(); + } + }, + href: query + }); + + dialog.show(); + }, + updateRandomFeed: function() { + console.log("in update_random_feed"); + + xhrPost("backend.php", {op: "rpc", method: "updateRandomFeed"}, (transport) => { + Utils.handleRpcJson(transport, true); + }); + }, }; diff --git a/js/functions.js b/js/functions.js index f2463dda3..0bddbbf0e 100755 --- a/js/functions.js +++ b/js/functions.js @@ -65,6 +65,70 @@ const Utils = { get_seq: function() { return this._rpc_seq; }, + setLoadingProgress: function(p) { + loading_progress += p; + + if (dijit.byId("loading_bar")) + dijit.byId("loading_bar").update({progress: loading_progress}); + + if (loading_progress >= 90) + Element.hide("overlay"); + + }, + keyeventToAction: function(e) { + + const hotkeys_map = getInitParam("hotkeys"); + const keycode = e.which; + const keychar = String.fromCharCode(keycode).toLowerCase(); + + if (keycode == 27) { // escape and drop prefix + hotkey_prefix = false; + } + + if (keycode == 16 || keycode == 17) return; // ignore lone shift / ctrl + + if (!hotkey_prefix && hotkeys_map[0].indexOf(keychar) != -1) { + + const date = new Date(); + const ts = Math.round(date.getTime() / 1000); + + hotkey_prefix = keychar; + hotkey_prefix_pressed = ts; + + $("cmdline").innerHTML = keychar; + Element.show("cmdline"); + + e.stopPropagation(); + + return false; + } + + Element.hide("cmdline"); + + let hotkey_name = keychar.search(/[a-zA-Z0-9]/) != -1 ? keychar : "(" + keycode + ")"; + + // ensure ^*char notation + if (e.shiftKey) hotkey_name = "*" + hotkey_name; + if (e.ctrlKey) hotkey_name = "^" + hotkey_name; + if (e.altKey) hotkey_name = "+" + hotkey_name; + if (e.metaKey) hotkey_name = "%" + hotkey_name; + + const hotkey_full = hotkey_prefix ? hotkey_prefix + " " + hotkey_name : hotkey_name; + hotkey_prefix = false; + + let action_name = false; + + for (const sequence in hotkeys_map[1]) { + if (sequence == hotkey_full) { + action_name = hotkeys_map[1][sequence]; + break; + } + } + + console.log('keyeventToAction', hotkey_full, '=>', action_name); + + return action_name; + }, cleanupMemory: function(root) { const dijits = dojo.query("[widgetid]", dijit.byId(root).domNode).map(dijit.byNode); @@ -311,6 +375,281 @@ const Utils = { } }; +const CommonDialogs = { + quickAddFeed: function() { + const query = "backend.php?op=feeds&method=quickAddFeed"; + + // overlapping widgets + if (dijit.byId("batchSubDlg")) dijit.byId("batchSubDlg").destroyRecursive(); + if (dijit.byId("feedAddDlg")) dijit.byId("feedAddDlg").destroyRecursive(); + + const dialog = new dijit.Dialog({ + id: "feedAddDlg", + title: __("Subscribe to Feed"), + style: "width: 600px", + show_error: function (msg) { + const elem = $("fadd_error_message"); + + elem.innerHTML = msg; + + if (!Element.visible(elem)) + new Effect.Appear(elem); + + }, + execute: function () { + if (this.validate()) { + console.log(dojo.objectToQuery(this.attr('value'))); + + const feed_url = this.attr('value').feed; + + Element.show("feed_add_spinner"); + Element.hide("fadd_error_message"); + + xhrPost("backend.php", this.attr('value'), (transport) => { + try { + + try { + var reply = JSON.parse(transport.responseText); + } catch (e) { + Element.hide("feed_add_spinner"); + alert(__("Failed to parse output. This can indicate server timeout and/or network issues. Backend output was logged to browser console.")); + console.log('quickAddFeed, backend returned:' + transport.responseText); + return; + } + + const rc = reply['result']; + + notify(''); + Element.hide("feed_add_spinner"); + + console.log(rc); + + switch (parseInt(rc['code'])) { + case 1: + dialog.hide(); + notify_info(__("Subscribed to %s").replace("%s", feed_url)); + + Feeds.reload(); + break; + case 2: + dialog.show_error(__("Specified URL seems to be invalid.")); + break; + case 3: + dialog.show_error(__("Specified URL doesn't seem to contain any feeds.")); + break; + case 4: + const feeds = rc['feeds']; + + Element.show("fadd_multiple_notify"); + + const select = dijit.byId("feedDlg_feedContainerSelect"); + + while (select.getOptions().length > 0) + select.removeOption(0); + + select.addOption({value: '', label: __("Expand to select feed")}); + + let count = 0; + for (const feedUrl in feeds) { + select.addOption({value: feedUrl, label: feeds[feedUrl]}); + count++; + } + + Effect.Appear('feedDlg_feedsContainer', {duration: 0.5}); + + break; + case 5: + dialog.show_error(__("Couldn't download the specified URL: %s").replace("%s", rc['message'])); + break; + case 6: + dialog.show_error(__("XML validation failed: %s").replace("%s", rc['message'])); + break; + case 0: + dialog.show_error(__("You are already subscribed to this feed.")); + break; + } + + } catch (e) { + console.error(transport.responseText); + exception_error(e); + } + }); + } + }, + href: query + }); + + dialog.show(); + }, + showFeedsWithErrors: function() { + const query = {op: "pref-feeds", method: "feedsWithErrors"}; + + if (dijit.byId("errorFeedsDlg")) + dijit.byId("errorFeedsDlg").destroyRecursive(); + + const dialog = new dijit.Dialog({ + id: "errorFeedsDlg", + title: __("Feeds with update errors"), + style: "width: 600px", + getSelectedFeeds: function () { + return getSelectedTableRowIds("prefErrorFeedList"); + }, + removeSelected: function () { + const sel_rows = this.getSelectedFeeds(); + + if (sel_rows.length > 0) { + if (confirm(__("Remove selected feeds?"))) { + notify_progress("Removing selected feeds...", true); + + const query = { + op: "pref-feeds", method: "remove", + ids: sel_rows.toString() + }; + + xhrPost("backend.php", query, () => { + notify(''); + dialog.hide(); + Feeds.reload(); + }); + } + + } else { + alert(__("No feeds are selected.")); + } + }, + execute: function () { + if (this.validate()) { + // + } + }, + href: "backend.php?" + dojo.objectToQuery(query) + }); + + dialog.show(); + }, + feedBrowser: function() { + const query = {op: "feeds", method: "feedBrowser"}; + + if (dijit.byId("feedAddDlg")) + dijit.byId("feedAddDlg").hide(); + + if (dijit.byId("feedBrowserDlg")) + dijit.byId("feedBrowserDlg").destroyRecursive(); + + // noinspection JSUnusedGlobalSymbols + const dialog = new dijit.Dialog({ + id: "feedBrowserDlg", + title: __("More Feeds"), + style: "width: 600px", + getSelectedFeedIds: function () { + const list = $$("#browseFeedList li[id*=FBROW]"); + const selected = []; + + list.each(function (child) { + const id = child.id.replace("FBROW-", ""); + + if (child.hasClassName('Selected')) { + selected.push(id); + } + }); + + return selected; + }, + getSelectedFeeds: function () { + const list = $$("#browseFeedList li.Selected"); + const selected = []; + + list.each(function (child) { + const title = child.getElementsBySelector("span.fb_feedTitle")[0].innerHTML; + const url = child.getElementsBySelector("a.fb_feedUrl")[0].href; + + selected.push([title, url]); + + }); + + return selected; + }, + + subscribe: function () { + const mode = this.attr('value').mode; + let selected = []; + + if (mode == "1") + selected = this.getSelectedFeeds(); + else + selected = this.getSelectedFeedIds(); + + if (selected.length > 0) { + dijit.byId("feedBrowserDlg").hide(); + + notify_progress("Loading, please wait...", true); + + const query = { + op: "rpc", method: "massSubscribe", + payload: JSON.stringify(selected), mode: mode + }; + + xhrPost("backend.php", query, () => { + notify(''); + Feeds.reload(); + }); + + } else { + alert(__("No feeds are selected.")); + } + + }, + update: function () { + Element.show('feed_browser_spinner'); + + xhrPost("backend.php", dialog.attr("value"), (transport) => { + notify(''); + + Element.hide('feed_browser_spinner'); + + const reply = JSON.parse(transport.responseText); + const mode = reply['mode']; + + if ($("browseFeedList") && reply['content']) { + $("browseFeedList").innerHTML = reply['content']; + } + + dojo.parser.parse("browseFeedList"); + + if (mode == 2) { + Element.show(dijit.byId('feed_archive_remove').domNode); + } else { + Element.hide(dijit.byId('feed_archive_remove').domNode); + } + }); + }, + removeFromArchive: function () { + const selected = this.getSelectedFeedIds(); + + if (selected.length > 0) { + if (confirm(__("Remove selected feeds from the archive? Feeds with stored articles will not be removed."))) { + Element.show('feed_browser_spinner'); + + const query = {op: "rpc", method: "remarchive", ids: selected.toString()}; + + xhrPost("backend.php", query, () => { + dialog.update(); + }); + } + } + }, + execute: function () { + if (this.validate()) { + this.subscribe(); + } + }, + href: "backend.php?" + dojo.objectToQuery(query) + }); + + dialog.show(); + } +}; + function report_error(message, filename, lineno, colno, error) { exception_error(error, null, filename, lineno); } @@ -665,17 +1004,6 @@ function explainError(code) { return Utils.displayDlg(__("Error explained"), "explainError", code); } -function setLoadingProgress(p) { - loading_progress += p; - - if (dijit.byId("loading_bar")) - dijit.byId("loading_bar").update({progress: loading_progress}); - - if (loading_progress >= 90) - Element.hide("overlay"); - -} - function strip_tags(s) { return s.replace(/<\/?[^>]+(>|$)/g, ""); } @@ -772,113 +1100,6 @@ function addLabel(select, callback) { } -function quickAddFeed() { - const query = "backend.php?op=feeds&method=quickAddFeed"; - - // overlapping widgets - if (dijit.byId("batchSubDlg")) dijit.byId("batchSubDlg").destroyRecursive(); - if (dijit.byId("feedAddDlg")) dijit.byId("feedAddDlg").destroyRecursive(); - - const dialog = new dijit.Dialog({ - id: "feedAddDlg", - title: __("Subscribe to Feed"), - style: "width: 600px", - show_error: function(msg) { - const elem = $("fadd_error_message"); - - elem.innerHTML = msg; - - if (!Element.visible(elem)) - new Effect.Appear(elem); - - }, - execute: function() { - if (this.validate()) { - console.log(dojo.objectToQuery(this.attr('value'))); - - const feed_url = this.attr('value').feed; - - Element.show("feed_add_spinner"); - Element.hide("fadd_error_message"); - - xhrPost("backend.php", this.attr('value'), (transport) => { - try { - - try { - var reply = JSON.parse(transport.responseText); - } catch (e) { - Element.hide("feed_add_spinner"); - alert(__("Failed to parse output. This can indicate server timeout and/or network issues. Backend output was logged to browser console.")); - console.log('quickAddFeed, backend returned:' + transport.responseText); - return; - } - - const rc = reply['result']; - - notify(''); - Element.hide("feed_add_spinner"); - - console.log(rc); - - switch (parseInt(rc['code'])) { - case 1: - dialog.hide(); - notify_info(__("Subscribed to %s").replace("%s", feed_url)); - - Feeds.reload(); - break; - case 2: - dialog.show_error(__("Specified URL seems to be invalid.")); - break; - case 3: - dialog.show_error(__("Specified URL doesn't seem to contain any feeds.")); - break; - case 4: - const feeds = rc['feeds']; - - Element.show("fadd_multiple_notify"); - - const select = dijit.byId("feedDlg_feedContainerSelect"); - - while (select.getOptions().length > 0) - select.removeOption(0); - - select.addOption({value: '', label: __("Expand to select feed")}); - - let count = 0; - for (const feedUrl in feeds) { - select.addOption({value: feedUrl, label: feeds[feedUrl]}); - count++; - } - - Effect.Appear('feedDlg_feedsContainer', {duration : 0.5}); - - break; - case 5: - dialog.show_error(__("Couldn't download the specified URL: %s"). - replace("%s", rc['message'])); - break; - case 6: - dialog.show_error(__("XML validation failed: %s"). - replace("%s", rc['message'])); - break; - case 0: - dialog.show_error(__("You are already subscribed to this feed.")); - break; - } - - } catch (e) { - console.error(transport.responseText); - exception_error(e); - } - }); - } - }, - href: query}); - - dialog.show(); -} - function createNewRuleElement(parentNode, replaceNode) { const form = document.forms["filter_new_rule_form"]; const query = { op: "pref-filters", method: "printrulename", rule: dojo.formToJson(form) }; @@ -1382,172 +1603,6 @@ function editFeed(feed) { dialog.show(); } -function feedBrowser() { - const query = { op: "feeds", method: "feedBrowser" }; - - if (dijit.byId("feedAddDlg")) - dijit.byId("feedAddDlg").hide(); - - if (dijit.byId("feedBrowserDlg")) - dijit.byId("feedBrowserDlg").destroyRecursive(); - - // noinspection JSUnusedGlobalSymbols - const dialog = new dijit.Dialog({ - id: "feedBrowserDlg", - title: __("More Feeds"), - style: "width: 600px", - getSelectedFeedIds: function () { - const list = $$("#browseFeedList li[id*=FBROW]"); - const selected = []; - - list.each(function (child) { - const id = child.id.replace("FBROW-", ""); - - if (child.hasClassName('Selected')) { - selected.push(id); - } - }); - - return selected; - }, - getSelectedFeeds: function () { - const list = $$("#browseFeedList li.Selected"); - const selected = []; - - list.each(function (child) { - const title = child.getElementsBySelector("span.fb_feedTitle")[0].innerHTML; - const url = child.getElementsBySelector("a.fb_feedUrl")[0].href; - - selected.push([title, url]); - - }); - - return selected; - }, - - subscribe: function () { - const mode = this.attr('value').mode; - let selected = []; - - if (mode == "1") - selected = this.getSelectedFeeds(); - else - selected = this.getSelectedFeedIds(); - - if (selected.length > 0) { - dijit.byId("feedBrowserDlg").hide(); - - notify_progress("Loading, please wait...", true); - - const query = { op: "rpc", method: "massSubscribe", - payload: JSON.stringify(selected), mode: mode }; - - xhrPost("backend.php", query, () => { - notify(''); - Feeds.reload(); - }); - - } else { - alert(__("No feeds are selected.")); - } - - }, - update: function () { - Element.show('feed_browser_spinner'); - - xhrPost("backend.php", dialog.attr("value"), (transport) => { - notify(''); - - Element.hide('feed_browser_spinner'); - - const reply = JSON.parse(transport.responseText); - const mode = reply['mode']; - - if ($("browseFeedList") && reply['content']) { - $("browseFeedList").innerHTML = reply['content']; - } - - dojo.parser.parse("browseFeedList"); - - if (mode == 2) { - Element.show(dijit.byId('feed_archive_remove').domNode); - } else { - Element.hide(dijit.byId('feed_archive_remove').domNode); - } - }); - }, - removeFromArchive: function () { - const selected = this.getSelectedFeedIds(); - - if (selected.length > 0) { - if (confirm(__("Remove selected feeds from the archive? Feeds with stored articles will not be removed."))) { - Element.show('feed_browser_spinner'); - - const query = { op: "rpc", method: "remarchive", ids: selected.toString() }; - - xhrPost("backend.php", query, () => { - dialog.update(); - }); - } - } - }, - execute: function () { - if (this.validate()) { - this.subscribe(); - } - }, - href: "backend.php?" + dojo.objectToQuery(query) - }); - - dialog.show(); -} - -// noinspection JSUnusedGlobalSymbols -function showFeedsWithErrors() { - const query = { op: "pref-feeds", method: "feedsWithErrors" }; - - if (dijit.byId("errorFeedsDlg")) - dijit.byId("errorFeedsDlg").destroyRecursive(); - - const dialog = new dijit.Dialog({ - id: "errorFeedsDlg", - title: __("Feeds with update errors"), - style: "width: 600px", - getSelectedFeeds: function() { - return getSelectedTableRowIds("prefErrorFeedList"); - }, - removeSelected: function() { - const sel_rows = this.getSelectedFeeds(); - - if (sel_rows.length > 0) { - if (confirm(__("Remove selected feeds?"))) { - notify_progress("Removing selected feeds...", true); - - const query = { op: "pref-feeds", method: "remove", - ids: sel_rows.toString() }; - - xhrPost("backend.php", query, () => { - notify(''); - dialog.hide(); - Feeds.reload(); - }); - } - - } else { - alert(__("No feeds are selected.")); - } - }, - execute: function() { - if (this.validate()) { - // - } - }, - href: "backend.php?" + dojo.objectToQuery(query) - }); - - dialog.show(); -} - function get_timestamp() { const date = new Date(); return Math.round(date.getTime() / 1000); @@ -1602,58 +1657,3 @@ function popupOpenArticle(id) { w.opener = null; w.location = "backend.php?op=article&method=view&mode=raw&html=1&zoom=1&id=" + id + "&csrf_token=" + getInitParam("csrf_token"); } - -function keyeventToAction(e) { - - const hotkeys_map = getInitParam("hotkeys"); - const keycode = e.which; - const keychar = String.fromCharCode(keycode).toLowerCase(); - - if (keycode == 27) { // escape and drop prefix - hotkey_prefix = false; - } - - if (keycode == 16 || keycode == 17) return; // ignore lone shift / ctrl - - if (!hotkey_prefix && hotkeys_map[0].indexOf(keychar) != -1) { - - const date = new Date(); - const ts = Math.round(date.getTime() / 1000); - - hotkey_prefix = keychar; - hotkey_prefix_pressed = ts; - - $("cmdline").innerHTML = keychar; - Element.show("cmdline"); - - e.stopPropagation(); - - return false; - } - - Element.hide("cmdline"); - - let hotkey_name = keychar.search(/[a-zA-Z0-9]/) != -1 ? keychar : "(" + keycode + ")"; - - // ensure ^*char notation - if (e.shiftKey) hotkey_name = "*" + hotkey_name; - if (e.ctrlKey) hotkey_name = "^" + hotkey_name; - if (e.altKey) hotkey_name = "+" + hotkey_name; - if (e.metaKey) hotkey_name = "%" + hotkey_name; - - const hotkey_full = hotkey_prefix ? hotkey_prefix + " " + hotkey_name : hotkey_name; - hotkey_prefix = false; - - let action_name = false; - - for (const sequence in hotkeys_map[1]) { - if (sequence == hotkey_full) { - action_name = hotkeys_map[1][sequence]; - break; - } - } - - console.log('keyeventToAction', hotkey_full, '=>', action_name); - - return action_name; -} \ No newline at end of file diff --git a/js/prefs.js b/js/prefs.js index 15007d014..e83e69bd5 100755 --- a/js/prefs.js +++ b/js/prefs.js @@ -49,7 +49,7 @@ const App = { try { parser.parse(); - setLoadingProgress(50); + Utils.setLoadingProgress(50); const clientTzOffset = new Date().getTimezoneOffset() * 60; const params = {op: "rpc", method: "sanityCheck", clientTzOffset: clientTzOffset}; @@ -66,7 +66,7 @@ const App = { }, initSecondStage: function() { document.onkeydown = this.hotkeyHandler; - setLoadingProgress(50); + Utils.setLoadingProgress(50); notify(""); let tab = getURLParam('tab'); @@ -91,12 +91,12 @@ const App = { hotkeyHandler: function (event) { if (event.target.nodeName == "INPUT" || event.target.nodeName == "TEXTAREA") return; - const action_name = keyeventToAction(event); + const action_name = Utils.keyeventToAction(event); if (action_name) { switch (action_name) { case "feed_subscribe": - quickAddFeed(); + CommonDialogs.quickAddFeed(); return false; case "create_label": addLabel(); diff --git a/js/tt-rss.js b/js/tt-rss.js index e48e4ece9..4c37102e6 100644 --- a/js/tt-rss.js +++ b/js/tt-rss.js @@ -1,10 +1,10 @@ /* global dijit, __ */ -let _widescreen_mode = false; let hotkey_actions = {}; const App = { global_unread: -1, + _widescreen_mode: false, init: function() { window.onerror = function (message, filename, lineno, colno, error) { @@ -56,7 +56,7 @@ const App = { if (!App.genericSanityCheck()) return false; - setLoadingProgress(30); + Utils.setLoadingProgress(30); init_hotkey_actions(); const a = document.createElement('audio'); @@ -132,21 +132,21 @@ const App = { Feeds.setActiveFeedId(hash_feed_id, hash_feed_is_cat); } - setLoadingProgress(50); + Utils.setLoadingProgress(50); ArticleCache.clear(); - _widescreen_mode = getInitParam("widescreen"); - this.switchPanelMode(_widescreen_mode); + this._widescreen_mode = getInitParam("widescreen"); + this.switchPanelMode(this._widescreen_mode); Headlines.initScrollHandler(); - console.log("second stage ok"); - if (getInitParam("simple_update")) { console.log("scheduling simple feed updater..."); - window.setTimeout(update_random_feed, 30 * 1000); + window.setInterval(Feeds.updateRandomFeed, 30 * 1000); } + + console.log("second stage ok"); }, genericSanityCheck: function() { setCookie("ttrss_test", "TEST"); @@ -176,7 +176,7 @@ const App = { hotkeyHandler(event) { if (event.target.nodeName == "INPUT" || event.target.nodeName == "TEXTAREA") return; - const action_name = keyeventToAction(event); + const action_name = Utils.keyeventToAction(event); if (action_name) { const action_func = hotkey_actions[action_name]; @@ -235,29 +235,6 @@ const App = { }, }; -function search() { - const query = "backend.php?op=feeds&method=search¶m=" + - param_escape(Feeds.getActiveFeedId() + ":" + Feeds.activeFeedIsCat()); - - if (dijit.byId("searchDlg")) - dijit.byId("searchDlg").destroyRecursive(); - - const dialog = new dijit.Dialog({ - id: "searchDlg", - title: __("Search"), - style: "width: 600px", - execute: function() { - if (this.validate()) { - Feeds._search_query = this.attr('value'); - this.hide(); - Feeds.viewCurrentFeed(); - } - }, - href: query}); - - dialog.show(); -} - function init_hotkey_actions() { hotkey_actions["next_feed"] = function () { const rv = dijit.byId("feedTree").getNextFeed( @@ -290,7 +267,7 @@ function init_hotkey_actions() { moveToPost('prev', true, true); }; hotkey_actions["search_dialog"] = function () { - search(); + Feeds.search(); }; hotkey_actions["toggle_mark"] = function () { selectionToggleMarked(); @@ -361,14 +338,13 @@ function init_hotkey_actions() { hotkey_actions["feed_refresh"] = function () { if (Feeds.getActiveFeedId() != undefined) { Feeds.viewfeed({feed: Feeds.getActiveFeedId(), is_cat: Feeds.activeFeedIsCat()}); - return; } }; hotkey_actions["feed_unhide_read"] = function () { Feeds.toggleDispRead(); }; hotkey_actions["feed_subscribe"] = function () { - quickAddFeed(); + CommonDialogs.quickAddFeed(); }; hotkey_actions["feed_debug_update"] = function () { if (!Feeds.activeFeedIsCat() && parseInt(Feeds.getActiveFeedId()) > 0) { @@ -392,7 +368,6 @@ function init_hotkey_actions() { hotkey_actions["feed_catchup"] = function () { if (Feeds.getActiveFeedId() != undefined) { Feeds.catchupCurrentFeed(); - return; } }; hotkey_actions["feed_reverse"] = function () { @@ -467,13 +442,13 @@ function init_hotkey_actions() { }; hotkey_actions["toggle_widescreen"] = function () { if (!App.isCombinedMode()) { - _widescreen_mode = !_widescreen_mode; + App._widescreen_mode = !App._widescreen_mode; // reset stored sizes because geometry changed setCookie("ttrss_ci_width", 0); setCookie("ttrss_ci_height", 0); - App.switchPanelMode(_widescreen_mode); + App.switchPanelMode(App._widescreen_mode); } else { alert(__("Widescreen is not available in combined mode.")); } @@ -518,10 +493,10 @@ function quickMenuGo(opid) { Utils.displayDlg(__("Tag cloud"), "printTagCloud"); break; case "qmcSearch": - search(); + Feeds.search(); break; case "qmcAddFeed": - quickAddFeed(); + CommonDialogs.quickAddFeed(); break; case "qmcDigest": window.location.href = "backend.php?op=digest"; @@ -561,13 +536,13 @@ function quickMenuGo(opid) { break; case "qmcToggleWidescreen": if (!App.isCombinedMode()) { - _widescreen_mode = !_widescreen_mode; + App._widescreen_mode = !App._widescreen_mode; // reset stored sizes because geometry changed setCookie("ttrss_ci_width", 0); setCookie("ttrss_ci_height", 0); - App.switchPanelMode(_widescreen_mode); + App.switchPanelMode(App._widescreen_mode); } else { alert(__("Widescreen is not available in combined mode.")); } @@ -584,15 +559,6 @@ function inPreferences() { return false; } -function update_random_feed() { - console.log("in update_random_feed"); - - xhrPost("backend.php", { op: "rpc", method: "updateRandomFeed" }, (transport) => { - Utils.handleRpcJson(transport, true); - window.setTimeout(update_random_feed, 30*1000); - }); -} - function hash_get(key) { const kv = window.location.hash.substring(1).toQueryParams(); return kv[key]; diff --git a/tests/functional/BasicTest.php b/tests/functional/BasicTest.php index dc44a67e1..c5bc70b4e 100644 --- a/tests/functional/BasicTest.php +++ b/tests/functional/BasicTest.php @@ -30,7 +30,7 @@ class BasicTest extends PHPUnit_Extensions_Selenium2TestCase { $this->execute(["script" => "dijit.byId('filterEditDlg').hide();", "args" => []]); - $this->execute(["script" => "quickAddFeed()", "args" => []]); + $this->execute(["script" => "CommonDialog.quickAddFeed()", "args" => []]); $this->byCssSelector("#feedAddDlg")->displayed(); $this->execute(["script" => "dijit.byId('feedAddDlg').hide();", "args" => []]); -- cgit v1.2.3-54-g00ecf From 642c37ea6117954fc19e2a800f2fce4c1304d89d Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Sat, 1 Dec 2018 21:01:53 +0300 Subject: further effocts to wrap JS stuff into objects --- classes/article.php | 2 +- classes/feeds.php | 26 +- js/feedlist.js | 25 +- js/functions.js | 6 +- js/prefs.js | 2 +- js/tt-rss.js | 46 +- js/viewfeed.js | 1097 ++++++++++++++++++++-------------------- plugins/embed_original/init.js | 6 +- plugins/mail/mail.js | 2 +- plugins/mailto/init.js | 2 +- plugins/mark_button/init.php | 4 +- 11 files changed, 596 insertions(+), 622 deletions(-) (limited to 'classes') diff --git a/classes/article.php b/classes/article.php index bc2e76537..60a956c8d 100755 --- a/classes/article.php +++ b/classes/article.php @@ -727,7 +727,7 @@ class Article extends Handler_Protected { if (!$zoom_mode) { $rv['content'] .= "$tags_str (+)"; + href=\"#\" onclick=\"Article.editArticleTags($id, $feed_id)\">(+)"; $rv['content'] .= "
"; + $marked_pic = ""; $published_pic_src = $line["published"] ? "pub_set.png" : "pub_unset.png"; $class .= $line["published"] ? " published" : ""; - $published_pic = ""; + $published_pic = ""; $updated_fmt = make_local_datetime($line["updated"], false, false, false, true); $date_entered_fmt = T_sprintf("Imported at %s", @@ -628,7 +628,7 @@ class Feeds extends Handler_Protected { $tmp_content .= "Tags $tags_str (+)"; + href=\"#\" onclick=\"Article.editArticleTags($id)\">(+)"; $num_comments = (int) $line["num_comments"]; $entry_comments = ""; diff --git a/js/feedlist.js b/js/feedlist.js index f2f5e60ba..ad863f94c 100644 --- a/js/feedlist.js +++ b/js/feedlist.js @@ -207,8 +207,8 @@ const Feeds = { Utils.setLoadingProgress(50); document.onkeydown = App.hotkeyHandler; - setInterval(hotkeyPrefixTimeout, 3 * 1000); - setInterval(catchupBatchedArticles, 10 * 1000); + window.setInterval(() => { hotkeyPrefixTimeout() }, 3 * 1000); + window.setInterval(() => { Headlines.catchupBatchedArticles() }, 10 * 1000); if (!this.getActiveFeedId()) { this.viewfeed({feed: -3}); @@ -246,10 +246,7 @@ const Feeds = { } else { setTimeout(() => { this.requestCounters(true); - - setInterval(() => { - this.requestCounters(); - }, 60 * 1000) + setInterval(() => { this.requestCounters(); }, 60 * 1000) }, 250); } }, @@ -271,7 +268,7 @@ const Feeds = { this.selectFeed(id, is_cat); - PluginHost.run(PluginHost.HOOK_FEED_SET_ACTIVE, _active_article_id); + PluginHost.run(PluginHost.HOOK_FEED_SET_ACTIVE, [this._active_feed_id, this._active_feed_is_cat]); }, selectFeed: function(feed, is_cat) { const tree = dijit.byId("feedTree"); @@ -303,7 +300,7 @@ const Feeds = { if (feed != this.getActiveFeedId() || this.activeFeedIsCat() != is_cat) { this._search_query = false; - setActiveArticleId(0); + Article.setActiveArticleId(0); } if (offset != 0) { @@ -330,8 +327,8 @@ const Feeds = { if (method) query.m = method; if (offset > 0) { - if (current_first_id) { - query.fid = current_first_id; + if (Headlines.current_first_id) { + query.fid = Headlines.current_first_id; } } @@ -343,8 +340,8 @@ const Feeds = { query.skip = offset; // to prevent duplicate feed titles when showing grouped vfeeds - if (vgroup_last_feed) { - query.vgrlf = vgroup_last_feed; + if (Headlines.vgroup_last_feed != undefined) { + query.vgrlf = Headlines.vgroup_last_feed; } } else if (!is_cat && feed == this.getActiveFeedId() && !params.method) { query.m = "ForceUpdate"; @@ -370,7 +367,7 @@ const Feeds = { window.clearTimeout(this._viewfeed_wait_timeout); this._viewfeed_wait_timeout = window.setTimeout(() => { - catchupBatchedArticles(() => { + Headlines.catchupBatchedArticles(() => { xhrPost("backend.php", query, (transport) => { try { this.setFeedExpandoIcon(feed, is_cat, 'images/blank_icon.gif'); @@ -492,7 +489,7 @@ const Feeds = { rows.each(function (row) { row.removeClassName("Unread"); - if (row.getAttribute("data-article-id") != getActiveArticleId()) { + if (row.getAttribute("data-article-id") != Article.getActiveArticleId()) { new Effect.Fade(row, {duration: 0.5}); } diff --git a/js/functions.js b/js/functions.js index 0bddbbf0e..1a0fca484 100755 --- a/js/functions.js +++ b/js/functions.js @@ -878,7 +878,7 @@ function toggleSelectRow2(sender, row, is_cdm) { row.removeClassName('Selected'); if (typeof updateSelectedPrompt != undefined) - updateSelectedPrompt(); + Headlines.updateSelectedPrompt(); } @@ -892,7 +892,7 @@ function toggleSelectRow(sender, row) { row.removeClassName('Selected'); if (typeof updateSelectedPrompt != undefined) - updateSelectedPrompt(); + Headlines.updateSelectedPrompt(); } // noinspection JSUnusedGlobalSymbols @@ -1412,7 +1412,7 @@ function quickAddFilter() { } else { - const query = { op: "rpc", method: "getlinktitlebyid", id: getActiveArticleId() }; + const query = { op: "rpc", method: "getlinktitlebyid", id: Article.getActiveArticleId() }; xhrPost("backend.php", query, (transport) => { const reply = JSON.parse(transport.responseText); diff --git a/js/prefs.js b/js/prefs.js index e83e69bd5..a9417cf3c 100755 --- a/js/prefs.js +++ b/js/prefs.js @@ -86,7 +86,7 @@ const App = { }, 100); } - setInterval(hotkeyPrefixTimeout, 5 * 1000); + setInterval(() => { hotkeyPrefixTimeout() }, 5 * 1000); }, hotkeyHandler: function (event) { if (event.target.nodeName == "INPUT" || event.target.nodeName == "TEXTAREA") return; diff --git a/js/tt-rss.js b/js/tt-rss.js index 4c37102e6..02cf1ddb6 100644 --- a/js/tt-rss.js +++ b/js/tt-rss.js @@ -143,7 +143,7 @@ const App = { if (getInitParam("simple_update")) { console.log("scheduling simple feed updater..."); - window.setInterval(Feeds.updateRandomFeed, 30 * 1000); + window.setInterval(() => { Feeds.updateRandomFeed() }, 30 * 1000); } console.log("second stage ok"); @@ -191,7 +191,7 @@ const App = { switchPanelMode: function(wide) { if (App.isCombinedMode()) return; - const article_id = getActiveArticleId(); + const article_id = Article.getActiveArticleId(); if (wide) { dijit.byId("headlines-wrap-inner").attr("design", 'sidebar'); @@ -249,44 +249,44 @@ function init_hotkey_actions() { if (rv) Feeds.viewfeed({feed: rv[0], is_cat: rv[1], delayed: true}) }; hotkey_actions["next_article"] = function () { - moveToPost('next'); + Headlines.moveToPost('next'); }; hotkey_actions["prev_article"] = function () { - moveToPost('prev'); + Headlines.moveToPost('prev'); }; hotkey_actions["next_article_noscroll"] = function () { - moveToPost('next', true); + Headlines.moveToPost('next', true); }; hotkey_actions["prev_article_noscroll"] = function () { - moveToPost('prev', true); + Headlines.moveToPost('prev', true); }; hotkey_actions["next_article_noexpand"] = function () { - moveToPost('next', true, true); + Headlines.moveToPost('next', true, true); }; hotkey_actions["prev_article_noexpand"] = function () { - moveToPost('prev', true, true); + Headlines.moveToPost('prev', true, true); }; hotkey_actions["search_dialog"] = function () { Feeds.search(); }; hotkey_actions["toggle_mark"] = function () { - selectionToggleMarked(); + Headlines.selectionToggleMarked(); }; hotkey_actions["toggle_publ"] = function () { - selectionTogglePublished(); + Headlines.selectionTogglePublished(); }; hotkey_actions["toggle_unread"] = function () { - selectionToggleUnread({no_error: 1}); + Headlines.selectionToggleUnread({no_error: 1}); }; hotkey_actions["edit_tags"] = function () { - const id = getActiveArticleId(); + const id = Article.getActiveArticleId(); if (id) { - editArticleTags(id); + Article.editArticleTags(id); } } hotkey_actions["open_in_new_window"] = function () { - if (getActiveArticleId()) { - Article.openArticleInNewWindow(getActiveArticleId()); + if (Article.getActiveArticleId()) { + Article.openArticleInNewWindow(Article.getActiveArticleId()); } }; hotkey_actions["catchup_below"] = function () { @@ -318,22 +318,22 @@ function init_hotkey_actions() { } }; hotkey_actions["select_all"] = function () { - selectArticles('all'); + Headlines.selectArticles('all'); }; hotkey_actions["select_unread"] = function () { - selectArticles('unread'); + Headlines.selectArticles('unread'); }; hotkey_actions["select_marked"] = function () { - selectArticles('marked'); + Headlines.selectArticles('marked'); }; hotkey_actions["select_published"] = function () { - selectArticles('published'); + Headlines.selectArticles('published'); }; hotkey_actions["select_invert"] = function () { - selectArticles('invert'); + Headlines.selectArticles('invert'); }; hotkey_actions["select_none"] = function () { - selectArticles('none'); + Headlines.selectArticles('none'); }; hotkey_actions["feed_refresh"] = function () { if (Feeds.getActiveFeedId() != undefined) { @@ -434,8 +434,8 @@ function init_hotkey_actions() { }; hotkey_actions["toggle_embed_original"] = function () { if (typeof embedOriginalArticle != "undefined") { - if (getActiveArticleId()) - embedOriginalArticle(getActiveArticleId()); + if (Article.getActiveArticleId()) + embedOriginalArticle(Article.getActiveArticleId()); } else { alert(__("Please enable embed_original plugin first.")); } diff --git a/js/viewfeed.js b/js/viewfeed.js index 45d2efebb..cbbea8a05 100755 --- a/js/viewfeed.js +++ b/js/viewfeed.js @@ -1,16 +1,6 @@ /* global dijit, __, ngettext */ -let _active_article_id = 0; - -let vgroup_last_feed = false; let post_under_pointer = false; - -let catchup_id_batch = []; -//let catchup_timeout_id = false; - -//let cids_requested = []; -let loaded_article_ids = []; -let current_first_id = 0; let last_search_query; const ArticleCache = { @@ -38,8 +28,9 @@ const ArticleCache = { }; const Article = { + _active_article_id: 0, setSelectionScore: function() { - const ids = getSelectedArticleIds2(); + const ids = Headlines.getSelectedArticleIds2(); if (ids.length > 0) { console.log(ids); @@ -127,7 +118,7 @@ const Article = { c.attr('content', article); PluginHost.run(PluginHost.HOOK_ARTICLE_RENDERED, c.domNode); - correctHeadlinesOffset(getActiveArticleId()); + correctHeadlinesOffset(Article.getActiveArticleId()); try { c.focus(); @@ -135,7 +126,7 @@ const Article = { } }, view: function(id, noexpand) { - setActiveArticleId(id); + Article.setActiveArticleId(id); if (!noexpand) { console.log("loading article", id); @@ -164,7 +155,7 @@ const Article = { if (reply) { reply.each(function (article) { - if (getActiveArticleId() == article['id']) { + if (Article.getActiveArticleId() == article['id']) { Article.renderArticle(article['content']); } ArticleCache.set(article['id'], article['content']); @@ -191,7 +182,7 @@ const Article = { return false; }, cdmCollapseActive: function(event) { - const row = $("RROW-" + getActiveArticleId()); + const row = $("RROW-" + Article.getActiveArticleId()); if (row) { row.removeClassName("active"); @@ -200,38 +191,157 @@ const Article = { if (cb && !row.hasClassName("Selected")) cb.attr("checked", false); - setActiveArticleId(0); + Article.setActiveArticleId(0); if (event) event.stopPropagation(); return false; } + }, + editArticleTags: function(id) { + const query = "backend.php?op=article&method=editArticleTags¶m=" + param_escape(id); + + if (dijit.byId("editTagsDlg")) + dijit.byId("editTagsDlg").destroyRecursive(); + + const dialog = new dijit.Dialog({ + id: "editTagsDlg", + title: __("Edit article Tags"), + style: "width: 600px", + execute: function () { + if (this.validate()) { + notify_progress("Saving article tags...", true); + + xhrPost("backend.php", this.attr('value'), (transport) => { + try { + notify(''); + dialog.hide(); + + const data = JSON.parse(transport.responseText); + + if (data) { + const id = data.id; + + const tags = $("ATSTR-" + id); + const tooltip = dijit.byId("ATSTRTIP-" + id); + + if (tags) tags.innerHTML = data.content; + if (tooltip) tooltip.attr('label', data.content_full); + } + } catch (e) { + exception_error(e); + } + }); + } + }, + href: query + }); + + const tmph = dojo.connect(dialog, 'onLoad', function () { + dojo.disconnect(tmph); + + new Ajax.Autocompleter('tags_str', 'tags_choices', + "backend.php?op=article&method=completeTags", + {tokens: ',', paramName: "search"}); + }); + + dialog.show(); + }, + cdmScrollToArticleId: function(id, force) { + const ctr = $("headlines-frame"); + const e = $("RROW-" + id); + + if (!e || !ctr) return; + + if (force || e.offsetTop + e.offsetHeight > (ctr.scrollTop + ctr.offsetHeight) || + e.offsetTop < ctr.scrollTop) { + + // expanded cdm has a 4px margin now + ctr.scrollTop = parseInt(e.offsetTop) - 4; + + Element.hide("floatingTitle"); + } + }, + setActiveArticleId: function(id) { + console.log("setActiveArticleId", id); + + $$("div[id*=RROW][class*=active]").each((e) => { + e.removeClassName("active"); + + if (!e.hasClassName("Selected")) { + const cb = dijit.getEnclosingWidget(e.select(".rchk")[0]); + if (cb) cb.attr("checked", false); + } + }); + + this._active_article_id = id; + + const row = $("RROW-" + id); + + if (row) { + if (row.hasAttribute("data-content")) { + console.log("unpacking: " + row.id); + + row.select(".content-inner")[0].innerHTML = row.getAttribute("data-content"); + row.removeAttribute("data-content"); + + PluginHost.run(PluginHost.HOOK_ARTICLE_RENDERED_CDM, row); + } + + if (row.hasClassName("Unread")) { + + Headlines.catchupBatchedArticles(() => { + Feeds.decrementFeedCounter(Feeds.getActiveFeedId(), Feeds.activeFeedIsCat()); + Headlines.toggleUnread(id, 0); + Headlines.updateFloatingTitle(true); + }); + + } + + row.addClassName("active"); + + if (!row.hasClassName("Selected")) { + const cb = dijit.getEnclosingWidget(row.select(".rchk")[0]); + if (cb) cb.attr("checked", true); + } + + PluginHost.run(PluginHost.HOOK_ARTICLE_SET_ACTIVE, this._active_article_id); + } + + Headlines.updateSelectedPrompt(); + }, + getActiveArticleId: function() { + return this._active_article_id; } }; const Headlines = { + vgroup_last_feed: undefined, _headlines_scroll_timeout: 0, + loaded_article_ids: [], + current_first_id: 0, + catchup_id_batch: [], click: function(event, id, in_body) { in_body = in_body || false; if (App.isCombinedMode()) { - if (!in_body && (event.ctrlKey || id == getActiveArticleId() || getInitParam("cdm_expanded"))) { + if (!in_body && (event.ctrlKey || id == Article.getActiveArticleId() || getInitParam("cdm_expanded"))) { Article.openArticleInNewWindow(id); } - setActiveArticleId(id); + Article.setActiveArticleId(id); if (!getInitParam("cdm_expanded")) - cdmScrollToArticleId(id); + Article.cdmScrollToArticleId(id); return in_body; } else { if (event.ctrlKey) { Article.openArticleInNewWindow(id); - setActiveArticleId(id); + Article.setActiveArticleId(id); } else { Article.view(id); } @@ -293,9 +403,9 @@ const Headlines = { if ($("headlines-frame").scrollTop <= row.offsetTop && row.offsetTop - $("headlines-frame").scrollTop < 100 && - row.getAttribute("data-article-id") != getActiveArticleId()) { + row.getAttribute("data-article-id") != Article.getActiveArticleId()) { - setActiveArticleId(row.getAttribute("data-article-id")); + Article.setActiveArticleId(row.getAttribute("data-article-id")); break; } } @@ -326,8 +436,8 @@ const Headlines = { if ($("headlines-frame").scrollTop > (row.offsetTop + row.offsetHeight / 2)) { const id = row.getAttribute("data-article-id") - if (catchup_id_batch.indexOf(id) == -1) - catchup_id_batch.push(id); + if (this.catchup_id_batch.indexOf(id) == -1) + this.catchup_id_batch.push(id); } else { break; @@ -373,7 +483,7 @@ const Headlines = { ft.setAttribute("data-article-id", id); ft.innerHTML = header.innerHTML; ft.firstChild.innerHTML = "" + ft.firstChild.innerHTML; + "onclick=\"Article.cdmScrollToArticleId(" + id + ", true)\">" + ft.firstChild.innerHTML; initFloatingMenu(); @@ -462,11 +572,11 @@ const Headlines = { console.log('received', headlines_count, 'headlines, infscroll disabled=', Feeds.infscroll_disabled); - vgroup_last_feed = reply['headlines-info']['vgroup_last_feed']; - current_first_id = reply['headlines']['first_id']; + this.vgroup_last_feed = reply['headlines-info']['vgroup_last_feed']; + this.current_first_id = reply['headlines']['first_id']; if (offset == 0) { - loaded_article_ids = []; + this.loaded_article_ids = []; dojo.html.set($("headlines-toolbar"), reply['headlines']['toolbar'], @@ -481,10 +591,10 @@ const Headlines = { while (tmp.hasChildNodes()) { const row = tmp.removeChild(tmp.firstChild); - if (loaded_article_ids.indexOf(row.id) == -1 || row.hasClassName("feed-title")) { + if (this.loaded_article_ids.indexOf(row.id) == -1 || row.hasClassName("feed-title")) { dijit.byId("headlines-frame").domNode.appendChild(row); - loaded_article_ids.push(row.id); + this.loaded_article_ids.push(row.id); } } @@ -506,7 +616,7 @@ const Headlines = { } else if (headlines_count > 0 && feed_id == Feeds.getActiveFeedId() && is_cat == Feeds.activeFeedIsCat()) { const c = dijit.byId("headlines-frame"); - //const ids = getSelectedArticleIds2(); + //const ids = Headlines.getSelectedArticleIds2(); let hsp = $("headlines-spacer"); @@ -520,10 +630,10 @@ const Headlines = { while (tmp.hasChildNodes()) { let row = tmp.removeChild(tmp.firstChild); - if (loaded_article_ids.indexOf(row.id) == -1 || row.hasClassName("feed-title")) { + if (this.loaded_article_ids.indexOf(row.id) == -1 || row.hasClassName("feed-title")) { dijit.byId("headlines-frame").domNode.appendChild(row); - loaded_article_ids.push(row.id); + this.loaded_article_ids.push(row.id); } } @@ -601,238 +711,247 @@ const Headlines = { Feeds.viewCurrentFeed(); }, -}; + selectionToggleUnread: function(params) { + params = params || {}; -function toggleMark(id, client_only) { - const query = { op: "rpc", id: id, method: "mark" }; - const row = $("RROW-" + id); + const cmode = params.cmode || 2; + const callback = params.callback; + const no_error = params.no_error || false; + const ids = params.ids || Headlines.getSelectedArticleIds2(); - if (row) { - const imgs = $$("img[class*=marked-pic][class*=marked-" + id + "]"); + if (ids.length == 0) { + if (!no_error) + alert(__("No articles are selected.")); - imgs.each((img) => { - if (!row.hasClassName("marked")) { - img.src = img.src.replace("mark_unset", "mark_set"); - query.mark = 1; - } else { - img.src = img.src.replace("mark_set", "mark_unset"); - query.mark = 0; + return; + } + + ids.each((id) => { + const row = $("RROW-" + id); + + if (row) { + switch (cmode) { + case 0: + row.removeClassName("Unread"); + break; + case 1: + row.addClassName("Unread"); + break; + case 2: + row.toggleClassName("Unread"); + } } }); - row.toggleClassName("marked"); + const query = { + op: "rpc", method: "catchupSelected", + cmode: cmode, ids: ids.toString() + }; - if (!client_only) - xhrPost("backend.php", query, (transport) => { - Utils.handleRpcJson(transport); - }); - } -} + notify_progress("Loading, please wait..."); -function togglePub(id, client_only) { - const row = $("RROW-" + id); + xhrPost("backend.php", query, (transport) => { + Utils.handleRpcJson(transport); + if (callback) callback(transport); + }); + }, + selectionToggleMarked: function(ids) { + const rows = ids || Headlines.getSelectedArticleIds2(); + + if (rows.length == 0) { + alert(__("No articles are selected.")); + return; + } - if (row) { - const query = { op: "rpc", id: id, method: "publ" }; + for (let i = 0; i < rows.length; i++) { + this.toggleMark(rows[i], true, true); + } - const imgs = $$("img[class*=pub-pic][class*=pub-" + id + "]"); + const query = { + op: "rpc", method: "markSelected", + ids: rows.toString(), cmode: 2 + }; - imgs.each((img) => { - if (!row.hasClassName("published")) { - img.src = img.src.replace("pub_unset", "pub_set"); - query.pub = 1; - } else { - img.src = img.src.replace("pub_set", "pub_unset"); - query.pub = 0; - } + xhrPost("backend.php", query, (transport) => { + Utils.handleRpcJson(transport); }); + }, + selectionTogglePublished: function(ids) { + const rows = ids || Headlines.getSelectedArticleIds2(); - row.toggleClassName("published"); + if (rows.length == 0) { + alert(__("No articles are selected.")); + return; + } + + for (let i = 0; i < rows.length; i++) { + this.togglePub(rows[i], true); + } + + if (rows.length > 0) { + const query = { + op: "rpc", method: "publishSelected", + ids: rows.toString(), cmode: 2 + }; - if (!client_only) xhrPost("backend.php", query, (transport) => { Utils.handleRpcJson(transport); }); + } + }, + toggleMark: function(id, client_only) { + const query = {op: "rpc", id: id, method: "mark"}; + const row = $("RROW-" + id); - } -} + if (row) { + const imgs = $$("img[class*=marked-pic][class*=marked-" + id + "]"); -function moveToPost(mode, noscroll, noexpand) { - const rows = getLoadedArticleIds(); + imgs.each((img) => { + if (!row.hasClassName("marked")) { + img.src = img.src.replace("mark_unset", "mark_set"); + query.mark = 1; + } else { + img.src = img.src.replace("mark_set", "mark_unset"); + query.mark = 0; + } + }); - let prev_id = false; - let next_id = false; + row.toggleClassName("marked"); - if (!$('RROW-' + getActiveArticleId())) { - setActiveArticleId(0); - } + if (!client_only) + xhrPost("backend.php", query, (transport) => { + Utils.handleRpcJson(transport); + }); + } + }, + togglePub: function(id, client_only) { + const row = $("RROW-" + id); - if (!getActiveArticleId()) { - next_id = rows[0]; - prev_id = rows[rows.length-1] - } else { - for (let i = 0; i < rows.length; i++) { - if (rows[i] == getActiveArticleId()) { + if (row) { + const query = {op: "rpc", id: id, method: "publ"}; - // Account for adjacent identical article ids. - if (i > 0) prev_id = rows[i-1]; + const imgs = $$("img[class*=pub-pic][class*=pub-" + id + "]"); - for (let j = i+1; j < rows.length; j++) { - if (rows[j] != getActiveArticleId()) { - next_id = rows[j]; - break; - } + imgs.each((img) => { + if (!row.hasClassName("published")) { + img.src = img.src.replace("pub_unset", "pub_set"); + query.pub = 1; + } else { + img.src = img.src.replace("pub_set", "pub_unset"); + query.pub = 0; } - break; - } - } - } - - console.log("cur: " + getActiveArticleId() + " next: " + next_id); - - if (mode == "next") { - if (next_id || getActiveArticleId()) { - if (App.isCombinedMode()) { + }); - const article = $("RROW-" + getActiveArticleId()); - const ctr = $("headlines-frame"); + row.toggleClassName("published"); - if (!noscroll && article && article.offsetTop + article.offsetHeight > - ctr.scrollTop + ctr.offsetHeight) { + if (!client_only) + xhrPost("backend.php", query, (transport) => { + Utils.handleRpcJson(transport); + }); - scrollArticle(ctr.offsetHeight/4); + } + }, + moveToPost: function(mode, noscroll, noexpand) { + const rows = Headlines.getLoadedArticleIds(); - } else if (next_id) { - setActiveArticleId(next_id); - cdmScrollToArticleId(next_id, true); - } + let prev_id = false; + let next_id = false; - } else if (next_id) { - correctHeadlinesOffset(next_id); - Article.view(next_id, noexpand); - } + if (!$('RROW-' + Article.getActiveArticleId())) { + Article.setActiveArticleId(0); } - } - if (mode == "prev") { - if (prev_id || getActiveArticleId()) { - if (App.isCombinedMode()) { + if (!Article.getActiveArticleId()) { + next_id = rows[0]; + prev_id = rows[rows.length - 1] + } else { + for (let i = 0; i < rows.length; i++) { + if (rows[i] == Article.getActiveArticleId()) { - const article = $("RROW-" + getActiveArticleId()); - const prev_article = $("RROW-" + prev_id); - const ctr = $("headlines-frame"); + // Account for adjacent identical article ids. + if (i > 0) prev_id = rows[i - 1]; - if (!noscroll && article && article.offsetTop < ctr.scrollTop) { - scrollArticle(-ctr.offsetHeight/3); - } else if (!noscroll && prev_article && - prev_article.offsetTop < ctr.scrollTop) { - scrollArticle(-ctr.offsetHeight/4); - } else if (prev_id) { - setActiveArticleId(prev_id); - cdmScrollToArticleId(prev_id, noscroll); + for (let j = i + 1; j < rows.length; j++) { + if (rows[j] != Article.getActiveArticleId()) { + next_id = rows[j]; + break; + } + } + break; } - - } else if (prev_id) { - correctHeadlinesOffset(prev_id); - Article.view(prev_id, noexpand); } } - } -} -function updateSelectedPrompt() { - const count = getSelectedArticleIds2().length; - const elem = $("selected_prompt"); + console.log("cur: " + Article.getActiveArticleId() + " next: " + next_id); - if (elem) { - elem.innerHTML = ngettext("%d article selected", - "%d articles selected", count).replace("%d", count); + if (mode == "next") { + if (next_id || Article.getActiveArticleId()) { + if (App.isCombinedMode()) { - count > 0 ? Element.show(elem) : Element.hide(elem); - } -} + const article = $("RROW-" + Article.getActiveArticleId()); + const ctr = $("headlines-frame"); -function toggleUnread(id, cmode) { - const row = $("RROW-" + id); + if (!noscroll && article && article.offsetTop + article.offsetHeight > + ctr.scrollTop + ctr.offsetHeight) { - if (row) { - const origClassName = row.className; + scrollArticle(ctr.offsetHeight / 4); - if (cmode == undefined) cmode = 2; + } else if (next_id) { + Article.setActiveArticleId(next_id); + Article.cdmScrollToArticleId(next_id, true); + } - switch (cmode) { - case 0: - row.removeClassName("Unread"); - break; - case 1: - row.addClassName("Unread"); - break; - case 2: - row.toggleClassName("Unread"); - break; + } else if (next_id) { + correctHeadlinesOffset(next_id); + Article.view(next_id, noexpand); + } + } } - if (row.className != origClassName) - xhrPost("backend.php", - {op: "rpc", method: "catchupSelected", cmode: cmode, ids: id},(transport) => { - Utils.handleRpcJson(transport); - }); - } -} - -function selectionRemoveLabel(id, ids) { - if (!ids) ids = getSelectedArticleIds2(); - - if (ids.length == 0) { - alert(__("No articles are selected.")); - return; - } - - const query = { op: "article", method: "removeFromLabel", - ids: ids.toString(), lid: id }; - - xhrPost("backend.php", query, (transport) => { - Utils.handleRpcJson(transport); - updateHeadlineLabels(transport); - }); -} - -function selectionAssignLabel(id, ids) { - if (!ids) ids = getSelectedArticleIds2(); - - if (ids.length == 0) { - alert(__("No articles are selected.")); - return; - } + if (mode == "prev") { + if (prev_id || Article.getActiveArticleId()) { + if (App.isCombinedMode()) { - const query = { op: "article", method: "assignToLabel", - ids: ids.toString(), lid: id }; + const article = $("RROW-" + Article.getActiveArticleId()); + const prev_article = $("RROW-" + prev_id); + const ctr = $("headlines-frame"); - xhrPost("backend.php", query, (transport) => { - Utils.handleRpcJson(transport); - updateHeadlineLabels(transport); - }); -} - -function selectionToggleUnread(params) { - params = params || {}; - - const cmode = params.cmode || 2; - const callback = params.callback; - const no_error = params.no_error || false; - const ids = params.ids || getSelectedArticleIds2(); + if (!noscroll && article && article.offsetTop < ctr.scrollTop) { + scrollArticle(-ctr.offsetHeight / 3); + } else if (!noscroll && prev_article && + prev_article.offsetTop < ctr.scrollTop) { + scrollArticle(-ctr.offsetHeight / 4); + } else if (prev_id) { + Article.setActiveArticleId(prev_id); + Article.cdmScrollToArticleId(prev_id, noscroll); + } - if (ids.length == 0) { - if (!no_error) - alert(__("No articles are selected.")); + } else if (prev_id) { + correctHeadlinesOffset(prev_id); + Article.view(prev_id, noexpand); + } + } + } + }, + updateSelectedPrompt: function() { + const count = Headlines.getSelectedArticleIds2().length; + const elem = $("selected_prompt"); - return; - } + if (elem) { + elem.innerHTML = ngettext("%d article selected", + "%d articles selected", count).replace("%d", count); - ids.each((id) => { + count > 0 ? Element.show(elem) : Element.hide(elem); + } + }, + toggleUnread: function(id, cmode) { const row = $("RROW-" + id); if (row) { + const origClassName = row.className; + + if (cmode == undefined) cmode = 2; + switch (cmode) { case 0: row.removeClassName("Unread"); @@ -842,368 +961,259 @@ function selectionToggleUnread(params) { break; case 2: row.toggleClassName("Unread"); + break; } - } - }); - - const query = {op: "rpc", method: "catchupSelected", - cmode: cmode, ids: ids.toString() }; - notify_progress("Loading, please wait..."); - - xhrPost("backend.php", query, (transport) => { - Utils.handleRpcJson(transport); - if (callback) callback(transport); - }); -} - -function selectionToggleMarked(ids) { - const rows = ids || getSelectedArticleIds2(); - - if (rows.length == 0) { - alert(__("No articles are selected.")); - return; - } - - for (let i = 0; i < rows.length; i++) { - toggleMark(rows[i], true, true); - } - - const query = { op: "rpc", method: "markSelected", - ids: rows.toString(), cmode: 2 }; + if (row.className != origClassName) + xhrPost("backend.php", + {op: "rpc", method: "catchupSelected", cmode: cmode, ids: id}, (transport) => { + Utils.handleRpcJson(transport); + }); + } + }, + selectionRemoveLabel: function(id, ids) { + if (!ids) ids = Headlines.getSelectedArticleIds2(); - xhrPost("backend.php", query, (transport) => { - Utils.handleRpcJson(transport); - }); -} + if (ids.length == 0) { + alert(__("No articles are selected.")); + return; + } -// sel_state ignored -function selectionTogglePublished(ids) { - const rows = ids || getSelectedArticleIds2(); + const query = { + op: "article", method: "removeFromLabel", + ids: ids.toString(), lid: id + }; - if (rows.length == 0) { - alert(__("No articles are selected.")); - return; - } + xhrPost("backend.php", query, (transport) => { + Utils.handleRpcJson(transport); + updateHeadlineLabels(transport); + }); + }, + selectionAssignLabel: function(id, ids) { + if (!ids) ids = Headlines.getSelectedArticleIds2(); - for (let i = 0; i < rows.length; i++) { - togglePub(rows[i], true); - } + if (ids.length == 0) { + alert(__("No articles are selected.")); + return; + } - if (rows.length > 0) { - const query = { op: "rpc", method: "publishSelected", - ids: rows.toString(), cmode: 2 }; + const query = { + op: "article", method: "assignToLabel", + ids: ids.toString(), lid: id + }; xhrPost("backend.php", query, (transport) => { Utils.handleRpcJson(transport); + updateHeadlineLabels(transport); }); - } -} + }, + deleteSelection: function() { + const rows = Headlines.getSelectedArticleIds2(); -function getSelectedArticleIds2() { + if (rows.length == 0) { + alert(__("No articles are selected.")); + return; + } - const rv = []; + const fn = Feeds.getFeedName(Feeds.getActiveFeedId(), Feeds.activeFeedIsCat()); + let str; - $$("#headlines-frame > div[id*=RROW][class*=Selected]").each( - function(child) { - rv.push(child.getAttribute("data-article-id")); - }); + if (Feeds.getActiveFeedId() != 0) { + str = ngettext("Delete %d selected article in %s?", "Delete %d selected articles in %s?", rows.length); + } else { + str = ngettext("Delete %d selected article?", "Delete %d selected articles?", rows.length); + } - // consider active article a honorary member of selected articles - if (getActiveArticleId()) - rv.push(getActiveArticleId()); + str = str.replace("%d", rows.length); + str = str.replace("%s", fn); - return rv.uniq(); -} + if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) { + return; + } -function getLoadedArticleIds() { - const rv = []; + const query = {op: "rpc", method: "delete", ids: rows.toString()}; - const children = $$("#headlines-frame > div[id*=RROW-]"); + xhrPost("backend.php", query, (transport) => { + Utils.handleRpcJson(transport); + Feeds.viewCurrentFeed(); + }); + }, + getSelectedArticleIds2: function() { + const rv = []; - children.each(function(child) { - if (Element.visible(child)) { - rv.push(child.getAttribute("data-article-id")); - } - }); + $$("#headlines-frame > div[id*=RROW][class*=Selected]").each( + function (child) { + rv.push(child.getAttribute("data-article-id")); + }); - return rv; -} + // consider active article a honorary member of selected articles + if (Article.getActiveArticleId()) + rv.push(Article.getActiveArticleId()); -// mode = all,none,unread,invert,marked,published -function selectArticles(mode) { - let query = "#headlines-frame > div[id*=RROW]"; + return rv.uniq(); + }, + getLoadedArticleIds: function() { + const rv = []; - switch (mode) { - case "none": - case "all": - case "invert": - break; - case "marked": - query += "[class*=marked]"; - break; - case "published": - query += "[class*=published]"; - break; - case "unread": - query += "[class*=Unread]"; - break; - default: - console.warn("selectArticles: unknown mode", mode); - } + const children = $$("#headlines-frame > div[id*=RROW-]"); - const rows = $$(query); + children.each(function (child) { + if (Element.visible(child)) { + rv.push(child.getAttribute("data-article-id")); + } + }); - for (let i = 0; i < rows.length; i++) { - const row = rows[i]; - const cb = dijit.getEnclosingWidget(row.select(".rchk")[0]); + return rv; + }, + selectArticles: function(mode) { + // mode = all,none,unread,invert,marked,published + let query = "#headlines-frame > div[id*=RROW]"; switch (mode) { case "none": - row.removeClassName("Selected"); - - if (!row.hasClassName("active")) - cb.attr("checked", false); - break; + case "all": case "invert": - if (row.hasClassName("Selected")) { - row.removeClassName("Selected"); - - if (!row.hasClassName("active")) - cb.attr("checked", false); - } else { - row.addClassName("Selected"); - cb.attr("checked", true); - } + break; + case "marked": + query += "[class*=marked]"; + break; + case "published": + query += "[class*=published]"; + break; + case "unread": + query += "[class*=Unread]"; break; default: - row.addClassName("Selected"); - cb.attr("checked", true); + console.warn("selectArticles: unknown mode", mode); } - updateSelectedPrompt(); - } -} - -// noinspection JSUnusedGlobalSymbols -function deleteSelection() { - - const rows = getSelectedArticleIds2(); - - if (rows.length == 0) { - alert(__("No articles are selected.")); - return; - } - - const fn = Feeds.getFeedName(Feeds.getActiveFeedId(), Feeds.activeFeedIsCat()); - let str; - - if (Feeds.getActiveFeedId() != 0) { - str = ngettext("Delete %d selected article in %s?", "Delete %d selected articles in %s?", rows.length); - } else { - str = ngettext("Delete %d selected article?", "Delete %d selected articles?", rows.length); - } - - str = str.replace("%d", rows.length); - str = str.replace("%s", fn); - - if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) { - return; - } - - const query = { op: "rpc", method: "delete", ids: rows.toString() }; - - xhrPost("backend.php", query, (transport) => { - Utils.handleRpcJson(transport); - Feeds.viewCurrentFeed(); - }); -} - -// noinspection JSUnusedGlobalSymbols -function archiveSelection() { - - const rows = getSelectedArticleIds2(); - - if (rows.length == 0) { - alert(__("No articles are selected.")); - return; - } - - const fn = Feeds.getFeedName(Feeds.getActiveFeedId(), Feeds.activeFeedIsCat()); - let str; - let op; - - if (Feeds.getActiveFeedId() != 0) { - str = ngettext("Archive %d selected article in %s?", "Archive %d selected articles in %s?", rows.length); - op = "archive"; - } else { - str = ngettext("Move %d archived article back?", "Move %d archived articles back?", rows.length); - str += " " + __("Please note that unstarred articles might get purged on next feed update."); - - op = "unarchive"; - } - - str = str.replace("%d", rows.length); - str = str.replace("%s", fn); - - if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) { - return; - } - - for (let i = 0; i < rows.length; i++) { - ArticleCache.del(rows[i]); - } - - const query = {op: "rpc", method: op, ids: rows.toString()}; - - xhrPost("backend.php", query, (transport) => { - Utils.handleRpcJson(transport); - Feeds.viewCurrentFeed(); - }); -} - -function catchupSelection() { - - const rows = getSelectedArticleIds2(); - - if (rows.length == 0) { - alert(__("No articles are selected.")); - return; - } - - const fn = Feeds.getFeedName(Feeds.getActiveFeedId(), Feeds.activeFeedIsCat()); - - let str = ngettext("Mark %d selected article in %s as read?", "Mark %d selected articles in %s as read?", rows.length); - - str = str.replace("%d", rows.length); - str = str.replace("%s", fn); - - if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) { - return; - } - - selectionToggleUnread({callback: viewCurrentFeed, no_error: 1}); -} - -function editArticleTags(id) { - const query = "backend.php?op=article&method=editArticleTags¶m=" + param_escape(id); - - if (dijit.byId("editTagsDlg")) - dijit.byId("editTagsDlg").destroyRecursive(); - - const dialog = new dijit.Dialog({ - id: "editTagsDlg", - title: __("Edit article Tags"), - style: "width: 600px", - execute: function() { - if (this.validate()) { - notify_progress("Saving article tags...", true); + const rows = $$(query); - xhrPost("backend.php", this.attr('value'), (transport) => { - try { - notify(''); - dialog.hide(); - - const data = JSON.parse(transport.responseText); + for (let i = 0; i < rows.length; i++) { + const row = rows[i]; + const cb = dijit.getEnclosingWidget(row.select(".rchk")[0]); - if (data) { - const id = data.id; + switch (mode) { + case "none": + row.removeClassName("Selected"); - const tags = $("ATSTR-" + id); - const tooltip = dijit.byId("ATSTRTIP-" + id); + if (!row.hasClassName("active")) + cb.attr("checked", false); + break; + case "invert": + if (row.hasClassName("Selected")) { + row.removeClassName("Selected"); - if (tags) tags.innerHTML = data.content; - if (tooltip) tooltip.attr('label', data.content_full); - } - } catch (e) { - exception_error(e); + if (!row.hasClassName("active")) + cb.attr("checked", false); + } else { + row.addClassName("Selected"); + cb.attr("checked", true); } - }); + break; + default: + row.addClassName("Selected"); + cb.attr("checked", true); } - }, - href: query - }); - - const tmph = dojo.connect(dialog, 'onLoad', function() { - dojo.disconnect(tmph); - new Ajax.Autocompleter('tags_str', 'tags_choices', - "backend.php?op=article&method=completeTags", - { tokens: ',', paramName: "search" }); - }); + Headlines.updateSelectedPrompt(); + } + }, + archiveSelection: function() { + const rows = Headlines.getSelectedArticleIds2(); - dialog.show(); + if (rows.length == 0) { + alert(__("No articles are selected.")); + return; + } -} + const fn = Feeds.getFeedName(Feeds.getActiveFeedId(), Feeds.activeFeedIsCat()); + let str; + let op; -function cdmScrollToArticleId(id, force) { - const ctr = $("headlines-frame"); - const e = $("RROW-" + id); + if (Feeds.getActiveFeedId() != 0) { + str = ngettext("Archive %d selected article in %s?", "Archive %d selected articles in %s?", rows.length); + op = "archive"; + } else { + str = ngettext("Move %d archived article back?", "Move %d archived articles back?", rows.length); + str += " " + __("Please note that unstarred articles might get purged on next feed update."); - if (!e || !ctr) return; + op = "unarchive"; + } - if (force || e.offsetTop+e.offsetHeight > (ctr.scrollTop+ctr.offsetHeight) || - e.offsetTop < ctr.scrollTop) { + str = str.replace("%d", rows.length); + str = str.replace("%s", fn); - // expanded cdm has a 4px margin now - ctr.scrollTop = parseInt(e.offsetTop) - 4; + if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) { + return; + } - Element.hide("floatingTitle"); - } -} + for (let i = 0; i < rows.length; i++) { + ArticleCache.del(rows[i]); + } -function setActiveArticleId(id) { - console.log("setActiveArticleId", id); + const query = {op: "rpc", method: op, ids: rows.toString()}; - $$("div[id*=RROW][class*=active]").each((e) => { - e.removeClassName("active"); + xhrPost("backend.php", query, (transport) => { + Utils.handleRpcJson(transport); + Feeds.viewCurrentFeed(); + }); + }, + catchupSelection: function() { + const rows = Headlines.getSelectedArticleIds2(); - if (!e.hasClassName("Selected")) { - const cb = dijit.getEnclosingWidget(e.select(".rchk")[0]); - if (cb) cb.attr("checked", false); + if (rows.length == 0) { + alert(__("No articles are selected.")); + return; } - }); - - _active_article_id = id; - const row = $("RROW-" + id); + const fn = Feeds.getFeedName(Feeds.getActiveFeedId(), Feeds.activeFeedIsCat()); - if (row) { - if (row.hasAttribute("data-content")) { - console.log("unpacking: " + row.id); + let str = ngettext("Mark %d selected article in %s as read?", "Mark %d selected articles in %s as read?", rows.length); - row.select(".content-inner")[0].innerHTML = row.getAttribute("data-content"); - row.removeAttribute("data-content"); + str = str.replace("%d", rows.length); + str = str.replace("%s", fn); - PluginHost.run(PluginHost.HOOK_ARTICLE_RENDERED_CDM, row); + if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) { + return; } - if (row.hasClassName("Unread")) { + Headlines.selectionToggleUnread({callback: Feeds.viewCurrentFeed, no_error: 1}); + }, + catchupBatchedArticles: function(callback) { + console.log("catchupBatchedArticles, size=", this.catchup_id_batch.length); - catchupBatchedArticles(() => { - Feeds.decrementFeedCounter(Feeds.getActiveFeedId(), Feeds.activeFeedIsCat()); - toggleUnread(id, 0); - Headlines.updateFloatingTitle(true); - }); + if (this.catchup_id_batch.length > 0) { - } + // make a copy of the array + const batch = this.catchup_id_batch.slice(); + const query = { + op: "rpc", method: "catchupSelected", + cmode: 0, ids: batch.toString() + }; - row.addClassName("active"); + xhrPost("backend.php", query, (transport) => { + const reply = Utils.handleRpcJson(transport); - if (!row.hasClassName("Selected")) { - const cb = dijit.getEnclosingWidget(row.select(".rchk")[0]); - if (cb) cb.attr("checked", true); - } + if (reply) { + const batch = reply.ids; - PluginHost.run(PluginHost.HOOK_ARTICLE_SET_ACTIVE, _active_article_id); - } + batch.each(function (id) { + const elem = $("RROW-" + id); + if (elem) elem.removeClassName("Unread"); + Headlines.catchup_id_batch.remove(id); + }); + } - updateSelectedPrompt(); -} + Headlines.updateFloatingTitle(true); -function getActiveArticleId() { - return _active_article_id; -} + if (callback) callback(); + }); + } else { + if (callback) callback(); + } + } +}; function postMouseIn(e, id) { post_under_pointer = id; @@ -1213,48 +1223,16 @@ function postMouseOut(id) { post_under_pointer = false; } -function catchupBatchedArticles(callback) { - console.log("catchupBatchedArticles, size=", catchup_id_batch.length); - - if (catchup_id_batch.length > 0) { - - // make a copy of the array - const batch = catchup_id_batch.slice(); - const query = { op: "rpc", method: "catchupSelected", - cmode: 0, ids: batch.toString() }; - - xhrPost("backend.php", query, (transport) => { - const reply = Utils.handleRpcJson(transport); - - if (reply) { - const batch = reply.ids; - - batch.each(function (id) { - const elem = $("RROW-" + id); - if (elem) elem.removeClassName("Unread"); - catchup_id_batch.remove(id); - }); - } - - Headlines.updateFloatingTitle(true); - - if (callback) callback(); - }); - } else { - if (callback) callback(); - } -} - function catchupRelativeToArticle(below, id) { - if (!id) id = getActiveArticleId(); + if (!id) id = Article.getActiveArticleId(); if (!id) { alert(__("No article is selected.")); return; } - const visible_ids = getLoadedArticleIds(); + const visible_ids = Headlines.getLoadedArticleIds(); const ids_to_mark = []; @@ -1343,7 +1321,7 @@ function getRelativePostIds(id, limit) { if (!limit) limit = 6; //3 - const ids = getLoadedArticleIds(); + const ids = Headlines.getLoadedArticleIds(); for (let i = 0; i < ids.length; i++) { if (ids[i] == id) { @@ -1379,7 +1357,6 @@ function correctHeadlinesOffset(id) { } } -// noinspection JSUnusedGlobalSymbols function headlineActionsChange(elem) { eval(elem.value); elem.attr('value', 'false'); @@ -1421,36 +1398,36 @@ function headlinesMenuCommon(menu) { label: __("Toggle unread"), onClick: function () { - let ids = getSelectedArticleIds2(); + let ids = Headlines.getSelectedArticleIds2(); // cast to string const id = (this.getParent().currentTarget.getAttribute("data-article-id")) + ""; ids = ids.length != 0 && ids.indexOf(id) != -1 ? ids : [id]; - selectionToggleUnread({ids: ids, no_error: 1}); + Headlines.selectionToggleUnread({ids: ids, no_error: 1}); } })); menu.addChild(new dijit.MenuItem({ label: __("Toggle starred"), onClick: function () { - let ids = getSelectedArticleIds2(); + let ids = Headlines.getSelectedArticleIds2(); // cast to string const id = (this.getParent().currentTarget.getAttribute("data-article-id")) + ""; ids = ids.length != 0 && ids.indexOf(id) != -1 ? ids : [id]; - selectionToggleMarked(ids); + Headlines.selectionToggleMarked(ids); } })); menu.addChild(new dijit.MenuItem({ label: __("Toggle published"), onClick: function () { - let ids = getSelectedArticleIds2(); + let ids = Headlines.getSelectedArticleIds2(); // cast to string const id = (this.getParent().currentTarget.getAttribute("data-article-id")) + ""; ids = ids.length != 0 && ids.indexOf(id) != -1 ? ids : [id]; - selectionTogglePublished(ids); + Headlines.selectionTogglePublished(ids); } })); @@ -1489,13 +1466,13 @@ function headlinesMenuCommon(menu) { labelId: bare_id, onClick: function () { - let ids = getSelectedArticleIds2(); + let ids = Headlines.getSelectedArticleIds2(); // cast to string const id = (this.getParent().ownerMenu.currentTarget.getAttribute("data-article-id")) + ""; ids = ids.length != 0 && ids.indexOf(id) != -1 ? ids : [id]; - selectionAssignLabel(this.labelId, ids); + Headlines.selectionAssignLabel(this.labelId, ids); } })); @@ -1503,13 +1480,13 @@ function headlinesMenuCommon(menu) { label: name, labelId: bare_id, onClick: function () { - let ids = getSelectedArticleIds2(); + let ids = Headlines.getSelectedArticleIds2(); // cast to string const id = (this.getParent().ownerMenu.currentTarget.getAttribute("data-article-id")) + ""; ids = ids.length != 0 && ids.indexOf(id) != -1 ? ids : [id]; - selectionRemoveLabel(this.labelId, ids); + Headlines.selectionRemoveLabel(this.labelId, ids); } })); @@ -1555,7 +1532,7 @@ function initHeadlinesMenu() { menu.addChild(new dijit.MenuItem({ label: __("Select articles in group"), onClick: function (event) { - selectArticles("all", + Headlines.selectArticles("all", "#headlines-frame > div[id*=RROW]" + "[data-orig-feed-id='" + this.getParent().currentTarget.getAttribute("data-feed-id") + "']"); @@ -1565,12 +1542,12 @@ function initHeadlinesMenu() { menu.addChild(new dijit.MenuItem({ label: __("Mark group as read"), onClick: function () { - selectArticles("none"); - selectArticles("all", + Headlines.selectArticles("none"); + Headlines.selectArticles("all", "#headlines-frame > div[id*=RROW]" + "[data-orig-feed-id='" + this.getParent().currentTarget.getAttribute("data-feed-id") + "']"); - catchupSelection(); + Headlines.catchupSelection(); } })); diff --git a/plugins/embed_original/init.js b/plugins/embed_original/init.js index d0731d5d1..95a5ef9e5 100644 --- a/plugins/embed_original/init.js +++ b/plugins/embed_original/init.js @@ -11,7 +11,7 @@ function embedOriginalArticle(id) { if (App.isCombinedMode()) { c = $$("div#RROW-" + id + " div[class=content-inner]")[0]; - } else if (id == getActiveArticleId()) { + } else if (id == Article.getActiveArticleId()) { c = $$(".post .content")[0]; } @@ -23,7 +23,7 @@ function embedOriginalArticle(id) { c.parentNode.removeChild(iframe); if (App.isCombinedMode()) { - cdmScrollToArticleId(id, true); + Article.cdmScrollToArticleId(id, true); } return; @@ -48,7 +48,7 @@ function embedOriginalArticle(id) { c.parentNode.insertBefore(iframe, c); if (App.isCombinedMode()) { - cdmScrollToArticleId(id, true); + Article.cdmScrollToArticleId(id, true); } } } diff --git a/plugins/mail/mail.js b/plugins/mail/mail.js index 929b35243..1dc383b00 100644 --- a/plugins/mail/mail.js +++ b/plugins/mail/mail.js @@ -1,7 +1,7 @@ function emailArticle(id) { try { if (!id) { - var ids = getSelectedArticleIds2(); + var ids = Headlines.getSelectedArticleIds2(); if (ids.length == 0) { alert(__("No articles are selected.")); diff --git a/plugins/mailto/init.js b/plugins/mailto/init.js index 272b8cea7..a3be90e95 100644 --- a/plugins/mailto/init.js +++ b/plugins/mailto/init.js @@ -1,7 +1,7 @@ function mailtoArticle(id) { try { if (!id) { - const ids = getSelectedArticleIds2(); + const ids = Headlines.getSelectedArticleIds2(); if (ids.length == 0) { alert(__("No articles are selected.")); diff --git a/plugins/mark_button/init.php b/plugins/mark_button/init.php index 2b8fa9242..8f05d1ada 100644 --- a/plugins/mark_button/init.php +++ b/plugins/mark_button/init.php @@ -23,12 +23,12 @@ class Mark_Button extends Plugin { $marked_pic = "\"Unstar"; + onclick='Headlines.toggleMark($id)'>"; } else { $marked_pic = "\"Star"; + onclick='Headlines.toggleMark($id)'>"; } } -- cgit v1.2.3-54-g00ecf From ab0fadf60d2576564b6fe6e2dd15699c1516de9f Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Sat, 1 Dec 2018 21:08:15 +0300 Subject: fix vfeed group title CSS in not combined mode --- classes/feeds.php | 2 +- css/default.css | 2 +- css/tt-rss.less | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) (limited to 'classes') diff --git a/classes/feeds.php b/classes/feeds.php index 0ab14c9d1..a5f384ed0 100755 --- a/classes/feeds.php +++ b/classes/feeds.php @@ -390,7 +390,7 @@ class Feeds extends Handler_Protected { $vf_catchup_link = "".__('mark feed as read').""; - $reply['content'] .= "
". + $reply['content'] .= "
". "
$feed_icon_img
". "". $line["feed_title"]." diff --git a/css/default.css b/css/default.css index 51c1d379f..23325507f 100644 --- a/css/default.css +++ b/css/default.css @@ -1 +1 @@ -body.ttrss_main,body.ttrss_prefs,#main{position:absolute;width:100%;height:100%;border:0;padding:0;margin:0}body.ttrss_main{background:#fff;color:#000;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;overflow:hidden}body.ttrss_main :focus{outline:none}body.ttrss_main div.post{padding:0}body.ttrss_main div.post div.header{padding:5px;color:#909090;border:0 solid #ddd;border-bottom-width:1px;background:#f0f0f0}body.ttrss_main div.post div.header div.date{text-align:right;float:right}body.ttrss_main div.post div.header div{padding-bottom:3px}body.ttrss_main div.post div.header span.author{color:#555;font-size:11px;font-weight:normal}body.ttrss_main div.post div.title{overflow:hidden;font-size:15px;text-overflow:ellipsis;white-space:nowrap;font-weight:600;text-rendering:optimizelegibility;font-family:"Segoe WP Semibold","Segoe UI Semibold","Segoe UI Web Semibold","Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}body.ttrss_main div.post div.date{padding-left:10px}body.ttrss_main div.post div.content{padding:10px;font-size:16px}body.ttrss_main div.post div.content img,body.ttrss_main div.post div.content video{border-width:0;max-width:98%;height:auto}body.ttrss_main div.post div.content h1{font-size:16px}body.ttrss_main div.post div.content h2,body.ttrss_main div.post div.content h3,body.ttrss_main div.post div.content h4{font-size:15px}body.ttrss_main div.post div.content p{hyphens:auto}body.ttrss_main div.post div.content iframe{min-width:50%;max-width:98%}body.ttrss_main div.post div.postEnclosures{color:#555}body.ttrss_main div.post img.tagsPic{width:16px;height:16px;margin-left:4px;vertical-align:middle}body.ttrss_main div.post span.author{font-size:12px}body.ttrss_main div.articleNote{background-color:#fff7d5;padding:5px;margin:5px;border:1px solid #e7d796;color:#9a8c59}body.ttrss_main div.articleNote div.noteEdit{float:right;cursor:pointer}body.ttrss_main h1{font-size:18px;font-weight:600;text-rendering:optimizelegibility;font-family:"Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}body.ttrss_main h2{font-size:16px;font-weight:600;border:0 solid #d5ebf6;border-bottom-width:1px;text-rendering:optimizelegibility;font-family:"Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}body.ttrss_main h3{font-size:13px;border:0 solid #d5ebf6;border-bottom-width:1px;font-weight:600;text-rendering:optimizelegibility;font-family:"Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}body.ttrss_main h4{font-size:14px;font-weight:600;text-rendering:optimizelegibility;font-family:"Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}body.ttrss_main hr{border:0 solid #ccc;border-bottom-width:1px}body.ttrss_main a{color:#257aa7;text-decoration:none}body.ttrss_main a:hover{color:#133d54;text-decoration:underline}body.ttrss_main #notify.visible{transform:translate(0, -35px)}body.ttrss_main #notify{bottom:-35px;right:0;height:20px;left:0;border-width:1px 0 0 0;border-style:solid;position:fixed;font-size:12px;z-index:99;padding:5px;box-shadow:0 -2px 2px rgba(0,0,0,0.1);transition:all .5s ease-in-out}body.ttrss_main #notify img{vertical-align:middle;max-height:14px}body.ttrss_main #notify span.msg{width:100%}body.ttrss_main #notify img.close{cursor:pointer}body.ttrss_main #notify span{display:table-cell;vertical-align:middle;padding:2px}body.ttrss_main .notify{border-color:#d7c47a;background-color:#fff7d5}body.ttrss_main .notify.notify_progress{border-color:#d7c47a;background-color:#fff7d5}body.ttrss_main .notify.notify_info{border-color:#257aa7;background-color:#d5ebf6}body.ttrss_main .notify.notify_error{background-color:#fcc;border-color:#f00}body.ttrss_main .hl{border:0 solid #ddd;border-bottom-width:1px;padding:1px;transition:color .2s,background .2s}body.ttrss_main .hl div.title{display:table-cell;cursor:pointer;width:100%;vertical-align:middle;overflow:hidden;white-space:nowrap;max-width:500px;text-overflow:ellipsis;padding:4px 6px}body.ttrss_main .hl div.left{display:table-cell;vertical-align:middle;white-space:nowrap}body.ttrss_main .hl div.right{display:table-cell;white-space:nowrap;text-align:right;vertical-align:middle}body.ttrss_main .hl div.right img{max-width:16px;max-height:16px}body.ttrss_main .hl span.feed{display:table-cell;vertical-align:middle;text-align:right}body.ttrss_main .hl span.feed a{border-radius:4px;display:inline-block;padding:1px 4px 1px 4px;font-size:11px;font-style:italic;font-weight:normal;color:#555;white-space:nowrap}body.ttrss_main .hl span.feed a:hover{color:#257aa7}body.ttrss_main .hl span.updated{color:#555;display:table-cell;vertical-align:middle;text-align:right;font-size:11px;white-space:nowrap;padding-left:10px}body.ttrss_main .hl span.updated div{display:inline-block}body.ttrss_main .hl div.left{padding-left:8px}body.ttrss_main .hl div.left input{margin-left:4px;margin-right:4px}body.ttrss_main .hl div.left img,body.ttrss_main .hl div.right img{margin:0 4px}body.ttrss_main .hl div.left img{width:16px;height:16px}body.ttrss_main .hl div.title a{font-weight:600;text-rendering:optimizelegibility;font-family:"Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif;color:#777}body.ttrss_main .hl a.title.high,body.ttrss_main .hl span.hl-content.high .preview{color:#0a0}body.ttrss_main .hl.Unread a.title.high,body.ttrss_main .hl.Unread span.hl-content.high .preview{color:#0d0}body.ttrss_main .hl a.title.low,body.ttrss_main span.hl-content.low .preview,body.ttrss_main .hl.Unread a.title.low,body.ttrss_main .hl.Unread span.hl-content.low .preview{color:#909090;text-decoration:line-through}body.ttrss_main .hl.Unread div.title a{color:#000}body.ttrss_main .hl.active div.title a{color:#257aa7}body.ttrss_main .hl.active{background:#257aa7 ! important}body.ttrss_main .hl.active,body.ttrss_main .hl.Selected{color:#fff;background:#3f728e}body.ttrss_main .hl.active a,body.ttrss_main .hl.Selected a,body.ttrss_main .hl.active .feed a,body.ttrss_main .hl.Selected .feed a,body.ttrss_main .hl.active .hl-content a.title,body.ttrss_main .hl.Selected .hl-content a.title,body.ttrss_main .hl.active span,body.ttrss_main .hl.Selected span{color:#fff}body.ttrss_main .hl.Grayed{color:#909090}body.ttrss_main div.filterTestHolder{height:300px;overflow:auto;border-color:#ddd;border-style:solid;margin:0 0 5px 0;border-width:1px}body.ttrss_main #content-insert blockquote,body.ttrss_main #headlines-frame blockquote,body.ttrss_main .dijitContentPane blockquote{margin:5px 0 5px 0;color:#555;padding-left:10px;border:0 solid #ccc;border-left-width:4px}body.ttrss_main #content-insert code,body.ttrss_main #headlines-frame code,body.ttrss_main .dijitContentPane code{color:#090;font-family:monospace}body.ttrss_main #content-insert pre,body.ttrss_main #headlines-frame pre,body.ttrss_main .dijitContentPane pre{margin:5px 0 5px 0;padding:10px;color:#555;font-family:monospace;font-size:12px;border:0 solid #ccc;background:#f5f5f5;display:block;max-width:98%;overflow:auto}body.ttrss_main .alert{padding:8px 35px 8px 14px;margin-bottom:10px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;border-radius:4px}body.ttrss_main .alert,body.ttrss_main .alert h4{color:#c09853}body.ttrss_main .alert h4{margin:0}body.ttrss_main .alert .close{position:relative;top:-2px;right:-21px;line-height:20px;cursor:pointer}body.ttrss_main .alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}body.ttrss_main .alert-success h4{color:#468847}body.ttrss_main .alert-danger,body.ttrss_main .alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}body.ttrss_main .alert-danger h4,body.ttrss_main .alert-error h4{color:#b94a48}body.ttrss_main .alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}body.ttrss_main .alert-info h4{color:#3a87ad}body.ttrss_main ul.nomarks{list-style-type:none;margin:0;padding:10px}body.ttrss_main div.prefHelp{color:#555;padding:5px}body.ttrss_main .insensitive{color:#555}body.ttrss_main .small{font-size:11px}body.ttrss_main #main-toolbar>*{white-space:nowrap;display:table-cell;color:#999;overflow:hidden}body.ttrss_main #main-toolbar>*,body.ttrss_main #main-toolbar table *,body.ttrss_main #main-toolbar .actionChooser *{text-rendering:optimizelegibility;font-family:"Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px}body.ttrss_main #main-toolbar #headlines-toolbar{padding-right:4px;width:100%}body.ttrss_main #main-toolbar #headlines-toolbar span.holder{display:table;width:100%}body.ttrss_main #main-toolbar #headlines-toolbar span.holder>*{display:table-cell}body.ttrss_main #main-toolbar #headlines-toolbar .main{text-align:right}body.ttrss_main #main-toolbar #headlines-toolbar .main,body.ttrss_main #main-toolbar #headlines-toolbar .r{line-height:24px}body.ttrss_main #main-toolbar #headlines-toolbar span.r img{margin-right:4px;position:relative;top:3px}body.ttrss_main #main-toolbar #headlines-toolbar span.r .error a{color:#f00}body.ttrss_main #main-toolbar #selected_prompt{font-style:italic;text-align:right;margin-right:4px}@media (max-width:992px){body.ttrss_main #main-toolbar #selected_prompt{display:none}}body.ttrss_main span.preview{color:#999;font-weight:normal;font-size:12px;padding-left:4px}body.ttrss_main span.hlLabelRef{background-color:#fff7d5;font-size:8px;color:#063064;font-weight:normal;margin-left:2px;padding:1px 4px 1px 4px;display:inline-block;vertical-align:middle;white-space:nowrap;border-radius:4px}body.ttrss_main img.marked-pic,body.ttrss_main img.pub-pic{cursor:pointer;vertical-align:middle;opacity:.5;transition:opacity .25s}body.ttrss_main img.marked-pic:hover,body.ttrss_main img.pub-pic:hover{opacity:1}body.ttrss_main img[src*='pub_set.png'],body.ttrss_main img[src*='mark_set.png']{opacity:1}body.ttrss_main div.tagCloudContainer{border:1px solid #ddd;margin:5px 0 5px 0;padding:5px;text-align:center}body.ttrss_main div.errorExplained{border:1px solid #ddd;margin:5px 0 5px 0;padding:5px}body.ttrss_main ul.feedErrorsList{max-height:300px;overflow:auto;list-style-type:none;border:1px solid #ddd;margin:0 0 5px 0;padding:5px}body.ttrss_main ul.feedErrorsList em{color:#555}body.ttrss_main ul.browseFeedList{height:300px;overflow:auto;border-width:0 1px 1px 1px;border-color:#ddd;border-style:solid;margin:0 0 5px 0;background-color:#fff;list-style-type:none;padding:0}body.ttrss_main ul.browseFeedList li{margin:0;padding:2px 4px 2px 4px}body.ttrss_main .browseFeedList span.subscribers{color:#808080}body.ttrss_main ul.compact{list-style-type:none;margin:0;padding:0}body.ttrss_main ul.compact li{margin:0;padding:0}body.ttrss_main .noborder{border-width:0}body.ttrss_main #overlay{background:#fff;left:0;top:0;height:100%;width:100%;z-index:100;position:absolute}body.ttrss_main #overlay_inner{font-weight:bold;margin:1em}body.ttrss_main form{margin:0;padding:0}body.ttrss_main div.loadingPrompt{padding:1em;text-align:center;font-weight:bold}body.ttrss_main div.whiteBox{margin-left:1px;text-align:center;padding:1em 1em 0 1em;font-size:11px;border:0 solid #ddd;border-bottom-width:1px}body.ttrss_main div.autocomplete{position:absolute;width:250px;background-color:#fff;border:1px solid #789;margin:0;padding:0}body.ttrss_main div.autocomplete ul{list-style-type:none;margin:0;padding:0}body.ttrss_main div.autocomplete ul li.selected{background-color:#fff7d5}body.ttrss_main div.autocomplete ul li{list-style-type:none;display:block;margin:0;padding:2px;height:32px;cursor:pointer}body.ttrss_main div#headlines-frame.wide .title{max-width:none;overflow:visible;white-space:normal}body.ttrss_main div#headlines-frame.wide .hl .feed{display:none}body.ttrss_main img.score-pic{vertical-align:middle;width:16px;height:16px}body.ttrss_main div.dlgSec{font-size:12px;color:#555;font-weight:bold;clear:both;height:20px}body.ttrss_main div.dlgSecCont{position:relative;left:150px;top:-20px;float:left;font-size:12px;font-weight:normal}body.ttrss_main div.dlgSecCont>*{position:relative;top:-2px}body.ttrss_main div.dlgSecCont hr,body.ttrss_main div.dlgSecSimple hr{height:0;line-height:0;border:0 solid transparent;margin:2px}body.ttrss_main div.dlgButtons{text-align:right;clear:both}body.ttrss_main span.labelColorIndicator{height:16px;width:16px;border-radius:4px;line-height:14px;vertical-align:middle;font-size:9px;display:inline-block;border:1px solid #ccc;background-color:#fff7d5;color:#063064;text-align:center}body.ttrss_main div#cmdline{position:absolute;left:5px;bottom:5px;font-size:11px;color:#555;font-weight:bold;background-color:#fff;border:1px solid #257aa7;padding:3px 5px 3px 5px;z-index:5}body.ttrss_main #feed_browser_spinner{vertical-align:middle;height:18px;width:18px}body.ttrss_main div.fatalError{margin-bottom:10px}body.ttrss_main div.fatalError button{margin-top:5px}body.ttrss_main div.fatalError textarea{width:565px;height:200px}body.ttrss_main #header-wrap{border-width:0;margin:0;padding:0}body.ttrss_main #content-wrap{padding:0;border-width:0;margin:0}body.ttrss_main #feeds-holder{padding:0;border:0 solid #ddd;overflow:hidden;background:#f5f5f5;box-shadow:inset -1px 0 2px -1px rgba(0,0,0,0.1);-webkit-overflow-scrolling:touch}body.ttrss_main #feeds-holder #feedTree .dijitTreeRow .dijitTreeLabel.Unread{font-weight:bold}body.ttrss_main #feeds-holder #feedTree .dijitTreeRow.Error .dijitTreeLabel{color:#f00}body.ttrss_main #feeds-holder #feedTree .dijitTreeRow.UpdatesDisabled .dijitTreeLabel{color:#909090}body.ttrss_main #feeds-holder #feedTree.dijitTree .dijitTreeNode .dijitTreeRowSelected{box-shadow:-1px 0 2px -1px rgba(0,0,0,0.1);border-right-color:#fff}body.ttrss_main #feeds-holder #feedTree.dijitTree .dijitTreeContainer{max-width:100%}body.ttrss_main #feeds-holder #feedTree.dijitTree .dijitTreeRow{overflow:hidden;text-overflow:ellipsis}body.ttrss_main #feeds-holder #feedTree.dijitTree .dijitTreeNode .dijitTreeRow{padding:4px 0 4px;border-width:1px;color:#333}body.ttrss_main #feeds-holder #feedTree.dijitTree img.tinyFeedIcon{position:relative;top:-2px}body.ttrss_main #feeds-holder #feedTree{height:100%;overflow-x:hidden;text-rendering:optimizelegibility;font-family:"Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}body.ttrss_main #feeds-holder #feedTree .counterNode.aux{background:#f0f0f0;color:#999;border-color:#f0f0f0}body.ttrss_main #feeds-holder #feedTree .counterNode{font-weight:bold;display:inline-block;font-size:9px;text-align:center;border:1px solid #2a89bc;color:#fff;background:#2a89bc;border-radius:4px;vertical-align:middle;float:right;position:relative;line-height:14px;margin-right:8px;margin-top:2px;min-width:23px;height:14px}body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .loadingExpando{left:-3px;height:22px;position:relative;top:-3px}body.ttrss_main #headlines-wrap-inner{padding:0;margin:0;border-width:0}body.ttrss_main #headlines-frame{padding:0;border:0 #ddd;margin-top:0;-webkit-overflow-scrolling:touch;-webkit-transform:translateZ(0);-webkit-backface-visibility:hidden}body.ttrss_main #headlines-toolbar_splitter,body.ttrss_main #toolbar_splitter{display:none}body.ttrss_main #content-insert_splitter.dijitSplitterH{background:#f0f0f0;border-color:#ddd;border-top-width:1px;border-style:solid}body.ttrss_main #toolbar{padding:0;margin:0;border-width:0;white-space:nowrap;font-size:12px}body.ttrss_main #main-toolbar{background:#fff;border:0 solid #ddd;border-bottom-width:1px;padding-left:4px;height:26px}body.ttrss_main #header{border-width:0;text-align:right;color:#555;padding:5px 5px 0 0;margin:0;position:absolute;right:0;top:0;z-index:5}body.ttrss_main #footer{text-align:center;color:#555;padding:4px 4px 8px 4px;border-width:0}body.ttrss_main #content-insert{padding:0;border-color:#ddd;border-width:0;line-height:1.5;overflow:auto;-webkit-overflow-scrolling:touch}body.ttrss_main img.feedIcon,body.ttrss_main img.tinyFeedIcon{width:16px;height:16px;line-height:16px;vertical-align:middle;display:inline-block}body.ttrss_main .player{display:inline-block;color:#555;font-size:11px;font-family:sans-serif;border:1px solid #555;padding:0 4px 0 4px;margin:0 2px 0 2px;width:50px;text-align:center;background:#fff}body.ttrss_main .player.playing{color:#00c000;border-color:#00c000}body.ttrss_main .player:hover{background:#f0f0f0;cursor:pointer}body.ttrss_main #headlines-spacer{height:100%;margin-left:1px;text-align:center;color:#555;font-size:11px;font-style:italic}body.ttrss_main #headlines-spacer a,body.ttrss_main #headlines-spacer span{color:#555;padding:10px;display:block}body.ttrss_main #headlines-spacer a:hover{color:#257aa7}body.ttrss_main ul#filterDlg_Matches,body.ttrss_main ul#filterDlg_Actions{max-height:100px;overflow:auto;list-style-type:none;border-style:solid;border-color:#ddd;border-width:0 1px 1px 1px;background-color:#fff;margin:0 0 5px 0;padding:0}body.ttrss_main ul#filterDlg_Matches li,body.ttrss_main ul#filterDlg_Actions li{cursor:pointer;padding:0 0 0 5px}body.ttrss_main ul.helpKbList{max-height:300px;overflow:auto;list-style-type:none;border:1px solid #ddd;margin:0 0 5px 0;padding:5px}body.ttrss_main ul.helpKbList span.hksequence{width:6em;margin-left:20px;color:#257aa7;font-weight:bold;display:inline-block}body.ttrss_main ul.helpKbList h2{margin-top:0}body.ttrss_main select.attachments{display:block;margin-top:10px;max-width:120px}body.ttrss_main #selected_prompt{margin-right:25px;vertical-align:middle}body.ttrss_main #filterDlg_feeds select{height:150px;width:410px}body.ttrss_main ul#filterDlg_Matches li div.dijitCheckBox,body.ttrss_main ul#filterDlg_Actions li div.dijitCheckBox{margin-right:5px}body.ttrss_main span.highlight{background-color:#ff0;color:#cc90cc}body.ttrss_main #headlines-frame .dijitCheckBox{border-width:0;opacity:.5}body.ttrss_main #headlines-frame .dijitCheckBoxHover,body.ttrss_main #headlines-frame .dijitCheckBoxChecked{opacity:1}body.ttrss_main #feedTree .dijitTreeRow img.dijitTreeExpandoLeaf{width:16px;height:16px;vertical-align:middle;position:relative}body.ttrss_main .dijitDropDownButton.attachments .dijitButtonText{font-size:12px}body.ttrss_main .dijitDropDownButton.attachments{display:inline-block}body.ttrss_main #editTagsDlg{overflow:visible}body.ttrss_main #feedEditDlg img.feedIcon{border:1px solid #ccc;padding:5px;margin:5px;max-width:20px;max-height:20px;height:auto;width:auto}body.ttrss_login{padding:2em;font-size:14px}body.ttrss_login fieldset{margin-left:auto;margin-right:auto;display:block;width:400px;border-width:0}body.ttrss_login label{width:120px;margin-right:20px;display:inline-block;text-align:right;color:#808080}body.ttrss_login div.header{border:0 solid #257aa7;border-bottom-width:1px;margin-bottom:1em;padding-bottom:5px}body.ttrss_login div.footer{margin-top:1em;padding-top:5px;border:0 solid #257aa7;border-top-width:1px;text-align:center;color:#808080;font-size:12px}body.ttrss_login a.forgotpass{text-align:right;font-size:11px;display:inline-block}body.ttrss_login a{color:#257aa7;text-decoration:none}body.ttrss_login a:hover,body.ttrss_login a:focus{color:#257aa7;text-decoration:underline}body.ttrss_login div.footer a{color:#808080}body.ttrss_login div.footer a:hover{color:#257aa7}body.ttrss_login div.row{padding:0 0 5px 0}body.ttrss_login div.row-error{color:#f00;text-align:center;padding:0 0 5px 0}::selection{background:#257aa7;color:#fff}.cdm{margin-right:4px}.cdm .header,.cdm .footer{display:table}.cdm .header img,.cdm .header input,.cdm .footer img{vertical-align:middle}.cdm .header>div,.cdm .footer>div{white-space:nowrap}.cdm .header>span,.cdm .footer>span.left{width:100%}.cdm .header img,.cdm .footer img{margin:0 4px}.cdm .header>*{display:table-cell;padding:5px}.cdm .header span.updated{color:#555;font-weight:normal;font-size:11px;white-space:nowrap;vertical-align:middle}.cdm .header input{margin-right:5px}.cdm .header div.updPic{width:25px;display:inline-block;text-align:center}.cdm .header div.updPic img{vertical-align:middle}.cdm .header input{margin-left:4px;margin-right:4px}.cdm .footer{height:30px;padding-left:5px;font-weight:normal;color:#555;clear:both}.cdm .footer>*{display:table-cell;vertical-align:middle}.cdm .intermediate{margin:10px}.cdm .content-inner{margin:10px;line-height:1.5;font-size:16px}.cdm .content-inner h1{font-size:16px}.cdm .content-inner h2,.cdm .content-inner h3,.cdm .content-inner h4{font-size:15px}.cdm .intermediate img,.cdm .intermediate video,.cdm .content-inner img,.cdm .content-inner video{border-width:0;max-width:98%;height:auto}.cdm.expanded{margin-top:4px;margin-bottom:4px}.cdm.expanded .collapse{display:none}.cdm.expanded .footer{border:0 solid #ddd;border-bottom-width:1px}.cdm.expanded>hr{margin-top:0;margin-bottom:0}div.cdm.expanded div.header{background:transparent ! important}div.cdm.expanded div.header a.title{font-size:16px;color:#999;font-weight:600;transition:color .2s,background .2s;text-rendering:optimizelegibility;font-family:"Segoe WP Semibold","Segoe UI Semibold","Segoe UI Web Semibold","Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}div.cdm.expanded.active{background:#fff}div.cdm.expanded.active div.header a.title{color:#257aa7}div.cdm.expanded.Unread div.header a.title{color:#000}div.cdm.expanded div.content{color:#555}div.cdm.expanded.Unread div.content{color:#000}div.cdm.active div.content{color:#000}.cdm div.content div.postEnclosures{margin-top:1em;color:#555}.cdm div.feed-title{border:0 solid #257aa7;border-bottom-width:1px;padding:5px 3px 5px 5px}.cdm div.feed-title a.title{color:#555;font-weight:bold}.cdm div.feed-title a{color:#555}.cdm div.feed-title a:hover{color:#257aa7}.cdm div.header span.feed{float:right;font-weight:normal;font-style:italic}.cdm div.header div.feed,.cdm div.header div.feed a{vertical-align:middle;color:#555;font-weight:normal;font-style:italic;font-size:11px}.cdm div.content-inner p{-webkit-hyphens:auto;-moz-hyphens:auto;hyphens:auto}.cdm div.content-inner iframe{min-width:50%;max-width:98%}.cdm div.header span.author{white-space:nowrap;color:#555;font-size:11px;font-weight:normal}.cdm .feed a{border-radius:4px;display:inline-block;padding:1px 4px 1px 4px}div#floatingTitle{position:absolute;z-index:5;top:0;right:0;left:0;border:0 solid #ddd;border-bottom-width:1px;background:#fff;color:#555;box-shadow:0 1px 1px -1px rgba(0,0,0,0.1)}div#floatingTitle>*{display:table-cell;white-space:nowrap;vertical-align:middle;padding:9px 5px}div#floatingTitle img{margin-right:4px;margin-left:4px}div#floatingTitle span.author{color:#555;font-size:11px;font-weight:normal}div#floatingTitle a.title{font-size:16px;color:#999;transition:color .2s,background .2s;font-weight:600;text-rendering:optimizelegibility;font-family:"Segoe WP Semibold","Segoe UI Semibold","Segoe UI Web Semibold","Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}div#floatingTitle img.anchor{margin-left:0}div#floatingTitle div.feed{padding-right:10px;color:#555;font-weight:normal;font-style:italic;font-size:11px;white-space:nowrap}div#floatingTitle div.feed a{border-radius:4px;display:inline-block;padding:1px 4px 1px 4px}div#floatingTitle span.updated{padding-right:10px;white-space:nowrap;color:#555;font-size:11px}div#floatingTitle div.feed a{color:#555}div#floatingTitle .collapse{display:none}div#floatingTitle span.titleWrap{width:100%;white-space:normal}div#floatingTitle .dijit,div#floatingTitle img.score-pic{display:none}div#floatingTitle .feed-title>*{display:table-cell;vertical-align:middle}div#floatingTitle .feed-title a.title{width:100%}div#floatingTitle .feed-title a.catchup{text-align:right;color:#555;padding-right:10px;font-size:11px;white-space:nowrap}div#floatingTitle .feed-title a.catchup:hover{color:#257aa7}div#floatingTitle.Unread a.title{color:#000}.cdm.high .header a.title.high,.cdm.high .header .excerpt,.cdm.high .header span.author{color:#0a0}.cdm.Unread.high .header a.title.high,.cdm.Unread.high .header .excerpt,.cdm.Unread.high .header span.author{color:#0d0}.cdm .header a.title.low,.cdm.low .header .excerpt,.cdm.Unread .header a.title.low,.cdm.Unread.low .header .excerpt,.cdm.low .header span.author{color:#909090;text-decoration:line-through}.cdm.expandable{background-color:#f0f0f0;border:0 solid #ddd;border-bottom-width:1px}.cdm.expandable>hr{display:none}.cdm.expandable div.header span.titleWrap{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;max-width:500px}.cdm.expandable.Unread{background:#fff}.cdm.expandable.Selected:not(.active){background:#3f728e}.cdm.expandable.Selected:not(.active) a,.cdm.expandable.Selected:not(.active) .header a.title,.cdm.expandable.Selected:not(.active) span{color:#fff}.cdm.expandable.active{background:#fff ! important}div.cdm.expandable.active div.header span.titleWrap{white-space:normal}div.cdm.expandable div.header a.title{font-weight:600;color:#555;font-size:14px;transition:color .2s,background .2s;text-rendering:optimizelegibility;font-family:"Segoe WP Semibold","Segoe UI Semibold","Segoe UI Web Semibold","Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}div.cdm.expandable.Unread div.header a.title{color:#000}div.cdm.expandable.active div.header a.title{color:#257aa7;font-size:16px;font-weight:600;text-rendering:optimizelegibility;font-family:"Segoe WP Semibold","Segoe UI Semibold","Segoe UI Web Semibold","Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}div.cdm.expandable:not(.active){cursor:pointer}div.cdm.expandable:not(.active) .content,div.cdm.expandable:not(.active) .collapse{display:none}body.ttrss_prefs{background-color:#f5f5f5}body.ttrss_prefs #footer,body.ttrss_prefs #header{background-color:#f5f5f5;padding-left:8px;padding-right:8px}body.ttrss_prefs #header a:hover{color:#000}body.ttrss_prefs #header img{vertical-align:middle;cursor:pointer}body.ttrss_prefs div#pref-tabs .dijitContentPane{font-size:13px}body.ttrss_prefs div#pref-tabs{box-shadow:0 1px 1px -1px rgba(0,0,0,0.1);margin:0 5px 0 5px}body.ttrss_prefs div#pref-tabs .dijitContentPane h3{font-size:14px}body.ttrss_prefs #pref-filter-wrap,body.ttrss_prefs #pref-filter-header,body.ttrss_prefs #pref-filter-content,body.ttrss_prefs #pref-label-wrap,body.ttrss_prefs #pref-label-header,body.ttrss_prefs #pref-label-content,body.ttrss_prefs #pref-user-wrap,body.ttrss_prefs #pref-user-header,body.ttrss_prefs #pref-user-content,body.ttrss_prefs #pref-instance-wrap,body.ttrss_prefs #pref-instance-header,body.ttrss_prefs #pref-instance-content{margin:0;padding:0;border-width:0}body.ttrss_prefs #userConfigTab,body.ttrss_prefs #labelConfigTab,body.ttrss_prefs #filterConfigTab,body.ttrss_prefs #pref-feeds-feeds,body.ttrss_prefs #instanceConfigTab{padding:0}body.ttrss_prefs table.prefPrefsList h3{margin-top:.5em;margin-bottom:0}body.ttrss_prefs tr.title td{border:0 solid #ecf4ff;border-bottom-width:1px;color:#257aa7}body.ttrss_prefs div.prefProfileHolder,body.ttrss_prefs div.prefFeedOPMLHolder,body.ttrss_prefs div.inactiveFeedHolder{height:300px;overflow:auto;border:1px solid #ddd;border-top-width:0;margin:0 0 5px 0;background-color:#fff}body.ttrss_prefs div.filterTestHolder,body.ttrss_prefs div.prefFeedOPMLHolder{border-width:1px}body.ttrss_prefs ul.userFeedList{height:200px;overflow:auto;list-style-type:none;border:1px solid #ddd;margin:0 0 5px 0;padding:5px}body.ttrss_prefs div#feedlistLoading,body.ttrss_prefs div#filterlistLoading,body.ttrss_prefs div#labellistLoading{text-align:center;padding:5px;color:#555}body.ttrss_prefs div#feedlistLoading img,body.ttrss_prefs div#filterlistLoading img,body.ttrss_prefs div#labellistLoading{margin-right:5px}body.ttrss_prefs #errorButton{color:#f00}body.ttrss_prefs table.prefPluginsList td label,body.ttrss_prefs table.prefUserList td{cursor:pointer}body.ttrss_prefs table.prefPluginsList label{white-space:nowrap}body.ttrss_prefs table.prefPluginsList label img{vertical-align:middle}body.ttrss_prefs table.prefErrorLog tr.errrow td{font-size:10px}body.ttrss_prefs table.prefErrorLog tr.errrow td.errno{font-style:italic;font-weight:bold;white-space:nowrap}body.ttrss_prefs table.prefErrorLog td.filename,body.ttrss_prefs table.prefErrorLog td.login,body.ttrss_prefs table.prefErrorLog td.timestamp{color:#555}body.ttrss_prefs hr{border-color:#ecf4ff;max-width:100%}.claro .dijitTreeRow .dijitCheckBox{position:relative;top:-2px}.claro .dijitTreeLabel{outline:0}.claro .dijitTree .feedParam{color:#555;float:right;margin-right:1em}.claro .dijitTree .filterRules{display:block;color:#ccc;font-size:10px;margin-left:100px}.claro .dijitTree .filterRules span{display:block;color:#008000}.claro #filterDlg_Matches span.filterRule{color:#008000}.claro .dijitTree .filterRules span.inverse,.claro #filterDlg_Matches span.filterRule.inverse{color:#f00}.claro .dijitTree .labelParam{float:right;margin-right:1em}.claro .dijitTree .dijitTreeLabel.filterDisabled,.claro .dijitTree .labelParam.filterDisabled{color:#555;text-decoration:line-through}.claro .dijitTreeRow.Error{color:#f00}.claro .dijitTreeRow.Hidden{display:none}.claro .dijitTreeNode .loadingNode{margin-left:3px;height:9px}.claro .dijitFolderClosed,.claro .dijitFolderOpened{display:none}.claro .dijitTreeNode .dijitCheckBox{margin-left:4px}.claro .dijitTreeIsRoot>.dijitTreeRow>.dijitTreeExpando{margin-left:5px}.claro .dijitTree .dijitTreeExpando{margin-top:0;opacity:.6}.claro .dijitTree .dijitTreeNode{padding:0;border-width:0}.claro .dijitTree .dijitTreeRowSelected{background:#fff}.claro .dijitTree .dijitTreeRowHover{background:#f0f0f0;border-color:#ddd}.claro .dijitTree .dijitTreeRowSelected{background:#fff;border-color:#ddd}.claro .dijitTreeRowSelected .dijitTreeLabel{text-shadow:1px 1px 2px #fff}.claro .dijitTreeRow .dijitTreeExpando{background-image:url("../images/treeExpandImages.png");position:relative;top:-1px}.claro .dijitTreeRow .dijitTreeExpandoLeaf{background:none}.claro .dijitToolbar{background:#f5f5f5;border-color:#ddd}.claro .dijitDialog .dijitToolbar{border:1px solid #ddd}.claro .dijitDialog h2{margin-top:0;margin-bottom:4px;border-width:0}.claro .dijitMenu .dijitMenuItem .dijitMenuItemLabel{font-size:13px;padding-top:3px;padding-bottom:3px}.claro .dijitCheckBox{background-image:url("../images/untick.png");background-color:transparent;width:15px;height:15px;margin:1px;opacity:.7;background-position:center center;transition:opacity .25s;-webkit-transition:opacity .25s;padding:1px}.claro .dijitCheckBox:hover{opacity:1}.claro .dijitCheckBox.dijitCheckBoxDisabled:hover{opacity:.7}.claro .dijitCheckBox.dijitCheckBoxChecked{border-color:#69c671;background-image:url("../images/tick.png");opacity:1}.claro .dijitButton.btn-danger .dijitButtonText{color:#fff}.claro .dijitButton.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top, #ee5f5b, #bd362f);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));background-image:-webkit-linear-gradient(top, #ee5f5b, #bd362f);background-image:-o-linear-gradient(top, #ee5f5b, #bd362f);background-image:linear-gradient(to bottom, #ee5f5b, #bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.claro .dijitButton.dijitButtonDisabled.btn-danger,.claro .dijitButton.dijitButtonActive.btn-danger,.claro .dijitButton.dijitButtonHover.btn-danger,.claro .dijitButton.dijitFocused.btn-danger{color:#fff;background-color:#bd362f;*background-color:#a9302a}.claro .dijitButton.dijitButtonActive.btn-danger{background-color:#942a25 \9}.claro .dijitButton.dijitButtonActive.btn-danger{color:rgba(255,255,255,0.75)}.claro .dijitButton.btn-primary .dijitButtonText{color:#fff}.claro .dijitButton.btn-primary{text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#2883b3;*background-color:#257aa7;background-image:-moz-linear-gradient(top, #4ba6d8, #257aa7);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#4ba6d8), to(#257aa7));background-image:-webkit-linear-gradient(top, #4ba6d8, #257aa7);background-image:-o-linear-gradient(top, #4ba6d8, #257aa7);background-image:linear-gradient(to bottom, #4ba6d8, #257aa7);background-repeat:repeat-x;border-color:#257aa7 #257aa7 #1d5f82;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.claro .dijitButton.dijitButtonDisabled.btn-primary,.claro .dijitButton.dijitButtonActive.btn-primary,.claro .dijitButton.dijitButtonHover.btn-primary,.claro .dijitButton.dijitFocused.btn-primary{color:#fff;background-color:#257aa7;*background-color:#1d6185}.claro .dijitButton.dijitButtonActive.btn-primary{background-color:#1f678d \9}.claro .dijitButton.dijitButtonActive.btn-primary{color:rgba(255,255,255,0.75)}.claro .dijitDropDownButton{margin:0}.claro .dijitDropDownButton .dijitButtonNode{padding:0}.claro .dijitButton .dijitButtonNode,.claro .dijitDropDownButton .dijitButtonNode,.claro .dijitComboButton .dijitButtonNode,.claro .dijitToolbar .dijitDropDownButton .dijitButtonNode,.claro .dijitToolbar .dijitComboButton,.claro .dijitToolbar .dijitSelect.dijitDownArrowButton .dijitButtonNode,.claro .dijitToolbar .dijitComboButton .dijitButtonNode{background:none;border-color:transparent;box-shadow:none}.claro button,.claro input[type="submit"]{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px}.claro button,.claro input[type="submit"],.claro .dijitButton,.claro .dijitDropDownButton .dijitDownArrowButton,.claro .dijitComboButton{display:inline-block;padding:4px 12px;margin-bottom:0;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;background-image:-moz-linear-gradient(top, #fff, #e6e6e6);background-image:-webkit-linear-gradient(top, #fff, #e6e6e6);background-image:linear-gradient(to bottom, #fff, #e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#b3b3b3;-webkit-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.claro button:hover,.claro button:focus,.claro button:active,.claro input[type="submit"]:hover,.claro input[type="submit"]:focus,.claro input[type="submit"]:active,.claro .dijitButton:hover,.claro .dijitButton:focus,.claro .dijitButton:active,.claro .dijitDropDownButton .dijitDownArrowButton:hover,.claro .dijitDropDownButton .dijitDownArrowButton:focus,.claro .dijitDropDownButton .dijitDownArrowButton:active,.claro .dijitComboButton:hover,.claro .dijitComboButton:focus,.claro .dijitComboButton:active,.claro .dijitButton.dijitButtonDisabled{color:#333;background-color:#e6e6e6}.claro button:active,.claro input[type="submit"]:active,.claro .dijitButton:active,.claro .dijitDropDownButton .dijitDownArrowButton:active,.claro .dijitComboButton:active{background-color:#cccccc \9}.claro .dijitToolbar .dijitButton,.claro .dijitToolbar .dijitButton.dijitHover,.claro .dijitToolbar .dijitComboButton,.claro .dijitToolbar .dijitDropDownButton .dijitDownArrowButton,.claro .dijitToolbar .dijitComboButton.dijitHover{background:none;border-color:transparent;box-shadow:none;padding:0;margin:0;line-height:auto;text-shadow:none}.claro .dijitToolbar .dijitDropDownButton .dijitButtonText,.claro .dijitToolbar .dijitDownArrowButton .dijitButtonText,.claro .dijitToolbar .dijitComboButton .dijitButtonText{padding:0}.claro .dijitToolbar .dijitDropDownButton .dijitButtonNode{border-radius:4px}.claro .dijitToolbar .dijitButton.dijitHover,.claro .dijitToolbar .dijitDropDownButton.dijitHover .dijitButtonNode,.claro .dijitToolbar .dijitComboButton.dijitHover{border-color:#ccc}.claro .dijitToolbar .dijitButton.dijitHover .dijitButtonNode,.claro .dijitToolbar .dijitButton.dijitButtonActive .dijitButtonNode{background:none}.claro .dijitToolbar .dijitButton .dijitButtonContents,.claro .dijitToolbar .dijitDropDownButton .dijitButtonContents,.claro .dijitToolbar .dijitComboButton .dijitButtonContents{font-size:13px}.claro button:hover,.claro button:focus,.claro input[type="submit"]:hover,.claro input[type="submit"]:focus,.claro .dijitButton:hover,.claro .dijitDropDownButton .dijitDownArrowButton:hover,.claro .dijitToolbar .dijitButton:hover .dijitButtonNode,.claro .dijitToolbar .dijitButton.dijitHover .dijitButtonNode,.claro .dijitButton:focus,.claro .dijitComboButton:hover,.claro .dijitComboButton:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;transition:background-position .1s linear}.claro button:focus,.claro input[type="submit"]:focus,.claro .dijitButton:focus,.claro .dijitDropDownButton .dijitDownArrowButton:focus,.claro .dijitComboButton:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.claro button:active,.claro input[type="submit"]:active,.claro .dijitButton:active,.claro .dijitComboButton:active,.claro .dijitToolbar .dijitDropDownButton.dijitOpened,.claro .dijitToolbar .dijitComboButton.dijitOpened,.claro .dijitToolbar .dijitButton.dijitButtonActive .dijitButtonNode{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.claro input[type="submit"][disabled],.claro button[disabled],.claro .dijitButton[disabled],.claro .dijitDropDownButton .dijitDownArrowButton[disabled],.claro .dijitButton.dijitButtonDisabled,.claro .dijitComboButton.dijitButtonDisabled{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.claro .dijitButton .dijitButtonContents,.claro .dijitDropDownButton .dijitButtonContents,.claro .dijitComboButton .dijitButtonContents{font-size:14px;font-weight:normal;line-height:20px}.claro .dijitButton.small .dijitButtonText{font-size:11px}.claro .dijitMenu{border-color:#257aa7}.claro .dijitMenu .dijitMenuItemSelected,.claro .dijitMenu .dijitMenuItemSelected td{background:#257aa7;color:#fff;border-color:#257aa7}.claro .dijitButton .dijitButtonNode,.claro .dijitComboButton .dijitButtonNode{padding:0}.claro .dijitAccordionTitle.dijitAccordionTitleHover,.claro .dijitAccordionTitle.dijitAccordionTitleFocused{background:#fff;transition:background .25s}.claro .dijitAccordionTitle{background:#f0f0f0;transition:background .25s}.claro .dijitAccordionInnerContainer.dijitAccordionInnerContainerSelected,.claro .dijitAccordionTitle.dijitAccordionTitleSelected{background:#257aa7;transition:background .25s}.claro .dijitAccordionTitle.dijitAccordionTitleSelected .dijitAccordionText{color:#fff}.claro .dijitAccordionInnerContainer.dijitAccordionInnerContainerSelected{border-color:#257aa7}.claro .dijitAccordionContainer .dijitAccordionChildWrapper{border-color:#ddd}.claro .dijitTabInner.dijitTab{background:#f0f0f0}.claro .dijitTabContent{background:#eee}.claro .dijitTabContent.dijitTabChecked,.claro .dijitTabContent.dijitTabHover,.claro .dijitTabContent.dijitFocused{background:#fff}.claro .dijitTabPaneWrapper,.claro .dijitTabContainerTop-tabs,.claro .dijitTab,.claro .dijitAccordionInnerContainer{border-color:#ddd}.claro .dijitComboBox .dijitArrowButton,.claro .dijitSelect .dijitArrowButton{background:transparent;border-color:transparent}.claro .dijitSelect .dijitArrowButton .dijitArrowButtonInner{margin-right:5px;float:right}.claro select,.claro .dijitDownArrowButton.dijitSelect{-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;margin-bottom:4px}.claro .dijitSelect .dijitButtonContents{display:inline-block;height:20px;padding:4px 6px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;border-width:0}.claro select,.claro textarea,.claro .input.input-text,.claro .dijitTextBox{display:inline-block;height:20px;padding:4px 6px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;margin-bottom:4px}.claro textarea{height:auto}.claro select,.claro .input.input-text{height:30px}.claro textarea,.claro select,.claro .input.input-text,.claro .dijitTextBox,.claro .dijitSelect{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}.claro select:focus,.claro .input.input-text:focus,.claro .dijitTextBox.dijitFocused,.claro .dijitSelect.dijitFocused{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(37,122,167,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(37,122,167,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(37,122,167,0.6)}.claro .dijitError .dijitValidationContainer{padding:0;width:13px;border-width:1px;display:none}.claro .dijitSelect.dijitSelectDisabled{background-color:#eee}.claro .dijitSelect.dijitSelectDisabled .dijitSelectLabel{cursor:not-allowed}.claro .dijitTextBox.dijitTextBoxDisabled,.claro .dijitTextBox.dijitTextBoxDisabled .dijitInputInner,.claro .dijitTextBox.dijitReadOnly,.claro .dijitTextBox.dijitReadOnly .dijitInputInner{cursor:not-allowed;background-color:#eee}.claro .dijitToolbar .dijitDownArrowButton.dijitSelect{border-color:rgba(0,0,0,0.1)}.claro .dijitToolbar .dijitDownArrowButton.dijitSelect .dijitButtonContents{padding:2px 2px 0 4px}.claro .dijitToolbar .dijitDownArrowButton.dijitSelect{margin:0}.claro .dijitToolbar .dijitTextBox{padding:0;margin-bottom:0;border-radius:0}.claro .dijitDialog{border-radius:6px}.claro .dijitDialog .dijitDialogCloseIcon{margin-top:5px}.claro .dijitDialog .dijitDialogTitleBar{background:#fff;padding:8px;font-weight:600;color:#555;font-size:16px;text-rendering:optimizelegibility;font-family:"Segoe WP Semibold","Segoe UI Semibold","Segoe UI Web Semibold","Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}.claro .dijitDialog .dijitDialogPaneContent{border-color:#ddd;padding:10px}.claro .dijitProgressBar.dijitProgressBarEmpty{background:#ddd;border-color:#257aa7}.claro .dijitProgressBar.dijitProgressBarEmpty .dijitProgressBarFull .dijitProgressBarTile{background:#257aa7}.claro .dijitProgressBar .dijitProgressBarLabel{color:#fff}body.ttrss_utility.sanity_failed{background:#900}body.ttrss_utility{background:#f5f5f5;color:#000;padding:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;margin-left:auto;margin-right:auto;max-width:800px}body.ttrss_utility form{margin:10px 0 0 0;padding:0}body.ttrss_utility div.content{overflow:hidden;background:#fff;border:1px solid #ddd;padding:10px;border-radius:6px;box-shadow:0 1px 1px -1px rgba(0,0,0,0.1)}body.ttrss_utility p.warning{color:#f00}body.ttrss_utility p.query,body.ttrss_utility code{color:#008000}body.ttrss_utility p.insensitive{color:#808080}body.ttrss_utility div.insensitive-small{color:#808080;font-size:10px}body.ttrss_utility .floatingLogo{display:none}body.ttrss_utility a{color:#257aa7;text-decoration:none}body.ttrss_utility a:hover,body.ttrss_utility a:focus{color:#133d54;text-decoration:underline}body.ttrss_utility .alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}body.ttrss_utility .alert,body.ttrss_utility .alert h4{color:#c09853}body.ttrss_utility .alert h4{margin:0}body.ttrss_utility .alert .close{position:relative;top:-2px;right:-21px;line-height:20px;cursor:pointer}body.ttrss_utility .alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}body.ttrss_utility .alert-success h4{color:#468847}body.ttrss_utility .alert-danger,body.ttrss_utility .alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}body.ttrss_utility .alert-danger h4,body.ttrss_utility .alert-error h4{color:#b94a48}body.ttrss_utility .alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}body.ttrss_utility .alert-info h4{color:#3a87ad}body.ttrss_utility h1{color:#257aa7;font-size:32px;margin:20px 0 5px 0;text-shadow:0 0 6px #fff}body.ttrss_utility h2{color:#257aa7;font-size:14pt;border-width:0 0 1px 0;border-color:#f0f0f0;border-style:solid}body.ttrss_utility div.content>h2{margin-top:0}body.ttrss_utility div.rss h1{border-width:0 0 1px 0;border-color:#808080;border-style:dotted;color:#808080}body.ttrss_utility div.rss h2{font-size:12pt}body.ttrss_utility div.rss a.extlink{color:#808080;border-width:0 0 1px 0;border-color:#789;border-style:dotted;font-size:9pt}body.ttrss_utility div.rss img{max-width:775px}body.ttrss_utility div.rss p.description{color:#808080;font-size:9pt}body.ttrss_utility div.rss div.content{margin-top:.5em}body.ttrss_utility div.rss img.feedicon{float:right}body.ttrss_utility div.rss hr{border-width:0 0 1px 0;border-style:dashed;border-color:#e0e0e0}body.ttrss_utility div.autocomplete{position:absolute;width:250px;background-color:#fff;border:1px solid #789;margin:0;padding:0;z-index:4}body.ttrss_utility div.autocomplete ul{list-style-type:none;margin:0;padding:0;font-size:10px}body.ttrss_utility div.autocomplete ul li.selected{background-color:#fff7d5}body.ttrss_utility div.autocomplete ul li{list-style-type:none;display:block;margin:0;padding:2px;height:32px;cursor:pointer}body.ttrss_utility fieldset{border-width:0;padding:0 0 5px 0;margin:0}body.ttrss_utility fieldset input{font-family:sans-serif;font-size:medium;border-spacing:2px;border:1px solid #b5bcc7;padding:2px}body.ttrss_utility fieldset label{width:120px;margin-right:20px;display:inline-block;text-align:right;color:#808080}body.ttrss_utility body.otp{margin:1em;padding:0}body.ttrss_utility form.otpform{margin:0;padding:0}body.ttrss_utility form.otpform label{margin:0;padding:0}body.ttrss_utility body.otp div.content{display:inline-block;width:auto}body.ttrss_utility span.hint{font-size:10px;color:#808080}body.small_margins{margin:1em;max-width:none}body#sharepopup{background:#fff url("../images/toolbar.png") repeat-x bottom;margin:10px;padding:0}body#sharepopup h1{font-size:14px;margin:0;color:#257aa7}body#sharepopup table{background:#fff;border:1px solid #257aa7;padding:5px}body#sharepopup form{height:100%}body#sharepopup input{width:100%}body.ttrss_zoom{margin-left:auto;margin-right:auto;padding:20px;max-width:800px;background:#f5f5f5}body.ttrss_zoom div.post{border:1px solid #ddd;background:#fff;box-shadow:0 1px 1px -1px rgba(0,0,0,0.1)}body.ttrss_zoom div.post div.header{margin:10px;padding-bottom:10px;border:0 solid #eee;border-bottom-width:1px;background:#fff;font-size:12px;color:#555}body.ttrss_zoom div.post div.header .author{font-size:11px}body.ttrss_zoom div.post div.header div.feed-title{float:left;text-align:right}body.ttrss_zoom div.post div.header a.comments{text-align:right}body.ttrss_zoom div.post div.header div.date{float:none;text-align:right;margin-bottom:5px}body.ttrss_zoom div.post div.header div.tags img{vertical-align:middle}body.ttrss_zoom div.post div.header div.title{white-space:normal;font-size:16px;margin-bottom:5px}body.ttrss_zoom div.post p{-webkit-hyphens:auto;-moz-hyphens:auto;hyphens:auto}body.ttrss_zoom div.post div.footer{margin-top:1em;text-align:center}body.ttrss_zoom div.post div.content{font-size:15px;line-height:1.5;padding:10px;border-width:0}body.ttrss_zoom div.post div.content img,body.ttrss_zoom div.post div.content video{max-width:760px;height:auto}body.ttrss_zoom div.post div.content blockquote{margin:5px 0 5px 0;color:#555;padding-left:10px;border:0 solid #ccc;border-left-width:4px}body.ttrss_zoom div.post div.content code{color:#090;font-family:monospace;font-size:12px}body.ttrss_zoom div.post div.content pre{margin:5px 0 5px 0;padding:10px;color:#555;font-family:monospace;font-size:12px;border:0 solid #ccc;background:#f5f5f5;display:block;max-width:98%;overflow:auto} \ No newline at end of file +body.ttrss_main,body.ttrss_prefs,#main{position:absolute;width:100%;height:100%;border:0;padding:0;margin:0}body.ttrss_main{background:#fff;color:#000;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;overflow:hidden}body.ttrss_main :focus{outline:none}body.ttrss_main div.post{padding:0}body.ttrss_main div.post div.header{padding:5px;color:#909090;border:0 solid #ddd;border-bottom-width:1px;background:#f0f0f0}body.ttrss_main div.post div.header div.date{text-align:right;float:right}body.ttrss_main div.post div.header div{padding-bottom:3px}body.ttrss_main div.post div.header span.author{color:#555;font-size:11px;font-weight:normal}body.ttrss_main div.post div.title{overflow:hidden;font-size:15px;text-overflow:ellipsis;white-space:nowrap;font-weight:600;text-rendering:optimizelegibility;font-family:"Segoe WP Semibold","Segoe UI Semibold","Segoe UI Web Semibold","Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}body.ttrss_main div.post div.date{padding-left:10px}body.ttrss_main div.post div.content{padding:10px;font-size:16px}body.ttrss_main div.post div.content img,body.ttrss_main div.post div.content video{border-width:0;max-width:98%;height:auto}body.ttrss_main div.post div.content h1{font-size:16px}body.ttrss_main div.post div.content h2,body.ttrss_main div.post div.content h3,body.ttrss_main div.post div.content h4{font-size:15px}body.ttrss_main div.post div.content p{hyphens:auto}body.ttrss_main div.post div.content iframe{min-width:50%;max-width:98%}body.ttrss_main div.post div.postEnclosures{color:#555}body.ttrss_main div.post img.tagsPic{width:16px;height:16px;margin-left:4px;vertical-align:middle}body.ttrss_main div.post span.author{font-size:12px}body.ttrss_main div.articleNote{background-color:#fff7d5;padding:5px;margin:5px;border:1px solid #e7d796;color:#9a8c59}body.ttrss_main div.articleNote div.noteEdit{float:right;cursor:pointer}body.ttrss_main h1{font-size:18px;font-weight:600;text-rendering:optimizelegibility;font-family:"Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}body.ttrss_main h2{font-size:16px;font-weight:600;border:0 solid #d5ebf6;border-bottom-width:1px;text-rendering:optimizelegibility;font-family:"Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}body.ttrss_main h3{font-size:13px;border:0 solid #d5ebf6;border-bottom-width:1px;font-weight:600;text-rendering:optimizelegibility;font-family:"Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}body.ttrss_main h4{font-size:14px;font-weight:600;text-rendering:optimizelegibility;font-family:"Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}body.ttrss_main hr{border:0 solid #ccc;border-bottom-width:1px}body.ttrss_main a{color:#257aa7;text-decoration:none}body.ttrss_main a:hover{color:#133d54;text-decoration:underline}body.ttrss_main #notify.visible{transform:translate(0, -35px)}body.ttrss_main #notify{bottom:-35px;right:0;height:20px;left:0;border-width:1px 0 0 0;border-style:solid;position:fixed;font-size:12px;z-index:99;padding:5px;box-shadow:0 -2px 2px rgba(0,0,0,0.1);transition:all .5s ease-in-out}body.ttrss_main #notify img{vertical-align:middle;max-height:14px}body.ttrss_main #notify span.msg{width:100%}body.ttrss_main #notify img.close{cursor:pointer}body.ttrss_main #notify span{display:table-cell;vertical-align:middle;padding:2px}body.ttrss_main .notify{border-color:#d7c47a;background-color:#fff7d5}body.ttrss_main .notify.notify_progress{border-color:#d7c47a;background-color:#fff7d5}body.ttrss_main .notify.notify_info{border-color:#257aa7;background-color:#d5ebf6}body.ttrss_main .notify.notify_error{background-color:#fcc;border-color:#f00}body.ttrss_main .hl{border:0 solid #ddd;border-bottom-width:1px;padding:1px;transition:color .2s,background .2s}body.ttrss_main .hl div.title{display:table-cell;cursor:pointer;width:100%;vertical-align:middle;overflow:hidden;white-space:nowrap;max-width:500px;text-overflow:ellipsis;padding:4px 6px}body.ttrss_main .hl div.left{display:table-cell;vertical-align:middle;white-space:nowrap}body.ttrss_main .hl div.right{display:table-cell;white-space:nowrap;text-align:right;vertical-align:middle}body.ttrss_main .hl div.right img{max-width:16px;max-height:16px}body.ttrss_main .hl span.feed{display:table-cell;vertical-align:middle;text-align:right}body.ttrss_main .hl span.feed a{border-radius:4px;display:inline-block;padding:1px 4px 1px 4px;font-size:11px;font-style:italic;font-weight:normal;color:#555;white-space:nowrap}body.ttrss_main .hl span.feed a:hover{color:#257aa7}body.ttrss_main .hl span.updated{color:#555;display:table-cell;vertical-align:middle;text-align:right;font-size:11px;white-space:nowrap;padding-left:10px}body.ttrss_main .hl span.updated div{display:inline-block}body.ttrss_main .hl div.left{padding-left:8px}body.ttrss_main .hl div.left input{margin-left:4px;margin-right:4px}body.ttrss_main .hl div.left img,body.ttrss_main .hl div.right img{margin:0 4px}body.ttrss_main .hl div.left img{width:16px;height:16px}body.ttrss_main .hl div.title a{font-weight:600;text-rendering:optimizelegibility;font-family:"Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif;color:#777}body.ttrss_main .hl a.title.high,body.ttrss_main .hl span.hl-content.high .preview{color:#0a0}body.ttrss_main .hl.Unread a.title.high,body.ttrss_main .hl.Unread span.hl-content.high .preview{color:#0d0}body.ttrss_main .hl a.title.low,body.ttrss_main span.hl-content.low .preview,body.ttrss_main .hl.Unread a.title.low,body.ttrss_main .hl.Unread span.hl-content.low .preview{color:#909090;text-decoration:line-through}body.ttrss_main .hl.Unread div.title a{color:#000}body.ttrss_main .hl.active div.title a{color:#257aa7}body.ttrss_main .hl.active{background:#257aa7 ! important}body.ttrss_main .hl.active,body.ttrss_main .hl.Selected{color:#fff;background:#3f728e}body.ttrss_main .hl.active a,body.ttrss_main .hl.Selected a,body.ttrss_main .hl.active .feed a,body.ttrss_main .hl.Selected .feed a,body.ttrss_main .hl.active .hl-content a.title,body.ttrss_main .hl.Selected .hl-content a.title,body.ttrss_main .hl.active span,body.ttrss_main .hl.Selected span{color:#fff}body.ttrss_main .hl.Grayed{color:#909090}body.ttrss_main div.filterTestHolder{height:300px;overflow:auto;border-color:#ddd;border-style:solid;margin:0 0 5px 0;border-width:1px}body.ttrss_main #content-insert blockquote,body.ttrss_main #headlines-frame blockquote,body.ttrss_main .dijitContentPane blockquote{margin:5px 0 5px 0;color:#555;padding-left:10px;border:0 solid #ccc;border-left-width:4px}body.ttrss_main #content-insert code,body.ttrss_main #headlines-frame code,body.ttrss_main .dijitContentPane code{color:#090;font-family:monospace}body.ttrss_main #content-insert pre,body.ttrss_main #headlines-frame pre,body.ttrss_main .dijitContentPane pre{margin:5px 0 5px 0;padding:10px;color:#555;font-family:monospace;font-size:12px;border:0 solid #ccc;background:#f5f5f5;display:block;max-width:98%;overflow:auto}body.ttrss_main .alert{padding:8px 35px 8px 14px;margin-bottom:10px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;border-radius:4px}body.ttrss_main .alert,body.ttrss_main .alert h4{color:#c09853}body.ttrss_main .alert h4{margin:0}body.ttrss_main .alert .close{position:relative;top:-2px;right:-21px;line-height:20px;cursor:pointer}body.ttrss_main .alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}body.ttrss_main .alert-success h4{color:#468847}body.ttrss_main .alert-danger,body.ttrss_main .alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}body.ttrss_main .alert-danger h4,body.ttrss_main .alert-error h4{color:#b94a48}body.ttrss_main .alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}body.ttrss_main .alert-info h4{color:#3a87ad}body.ttrss_main ul.nomarks{list-style-type:none;margin:0;padding:10px}body.ttrss_main div.prefHelp{color:#555;padding:5px}body.ttrss_main .insensitive{color:#555}body.ttrss_main .small{font-size:11px}body.ttrss_main #main-toolbar>*{white-space:nowrap;display:table-cell;color:#999;overflow:hidden}body.ttrss_main #main-toolbar>*,body.ttrss_main #main-toolbar table *,body.ttrss_main #main-toolbar .actionChooser *{text-rendering:optimizelegibility;font-family:"Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px}body.ttrss_main #main-toolbar #headlines-toolbar{padding-right:4px;width:100%}body.ttrss_main #main-toolbar #headlines-toolbar span.holder{display:table;width:100%}body.ttrss_main #main-toolbar #headlines-toolbar span.holder>*{display:table-cell}body.ttrss_main #main-toolbar #headlines-toolbar .main{text-align:right}body.ttrss_main #main-toolbar #headlines-toolbar .main,body.ttrss_main #main-toolbar #headlines-toolbar .r{line-height:24px}body.ttrss_main #main-toolbar #headlines-toolbar span.r img{margin-right:4px;position:relative;top:3px}body.ttrss_main #main-toolbar #headlines-toolbar span.r .error a{color:#f00}body.ttrss_main #main-toolbar #selected_prompt{font-style:italic;text-align:right;margin-right:4px}@media (max-width:992px){body.ttrss_main #main-toolbar #selected_prompt{display:none}}body.ttrss_main span.preview{color:#999;font-weight:normal;font-size:12px;padding-left:4px}body.ttrss_main span.hlLabelRef{background-color:#fff7d5;font-size:8px;color:#063064;font-weight:normal;margin-left:2px;padding:1px 4px 1px 4px;display:inline-block;vertical-align:middle;white-space:nowrap;border-radius:4px}body.ttrss_main img.marked-pic,body.ttrss_main img.pub-pic{cursor:pointer;vertical-align:middle;opacity:.5;transition:opacity .25s}body.ttrss_main img.marked-pic:hover,body.ttrss_main img.pub-pic:hover{opacity:1}body.ttrss_main img[src*='pub_set.png'],body.ttrss_main img[src*='mark_set.png']{opacity:1}body.ttrss_main div.tagCloudContainer{border:1px solid #ddd;margin:5px 0 5px 0;padding:5px;text-align:center}body.ttrss_main div.errorExplained{border:1px solid #ddd;margin:5px 0 5px 0;padding:5px}body.ttrss_main ul.feedErrorsList{max-height:300px;overflow:auto;list-style-type:none;border:1px solid #ddd;margin:0 0 5px 0;padding:5px}body.ttrss_main ul.feedErrorsList em{color:#555}body.ttrss_main ul.browseFeedList{height:300px;overflow:auto;border-width:0 1px 1px 1px;border-color:#ddd;border-style:solid;margin:0 0 5px 0;background-color:#fff;list-style-type:none;padding:0}body.ttrss_main ul.browseFeedList li{margin:0;padding:2px 4px 2px 4px}body.ttrss_main .browseFeedList span.subscribers{color:#808080}body.ttrss_main ul.compact{list-style-type:none;margin:0;padding:0}body.ttrss_main ul.compact li{margin:0;padding:0}body.ttrss_main .noborder{border-width:0}body.ttrss_main #overlay{background:#fff;left:0;top:0;height:100%;width:100%;z-index:100;position:absolute}body.ttrss_main #overlay_inner{font-weight:bold;margin:1em}body.ttrss_main form{margin:0;padding:0}body.ttrss_main div.loadingPrompt{padding:1em;text-align:center;font-weight:bold}body.ttrss_main div.whiteBox{margin-left:1px;text-align:center;padding:1em 1em 0 1em;font-size:11px;border:0 solid #ddd;border-bottom-width:1px}body.ttrss_main div.autocomplete{position:absolute;width:250px;background-color:#fff;border:1px solid #789;margin:0;padding:0}body.ttrss_main div.autocomplete ul{list-style-type:none;margin:0;padding:0}body.ttrss_main div.autocomplete ul li.selected{background-color:#fff7d5}body.ttrss_main div.autocomplete ul li{list-style-type:none;display:block;margin:0;padding:2px;height:32px;cursor:pointer}body.ttrss_main div#headlines-frame.wide .title{max-width:none;overflow:visible;white-space:normal}body.ttrss_main div#headlines-frame.wide .hl .feed{display:none}body.ttrss_main img.score-pic{vertical-align:middle;width:16px;height:16px}body.ttrss_main div.dlgSec{font-size:12px;color:#555;font-weight:bold;clear:both;height:20px}body.ttrss_main div.dlgSecCont{position:relative;left:150px;top:-20px;float:left;font-size:12px;font-weight:normal}body.ttrss_main div.dlgSecCont>*{position:relative;top:-2px}body.ttrss_main div.dlgSecCont hr,body.ttrss_main div.dlgSecSimple hr{height:0;line-height:0;border:0 solid transparent;margin:2px}body.ttrss_main div.dlgButtons{text-align:right;clear:both}body.ttrss_main span.labelColorIndicator{height:16px;width:16px;border-radius:4px;line-height:14px;vertical-align:middle;font-size:9px;display:inline-block;border:1px solid #ccc;background-color:#fff7d5;color:#063064;text-align:center}body.ttrss_main div#cmdline{position:absolute;left:5px;bottom:5px;font-size:11px;color:#555;font-weight:bold;background-color:#fff;border:1px solid #257aa7;padding:3px 5px 3px 5px;z-index:5}body.ttrss_main #feed_browser_spinner{vertical-align:middle;height:18px;width:18px}body.ttrss_main div.fatalError{margin-bottom:10px}body.ttrss_main div.fatalError button{margin-top:5px}body.ttrss_main div.fatalError textarea{width:565px;height:200px}body.ttrss_main #header-wrap{border-width:0;margin:0;padding:0}body.ttrss_main #content-wrap{padding:0;border-width:0;margin:0}body.ttrss_main #feeds-holder{padding:0;border:0 solid #ddd;overflow:hidden;background:#f5f5f5;box-shadow:inset -1px 0 2px -1px rgba(0,0,0,0.1);-webkit-overflow-scrolling:touch}body.ttrss_main #feeds-holder #feedTree .dijitTreeRow .dijitTreeLabel.Unread{font-weight:bold}body.ttrss_main #feeds-holder #feedTree .dijitTreeRow.Error .dijitTreeLabel{color:#f00}body.ttrss_main #feeds-holder #feedTree .dijitTreeRow.UpdatesDisabled .dijitTreeLabel{color:#909090}body.ttrss_main #feeds-holder #feedTree.dijitTree .dijitTreeNode .dijitTreeRowSelected{box-shadow:-1px 0 2px -1px rgba(0,0,0,0.1);border-right-color:#fff}body.ttrss_main #feeds-holder #feedTree.dijitTree .dijitTreeContainer{max-width:100%}body.ttrss_main #feeds-holder #feedTree.dijitTree .dijitTreeRow{overflow:hidden;text-overflow:ellipsis}body.ttrss_main #feeds-holder #feedTree.dijitTree .dijitTreeNode .dijitTreeRow{padding:4px 0 4px;border-width:1px;color:#333}body.ttrss_main #feeds-holder #feedTree.dijitTree img.tinyFeedIcon{position:relative;top:-2px}body.ttrss_main #feeds-holder #feedTree{height:100%;overflow-x:hidden;text-rendering:optimizelegibility;font-family:"Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}body.ttrss_main #feeds-holder #feedTree .counterNode.aux{background:#f0f0f0;color:#999;border-color:#f0f0f0}body.ttrss_main #feeds-holder #feedTree .counterNode{font-weight:bold;display:inline-block;font-size:9px;text-align:center;border:1px solid #2a89bc;color:#fff;background:#2a89bc;border-radius:4px;vertical-align:middle;float:right;position:relative;line-height:14px;margin-right:8px;margin-top:2px;min-width:23px;height:14px}body.ttrss_main #feeds-holder #feedTree .dijitTreeNode .loadingExpando{left:-3px;height:22px;position:relative;top:-3px}body.ttrss_main #headlines-wrap-inner{padding:0;margin:0;border-width:0}body.ttrss_main #headlines-frame{padding:0;border:0 #ddd;margin-top:0;-webkit-overflow-scrolling:touch;-webkit-transform:translateZ(0);-webkit-backface-visibility:hidden}body.ttrss_main #headlines-frame div.feed-title{border:0 solid #257aa7;border-bottom-width:1px;padding:5px 3px 5px 5px}body.ttrss_main #headlines-frame div.feed-title a.title{color:#555;font-weight:bold}body.ttrss_main #headlines-frame div.feed-title a{color:#555}body.ttrss_main #headlines-frame div.feed-title a:hover{color:#257aa7}body.ttrss_main #headlines-toolbar_splitter,body.ttrss_main #toolbar_splitter{display:none}body.ttrss_main #content-insert_splitter.dijitSplitterH{background:#f0f0f0;border-color:#ddd;border-top-width:1px;border-style:solid}body.ttrss_main #toolbar{padding:0;margin:0;border-width:0;white-space:nowrap;font-size:12px}body.ttrss_main #main-toolbar{background:#fff;border:0 solid #ddd;border-bottom-width:1px;padding-left:4px;height:26px}body.ttrss_main #header{border-width:0;text-align:right;color:#555;padding:5px 5px 0 0;margin:0;position:absolute;right:0;top:0;z-index:5}body.ttrss_main #footer{text-align:center;color:#555;padding:4px 4px 8px 4px;border-width:0}body.ttrss_main #content-insert{padding:0;border-color:#ddd;border-width:0;line-height:1.5;overflow:auto;-webkit-overflow-scrolling:touch}body.ttrss_main img.feedIcon,body.ttrss_main img.tinyFeedIcon{width:16px;height:16px;line-height:16px;vertical-align:middle;display:inline-block}body.ttrss_main .player{display:inline-block;color:#555;font-size:11px;font-family:sans-serif;border:1px solid #555;padding:0 4px 0 4px;margin:0 2px 0 2px;width:50px;text-align:center;background:#fff}body.ttrss_main .player.playing{color:#00c000;border-color:#00c000}body.ttrss_main .player:hover{background:#f0f0f0;cursor:pointer}body.ttrss_main #headlines-spacer{height:100%;margin-left:1px;text-align:center;color:#555;font-size:11px;font-style:italic}body.ttrss_main #headlines-spacer a,body.ttrss_main #headlines-spacer span{color:#555;padding:10px;display:block}body.ttrss_main #headlines-spacer a:hover{color:#257aa7}body.ttrss_main ul#filterDlg_Matches,body.ttrss_main ul#filterDlg_Actions{max-height:100px;overflow:auto;list-style-type:none;border-style:solid;border-color:#ddd;border-width:0 1px 1px 1px;background-color:#fff;margin:0 0 5px 0;padding:0}body.ttrss_main ul#filterDlg_Matches li,body.ttrss_main ul#filterDlg_Actions li{cursor:pointer;padding:0 0 0 5px}body.ttrss_main ul.helpKbList{max-height:300px;overflow:auto;list-style-type:none;border:1px solid #ddd;margin:0 0 5px 0;padding:5px}body.ttrss_main ul.helpKbList span.hksequence{width:6em;margin-left:20px;color:#257aa7;font-weight:bold;display:inline-block}body.ttrss_main ul.helpKbList h2{margin-top:0}body.ttrss_main select.attachments{display:block;margin-top:10px;max-width:120px}body.ttrss_main #selected_prompt{margin-right:25px;vertical-align:middle}body.ttrss_main #filterDlg_feeds select{height:150px;width:410px}body.ttrss_main ul#filterDlg_Matches li div.dijitCheckBox,body.ttrss_main ul#filterDlg_Actions li div.dijitCheckBox{margin-right:5px}body.ttrss_main span.highlight{background-color:#ff0;color:#cc90cc}body.ttrss_main #headlines-frame .dijitCheckBox{border-width:0;opacity:.5}body.ttrss_main #headlines-frame .dijitCheckBoxHover,body.ttrss_main #headlines-frame .dijitCheckBoxChecked{opacity:1}body.ttrss_main #feedTree .dijitTreeRow img.dijitTreeExpandoLeaf{width:16px;height:16px;vertical-align:middle;position:relative}body.ttrss_main .dijitDropDownButton.attachments .dijitButtonText{font-size:12px}body.ttrss_main .dijitDropDownButton.attachments{display:inline-block}body.ttrss_main #editTagsDlg{overflow:visible}body.ttrss_main #feedEditDlg img.feedIcon{border:1px solid #ccc;padding:5px;margin:5px;max-width:20px;max-height:20px;height:auto;width:auto}body.ttrss_login{padding:2em;font-size:14px}body.ttrss_login fieldset{margin-left:auto;margin-right:auto;display:block;width:400px;border-width:0}body.ttrss_login label{width:120px;margin-right:20px;display:inline-block;text-align:right;color:#808080}body.ttrss_login div.header{border:0 solid #257aa7;border-bottom-width:1px;margin-bottom:1em;padding-bottom:5px}body.ttrss_login div.footer{margin-top:1em;padding-top:5px;border:0 solid #257aa7;border-top-width:1px;text-align:center;color:#808080;font-size:12px}body.ttrss_login a.forgotpass{text-align:right;font-size:11px;display:inline-block}body.ttrss_login a{color:#257aa7;text-decoration:none}body.ttrss_login a:hover,body.ttrss_login a:focus{color:#257aa7;text-decoration:underline}body.ttrss_login div.footer a{color:#808080}body.ttrss_login div.footer a:hover{color:#257aa7}body.ttrss_login div.row{padding:0 0 5px 0}body.ttrss_login div.row-error{color:#f00;text-align:center;padding:0 0 5px 0}::selection{background:#257aa7;color:#fff}.cdm{margin-right:4px}.cdm .header,.cdm .footer{display:table}.cdm .header img,.cdm .header input,.cdm .footer img{vertical-align:middle}.cdm .header>div,.cdm .footer>div{white-space:nowrap}.cdm .header>span,.cdm .footer>span.left{width:100%}.cdm .header img,.cdm .footer img{margin:0 4px}.cdm .header>*{display:table-cell;padding:5px}.cdm .header span.updated{color:#555;font-weight:normal;font-size:11px;white-space:nowrap;vertical-align:middle}.cdm .header input{margin-right:5px}.cdm .header div.updPic{width:25px;display:inline-block;text-align:center}.cdm .header div.updPic img{vertical-align:middle}.cdm .header input{margin-left:4px;margin-right:4px}.cdm .footer{height:30px;padding-left:5px;font-weight:normal;color:#555;clear:both}.cdm .footer>*{display:table-cell;vertical-align:middle}.cdm .intermediate{margin:10px}.cdm .content-inner{margin:10px;line-height:1.5;font-size:16px}.cdm .content-inner h1{font-size:16px}.cdm .content-inner h2,.cdm .content-inner h3,.cdm .content-inner h4{font-size:15px}.cdm .intermediate img,.cdm .intermediate video,.cdm .content-inner img,.cdm .content-inner video{border-width:0;max-width:98%;height:auto}.cdm.expanded{margin-top:4px;margin-bottom:4px}.cdm.expanded .collapse{display:none}.cdm.expanded .footer{border:0 solid #ddd;border-bottom-width:1px}.cdm.expanded>hr{margin-top:0;margin-bottom:0}div.cdm.expanded div.header{background:transparent ! important}div.cdm.expanded div.header a.title{font-size:16px;color:#999;font-weight:600;transition:color .2s,background .2s;text-rendering:optimizelegibility;font-family:"Segoe WP Semibold","Segoe UI Semibold","Segoe UI Web Semibold","Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}div.cdm.expanded.active{background:#fff}div.cdm.expanded.active div.header a.title{color:#257aa7}div.cdm.expanded.Unread div.header a.title{color:#000}div.cdm.expanded div.content{color:#555}div.cdm.expanded.Unread div.content{color:#000}div.cdm.active div.content{color:#000}.cdm div.content div.postEnclosures{margin-top:1em;color:#555}.cdm div.feed-title{border:0 solid #257aa7;border-bottom-width:1px;padding:5px 3px 5px 5px}.cdm div.feed-title a.title{color:#555;font-weight:bold}.cdm div.feed-title a{color:#555}.cdm div.feed-title a:hover{color:#257aa7}.cdm div.header span.feed{float:right;font-weight:normal;font-style:italic}.cdm div.header div.feed,.cdm div.header div.feed a{vertical-align:middle;color:#555;font-weight:normal;font-style:italic;font-size:11px}.cdm div.content-inner p{-webkit-hyphens:auto;-moz-hyphens:auto;hyphens:auto}.cdm div.content-inner iframe{min-width:50%;max-width:98%}.cdm div.header span.author{white-space:nowrap;color:#555;font-size:11px;font-weight:normal}.cdm .feed a{border-radius:4px;display:inline-block;padding:1px 4px 1px 4px}div#floatingTitle{position:absolute;z-index:5;top:0;right:0;left:0;border:0 solid #ddd;border-bottom-width:1px;background:#fff;color:#555;box-shadow:0 1px 1px -1px rgba(0,0,0,0.1)}div#floatingTitle>*{display:table-cell;white-space:nowrap;vertical-align:middle;padding:9px 5px}div#floatingTitle img{margin-right:4px;margin-left:4px}div#floatingTitle span.author{color:#555;font-size:11px;font-weight:normal}div#floatingTitle a.title{font-size:16px;color:#999;transition:color .2s,background .2s;font-weight:600;text-rendering:optimizelegibility;font-family:"Segoe WP Semibold","Segoe UI Semibold","Segoe UI Web Semibold","Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}div#floatingTitle img.anchor{margin-left:0}div#floatingTitle div.feed{padding-right:10px;color:#555;font-weight:normal;font-style:italic;font-size:11px;white-space:nowrap}div#floatingTitle div.feed a{border-radius:4px;display:inline-block;padding:1px 4px 1px 4px}div#floatingTitle span.updated{padding-right:10px;white-space:nowrap;color:#555;font-size:11px}div#floatingTitle div.feed a{color:#555}div#floatingTitle .collapse{display:none}div#floatingTitle span.titleWrap{width:100%;white-space:normal}div#floatingTitle .dijit,div#floatingTitle img.score-pic{display:none}div#floatingTitle .feed-title>*{display:table-cell;vertical-align:middle}div#floatingTitle .feed-title a.title{width:100%}div#floatingTitle .feed-title a.catchup{text-align:right;color:#555;padding-right:10px;font-size:11px;white-space:nowrap}div#floatingTitle .feed-title a.catchup:hover{color:#257aa7}div#floatingTitle.Unread a.title{color:#000}.cdm.high .header a.title.high,.cdm.high .header .excerpt,.cdm.high .header span.author{color:#0a0}.cdm.Unread.high .header a.title.high,.cdm.Unread.high .header .excerpt,.cdm.Unread.high .header span.author{color:#0d0}.cdm .header a.title.low,.cdm.low .header .excerpt,.cdm.Unread .header a.title.low,.cdm.Unread.low .header .excerpt,.cdm.low .header span.author{color:#909090;text-decoration:line-through}.cdm.expandable{background-color:#f0f0f0;border:0 solid #ddd;border-bottom-width:1px}.cdm.expandable>hr{display:none}.cdm.expandable div.header span.titleWrap{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;max-width:500px}.cdm.expandable.Unread{background:#fff}.cdm.expandable.Selected:not(.active){background:#3f728e}.cdm.expandable.Selected:not(.active) a,.cdm.expandable.Selected:not(.active) .header a.title,.cdm.expandable.Selected:not(.active) span{color:#fff}.cdm.expandable.active{background:#fff ! important}div.cdm.expandable.active div.header span.titleWrap{white-space:normal}div.cdm.expandable div.header a.title{font-weight:600;color:#555;font-size:14px;transition:color .2s,background .2s;text-rendering:optimizelegibility;font-family:"Segoe WP Semibold","Segoe UI Semibold","Segoe UI Web Semibold","Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}div.cdm.expandable.Unread div.header a.title{color:#000}div.cdm.expandable.active div.header a.title{color:#257aa7;font-size:16px;font-weight:600;text-rendering:optimizelegibility;font-family:"Segoe WP Semibold","Segoe UI Semibold","Segoe UI Web Semibold","Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}div.cdm.expandable:not(.active){cursor:pointer}div.cdm.expandable:not(.active) .content,div.cdm.expandable:not(.active) .collapse{display:none}body.ttrss_prefs{background-color:#f5f5f5}body.ttrss_prefs #footer,body.ttrss_prefs #header{background-color:#f5f5f5;padding-left:8px;padding-right:8px}body.ttrss_prefs #header a:hover{color:#000}body.ttrss_prefs #header img{vertical-align:middle;cursor:pointer}body.ttrss_prefs div#pref-tabs .dijitContentPane{font-size:13px}body.ttrss_prefs div#pref-tabs{box-shadow:0 1px 1px -1px rgba(0,0,0,0.1);margin:0 5px 0 5px}body.ttrss_prefs div#pref-tabs .dijitContentPane h3{font-size:14px}body.ttrss_prefs #pref-filter-wrap,body.ttrss_prefs #pref-filter-header,body.ttrss_prefs #pref-filter-content,body.ttrss_prefs #pref-label-wrap,body.ttrss_prefs #pref-label-header,body.ttrss_prefs #pref-label-content,body.ttrss_prefs #pref-user-wrap,body.ttrss_prefs #pref-user-header,body.ttrss_prefs #pref-user-content,body.ttrss_prefs #pref-instance-wrap,body.ttrss_prefs #pref-instance-header,body.ttrss_prefs #pref-instance-content{margin:0;padding:0;border-width:0}body.ttrss_prefs #userConfigTab,body.ttrss_prefs #labelConfigTab,body.ttrss_prefs #filterConfigTab,body.ttrss_prefs #pref-feeds-feeds,body.ttrss_prefs #instanceConfigTab{padding:0}body.ttrss_prefs table.prefPrefsList h3{margin-top:.5em;margin-bottom:0}body.ttrss_prefs tr.title td{border:0 solid #ecf4ff;border-bottom-width:1px;color:#257aa7}body.ttrss_prefs div.prefProfileHolder,body.ttrss_prefs div.prefFeedOPMLHolder,body.ttrss_prefs div.inactiveFeedHolder{height:300px;overflow:auto;border:1px solid #ddd;border-top-width:0;margin:0 0 5px 0;background-color:#fff}body.ttrss_prefs div.filterTestHolder,body.ttrss_prefs div.prefFeedOPMLHolder{border-width:1px}body.ttrss_prefs ul.userFeedList{height:200px;overflow:auto;list-style-type:none;border:1px solid #ddd;margin:0 0 5px 0;padding:5px}body.ttrss_prefs div#feedlistLoading,body.ttrss_prefs div#filterlistLoading,body.ttrss_prefs div#labellistLoading{text-align:center;padding:5px;color:#555}body.ttrss_prefs div#feedlistLoading img,body.ttrss_prefs div#filterlistLoading img,body.ttrss_prefs div#labellistLoading{margin-right:5px}body.ttrss_prefs #errorButton{color:#f00}body.ttrss_prefs table.prefPluginsList td label,body.ttrss_prefs table.prefUserList td{cursor:pointer}body.ttrss_prefs table.prefPluginsList label{white-space:nowrap}body.ttrss_prefs table.prefPluginsList label img{vertical-align:middle}body.ttrss_prefs table.prefErrorLog tr.errrow td{font-size:10px}body.ttrss_prefs table.prefErrorLog tr.errrow td.errno{font-style:italic;font-weight:bold;white-space:nowrap}body.ttrss_prefs table.prefErrorLog td.filename,body.ttrss_prefs table.prefErrorLog td.login,body.ttrss_prefs table.prefErrorLog td.timestamp{color:#555}body.ttrss_prefs hr{border-color:#ecf4ff;max-width:100%}.claro .dijitTreeRow .dijitCheckBox{position:relative;top:-2px}.claro .dijitTreeLabel{outline:0}.claro .dijitTree .feedParam{color:#555;float:right;margin-right:1em}.claro .dijitTree .filterRules{display:block;color:#ccc;font-size:10px;margin-left:100px}.claro .dijitTree .filterRules span{display:block;color:#008000}.claro #filterDlg_Matches span.filterRule{color:#008000}.claro .dijitTree .filterRules span.inverse,.claro #filterDlg_Matches span.filterRule.inverse{color:#f00}.claro .dijitTree .labelParam{float:right;margin-right:1em}.claro .dijitTree .dijitTreeLabel.filterDisabled,.claro .dijitTree .labelParam.filterDisabled{color:#555;text-decoration:line-through}.claro .dijitTreeRow.Error{color:#f00}.claro .dijitTreeRow.Hidden{display:none}.claro .dijitTreeNode .loadingNode{margin-left:3px;height:9px}.claro .dijitFolderClosed,.claro .dijitFolderOpened{display:none}.claro .dijitTreeNode .dijitCheckBox{margin-left:4px}.claro .dijitTreeIsRoot>.dijitTreeRow>.dijitTreeExpando{margin-left:5px}.claro .dijitTree .dijitTreeExpando{margin-top:0;opacity:.6}.claro .dijitTree .dijitTreeNode{padding:0;border-width:0}.claro .dijitTree .dijitTreeRowSelected{background:#fff}.claro .dijitTree .dijitTreeRowHover{background:#f0f0f0;border-color:#ddd}.claro .dijitTree .dijitTreeRowSelected{background:#fff;border-color:#ddd}.claro .dijitTreeRowSelected .dijitTreeLabel{text-shadow:1px 1px 2px #fff}.claro .dijitTreeRow .dijitTreeExpando{background-image:url("../images/treeExpandImages.png");position:relative;top:-1px}.claro .dijitTreeRow .dijitTreeExpandoLeaf{background:none}.claro .dijitToolbar{background:#f5f5f5;border-color:#ddd}.claro .dijitDialog .dijitToolbar{border:1px solid #ddd}.claro .dijitDialog h2{margin-top:0;margin-bottom:4px;border-width:0}.claro .dijitMenu .dijitMenuItem .dijitMenuItemLabel{font-size:13px;padding-top:3px;padding-bottom:3px}.claro .dijitCheckBox{background-image:url("../images/untick.png");background-color:transparent;width:15px;height:15px;margin:1px;opacity:.7;background-position:center center;transition:opacity .25s;-webkit-transition:opacity .25s;padding:1px}.claro .dijitCheckBox:hover{opacity:1}.claro .dijitCheckBox.dijitCheckBoxDisabled:hover{opacity:.7}.claro .dijitCheckBox.dijitCheckBoxChecked{border-color:#69c671;background-image:url("../images/tick.png");opacity:1}.claro .dijitButton.btn-danger .dijitButtonText{color:#fff}.claro .dijitButton.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top, #ee5f5b, #bd362f);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));background-image:-webkit-linear-gradient(top, #ee5f5b, #bd362f);background-image:-o-linear-gradient(top, #ee5f5b, #bd362f);background-image:linear-gradient(to bottom, #ee5f5b, #bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.claro .dijitButton.dijitButtonDisabled.btn-danger,.claro .dijitButton.dijitButtonActive.btn-danger,.claro .dijitButton.dijitButtonHover.btn-danger,.claro .dijitButton.dijitFocused.btn-danger{color:#fff;background-color:#bd362f;*background-color:#a9302a}.claro .dijitButton.dijitButtonActive.btn-danger{background-color:#942a25 \9}.claro .dijitButton.dijitButtonActive.btn-danger{color:rgba(255,255,255,0.75)}.claro .dijitButton.btn-primary .dijitButtonText{color:#fff}.claro .dijitButton.btn-primary{text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#2883b3;*background-color:#257aa7;background-image:-moz-linear-gradient(top, #4ba6d8, #257aa7);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#4ba6d8), to(#257aa7));background-image:-webkit-linear-gradient(top, #4ba6d8, #257aa7);background-image:-o-linear-gradient(top, #4ba6d8, #257aa7);background-image:linear-gradient(to bottom, #4ba6d8, #257aa7);background-repeat:repeat-x;border-color:#257aa7 #257aa7 #1d5f82;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25)}.claro .dijitButton.dijitButtonDisabled.btn-primary,.claro .dijitButton.dijitButtonActive.btn-primary,.claro .dijitButton.dijitButtonHover.btn-primary,.claro .dijitButton.dijitFocused.btn-primary{color:#fff;background-color:#257aa7;*background-color:#1d6185}.claro .dijitButton.dijitButtonActive.btn-primary{background-color:#1f678d \9}.claro .dijitButton.dijitButtonActive.btn-primary{color:rgba(255,255,255,0.75)}.claro .dijitDropDownButton{margin:0}.claro .dijitDropDownButton .dijitButtonNode{padding:0}.claro .dijitButton .dijitButtonNode,.claro .dijitDropDownButton .dijitButtonNode,.claro .dijitComboButton .dijitButtonNode,.claro .dijitToolbar .dijitDropDownButton .dijitButtonNode,.claro .dijitToolbar .dijitComboButton,.claro .dijitToolbar .dijitSelect.dijitDownArrowButton .dijitButtonNode,.claro .dijitToolbar .dijitComboButton .dijitButtonNode{background:none;border-color:transparent;box-shadow:none}.claro button,.claro input[type="submit"]{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px}.claro button,.claro input[type="submit"],.claro .dijitButton,.claro .dijitDropDownButton .dijitDownArrowButton,.claro .dijitComboButton{display:inline-block;padding:4px 12px;margin-bottom:0;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;background-image:-moz-linear-gradient(top, #fff, #e6e6e6);background-image:-webkit-linear-gradient(top, #fff, #e6e6e6);background-image:linear-gradient(to bottom, #fff, #e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#b3b3b3;-webkit-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.claro button:hover,.claro button:focus,.claro button:active,.claro input[type="submit"]:hover,.claro input[type="submit"]:focus,.claro input[type="submit"]:active,.claro .dijitButton:hover,.claro .dijitButton:focus,.claro .dijitButton:active,.claro .dijitDropDownButton .dijitDownArrowButton:hover,.claro .dijitDropDownButton .dijitDownArrowButton:focus,.claro .dijitDropDownButton .dijitDownArrowButton:active,.claro .dijitComboButton:hover,.claro .dijitComboButton:focus,.claro .dijitComboButton:active,.claro .dijitButton.dijitButtonDisabled{color:#333;background-color:#e6e6e6}.claro button:active,.claro input[type="submit"]:active,.claro .dijitButton:active,.claro .dijitDropDownButton .dijitDownArrowButton:active,.claro .dijitComboButton:active{background-color:#cccccc \9}.claro .dijitToolbar .dijitButton,.claro .dijitToolbar .dijitButton.dijitHover,.claro .dijitToolbar .dijitComboButton,.claro .dijitToolbar .dijitDropDownButton .dijitDownArrowButton,.claro .dijitToolbar .dijitComboButton.dijitHover{background:none;border-color:transparent;box-shadow:none;padding:0;margin:0;line-height:auto;text-shadow:none}.claro .dijitToolbar .dijitDropDownButton .dijitButtonText,.claro .dijitToolbar .dijitDownArrowButton .dijitButtonText,.claro .dijitToolbar .dijitComboButton .dijitButtonText{padding:0}.claro .dijitToolbar .dijitDropDownButton .dijitButtonNode{border-radius:4px}.claro .dijitToolbar .dijitButton.dijitHover,.claro .dijitToolbar .dijitDropDownButton.dijitHover .dijitButtonNode,.claro .dijitToolbar .dijitComboButton.dijitHover{border-color:#ccc}.claro .dijitToolbar .dijitButton.dijitHover .dijitButtonNode,.claro .dijitToolbar .dijitButton.dijitButtonActive .dijitButtonNode{background:none}.claro .dijitToolbar .dijitButton .dijitButtonContents,.claro .dijitToolbar .dijitDropDownButton .dijitButtonContents,.claro .dijitToolbar .dijitComboButton .dijitButtonContents{font-size:13px}.claro button:hover,.claro button:focus,.claro input[type="submit"]:hover,.claro input[type="submit"]:focus,.claro .dijitButton:hover,.claro .dijitDropDownButton .dijitDownArrowButton:hover,.claro .dijitToolbar .dijitButton:hover .dijitButtonNode,.claro .dijitToolbar .dijitButton.dijitHover .dijitButtonNode,.claro .dijitButton:focus,.claro .dijitComboButton:hover,.claro .dijitComboButton:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;transition:background-position .1s linear}.claro button:focus,.claro input[type="submit"]:focus,.claro .dijitButton:focus,.claro .dijitDropDownButton .dijitDownArrowButton:focus,.claro .dijitComboButton:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.claro button:active,.claro input[type="submit"]:active,.claro .dijitButton:active,.claro .dijitComboButton:active,.claro .dijitToolbar .dijitDropDownButton.dijitOpened,.claro .dijitToolbar .dijitComboButton.dijitOpened,.claro .dijitToolbar .dijitButton.dijitButtonActive .dijitButtonNode{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.claro input[type="submit"][disabled],.claro button[disabled],.claro .dijitButton[disabled],.claro .dijitDropDownButton .dijitDownArrowButton[disabled],.claro .dijitButton.dijitButtonDisabled,.claro .dijitComboButton.dijitButtonDisabled{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.claro .dijitButton .dijitButtonContents,.claro .dijitDropDownButton .dijitButtonContents,.claro .dijitComboButton .dijitButtonContents{font-size:14px;font-weight:normal;line-height:20px}.claro .dijitButton.small .dijitButtonText{font-size:11px}.claro .dijitMenu{border-color:#257aa7}.claro .dijitMenu .dijitMenuItemSelected,.claro .dijitMenu .dijitMenuItemSelected td{background:#257aa7;color:#fff;border-color:#257aa7}.claro .dijitButton .dijitButtonNode,.claro .dijitComboButton .dijitButtonNode{padding:0}.claro .dijitAccordionTitle.dijitAccordionTitleHover,.claro .dijitAccordionTitle.dijitAccordionTitleFocused{background:#fff;transition:background .25s}.claro .dijitAccordionTitle{background:#f0f0f0;transition:background .25s}.claro .dijitAccordionInnerContainer.dijitAccordionInnerContainerSelected,.claro .dijitAccordionTitle.dijitAccordionTitleSelected{background:#257aa7;transition:background .25s}.claro .dijitAccordionTitle.dijitAccordionTitleSelected .dijitAccordionText{color:#fff}.claro .dijitAccordionInnerContainer.dijitAccordionInnerContainerSelected{border-color:#257aa7}.claro .dijitAccordionContainer .dijitAccordionChildWrapper{border-color:#ddd}.claro .dijitTabInner.dijitTab{background:#f0f0f0}.claro .dijitTabContent{background:#eee}.claro .dijitTabContent.dijitTabChecked,.claro .dijitTabContent.dijitTabHover,.claro .dijitTabContent.dijitFocused{background:#fff}.claro .dijitTabPaneWrapper,.claro .dijitTabContainerTop-tabs,.claro .dijitTab,.claro .dijitAccordionInnerContainer{border-color:#ddd}.claro .dijitComboBox .dijitArrowButton,.claro .dijitSelect .dijitArrowButton{background:transparent;border-color:transparent}.claro .dijitSelect .dijitArrowButton .dijitArrowButtonInner{margin-right:5px;float:right}.claro select,.claro .dijitDownArrowButton.dijitSelect{-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;margin-bottom:4px}.claro .dijitSelect .dijitButtonContents{display:inline-block;height:20px;padding:4px 6px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;border-width:0}.claro select,.claro textarea,.claro .input.input-text,.claro .dijitTextBox{display:inline-block;height:20px;padding:4px 6px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;margin-bottom:4px}.claro textarea{height:auto}.claro select,.claro .input.input-text{height:30px}.claro textarea,.claro select,.claro .input.input-text,.claro .dijitTextBox,.claro .dijitSelect{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}.claro select:focus,.claro .input.input-text:focus,.claro .dijitTextBox.dijitFocused,.claro .dijitSelect.dijitFocused{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(37,122,167,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(37,122,167,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(37,122,167,0.6)}.claro .dijitError .dijitValidationContainer{padding:0;width:13px;border-width:1px;display:none}.claro .dijitSelect.dijitSelectDisabled{background-color:#eee}.claro .dijitSelect.dijitSelectDisabled .dijitSelectLabel{cursor:not-allowed}.claro .dijitTextBox.dijitTextBoxDisabled,.claro .dijitTextBox.dijitTextBoxDisabled .dijitInputInner,.claro .dijitTextBox.dijitReadOnly,.claro .dijitTextBox.dijitReadOnly .dijitInputInner{cursor:not-allowed;background-color:#eee}.claro .dijitToolbar .dijitDownArrowButton.dijitSelect{border-color:rgba(0,0,0,0.1)}.claro .dijitToolbar .dijitDownArrowButton.dijitSelect .dijitButtonContents{padding:2px 2px 0 4px}.claro .dijitToolbar .dijitDownArrowButton.dijitSelect{margin:0}.claro .dijitToolbar .dijitTextBox{padding:0;margin-bottom:0;border-radius:0}.claro .dijitDialog{border-radius:6px}.claro .dijitDialog .dijitDialogCloseIcon{margin-top:5px}.claro .dijitDialog .dijitDialogTitleBar{background:#fff;padding:8px;font-weight:600;color:#555;font-size:16px;text-rendering:optimizelegibility;font-family:"Segoe WP Semibold","Segoe UI Semibold","Segoe UI Web Semibold","Segoe UI",Ubuntu,"Helvetica Neue",Helvetica,Arial,sans-serif}.claro .dijitDialog .dijitDialogPaneContent{border-color:#ddd;padding:10px}.claro .dijitProgressBar.dijitProgressBarEmpty{background:#ddd;border-color:#257aa7}.claro .dijitProgressBar.dijitProgressBarEmpty .dijitProgressBarFull .dijitProgressBarTile{background:#257aa7}.claro .dijitProgressBar .dijitProgressBarLabel{color:#fff}body.ttrss_utility.sanity_failed{background:#900}body.ttrss_utility{background:#f5f5f5;color:#000;padding:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;margin-left:auto;margin-right:auto;max-width:800px}body.ttrss_utility form{margin:10px 0 0 0;padding:0}body.ttrss_utility div.content{overflow:hidden;background:#fff;border:1px solid #ddd;padding:10px;border-radius:6px;box-shadow:0 1px 1px -1px rgba(0,0,0,0.1)}body.ttrss_utility p.warning{color:#f00}body.ttrss_utility p.query,body.ttrss_utility code{color:#008000}body.ttrss_utility p.insensitive{color:#808080}body.ttrss_utility div.insensitive-small{color:#808080;font-size:10px}body.ttrss_utility .floatingLogo{display:none}body.ttrss_utility a{color:#257aa7;text-decoration:none}body.ttrss_utility a:hover,body.ttrss_utility a:focus{color:#133d54;text-decoration:underline}body.ttrss_utility .alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}body.ttrss_utility .alert,body.ttrss_utility .alert h4{color:#c09853}body.ttrss_utility .alert h4{margin:0}body.ttrss_utility .alert .close{position:relative;top:-2px;right:-21px;line-height:20px;cursor:pointer}body.ttrss_utility .alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}body.ttrss_utility .alert-success h4{color:#468847}body.ttrss_utility .alert-danger,body.ttrss_utility .alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}body.ttrss_utility .alert-danger h4,body.ttrss_utility .alert-error h4{color:#b94a48}body.ttrss_utility .alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}body.ttrss_utility .alert-info h4{color:#3a87ad}body.ttrss_utility h1{color:#257aa7;font-size:32px;margin:20px 0 5px 0;text-shadow:0 0 6px #fff}body.ttrss_utility h2{color:#257aa7;font-size:14pt;border-width:0 0 1px 0;border-color:#f0f0f0;border-style:solid}body.ttrss_utility div.content>h2{margin-top:0}body.ttrss_utility div.rss h1{border-width:0 0 1px 0;border-color:#808080;border-style:dotted;color:#808080}body.ttrss_utility div.rss h2{font-size:12pt}body.ttrss_utility div.rss a.extlink{color:#808080;border-width:0 0 1px 0;border-color:#789;border-style:dotted;font-size:9pt}body.ttrss_utility div.rss img{max-width:775px}body.ttrss_utility div.rss p.description{color:#808080;font-size:9pt}body.ttrss_utility div.rss div.content{margin-top:.5em}body.ttrss_utility div.rss img.feedicon{float:right}body.ttrss_utility div.rss hr{border-width:0 0 1px 0;border-style:dashed;border-color:#e0e0e0}body.ttrss_utility div.autocomplete{position:absolute;width:250px;background-color:#fff;border:1px solid #789;margin:0;padding:0;z-index:4}body.ttrss_utility div.autocomplete ul{list-style-type:none;margin:0;padding:0;font-size:10px}body.ttrss_utility div.autocomplete ul li.selected{background-color:#fff7d5}body.ttrss_utility div.autocomplete ul li{list-style-type:none;display:block;margin:0;padding:2px;height:32px;cursor:pointer}body.ttrss_utility fieldset{border-width:0;padding:0 0 5px 0;margin:0}body.ttrss_utility fieldset input{font-family:sans-serif;font-size:medium;border-spacing:2px;border:1px solid #b5bcc7;padding:2px}body.ttrss_utility fieldset label{width:120px;margin-right:20px;display:inline-block;text-align:right;color:#808080}body.ttrss_utility body.otp{margin:1em;padding:0}body.ttrss_utility form.otpform{margin:0;padding:0}body.ttrss_utility form.otpform label{margin:0;padding:0}body.ttrss_utility body.otp div.content{display:inline-block;width:auto}body.ttrss_utility span.hint{font-size:10px;color:#808080}body.small_margins{margin:1em;max-width:none}body#sharepopup{background:#fff url("../images/toolbar.png") repeat-x bottom;margin:10px;padding:0}body#sharepopup h1{font-size:14px;margin:0;color:#257aa7}body#sharepopup table{background:#fff;border:1px solid #257aa7;padding:5px}body#sharepopup form{height:100%}body#sharepopup input{width:100%}body.ttrss_zoom{margin-left:auto;margin-right:auto;padding:20px;max-width:800px;background:#f5f5f5}body.ttrss_zoom div.post{border:1px solid #ddd;background:#fff;box-shadow:0 1px 1px -1px rgba(0,0,0,0.1)}body.ttrss_zoom div.post div.header{margin:10px;padding-bottom:10px;border:0 solid #eee;border-bottom-width:1px;background:#fff;font-size:12px;color:#555}body.ttrss_zoom div.post div.header .author{font-size:11px}body.ttrss_zoom div.post div.header div.feed-title{float:left;text-align:right}body.ttrss_zoom div.post div.header a.comments{text-align:right}body.ttrss_zoom div.post div.header div.date{float:none;text-align:right;margin-bottom:5px}body.ttrss_zoom div.post div.header div.tags img{vertical-align:middle}body.ttrss_zoom div.post div.header div.title{white-space:normal;font-size:16px;margin-bottom:5px}body.ttrss_zoom div.post p{-webkit-hyphens:auto;-moz-hyphens:auto;hyphens:auto}body.ttrss_zoom div.post div.footer{margin-top:1em;text-align:center}body.ttrss_zoom div.post div.content{font-size:15px;line-height:1.5;padding:10px;border-width:0}body.ttrss_zoom div.post div.content img,body.ttrss_zoom div.post div.content video{max-width:760px;height:auto}body.ttrss_zoom div.post div.content blockquote{margin:5px 0 5px 0;color:#555;padding-left:10px;border:0 solid #ccc;border-left-width:4px}body.ttrss_zoom div.post div.content code{color:#090;font-family:monospace;font-size:12px}body.ttrss_zoom div.post div.content pre{margin:5px 0 5px 0;padding:10px;color:#555;font-family:monospace;font-size:12px;border:0 solid #ccc;background:#f5f5f5;display:block;max-width:98%;overflow:auto} \ No newline at end of file diff --git a/css/tt-rss.less b/css/tt-rss.less index 467a85622..fbda70747 100755 --- a/css/tt-rss.less +++ b/css/tt-rss.less @@ -910,6 +910,25 @@ body.ttrss_main { -webkit-overflow-scrolling : touch; -webkit-transform: translateZ(0); -webkit-backface-visibility: hidden; + + div.feed-title { + border: 0px solid @color-link; + border-bottom-width: 1px; + padding: 5px 3px 5px 5px; + } + + div.feed-title a.title { + color: @default-text; + font-weight: bold; + } + + div.feed-title a { + color: @default-text; + } + + div.feed-title a:hover { + color: @color-link; + } } #headlines-toolbar_splitter, #toolbar_splitter { -- cgit v1.2.3-54-g00ecf From cc26be0793c6c0e44a540c25f86627342a82714f Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Sat, 1 Dec 2018 21:51:00 +0300 Subject: migrate tt-rss.js contents to App --- classes/dlg.php | 2 +- classes/feeds.php | 4 +- index.php | 20 +- js/feedlist.js | 9 +- js/functions.js | 14 +- js/prefs.js | 11 +- js/tt-rss.js | 622 +++++++++++++++++++++++++++--------------------------- js/viewfeed.js | 582 +++++++++++++++++++++++++------------------------- 8 files changed, 620 insertions(+), 644 deletions(-) (limited to 'classes') diff --git a/classes/dlg.php b/classes/dlg.php index d73a53618..50cbd12dd 100644 --- a/classes/dlg.php +++ b/classes/dlg.php @@ -190,7 +190,7 @@ class Dlg extends Handler_Protected { print_warning(__("You are using default tt-rss password. Please change it in the Preferences (Personal data / Authentication).")); print "
"; - print " "; print " "; print " -- cgit v1.2.3-54-g00ecf From 2f85b50e3607b2b159989c493ac8f8c46a389559 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Sun, 2 Dec 2018 10:16:25 +0300 Subject: remove toggleSelectListRow2() --- classes/pref/filters.php | 4 ++-- include/feedbrowser.php | 8 ++------ js/functions.js | 19 +++++++++++-------- 3 files changed, 15 insertions(+), 16 deletions(-) (limited to 'classes') diff --git a/classes/pref/filters.php b/classes/pref/filters.php index e60628f8f..e48615395 100755 --- a/classes/pref/filters.php +++ b/classes/pref/filters.php @@ -429,7 +429,7 @@ class Pref_Filters extends Handler_Protected { $data = htmlspecialchars(json_encode($line)); - print "
  • ". + print "
  • ". "".$this->getRuleName($line)."". "
  • "; } @@ -473,7 +473,7 @@ class Pref_Filters extends Handler_Protected { $data = htmlspecialchars(json_encode($line)); - print "
  • ". + print "
  • ". "".$this->getActionName($line)."". "
  • "; } diff --git a/include/feedbrowser.php b/include/feedbrowser.php index 8ebeb20cc..a0b1b6e8f 100644 --- a/include/feedbrowser.php +++ b/include/feedbrowser.php @@ -53,12 +53,10 @@ $site_url = htmlspecialchars($line["site_url"]); $subscribers = $line["subscribers"]; - $check_box = ""; - $class = ($feedctr % 2) ? "even" : "odd"; - $site_url = " ". @@ -75,11 +73,9 @@ $feed_url = htmlspecialchars($line["feed_url"]); $site_url = htmlspecialchars($line["site_url"]); - $check_box = ""; - $class = ($feedctr % 2) ? "even" : "odd"; - if ($line['articles_archived'] > 0) { $archived = sprintf(_ngettext("%d archived article", "%d archived articles", (int) $line['articles_archived']), $line['articles_archived']); $archived = " ($archived)"; diff --git a/js/functions.js b/js/functions.js index 59912905d..ce6d7aca9 100755 --- a/js/functions.js +++ b/js/functions.js @@ -53,6 +53,15 @@ Array.prototype.remove = function(s) { } }; +const ListUtils = { + onChecked: function(elem) { + // account for dojo checkboxes + elem = elem.domNode || elem; + + elem.up("li").toggleClassName("Selected"); + } +}; + const Utils = { _rpc_seq: 0, hotkey_prefix: 0, @@ -984,12 +993,6 @@ function toggleSelectRowById(sender, id) { return toggleSelectRow(sender, row); } -/* this is for dijit Checkbox */ -function toggleSelectListRow2(sender) { - const row = sender.domNode.parentNode; - return toggleSelectRow(sender, row); -} - /* this is for dijit Checkbox */ function toggleSelectRow2(sender, row, is_cdm) { @@ -1137,7 +1140,7 @@ const Filters = { new dijit.form.CheckBox({ onChange: function () { - this.domNode.up("li").toggleClassName("Selected"); + ListUtils.onChecked(this); }, }, cb); @@ -1186,7 +1189,7 @@ const Filters = { new dijit.form.CheckBox({ onChange: function () { - this.domNode.up("li").toggleClassName("Selected"); + ListUtils.onChecked(this); }, }, cb); -- cgit v1.2.3-54-g00ecf From 874560db547f718b82d77657dc019d840c30e0ed Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Sun, 2 Dec 2018 10:33:58 +0300 Subject: remove obsolete row selection functions move getUrlParam() to Utils --- classes/feeds.php | 4 ++-- classes/pref/feeds.php | 4 ++-- classes/pref/filters.php | 4 ++-- classes/pref/prefs.php | 6 ++--- classes/pref/users.php | 2 +- include/feedbrowser.php | 4 ++-- include/functions.php | 2 +- js/functions.js | 61 +++++++++++++----------------------------------- js/prefs.js | 6 ++--- js/tt-rss.js | 2 +- js/viewfeed.js | 8 +++++++ 11 files changed, 41 insertions(+), 62 deletions(-) (limited to 'classes') diff --git a/classes/feeds.php b/classes/feeds.php index c9e5ca496..b32521130 100755 --- a/classes/feeds.php +++ b/classes/feeds.php @@ -406,7 +406,7 @@ class Feeds extends Handler_Protected { $reply['content'] .= "
    "; $reply['content'] .= ""; $reply['content'] .= "$marked_pic"; @@ -505,7 +505,7 @@ class Feeds extends Handler_Protected { $tmp_content .= "
    "; $tmp_content .= ""; $tmp_content .= "$marked_pic"; diff --git a/classes/pref/feeds.php b/classes/pref/feeds.php index f47d24501..efc76701e 100755 --- a/classes/pref/feeds.php +++ b/classes/pref/feeds.php @@ -1435,7 +1435,7 @@ class Pref_Feeds extends Handler_Protected { # id needed for selectTableRows() print ""; print ""; @@ -1500,7 +1500,7 @@ class Pref_Feeds extends Handler_Protected { # id needed for selectTableRows() print ""; print ""; diff --git a/classes/pref/filters.php b/classes/pref/filters.php index e48615395..f9b4bfb2a 100755 --- a/classes/pref/filters.php +++ b/classes/pref/filters.php @@ -429,7 +429,7 @@ class Pref_Filters extends Handler_Protected { $data = htmlspecialchars(json_encode($line)); - print "
  • ". + print "
  • ". "".$this->getRuleName($line)."". "
  • "; } @@ -473,7 +473,7 @@ class Pref_Filters extends Handler_Protected { $data = htmlspecialchars(json_encode($line)); - print "
  • ". + print "
  • ". "".$this->getActionName($line)."". "
  • "; } diff --git a/classes/pref/prefs.php b/classes/pref/prefs.php index 82456f342..017f2e06c 100644 --- a/classes/pref/prefs.php +++ b/classes/pref/prefs.php @@ -799,7 +799,7 @@ class Pref_Prefs extends Handler_Protected { $plugin_icon = $checked ? "plugin.png" : "plugin_disabled.png"; - print ""; @@ -1023,7 +1023,7 @@ class Pref_Prefs extends Handler_Protected { print ""; @@ -1050,7 +1050,7 @@ class Pref_Prefs extends Handler_Protected { $edit_title = htmlspecialchars($line["title"]); print ""; diff --git a/classes/pref/users.php b/classes/pref/users.php index 1e6eae227..eda3e1a0e 100644 --- a/classes/pref/users.php +++ b/classes/pref/users.php @@ -419,7 +419,7 @@ class Pref_Users extends Handler_Protected { $line["created"] = make_local_datetime($line["created"], false); $line["last_login"] = make_local_datetime($line["last_login"], false); - print ""; diff --git a/include/feedbrowser.php b/include/feedbrowser.php index a0b1b6e8f..4f37241ea 100644 --- a/include/feedbrowser.php +++ b/include/feedbrowser.php @@ -53,7 +53,7 @@ $site_url = htmlspecialchars($line["site_url"]); $subscribers = $line["subscribers"]; - $check_box = ""; @@ -73,7 +73,7 @@ $feed_url = htmlspecialchars($line["feed_url"]); $site_url = htmlspecialchars($line["site_url"]); - $check_box = ""; if ($line['articles_archived'] > 0) { diff --git a/include/functions.php b/include/functions.php index f6d09fe67..2ec42c7ee 100755 --- a/include/functions.php +++ b/include/functions.php @@ -1244,7 +1244,7 @@ "g t" => "goto_tagcloud", "g *p" => "goto_prefs", // "other" => array( - "(9)|Tab" => "select_article_cursor", // tab + "r" => "select_article_cursor", "c l" => "create_label", "c f" => "create_filter", "c s" => "collapse_sidebar", diff --git a/js/functions.js b/js/functions.js index ce6d7aca9..033933794 100755 --- a/js/functions.js +++ b/js/functions.js @@ -53,8 +53,8 @@ Array.prototype.remove = function(s) { } }; -const ListUtils = { - onChecked: function(elem) { +const Lists = { + onRowChecked: function(elem) { // account for dojo checkboxes elem = elem.domNode || elem; @@ -62,11 +62,23 @@ const ListUtils = { } }; +const Tables = { + onRowChecked: function(elem) { + // account for dojo checkboxes + elem = elem.domNode || elem; + + elem.up("tr").toggleClassName("Selected"); + } +} + const Utils = { _rpc_seq: 0, hotkey_prefix: 0, hotkey_prefix_pressed: false, hotkey_prefix_timeout: 0, + urlParam: function(param) { + return String(window.location.href).parseQuery()[param]; + }, next_seq: function() { this._rpc_seq += 1; return this._rpc_seq; @@ -988,43 +1000,6 @@ function getCookie(name) { return unescape(dc.substring(begin + prefix.length, end)); } -function toggleSelectRowById(sender, id) { - const row = $(id); - return toggleSelectRow(sender, row); -} - -/* this is for dijit Checkbox */ -function toggleSelectRow2(sender, row, is_cdm) { - - if (!row) - if (!is_cdm) - row = sender.domNode.parentNode.parentNode; - else - row = sender.domNode.parentNode.parentNode.parentNode; // oh ffs - - if (sender.checked && !row.hasClassName('Selected')) - row.addClassName('Selected'); - else - row.removeClassName('Selected'); - - if (typeof Headlines != "undefined") - Headlines.updateSelectedPrompt(); -} - - -function toggleSelectRow(sender, row) { - - if (!row) row = sender.parentNode.parentNode; - - if (sender.checked && !row.hasClassName('Selected')) - row.addClassName('Selected'); - else - row.removeClassName('Selected'); - - if (typeof Headlines != "undefined") - Headlines.updateSelectedPrompt(); -} - // noinspection JSUnusedGlobalSymbols function displayIfChecked(checkbox, elemId) { if (checkbox.checked) { @@ -1034,10 +1009,6 @@ function displayIfChecked(checkbox, elemId) { } } -function getURLParam(param){ - return String(window.location.href).parseQuery()[param]; -} - // noinspection JSUnusedGlobalSymbols function closeInfoBox() { const dialog = dijit.byId("infoBox"); @@ -1140,7 +1111,7 @@ const Filters = { new dijit.form.CheckBox({ onChange: function () { - ListUtils.onChecked(this); + Lists.onRowChecked(this); }, }, cb); @@ -1189,7 +1160,7 @@ const Filters = { new dijit.form.CheckBox({ onChange: function () { - ListUtils.onChecked(this); + Lists.onRowChecked(this); }, }, cb); diff --git a/js/prefs.js b/js/prefs.js index 40068b95c..f12c31441 100755 --- a/js/prefs.js +++ b/js/prefs.js @@ -69,17 +69,17 @@ const App = { Utils.setLoadingProgress(50); notify(""); - let tab = getURLParam('tab'); + let tab = Utils.urlParam('tab'); if (tab) { tab = dijit.byId(tab + "Tab"); if (tab) dijit.byId("pref-tabs").selectChild(tab); } - const method = getURLParam('method'); + const method = Utils.urlParam('method'); if (method == 'editFeed') { - const param = getURLParam('methodparam'); + const param = Utils.urlParam('methodparam'); window.setTimeout(function () { CommonDialogs.editFeed(param) diff --git a/js/tt-rss.js b/js/tt-rss.js index b337e0ae5..71bb2337a 100644 --- a/js/tt-rss.js +++ b/js/tt-rss.js @@ -414,7 +414,7 @@ const App = { if (!row.hasClassName("active")) cb.attr("checked", !cb.attr("checked")); - toggleSelectRowById(cb, "RROW-" + id); + Headlines.onRowChecked(cb); return false; } } diff --git a/js/viewfeed.js b/js/viewfeed.js index 93bc56c9d..e7703ed55 100755 --- a/js/viewfeed.js +++ b/js/viewfeed.js @@ -1109,6 +1109,14 @@ const Headlines = { return rv; }, + onRowChecked: function(elem) { + // account for dojo checkboxes + elem = elem.domNode || elem; + + elem.up("div[id*=RROW]").toggleClassName("Selected"); + + this.updateSelectedPrompt(); + }, select: function(mode) { // mode = all,none,unread,invert,marked,published let query = "#headlines-frame > div[id*=RROW]"; -- cgit v1.2.3-54-g00ecf From e23b6e397dbbbba90f9a15a6fe2d45eb862efdc5 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Sun, 2 Dec 2018 11:25:32 +0300 Subject: prefs: store active tab for reload, remove most old table row functions --- classes/pref/feeds.php | 22 +++++-------- classes/pref/prefs.php | 11 +++---- classes/pref/users.php | 9 +++--- js/functions.js | 83 ++++++++++++++++---------------------------------- js/prefs.js | 39 ++++++++++++++++-------- 5 files changed, 70 insertions(+), 94 deletions(-) (limited to 'classes') diff --git a/classes/pref/feeds.php b/classes/pref/feeds.php index efc76701e..0a7fed7b2 100755 --- a/classes/pref/feeds.php +++ b/classes/pref/feeds.php @@ -1412,9 +1412,9 @@ class Pref_Feeds extends Handler_Protected { print "
    ". "" . __('Select').""; print "
    "; - print "
    ".__('All')."
    "; - print "
    ".__('None')."
    "; print "
    "; print "
    "; #toolbar @@ -1428,15 +1428,12 @@ class Pref_Feeds extends Handler_Protected { while ($line = $sth->fetch()) { $feed_id = $line["id"]; - $this_row_id = "id=\"FUPDD-$feed_id\""; - # class needed for selectTableRows() - print ""; + print ""; - # id needed for selectTableRows() print ""; + type=\"checkbox\">"; print ""; print "
    ". "" . __('Select').""; print "
    "; - print "
    ".__('All')."
    "; - print "
    ".__('None')."
    "; print "
    "; print "
    "; #toolbar @@ -1493,15 +1490,12 @@ class Pref_Feeds extends Handler_Protected { while ($line = $sth->fetch()) { $feed_id = $line["id"]; - $this_row_id = "id=\"FERDD-$feed_id\""; - # class needed for selectTableRows() - print ""; + print ""; - # id needed for selectTableRows() print ""; + type=\"checkbox\">"; print ""; print "". "" . __('Select').""; print "
    "; - print "
    ".__('All')."
    "; - print "
    ".__('None')."
    "; print "
    "; @@ -1019,10 +1019,9 @@ class Pref_Prefs extends Handler_Protected { print ""; - print ""; #odd + print ""; # data-row-id='0' <-- no point, shouldn't be removed print ""; @@ -1043,15 +1042,13 @@ class Pref_Prefs extends Handler_Protected { while ($line = $sth->fetch()) { $profile_id = $line["id"]; - $this_row_id = "id=\"FCATR-$profile_id\""; - print ""; + print ""; $edit_title = htmlspecialchars($line["title"]); print ""; diff --git a/classes/pref/users.php b/classes/pref/users.php index eda3e1a0e..fb7afcf04 100644 --- a/classes/pref/users.php +++ b/classes/pref/users.php @@ -354,9 +354,9 @@ class Pref_Users extends Handler_Protected { print "
    ". "" . __('Select').""; print "
    "; - print "
    ".__('All')."
    "; - print "
    ".__('None')."
    "; print "
    "; @@ -412,7 +412,7 @@ class Pref_Users extends Handler_Protected { $uid = $line["id"]; - print ""; + print ""; $line["login"] = htmlspecialchars($line["login"]); @@ -420,8 +420,7 @@ class Pref_Users extends Handler_Protected { $line["last_login"] = make_local_datetime($line["last_login"], false); print ""; + dojoType=\"dijit.form.CheckBox\" type=\"checkbox\">"; $onclick = "onclick='editUser($uid, event)' title='".__('Click to edit')."'"; diff --git a/js/functions.js b/js/functions.js index 6e61f4c9f..673e0e8f1 100755 --- a/js/functions.js +++ b/js/functions.js @@ -55,10 +55,14 @@ Array.prototype.remove = function(s) { const Lists = { onRowChecked: function(elem) { + const checked = elem.domNode ? elem.attr("checked") : elem.checked; // account for dojo checkboxes elem = elem.domNode || elem; - elem.up("li").toggleClassName("Selected"); + const row = elem.up("li"); + + if (row) + checked ? row.addClassName("Selected") : row.removeClassName("Selected"); } }; @@ -66,9 +70,30 @@ const Lists = { const Tables = { onRowChecked: function(elem) { // account for dojo checkboxes + const checked = elem.domNode ? elem.attr("checked") : elem.checked; elem = elem.domNode || elem; - elem.up("tr").toggleClassName("Selected"); + 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 = []; @@ -1532,60 +1557,6 @@ function uploadFeedIcon() { return false; } -// mode = all, none, invert -function selectTableRows(id, mode) { - const rows = $(id).rows; - - for (let i = 0; i < rows.length; i++) { - const row = rows[i]; - let cb = false; - let dcb = false; - - if (row.id && row.className) { - const bare_id = row.id.replace(/^[A-Z]*?-/, ""); - const inputs = rows[i].getElementsByTagName("input"); - - for (let j = 0; j < inputs.length; j++) { - const input = inputs[j]; - - if (input.getAttribute("type") == "checkbox" && - input.id.match(bare_id)) { - - cb = input; - dcb = dijit.getEnclosingWidget(cb); - break; - } - } - - if (cb || dcb) { - const issel = row.hasClassName("Selected"); - - if (mode == "all" && !issel) { - row.addClassName("Selected"); - cb.checked = true; - if (dcb) dcb.set("checked", true); - } else if (mode == "none" && issel) { - row.removeClassName("Selected"); - cb.checked = false; - if (dcb) dcb.set("checked", false); - - } else if (mode == "invert") { - - if (issel) { - row.removeClassName("Selected"); - cb.checked = false; - if (dcb) dcb.set("checked", false); - } else { - row.addClassName("Selected"); - cb.checked = true; - if (dcb) dcb.set("checked", true); - } - } - } - } - } -} - // noinspection JSUnusedGlobalSymbols function label_to_feed_id(label) { return _label_base_index - 1 - Math.abs(label); diff --git a/js/prefs.js b/js/prefs.js index 3b9e090cc..c2ff01d47 100755 --- a/js/prefs.js +++ b/js/prefs.js @@ -73,18 +73,34 @@ const App = { if (tab) { tab = dijit.byId(tab + "Tab"); - if (tab) dijit.byId("pref-tabs").selectChild(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"); - const method = Utils.urlParam('method'); + if (tab) { + tab = dijit.byId(tab); + if (tab) { + dijit.byId("pref-tabs").selectChild(tab); + } + } + } - if (method == 'editFeed') { - const param = Utils.urlParam('methodparam'); + dojo.connect(dijit.byId("pref-tabs"), "selectChild", function (elem) { + localStorage.setItem("ttrss:prefs-tab", elem.id); + }); - window.setTimeout(function () { - CommonDialogs.editFeed(param) - }, 100); - } }, hotkeyHandler: function (event) { if (event.target.nodeName == "INPUT" || event.target.nodeName == "TEXTAREA") return; @@ -725,8 +741,8 @@ function updateSystemList() { }); } -function selectTab(id, noupdate) { - if (!noupdate) { +function selectTab(id, selectOnly) { + if (!selectOnly) { notify_progress("Loading, please wait..."); switch (id) { @@ -754,7 +770,6 @@ function selectTab(id, noupdate) { const tab = dijit.byId(id + "Tab"); dijit.byId("pref-tabs").selectChild(tab); - } } -- cgit v1.2.3-54-g00ecf From 2e985d173352487f96984577ac512a3639267edf Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Sun, 2 Dec 2018 11:34:57 +0300 Subject: move some label helper functions to prefLabelTree --- classes/pref/labels.php | 4 ++-- js/PrefLabelTree.js | 55 ++++++++++++++++++++++++++++++++++++++++++++++++- js/prefs.js | 54 ------------------------------------------------ 3 files changed, 56 insertions(+), 57 deletions(-) (limited to 'classes') diff --git a/classes/pref/labels.php b/classes/pref/labels.php index 1dbe3e18c..ae68a6eb7 100644 --- a/classes/pref/labels.php +++ b/classes/pref/labels.php @@ -278,10 +278,10 @@ class Pref_Labels extends Handler_Protected { print" "; - print " "; - print ""; diff --git a/js/PrefLabelTree.js b/js/PrefLabelTree.js index 7321b80d8..c4c3ea103 100644 --- a/js/PrefLabelTree.js +++ b/js/PrefLabelTree.js @@ -37,7 +37,60 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree", "dijit/f getIconClass: function (item, opened) { return (!item || this.model.mayHaveChildren(item)) ? (opened ? "dijitFolderOpened" : "dijitFolderClosed") : "invisible"; }, - }); + getSelectedLabels: function() { + const tree = dijit.byId("labelTree"); + const items = tree.model.getCheckedItems(); + const rv = []; + + items.each(function(item) { + rv.push(tree.model.store.getValue(item, 'bare_id')); + }); + + return rv; + }, + resetColors: function() { + const labels = this.getSelectedLabels(); + + if (labels.length > 0) { + if (confirm(__("Reset selected labels to default colors?"))) { + + const query = { + op: "pref-labels", method: "colorreset", + ids: labels.toString() + }; + + xhrPost("backend.php", query, () => { + updateLabelList(); + }); + } + + } else { + alert(__("No labels are selected.")); + } + }, + removeSelected: function() { + const sel_rows = this.getSelectedLabels(); + + if (sel_rows.length > 0) { + if (confirm(__("Remove selected labels?"))) { + notify_progress("Removing selected labels..."); + + const query = { + op: "pref-labels", method: "remove", + ids: sel_rows.toString() + }; + + xhrPost("backend.php", query, () => { + updateLabelList(); + }); + } + } else { + alert(__("No labels are selected.")); + } + + return false; + } +}); }); diff --git a/js/prefs.js b/js/prefs.js index c2ff01d47..05023b053 100755 --- a/js/prefs.js +++ b/js/prefs.js @@ -316,19 +316,6 @@ function editFilter(id) { dialog.show(); } - -function getSelectedLabels() { - const tree = dijit.byId("labelTree"); - const items = tree.model.getCheckedItems(); - const rv = []; - - items.each(function(item) { - rv.push(tree.model.store.getValue(item, 'bare_id')); - }); - - return rv; -} - function getSelectedUsers() { return Tables.getSelected("prefUserList"); } @@ -372,28 +359,6 @@ function getSelectedFilters() { } -function removeSelectedLabels() { - - const sel_rows = getSelectedLabels(); - - if (sel_rows.length > 0) { - if (confirm(__("Remove selected labels?"))) { - notify_progress("Removing selected labels..."); - - const query = { op: "pref-labels", method: "remove", - ids: sel_rows.toString() }; - - xhrPost("backend.php", query, () => { - updateLabelList(); - }); - } - } else { - alert(__("No labels are selected.")); - } - - return false; -} - function removeSelectedUsers() { const sel_rows = getSelectedUsers(); @@ -906,25 +871,6 @@ function opmlRegenKey() { return false; } -function labelColorReset() { - const labels = getSelectedLabels(); - - if (labels.length > 0) { - if (confirm(__("Reset selected labels to default colors?"))) { - - const query = { op: "pref-labels", method: "colorreset", - ids: labels.toString() }; - - xhrPost("backend.php", query, () => { - updateLabelList(); - }); - } - - } else { - alert(__("No labels are selected.")); - } -} - function editProfiles() { if (dijit.byId("profileEditDlg")) -- cgit v1.2.3-54-g00ecf From 60cd4676943169a057518634e3060745e9112511 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Sun, 2 Dec 2018 11:50:53 +0300 Subject: embed some pref-feed helper functions into the tree --- classes/pref/feeds.php | 14 ++-- js/PrefFeedTree.js | 207 +++++++++++++++++++++++++++++++++++++++++++++++ js/PrefLabelTree.js | 2 +- js/prefs.js | 216 ------------------------------------------------- 4 files changed, 215 insertions(+), 224 deletions(-) (limited to 'classes') diff --git a/classes/pref/feeds.php b/classes/pref/feeds.php index 0a7fed7b2..697daeab2 100755 --- a/classes/pref/feeds.php +++ b/classes/pref/feeds.php @@ -1192,13 +1192,13 @@ class Pref_Feeds extends Handler_Protected { print "
    "; print "
    ".__('Subscribe to feed')."
    "; - print "
    ".__('Edit selected feeds')."
    "; - print "
    ".__('Reset sort order')."
    "; - print "
    ".__('Batch subscribe')."
    "; - print "
    " + print "
    " .__('Unsubscribe')."
    "; print "
    "; @@ -1206,11 +1206,11 @@ class Pref_Feeds extends Handler_Protected { print "
    ". "" . __('Categories').""; print "
    "; - print "
    ".__('Add category')."
    "; - print "
    ".__('Reset sort order')."
    "; - print "
    ".__('Remove selected')."
    "; print "
    "; diff --git a/js/PrefFeedTree.js b/js/PrefFeedTree.js index afa644251..1f1c58f2f 100644 --- a/js/PrefFeedTree.js +++ b/js/PrefFeedTree.js @@ -109,6 +109,213 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio (id.match("root") && position == "over")); } }, + resetFeedOrder: function() { + notify_progress("Loading, please wait..."); + + xhrPost("backend.php", {op: "pref-feeds", method: "feedsortreset"}, () => { + updateFeedList(); + }); + }, + resetCatOrder: function() { + notify_progress("Loading, please wait..."); + + xhrPost("backend.php", {op: "pref-feeds", method: "catsortreset"}, () => { + updateFeedList(); + }); + }, + removeSelectedFeeds: function() { + const sel_rows = this.getSelectedFeeds(); + + if (sel_rows.length > 0) { + if (confirm(__("Unsubscribe from selected feeds?"))) { + + notify_progress("Unsubscribing from selected feeds...", true); + + const query = { + op: "pref-feeds", method: "remove", + ids: sel_rows.toString() + }; + + xhrPost("backend.php", query, () => { + updateFeedList(); + }); + } + + } else { + alert(__("No feeds are selected.")); + } + + return false; + }, + getSelectedCategories: function() { + const tree = this; + const items = tree.model.getCheckedItems(); + const rv = []; + + items.each(function (item) { + if (item.id[0].match("CAT:")) + rv.push(tree.model.store.getValue(item, 'bare_id')); + }); + + return rv; + }, + removeSelectedCategories: function() { + const sel_rows = this.getSelectedCategories(); + + if (sel_rows.length > 0) { + if (confirm(__("Remove selected categories?"))) { + notify_progress("Removing selected categories..."); + + const query = { + op: "pref-feeds", method: "removeCat", + ids: sel_rows.toString() + }; + + xhrPost("backend.php", query, () => { + updateFeedList(); + }); + } + } else { + alert(__("No categories are selected.")); + } + + return false; + }, + getSelectedFeeds: function() { + const tree = this; + const items = tree.model.getCheckedItems(); + const rv = []; + + items.each(function (item) { + if (item.id[0].match("FEED:")) + rv.push(tree.model.store.getValue(item, 'bare_id')); + }); + + return rv; + }, + editSelectedFeed: function() { + const rows = this.getSelectedFeeds(); + + if (rows.length == 0) { + alert(__("No feeds are selected.")); + return; + } + + notify(""); + + if (rows.length > 1) { + return this.editMultiple(); + } else { + CommonDialogs.editFeed(rows[0], {}); + } + }, + editMultiple: function() { + const rows = this.getSelectedFeeds(); + + if (rows.length == 0) { + alert(__("No feeds are selected.")); + return; + } + + notify_progress("Loading, please wait..."); + + if (dijit.byId("feedEditDlg")) + dijit.byId("feedEditDlg").destroyRecursive(); + + xhrPost("backend.php", {op: "pref-feeds", method: "editfeeds", ids: rows.toString()}, (transport) => { + notify(""); + + const dialog = new dijit.Dialog({ + id: "feedEditDlg", + title: __("Edit Multiple Feeds"), + style: "width: 600px", + getChildByName: function (name) { + let rv = null; + this.getChildren().each( + function (child) { + if (child.name == name) { + rv = child; + return; + } + }); + return rv; + }, + toggleField: function (checkbox, elem, label) { + this.getChildByName(elem).attr('disabled', !checkbox.checked); + + if ($(label)) + if (checkbox.checked) + $(label).removeClassName('insensitive'); + else + $(label).addClassName('insensitive'); + + }, + execute: function () { + if (this.validate() && confirm(__("Save changes to selected feeds?"))) { + const query = this.attr('value'); + + /* normalize unchecked checkboxes because [] is not serialized */ + + Object.keys(query).each((key) => { + let val = query[key]; + + if (typeof val == "object" && val.length == 0) + query[key] = ["off"]; + }); + + notify_progress("Saving data...", true); + + xhrPost("backend.php", query, () => { + dialog.hide(); + updateFeedList(); + }); + } + }, + content: transport.responseText + }); + + dialog.show(); + }); + }, + createCategory: function() { + const title = prompt(__("Category title:")); + + if (title) { + notify_progress("Creating category..."); + + xhrPost("backend.php", {op: "pref-feeds", method: "addCat", cat: title}, () => { + notify(''); + updateFeedList(); + }); + } + }, + batchSubscribe: function() { + const query = "backend.php?op=pref-feeds&method=batchSubscribe"; + + // overlapping widgets + if (dijit.byId("batchSubDlg")) dijit.byId("batchSubDlg").destroyRecursive(); + if (dijit.byId("feedAddDlg")) dijit.byId("feedAddDlg").destroyRecursive(); + + const dialog = new dijit.Dialog({ + id: "batchSubDlg", + title: __("Batch subscribe"), + style: "width: 600px", + execute: function () { + if (this.validate()) { + notify_progress(__("Subscribing to feeds..."), true); + + xhrPost("backend.php", this.attr('value'), () => { + notify(""); + updateFeedList(); + dialog.hide(); + }); + } + }, + href: query + }); + + dialog.show(); + } }); }); diff --git a/js/PrefLabelTree.js b/js/PrefLabelTree.js index c4c3ea103..e5eb595e5 100644 --- a/js/PrefLabelTree.js +++ b/js/PrefLabelTree.js @@ -38,7 +38,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree", "dijit/f return (!item || this.model.mayHaveChildren(item)) ? (opened ? "dijitFolderOpened" : "dijitFolderClosed") : "invisible"; }, getSelectedLabels: function() { - const tree = dijit.byId("labelTree"); + const tree = this; const items = tree.model.getCheckedItems(); const rv = []; diff --git a/js/prefs.js b/js/prefs.js index 05023b053..18facd9a9 100755 --- a/js/prefs.js +++ b/js/prefs.js @@ -320,32 +320,6 @@ function getSelectedUsers() { return Tables.getSelected("prefUserList"); } -function getSelectedFeeds() { - const tree = dijit.byId("feedTree"); - const items = tree.model.getCheckedItems(); - const rv = []; - - items.each(function(item) { - if (item.id[0].match("FEED:")) - rv.push(tree.model.store.getValue(item, 'bare_id')); - }); - - return rv; -} - -function getSelectedCategories() { - const tree = dijit.byId("feedTree"); - const items = tree.model.getCheckedItems(); - const rv = []; - - items.each(function(item) { - if (item.id[0].match("CAT:")) - rv.push(tree.model.store.getValue(item, 'bare_id')); - }); - - return rv; -} - function getSelectedFilters() { const tree = dijit.byId("filterTree"); const items = tree.model.getCheckedItems(); @@ -405,30 +379,6 @@ function removeSelectedFilters() { return false; } -function removeSelectedFeeds() { - - const sel_rows = getSelectedFeeds(); - - if (sel_rows.length > 0) { - if (confirm(__("Unsubscribe from selected feeds?"))) { - - notify_progress("Unsubscribing from selected feeds...", true); - - const query = { op: "pref-feeds", method: "remove", - ids: sel_rows.toString() }; - - xhrPost("backend.php", query, () => { - updateFeedList(); - }); - } - - } else { - alert(__("No feeds are selected.")); - } - - return false; -} - function editSelectedUser() { const rows = getSelectedUsers(); @@ -542,93 +492,6 @@ function joinSelectedFilters() { } } -function editSelectedFeed() { - const rows = getSelectedFeeds(); - - if (rows.length == 0) { - alert(__("No feeds are selected.")); - return; - } - - if (rows.length > 1) { - return editSelectedFeeds(); - } - - notify(""); - - CommonDialogs.editFeed(rows[0], {}); - -} - -function editSelectedFeeds() { - const rows = getSelectedFeeds(); - - if (rows.length == 0) { - alert(__("No feeds are selected.")); - return; - } - - notify_progress("Loading, please wait..."); - - if (dijit.byId("feedEditDlg")) - dijit.byId("feedEditDlg").destroyRecursive(); - - xhrPost("backend.php", { op: "pref-feeds", method: "editfeeds", ids: rows.toString() }, (transport) => { - notify(""); - - const dialog = new dijit.Dialog({ - id: "feedEditDlg", - title: __("Edit Multiple Feeds"), - style: "width: 600px", - getChildByName: function (name) { - let rv = null; - this.getChildren().each( - function (child) { - if (child.name == name) { - rv = child; - return; - } - }); - return rv; - }, - toggleField: function (checkbox, elem, label) { - this.getChildByName(elem).attr('disabled', !checkbox.checked); - - if ($(label)) - if (checkbox.checked) - $(label).removeClassName('insensitive'); - else - $(label).addClassName('insensitive'); - - }, - execute: function () { - if (this.validate() && confirm(__("Save changes to selected feeds?"))) { - const query = this.attr('value'); - - /* normalize unchecked checkboxes because [] is not serialized */ - - Object.keys(query).each((key) => { - let val = query[key]; - - if (typeof val == "object" && val.length == 0) - query[key] = ["off"]; - }); - - notify_progress("Saving data...", true); - - xhrPost("backend.php", query, () => { - dialog.hide(); - updateFeedList(); - }); - } - }, - content: transport.responseText - }); - - dialog.show(); - }); -} - function opmlImportComplete(iframe) { if (!iframe.contentDocument.body.innerHTML) return false; @@ -767,39 +630,6 @@ function removeCategory(id, item) { } } -function removeSelectedCategories() { - const sel_rows = getSelectedCategories(); - - if (sel_rows.length > 0) { - if (confirm(__("Remove selected categories?"))) { - notify_progress("Removing selected categories..."); - - const query = { op: "pref-feeds", method: "removeCat", - ids: sel_rows.toString() }; - - xhrPost("backend.php", query, () => { - updateFeedList(); - }); - } - } else { - alert(__("No categories are selected.")); - } - - return false; -} - -function createCategory() { - const title = prompt(__("Category title:")); - - if (title) { - notify_progress("Creating category..."); - - xhrPost("backend.php", { op: "pref-feeds", method: "addCat", cat: title }, () => { - notify(''); - updateFeedList(); - }); - } -} function showInactiveFeeds() { const query = "backend.php?op=pref-feeds&method=inactiveFeeds"; @@ -989,23 +819,6 @@ function resetFilterOrder() { }); } - -function resetFeedOrder() { - notify_progress("Loading, please wait..."); - - xhrPost("backend.php", { op: "pref-feeds", method: "feedsortreset" }, () => { - updateFeedList(); - }); -} - -function resetCatOrder() { - notify_progress("Loading, please wait..."); - - xhrPost("backend.php", { op: "pref-feeds", method: "catsortreset" }, () => { - updateFeedList(); - }); -} - function editCat(id, item) { const new_name = prompt(__('Rename category to:'), item.name); @@ -1115,35 +928,6 @@ function gotoExportOpml(filename, settings) { document.location.href = "backend.php?op=opml&method=export&filename=" + filename + "&settings=" + tmp; } - -function batchSubscribe() { - const query = "backend.php?op=pref-feeds&method=batchSubscribe"; - - // overlapping widgets - if (dijit.byId("batchSubDlg")) dijit.byId("batchSubDlg").destroyRecursive(); - if (dijit.byId("feedAddDlg")) dijit.byId("feedAddDlg").destroyRecursive(); - - const dialog = new dijit.Dialog({ - id: "batchSubDlg", - title: __("Batch subscribe"), - style: "width: 600px", - execute: function () { - if (this.validate()) { - notify_progress(__("Subscribing to feeds..."), true); - - xhrPost("backend.php", this.attr('value'), () => { - notify(""); - updateFeedList(); - dialog.hide(); - }); - } - }, - href: query - }); - - dialog.show(); -} - function clearPluginData(name) { if (confirm(__("Clear stored data for this plugin?"))) { notify_progress("Loading, please wait..."); -- cgit v1.2.3-54-g00ecf From f26d404890a55a34ed5779b6f36e949d38705e8d Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Sun, 2 Dec 2018 12:03:28 +0300 Subject: prefs: move other tree-related functions to respective trees --- classes/pref/feeds.php | 2 +- classes/pref/filters.php | 10 +- classes/pref/labels.php | 2 +- classes/pref/prefs.php | 2 +- js/PrefFeedTree.js | 7 ++ js/PrefFilterTree.js | 174 ++++++++++++++++++++++++++++- js/PrefLabelTree.js | 63 +++++++++++ js/prefs.js | 280 ----------------------------------------------- prefs.php | 2 +- 9 files changed, 252 insertions(+), 290 deletions(-) (limited to 'classes') diff --git a/classes/pref/feeds.php b/classes/pref/feeds.php index 697daeab2..f34ed33eb 100755 --- a/classes/pref/feeds.php +++ b/classes/pref/feeds.php @@ -1255,7 +1255,7 @@ class Pref_Feeds extends Handler_Protected { "; diff --git a/classes/pref/filters.php b/classes/pref/filters.php index f9b4bfb2a..8fe3bbda6 100755 --- a/classes/pref/filters.php +++ b/classes/pref/filters.php @@ -800,17 +800,17 @@ class Pref_Filters extends Handler_Protected { print " "; - print " "; - print " "; - print " "; - print " "; print ""; # toolbar @@ -840,7 +840,7 @@ class Pref_Filters extends Handler_Protected { var bare_id = id.substr(id.indexOf(':')+1); if (id.match('FILTER:')) { - editFilter(bare_id); + dijit.byId('filterTree').editFilter(bare_id); } diff --git a/classes/pref/labels.php b/classes/pref/labels.php index ae68a6eb7..c52f8bd79 100644 --- a/classes/pref/labels.php +++ b/classes/pref/labels.php @@ -310,7 +310,7 @@ class Pref_Labels extends Handler_Protected { var bare_id = id.substr(id.indexOf(':')+1); if (id.match('LABEL:')) { - editLabel(bare_id); + dijit.byId('labelTree').editLabel(bare_id); } "; diff --git a/classes/pref/prefs.php b/classes/pref/prefs.php index ccbc829a3..47062f739 100644 --- a/classes/pref/prefs.php +++ b/classes/pref/prefs.php @@ -436,7 +436,7 @@ class Pref_Prefs extends Handler_Protected { onComplete: function(transport) { var msg = transport.responseText; if (quit) { - gotoMain(); + document.location.href = 'index.php'; } else { if (msg == 'PREFS_NEED_RELOAD') { window.location.reload(); diff --git a/js/PrefFeedTree.js b/js/PrefFeedTree.js index 1f1c58f2f..a23624c08 100644 --- a/js/PrefFeedTree.js +++ b/js/PrefFeedTree.js @@ -147,6 +147,13 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio return false; }, + checkInactiveFeeds: function() { + xhrPost("backend.php", {op: "pref-feeds", method: "getinactivefeeds"}, (transport) => { + if (parseInt(transport.responseText) > 0) { + Element.show(dijit.byId("pref_feeds_inactive_btn").domNode); + } + }); + }, getSelectedCategories: function() { const tree = this; const items = tree.model.getCheckedItems(); diff --git a/js/PrefFilterTree.js b/js/PrefFilterTree.js index 1167365d6..9940372dd 100644 --- a/js/PrefFilterTree.js +++ b/js/PrefFilterTree.js @@ -75,8 +75,180 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree"], functio this.inherited(arguments); this.tree.model.store.save(); }, - }); + getSelectedFilters: function() { + const tree = this; + const items = tree.model.getCheckedItems(); + const rv = []; + items.each(function (item) { + rv.push(tree.model.store.getValue(item, 'bare_id')); + }); + + return rv; + }, + resetFilterOrder: function() { + notify_progress("Loading, please wait..."); + + xhrPost("backend.php", {op: "pref-filters", method: "filtersortreset"}, () => { + updateFilterList(); + }); + }, + joinSelectedFilters: function() { + const rows = getSelectedFilters(); + + if (rows.length == 0) { + alert(__("No filters are selected.")); + return; + } + + if (confirm(__("Combine selected filters?"))) { + notify_progress("Joining filters..."); + + xhrPost("backend.php", {op: "pref-filters", method: "join", ids: rows.toString()}, () => { + updateFilterList(); + }); + } + }, + editSelectedFilter: function() { + const rows = this.getSelectedFilters(); + + if (rows.length == 0) { + alert(__("No filters are selected.")); + return; + } + + if (rows.length > 1) { + alert(__("Please select only one filter.")); + return; + } + + notify(""); + + this.editFilter(rows[0]); + }, + editFilter: function(id) { + + const query = "backend.php?op=pref-filters&method=edit&id=" + param_escape(id); + + if (dijit.byId("feedEditDlg")) + dijit.byId("feedEditDlg").destroyRecursive(); + + if (dijit.byId("filterEditDlg")) + dijit.byId("filterEditDlg").destroyRecursive(); + + const dialog = new dijit.Dialog({ + id: "filterEditDlg", + title: __("Edit Filter"), + style: "width: 600px", + + test: function () { + const query = "backend.php?" + dojo.formToQuery("filter_edit_form") + "&savemode=test"; + + Filters.editFilterTest(query); + }, + selectRules: function (select) { + $$("#filterDlg_Matches input[type=checkbox]").each(function (e) { + e.checked = select; + if (select) + e.parentNode.addClassName("Selected"); + else + e.parentNode.removeClassName("Selected"); + }); + }, + selectActions: function (select) { + $$("#filterDlg_Actions input[type=checkbox]").each(function (e) { + e.checked = select; + + if (select) + e.parentNode.addClassName("Selected"); + else + e.parentNode.removeClassName("Selected"); + + }); + }, + editRule: function (e) { + const li = e.parentNode; + const rule = li.getElementsByTagName("INPUT")[1].value; + Filters.addFilterRule(li, rule); + }, + editAction: function (e) { + const li = e.parentNode; + const action = li.getElementsByTagName("INPUT")[1].value; + Filters.addFilterAction(li, action); + }, + removeFilter: function () { + const msg = __("Remove filter?"); + + if (confirm(msg)) { + this.hide(); + + notify_progress("Removing filter..."); + + const query = {op: "pref-filters", method: "remove", ids: this.attr('value').id}; + + xhrPost("backend.php", query, () => { + updateFilterList(); + }); + } + }, + addAction: function () { + Filters.addFilterAction(); + }, + addRule: function () { + Filters.addFilterRule(); + }, + deleteAction: function () { + $$("#filterDlg_Actions li[class*=Selected]").each(function (e) { + e.parentNode.removeChild(e) + }); + }, + deleteRule: function () { + $$("#filterDlg_Matches li[class*=Selected]").each(function (e) { + e.parentNode.removeChild(e) + }); + }, + execute: function () { + if (this.validate()) { + + notify_progress("Saving data...", true); + + xhrPost("backend.php", dojo.formToObject("filter_edit_form"), () => { + dialog.hide(); + updateFilterList(); + }); + } + }, + href: query + }); + + dialog.show(); + }, + removeSelectedFilters: function() { + const sel_rows = this.getSelectedFilters(); + + if (sel_rows.length > 0) { + if (confirm(__("Remove selected filters?"))) { + notify_progress("Removing selected filters..."); + + const query = { + op: "pref-filters", method: "remove", + ids: sel_rows.toString() + }; + + xhrPost("backend.php", query, () => { + updateFilterList(); + }); + } + } else { + alert(__("No filters are selected.")); + } + + return false; + }, + + + +}); }); diff --git a/js/PrefLabelTree.js b/js/PrefLabelTree.js index e5eb595e5..ba052eb07 100644 --- a/js/PrefLabelTree.js +++ b/js/PrefLabelTree.js @@ -48,6 +48,69 @@ define(["dojo/_base/declare", "dojo/dom-construct", "lib/CheckBoxTree", "dijit/f return rv; }, + editLabel: function(id) { + const query = "backend.php?op=pref-labels&method=edit&id=" + + param_escape(id); + + if (dijit.byId("labelEditDlg")) + dijit.byId("labelEditDlg").destroyRecursive(); + + const dialog = new dijit.Dialog({ + id: "labelEditDlg", + title: __("Label Editor"), + style: "width: 600px", + setLabelColor: function (id, fg, bg) { + + let kind = ''; + let color = ''; + + if (fg && bg) { + kind = 'both'; + } else if (fg) { + kind = 'fg'; + color = fg; + } else if (bg) { + kind = 'bg'; + color = bg; + } + + const e = $("LICID-" + id); + + if (e) { + if (fg) e.style.color = fg; + if (bg) e.style.backgroundColor = bg; + } + + const query = { + op: "pref-labels", method: "colorset", kind: kind, + ids: id, fg: fg, bg: bg, color: color + }; + + xhrPost("backend.php", query, () => { + updateFilterList(); // maybe there's labels in there + }); + + }, + execute: function () { + if (this.validate()) { + const caption = this.attr('value').caption; + const fg_color = this.attr('value').fg_color; + const bg_color = this.attr('value').bg_color; + + dijit.byId('labelTree').setNameById(id, caption); + this.setLabelColor(id, fg_color, bg_color); + this.hide(); + + xhrPost("backend.php", this.attr('value'), () => { + updateFilterList(); // maybe there's labels in there + }); + } + }, + href: query + }); + + dialog.show(); + }, resetColors: function() { const labels = this.getSelectedLabels(); diff --git a/js/prefs.js b/js/prefs.js index 18facd9a9..2bad86168 100755 --- a/js/prefs.js +++ b/js/prefs.js @@ -148,14 +148,6 @@ function updateFeedList() { }); } -function checkInactiveFeeds() { - xhrPost("backend.php", { op: "pref-feeds", method: "getinactivefeeds" }, (transport) => { - if (parseInt(transport.responseText) > 0) { - Element.show(dijit.byId("pref_feeds_inactive_btn").domNode); - } - }); -} - function updateUsersList(sort_key) { const user_search = $("user_search"); const search = user_search ? user_search.value : ""; @@ -218,120 +210,10 @@ function editUser(id) { dialog.show(); } -function editFilter(id) { - - const query = "backend.php?op=pref-filters&method=edit&id=" + param_escape(id); - - if (dijit.byId("feedEditDlg")) - dijit.byId("feedEditDlg").destroyRecursive(); - - if (dijit.byId("filterEditDlg")) - dijit.byId("filterEditDlg").destroyRecursive(); - - const dialog = new dijit.Dialog({ - id: "filterEditDlg", - title: __("Edit Filter"), - style: "width: 600px", - - test: function () { - const query = "backend.php?" + dojo.formToQuery("filter_edit_form") + "&savemode=test"; - - editFilterTest(query); - }, - selectRules: function (select) { - $$("#filterDlg_Matches input[type=checkbox]").each(function (e) { - e.checked = select; - if (select) - e.parentNode.addClassName("Selected"); - else - e.parentNode.removeClassName("Selected"); - }); - }, - selectActions: function (select) { - $$("#filterDlg_Actions input[type=checkbox]").each(function (e) { - e.checked = select; - - if (select) - e.parentNode.addClassName("Selected"); - else - e.parentNode.removeClassName("Selected"); - - }); - }, - editRule: function (e) { - const li = e.parentNode; - const rule = li.getElementsByTagName("INPUT")[1].value; - Filters.addFilterRule(li, rule); - }, - editAction: function (e) { - const li = e.parentNode; - const action = li.getElementsByTagName("INPUT")[1].value; - Filters.addFilterAction(li, action); - }, - removeFilter: function () { - const msg = __("Remove filter?"); - - if (confirm(msg)) { - this.hide(); - - notify_progress("Removing filter..."); - - const query = { op: "pref-filters", method: "remove", ids: this.attr('value').id }; - - xhrPost("backend.php", query, () => { - updateFilterList(); - }); - } - }, - addAction: function () { - Filters.addFilterAction(); - }, - addRule: function () { - Filters.addFilterRule(); - }, - deleteAction: function () { - $$("#filterDlg_Actions li[class*=Selected]").each(function (e) { - e.parentNode.removeChild(e) - }); - }, - deleteRule: function () { - $$("#filterDlg_Matches li[class*=Selected]").each(function (e) { - e.parentNode.removeChild(e) - }); - }, - execute: function () { - if (this.validate()) { - - notify_progress("Saving data...", true); - - xhrPost("backend.php", dojo.formToObject("filter_edit_form"), () => { - dialog.hide(); - updateFilterList(); - }); - } - }, - href: query - }); - - dialog.show(); -} - function getSelectedUsers() { return Tables.getSelected("prefUserList"); } -function getSelectedFilters() { - const tree = dijit.byId("filterTree"); - const items = tree.model.getCheckedItems(); - const rv = []; - - items.each(function(item) { - rv.push(tree.model.store.getValue(item, 'bare_id')); - }); - - return rv; - -} function removeSelectedUsers() { @@ -357,28 +239,6 @@ function removeSelectedUsers() { return false; } -function removeSelectedFilters() { - - const sel_rows = getSelectedFilters(); - - if (sel_rows.length > 0) { - if (confirm(__("Remove selected filters?"))) { - notify_progress("Removing selected filters..."); - - const query = { op: "pref-filters", method: "remove", - ids: sel_rows.toString() }; - - xhrPost("backend.php", query, () => { - updateFilterList(); - }); - } - } else { - alert(__("No filters are selected.")); - } - - return false; -} - function editSelectedUser() { const rows = getSelectedUsers(); @@ -455,43 +315,6 @@ function selectedUserDetails() { dialog.show(); } - -function editSelectedFilter() { - const rows = getSelectedFilters(); - - if (rows.length == 0) { - alert(__("No filters are selected.")); - return; - } - - if (rows.length > 1) { - alert(__("Please select only one filter.")); - return; - } - - notify(""); - - editFilter(rows[0]); - -} - -function joinSelectedFilters() { - const rows = getSelectedFilters(); - - if (rows.length == 0) { - alert(__("No filters are selected.")); - return; - } - - if (confirm(__("Combine selected filters?"))) { - notify_progress("Joining filters..."); - - xhrPost("backend.php", { op: "pref-filters", method: "join", ids: rows.toString() }, () => { - updateFilterList(); - }); - } -} - function opmlImportComplete(iframe) { if (!iframe.contentDocument.body.innerHTML) return false; @@ -774,30 +597,6 @@ function editProfiles() { dialog.show(); } -/* -function activatePrefProfile() { - - const sel_rows = getSelectedFeedCats(); - - if (sel_rows.length == 1) { - - const ok = confirm(__("Activate selected profile?")); - - if (ok) { - notify_progress("Loading, please wait..."); - - xhrPost("backend.php", { op: "rpc", method: "setprofile", id: sel_rows.toString() }, () => { - window.location.reload(); - }); - } - - } else { - alert(__("Please choose a profile to activate.")); - } - - return false; -} */ - function clearFeedAccessKeys() { if (confirm(__("This will invalidate all previously generated feed URLs. Continue?"))) { @@ -811,14 +610,6 @@ function clearFeedAccessKeys() { return false; } -function resetFilterOrder() { - notify_progress("Loading, please wait..."); - - xhrPost("backend.php", { op: "pref-filters", method: "filtersortreset" }, () => { - updateFilterList(); - }); -} - function editCat(id, item) { const new_name = prompt(__('Rename category to:'), item.name); @@ -832,69 +623,6 @@ function editCat(id, item) { } } -function editLabel(id) { - const query = "backend.php?op=pref-labels&method=edit&id=" + - param_escape(id); - - if (dijit.byId("labelEditDlg")) - dijit.byId("labelEditDlg").destroyRecursive(); - - const dialog = new dijit.Dialog({ - id: "labelEditDlg", - title: __("Label Editor"), - style: "width: 600px", - setLabelColor: function (id, fg, bg) { - - let kind = ''; - let color = ''; - - if (fg && bg) { - kind = 'both'; - } else if (fg) { - kind = 'fg'; - color = fg; - } else if (bg) { - kind = 'bg'; - color = bg; - } - - const e = $("LICID-" + id); - - if (e) { - if (fg) e.style.color = fg; - if (bg) e.style.backgroundColor = bg; - } - - const query = { op: "pref-labels", method: "colorset", kind: kind, - ids: id, fg: fg, bg: bg, color: color }; - - xhrPost("backend.php", query, () => { - updateFilterList(); // maybe there's labels in there - }); - - }, - execute: function () { - if (this.validate()) { - const caption = this.attr('value').caption; - const fg_color = this.attr('value').fg_color; - const bg_color = this.attr('value').bg_color; - - dijit.byId('labelTree').setNameById(id, caption); - this.setLabelColor(id, fg_color, bg_color); - this.hide(); - - xhrPost("backend.php", this.attr('value'), () => { - updateFilterList(); // maybe there's labels in there - }); - } - }, - href: query - }); - - dialog.show(); -} - - function customizeCSS() { const query = "backend.php?op=pref-prefs&method=customizeCSS"; @@ -951,11 +679,3 @@ function clearSqlLog() { } } - -function updateSelectedPrompt() { - // no-op shim for toggleSelectedRow() -} - -function gotoMain() { - document.location.href = "index.php"; -} diff --git a/prefs.php b/prefs.php index 6ff81af74..13001788b 100644 --- a/prefs.php +++ b/prefs.php @@ -127,7 +127,7 @@
    -- cgit v1.2.3-54-g00ecf From 58e54282d36d54c2be0e50f78fbc500772a3b762 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Sun, 2 Dec 2018 15:30:07 +0300 Subject: prefs: move more global functions into matching classes --- classes/pref/feeds.php | 4 +- classes/pref/prefs.php | 14 +- classes/pref/system.php | 4 +- js/PrefFeedTree.js | 75 +++++++++- js/prefs.js | 387 +++++++++++++++++------------------------------- 5 files changed, 217 insertions(+), 267 deletions(-) (limited to 'classes') diff --git a/classes/pref/feeds.php b/classes/pref/feeds.php index f34ed33eb..a39090767 100755 --- a/classes/pref/feeds.php +++ b/classes/pref/feeds.php @@ -1156,7 +1156,7 @@ class Pref_Feeds extends Handler_Protected { $inactive_button = ""; $feed_search = clean($_REQUEST["search"]); @@ -1249,7 +1249,7 @@ class Pref_Feeds extends Handler_Protected { if (id.match('FEED:')) { CommonDialogs.editFeed(bare_id); } else if (id.match('CAT:')) { - editCat(bare_id, item); + dijit.byId('feedTree').editCategory(bare_id, item); } "; 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 5ead558e435dd8d58f6666b445374b0005a60337 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Sun, 2 Dec 2018 22:08:18 +0300 Subject: move Utils to AppBase where it belongs --- classes/feeds.php | 4 +- classes/pref/feeds.php | 4 +- js/AppBase.js | 325 +++++++++++++++++++++++++++++++++++++++++++++++- js/Article.js | 4 +- js/Feeds.js | 14 +-- js/Headlines.js | 26 ++-- js/Utils.js | 330 ------------------------------------------------- js/prefs.js | 25 ++-- js/tt-rss.js | 19 ++- 9 files changed, 370 insertions(+), 381 deletions(-) delete mode 100644 js/Utils.js (limited to 'classes') diff --git a/classes/feeds.php b/classes/feeds.php index 1e62a9206..3c6c20f26 100755 --- a/classes/feeds.php +++ b/classes/feeds.php @@ -51,7 +51,7 @@ class Feeds extends Handler_Protected { $reply .= " + onclick=\"App.displayDlg('".__("Show as feed")."','generatedFeed', '$feed_id:$is_cat:$rss_link')\"> "; @@ -137,7 +137,7 @@ class Feeds extends Handler_Protected { //$reply .= ""; - $reply .= ""; $reply .= ""; diff --git a/classes/pref/feeds.php b/classes/pref/feeds.php index 82cb84daf..961a09c28 100755 --- a/classes/pref/feeds.php +++ b/classes/pref/feeds.php @@ -1306,7 +1306,7 @@ class Pref_Feeds extends Handler_Protected { print_warning("Published OPML does not include your Tiny Tiny RSS settings, feeds that require authentication or feeds hidden from Popular feeds."); - print " "; PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION, @@ -1323,7 +1323,7 @@ class Pref_Feeds extends Handler_Protected { print "

    "; - print " "; print "

    "; print ""; - print" "; print " "; print "

    "; @@ -74,7 +74,7 @@ class Share extends Plugin { return ""; } diff --git a/plugins/share/share.js b/plugins/share/share.js index a22e01715..7366c2aff 100644 --- a/plugins/share/share.js +++ b/plugins/share/share.js @@ -1,20 +1,20 @@ -function shareArticle(id) { - try { +Plugins.Share = { + shareArticle: function(id) { if (dijit.byId("shareArticleDlg")) dijit.byId("shareArticleDlg").destroyRecursive(); - var query = "backend.php?op=pluginhandler&plugin=share&method=shareArticle¶m=" + encodeURIComponent(id); + const query = "backend.php?op=pluginhandler&plugin=share&method=shareArticle¶m=" + encodeURIComponent(id); - dialog = new dijit.Dialog({ + const dialog = new dijit.Dialog({ id: "shareArticleDlg", title: __("Share article by URL"), style: "width: 600px", - newurl: function() { + newurl: function () { if (confirm(__("Generate new share URL for this article?"))) { Notify.progress("Trying to change URL...", true); - const query = { op: "pluginhandler", plugin: "share", method: "newkey", id: id }; + const query = {op: "pluginhandler", plugin: "share", method: "newkey", id: id}; xhrJson("backend.php", query, (reply) => { if (reply) { @@ -44,12 +44,12 @@ function shareArticle(id) { } }, - unshare: function() { + unshare: function () { if (confirm(__("Remove sharing for this article?"))) { Notify.progress("Trying to unshare...", true); - const query = { op: "pluginhandler", plugin: "share", method: "unshare", id: id }; + const query = {op: "pluginhandler", plugin: "share", method: "unshare", id: id}; xhrPost("backend.php", query, () => { notify("Article unshared."); @@ -62,16 +62,15 @@ function shareArticle(id) { } }, - href: query}); + href: query + }); dialog.show(); const img = $("SHARE-IMG-" + id); if (img) img.src = img.src.replace("notshared.png", "share.png"); - - } catch (e) { - exception_error("shareArticle", e); } -} +}; + diff --git a/plugins/share/share_prefs.js b/plugins/share/share_prefs.js index 92975f8f4..071a6667c 100644 --- a/plugins/share/share_prefs.js +++ b/plugins/share/share_prefs.js @@ -1,16 +1,15 @@ -function clearArticleAccessKeys() { - if (confirm(__("This will invalidate all previously shared article URLs. Continue?"))) { - Notify.progress("Clearing URLs..."); - - const query = { op: "pluginhandler", plugin: "share", method: "clearArticleKeys" }; - - xhrPost("backend.php", query, () => { - Notify.info("Shared URLs cleared."); - }); - } - - return false; -} +Plugins.Share = { + clearKeys: function() { + if (confirm(__("This will invalidate all previously shared article URLs. Continue?"))) { + Notify.progress("Clearing URLs..."); + const query = {op: "pluginhandler", plugin: "share", method: "clearArticleKeys"}; + xhrPost("backend.php", query, () => { + Notify.info("Shared URLs cleared."); + }); + } + return false; + } +}; -- cgit v1.2.3-54-g00ecf From b3bc638a9fa87cdaf61bff446f8aa0534d2b49ee Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Mon, 3 Dec 2018 12:26:49 +0300 Subject: refactor OPML export/import code to be less horrible --- classes/dlg.php | 2 +- classes/opml.php | 7 ++--- classes/pref/feeds.php | 33 ++++++++++++--------- js/PrefHelpers.js | 80 +++++++++++++++++++++++++++++++++++++++++++++++++- js/prefs.js | 77 +----------------------------------------------- 5 files changed, 102 insertions(+), 97 deletions(-) (limited to 'classes') diff --git a/classes/dlg.php b/classes/dlg.php index 32c41ee34..6617dfe07 100644 --- a/classes/dlg.php +++ b/classes/dlg.php @@ -49,7 +49,7 @@ class Dlg extends Handler_Protected { print "
    "; - print " "; print ""; + "; - print "
    "; + print ""; + + print "

    "; - $opml_export_filename = "TinyTinyRSS_".date("Y-m-d").".opml"; + print "
    "; - print "

    " . __('Filename:') . - "  " . - __('Include settings') . ""; + print ""; - print "

    "; + print ""; + + print ""; print "
    "; - print "

    " . __('Your OPML can be published publicly and can be subscribed by anyone who knows the URL below.') . "

    "; + print_notice(__('Your OPML can be published publicly and can be subscribed by anyone who knows the URL below.')); print_warning("Published OPML does not include your Tiny Tiny RSS settings, feeds that require authentication or feeds hidden from Popular feeds."); diff --git a/js/PrefHelpers.js b/js/PrefHelpers.js index 749e954cc..df42547b2 100644 --- a/js/PrefHelpers.js +++ b/js/PrefHelpers.js @@ -148,7 +148,85 @@ define(["dojo/_base/declare"], function (declare) { Notify.close(); }); } - } + }; + + Prefs.OPML = { + import: function() { + const opml_file = $("opml_file"); + + if (opml_file.value.length == 0) { + alert(__("Please choose an OPML file first.")); + return false; + } else { + Notify.progress("Importing, please wait...", true); + + Element.show("upload_iframe"); + + return true; + } + }, + onImportComplete: function(iframe) { + if (!iframe.contentDocument.body.innerHTML) return false; + + Element.show(iframe); + + Notify.close(); + + if (dijit.byId('opmlImportDlg')) + dijit.byId('opmlImportDlg').destroyRecursive(); + + const content = iframe.contentDocument.body.innerHTML; + + const dialog = new dijit.Dialog({ + id: "opmlImportDlg", + title: __("OPML Import"), + style: "width: 600px", + onCancel: function () { + window.location.reload(); + }, + execute: function () { + window.location.reload(); + }, + content: content + }); + + dojo.connect(dialog, "onShow", function () { + Element.hide(iframe); + }); + + dialog.show(); + }, + export: function() { + console.log("export"); + window.open("backend.php?op=opml&method=export&" + dojo.formToQuery("opmlExportForm")); + }, + changeKey: function() { + if (confirm(__("Replace current OPML publishing address with a new one?"))) { + Notify.progress("Trying to change address...", true); + + xhrJson("backend.php", {op: "pref-feeds", method: "regenOPMLKey"}, (reply) => { + if (reply) { + const new_link = reply.link; + const e = $('pub_opml_url'); + + if (new_link) { + e.href = new_link; + e.innerHTML = new_link; + + new Effect.Highlight(e); + + Notify.close(); + + } else { + Notify.error("Could not change feed URL."); + } + } + }); + } + return false; + }, + +}; return Prefs; }); diff --git a/js/prefs.js b/js/prefs.js index edb11bc7d..4bdfb45ef 100755 --- a/js/prefs.js +++ b/js/prefs.js @@ -152,79 +152,4 @@ require(["dojo/_base/kernel", exception_error(e); } }); -}); - -function opmlImportComplete(iframe) { - if (!iframe.contentDocument.body.innerHTML) return false; - - Element.show(iframe); - - Notify.close(); - - if (dijit.byId('opmlImportDlg')) - dijit.byId('opmlImportDlg').destroyRecursive(); - - const content = iframe.contentDocument.body.innerHTML; - - const dialog = new dijit.Dialog({ - id: "opmlImportDlg", - title: __("OPML Import"), - style: "width: 600px", - onCancel: function () { - window.location.reload(); - }, - execute: function () { - window.location.reload(); - }, - content: content - }); - - dialog.show(); -} - -function opmlImport() { - - const opml_file = $("opml_file"); - - if (opml_file.value.length == 0) { - alert(__("Please choose an OPML file first.")); - return false; - } else { - Notify.progress("Importing, please wait...", true); - - Element.show("upload_iframe"); - - return true; - } -} - -function opmlRegenKey() { - if (confirm(__("Replace current OPML publishing address with a new one?"))) { - Notify.progress("Trying to change address...", true); - - xhrJson("backend.php", { op: "pref-feeds", method: "regenOPMLKey" }, (reply) => { - if (reply) { - const new_link = reply.link; - const e = $('pub_opml_url'); - - if (new_link) { - e.href = new_link; - e.innerHTML = new_link; - - new Effect.Highlight(e); - - Notify.close(); - - } else { - Notify.error("Could not change feed URL."); - } - } - }); - } - return false; -} - -function gotoExportOpml(filename, settings) { - const tmp = settings ? 1 : 0; - document.location.href = "backend.php?op=opml&method=export&filename=" + filename + "&settings=" + tmp; -} +}); \ No newline at end of file -- cgit v1.2.3-54-g00ecf From 4d4034091af3d5f7308cc794cf38f654bbe3083f Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Mon, 3 Dec 2018 12:46:00 +0300 Subject: prefs: Prefs global -> Helpers --- classes/dlg.php | 2 +- classes/pref/feeds.php | 8 ++++---- classes/pref/prefs.php | 10 +++++----- classes/pref/system.php | 4 ++-- js/PrefHelpers.js | 17 ++++++++--------- js/prefs.js | 2 +- 6 files changed, 21 insertions(+), 22 deletions(-) (limited to 'classes') diff --git a/classes/dlg.php b/classes/dlg.php index 6617dfe07..7ac18bb90 100644 --- a/classes/dlg.php +++ b/classes/dlg.php @@ -49,7 +49,7 @@ class Dlg extends Handler_Protected { print "
    "; - print " "; print ""; print ""; @@ -1295,7 +1295,7 @@ class Pref_Feeds extends Handler_Protected { print "
    "; print ""; print "
    "; - print " "; - print ""; print " "; @@ -756,7 +756,7 @@ class Pref_Prefs extends Handler_Protected { if (count($tmppluginhost->get_all($plugin)) > 0) { if (in_array($name, $system_enabled)) { - print "
    "; } } @@ -816,7 +816,7 @@ class Pref_Prefs extends Handler_Protected { if (count($tmppluginhost->get_all($plugin)) > 0) { if (in_array($name, $system_enabled) || in_array($name, $user_enabled)) { - print ""; + print ""; } } diff --git a/classes/pref/system.php b/classes/pref/system.php index 17dfb10ca..d60b419cf 100644 --- a/classes/pref/system.php +++ b/classes/pref/system.php @@ -37,10 +37,10 @@ class Pref_System extends Handler_Protected { LIMIT 100"); print " "; + onclick=\"Helpers.updateEventLog()\">".__('Refresh')." "; print "  "; + class=\"btn-danger\" onclick=\"Helpers.clearEventLog()\">".__('Clear')." "; print "

    ".__("Clear data")."".__("Clear data")."".__("Clear data")."
    "; diff --git a/js/PrefHelpers.js b/js/PrefHelpers.js index df42547b2..e4ffb04ef 100644 --- a/js/PrefHelpers.js +++ b/js/PrefHelpers.js @@ -1,5 +1,5 @@ define(["dojo/_base/declare"], function (declare) { - Prefs = { + Helpers = { clearFeedAccessKeys: function() { if (confirm(__("This will invalidate all previously generated feed URLs. Continue?"))) { Notify.progress("Clearing URLs..."); @@ -56,7 +56,7 @@ define(["dojo/_base/declare"], function (declare) { xhrPost("backend.php", query, () => { Notify.close(); - Prefs.editProfiles(); + Helpers.editProfiles(); }); } @@ -88,7 +88,7 @@ define(["dojo/_base/declare"], function (declare) { xhrPost("backend.php", query, () => { Notify.close(); - Prefs.editProfiles(); + Helpers.editProfiles(); }); } @@ -128,7 +128,7 @@ define(["dojo/_base/declare"], function (declare) { confirmReset: function() { if (confirm(__("Reset to defaults?"))) { xhrPost("backend.php", {op: "pref-prefs", method: "resetconfig"}, (transport) => { - Prefs.refresh(); + Helpers.refresh(); Notify.info(transport.responseText); }); } @@ -138,7 +138,7 @@ define(["dojo/_base/declare"], function (declare) { Notify.progress("Loading, please wait..."); xhrPost("backend.php", {op: "pref-prefs", method: "clearplugindata", name: name}, () => { - Prefs.refresh(); + Helpers.refresh(); }); } }, @@ -150,7 +150,7 @@ define(["dojo/_base/declare"], function (declare) { } }; - Prefs.OPML = { + Helpers.OPML = { import: function() { const opml_file = $("opml_file"); @@ -225,8 +225,7 @@ define(["dojo/_base/declare"], function (declare) { } return false; }, + }; -}; - - return Prefs; + return Helpers; }); diff --git a/js/prefs.js b/js/prefs.js index 4bdfb45ef..dafdbcdee 100755 --- a/js/prefs.js +++ b/js/prefs.js @@ -5,7 +5,7 @@ let App; let CommonDialogs; let Filters; let Users; -let Prefs; +let Helpers; const Plugins = {}; -- cgit v1.2.3-54-g00ecf From e76d1fb995e25d78f0131ac56660846b0e9ecb9a Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Mon, 3 Dec 2018 14:21:50 +0300 Subject: plugins: mail, mailto: remove code from global context --- classes/feeds.php | 4 +-- js/tt-rss.js | 8 ++--- plugins/mail/init.php | 2 +- plugins/mail/mail.js | 94 ++++++++++++++++++++++++++----------------------- plugins/mailto/init.js | 45 +++++++++++++---------- plugins/mailto/init.php | 2 +- 6 files changed, 82 insertions(+), 73 deletions(-) (limited to 'classes') diff --git a/classes/feeds.php b/classes/feeds.php index 58d4f68d9..9fe528723 100755 --- a/classes/feeds.php +++ b/classes/feeds.php @@ -124,12 +124,12 @@ class Feeds extends Handler_Protected { } if (PluginHost::getInstance()->get_plugin("mail")) { - $reply .= ""; } if (PluginHost::getInstance()->get_plugin("mailto")) { - $reply .= ""; } diff --git a/js/tt-rss.js b/js/tt-rss.js index 8931e9860..fc87ae24d 100644 --- a/js/tt-rss.js +++ b/js/tt-rss.js @@ -302,12 +302,10 @@ require(["dojo/_base/kernel", } }; this.hotkey_actions["email_article"] = function () { - if (typeof emailArticle != "undefined") { - emailArticle(); - } else if (typeof mailtoArticle != "undefined") { - mailtoArticle(); + if (typeof Plugins.Mail != "undefined") { + Plugins.Mail.onHotkey(Headlines.getSelected()); } else { - alert(__("Please enable mail plugin first.")); + alert(__("Please enable mail or mailto plugin first.")); } }; this.hotkey_actions["select_all"] = function () { diff --git a/plugins/mail/init.php b/plugins/mail/init.php index d8f92853e..1609a05c3 100644 --- a/plugins/mail/init.php +++ b/plugins/mail/init.php @@ -72,7 +72,7 @@ class Mail extends Plugin { function hook_article_button($line) { return "Zoom"; } diff --git a/plugins/mail/mail.js b/plugins/mail/mail.js index 87e354b42..eb7b7e6b6 100644 --- a/plugins/mail/mail.js +++ b/plugins/mail/mail.js @@ -1,52 +1,56 @@ -function emailArticle(id) { - if (!id) { - let ids = Headlines.getSelected(); +Plugins.Mail = { + send: function(id) { + if (!id) { + let ids = Headlines.getSelected(); + + if (ids.length == 0) { + alert(__("No articles selected.")); + return; + } - if (ids.length == 0) { - alert(__("No articles selected.")); - return; + id = ids.toString(); } - id = ids.toString(); - } + if (dijit.byId("emailArticleDlg")) + dijit.byId("emailArticleDlg").destroyRecursive(); - 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}); + const query = "backend.php?op=pluginhandler&plugin=mail&method=emailArticle¶m=" + encodeURIComponent(id); - /* var tmph = dojo.connect(dialog, 'onLoad', function() { - dojo.disconnect(tmph); - - new Ajax.Autocompleter('emailArticleDlg_destination', 'emailArticleDlg_dst_choices', - "backend.php?op=pluginhandler&plugin=mail&method=completeEmails", - { tokens: '', paramName: "search" }); - }); */ - - dialog.show(); -} + 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); + + new Ajax.Autocompleter('emailArticleDlg_destination', 'emailArticleDlg_dst_choices', + "backend.php?op=pluginhandler&plugin=mail&method=completeEmails", + { tokens: '', paramName: "search" }); + }); */ + + dialog.show(); + }, + onHotkey: function(id) { + Plugins.Mail.send(id); + } +}; diff --git a/plugins/mailto/init.js b/plugins/mailto/init.js index 92a90f8e9..f81f70fc7 100644 --- a/plugins/mailto/init.js +++ b/plugins/mailto/init.js @@ -1,27 +1,34 @@ -function mailtoArticle(id) { - if (!id) { - const ids = Headlines.getSelected(); +Plugins.Mailto = { + send: function (id) { + if (!id) { + const ids = Headlines.getSelected(); - if (ids.length == 0) { - alert(__("No articles selected.")); - return; - } + if (ids.length == 0) { + alert(__("No articles selected.")); + return; + } - id = ids.toString(); - } + id = ids.toString(); + } - if (dijit.byId("emailArticleDlg")) - dijit.byId("emailArticleDlg").destroyRecursive(); + if (dijit.byId("emailArticleDlg")) + dijit.byId("emailArticleDlg").destroyRecursive(); - const query = "backend.php?op=pluginhandler&plugin=mailto&method=emailArticle¶m=" + encodeURIComponent(id); + const query = "backend.php?op=pluginhandler&plugin=mailto&method=emailArticle¶m=" + encodeURIComponent(id); - const dialog = new dijit.Dialog({ - id: "emailArticleDlg", - title: __("Forward article by email"), - style: "width: 600px", - href: query}); + const dialog = new dijit.Dialog({ + id: "emailArticleDlg", + title: __("Forward article by email"), + style: "width: 600px", + href: query}); - dialog.show(); -} + dialog.show(); + } +}; +// override default hotkey action if enabled +Plugins.Mail = Plugins.Mail || {}; +Plugins.Mail.onHotkey = function(id) { + Plugins.Mailto.send(id); +}; \ No newline at end of file diff --git a/plugins/mailto/init.php b/plugins/mailto/init.php index 60c58b707..3dbc8d643 100644 --- a/plugins/mailto/init.php +++ b/plugins/mailto/init.php @@ -21,7 +21,7 @@ class MailTo extends Plugin { function hook_article_button($line) { return "Zoom"; } -- cgit v1.2.3-54-g00ecf