summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2020-06-04 19:50:13 +0300
committerAndrew Dolgov <[email protected]>2020-06-04 19:50:13 +0300
commite37f8cfa7817bb4d9f7330838542666b74e52b94 (patch)
treed90c2f76ea70d928a5d751bad9263b20d47d39b1
parent06cc6e3a2a042c5c4ccee136f3365eabee5376a7 (diff)
don't use declare() for static objects with no inheritance because apparently it's not actually needed by AMD
-rw-r--r--js/Article.js586
-rw-r--r--js/CommonDialogs.js8
-rw-r--r--js/CommonFilters.js643
-rw-r--r--js/Feeds.js1059
-rwxr-xr-xjs/Headlines.js2258
-rw-r--r--js/PluginHost.js2
-rw-r--r--js/tt-rss.js6
7 files changed, 2269 insertions, 2293 deletions
diff --git a/js/Article.js b/js/Article.js
index 3056dd666..197bfb3ab 100644
--- a/js/Article.js
+++ b/js/Article.js
@@ -1,355 +1,351 @@
'use strict'
/* global __, ngettext */
-define(["dojo/_base/declare"], function (declare) {
- Article = {
- _scroll_reset_timeout: false,
- getScoreClass: function (score) {
- if (score > 500) {
- return "score-high";
- } else if (score > 0) {
- return "score-half-high";
- } else if (score < -100) {
- return "score-low";
- } else if (score < 0) {
- return "score-half-low";
- } else {
- return "score-neutral";
- }
- },
- getScorePic: function (score) {
- if (score > 500) {
- return "trending_up";
- } else if (score > 0) {
- return "trending_up";
- } else if (score < 0) {
- return "trending_down";
- } else {
- return "trending_neutral";
- }
- },
- selectionSetScore: function () {
- const ids = Headlines.getSelected();
+const Article = {
+ _scroll_reset_timeout: false,
+ getScoreClass: function (score) {
+ if (score > 500) {
+ return "score-high";
+ } else if (score > 0) {
+ return "score-half-high";
+ } else if (score < -100) {
+ return "score-low";
+ } else if (score < 0) {
+ return "score-half-low";
+ } else {
+ return "score-neutral";
+ }
+ },
+ getScorePic: function (score) {
+ if (score > 500) {
+ return "trending_up";
+ } else if (score > 0) {
+ return "trending_up";
+ } else if (score < 0) {
+ return "trending_down";
+ } else {
+ return "trending_neutral";
+ }
+ },
+ selectionSetScore: function () {
+ const ids = Headlines.getSelected();
- if (ids.length > 0) {
- const score = prompt(__("Please enter new score for selected articles:"));
+ if (ids.length > 0) {
+ const score = prompt(__("Please enter new score for selected articles:"));
- if (!isNaN(parseInt(score))) {
- ids.each((id) => {
- const row = $("RROW-" + id);
+ if (!isNaN(parseInt(score))) {
+ ids.each((id) => {
+ const row = $("RROW-" + id);
- if (row) {
- row.setAttribute("data-score", score);
+ if (row) {
+ row.setAttribute("data-score", score);
- const pic = row.select(".icon-score")[0];
+ const pic = row.select(".icon-score")[0];
- pic.innerHTML = Article.getScorePic(score);
- pic.setAttribute("title", score);
+ pic.innerHTML = Article.getScorePic(score);
+ pic.setAttribute("title", score);
- ["score-low", "score-high", "score-half-low", "score-half-high", "score-neutral"]
- .each(function(scl) {
- if (row.hasClassName(scl))
- row.removeClassName(scl);
- });
+ ["score-low", "score-high", "score-half-low", "score-half-high", "score-neutral"]
+ .each(function(scl) {
+ if (row.hasClassName(scl))
+ row.removeClassName(scl);
+ });
- row.addClassName(Article.getScoreClass(score));
- }
- });
- }
-
- } else {
- alert(__("No articles selected."));
+ row.addClassName(Article.getScoreClass(score));
+ }
+ });
}
- },
- setScore: function (id, pic) {
- const row = pic.up("div[id*=RROW]");
- if (row) {
- const score_old = row.getAttribute("data-score");
- const score = prompt(__("Please enter new score for this article:"), score_old);
+ } else {
+ alert(__("No articles selected."));
+ }
+ },
+ setScore: function (id, pic) {
+ const row = pic.up("div[id*=RROW]");
- if (!isNaN(parseInt(score))) {
- row.setAttribute("data-score", score);
+ if (row) {
+ const score_old = row.getAttribute("data-score");
+ const score = prompt(__("Please enter new score for this article:"), score_old);
- const pic = row.select(".icon-score")[0];
+ if (!isNaN(parseInt(score))) {
+ row.setAttribute("data-score", score);
- pic.innerHTML = Article.getScorePic(score);
- pic.setAttribute("title", score);
+ const pic = row.select(".icon-score")[0];
- ["score-low", "score-high", "score-half-low", "score-half-high", "score-neutral"]
- .each(function(scl) {
- if (row.hasClassName(scl))
- row.removeClassName(scl);
- });
+ pic.innerHTML = Article.getScorePic(score);
+ pic.setAttribute("title", score);
- row.addClassName(Article.getScoreClass(score));
- }
+ ["score-low", "score-high", "score-half-low", "score-half-high", "score-neutral"]
+ .each(function(scl) {
+ if (row.hasClassName(scl))
+ row.removeClassName(scl);
+ });
+
+ row.addClassName(Article.getScoreClass(score));
}
- },
- cdmUnsetActive: function (event) {
- const row = $("RROW-" + Article.getActive());
+ }
+ },
+ cdmUnsetActive: function (event) {
+ const row = $("RROW-" + Article.getActive());
- if (row) {
- row.removeClassName("active");
+ if (row) {
+ row.removeClassName("active");
- if (event)
- event.stopPropagation();
+ if (event)
+ event.stopPropagation();
- return false;
- }
- },
- close: function () {
- if (dijit.byId("content-insert"))
- dijit.byId("headlines-wrap-inner").removeChild(
- dijit.byId("content-insert"));
-
- Article.setActive(0);
- },
- displayUrl: function (id) {
- const query = {op: "rpc", method: "getlinktitlebyid", id: id};
-
- xhrJson("backend.php", query, (reply) => {
- if (reply && reply.link) {
- prompt(__("Article URL:"), reply.link);
- }
- });
- },
- openInNewWindow: function (id) {
- const w = window.open("");
+ return false;
+ }
+ },
+ close: function () {
+ if (dijit.byId("content-insert"))
+ dijit.byId("headlines-wrap-inner").removeChild(
+ dijit.byId("content-insert"));
- if (w) {
- w.opener = null;
- w.location = "backend.php?op=article&method=redirect&id=" + id;
+ Article.setActive(0);
+ },
+ displayUrl: function (id) {
+ const query = {op: "rpc", method: "getlinktitlebyid", id: id};
- Headlines.toggleUnread(id, 0);
+ xhrJson("backend.php", query, (reply) => {
+ if (reply && reply.link) {
+ prompt(__("Article URL:"), reply.link);
}
- },
- render: function (article) {
- App.cleanupMemory("content-insert");
+ });
+ },
+ openInNewWindow: function (id) {
+ const w = window.open("");
- dijit.byId("headlines-wrap-inner").addChild(
- dijit.byId("content-insert"));
+ if (w) {
+ w.opener = null;
+ w.location = "backend.php?op=article&method=redirect&id=" + id;
- const c = dijit.byId("content-insert");
+ Headlines.toggleUnread(id, 0);
+ }
+ },
+ render: function (article) {
+ App.cleanupMemory("content-insert");
- try {
- c.domNode.scrollTop = 0;
- } catch (e) {
- }
+ dijit.byId("headlines-wrap-inner").addChild(
+ dijit.byId("content-insert"));
- c.attr('content', article);
- PluginHost.run(PluginHost.HOOK_ARTICLE_RENDERED, c.domNode);
+ const c = dijit.byId("content-insert");
- //Headlines.correctHeadlinesOffset(Article.getActive());
+ try {
+ c.domNode.scrollTop = 0;
+ } catch (e) {
+ }
- try {
- c.focus();
- } catch (e) {
- }
- },
- formatComments: function(hl) {
- let comments = "";
+ c.attr('content', article);
+ PluginHost.run(PluginHost.HOOK_ARTICLE_RENDERED, c.domNode);
- if (hl.comments || hl.num_comments > 0) {
- let comments_msg = __("comments");
+ //Headlines.correctHeadlinesOffset(Article.getActive());
- if (hl.num_comments > 0) {
- comments_msg = hl.num_comments + " " + ngettext("comment", "comments", hl.num_comments)
- }
+ try {
+ c.focus();
+ } catch (e) {
+ }
+ },
+ formatComments: function(hl) {
+ let comments = "";
- comments = `<a href="${escapeHtml(hl.comments ? hl.comments : hl.link)}">(${comments_msg})</a>`;
+ if (hl.comments || hl.num_comments > 0) {
+ let comments_msg = __("comments");
+
+ if (hl.num_comments > 0) {
+ comments_msg = hl.num_comments + " " + ngettext("comment", "comments", hl.num_comments)
}
- return comments;
- },
- formatOriginallyFrom: function(hl) {
- return hl.orig_feed ? `<span>
- ${__('Originally from:')} <a target="_blank" rel="noopener noreferrer" href="${escapeHtml(hl.orig_feed[1])}">${hl.orig_feed[0]}</a>
- </span>` : "";
- },
- unpack: function(row) {
- if (row.hasAttribute("data-content")) {
- console.log("unpacking: " + row.id);
+ comments = `<a href="${escapeHtml(hl.comments ? hl.comments : hl.link)}">(${comments_msg})</a>`;
+ }
- const container = row.querySelector(".content-inner");
+ return comments;
+ },
+ formatOriginallyFrom: function(hl) {
+ return hl.orig_feed ? `<span>
+ ${__('Originally from:')} <a target="_blank" rel="noopener noreferrer" href="${escapeHtml(hl.orig_feed[1])}">${hl.orig_feed[0]}</a>
+ </span>` : "";
+ },
+ unpack: function(row) {
+ if (row.hasAttribute("data-content")) {
+ console.log("unpacking: " + row.id);
- container.innerHTML = row.getAttribute("data-content").trim();
+ const container = row.querySelector(".content-inner");
- // blank content element might screw up onclick selection and keyboard moving
- if (container.textContent.length == 0)
- container.innerHTML += "&nbsp;";
+ container.innerHTML = row.getAttribute("data-content").trim();
- // in expandable mode, save content for later, so that we can pack unfocused rows back
- if (App.isCombinedMode() && $("main").hasClassName("expandable"))
- row.setAttribute("data-content-original", row.getAttribute("data-content"));
+ // blank content element might screw up onclick selection and keyboard moving
+ if (container.textContent.length == 0)
+ container.innerHTML += "&nbsp;";
- row.removeAttribute("data-content");
+ // in expandable mode, save content for later, so that we can pack unfocused rows back
+ if (App.isCombinedMode() && $("main").hasClassName("expandable"))
+ row.setAttribute("data-content-original", row.getAttribute("data-content"));
- PluginHost.run(PluginHost.HOOK_ARTICLE_RENDERED_CDM, row);
- }
- },
- pack: function(row) {
- if (row.hasAttribute("data-content-original")) {
- console.log("packing", row.id);
- row.setAttribute("data-content", row.getAttribute("data-content-original"));
- row.removeAttribute("data-content-original");
-
- row.querySelector(".content-inner").innerHTML = "&nbsp;";
- }
- },
- view: function (id, no_expand) {
- this.setActive(id);
- Headlines.scrollToArticleId(id);
-
- if (!no_expand) {
- const hl = Headlines.objectById(id);
-
- if (hl) {
-
- const comments = this.formatComments(hl);
- const originally_from = this.formatOriginallyFrom(hl);
-
- const article = `<div class="post post-${hl.id}" data-article-id="${hl.id}">
- <div class="header">
- <div class="row">
- <div class="title"><a target="_blank" rel="noopener noreferrer"
- title="${escapeHtml(hl.title)}"
- href="${escapeHtml(hl.link)}">${hl.title}</a></div>
- <div class="date">${hl.updated_long}</div>
- </div>
- <div class="row">
- <div class="buttons left">${hl.buttons_left}</div>
- <div class="comments">${comments}</div>
- <div class="author">${hl.author}</div>
- <i class="material-icons">label_outline</i>
- <span id="ATSTR-${hl.id}">${hl.tags_str}</span>
- &nbsp;<a title="${__("Edit tags for this article")}" href="#"
- onclick="Article.editTags(${hl.id})">(+)</a>
- <div class="buttons right">${hl.buttons}</div>
- </div>
+ row.removeAttribute("data-content");
+
+ PluginHost.run(PluginHost.HOOK_ARTICLE_RENDERED_CDM, row);
+ }
+ },
+ pack: function(row) {
+ if (row.hasAttribute("data-content-original")) {
+ console.log("packing", row.id);
+ row.setAttribute("data-content", row.getAttribute("data-content-original"));
+ row.removeAttribute("data-content-original");
+
+ row.querySelector(".content-inner").innerHTML = "&nbsp;";
+ }
+ },
+ view: function (id, no_expand) {
+ this.setActive(id);
+ Headlines.scrollToArticleId(id);
+
+ if (!no_expand) {
+ const hl = Headlines.objectById(id);
+
+ if (hl) {
+
+ const comments = this.formatComments(hl);
+ const originally_from = this.formatOriginallyFrom(hl);
+
+ const article = `<div class="post post-${hl.id}" data-article-id="${hl.id}">
+ <div class="header">
+ <div class="row">
+ <div class="title"><a target="_blank" rel="noopener noreferrer"
+ title="${escapeHtml(hl.title)}"
+ href="${escapeHtml(hl.link)}">${hl.title}</a></div>
+ <div class="date">${hl.updated_long}</div>
</div>
- <div id="POSTNOTE-${hl.id}">${hl.note}</div>
- <div class="content" lang="${hl.lang ? hl.lang : 'en'}">
- ${originally_from}
- ${hl.content}
- ${hl.enclosures}
+ <div class="row">
+ <div class="buttons left">${hl.buttons_left}</div>
+ <div class="comments">${comments}</div>
+ <div class="author">${hl.author}</div>
+ <i class="material-icons">label_outline</i>
+ <span id="ATSTR-${hl.id}">${hl.tags_str}</span>
+ &nbsp;<a title="${__("Edit tags for this article")}" href="#"
+ onclick="Article.editTags(${hl.id})">(+)</a>
+ <div class="buttons right">${hl.buttons}</div>
</div>
- </div>`;
+ </div>
+ <div id="POSTNOTE-${hl.id}">${hl.note}</div>
+ <div class="content" lang="${hl.lang ? hl.lang : 'en'}">
+ ${originally_from}
+ ${hl.content}
+ ${hl.enclosures}
+ </div>
+ </div>`;
- Headlines.toggleUnread(id, 0);
- this.render(article);
- }
+ Headlines.toggleUnread(id, 0);
+ this.render(article);
}
+ }
- return false;
- },
- editTags: function (id) {
- const query = "backend.php?op=article&method=editArticleTags&param=" + encodeURIComponent(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.close();
- 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) {
- App.Error.report(e);
+ return false;
+ },
+ editTags: function (id) {
+ const query = "backend.php?op=article&method=editArticleTags&param=" + encodeURIComponent(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.close();
+ 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);
}
- });
- }
- },
- href: query
- });
+ } catch (e) {
+ App.Error.report(e);
+ }
+ });
+ }
+ },
+ href: query
+ });
- const tmph = dojo.connect(dialog, 'onLoad', function () {
- dojo.disconnect(tmph);
+ 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"});
- });
+ new Ajax.Autocompleter('tags_str', 'tags_choices',
+ "backend.php?op=article&method=completeTags",
+ {tokens: ',', paramName: "search"});
+ });
- dialog.show();
- },
- cdmMoveToId: function (id, params) {
- params = params || {};
+ dialog.show();
+ },
+ cdmMoveToId: function (id, params) {
+ params = params || {};
- const force_to_top = params.force_to_top || false;
+ const force_to_top = params.force_to_top || false;
- const ctr = $("headlines-frame");
- const row = $("RROW-" + id);
+ const ctr = $("headlines-frame");
+ const row = $("RROW-" + id);
- if (!row || !ctr) return;
+ if (!row || !ctr) return;
- if (force_to_top || !App.Scrollable.fitsInContainer(row, ctr)) {
- ctr.scrollTop = row.offsetTop;
- }
- },
- setActive: function (id) {
- if (id != Article.getActive()) {
- console.log("setActive", id, "was", Article.getActive());
-
- $$("div[id*=RROW][class*=active]").each((row) => {
- row.removeClassName("active");
- Article.pack(row);
- });
+ if (force_to_top || !App.Scrollable.fitsInContainer(row, ctr)) {
+ ctr.scrollTop = row.offsetTop;
+ }
+ },
+ setActive: function (id) {
+ if (id != Article.getActive()) {
+ console.log("setActive", id, "was", Article.getActive());
+
+ $$("div[id*=RROW][class*=active]").each((row) => {
+ row.removeClassName("active");
+ Article.pack(row);
+ });
- const row = $("RROW-" + id);
+ const row = $("RROW-" + id);
- if (row) {
- Article.unpack(row);
+ if (row) {
+ Article.unpack(row);
- row.removeClassName("Unread");
- row.addClassName("active");
+ row.removeClassName("Unread");
+ row.addClassName("active");
- PluginHost.run(PluginHost.HOOK_ARTICLE_SET_ACTIVE, row.getAttribute("data-article-id"));
- }
+ PluginHost.run(PluginHost.HOOK_ARTICLE_SET_ACTIVE, row.getAttribute("data-article-id"));
}
- },
- getActive: function () {
- const row = document.querySelector("#headlines-frame > div[id*=RROW][class*=active]");
-
- if (row)
- return row.getAttribute("data-article-id");
- else
- return 0;
- },
- scrollByPages: function (page_offset) {
- App.Scrollable.scrollByPages($("content-insert"), page_offset);
- },
- scroll: function (offset) {
- App.Scrollable.scroll($("content-insert"), offset);
- },
- mouseIn: function (id) {
- this.post_under_pointer = id;
- },
- mouseOut: function (id) {
- this.post_under_pointer = false;
- },
- getUnderPointer: function () {
- return this.post_under_pointer;
}
+ },
+ getActive: function () {
+ const row = document.querySelector("#headlines-frame > div[id*=RROW][class*=active]");
+
+ if (row)
+ return row.getAttribute("data-article-id");
+ else
+ return 0;
+ },
+ scrollByPages: function (page_offset) {
+ App.Scrollable.scrollByPages($("content-insert"), page_offset);
+ },
+ scroll: function (offset) {
+ App.Scrollable.scroll($("content-insert"), offset);
+ },
+ mouseIn: function (id) {
+ this.post_under_pointer = id;
+ },
+ mouseOut: function (id) {
+ this.post_under_pointer = false;
+ },
+ getUnderPointer: function () {
+ return this.post_under_pointer;
}
-
- return Article;
-});
+}
diff --git a/js/CommonDialogs.js b/js/CommonDialogs.js
index c6d476de0..16e390302 100644
--- a/js/CommonDialogs.js
+++ b/js/CommonDialogs.js
@@ -1,8 +1,7 @@
'use strict'
/* global __, ngettext */
-define(["dojo/_base/declare"], function (declare) {
- // noinspection JSUnusedGlobalSymbols
- CommonDialogs = {
+// noinspection JSUnusedGlobalSymbols
+const CommonDialogs = {
closeInfoBox: function() {
const dialog = dijit.byId("infoBox");
if (dialog) dialog.hide();
@@ -478,6 +477,3 @@ define(["dojo/_base/declare"], function (declare) {
return false;
}
};
-
- return CommonDialogs;
-});
diff --git a/js/CommonFilters.js b/js/CommonFilters.js
index 53573b365..9f0ee579a 100644
--- a/js/CommonFilters.js
+++ b/js/CommonFilters.js
@@ -1,383 +1,380 @@
'use strict'
/* global __, ngettext */
-define(["dojo/_base/declare"], function (declare) {
- Filters = {
- filterDlgCheckAction: function(sender) {
- const action = sender.value;
- const action_param = $("filterDlg_paramBox");
+const Filters = {
+ filterDlgCheckAction: function(sender) {
+ const action = sender.value;
- if (!action_param) {
- console.log("filterDlgCheckAction: can't find action param box!");
- return;
- }
+ const action_param = $("filterDlg_paramBox");
- // if selected action supports parameters, enable params field
- if (action == 4 || action == 6 || action == 7 || action == 9) {
- new Effect.Appear(action_param, {duration: 0.5});
+ if (!action_param) {
+ console.log("filterDlgCheckAction: can't find action param box!");
+ return;
+ }
- Element.hide(dijit.byId("filterDlg_actionParam").domNode);
- Element.hide(dijit.byId("filterDlg_actionParamLabel").domNode);
- Element.hide(dijit.byId("filterDlg_actionParamPlugin").domNode);
+ // if selected action supports parameters, enable params field
+ if (action == 4 || action == 6 || action == 7 || action == 9) {
+ new Effect.Appear(action_param, {duration: 0.5});
- if (action == 7) {
- Element.show(dijit.byId("filterDlg_actionParamLabel").domNode);
- } else if (action == 9) {
- Element.show(dijit.byId("filterDlg_actionParamPlugin").domNode);
- } else {
- Element.show(dijit.byId("filterDlg_actionParam").domNode);
- }
+ Element.hide(dijit.byId("filterDlg_actionParam").domNode);
+ Element.hide(dijit.byId("filterDlg_actionParamLabel").domNode);
+ Element.hide(dijit.byId("filterDlg_actionParamPlugin").domNode);
+ if (action == 7) {
+ Element.show(dijit.byId("filterDlg_actionParamLabel").domNode);
+ } else if (action == 9) {
+ Element.show(dijit.byId("filterDlg_actionParamPlugin").domNode);
} else {
- Element.hide(action_param);
+ Element.show(dijit.byId("filterDlg_actionParam").domNode);
}
- },
- createNewRuleElement: function(parentNode, replaceNode) {
- const form = document.forms["filter_new_rule_form"];
- const query = {op: "pref-filters", method: "printrulename", rule: dojo.formToJson(form)};
-
- xhrPost("backend.php", query, (transport) => {
- try {
- const li = dojo.create("li");
-
- const cb = dojo.create("input", {type: "checkbox"}, li);
-
- new dijit.form.CheckBox({
- onChange: function () {
- Lists.onRowChecked(this);
- },
- }, cb);
-
- dojo.create("input", {
- type: "hidden",
- name: "rule[]",
- value: dojo.formToJson(form)
- }, li);
-
- dojo.create("span", {
- onclick: function () {
- dijit.byId('filterEditDlg').editRule(this);
- },
- innerHTML: transport.responseText
- }, li);
-
- if (replaceNode) {
- parentNode.replaceChild(li, replaceNode);
- } else {
- parentNode.appendChild(li);
- }
- } catch (e) {
- App.Error.report(e);
+
+ } else {
+ Element.hide(action_param);
+ }
+ },
+ createNewRuleElement: function(parentNode, replaceNode) {
+ const form = document.forms["filter_new_rule_form"];
+ const query = {op: "pref-filters", method: "printrulename", rule: dojo.formToJson(form)};
+
+ xhrPost("backend.php", query, (transport) => {
+ try {
+ const li = dojo.create("li");
+
+ const cb = dojo.create("input", {type: "checkbox"}, li);
+
+ new dijit.form.CheckBox({
+ onChange: function () {
+ Lists.onRowChecked(this);
+ },
+ }, cb);
+
+ dojo.create("input", {
+ type: "hidden",
+ name: "rule[]",
+ value: dojo.formToJson(form)
+ }, li);
+
+ dojo.create("span", {
+ onclick: function () {
+ dijit.byId('filterEditDlg').editRule(this);
+ },
+ innerHTML: transport.responseText
+ }, li);
+
+ if (replaceNode) {
+ parentNode.replaceChild(li, replaceNode);
+ } else {
+ parentNode.appendChild(li);
}
- });
- },
- createNewActionElement: function(parentNode, replaceNode) {
- const form = document.forms["filter_new_action_form"];
-
- if (form.action_id.value == 7) {
- form.action_param.value = form.action_param_label.value;
- } else if (form.action_id.value == 9) {
- form.action_param.value = form.action_param_plugin.value;
+ } catch (e) {
+ App.Error.report(e);
}
-
- const query = {
- op: "pref-filters", method: "printactionname",
- action: dojo.formToJson(form)
- };
-
- xhrPost("backend.php", query, (transport) => {
- try {
- const li = dojo.create("li");
-
- const cb = dojo.create("input", {type: "checkbox"}, li);
-
- new dijit.form.CheckBox({
- onChange: function () {
- Lists.onRowChecked(this);
- },
- }, cb);
-
- dojo.create("input", {
- type: "hidden",
- name: "action[]",
- value: dojo.formToJson(form)
- }, li);
-
- dojo.create("span", {
- onclick: function () {
- dijit.byId('filterEditDlg').editAction(this);
- },
- innerHTML: transport.responseText
- }, li);
-
- if (replaceNode) {
- parentNode.replaceChild(li, replaceNode);
- } else {
- parentNode.appendChild(li);
- }
-
- } catch (e) {
- App.Error.report(e);
+ });
+ },
+ createNewActionElement: function(parentNode, replaceNode) {
+ const form = document.forms["filter_new_action_form"];
+
+ if (form.action_id.value == 7) {
+ form.action_param.value = form.action_param_label.value;
+ } else if (form.action_id.value == 9) {
+ form.action_param.value = form.action_param_plugin.value;
+ }
+
+ const query = {
+ op: "pref-filters", method: "printactionname",
+ action: dojo.formToJson(form)
+ };
+
+ xhrPost("backend.php", query, (transport) => {
+ try {
+ const li = dojo.create("li");
+
+ const cb = dojo.create("input", {type: "checkbox"}, li);
+
+ new dijit.form.CheckBox({
+ onChange: function () {
+ Lists.onRowChecked(this);
+ },
+ }, cb);
+
+ dojo.create("input", {
+ type: "hidden",
+ name: "action[]",
+ value: dojo.formToJson(form)
+ }, li);
+
+ dojo.create("span", {
+ onclick: function () {
+ dijit.byId('filterEditDlg').editAction(this);
+ },
+ innerHTML: transport.responseText
+ }, li);
+
+ if (replaceNode) {
+ parentNode.replaceChild(li, replaceNode);
+ } else {
+ parentNode.appendChild(li);
}
- });
- },
- addFilterRule: function(replaceNode, ruleStr) {
- if (dijit.byId("filterNewRuleDlg"))
- dijit.byId("filterNewRuleDlg").destroyRecursive();
-
- const rule_dlg = new dijit.Dialog({
- id: "filterNewRuleDlg",
- title: ruleStr ? __("Edit rule") : __("Add rule"),
- style: "width: 600px",
- execute: function () {
- if (this.validate()) {
- Filters.createNewRuleElement($("filterDlg_Matches"), replaceNode);
- this.hide();
- }
- },
- content: __('Loading, please wait...'),
- });
- const tmph = dojo.connect(rule_dlg, "onShow", null, function (e) {
- dojo.disconnect(tmph);
+ } catch (e) {
+ App.Error.report(e);
+ }
+ });
+ },
+ addFilterRule: function(replaceNode, ruleStr) {
+ if (dijit.byId("filterNewRuleDlg"))
+ dijit.byId("filterNewRuleDlg").destroyRecursive();
+
+ const rule_dlg = new dijit.Dialog({
+ id: "filterNewRuleDlg",
+ title: ruleStr ? __("Edit rule") : __("Add rule"),
+ style: "width: 600px",
+ execute: function () {
+ if (this.validate()) {
+ Filters.createNewRuleElement($("filterDlg_Matches"), replaceNode);
+ this.hide();
+ }
+ },
+ content: __('Loading, please wait...'),
+ });
- xhrPost("backend.php", {op: 'pref-filters', method: 'newrule', rule: ruleStr}, (transport) => {
- rule_dlg.attr('content', transport.responseText);
- });
- });
+ const tmph = dojo.connect(rule_dlg, "onShow", null, function (e) {
+ dojo.disconnect(tmph);
- rule_dlg.show();
- },
- addFilterAction: function(replaceNode, actionStr) {
- if (dijit.byId("filterNewActionDlg"))
- dijit.byId("filterNewActionDlg").destroyRecursive();
-
- const query = "backend.php?op=pref-filters&method=newaction&action=" +
- encodeURIComponent(actionStr);
-
- const rule_dlg = new dijit.Dialog({
- id: "filterNewActionDlg",
- title: actionStr ? __("Edit action") : __("Add action"),
- style: "width: 600px",
- execute: function () {
- if (this.validate()) {
- Filters.createNewActionElement($("filterDlg_Actions"), replaceNode);
- this.hide();
- }
- },
- href: query
+ xhrPost("backend.php", {op: 'pref-filters', method: 'newrule', rule: ruleStr}, (transport) => {
+ rule_dlg.attr('content', transport.responseText);
});
+ });
+
+ rule_dlg.show();
+ },
+ addFilterAction: function(replaceNode, actionStr) {
+ if (dijit.byId("filterNewActionDlg"))
+ dijit.byId("filterNewActionDlg").destroyRecursive();
+
+ const query = "backend.php?op=pref-filters&method=newaction&action=" +
+ encodeURIComponent(actionStr);
+
+ const rule_dlg = new dijit.Dialog({
+ id: "filterNewActionDlg",
+ title: actionStr ? __("Edit action") : __("Add action"),
+ style: "width: 600px",
+ execute: function () {
+ if (this.validate()) {
+ Filters.createNewActionElement($("filterDlg_Actions"), replaceNode);
+ this.hide();
+ }
+ },
+ href: query
+ });
- rule_dlg.show();
- },
- editFilterTest: function(params) {
-
- if (dijit.byId("filterTestDlg"))
- dijit.byId("filterTestDlg").destroyRecursive();
-
- const test_dlg = new dijit.Dialog({
- id: "filterTestDlg",
- title: "Test Filter",
- style: "width: 600px",
- results: 0,
- limit: 100,
- max_offset: 10000,
- getTestResults: function (params, offset) {
- params.method = 'testFilterDo';
- params.offset = offset;
- params.limit = test_dlg.limit;
-
- console.log("getTestResults:" + offset);
-
- xhrPost("backend.php", params, (transport) => {
- try {
- const result = JSON.parse(transport.responseText);
+ rule_dlg.show();
+ },
+ editFilterTest: function(params) {
- if (result && dijit.byId("filterTestDlg") && dijit.byId("filterTestDlg").open) {
- test_dlg.results += result.length;
+ if (dijit.byId("filterTestDlg"))
+ dijit.byId("filterTestDlg").destroyRecursive();
- console.log("got results:" + result.length);
+ const test_dlg = new dijit.Dialog({
+ id: "filterTestDlg",
+ title: "Test Filter",
+ style: "width: 600px",
+ results: 0,
+ limit: 100,
+ max_offset: 10000,
+ getTestResults: function (params, offset) {
+ params.method = 'testFilterDo';
+ params.offset = offset;
+ params.limit = test_dlg.limit;
- $("prefFilterProgressMsg").innerHTML = __("Looking for articles (%d processed, %f found)...")
- .replace("%f", test_dlg.results)
- .replace("%d", offset);
+ console.log("getTestResults:" + offset);
- console.log(offset + " " + test_dlg.max_offset);
+ xhrPost("backend.php", params, (transport) => {
+ try {
+ const result = JSON.parse(transport.responseText);
- for (let i = 0; i < result.length; i++) {
- const tmp = dojo.create("table", { innerHTML: result[i]});
+ if (result && dijit.byId("filterTestDlg") && dijit.byId("filterTestDlg").open) {
+ test_dlg.results += result.length;
- $("prefFilterTestResultList").innerHTML += tmp.innerHTML;
- }
+ console.log("got results:" + result.length);
- if (test_dlg.results < 30 && offset < test_dlg.max_offset) {
+ $("prefFilterProgressMsg").innerHTML = __("Looking for articles (%d processed, %f found)...")
+ .replace("%f", test_dlg.results)
+ .replace("%d", offset);
- // get the next batch
- window.setTimeout(function () {
- test_dlg.getTestResults(params, offset + test_dlg.limit);
- }, 0);
+ console.log(offset + " " + test_dlg.max_offset);
- } else {
- // all done
+ for (let i = 0; i < result.length; i++) {
+ const tmp = dojo.create("table", { innerHTML: result[i]});
- Element.hide("prefFilterLoadingIndicator");
+ $("prefFilterTestResultList").innerHTML += tmp.innerHTML;
+ }
- if (test_dlg.results == 0) {
- $("prefFilterTestResultList").innerHTML = `<tr><td align='center'>
- ${__('No recent articles matching this filter have been found.')}</td></tr>`;
- $("prefFilterProgressMsg").innerHTML = "Articles matching this filter:";
- } else {
- $("prefFilterProgressMsg").innerHTML = __("Found %d articles matching this filter:")
- .replace("%d", test_dlg.results);
- }
+ if (test_dlg.results < 30 && offset < test_dlg.max_offset) {
- }
+ // get the next batch
+ window.setTimeout(function () {
+ test_dlg.getTestResults(params, offset + test_dlg.limit);
+ }, 0);
- } else if (!result) {
- console.log("getTestResults: can't parse results object");
+ } else {
+ // all done
Element.hide("prefFilterLoadingIndicator");
- Notify.error("Error while trying to get filter test results.");
+ if (test_dlg.results == 0) {
+ $("prefFilterTestResultList").innerHTML = `<tr><td align='center'>
+ ${__('No recent articles matching this filter have been found.')}</td></tr>`;
+ $("prefFilterProgressMsg").innerHTML = "Articles matching this filter:";
+ } else {
+ $("prefFilterProgressMsg").innerHTML = __("Found %d articles matching this filter:")
+ .replace("%d", test_dlg.results);
+ }
- } else {
- console.log("getTestResults: dialog closed, bailing out.");
}
- } catch (e) {
- App.Error.report(e);
- }
-
- });
- },
- href: "backend.php?op=pref-filters&method=testFilterDlg"
- });
- dojo.connect(test_dlg, "onLoad", null, function (e) {
- test_dlg.getTestResults(params, 0);
- });
+ } else if (!result) {
+ console.log("getTestResults: can't parse results object");
- test_dlg.show();
- },
- quickAddFilter: function() {
- let query;
+ Element.hide("prefFilterLoadingIndicator");
- if (!App.isPrefs()) {
- query = {
- op: "pref-filters", method: "newfilter",
- feed: Feeds.getActive(), is_cat: Feeds.activeIsCat()
- };
- } else {
- query = {op: "pref-filters", method: "newfilter"};
- }
+ Notify.error("Error while trying to get filter test results.");
- console.log('quickAddFilter', query);
-
- if (dijit.byId("feedEditDlg"))
- dijit.byId("feedEditDlg").destroyRecursive();
-
- if (dijit.byId("filterEditDlg"))
- dijit.byId("filterEditDlg").destroyRecursive();
-
- const dialog = new dijit.Dialog({
- id: "filterEditDlg",
- title: __("Create Filter"),
- style: "width: 600px",
- test: function () {
- Filters.editFilterTest(dojo.formToObject("filter_new_form"));
- },
- selectRules: function (select) {
- Lists.select("filterDlg_Matches", select);
- },
- selectActions: function (select) {
- Lists.select("filterDlg_Actions", select);
- },
- 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);
- },
- 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()) {
+ } else {
+ console.log("getTestResults: dialog closed, bailing out.");
+ }
+ } catch (e) {
+ App.Error.report(e);
+ }
- const query = dojo.formToQuery("filter_new_form");
+ });
+ },
+ href: "backend.php?op=pref-filters&method=testFilterDlg"
+ });
+
+ dojo.connect(test_dlg, "onLoad", null, function (e) {
+ test_dlg.getTestResults(params, 0);
+ });
+
+ test_dlg.show();
+ },
+ quickAddFilter: function() {
+ let query;
+
+ if (!App.isPrefs()) {
+ query = {
+ op: "pref-filters", method: "newfilter",
+ feed: Feeds.getActive(), is_cat: Feeds.activeIsCat()
+ };
+ } else {
+ query = {op: "pref-filters", method: "newfilter"};
+ }
+
+ console.log('quickAddFilter', query);
+
+ if (dijit.byId("feedEditDlg"))
+ dijit.byId("feedEditDlg").destroyRecursive();
+
+ if (dijit.byId("filterEditDlg"))
+ dijit.byId("filterEditDlg").destroyRecursive();
+
+ const dialog = new dijit.Dialog({
+ id: "filterEditDlg",
+ title: __("Create Filter"),
+ style: "width: 600px",
+ test: function () {
+ Filters.editFilterTest(dojo.formToObject("filter_new_form"));
+ },
+ selectRules: function (select) {
+ Lists.select("filterDlg_Matches", select);
+ },
+ selectActions: function (select) {
+ Lists.select("filterDlg_Actions", select);
+ },
+ 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);
+ },
+ 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()) {
- xhrPost("backend.php", query, () => {
- if (App.isPrefs()) {
- dijit.byId("filterTree").reload();
- }
+ const query = dojo.formToQuery("filter_new_form");
- dialog.hide();
- });
- }
- },
- href: "backend.php?" + dojo.objectToQuery(query)
- });
+ xhrPost("backend.php", query, () => {
+ if (App.isPrefs()) {
+ dijit.byId("filterTree").reload();
+ }
- if (!App.isPrefs()) {
- const selectedText = getSelectionText();
+ dialog.hide();
+ });
+ }
+ },
+ href: "backend.php?" + dojo.objectToQuery(query)
+ });
- const lh = dojo.connect(dialog, "onLoad", function () {
- dojo.disconnect(lh);
+ if (!App.isPrefs()) {
+ const selectedText = getSelectionText();
- if (selectedText != "") {
+ const lh = dojo.connect(dialog, "onLoad", function () {
+ dojo.disconnect(lh);
- const feed_id = Feeds.activeIsCat() ? 'CAT:' + parseInt(Feeds.getActive()) :
- Feeds.getActive();
+ if (selectedText != "") {
- const rule = {reg_exp: selectedText, feed_id: [feed_id], filter_type: 1};
+ const feed_id = Feeds.activeIsCat() ? 'CAT:' + parseInt(Feeds.getActive()) :
+ Feeds.getActive();
- Filters.addFilterRule(null, dojo.toJson(rule));
+ const rule = {reg_exp: selectedText, feed_id: [feed_id], filter_type: 1};
- } else {
+ Filters.addFilterRule(null, dojo.toJson(rule));
- const query = {op: "rpc", method: "getlinktitlebyid", id: Article.getActive()};
+ } else {
- xhrPost("backend.php", query, (transport) => {
- const reply = JSON.parse(transport.responseText);
+ const query = {op: "rpc", method: "getlinktitlebyid", id: Article.getActive()};
- let title = false;
+ xhrPost("backend.php", query, (transport) => {
+ const reply = JSON.parse(transport.responseText);
- if (reply && reply.title) title = reply.title;
+ let title = false;
- if (title || Feeds.getActive() || Feeds.activeIsCat()) {
+ if (reply && reply.title) title = reply.title;
- console.log(title + " " + Feeds.getActive());
+ if (title || Feeds.getActive() || Feeds.activeIsCat()) {
- const feed_id = Feeds.activeIsCat() ? 'CAT:' + parseInt(Feeds.getActive()) :
- Feeds.getActive();
+ console.log(title + " " + Feeds.getActive());
- const rule = {reg_exp: title, feed_id: [feed_id], filter_type: 1};
+ const feed_id = Feeds.activeIsCat() ? 'CAT:' + parseInt(Feeds.getActive()) :
+ Feeds.getActive();
- Filters.addFilterRule(null, dojo.toJson(rule));
- }
- });
- }
- });
- }
- dialog.show();
- },
- };
+ const rule = {reg_exp: title, feed_id: [feed_id], filter_type: 1};
- return Filters;
-});
+ Filters.addFilterRule(null, dojo.toJson(rule));
+ }
+ });
+ }
+ });
+ }
+ dialog.show();
+ },
+};
diff --git a/js/Feeds.js b/js/Feeds.js
index 7fa376984..81629f14b 100644
--- a/js/Feeds.js
+++ b/js/Feeds.js
@@ -1,604 +1,601 @@
'use strict'
/* global __, ngettext */
-define(["dojo/_base/declare"], function (declare) {
- Feeds = {
- counters_last_request: 0,
- _active_feed_id: undefined,
- _active_feed_is_cat: false,
- infscroll_in_progress: 0,
- infscroll_disabled: 0,
- _infscroll_timeout: false,
- _search_query: false,
- last_search_query: [],
- _viewfeed_wait_timeout: false,
- _counters_prev: [],
- // NOTE: this implementation is incomplete
- // for general objects but good enough for counters
- // http://adripofjavascript.com/blog/drips/object-equality-in-javascript.html
- counterEquals: function(a, b) {
- // Create arrays of property names
- const aProps = Object.getOwnPropertyNames(a);
- const bProps = Object.getOwnPropertyNames(b);
-
- // If number of properties is different,
- // objects are not equivalent
- if (aProps.length != bProps.length) {
- return false;
- }
-
- for (let i = 0; i < aProps.length; i++) {
- const propName = aProps[i];
-
- // If values of same property are not equal,
- // objects are not equivalent
- if (a[propName] !== b[propName]) {
- return false;
- }
- }
-
- // If we made it this far, objects
- // are considered equivalent
- return true;
- },
- resetCounters: function () {
- this._counters_prev = [];
- },
- parseCounters: function (elems) {
- PluginHost.run(PluginHost.HOOK_COUNTERS_RECEIVED, elems);
- for (let l = 0; l < elems.length; l++) {
-
- if (Feeds._counters_prev[l] && this.counterEquals(elems[l], this._counters_prev[l])) {
- continue;
- }
+const Feeds = {
+ counters_last_request: 0,
+ _active_feed_id: undefined,
+ _active_feed_is_cat: false,
+ infscroll_in_progress: 0,
+ infscroll_disabled: 0,
+ _infscroll_timeout: false,
+ _search_query: false,
+ last_search_query: [],
+ _viewfeed_wait_timeout: false,
+ _counters_prev: [],
+ // NOTE: this implementation is incomplete
+ // for general objects but good enough for counters
+ // http://adripofjavascript.com/blog/drips/object-equality-in-javascript.html
+ counterEquals: function(a, b) {
+ // Create arrays of property names
+ const aProps = Object.getOwnPropertyNames(a);
+ const bProps = Object.getOwnPropertyNames(b);
+
+ // If number of properties is different,
+ // objects are not equivalent
+ if (aProps.length != bProps.length) {
+ return false;
+ }
- const id = elems[l].id;
- const kind = elems[l].kind;
- const ctr = parseInt(elems[l].counter);
- const error = elems[l].error;
- const has_img = elems[l].has_img;
- const updated = elems[l].updated;
-
- if (id == "global-unread") {
- App.global_unread = ctr;
- App.updateTitle();
- continue;
- }
+ for (let i = 0; i < aProps.length; i++) {
+ const propName = aProps[i];
- if (id == "subscribed-feeds") {
- /* feeds_found = ctr; */
- continue;
- }
-
- /*if (this.getUnread(id, (kind == "cat")) != ctr ||
- (kind == "cat")) {
- }*/
-
- this.setUnread(id, (kind == "cat"), ctr);
- this.setValue(id, (kind == "cat"), 'auxcounter', parseInt(elems[l].auxcounter));
- this.setValue(id, (kind == "cat"), 'markedcounter', parseInt(elems[l].markedcounter));
-
- if (kind != "cat") {
- this.setValue(id, false, 'error', error);
- this.setValue(id, false, 'updated', updated);
-
- if (id > 0) {
- if (has_img) {
- this.setIcon(id, false,
- App.getInitParam("icons_url") + "/" + id + ".ico?" + has_img);
- } else {
- this.setIcon(id, false, 'images/blank_icon.gif');
- }
- }
- }
+ // If values of same property are not equal,
+ // objects are not equivalent
+ if (a[propName] !== b[propName]) {
+ return false;
}
-
- Headlines.updateCurrentUnread();
-
- this.hideOrShowFeeds(App.getInitParam("hide_read_feeds"));
- this._counters_prev = elems;
-
- PluginHost.run(PluginHost.HOOK_COUNTERS_PROCESSED);
- },
- reloadCurrent: function(method) {
- if (this.getActive() != undefined) {
- console.log("reloadCurrent: " + method);
-
- this.open({feed: this.getActive(), is_cat: this.activeIsCat(), method: method});
+ }
+
+ // If we made it this far, objects
+ // are considered equivalent
+ return true;
+ },
+ resetCounters: function () {
+ this._counters_prev = [];
+ },
+ parseCounters: function (elems) {
+ PluginHost.run(PluginHost.HOOK_COUNTERS_RECEIVED, elems);
+
+ for (let l = 0; l < elems.length; l++) {
+
+ if (Feeds._counters_prev[l] && this.counterEquals(elems[l], this._counters_prev[l])) {
+ continue;
}
- return false; // block unneeded form submits
- },
- openNextUnread: function() {
- const is_cat = this.activeIsCat();
- const nuf = this.getNextUnread(this.getActive(), is_cat);
- if (nuf) this.open({feed: nuf, is_cat: is_cat});
- },
- toggle: function() {
- Element.toggle("feeds-holder");
-
- const splitter = $("feeds-holder_splitter");
-
- Element.visible("feeds-holder") ? splitter.show() : splitter.hide();
-
- dijit.byId("main").resize();
-
- Headlines.updateCurrentUnread();
- },
- cancelSearch: function() {
- this._search_query = "";
- this.reloadCurrent();
- },
- requestCounters: function() {
- xhrPost("backend.php", {op: "rpc", method: "getAllCounters", seq: App.next_seq()}, (transport) => {
- App.handleRpcJson(transport);
- });
- },
- reload: function() {
- try {
- Element.show("feedlistLoading");
- this.resetCounters();
+ const id = elems[l].id;
+ const kind = elems[l].kind;
+ const ctr = parseInt(elems[l].counter);
+ const error = elems[l].error;
+ const has_img = elems[l].has_img;
+ const updated = elems[l].updated;
- if (dijit.byId("feedTree")) {
- dijit.byId("feedTree").destroyRecursive();
- }
-
- const store = new dojo.data.ItemFileWriteStore({
- url: "backend.php?op=pref_feeds&method=getfeedtree&mode=2"
- });
-
- // noinspection JSUnresolvedFunction
- const treeModel = new fox.FeedStoreModel({
- store: store,
- query: {
- "type": App.getInitParam('enable_feed_cats') ? "category" : "feed"
- },
- rootId: "root",
- rootLabel: "Feeds",
- childrenAttrs: ["items"]
- });
-
- // noinspection JSUnresolvedFunction
- const tree = new fox.FeedTree({
- model: treeModel,
- onClick: function (item/*, node*/) {
- const id = String(item.id);
- const is_cat = id.match("^CAT:");
- const feed = id.substr(id.indexOf(":") + 1);
- Feeds.open({feed: feed, is_cat: is_cat});
- return false;
- },
- openOnClick: false,
- showRoot: false,
- persist: true,
- id: "feedTree",
- }, "feedTree");
-
- const tmph = dojo.connect(dijit.byId('feedMenu'), '_openMyself', function (event) {
- console.log(dijit.getEnclosingWidget(event.target));
- dojo.disconnect(tmph);
- });
-
- $("feeds-holder").appendChild(tree.domNode);
-
- const tmph2 = dojo.connect(tree, 'onLoad', function () {
- dojo.disconnect(tmph2);
- Element.hide("feedlistLoading");
-
- try {
- Feeds.init();
- App.setLoadingProgress(25);
- } catch (e) {
- App.Error.report(e);
- }
- });
-
- tree.startup();
- } catch (e) {
- App.Error.report(e);
+ if (id == "global-unread") {
+ App.global_unread = ctr;
+ App.updateTitle();
+ continue;
}
- },
- init: function() {
- console.log("in feedlist init");
- App.setLoadingProgress(50);
+ if (id == "subscribed-feeds") {
+ /* feeds_found = ctr; */
+ continue;
+ }
- document.onkeydown = (event) => { return App.hotkeyHandler(event) };
- document.onkeypress = (event) => { return App.hotkeyHandler(event) };
- window.onresize = () => { Headlines.scrollHandler(); }
+ /*if (this.getUnread(id, (kind == "cat")) != ctr ||
+ (kind == "cat")) {
+ }*/
- const hash_feed_id = hash_get('f');
- const hash_feed_is_cat = hash_get('c') == "1";
+ this.setUnread(id, (kind == "cat"), ctr);
+ this.setValue(id, (kind == "cat"), 'auxcounter', parseInt(elems[l].auxcounter));
+ this.setValue(id, (kind == "cat"), 'markedcounter', parseInt(elems[l].markedcounter));
- if (hash_feed_id != undefined) {
- this.open({feed: hash_feed_id, is_cat: hash_feed_is_cat});
- } else {
- this.open({feed: -3});
- }
+ if (kind != "cat") {
+ this.setValue(id, false, 'error', error);
+ this.setValue(id, false, 'updated', updated);
- this.hideOrShowFeeds(App.getInitParam("hide_read_feeds"));
-
- if (App.getInitParam("is_default_pw")) {
- console.warn("user password is at default value");
-
- if (dijit.byId("defaultPasswordDlg"))
- dijit.byId("defaultPasswordDlg").destroyRecursive();
-
- const dialog = new dijit.Dialog({
- title: __("Your password is at default value"),
- href: "backend.php?op=dlg&method=defaultpasswordwarning",
- id: 'defaultPasswordDlg',
- style: "width: 600px",
- onCancel: function () {
- return true;
- },
- onExecute: function () {
- return true;
- },
- onClose: function () {
- return true;
+ if (id > 0) {
+ if (has_img) {
+ this.setIcon(id, false,
+ App.getInitParam("icons_url") + "/" + id + ".ico?" + has_img);
+ } else {
+ this.setIcon(id, false, 'images/blank_icon.gif');
}
- });
-
- dialog.show();
+ }
}
-
- // bw_limit disables timeout() so we request initial counters separately
- if (App.getInitParam("bw_limit")) {
- this.requestCounters(true);
- } else {
- setTimeout(() => {
- this.requestCounters(true);
- setInterval(() => { this.requestCounters(); }, 60 * 1000)
- }, 250);
+ }
+
+ Headlines.updateCurrentUnread();
+
+ this.hideOrShowFeeds(App.getInitParam("hide_read_feeds"));
+ this._counters_prev = elems;
+
+ PluginHost.run(PluginHost.HOOK_COUNTERS_PROCESSED);
+ },
+ reloadCurrent: function(method) {
+ if (this.getActive() != undefined) {
+ console.log("reloadCurrent: " + method);
+
+ this.open({feed: this.getActive(), is_cat: this.activeIsCat(), method: method});
+ }
+ return false; // block unneeded form submits
+ },
+ openNextUnread: function() {
+ const is_cat = this.activeIsCat();
+ const nuf = this.getNextUnread(this.getActive(), is_cat);
+ if (nuf) this.open({feed: nuf, is_cat: is_cat});
+ },
+ toggle: function() {
+ Element.toggle("feeds-holder");
+
+ const splitter = $("feeds-holder_splitter");
+
+ Element.visible("feeds-holder") ? splitter.show() : splitter.hide();
+
+ dijit.byId("main").resize();
+
+ Headlines.updateCurrentUnread();
+ },
+ cancelSearch: function() {
+ this._search_query = "";
+ this.reloadCurrent();
+ },
+ requestCounters: function() {
+ xhrPost("backend.php", {op: "rpc", method: "getAllCounters", seq: App.next_seq()}, (transport) => {
+ App.handleRpcJson(transport);
+ });
+ },
+ reload: function() {
+ try {
+ Element.show("feedlistLoading");
+
+ this.resetCounters();
+
+ if (dijit.byId("feedTree")) {
+ dijit.byId("feedTree").destroyRecursive();
}
- },
- activeIsCat: function() {
- return !!this._active_feed_is_cat;
- },
- getActive: function() {
- return this._active_feed_id;
- },
- setActive: function(id, is_cat) {
- console.log('setActive', id, is_cat);
-
- hash_set('f', id);
- hash_set('c', is_cat ? 1 : 0);
-
- this._active_feed_id = id;
- this._active_feed_is_cat = is_cat;
-
- $("headlines-frame").setAttribute("feed-id", id);
- $("headlines-frame").setAttribute("is-cat", is_cat ? 1 : 0);
-
- this.select(id, is_cat);
-
- PluginHost.run(PluginHost.HOOK_FEED_SET_ACTIVE, [this._active_feed_id, this._active_feed_is_cat]);
- },
- select: function(feed, is_cat) {
- const tree = dijit.byId("feedTree");
- if (tree) return tree.selectFeed(feed, is_cat);
- },
- toggleUnread: function() {
- const hide = !App.getInitParam("hide_read_feeds");
+ const store = new dojo.data.ItemFileWriteStore({
+ url: "backend.php?op=pref_feeds&method=getfeedtree&mode=2"
+ });
- xhrPost("backend.php", {op: "rpc", method: "setpref", key: "HIDE_READ_FEEDS", value: hide}, () => {
- this.hideOrShowFeeds(hide);
- App.setInitParam("hide_read_feeds", hide);
+ // noinspection JSUnresolvedFunction
+ const treeModel = new fox.FeedStoreModel({
+ store: store,
+ query: {
+ "type": App.getInitParam('enable_feed_cats') ? "category" : "feed"
+ },
+ rootId: "root",
+ rootLabel: "Feeds",
+ childrenAttrs: ["items"]
});
- },
- hideOrShowFeeds: function (hide) {
- /*const tree = dijit.byId("feedTree");
-
- if (tree)
- return tree.hideRead(hide, App.getInitParam("hide_read_shows_special"));*/
-
- $$("body")[0].setAttribute("hide-read-feeds", !!hide);
- $$("body")[0].setAttribute("hide-read-shows-special", !!App.getInitParam("hide_read_shows_special"));
- },
- open: function(params) {
- const feed = params.feed;
- const is_cat = !!params.is_cat || false;
- const offset = params.offset || 0;
- const viewfeed_debug = params.viewfeed_debug;
- const append = params.append || false;
- const method = params.method;
- // this is used to quickly switch between feeds, sets active but xhr is on a timeout
- const delayed = params.delayed || false;
-
- if (offset != 0) {
- if (this.infscroll_in_progress)
- return;
-
- this.infscroll_in_progress = 1;
-
- window.clearTimeout(this._infscroll_timeout);
- this._infscroll_timeout = window.setTimeout(() => {
- console.log('infscroll request timed out, aborting');
- this.infscroll_in_progress = 0;
-
- // call scroll handler to maybe repeat infscroll request
- Headlines.scrollHandler();
- }, 10 * 1000);
- }
- Form.enable("toolbar-main");
+ // noinspection JSUnresolvedFunction
+ const tree = new fox.FeedTree({
+ model: treeModel,
+ onClick: function (item/*, node*/) {
+ const id = String(item.id);
+ const is_cat = id.match("^CAT:");
+ const feed = id.substr(id.indexOf(":") + 1);
+ Feeds.open({feed: feed, is_cat: is_cat});
+ return false;
+ },
+ openOnClick: false,
+ showRoot: false,
+ persist: true,
+ id: "feedTree",
+ }, "feedTree");
+
+ const tmph = dojo.connect(dijit.byId('feedMenu'), '_openMyself', function (event) {
+ console.log(dijit.getEnclosingWidget(event.target));
+ dojo.disconnect(tmph);
+ });
- let query = Object.assign({op: "feeds", method: "view", feed: feed},
- dojo.formToObject("toolbar-main"));
+ $("feeds-holder").appendChild(tree.domNode);
- if (method) query.m = method;
+ const tmph2 = dojo.connect(tree, 'onLoad', function () {
+ dojo.disconnect(tmph2);
+ Element.hide("feedlistLoading");
- if (offset > 0) {
- if (Headlines.current_first_id) {
- query.fid = Headlines.current_first_id;
+ try {
+ Feeds.init();
+ App.setLoadingProgress(25);
+ } catch (e) {
+ App.Error.report(e);
}
- }
-
- if (this._search_query) {
- query = Object.assign(query, this._search_query);
- }
-
- if (offset != 0) {
- query.skip = offset;
- } else if (!is_cat && feed == this.getActive() && !params.method) {
- query.m = "ForceUpdate";
- }
-
- Form.enable("toolbar-main");
-
- if (!delayed)
- if (!this.setExpando(feed, is_cat,
- (is_cat) ? 'images/indicator_tiny.gif' : 'images/indicator_white.gif'))
- Notify.progress("Loading, please wait...", true);
+ });
- query.cat = is_cat;
+ tree.startup();
+ } catch (e) {
+ App.Error.report(e);
+ }
+ },
+ init: function() {
+ console.log("in feedlist init");
- this.setActive(feed, is_cat);
+ App.setLoadingProgress(50);
- if (viewfeed_debug) {
- window.open("backend.php?" +
- dojo.objectToQuery(
- Object.assign({csrf_token: App.getInitParam("csrf_token")}, query)
- ));
- }
+ document.onkeydown = (event) => { return App.hotkeyHandler(event) };
+ document.onkeypress = (event) => { return App.hotkeyHandler(event) };
+ window.onresize = () => { Headlines.scrollHandler(); }
- window.clearTimeout(this._viewfeed_wait_timeout);
- this._viewfeed_wait_timeout = window.setTimeout(() => {
- xhrPost("backend.php", query, (transport) => {
- try {
- window.clearTimeout(this._infscroll_timeout);
- this.setExpando(feed, is_cat, 'images/blank_icon.gif');
- Headlines.onLoaded(transport, offset, append);
- PluginHost.run(PluginHost.HOOK_FEED_LOADED, [feed, is_cat]);
- } catch (e) {
- App.Error.report(e);
- }
- });
- }, delayed ? 250 : 0);
- },
- catchupAll: function() {
- const str = __("Mark all articles as read?");
+ const hash_feed_id = hash_get('f');
+ const hash_feed_is_cat = hash_get('c') == "1";
- if (App.getInitParam("confirm_feed_catchup") != 1 || confirm(str)) {
+ if (hash_feed_id != undefined) {
+ this.open({feed: hash_feed_id, is_cat: hash_feed_is_cat});
+ } else {
+ this.open({feed: -3});
+ }
- Notify.progress("Marking all feeds as read...");
+ this.hideOrShowFeeds(App.getInitParam("hide_read_feeds"));
- xhrPost("backend.php", {op: "feeds", method: "catchupAll"}, () => {
- this.requestCounters(true);
- this.reloadCurrent();
- });
+ if (App.getInitParam("is_default_pw")) {
+ console.warn("user password is at default value");
- App.global_unread = 0;
- App.updateTitle();
- }
- },
- catchupFeed: function(feed, is_cat, mode) {
- is_cat = is_cat || false;
-
- let str = false;
-
- switch (mode) {
- case "1day":
- str = __("Mark %w in %s older than 1 day as read?");
- break;
- case "1week":
- str = __("Mark %w in %s older than 1 week as read?");
- break;
- case "2week":
- str = __("Mark %w in %s older than 2 weeks as read?");
- break;
- default:
- str = __("Mark %w in %s as read?");
- }
+ if (dijit.byId("defaultPasswordDlg"))
+ dijit.byId("defaultPasswordDlg").destroyRecursive();
- const mark_what = this.last_search_query && this.last_search_query[0] ? __("search results") : __("all articles");
- const fn = this.getName(feed, is_cat);
+ const dialog = new dijit.Dialog({
+ title: __("Your password is at default value"),
+ href: "backend.php?op=dlg&method=defaultpasswordwarning",
+ id: 'defaultPasswordDlg',
+ style: "width: 600px",
+ onCancel: function () {
+ return true;
+ },
+ onExecute: function () {
+ return true;
+ },
+ onClose: function () {
+ return true;
+ }
+ });
- str = str.replace("%s", fn)
- .replace("%w", mark_what);
+ dialog.show();
+ }
- if (App.getInitParam("confirm_feed_catchup") && !confirm(str)) {
+ // bw_limit disables timeout() so we request initial counters separately
+ if (App.getInitParam("bw_limit")) {
+ this.requestCounters(true);
+ } else {
+ setTimeout(() => {
+ this.requestCounters(true);
+ setInterval(() => { this.requestCounters(); }, 60 * 1000)
+ }, 250);
+ }
+ },
+ activeIsCat: function() {
+ return !!this._active_feed_is_cat;
+ },
+ getActive: function() {
+ return this._active_feed_id;
+ },
+ setActive: function(id, is_cat) {
+ console.log('setActive', id, is_cat);
+
+ hash_set('f', id);
+ hash_set('c', is_cat ? 1 : 0);
+
+ this._active_feed_id = id;
+ this._active_feed_is_cat = is_cat;
+
+ $("headlines-frame").setAttribute("feed-id", id);
+ $("headlines-frame").setAttribute("is-cat", is_cat ? 1 : 0);
+
+ this.select(id, is_cat);
+
+ PluginHost.run(PluginHost.HOOK_FEED_SET_ACTIVE, [this._active_feed_id, this._active_feed_is_cat]);
+ },
+ select: function(feed, is_cat) {
+ const tree = dijit.byId("feedTree");
+
+ if (tree) return tree.selectFeed(feed, is_cat);
+ },
+ toggleUnread: function() {
+ const hide = !App.getInitParam("hide_read_feeds");
+
+ xhrPost("backend.php", {op: "rpc", method: "setpref", key: "HIDE_READ_FEEDS", value: hide}, () => {
+ this.hideOrShowFeeds(hide);
+ App.setInitParam("hide_read_feeds", hide);
+ });
+ },
+ hideOrShowFeeds: function (hide) {
+ /*const tree = dijit.byId("feedTree");
+
+ if (tree)
+ return tree.hideRead(hide, App.getInitParam("hide_read_shows_special"));*/
+
+ $$("body")[0].setAttribute("hide-read-feeds", !!hide);
+ $$("body")[0].setAttribute("hide-read-shows-special", !!App.getInitParam("hide_read_shows_special"));
+ },
+ open: function(params) {
+ const feed = params.feed;
+ const is_cat = !!params.is_cat || false;
+ const offset = params.offset || 0;
+ const viewfeed_debug = params.viewfeed_debug;
+ const append = params.append || false;
+ const method = params.method;
+ // this is used to quickly switch between feeds, sets active but xhr is on a timeout
+ const delayed = params.delayed || false;
+
+ if (offset != 0) {
+ if (this.infscroll_in_progress)
return;
- }
- const catchup_query = {
- op: 'rpc', method: 'catchupFeed', feed_id: feed,
- is_cat: is_cat, mode: mode, search_query: this.last_search_query[0],
- search_lang: this.last_search_query[1]
- };
+ this.infscroll_in_progress = 1;
- Notify.progress("Loading, please wait...", true);
+ window.clearTimeout(this._infscroll_timeout);
+ this._infscroll_timeout = window.setTimeout(() => {
+ console.log('infscroll request timed out, aborting');
+ this.infscroll_in_progress = 0;
- xhrPost("backend.php", catchup_query, (transport) => {
- App.handleRpcJson(transport);
+ // call scroll handler to maybe repeat infscroll request
+ Headlines.scrollHandler();
+ }, 10 * 1000);
+ }
- const show_next_feed = App.getInitParam("on_catchup_show_next_feed");
+ Form.enable("toolbar-main");
- if (show_next_feed) {
- const nuf = this.getNextUnread(feed, is_cat);
+ let query = Object.assign({op: "feeds", method: "view", feed: feed},
+ dojo.formToObject("toolbar-main"));
- if (nuf) {
- this.open({feed: nuf, is_cat: is_cat});
- }
- } else if (feed == this.getActive() && is_cat == this.activeIsCat()) {
- this.reloadCurrent();
- }
+ if (method) query.m = method;
- Notify.close();
+ if (offset > 0) {
+ if (Headlines.current_first_id) {
+ query.fid = Headlines.current_first_id;
+ }
+ }
+
+ if (this._search_query) {
+ query = Object.assign(query, this._search_query);
+ }
+
+ if (offset != 0) {
+ query.skip = offset;
+ } else if (!is_cat && feed == this.getActive() && !params.method) {
+ query.m = "ForceUpdate";
+ }
+
+ Form.enable("toolbar-main");
+
+ if (!delayed)
+ if (!this.setExpando(feed, is_cat,
+ (is_cat) ? 'images/indicator_tiny.gif' : 'images/indicator_white.gif'))
+ Notify.progress("Loading, please wait...", true);
+
+ query.cat = is_cat;
+
+ this.setActive(feed, is_cat);
+
+ if (viewfeed_debug) {
+ window.open("backend.php?" +
+ dojo.objectToQuery(
+ Object.assign({csrf_token: App.getInitParam("csrf_token")}, query)
+ ));
+ }
+
+ window.clearTimeout(this._viewfeed_wait_timeout);
+ this._viewfeed_wait_timeout = window.setTimeout(() => {
+ xhrPost("backend.php", query, (transport) => {
+ try {
+ window.clearTimeout(this._infscroll_timeout);
+ this.setExpando(feed, is_cat, 'images/blank_icon.gif');
+ Headlines.onLoaded(transport, offset, append);
+ PluginHost.run(PluginHost.HOOK_FEED_LOADED, [feed, is_cat]);
+ } catch (e) {
+ App.Error.report(e);
+ }
});
- },
- catchupCurrent: function(mode) {
- this.catchupFeed(this.getActive(), this.activeIsCat(), mode);
- },
- catchupFeedInGroup: function(id) {
- const title = this.getName(id);
+ }, delayed ? 250 : 0);
+ },
+ catchupAll: function() {
+ const str = __("Mark all articles as read?");
- const str = __("Mark all articles in %s as read?").replace("%s", title);
+ if (App.getInitParam("confirm_feed_catchup") != 1 || confirm(str)) {
- if (App.getInitParam("confirm_feed_catchup") != 1 || confirm(str)) {
+ Notify.progress("Marking all feeds as read...");
- const rows = $$("#headlines-frame > div[id*=RROW][class*=Unread][data-orig-feed-id='" + id + "']");
-
- rows.each((row) => {
- row.removeClassName("Unread");
- })
- }
- },
- getUnread: function(feed, is_cat) {
- try {
- const tree = dijit.byId("feedTree");
-
- if (tree && tree.model)
- return tree.model.getFeedUnread(feed, is_cat);
+ xhrPost("backend.php", {op: "feeds", method: "catchupAll"}, () => {
+ this.requestCounters(true);
+ this.reloadCurrent();
+ });
- } catch (e) {
- //
+ App.global_unread = 0;
+ App.updateTitle();
+ }
+ },
+ catchupFeed: function(feed, is_cat, mode) {
+ is_cat = is_cat || false;
+
+ let str = false;
+
+ switch (mode) {
+ case "1day":
+ str = __("Mark %w in %s older than 1 day as read?");
+ break;
+ case "1week":
+ str = __("Mark %w in %s older than 1 week as read?");
+ break;
+ case "2week":
+ str = __("Mark %w in %s older than 2 weeks as read?");
+ break;
+ default:
+ str = __("Mark %w in %s as read?");
+ }
+
+ const mark_what = this.last_search_query && this.last_search_query[0] ? __("search results") : __("all articles");
+ const fn = this.getName(feed, is_cat);
+
+ str = str.replace("%s", fn)
+ .replace("%w", mark_what);
+
+ if (App.getInitParam("confirm_feed_catchup") && !confirm(str)) {
+ return;
+ }
+
+ const catchup_query = {
+ op: 'rpc', method: 'catchupFeed', feed_id: feed,
+ is_cat: is_cat, mode: mode, search_query: this.last_search_query[0],
+ search_lang: this.last_search_query[1]
+ };
+
+ Notify.progress("Loading, please wait...", true);
+
+ xhrPost("backend.php", catchup_query, (transport) => {
+ App.handleRpcJson(transport);
+
+ const show_next_feed = App.getInitParam("on_catchup_show_next_feed");
+
+ if (show_next_feed) {
+ const nuf = this.getNextUnread(feed, is_cat);
+
+ if (nuf) {
+ this.open({feed: nuf, is_cat: is_cat});
+ }
+ } else if (feed == this.getActive() && is_cat == this.activeIsCat()) {
+ this.reloadCurrent();
}
- return -1;
- },
- getCategory: function(feed) {
- try {
- const tree = dijit.byId("feedTree");
-
- if (tree && tree.model)
- return tree.getFeedCategory(feed);
+ Notify.close();
+ });
+ },
+ catchupCurrent: function(mode) {
+ this.catchupFeed(this.getActive(), this.activeIsCat(), mode);
+ },
+ catchupFeedInGroup: function(id) {
+ const title = this.getName(id);
- } catch (e) {
- //
- }
+ const str = __("Mark all articles in %s as read?").replace("%s", title);
- return false;
- },
- getName: function(feed, is_cat) {
- if (isNaN(feed)) return feed; // it's a tag
+ if (App.getInitParam("confirm_feed_catchup") != 1 || confirm(str)) {
- const tree = dijit.byId("feedTree");
+ const rows = $$("#headlines-frame > div[id*=RROW][class*=Unread][data-orig-feed-id='" + id + "']");
- if (tree && tree.model)
- return tree.model.getFeedValue(feed, is_cat, 'name');
- },
- setUnread: function(feed, is_cat, unread) {
+ rows.each((row) => {
+ row.removeClassName("Unread");
+ })
+ }
+ },
+ getUnread: function(feed, is_cat) {
+ try {
const tree = dijit.byId("feedTree");
if (tree && tree.model)
- return tree.model.setFeedUnread(feed, is_cat, unread);
- },
- setValue: function(feed, is_cat, key, value) {
- try {
- const tree = dijit.byId("feedTree");
+ return tree.model.getFeedUnread(feed, is_cat);
- if (tree && tree.model)
- return tree.model.setFeedValue(feed, is_cat, key, value);
+ } catch (e) {
+ //
+ }
- } catch (e) {
- //
- }
- },
- getValue: function(feed, is_cat, key) {
- try {
- const tree = dijit.byId("feedTree");
-
- if (tree && tree.model)
- return tree.model.getFeedValue(feed, is_cat, key);
-
- } catch (e) {
- //
- }
- return '';
- },
- setIcon: function(feed, is_cat, src) {
+ return -1;
+ },
+ getCategory: function(feed) {
+ try {
const tree = dijit.byId("feedTree");
- if (tree) return tree.setFeedIcon(feed, is_cat, src);
- },
- setExpando: function(feed, is_cat, src) {
+ if (tree && tree.model)
+ return tree.getFeedCategory(feed);
+
+ } catch (e) {
+ //
+ }
+
+ return false;
+ },
+ getName: function(feed, is_cat) {
+ if (isNaN(feed)) return feed; // it's a tag
+
+ const tree = dijit.byId("feedTree");
+
+ if (tree && tree.model)
+ return tree.model.getFeedValue(feed, is_cat, 'name');
+ },
+ setUnread: function(feed, is_cat, unread) {
+ const tree = dijit.byId("feedTree");
+
+ if (tree && tree.model)
+ return tree.model.setFeedUnread(feed, is_cat, unread);
+ },
+ setValue: function(feed, is_cat, key, value) {
+ try {
const tree = dijit.byId("feedTree");
- if (tree) return tree.setFeedExpandoIcon(feed, is_cat, src);
-
- return false;
- },
- getNextUnread: function(feed, is_cat) {
+ if (tree && tree.model)
+ return tree.model.setFeedValue(feed, is_cat, key, value);
+
+ } catch (e) {
+ //
+ }
+ },
+ getValue: function(feed, is_cat, key) {
+ try {
const tree = dijit.byId("feedTree");
- const nuf = tree.model.getNextUnreadFeed(feed, is_cat);
-
- if (nuf)
- return tree.model.store.getValue(nuf, 'bare_id');
- },
- search: function() {
- const query = "backend.php?op=feeds&method=search&param=" +
- encodeURIComponent(Feeds.getActive() + ":" + Feeds.activeIsCat());
-
- 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');
- // disallow empty queries
- if (!Feeds._search_query.query)
- Feeds._search_query = false;
-
- this.hide();
- Feeds.reloadCurrent();
- }
- },
- href: query
- });
-
- const tmph = dojo.connect(dialog, 'onLoad', function () {
- dojo.disconnect(tmph);
+ if (tree && tree.model)
+ return tree.model.getFeedValue(feed, is_cat, key);
+
+ } catch (e) {
+ //
+ }
+ return '';
+ },
+ setIcon: function(feed, is_cat, src) {
+ const tree = dijit.byId("feedTree");
+
+ if (tree) return tree.setFeedIcon(feed, is_cat, src);
+ },
+ setExpando: function(feed, is_cat, src) {
+ const tree = dijit.byId("feedTree");
+
+ if (tree) return tree.setFeedExpandoIcon(feed, is_cat, src);
+
+ return false;
+ },
+ getNextUnread: function(feed, is_cat) {
+ const tree = dijit.byId("feedTree");
+ const nuf = tree.model.getNextUnreadFeed(feed, is_cat);
+
+ if (nuf)
+ return tree.model.store.getValue(nuf, 'bare_id');
+ },
+ search: function() {
+ const query = "backend.php?op=feeds&method=search&param=" +
+ encodeURIComponent(Feeds.getActive() + ":" + Feeds.activeIsCat());
+
+ 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');
+
+ // disallow empty queries
+ if (!Feeds._search_query.query)
+ Feeds._search_query = false;
+
+ this.hide();
+ Feeds.reloadCurrent();
+ }
+ },
+ href: query
+ });
- if (Feeds._search_query) {
- if (Feeds._search_query.query)
- dijit.byId('search_query')
- .attr('value', Feeds._search_query.query);
+ const tmph = dojo.connect(dialog, 'onLoad', function () {
+ dojo.disconnect(tmph);
- if (Feeds._search_query.search_language)
- dijit.byId('search_language')
- .attr('value', Feeds._search_query.search_language);
- }
+ if (Feeds._search_query) {
+ if (Feeds._search_query.query)
+ dijit.byId('search_query')
+ .attr('value', Feeds._search_query.query);
- });
+ if (Feeds._search_query.search_language)
+ dijit.byId('search_language')
+ .attr('value', Feeds._search_query.search_language);
+ }
- dialog.show();
- },
- updateRandom: function() {
- console.log("in update_random_feed");
+ });
- xhrPost("backend.php", {op: "rpc", method: "updaterandomfeed"}, (transport) => {
- App.handleRpcJson(transport, true);
- });
- },
- };
+ dialog.show();
+ },
+ updateRandom: function() {
+ console.log("in update_random_feed");
- return Feeds;
-});
+ xhrPost("backend.php", {op: "rpc", method: "updaterandomfeed"}, (transport) => {
+ App.handleRpcJson(transport, true);
+ });
+ },
+};
diff --git a/js/Headlines.js b/js/Headlines.js
index 8425dc980..797999d49 100755
--- a/js/Headlines.js
+++ b/js/Headlines.js
@@ -1,897 +1,756 @@
'use strict';
/* global __, ngettext */
-define(["dojo/_base/declare"], function (declare) {
- Headlines = {
- vgroup_last_feed: undefined,
- _headlines_scroll_timeout: 0,
- _observer_counters_timeout: 0,
- headlines: [],
- current_first_id: 0,
- _scroll_reset_timeout: false,
- default_force_previous: false,
- default_force_to_top: false,
- line_scroll_offset: 120, /* px */
- sticky_header_observer: new IntersectionObserver(
- (entries, observer) => {
- entries.forEach((entry) => {
- const header = entry.target.nextElementSibling;
-
- if (entry.intersectionRatio == 0) {
- header.setAttribute("stuck", "1");
-
- } else if (entry.intersectionRatio == 1) {
- header.removeAttribute("stuck");
- }
+const Headlines = {
+ vgroup_last_feed: undefined,
+ _headlines_scroll_timeout: 0,
+ _observer_counters_timeout: 0,
+ headlines: [],
+ current_first_id: 0,
+ _scroll_reset_timeout: false,
+ default_force_previous: false,
+ default_force_to_top: false,
+ line_scroll_offset: 120, /* px */
+ sticky_header_observer: new IntersectionObserver(
+ (entries, observer) => {
+ entries.forEach((entry) => {
+ const header = entry.target.nextElementSibling;
+
+ if (entry.intersectionRatio == 0) {
+ header.setAttribute("stuck", "1");
+
+ } else if (entry.intersectionRatio == 1) {
+ header.removeAttribute("stuck");
+ }
- //console.log(entry.target, header, entry.intersectionRatio);
+ //console.log(entry.target, header, entry.intersectionRatio);
- });
- },
- {threshold: [0, 1], root: document.querySelector("#headlines-frame")}
- ),
- unpack_observer: new IntersectionObserver(
- (entries, observer) => {
- entries.forEach((entry) => {
- if (entry.intersectionRatio > 0)
- Article.unpack(entry.target);
- });
- },
- {threshold: [0], root: document.querySelector("#headlines-frame")}
- ),
- row_observer: new MutationObserver((mutations) => {
- const modified = [];
+ });
+ },
+ {threshold: [0, 1], root: document.querySelector("#headlines-frame")}
+ ),
+ unpack_observer: new IntersectionObserver(
+ (entries, observer) => {
+ entries.forEach((entry) => {
+ if (entry.intersectionRatio > 0)
+ Article.unpack(entry.target);
+ });
+ },
+ {threshold: [0], root: document.querySelector("#headlines-frame")}
+ ),
+ row_observer: new MutationObserver((mutations) => {
+ const modified = [];
- mutations.each((m) => {
- if (m.type == 'attributes' && ['class', 'data-score'].indexOf(m.attributeName) != -1) {
+ mutations.each((m) => {
+ if (m.type == 'attributes' && ['class', 'data-score'].indexOf(m.attributeName) != -1) {
- const row = m.target;
- const id = row.getAttribute("data-article-id");
+ const row = m.target;
+ const id = row.getAttribute("data-article-id");
- if (Headlines.headlines[id]) {
- const hl = Headlines.headlines[id];
+ if (Headlines.headlines[id]) {
+ const hl = Headlines.headlines[id];
- if (hl) {
- const hl_old = Object.extend({}, hl);
+ if (hl) {
+ const hl_old = Object.extend({}, hl);
- hl.unread = row.hasClassName("Unread");
- hl.marked = row.hasClassName("marked");
- hl.published = row.hasClassName("published");
+ hl.unread = row.hasClassName("Unread");
+ hl.marked = row.hasClassName("marked");
+ hl.published = row.hasClassName("published");
- // not sent by backend
- hl.selected = row.hasClassName("Selected");
- hl.active = row.hasClassName("active");
+ // not sent by backend
+ hl.selected = row.hasClassName("Selected");
+ hl.active = row.hasClassName("active");
- hl.score = row.getAttribute("data-score");
+ hl.score = row.getAttribute("data-score");
- modified.push({id: hl.id, new: hl, old: hl_old, row: row});
- }
+ modified.push({id: hl.id, new: hl, old: hl_old, row: row});
}
}
- });
+ }
+ });
- Headlines.updateSelectedPrompt();
+ Headlines.updateSelectedPrompt();
- if ('requestIdleCallback' in window)
- window.requestIdleCallback(() => {
- Headlines.syncModified(modified);
- });
- else
+ if ('requestIdleCallback' in window)
+ window.requestIdleCallback(() => {
Headlines.syncModified(modified);
- }),
- syncModified: function (modified) {
- const ops = {
- tmark: [],
- tpub: [],
- read: [],
- unread: [],
- select: [],
- deselect: [],
- activate: [],
- deactivate: [],
- rescore: {},
- };
-
- modified.each(function (m) {
- if (m.old.marked != m.new.marked)
- ops.tmark.push(m.id);
-
- if (m.old.published != m.new.published)
- ops.tpub.push(m.id);
-
- if (m.old.unread != m.new.unread)
- m.new.unread ? ops.unread.push(m.id) : ops.read.push(m.id);
-
- if (m.old.selected != m.new.selected)
- m.new.selected ? ops.select.push(m.row) : ops.deselect.push(m.row);
-
- if (m.old.active != m.new.active)
- m.new.active ? ops.activate.push(m.row) : ops.deactivate.push(m.row);
-
- if (m.old.score != m.new.score) {
- const score = m.new.score;
-
- ops.rescore[score] = ops.rescore[score] || [];
- ops.rescore[score].push(m.id);
- }
});
+ else
+ Headlines.syncModified(modified);
+ }),
+ syncModified: function (modified) {
+ const ops = {
+ tmark: [],
+ tpub: [],
+ read: [],
+ unread: [],
+ select: [],
+ deselect: [],
+ activate: [],
+ deactivate: [],
+ rescore: {},
+ };
+
+ modified.each(function (m) {
+ if (m.old.marked != m.new.marked)
+ ops.tmark.push(m.id);
+
+ if (m.old.published != m.new.published)
+ ops.tpub.push(m.id);
+
+ if (m.old.unread != m.new.unread)
+ m.new.unread ? ops.unread.push(m.id) : ops.read.push(m.id);
+
+ if (m.old.selected != m.new.selected)
+ m.new.selected ? ops.select.push(m.row) : ops.deselect.push(m.row);
+
+ if (m.old.active != m.new.active)
+ m.new.active ? ops.activate.push(m.row) : ops.deactivate.push(m.row);
+
+ if (m.old.score != m.new.score) {
+ const score = m.new.score;
+
+ ops.rescore[score] = ops.rescore[score] || [];
+ ops.rescore[score].push(m.id);
+ }
+ });
- ops.select.each((row) => {
- const cb = dijit.getEnclosingWidget(row.select(".rchk")[0]);
-
- if (cb)
- cb.attr('checked', true);
- });
+ ops.select.each((row) => {
+ const cb = dijit.getEnclosingWidget(row.select(".rchk")[0]);
- ops.deselect.each((row) => {
- const cb = dijit.getEnclosingWidget(row.select(".rchk")[0]);
+ if (cb)
+ cb.attr('checked', true);
+ });
- if (cb && !row.hasClassName("active"))
- cb.attr('checked', false);
- });
+ ops.deselect.each((row) => {
+ const cb = dijit.getEnclosingWidget(row.select(".rchk")[0]);
- ops.activate.each((row) => {
- const cb = dijit.getEnclosingWidget(row.select(".rchk")[0]);
+ if (cb && !row.hasClassName("active"))
+ cb.attr('checked', false);
+ });
- if (cb)
- cb.attr('checked', true);
- });
+ ops.activate.each((row) => {
+ const cb = dijit.getEnclosingWidget(row.select(".rchk")[0]);
- ops.deactivate.each((row) => {
- const cb = dijit.getEnclosingWidget(row.select(".rchk")[0]);
+ if (cb)
+ cb.attr('checked', true);
+ });
- if (cb && !row.hasClassName("Selected"))
- cb.attr('checked', false);
- });
+ ops.deactivate.each((row) => {
+ const cb = dijit.getEnclosingWidget(row.select(".rchk")[0]);
- const promises = [];
+ if (cb && !row.hasClassName("Selected"))
+ cb.attr('checked', false);
+ });
- if (ops.tmark.length != 0)
- promises.push(xhrPost("backend.php",
- {op: "rpc", method: "markSelected", ids: ops.tmark.toString(), cmode: 2}));
+ const promises = [];
- if (ops.tpub.length != 0)
- promises.push(xhrPost("backend.php",
- {op: "rpc", method: "publishSelected", ids: ops.tpub.toString(), cmode: 2}));
+ if (ops.tmark.length != 0)
+ promises.push(xhrPost("backend.php",
+ {op: "rpc", method: "markSelected", ids: ops.tmark.toString(), cmode: 2}));
- if (ops.read.length != 0)
- promises.push(xhrPost("backend.php",
- {op: "rpc", method: "catchupSelected", ids: ops.read.toString(), cmode: 0}));
+ if (ops.tpub.length != 0)
+ promises.push(xhrPost("backend.php",
+ {op: "rpc", method: "publishSelected", ids: ops.tpub.toString(), cmode: 2}));
- if (ops.unread.length != 0)
- promises.push(xhrPost("backend.php",
- {op: "rpc", method: "catchupSelected", ids: ops.unread.toString(), cmode: 1}));
+ if (ops.read.length != 0)
+ promises.push(xhrPost("backend.php",
+ {op: "rpc", method: "catchupSelected", ids: ops.read.toString(), cmode: 0}));
- const scores = Object.keys(ops.rescore);
+ if (ops.unread.length != 0)
+ promises.push(xhrPost("backend.php",
+ {op: "rpc", method: "catchupSelected", ids: ops.unread.toString(), cmode: 1}));
- if (scores.length != 0) {
- scores.each((score) => {
- promises.push(xhrPost("backend.php",
- {op: "article", method: "setScore", id: ops.rescore[score].toString(), score: score}));
- });
- }
+ const scores = Object.keys(ops.rescore);
- if (promises.length > 0)
- Promise.all([promises]).then(() => {
- window.clearTimeout(this._observer_counters_timeout);
+ if (scores.length != 0) {
+ scores.each((score) => {
+ promises.push(xhrPost("backend.php",
+ {op: "article", method: "setScore", id: ops.rescore[score].toString(), score: score}));
+ });
+ }
- this._observer_counters_timeout = setTimeout(() => {
- Feeds.requestCounters(true);
- }, 1000);
- });
+ if (promises.length > 0)
+ Promise.all([promises]).then(() => {
+ window.clearTimeout(this._observer_counters_timeout);
- },
- click: function (event, id, in_body) {
- in_body = in_body || false;
+ this._observer_counters_timeout = setTimeout(() => {
+ Feeds.requestCounters(true);
+ }, 1000);
+ });
- if (event.shiftKey && Article.getActive()) {
- Headlines.select('none');
+ },
+ click: function (event, id, in_body) {
+ in_body = in_body || false;
- const ids = Headlines.getRange(Article.getActive(), id);
+ if (event.shiftKey && Article.getActive()) {
+ Headlines.select('none');
- console.log(Article.getActive(), id, ids);
+ const ids = Headlines.getRange(Article.getActive(), id);
- for (let i = 0; i < ids.length; i++)
- Headlines.select('all', ids[i]);
+ console.log(Article.getActive(), id, ids);
- } else if (event.ctrlKey) {
- Headlines.select('invert', id);
- } else {
- if (App.isCombinedMode()) {
+ for (let i = 0; i < ids.length; i++)
+ Headlines.select('all', ids[i]);
- if (event.altKey && !in_body) {
+ } else if (event.ctrlKey) {
+ Headlines.select('invert', id);
+ } else {
+ if (App.isCombinedMode()) {
- Article.openInNewWindow(id);
- Headlines.toggleUnread(id, 0);
+ if (event.altKey && !in_body) {
- } else if (Article.getActive() != id) {
+ Article.openInNewWindow(id);
+ Headlines.toggleUnread(id, 0);
- Headlines.select('none');
+ } else if (Article.getActive() != id) {
- const scroll_position_A = $("RROW-" + id).offsetTop - $("headlines-frame").scrollTop;
+ Headlines.select('none');
- Article.setActive(id);
+ const scroll_position_A = $("RROW-" + id).offsetTop - $("headlines-frame").scrollTop;
- if (App.getInitParam("cdm_expanded")) {
+ Article.setActive(id);
- if (!in_body)
- Article.openInNewWindow(id);
+ if (App.getInitParam("cdm_expanded")) {
- Headlines.toggleUnread(id, 0);
- } else {
- const scroll_position_B = $("RROW-" + id).offsetTop - $("headlines-frame").scrollTop;
+ if (!in_body)
+ Article.openInNewWindow(id);
- // this would only work if there's enough space
- $("headlines-frame").scrollTop -= scroll_position_A-scroll_position_B;
+ Headlines.toggleUnread(id, 0);
+ } else {
+ const scroll_position_B = $("RROW-" + id).offsetTop - $("headlines-frame").scrollTop;
- Article.cdmMoveToId(id);
- }
+ // this would only work if there's enough space
+ $("headlines-frame").scrollTop -= scroll_position_A-scroll_position_B;
- } else if (in_body) {
- Headlines.toggleUnread(id, 0);
- } else { /* !in body */
- Article.openInNewWindow(id);
+ Article.cdmMoveToId(id);
}
- return in_body;
- } else {
- if (event.altKey) {
- Article.openInNewWindow(id);
- Headlines.toggleUnread(id, 0);
- } else {
- Headlines.select('none');
- Article.view(id);
- }
+ } else if (in_body) {
+ Headlines.toggleUnread(id, 0);
+ } else { /* !in body */
+ Article.openInNewWindow(id);
}
- }
- return false;
- },
- initScrollHandler: function () {
- $("headlines-frame").onscroll = (event) => {
- clearTimeout(this._headlines_scroll_timeout);
- this._headlines_scroll_timeout = window.setTimeout(function () {
- //console.log('done scrolling', event);
- Headlines.scrollHandler(event);
- }, 50);
+ return in_body;
+ } else {
+ if (event.altKey) {
+ Article.openInNewWindow(id);
+ Headlines.toggleUnread(id, 0);
+ } else {
+ Headlines.select('none');
+ Article.view(id);
+ }
}
- },
- loadMore: function () {
- const view_mode = document.forms["toolbar-main"].view_mode.value;
- const unread_in_buffer = $$("#headlines-frame > div[id*=RROW][class*=Unread]").length;
- const num_all = $$("#headlines-frame > div[id*=RROW]").length;
- const num_unread = Feeds.getUnread(Feeds.getActive(), Feeds.activeIsCat());
-
- // TODO implement marked & published
-
- let offset = num_all;
+ }
- switch (view_mode) {
- case "marked":
- case "published":
- console.warn("loadMore: ", view_mode, "not implemented");
- break;
- case "unread":
- offset = unread_in_buffer;
- break;
- case "adaptive":
- if (!(Feeds.getActive() == -1 && !Feeds.activeIsCat()))
- offset = num_unread > 0 ? unread_in_buffer : num_all;
- break;
- }
+ return false;
+ },
+ initScrollHandler: function () {
+ $("headlines-frame").onscroll = (event) => {
+ clearTimeout(this._headlines_scroll_timeout);
+ this._headlines_scroll_timeout = window.setTimeout(function () {
+ //console.log('done scrolling', event);
+ Headlines.scrollHandler(event);
+ }, 50);
+ }
+ },
+ loadMore: function () {
+ const view_mode = document.forms["toolbar-main"].view_mode.value;
+ const unread_in_buffer = $$("#headlines-frame > div[id*=RROW][class*=Unread]").length;
+ const num_all = $$("#headlines-frame > div[id*=RROW]").length;
+ const num_unread = Feeds.getUnread(Feeds.getActive(), Feeds.activeIsCat());
+
+ // TODO implement marked & published
+
+ let offset = num_all;
+
+ switch (view_mode) {
+ case "marked":
+ case "published":
+ console.warn("loadMore: ", view_mode, "not implemented");
+ break;
+ case "unread":
+ offset = unread_in_buffer;
+ break;
+ case "adaptive":
+ if (!(Feeds.getActive() == -1 && !Feeds.activeIsCat()))
+ offset = num_unread > 0 ? unread_in_buffer : num_all;
+ break;
+ }
- console.log("loadMore, offset=", offset);
+ console.log("loadMore, offset=", offset);
- Feeds.open({feed: Feeds.getActive(), is_cat: Feeds.activeIsCat(), offset: offset, append: true});
- },
- isChildVisible: function (elem) {
- return App.Scrollable.isChildVisible(elem, $("headlines-frame"));
- },
- firstVisible: function () {
- const rows = $$("#headlines-frame > div[id*=RROW]");
+ Feeds.open({feed: Feeds.getActive(), is_cat: Feeds.activeIsCat(), offset: offset, append: true});
+ },
+ isChildVisible: function (elem) {
+ return App.Scrollable.isChildVisible(elem, $("headlines-frame"));
+ },
+ firstVisible: function () {
+ const rows = $$("#headlines-frame > div[id*=RROW]");
- for (let i = 0; i < rows.length; i++) {
- const row = rows[i];
+ for (let i = 0; i < rows.length; i++) {
+ const row = rows[i];
- if (this.isChildVisible(row)) {
- return row.getAttribute("data-article-id");
- }
+ if (this.isChildVisible(row)) {
+ return row.getAttribute("data-article-id");
}
- },
- scrollHandler: function (/*event*/) {
- try {
- if (!Feeds.infscroll_disabled && !Feeds.infscroll_in_progress) {
- const hsp = $("headlines-spacer");
- const container = $("headlines-frame");
-
- if (hsp && hsp.previousSibling) {
- const last_row = hsp.previousSibling;
-
- // invoke lazy load if last article in buffer is nearly visible OR is active
- if (Article.getActive() == last_row.getAttribute("data-article-id") || last_row.offsetTop - 250 <= container.scrollTop + container.offsetHeight) {
- hsp.innerHTML = "<span class='loading'><img src='images/indicator_tiny.gif'> " +
- __("Loading, please wait...") + "</span>";
-
- Headlines.loadMore();
- return;
- }
+ }
+ },
+ scrollHandler: function (/*event*/) {
+ try {
+ if (!Feeds.infscroll_disabled && !Feeds.infscroll_in_progress) {
+ const hsp = $("headlines-spacer");
+ const container = $("headlines-frame");
+
+ if (hsp && hsp.previousSibling) {
+ const last_row = hsp.previousSibling;
+
+ // invoke lazy load if last article in buffer is nearly visible OR is active
+ if (Article.getActive() == last_row.getAttribute("data-article-id") || last_row.offsetTop - 250 <= container.scrollTop + container.offsetHeight) {
+ hsp.innerHTML = "<span class='loading'><img src='images/indicator_tiny.gif'> " +
+ __("Loading, please wait...") + "</span>";
+
+ Headlines.loadMore();
+ return;
}
}
+ }
- if (App.getInitParam("cdm_auto_catchup")) {
+ if (App.getInitParam("cdm_auto_catchup")) {
- let rows = $$("#headlines-frame > div[id*=RROW][class*=Unread]");
+ let rows = $$("#headlines-frame > div[id*=RROW][class*=Unread]");
- for (let i = 0; i < rows.length; i++) {
- const row = rows[i];
+ for (let i = 0; i < rows.length; i++) {
+ const row = rows[i];
- if ($("headlines-frame").scrollTop > (row.offsetTop + row.offsetHeight / 2)) {
- row.removeClassName("Unread");
- } else {
- break;
- }
+ if ($("headlines-frame").scrollTop > (row.offsetTop + row.offsetHeight / 2)) {
+ row.removeClassName("Unread");
+ } else {
+ break;
}
}
- } catch (e) {
- console.warn("scrollHandler", e);
}
- },
- objectById: function (id) {
- return this.headlines[id];
- },
- setCommonClasses: function () {
- $("headlines-frame").removeClassName("cdm");
- $("headlines-frame").removeClassName("normal");
-
- $("headlines-frame").addClassName(App.isCombinedMode() ? "cdm" : "normal");
+ } catch (e) {
+ console.warn("scrollHandler", e);
+ }
+ },
+ objectById: function (id) {
+ return this.headlines[id];
+ },
+ setCommonClasses: function () {
+ $("headlines-frame").removeClassName("cdm");
+ $("headlines-frame").removeClassName("normal");
+
+ $("headlines-frame").addClassName(App.isCombinedMode() ? "cdm" : "normal");
+
+ // for floating title because it's placed outside of headlines-frame
+ $("main").removeClassName("expandable");
+ $("main").removeClassName("expanded");
+
+ if (App.isCombinedMode())
+ $("main").addClassName(App.getInitParam("cdm_expanded") ? " expanded" : " expandable");
+ },
+ renderAgain: function () {
+ // TODO: wrap headline elements into a knockoutjs model to prevent all this stuff
+ Headlines.setCommonClasses();
+
+ $$("#headlines-frame > div[id*=RROW]").each((row) => {
+ const id = row.getAttribute("data-article-id");
+ const hl = this.headlines[id];
+
+ if (hl) {
+ const new_row = this.render({}, hl);
+
+ row.parentNode.replaceChild(new_row, row);
+
+ if (hl.active) {
+ new_row.addClassName("active");
+ Article.unpack(new_row);
+
+ if (App.isCombinedMode())
+ Article.cdmMoveToId(id, {noscroll: true});
+ else
+ Article.view(id);
+ }
- // for floating title because it's placed outside of headlines-frame
- $("main").removeClassName("expandable");
- $("main").removeClassName("expanded");
+ if (hl.selected) this.select("all", id);
+ }
+ });
- if (App.isCombinedMode())
- $("main").addClassName(App.getInitParam("cdm_expanded") ? " expanded" : " expandable");
- },
- renderAgain: function () {
- // TODO: wrap headline elements into a knockoutjs model to prevent all this stuff
- Headlines.setCommonClasses();
+ $$(".cdm .header-sticky-guard").each((e) => {
+ this.sticky_header_observer.observe(e)
+ });
- $$("#headlines-frame > div[id*=RROW]").each((row) => {
- const id = row.getAttribute("data-article-id");
- const hl = this.headlines[id];
+ if (App.getInitParam("cdm_expanded"))
+ $$("#headlines-frame > div[id*=RROW].cdm").each((e) => {
+ this.unpack_observer.observe(e)
+ });
- if (hl) {
- const new_row = this.render({}, hl);
+ },
+ render: function (headlines, hl) {
+ let row = null;
- row.parentNode.replaceChild(new_row, row);
+ let row_class = "";
- if (hl.active) {
- new_row.addClassName("active");
- Article.unpack(new_row);
+ if (hl.marked) row_class += " marked";
+ if (hl.published) row_class += " published";
+ if (hl.unread) row_class += " Unread";
+ if (headlines.vfeed_group_enabled) row_class += " vgrlf";
- if (App.isCombinedMode())
- Article.cdmMoveToId(id, {noscroll: true});
- else
- Article.view(id);
- }
+ if (headlines.vfeed_group_enabled && hl.feed_title && this.vgroup_last_feed != hl.feed_id) {
+ let vgrhdr = `<div data-feed-id='${hl.feed_id}' class='feed-title'>
+ <div style='float : right'>${hl.feed_icon}</div>
+ <a class="title" href="#" onclick="Feeds.open({feed:${hl.feed_id}})">${hl.feed_title}
+ <a class="catchup" title="${__('mark feed as read')}" onclick="Feeds.catchupFeedInGroup(${hl.feed_id})" href="#"><i class="icon-done material-icons">done_all</i></a>
+ </div>`
- if (hl.selected) this.select("all", id);
- }
- });
+ const tmp = document.createElement("div");
+ tmp.innerHTML = vgrhdr;
- $$(".cdm .header-sticky-guard").each((e) => {
- this.sticky_header_observer.observe(e)
- });
+ $("headlines-frame").appendChild(tmp.firstChild);
- if (App.getInitParam("cdm_expanded"))
- $$("#headlines-frame > div[id*=RROW].cdm").each((e) => {
- this.unpack_observer.observe(e)
- });
+ this.vgroup_last_feed = hl.feed_id;
+ }
- },
- render: function (headlines, hl) {
- let row = null;
+ if (App.isCombinedMode()) {
+ row_class += App.getInitParam("cdm_expanded") ? " expanded" : " expandable";
+
+ const comments = Article.formatComments(hl);
+ const originally_from = Article.formatOriginallyFrom(hl);
+
+ row = `<div class="cdm ${row_class} ${Article.getScoreClass(hl.score)}"
+ id="RROW-${hl.id}"
+ data-article-id="${hl.id}"
+ data-orig-feed-id="${hl.feed_id}"
+ data-content="${escapeHtml(hl.content)}"
+ data-score="${hl.score}"
+ data-article-title="${escapeHtml(hl.title)}"
+ onmouseover="Article.mouseIn(${hl.id})"
+ onmouseout="Article.mouseOut(${hl.id})">
+ <div class="header-sticky-guard"></div>
+ <div class="header">
+ <div class="left">
+ <input dojoType="dijit.form.CheckBox" type="checkbox" onclick="Headlines.onRowChecked(this)" class='rchk'>
+ <i class="marked-pic marked-${hl.id} material-icons" onclick="Headlines.toggleMark(${hl.id})">star</i>
+ <i class="pub-pic pub-${hl.id} material-icons" onclick="Headlines.togglePub(${hl.id})">rss_feed</i>
+ </div>
- let row_class = "";
+ <span onclick="return Headlines.click(event, ${hl.id});" data-article-id="${hl.id}" class="titleWrap hlMenuAttach">
+ <a class="title" title="${escapeHtml(hl.title)}" target="_blank" rel="noopener noreferrer" href="${escapeHtml(hl.link)}">
+ ${hl.title}</a>
+ <span class="author">${hl.author}</span>
+ ${hl.labels}
+ ${hl.cdm_excerpt ? hl.cdm_excerpt : ""}
+ </span>
+
+ <div class="feed">
+ <a href="#" style="background-color: ${hl.feed_bg_color}"
+ onclick="Feeds.open({feed:${hl.feed_id}})">${hl.feed_title}</a>
+ </div>
- if (hl.marked) row_class += " marked";
- if (hl.published) row_class += " published";
- if (hl.unread) row_class += " Unread";
- if (headlines.vfeed_group_enabled) row_class += " vgrlf";
+ <span class="updated" title="${hl.imported}">${hl.updated}</span>
- if (headlines.vfeed_group_enabled && hl.feed_title && this.vgroup_last_feed != hl.feed_id) {
- let vgrhdr = `<div data-feed-id='${hl.feed_id}' class='feed-title'>
- <div style='float : right'>${hl.feed_icon}</div>
- <a class="title" href="#" onclick="Feeds.open({feed:${hl.feed_id}})">${hl.feed_title}
- <a class="catchup" title="${__('mark feed as read')}" onclick="Feeds.catchupFeedInGroup(${hl.feed_id})" href="#"><i class="icon-done material-icons">done_all</i></a>
- </div>`
+ <div class="right">
+ <i class="material-icons icon-score" title="${hl.score}" onclick="Article.setScore(${hl.id}, this)">${Article.getScorePic(hl.score)}</i>
- const tmp = document.createElement("div");
- tmp.innerHTML = vgrhdr;
+ <span style="cursor : pointer" title="${escapeHtml(hl.feed_title)}" onclick="Feeds.open({feed:${hl.feed_id}})">
+ ${hl.feed_icon}</span>
+ </div>
- $("headlines-frame").appendChild(tmp.firstChild);
+ </div>
- this.vgroup_last_feed = hl.feed_id;
- }
+ <div class="content" onclick="return Headlines.click(event, ${hl.id}, true);">
+ <div id="POSTNOTE-${hl.id}">${hl.note}</div>
+ <div class="content-inner" lang="${hl.lang ? hl.lang : 'en'}">
+ <img src="${App.getInitParam('icon_indicator_white')}">
+ </div>
+ <div class="intermediate">
+ ${hl.enclosures}
+ </div>
+ <div class="footer" onclick="event.stopPropagation()">
- if (App.isCombinedMode()) {
- row_class += App.getInitParam("cdm_expanded") ? " expanded" : " expandable";
-
- const comments = Article.formatComments(hl);
- const originally_from = Article.formatOriginallyFrom(hl);
-
- row = `<div class="cdm ${row_class} ${Article.getScoreClass(hl.score)}"
- id="RROW-${hl.id}"
- data-article-id="${hl.id}"
- data-orig-feed-id="${hl.feed_id}"
- data-content="${escapeHtml(hl.content)}"
- data-score="${hl.score}"
- data-article-title="${escapeHtml(hl.title)}"
- onmouseover="Article.mouseIn(${hl.id})"
- onmouseout="Article.mouseOut(${hl.id})">
- <div class="header-sticky-guard"></div>
- <div class="header">
<div class="left">
- <input dojoType="dijit.form.CheckBox" type="checkbox" onclick="Headlines.onRowChecked(this)" class='rchk'>
- <i class="marked-pic marked-${hl.id} material-icons" onclick="Headlines.toggleMark(${hl.id})">star</i>
- <i class="pub-pic pub-${hl.id} material-icons" onclick="Headlines.togglePub(${hl.id})">rss_feed</i>
- </div>
-
- <span onclick="return Headlines.click(event, ${hl.id});" data-article-id="${hl.id}" class="titleWrap hlMenuAttach">
- <a class="title" title="${escapeHtml(hl.title)}" target="_blank" rel="noopener noreferrer" href="${escapeHtml(hl.link)}">
- ${hl.title}</a>
- <span class="author">${hl.author}</span>
- ${hl.labels}
- ${hl.cdm_excerpt ? hl.cdm_excerpt : ""}
- </span>
-
- <div class="feed">
- <a href="#" style="background-color: ${hl.feed_bg_color}"
- onclick="Feeds.open({feed:${hl.feed_id}})">${hl.feed_title}</a>
- </div>
-
- <span class="updated" title="${hl.imported}">${hl.updated}</span>
-
- <div class="right">
- <i class="material-icons icon-score" title="${hl.score}" onclick="Article.setScore(${hl.id}, this)">${Article.getScorePic(hl.score)}</i>
-
- <span style="cursor : pointer" title="${escapeHtml(hl.feed_title)}" onclick="Feeds.open({feed:${hl.feed_id}})">
- ${hl.feed_icon}</span>
- </div>
-
- </div>
-
- <div class="content" onclick="return Headlines.click(event, ${hl.id}, true);">
- <div id="POSTNOTE-${hl.id}">${hl.note}</div>
- <div class="content-inner" lang="${hl.lang ? hl.lang : 'en'}">
- <img src="${App.getInitParam('icon_indicator_white')}">
+ ${hl.buttons_left}
+ <i class="material-icons">label_outline</i>
+ <span id="ATSTR-${hl.id}">${hl.tags_str}</span>
+ <a title="${__("Edit tags for this article")}" href="#"
+ onclick="Article.editTags(${hl.id})">(+)</a>
+ ${comments}
</div>
- <div class="intermediate">
- ${hl.enclosures}
- </div>
- <div class="footer" onclick="event.stopPropagation()">
-
- <div class="left">
- ${hl.buttons_left}
- <i class="material-icons">label_outline</i>
- <span id="ATSTR-${hl.id}">${hl.tags_str}</span>
- <a title="${__("Edit tags for this article")}" href="#"
- onclick="Article.editTags(${hl.id})">(+)</a>
- ${comments}
- </div>
-
- <div class="right">
- ${originally_from}
- ${hl.buttons}
- </div>
+
+ <div class="right">
+ ${originally_from}
+ ${hl.buttons}
</div>
</div>
- </div>`;
-
-
- } else {
- row = `<div class="hl ${row_class} ${Article.getScoreClass(hl.score)}"
- id="RROW-${hl.id}"
- data-orig-feed-id="${hl.feed_id}"
- data-article-id="${hl.id}"
- data-score="${hl.score}"
- data-article-title="${escapeHtml(hl.title)}"
- onmouseover="Article.mouseIn(${hl.id})"
- onmouseout="Article.mouseOut(${hl.id})">
- <div class="left">
- <input dojoType="dijit.form.CheckBox" type="checkbox" onclick="Headlines.onRowChecked(this)" class='rchk'>
- <i class="marked-pic marked-${hl.id} material-icons" onclick="Headlines.toggleMark(${hl.id})">star</i>
- <i class="pub-pic pub-${hl.id} material-icons" onclick="Headlines.togglePub(${hl.id})">rss_feed</i>
- </div>
- <div onclick="return Headlines.click(event, ${hl.id})" class="title">
- <span data-article-id="${hl.id}" class="hl-content hlMenuAttach">
- <a class="title" href="${escapeHtml(hl.link)}">${hl.title} <span class="preview">${hl.content_preview}</span></a>
- <span class="author">${hl.author}</span>
- ${hl.labels}
+ </div>
+ </div>`;
+
+
+ } else {
+ row = `<div class="hl ${row_class} ${Article.getScoreClass(hl.score)}"
+ id="RROW-${hl.id}"
+ data-orig-feed-id="${hl.feed_id}"
+ data-article-id="${hl.id}"
+ data-score="${hl.score}"
+ data-article-title="${escapeHtml(hl.title)}"
+ onmouseover="Article.mouseIn(${hl.id})"
+ onmouseout="Article.mouseOut(${hl.id})">
+ <div class="left">
+ <input dojoType="dijit.form.CheckBox" type="checkbox" onclick="Headlines.onRowChecked(this)" class='rchk'>
+ <i class="marked-pic marked-${hl.id} material-icons" onclick="Headlines.toggleMark(${hl.id})">star</i>
+ <i class="pub-pic pub-${hl.id} material-icons" onclick="Headlines.togglePub(${hl.id})">rss_feed</i>
+ </div>
+ <div onclick="return Headlines.click(event, ${hl.id})" class="title">
+ <span data-article-id="${hl.id}" class="hl-content hlMenuAttach">
+ <a class="title" href="${escapeHtml(hl.link)}">${hl.title} <span class="preview">${hl.content_preview}</span></a>
+ <span class="author">${hl.author}</span>
+ ${hl.labels}
+ </span>
+ </div>
+ <span class="feed">
+ <a style="background : ${hl.feed_bg_color}" href="#" onclick="Feeds.open({feed:${hl.feed_id}})">${hl.feed_title}</a>
</span>
- </div>
- <span class="feed">
- <a style="background : ${hl.feed_bg_color}" href="#" onclick="Feeds.open({feed:${hl.feed_id}})">${hl.feed_title}</a>
- </span>
- <div title="${hl.imported}">
- <span class="updated">${hl.updated}</span>
- </div>
- <div class="right">
- <i class="material-icons icon-score" title="${hl.score}" onclick="Article.setScore(${hl.id}, this)">${Article.getScorePic(hl.score)}</i>
- <span onclick="Feeds.open({feed:${hl.feed_id}})" style="cursor : pointer" title="${escapeHtml(hl.feed_title)}">${hl.feed_icon}</span>
- </div>
- </div>
- `;
- }
+ <div title="${hl.imported}">
+ <span class="updated">${hl.updated}</span>
+ </div>
+ <div class="right">
+ <i class="material-icons icon-score" title="${hl.score}" onclick="Article.setScore(${hl.id}, this)">${Article.getScorePic(hl.score)}</i>
+ <span onclick="Feeds.open({feed:${hl.feed_id}})" style="cursor : pointer" title="${escapeHtml(hl.feed_title)}">${hl.feed_icon}</span>
+ </div>
+ </div>
+ `;
+ }
- const tmp = document.createElement("div");
- tmp.innerHTML = row;
- dojo.parser.parse(tmp);
+ const tmp = document.createElement("div");
+ tmp.innerHTML = row;
+ dojo.parser.parse(tmp);
- this.row_observer.observe(tmp.firstChild, {attributes: true});
+ this.row_observer.observe(tmp.firstChild, {attributes: true});
- PluginHost.run(PluginHost.HOOK_HEADLINE_RENDERED, tmp.firstChild);
+ PluginHost.run(PluginHost.HOOK_HEADLINE_RENDERED, tmp.firstChild);
- return tmp.firstChild;
- },
- updateCurrentUnread: function () {
- if ($("feed_current_unread")) {
- const feed_unread = Feeds.getUnread(Feeds.getActive(), Feeds.activeIsCat());
+ return tmp.firstChild;
+ },
+ updateCurrentUnread: function () {
+ if ($("feed_current_unread")) {
+ const feed_unread = Feeds.getUnread(Feeds.getActive(), Feeds.activeIsCat());
- if (feed_unread > 0 && !Element.visible("feeds-holder")) {
- $("feed_current_unread").innerText = feed_unread;
- Element.show("feed_current_unread");
- } else {
- Element.hide("feed_current_unread");
- }
+ if (feed_unread > 0 && !Element.visible("feeds-holder")) {
+ $("feed_current_unread").innerText = feed_unread;
+ Element.show("feed_current_unread");
+ } else {
+ Element.hide("feed_current_unread");
}
- },
- onLoaded: function (transport, offset, append) {
- const reply = App.handleRpcJson(transport);
-
- console.log("Headlines.onLoaded: offset=", offset, "append=", append);
-
- let is_cat = false;
- let feed_id = false;
-
- if (reply) {
-
- is_cat = reply['headlines']['is_cat'];
- feed_id = reply['headlines']['id'];
- Feeds.last_search_query = reply['headlines']['search_query'];
-
- if (feed_id != -7 && (feed_id != Feeds.getActive() || is_cat != Feeds.activeIsCat()))
- return;
+ }
+ },
+ onLoaded: function (transport, offset, append) {
+ const reply = App.handleRpcJson(transport);
- const headlines_count = reply['headlines-info']['count'];
+ console.log("Headlines.onLoaded: offset=", offset, "append=", append);
- //this.vgroup_last_feed = reply['headlines-info']['vgroup_last_feed'];
- this.current_first_id = reply['headlines']['first_id'];
+ let is_cat = false;
+ let feed_id = false;
- console.log('received', headlines_count, 'headlines');
+ if (reply) {
- if (!append) {
- Feeds.infscroll_disabled = parseInt(headlines_count) != 30;
- console.log('infscroll_disabled=', Feeds.infscroll_disabled);
+ is_cat = reply['headlines']['is_cat'];
+ feed_id = reply['headlines']['id'];
+ Feeds.last_search_query = reply['headlines']['search_query'];
- // also called in renderAgain() after view mode switch
- Headlines.setCommonClasses();
+ if (feed_id != -7 && (feed_id != Feeds.getActive() || is_cat != Feeds.activeIsCat()))
+ return;
- $("headlines-frame").setAttribute("is-vfeed",
- reply['headlines']['is_vfeed'] ? 1 : 0);
+ const headlines_count = reply['headlines-info']['count'];
- Article.setActive(0);
+ //this.vgroup_last_feed = reply['headlines-info']['vgroup_last_feed'];
+ this.current_first_id = reply['headlines']['first_id'];
- try {
- $("headlines-frame").removeClassName("smooth-scroll");
- $("headlines-frame").scrollTop = 0;
- $("headlines-frame").addClassName("smooth-scroll");
- } catch (e) {
- console.warn(e);
- }
+ console.log('received', headlines_count, 'headlines');
- this.headlines = [];
- this.vgroup_last_feed = undefined;
+ if (!append) {
+ Feeds.infscroll_disabled = parseInt(headlines_count) != 30;
+ console.log('infscroll_disabled=', Feeds.infscroll_disabled);
- dojo.html.set($("toolbar-headlines"),
- reply['headlines']['toolbar'],
- {parseContent: true});
+ // also called in renderAgain() after view mode switch
+ Headlines.setCommonClasses();
- if (typeof reply['headlines']['content'] == 'string') {
- $("headlines-frame").innerHTML = reply['headlines']['content'];
- } else {
- $("headlines-frame").innerHTML = '';
+ $("headlines-frame").setAttribute("is-vfeed",
+ reply['headlines']['is_vfeed'] ? 1 : 0);
- for (let i = 0; i < reply['headlines']['content'].length; i++) {
- const hl = reply['headlines']['content'][i];
+ Article.setActive(0);
- $("headlines-frame").appendChild(this.render(reply['headlines'], hl));
-
- this.headlines[parseInt(hl.id)] = hl;
- }
- }
+ try {
+ $("headlines-frame").removeClassName("smooth-scroll");
+ $("headlines-frame").scrollTop = 0;
+ $("headlines-frame").addClassName("smooth-scroll");
+ } catch (e) {
+ console.warn(e);
+ }
- let hsp = $("headlines-spacer");
+ this.headlines = [];
+ this.vgroup_last_feed = undefined;
- if (!hsp) {
- hsp = document.createElement("div");
- hsp.id = "headlines-spacer";
- }
+ dojo.html.set($("toolbar-headlines"),
+ reply['headlines']['toolbar'],
+ {parseContent: true});
- dijit.byId('headlines-frame').domNode.appendChild(hsp);
+ if (typeof reply['headlines']['content'] == 'string') {
+ $("headlines-frame").innerHTML = reply['headlines']['content'];
+ } else {
+ $("headlines-frame").innerHTML = '';
- this.initHeadlinesMenu();
+ for (let i = 0; i < reply['headlines']['content'].length; i++) {
+ const hl = reply['headlines']['content'][i];
- if (Feeds.infscroll_disabled)
- hsp.innerHTML = "<a href='#' onclick='Feeds.openNextUnread()'>" +
- __("Click to open next unread feed.") + "</a>";
+ $("headlines-frame").appendChild(this.render(reply['headlines'], hl));
- if (Feeds._search_query) {
- $("feed_title").innerHTML += "<span id='cancel_search'>" +
- " (<a href='#' onclick='Feeds.cancelSearch()'>" + __("Cancel search") + "</a>)" +
- "</span>";
+ this.headlines[parseInt(hl.id)] = hl;
}
+ }
- Headlines.updateCurrentUnread();
-
- } else if (headlines_count > 0 && feed_id == Feeds.getActive() && is_cat == Feeds.activeIsCat()) {
- const c = dijit.byId("headlines-frame");
-
- let hsp = $("headlines-spacer");
-
- if (hsp)
- c.domNode.removeChild(hsp);
+ let hsp = $("headlines-spacer");
- let headlines_appended = 0;
+ if (!hsp) {
+ hsp = document.createElement("div");
+ hsp.id = "headlines-spacer";
+ }
- if (typeof reply['headlines']['content'] == 'string') {
- $("headlines-frame").innerHTML = reply['headlines']['content'];
- } else {
- for (let i = 0; i < reply['headlines']['content'].length; i++) {
- const hl = reply['headlines']['content'][i];
+ dijit.byId('headlines-frame').domNode.appendChild(hsp);
- if (!this.headlines[parseInt(hl.id)]) {
- $("headlines-frame").appendChild(this.render(reply['headlines'], hl));
+ this.initHeadlinesMenu();
- this.headlines[parseInt(hl.id)] = hl;
- ++headlines_appended;
- }
- }
- }
+ if (Feeds.infscroll_disabled)
+ hsp.innerHTML = "<a href='#' onclick='Feeds.openNextUnread()'>" +
+ __("Click to open next unread feed.") + "</a>";
- Feeds.infscroll_disabled = headlines_appended == 0;
+ if (Feeds._search_query) {
+ $("feed_title").innerHTML += "<span id='cancel_search'>" +
+ " (<a href='#' onclick='Feeds.cancelSearch()'>" + __("Cancel search") + "</a>)" +
+ "</span>";
+ }
- console.log('appended', headlines_appended, 'headlines, infscroll_disabled=', Feeds.infscroll_disabled);
+ Headlines.updateCurrentUnread();
- if (!hsp) {
- hsp = document.createElement("div");
- hsp.id = "headlines-spacer";
- }
+ } else if (headlines_count > 0 && feed_id == Feeds.getActive() && is_cat == Feeds.activeIsCat()) {
+ const c = dijit.byId("headlines-frame");
- c.domNode.appendChild(hsp);
+ let hsp = $("headlines-spacer");
- this.initHeadlinesMenu();
+ if (hsp)
+ c.domNode.removeChild(hsp);
- if (Feeds.infscroll_disabled) {
- hsp.innerHTML = "<a href='#' onclick='Feeds.openNextUnread()'>" +
- __("Click to open next unread feed.") + "</a>";
- }
+ let headlines_appended = 0;
+ if (typeof reply['headlines']['content'] == 'string') {
+ $("headlines-frame").innerHTML = reply['headlines']['content'];
} else {
- Feeds.infscroll_disabled = true;
- const first_id_changed = reply['headlines']['first_id_changed'];
+ for (let i = 0; i < reply['headlines']['content'].length; i++) {
+ const hl = reply['headlines']['content'][i];
- console.log("no headlines received, infscroll_disabled=", Feeds.infscroll_disabled, 'first_id_changed=', first_id_changed);
-
- let hsp = $("headlines-spacer");
+ if (!this.headlines[parseInt(hl.id)]) {
+ $("headlines-frame").appendChild(this.render(reply['headlines'], hl));
- if (hsp) {
- if (first_id_changed) {
- hsp.innerHTML = "<a href='#' onclick='Feeds.reloadCurrent()'>" +
- __("New articles found, reload feed to continue.") + "</a>";
- } else {
- hsp.innerHTML = "<a href='#' onclick='Feeds.openNextUnread()'>" +
- __("Click to open next unread feed.") + "</a>";
+ this.headlines[parseInt(hl.id)] = hl;
+ ++headlines_appended;
}
}
}
- $$(".cdm .header-sticky-guard").each((e) => {
- this.sticky_header_observer.observe(e)
- });
-
- if (App.getInitParam("cdm_expanded"))
- $$("#headlines-frame > div[id*=RROW].cdm").each((e) => {
- this.unpack_observer.observe(e)
- });
-
- } else {
- console.error("Invalid object received: " + transport.responseText);
- dijit.byId("headlines-frame").attr('content', "<div class='whiteBox'>" +
- __('Could not update headlines (invalid object received - see error console for details)') +
- "</div>");
- }
-
- Feeds.infscroll_in_progress = 0;
-
- // this is used to auto-catchup articles if needed after infscroll request has finished,
- // unpack visible articles, fill buffer more, etc
- this.scrollHandler();
-
- Notify.close();
- },
- reverse: function () {
- const toolbar = document.forms["toolbar-main"];
- const order_by = dijit.getEnclosingWidget(toolbar.order_by);
+ Feeds.infscroll_disabled = headlines_appended == 0;
- let value = order_by.attr('value');
+ console.log('appended', headlines_appended, 'headlines, infscroll_disabled=', Feeds.infscroll_disabled);
- if (value != "date_reverse")
- value = "date_reverse";
- else
- value = "default";
+ if (!hsp) {
+ hsp = document.createElement("div");
+ hsp.id = "headlines-spacer";
+ }
- order_by.attr('value', value);
+ c.domNode.appendChild(hsp);
- Feeds.reloadCurrent();
- },
- selectionToggleUnread: function (params) {
- params = params || {};
+ this.initHeadlinesMenu();
- const cmode = params.cmode != undefined ? params.cmode : 2;
- const no_error = params.no_error || false;
- const ids = params.ids || Headlines.getSelected();
+ if (Feeds.infscroll_disabled) {
+ hsp.innerHTML = "<a href='#' onclick='Feeds.openNextUnread()'>" +
+ __("Click to open next unread feed.") + "</a>";
+ }
- if (ids.length == 0) {
- if (!no_error)
- alert(__("No articles selected."));
+ } else {
+ Feeds.infscroll_disabled = true;
+ const first_id_changed = reply['headlines']['first_id_changed'];
- return;
- }
+ console.log("no headlines received, infscroll_disabled=", Feeds.infscroll_disabled, 'first_id_changed=', first_id_changed);
- ids.each((id) => {
- const row = $("RROW-" + id);
+ let hsp = $("headlines-spacer");
- if (row) {
- switch (cmode) {
- case 0:
- row.removeClassName("Unread");
- break;
- case 1:
- row.addClassName("Unread");
- break;
- case 2:
- row.toggleClassName("Unread");
+ if (hsp) {
+ if (first_id_changed) {
+ hsp.innerHTML = "<a href='#' onclick='Feeds.reloadCurrent()'>" +
+ __("New articles found, reload feed to continue.") + "</a>";
+ } else {
+ hsp.innerHTML = "<a href='#' onclick='Feeds.openNextUnread()'>" +
+ __("Click to open next unread feed.") + "</a>";
}
}
- });
- },
- selectionToggleMarked: function (ids) {
- ids = ids || Headlines.getSelected();
-
- if (ids.length == 0) {
- alert(__("No articles selected."));
- return;
}
- ids.each((id) => {
- this.toggleMark(id);
+ $$(".cdm .header-sticky-guard").each((e) => {
+ this.sticky_header_observer.observe(e)
});
- },
- selectionTogglePublished: function (ids) {
- ids = ids || Headlines.getSelected();
- if (ids.length == 0) {
- alert(__("No articles selected."));
- return;
- }
+ if (App.getInitParam("cdm_expanded"))
+ $$("#headlines-frame > div[id*=RROW].cdm").each((e) => {
+ this.unpack_observer.observe(e)
+ });
- ids.each((id) => {
- this.togglePub(id);
- });
- },
- toggleMark: function (id) {
- const row = $("RROW-" + id);
+ } else {
+ console.error("Invalid object received: " + transport.responseText);
+ dijit.byId("headlines-frame").attr('content', "<div class='whiteBox'>" +
+ __('Could not update headlines (invalid object received - see error console for details)') +
+ "</div>");
+ }
- if (row)
- row.toggleClassName("marked");
+ Feeds.infscroll_in_progress = 0;
- },
- togglePub: function (id) {
- const row = $("RROW-" + id);
+ // this is used to auto-catchup articles if needed after infscroll request has finished,
+ // unpack visible articles, fill buffer more, etc
+ this.scrollHandler();
- if (row)
- row.toggleClassName("published");
- },
- move: function (mode, params) {
- params = params || {};
-
- const no_expand = params.no_expand || false;
- const force_previous = params.force_previous || this.default_force_previous;
- const force_to_top = params.force_to_top || this.default_force_to_top;
-
- let prev_id = false;
- let next_id = false;
- let current_id = Article.getActive();
-
- if (!Headlines.isChildVisible($("RROW-" + current_id))) {
- console.log('active article is obscured, resetting to first visible...');
- current_id = Headlines.firstVisible();
- prev_id = current_id;
- next_id = current_id;
- } else {
- const rows = Headlines.getLoaded();
+ Notify.close();
+ },
+ reverse: function () {
+ const toolbar = document.forms["toolbar-main"];
+ const order_by = dijit.getEnclosingWidget(toolbar.order_by);
- for (let i = 0; i < rows.length; i++) {
- if (rows[i] == current_id) {
+ let value = order_by.attr('value');
- // Account for adjacent identical article ids.
- if (i > 0) prev_id = rows[i - 1];
+ if (value != "date_reverse")
+ value = "date_reverse";
+ else
+ value = "default";
- for (let j = i + 1; j < rows.length; j++) {
- if (rows[j] != current_id) {
- next_id = rows[j];
- break;
- }
- }
- break;
- }
- }
- }
+ order_by.attr('value', value);
- console.log("cur: " + current_id + " next: " + next_id + " prev:" + prev_id);
+ Feeds.reloadCurrent();
+ },
+ selectionToggleUnread: function (params) {
+ params = params || {};
- if (mode === "next") {
- if (next_id) {
- if (App.isCombinedMode()) {
- window.requestAnimationFrame(() => {
- Article.setActive(next_id);
- Article.cdmMoveToId(next_id, {force_to_top: force_to_top});
- });
- } else {
- Article.view(next_id, no_expand);
- }
- }
- } else if (mode === "prev") {
- if (prev_id || current_id) {
- if (App.isCombinedMode()) {
- window.requestAnimationFrame(() => {
- const row = $("RROW-" + current_id);
- const ctr = $("headlines-frame");
- const delta_px = Math.round(row.offsetTop) - Math.round(ctr.scrollTop);
-
- console.log('moving back, delta_px', delta_px);
-
- if (!force_previous && row && delta_px < -8) {
- Article.setActive(current_id);
- Article.cdmMoveToId(current_id, {force_to_top: force_to_top});
- } else if (prev_id) {
- Article.setActive(prev_id);
- Article.cdmMoveToId(prev_id, {force_to_top: force_to_top});
- }
- });
- } else if (prev_id) {
- Article.view(prev_id, no_expand);
- }
- }
- }
- },
- updateSelectedPrompt: function () {
- const count = Headlines.getSelected().length;
- const elem = $("selected_prompt");
+ const cmode = params.cmode != undefined ? params.cmode : 2;
+ const no_error = params.no_error || false;
+ const ids = params.ids || Headlines.getSelected();
+
+ if (ids.length == 0) {
+ if (!no_error)
+ alert(__("No articles selected."));
- if (elem) {
- elem.innerHTML = ngettext("%d article selected",
- "%d articles selected", count).replace("%d", count);
+ return;
+ }
- count > 0 ? Element.show(elem) : Element.hide(elem);
- }
- },
- toggleUnread: function (id, cmode) {
+ ids.each((id) => {
const row = $("RROW-" + id);
if (row) {
- if (typeof cmode == "undefined") cmode = 2;
-
switch (cmode) {
case 0:
row.removeClassName("Unread");
@@ -901,530 +760,667 @@ define(["dojo/_base/declare"], function (declare) {
break;
case 2:
row.toggleClassName("Unread");
- break;
}
}
- },
- selectionRemoveLabel: function (id, ids) {
- if (!ids) ids = Headlines.getSelected();
-
- if (ids.length == 0) {
- alert(__("No articles selected."));
- return;
- }
+ });
+ },
+ selectionToggleMarked: function (ids) {
+ ids = ids || Headlines.getSelected();
+
+ if (ids.length == 0) {
+ alert(__("No articles selected."));
+ return;
+ }
- const query = {
- op: "article", method: "removeFromLabel",
- ids: ids.toString(), lid: id
- };
+ ids.each((id) => {
+ this.toggleMark(id);
+ });
+ },
+ selectionTogglePublished: function (ids) {
+ ids = ids || Headlines.getSelected();
- xhrPost("backend.php", query, (transport) => {
- App.handleRpcJson(transport);
- this.onLabelsUpdated(transport);
- });
- },
- selectionAssignLabel: function (id, ids) {
- if (!ids) ids = Headlines.getSelected();
+ if (ids.length == 0) {
+ alert(__("No articles selected."));
+ return;
+ }
- if (ids.length == 0) {
- alert(__("No articles selected."));
- return;
- }
+ ids.each((id) => {
+ this.togglePub(id);
+ });
+ },
+ toggleMark: function (id) {
+ const row = $("RROW-" + id);
+
+ if (row)
+ row.toggleClassName("marked");
+
+ },
+ togglePub: function (id) {
+ const row = $("RROW-" + id);
+
+ if (row)
+ row.toggleClassName("published");
+ },
+ move: function (mode, params) {
+ params = params || {};
+
+ const no_expand = params.no_expand || false;
+ const force_previous = params.force_previous || this.default_force_previous;
+ const force_to_top = params.force_to_top || this.default_force_to_top;
+
+ let prev_id = false;
+ let next_id = false;
+ let current_id = Article.getActive();
+
+ if (!Headlines.isChildVisible($("RROW-" + current_id))) {
+ console.log('active article is obscured, resetting to first visible...');
+ current_id = Headlines.firstVisible();
+ prev_id = current_id;
+ next_id = current_id;
+ } else {
+ const rows = Headlines.getLoaded();
- const query = {
- op: "article", method: "assignToLabel",
- ids: ids.toString(), lid: id
- };
+ for (let i = 0; i < rows.length; i++) {
+ if (rows[i] == current_id) {
- xhrPost("backend.php", query, (transport) => {
- App.handleRpcJson(transport);
- this.onLabelsUpdated(transport);
- });
- },
- deleteSelection: function () {
- const rows = Headlines.getSelected();
+ // Account for adjacent identical article ids.
+ if (i > 0) prev_id = rows[i - 1];
- if (rows.length == 0) {
- alert(__("No articles selected."));
- return;
+ for (let j = i + 1; j < rows.length; j++) {
+ if (rows[j] != current_id) {
+ next_id = rows[j];
+ break;
+ }
+ }
+ break;
+ }
}
+ }
- const fn = Feeds.getName(Feeds.getActive(), Feeds.activeIsCat());
- let str;
+ console.log("cur: " + current_id + " next: " + next_id + " prev:" + prev_id);
- if (Feeds.getActive() != 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);
+ if (mode === "next") {
+ if (next_id) {
+ if (App.isCombinedMode()) {
+ window.requestAnimationFrame(() => {
+ Article.setActive(next_id);
+ Article.cdmMoveToId(next_id, {force_to_top: force_to_top});
+ });
+ } else {
+ Article.view(next_id, no_expand);
+ }
+ }
+ } else if (mode === "prev") {
+ if (prev_id || current_id) {
+ if (App.isCombinedMode()) {
+ window.requestAnimationFrame(() => {
+ const row = $("RROW-" + current_id);
+ const ctr = $("headlines-frame");
+ const delta_px = Math.round(row.offsetTop) - Math.round(ctr.scrollTop);
+
+ console.log('moving back, delta_px', delta_px);
+
+ if (!force_previous && row && delta_px < -8) {
+ Article.setActive(current_id);
+ Article.cdmMoveToId(current_id, {force_to_top: force_to_top});
+ } else if (prev_id) {
+ Article.setActive(prev_id);
+ Article.cdmMoveToId(prev_id, {force_to_top: force_to_top});
+ }
+ });
+ } else if (prev_id) {
+ Article.view(prev_id, no_expand);
+ }
}
+ }
+ },
+ updateSelectedPrompt: function () {
+ const count = Headlines.getSelected().length;
+ const elem = $("selected_prompt");
- str = str.replace("%d", rows.length);
- str = str.replace("%s", fn);
+ if (elem) {
+ elem.innerHTML = ngettext("%d article selected",
+ "%d articles selected", count).replace("%d", count);
- if (App.getInitParam("confirm_feed_catchup") && !confirm(str)) {
- return;
+ count > 0 ? Element.show(elem) : Element.hide(elem);
+ }
+ },
+ toggleUnread: function (id, cmode) {
+ const row = $("RROW-" + id);
+
+ if (row) {
+ if (typeof cmode == "undefined") cmode = 2;
+
+ switch (cmode) {
+ case 0:
+ row.removeClassName("Unread");
+ break;
+ case 1:
+ row.addClassName("Unread");
+ break;
+ case 2:
+ row.toggleClassName("Unread");
+ break;
}
+ }
+ },
+ selectionRemoveLabel: function (id, ids) {
+ if (!ids) ids = Headlines.getSelected();
- const query = {op: "rpc", method: "delete", ids: rows.toString()};
+ if (ids.length == 0) {
+ alert(__("No articles selected."));
+ return;
+ }
- xhrPost("backend.php", query, (transport) => {
- App.handleRpcJson(transport);
- Feeds.reloadCurrent();
- });
- },
- getSelected: function () {
- const rv = [];
+ const query = {
+ op: "article", method: "removeFromLabel",
+ ids: ids.toString(), lid: id
+ };
+
+ xhrPost("backend.php", query, (transport) => {
+ App.handleRpcJson(transport);
+ this.onLabelsUpdated(transport);
+ });
+ },
+ selectionAssignLabel: function (id, ids) {
+ if (!ids) ids = Headlines.getSelected();
+
+ if (ids.length == 0) {
+ alert(__("No articles selected."));
+ return;
+ }
- $$("#headlines-frame > div[id*=RROW][class*=Selected]").each(
- function (child) {
- rv.push(child.getAttribute("data-article-id"));
- });
+ const query = {
+ op: "article", method: "assignToLabel",
+ ids: ids.toString(), lid: id
+ };
+
+ xhrPost("backend.php", query, (transport) => {
+ App.handleRpcJson(transport);
+ this.onLabelsUpdated(transport);
+ });
+ },
+ deleteSelection: function () {
+ const rows = Headlines.getSelected();
+
+ if (rows.length == 0) {
+ alert(__("No articles selected."));
+ return;
+ }
- // consider active article a honorary member of selected articles
- if (Article.getActive())
- rv.push(Article.getActive());
+ const fn = Feeds.getName(Feeds.getActive(), Feeds.activeIsCat());
+ let str;
- return rv.uniq();
- },
- getLoaded: function () {
- const rv = [];
+ if (Feeds.getActive() != 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);
+ }
- const children = $$("#headlines-frame > div[id*=RROW-]");
+ str = str.replace("%d", rows.length);
+ str = str.replace("%s", fn);
- children.each(function (child) {
- if (Element.visible(child)) {
- rv.push(child.getAttribute("data-article-id"));
- }
+ if (App.getInitParam("confirm_feed_catchup") && !confirm(str)) {
+ return;
+ }
+
+ const query = {op: "rpc", method: "delete", ids: rows.toString()};
+
+ xhrPost("backend.php", query, (transport) => {
+ App.handleRpcJson(transport);
+ Feeds.reloadCurrent();
+ });
+ },
+ getSelected: function () {
+ const rv = [];
+
+ $$("#headlines-frame > div[id*=RROW][class*=Selected]").each(
+ function (child) {
+ rv.push(child.getAttribute("data-article-id"));
});
- return rv;
- },
- onRowChecked: function (elem) {
- const row = elem.domNode.up("div[id*=RROW]");
+ // consider active article a honorary member of selected articles
+ if (Article.getActive())
+ rv.push(Article.getActive());
- // do not allow unchecking active article checkbox
- if (row.hasClassName("active")) {
- elem.attr("checked", 1);
- return;
- }
+ return rv.uniq();
+ },
+ getLoaded: function () {
+ const rv = [];
- if (elem.attr("checked")) {
- row.addClassName("Selected");
- } else {
- row.removeClassName("Selected");
- }
- },
- getRange: function (start, stop) {
- if (start == stop)
- return [start];
+ const children = $$("#headlines-frame > div[id*=RROW-]");
- const rows = $$("#headlines-frame > div[id*=RROW]");
- const results = [];
- let collecting = false;
+ 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 id = row.getAttribute('data-article-id');
+ return rv;
+ },
+ onRowChecked: function (elem) {
+ const row = elem.domNode.up("div[id*=RROW]");
- if (id == start || id == stop) {
- if (!collecting) {
- collecting = true;
- } else {
- results.push(id);
- break;
- }
- }
+ // do not allow unchecking active article checkbox
+ if (row.hasClassName("active")) {
+ elem.attr("checked", 1);
+ return;
+ }
- if (collecting)
+ if (elem.attr("checked")) {
+ row.addClassName("Selected");
+ } else {
+ row.removeClassName("Selected");
+ }
+ },
+ getRange: function (start, stop) {
+ if (start == stop)
+ return [start];
+
+ const rows = $$("#headlines-frame > div[id*=RROW]");
+ const results = [];
+ let collecting = false;
+
+ for (let i = 0; i < rows.length; i++) {
+ const row = rows[i];
+ const id = row.getAttribute('data-article-id');
+
+ if (id == start || id == stop) {
+ if (!collecting) {
+ collecting = true;
+ } else {
results.push(id);
+ break;
+ }
}
- return results;
- },
- select: function (mode, articleId) {
- // mode = all,none,unread,invert,marked,published
- let query = "#headlines-frame > div[id*=RROW]";
+ if (collecting)
+ results.push(id);
+ }
- if (articleId) query += "[data-article-id=" + articleId + "]";
+ return results;
+ },
+ select: function (mode, articleId) {
+ // mode = all,none,unread,invert,marked,published
+ let query = "#headlines-frame > div[id*=RROW]";
+
+ if (articleId) query += "[data-article-id=" + articleId + "]";
+
+ 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("select: unknown mode", mode);
+ }
+
+ const rows = $$(query);
+
+ for (let i = 0; i < rows.length; i++) {
+ const row = rows[i];
switch (mode) {
case "none":
- case "all":
- case "invert":
+ row.removeClassName("Selected");
break;
- case "marked":
- query += "[class*=marked]";
- break;
- case "published":
- query += "[class*=published]";
- break;
- case "unread":
- query += "[class*=Unread]";
+ case "invert":
+ row.toggleClassName("Selected");
break;
default:
- console.warn("select: unknown mode", mode);
- }
-
- const rows = $$(query);
-
- for (let i = 0; i < rows.length; i++) {
- const row = rows[i];
-
- switch (mode) {
- case "none":
- row.removeClassName("Selected");
- break;
- case "invert":
- row.toggleClassName("Selected");
- break;
- default:
- row.addClassName("Selected");
- }
- }
- },
- archiveSelection: function () {
- const rows = Headlines.getSelected();
-
- if (rows.length == 0) {
- alert(__("No articles selected."));
- return;
+ row.addClassName("Selected");
}
+ }
+ },
+ archiveSelection: function () {
+ const rows = Headlines.getSelected();
- const fn = Feeds.getName(Feeds.getActive(), Feeds.activeIsCat());
- let str;
- let op;
+ if (rows.length == 0) {
+ alert(__("No articles selected."));
+ return;
+ }
- if (Feeds.getActive() != 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.");
+ const fn = Feeds.getName(Feeds.getActive(), Feeds.activeIsCat());
+ let str;
+ let op;
- op = "unarchive";
- }
+ if (Feeds.getActive() != 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.");
- str = str.replace("%d", rows.length);
- str = str.replace("%s", fn);
+ op = "unarchive";
+ }
- if (App.getInitParam("confirm_feed_catchup") && !confirm(str)) {
- return;
- }
+ str = str.replace("%d", rows.length);
+ str = str.replace("%s", fn);
- const query = {op: "rpc", method: op, ids: rows.toString()};
+ if (App.getInitParam("confirm_feed_catchup") && !confirm(str)) {
+ return;
+ }
- xhrPost("backend.php", query, (transport) => {
- App.handleRpcJson(transport);
- Feeds.reloadCurrent();
- });
- },
- catchupSelection: function () {
- const rows = Headlines.getSelected();
+ const query = {op: "rpc", method: op, ids: rows.toString()};
- if (rows.length == 0) {
- alert(__("No articles selected."));
- return;
- }
+ xhrPost("backend.php", query, (transport) => {
+ App.handleRpcJson(transport);
+ Feeds.reloadCurrent();
+ });
+ },
+ catchupSelection: function () {
+ const rows = Headlines.getSelected();
+
+ if (rows.length == 0) {
+ alert(__("No articles selected."));
+ return;
+ }
- const fn = Feeds.getName(Feeds.getActive(), Feeds.activeIsCat());
+ const fn = Feeds.getName(Feeds.getActive(), Feeds.activeIsCat());
- let str = ngettext("Mark %d selected article in %s as read?", "Mark %d selected articles in %s as read?", rows.length);
+ 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);
+ str = str.replace("%d", rows.length);
+ str = str.replace("%s", fn);
- if (App.getInitParam("confirm_feed_catchup") && !confirm(str)) {
- return;
- }
+ if (App.getInitParam("confirm_feed_catchup") && !confirm(str)) {
+ return;
+ }
- Headlines.selectionToggleUnread({ids: rows, cmode: 0});
- },
- catchupRelativeTo: function (below, id) {
+ Headlines.selectionToggleUnread({ids: rows, cmode: 0});
+ },
+ catchupRelativeTo: function (below, id) {
- if (!id) id = Article.getActive();
+ if (!id) id = Article.getActive();
- if (!id) {
- alert(__("No article is selected."));
- return;
- }
+ if (!id) {
+ alert(__("No article is selected."));
+ return;
+ }
- const visible_ids = this.getLoaded();
+ const visible_ids = this.getLoaded();
- const ids_to_mark = [];
+ const ids_to_mark = [];
- if (!below) {
- for (let i = 0; i < visible_ids.length; i++) {
- if (visible_ids[i] != id) {
- const e = $("RROW-" + visible_ids[i]);
+ if (!below) {
+ for (let i = 0; i < visible_ids.length; i++) {
+ if (visible_ids[i] != id) {
+ const e = $("RROW-" + visible_ids[i]);
- if (e && e.hasClassName("Unread")) {
- ids_to_mark.push(visible_ids[i]);
- }
- } else {
- break;
+ if (e && e.hasClassName("Unread")) {
+ ids_to_mark.push(visible_ids[i]);
}
+ } else {
+ break;
}
- } else {
- for (let i = visible_ids.length - 1; i >= 0; i--) {
- if (visible_ids[i] != id) {
- const e = $("RROW-" + visible_ids[i]);
+ }
+ } else {
+ for (let i = visible_ids.length - 1; i >= 0; i--) {
+ if (visible_ids[i] != id) {
+ const e = $("RROW-" + visible_ids[i]);
- if (e && e.hasClassName("Unread")) {
- ids_to_mark.push(visible_ids[i]);
- }
- } else {
- break;
+ if (e && e.hasClassName("Unread")) {
+ ids_to_mark.push(visible_ids[i]);
}
+ } else {
+ break;
}
}
+ }
- if (ids_to_mark.length == 0) {
- alert(__("No articles found to mark"));
- } else {
- const msg = ngettext("Mark %d article as read?", "Mark %d articles as read?", ids_to_mark.length).replace("%d", ids_to_mark.length);
+ if (ids_to_mark.length == 0) {
+ alert(__("No articles found to mark"));
+ } else {
+ const msg = ngettext("Mark %d article as read?", "Mark %d articles as read?", ids_to_mark.length).replace("%d", ids_to_mark.length);
- if (App.getInitParam("confirm_feed_catchup") != 1 || confirm(msg)) {
+ if (App.getInitParam("confirm_feed_catchup") != 1 || confirm(msg)) {
- for (var i = 0; i < ids_to_mark.length; i++) {
- var e = $("RROW-" + ids_to_mark[i]);
- e.removeClassName("Unread");
- }
+ for (var i = 0; i < ids_to_mark.length; i++) {
+ var e = $("RROW-" + ids_to_mark[i]);
+ e.removeClassName("Unread");
}
}
- },
- onLabelsUpdated: function (transport) {
- const data = JSON.parse(transport.responseText);
-
- if (data) {
- data['info-for-headlines'].each(function (elem) {
- $$(".HLLCTR-" + elem.id).each(function (ctr) {
- ctr.innerHTML = elem.labels;
- });
+ }
+ },
+ onLabelsUpdated: function (transport) {
+ const data = JSON.parse(transport.responseText);
+
+ if (data) {
+ data['info-for-headlines'].each(function (elem) {
+ $$(".HLLCTR-" + elem.id).each(function (ctr) {
+ ctr.innerHTML = elem.labels;
});
- }
- },
- onActionChanged: function (elem) {
- eval(elem.value);
- elem.attr('value', 'false');
- },
- scrollToArticleId: function (id) {
- const container = $("headlines-frame");
- const row = $("RROW-" + id);
-
- if (!container || !row) return;
-
- const viewport = container.offsetHeight;
+ });
+ }
+ },
+ onActionChanged: function (elem) {
+ eval(elem.value);
+ elem.attr('value', 'false');
+ },
+ scrollToArticleId: function (id) {
+ const container = $("headlines-frame");
+ const row = $("RROW-" + id);
- const rel_offset_top = row.offsetTop - container.scrollTop;
- const rel_offset_bottom = row.offsetTop + row.offsetHeight - container.scrollTop;
+ if (!container || !row) return;
- //console.log("Rtop: " + rel_offset_top + " Rbtm: " + rel_offset_bottom);
- //console.log("Vport: " + viewport);
+ const viewport = container.offsetHeight;
- if (rel_offset_top <= 0 || rel_offset_top > viewport) {
- container.scrollTop = row.offsetTop;
- } else if (rel_offset_bottom > viewport) {
- container.scrollTop = row.offsetTop + row.offsetHeight - viewport;
- }
- },
- headlinesMenuCommon: function (menu) {
+ const rel_offset_top = row.offsetTop - container.scrollTop;
+ const rel_offset_bottom = row.offsetTop + row.offsetHeight - container.scrollTop;
- menu.addChild(new dijit.MenuItem({
- label: __("Open original article"),
- onClick: function (event) {
- Article.openInNewWindow(this.getParent().currentTarget.getAttribute("data-article-id"));
- }
- }));
+ //console.log("Rtop: " + rel_offset_top + " Rbtm: " + rel_offset_bottom);
+ //console.log("Vport: " + viewport);
- menu.addChild(new dijit.MenuItem({
- label: __("Display article URL"),
- onClick: function (event) {
- Article.displayUrl(this.getParent().currentTarget.getAttribute("data-article-id"));
- }
- }));
+ if (rel_offset_top <= 0 || rel_offset_top > viewport) {
+ container.scrollTop = row.offsetTop;
+ } else if (rel_offset_bottom > viewport) {
+ container.scrollTop = row.offsetTop + row.offsetHeight - viewport;
+ }
+ },
+ headlinesMenuCommon: function (menu) {
- menu.addChild(new dijit.MenuSeparator());
+ menu.addChild(new dijit.MenuItem({
+ label: __("Open original article"),
+ onClick: function (event) {
+ Article.openInNewWindow(this.getParent().currentTarget.getAttribute("data-article-id"));
+ }
+ }));
- menu.addChild(new dijit.MenuItem({
- label: __("Toggle unread"),
- onClick: function () {
+ menu.addChild(new dijit.MenuItem({
+ label: __("Display article URL"),
+ onClick: function (event) {
+ Article.displayUrl(this.getParent().currentTarget.getAttribute("data-article-id"));
+ }
+ }));
- let ids = Headlines.getSelected();
- // cast to string
- const id = (this.getParent().currentTarget.getAttribute("data-article-id")) + "";
- ids = ids.length != 0 && ids.indexOf(id) != -1 ? ids : [id];
+ menu.addChild(new dijit.MenuSeparator());
- Headlines.selectionToggleUnread({ids: ids, no_error: 1});
- }
- }));
+ menu.addChild(new dijit.MenuItem({
+ label: __("Toggle unread"),
+ onClick: function () {
- menu.addChild(new dijit.MenuItem({
- label: __("Toggle starred"),
- onClick: function () {
- let ids = Headlines.getSelected();
- // cast to string
- const id = (this.getParent().currentTarget.getAttribute("data-article-id")) + "";
- ids = ids.length != 0 && ids.indexOf(id) != -1 ? ids : [id];
+ let ids = Headlines.getSelected();
+ // cast to string
+ const id = (this.getParent().currentTarget.getAttribute("data-article-id")) + "";
+ ids = ids.length != 0 && ids.indexOf(id) != -1 ? ids : [id];
- Headlines.selectionToggleMarked(ids);
- }
- }));
+ Headlines.selectionToggleUnread({ids: ids, no_error: 1});
+ }
+ }));
- menu.addChild(new dijit.MenuItem({
- label: __("Toggle published"),
- onClick: function () {
- let ids = Headlines.getSelected();
- // cast to string
- const id = (this.getParent().currentTarget.getAttribute("data-article-id")) + "";
- ids = ids.length != 0 && ids.indexOf(id) != -1 ? ids : [id];
+ menu.addChild(new dijit.MenuItem({
+ label: __("Toggle starred"),
+ onClick: function () {
+ let ids = Headlines.getSelected();
+ // cast to string
+ const id = (this.getParent().currentTarget.getAttribute("data-article-id")) + "";
+ ids = ids.length != 0 && ids.indexOf(id) != -1 ? ids : [id];
- Headlines.selectionTogglePublished(ids);
- }
- }));
+ Headlines.selectionToggleMarked(ids);
+ }
+ }));
- menu.addChild(new dijit.MenuSeparator());
+ menu.addChild(new dijit.MenuItem({
+ label: __("Toggle published"),
+ onClick: function () {
+ let ids = Headlines.getSelected();
+ // cast to string
+ const id = (this.getParent().currentTarget.getAttribute("data-article-id")) + "";
+ ids = ids.length != 0 && ids.indexOf(id) != -1 ? ids : [id];
- menu.addChild(new dijit.MenuItem({
- label: __("Mark above as read"),
- onClick: function () {
- Headlines.catchupRelativeTo(0, this.getParent().currentTarget.getAttribute("data-article-id"));
- }
- }));
+ Headlines.selectionTogglePublished(ids);
+ }
+ }));
- menu.addChild(new dijit.MenuItem({
- label: __("Mark below as read"),
- onClick: function () {
- Headlines.catchupRelativeTo(1, this.getParent().currentTarget.getAttribute("data-article-id"));
- }
- }));
+ menu.addChild(new dijit.MenuSeparator());
+ menu.addChild(new dijit.MenuItem({
+ label: __("Mark above as read"),
+ onClick: function () {
+ Headlines.catchupRelativeTo(0, this.getParent().currentTarget.getAttribute("data-article-id"));
+ }
+ }));
- const labels = App.getInitParam("labels");
+ menu.addChild(new dijit.MenuItem({
+ label: __("Mark below as read"),
+ onClick: function () {
+ Headlines.catchupRelativeTo(1, this.getParent().currentTarget.getAttribute("data-article-id"));
+ }
+ }));
- if (labels && labels.length) {
- menu.addChild(new dijit.MenuSeparator());
+ const labels = App.getInitParam("labels");
- const labelAddMenu = new dijit.Menu({ownerMenu: menu});
- const labelDelMenu = new dijit.Menu({ownerMenu: menu});
+ if (labels && labels.length) {
- labels.each(function (label) {
- const bare_id = label.id;
- const name = label.caption;
+ menu.addChild(new dijit.MenuSeparator());
- labelAddMenu.addChild(new dijit.MenuItem({
- label: name,
- labelId: bare_id,
- onClick: function () {
+ const labelAddMenu = new dijit.Menu({ownerMenu: menu});
+ const labelDelMenu = new dijit.Menu({ownerMenu: menu});
- let ids = Headlines.getSelected();
- // cast to string
- const id = (this.getParent().ownerMenu.currentTarget.getAttribute("data-article-id")) + "";
+ labels.each(function (label) {
+ const bare_id = label.id;
+ const name = label.caption;
- ids = ids.length != 0 && ids.indexOf(id) != -1 ? ids : [id];
+ labelAddMenu.addChild(new dijit.MenuItem({
+ label: name,
+ labelId: bare_id,
+ onClick: function () {
- Headlines.selectionAssignLabel(this.labelId, ids);
- }
- }));
+ let ids = Headlines.getSelected();
+ // cast to string
+ const id = (this.getParent().ownerMenu.currentTarget.getAttribute("data-article-id")) + "";
- labelDelMenu.addChild(new dijit.MenuItem({
- label: name,
- labelId: bare_id,
- onClick: function () {
- let ids = Headlines.getSelected();
- // cast to string
- const id = (this.getParent().ownerMenu.currentTarget.getAttribute("data-article-id")) + "";
+ ids = ids.length != 0 && ids.indexOf(id) != -1 ? ids : [id];
- ids = ids.length != 0 && ids.indexOf(id) != -1 ? ids : [id];
+ Headlines.selectionAssignLabel(this.labelId, ids);
+ }
+ }));
- Headlines.selectionRemoveLabel(this.labelId, ids);
- }
- }));
+ labelDelMenu.addChild(new dijit.MenuItem({
+ label: name,
+ labelId: bare_id,
+ onClick: function () {
+ let ids = Headlines.getSelected();
+ // cast to string
+ const id = (this.getParent().ownerMenu.currentTarget.getAttribute("data-article-id")) + "";
- });
+ ids = ids.length != 0 && ids.indexOf(id) != -1 ? ids : [id];
- menu.addChild(new dijit.PopupMenuItem({
- label: __("Assign label"),
- popup: labelAddMenu
+ Headlines.selectionRemoveLabel(this.labelId, ids);
+ }
}));
- menu.addChild(new dijit.PopupMenuItem({
- label: __("Remove label"),
- popup: labelDelMenu
- }));
+ });
- }
- },
- scrollByPages: function (page_offset) {
- App.Scrollable.scrollByPages($("headlines-frame"), page_offset);
- },
- scroll: function (offset) {
- App.Scrollable.scroll($("headlines-frame"), offset);
- },
- initHeadlinesMenu: function () {
- if (!dijit.byId("headlinesMenu")) {
+ menu.addChild(new dijit.PopupMenuItem({
+ label: __("Assign label"),
+ popup: labelAddMenu
+ }));
- const menu = new dijit.Menu({
- id: "headlinesMenu",
- targetNodeIds: ["headlines-frame"],
- selector: ".hlMenuAttach"
- });
+ menu.addChild(new dijit.PopupMenuItem({
+ label: __("Remove label"),
+ popup: labelDelMenu
+ }));
- this.headlinesMenuCommon(menu);
+ }
+ },
+ scrollByPages: function (page_offset) {
+ App.Scrollable.scrollByPages($("headlines-frame"), page_offset);
+ },
+ scroll: function (offset) {
+ App.Scrollable.scroll($("headlines-frame"), offset);
+ },
+ initHeadlinesMenu: function () {
+ if (!dijit.byId("headlinesMenu")) {
+
+ const menu = new dijit.Menu({
+ id: "headlinesMenu",
+ targetNodeIds: ["headlines-frame"],
+ selector: ".hlMenuAttach"
+ });
- menu.startup();
- }
+ this.headlinesMenuCommon(menu);
- /* vgroup feed title menu */
+ menu.startup();
+ }
- if (!dijit.byId("headlinesFeedTitleMenu")) {
+ /* vgroup feed title menu */
- const menu = new dijit.Menu({
- id: "headlinesFeedTitleMenu",
- targetNodeIds: ["headlines-frame"],
- selector: "div.cdmFeedTitle"
- });
+ if (!dijit.byId("headlinesFeedTitleMenu")) {
- menu.addChild(new dijit.MenuItem({
- label: __("Select articles in group"),
- onClick: function (event) {
- Headlines.select("all",
- "#headlines-frame > div[id*=RROW]" +
- "[data-orig-feed-id='" + this.getParent().currentTarget.getAttribute("data-feed-id") + "']");
+ const menu = new dijit.Menu({
+ id: "headlinesFeedTitleMenu",
+ targetNodeIds: ["headlines-frame"],
+ selector: "div.cdmFeedTitle"
+ });
- }
- }));
+ menu.addChild(new dijit.MenuItem({
+ label: __("Select articles in group"),
+ onClick: function (event) {
+ Headlines.select("all",
+ "#headlines-frame > div[id*=RROW]" +
+ "[data-orig-feed-id='" + this.getParent().currentTarget.getAttribute("data-feed-id") + "']");
- menu.addChild(new dijit.MenuItem({
- label: __("Mark group as read"),
- onClick: function () {
- Headlines.select("none");
- Headlines.select("all",
- "#headlines-frame > div[id*=RROW]" +
- "[data-orig-feed-id='" + this.getParent().currentTarget.getAttribute("data-feed-id") + "']");
+ }
+ }));
- Headlines.catchupSelection();
- }
- }));
+ menu.addChild(new dijit.MenuItem({
+ label: __("Mark group as read"),
+ onClick: function () {
+ Headlines.select("none");
+ Headlines.select("all",
+ "#headlines-frame > div[id*=RROW]" +
+ "[data-orig-feed-id='" + this.getParent().currentTarget.getAttribute("data-feed-id") + "']");
- menu.addChild(new dijit.MenuItem({
- label: __("Mark feed as read"),
- onClick: function () {
- Feeds.catchupFeedInGroup(this.getParent().currentTarget.getAttribute("data-feed-id"));
- }
- }));
+ Headlines.catchupSelection();
+ }
+ }));
- menu.addChild(new dijit.MenuItem({
- label: __("Edit feed"),
- onClick: function () {
- CommonDialogs.editFeed(this.getParent().currentTarget.getAttribute("data-feed-id"));
- }
- }));
+ menu.addChild(new dijit.MenuItem({
+ label: __("Mark feed as read"),
+ onClick: function () {
+ Feeds.catchupFeedInGroup(this.getParent().currentTarget.getAttribute("data-feed-id"));
+ }
+ }));
- menu.startup();
- }
+ menu.addChild(new dijit.MenuItem({
+ label: __("Edit feed"),
+ onClick: function () {
+ CommonDialogs.editFeed(this.getParent().currentTarget.getAttribute("data-feed-id"));
+ }
+ }));
+
+ menu.startup();
}
}
-
- return Headlines;
-});
+}
diff --git a/js/PluginHost.js b/js/PluginHost.js
index 71596ad31..11f2bd1f1 100644
--- a/js/PluginHost.js
+++ b/js/PluginHost.js
@@ -1,6 +1,6 @@
// based on http://www.velvetcache.org/2010/08/19/a-simple-javascript-hooks-system
-PluginHost = {
+const PluginHost = {
HOOK_ARTICLE_RENDERED: 1,
HOOK_ARTICLE_RENDERED_CDM: 2,
HOOK_ARTICLE_SET_ACTIVE: 3,
diff --git a/js/tt-rss.js b/js/tt-rss.js
index 7c325cedf..2e6fe437f 100644
--- a/js/tt-rss.js
+++ b/js/tt-rss.js
@@ -2,12 +2,6 @@
/* global dijit,__ */
let App;
-let CommonDialogs;
-let Filters;
-let Feeds;
-let Headlines;
-let Article;
-let PluginHost;
const Plugins = {};