1
0
mirror of https://git.tt-rss.org/git/tt-rss.git synced 2025-12-13 15:25:59 +00:00

Merge branch 'master' into css-feedtree-counter

Conflicts:
	tt-rss.css
This commit is contained in:
Andrew Dolgov
2013-05-07 15:36:14 +04:00
218 changed files with 24450 additions and 42954 deletions

View File

@@ -100,7 +100,7 @@ dojo.declare("fox.FeedTree", dijit.Tree, {
_createTreeNode: function(args) {
var tnode = new dijit._TreeNode(args);
if (args.item.icon)
if (args.item.icon && args.item.icon[0])
tnode.iconNode.src = args.item.icon[0];
var id = args.item.id[0];

34
js/PluginHost.js Normal file
View File

@@ -0,0 +1,34 @@
// based on http://www.velvetcache.org/2010/08/19/a-simple-javascript-hooks-system
var PluginHost = {
HOOK_ARTICLE_RENDERED: 1,
HOOK_ARTICLE_RENDERED_CDM: 2,
HOOK_ARTICLE_SET_ACTIVE: 3,
HOOK_FEED_SET_ACTIVE: 4,
HOOK_FEED_LOADED: 5,
HOOK_ARTICLE_EXPANDED: 6,
HOOK_ARTICLE_COLLAPSED: 7,
HOOK_PARAMS_LOADED: 8,
HOOK_RUNTIME_INFO_LOADED: 9,
hooks: [],
register: function (name, callback) {
if (typeof(this.hooks[name]) == 'undefined')
this.hooks[name] = [];
this.hooks[name].push(callback);
},
run: function (name, args) {
console.warn('PluginHost::run ' + name);
if (typeof(this.hooks[name]) != 'undefined')
for (i = 0; i < this.hooks[name].length; i++)
if (!this.hooks[name][i](args)) break;
}
};
/* PluginHost.register(PluginHost.HOOK_ARTICLE_RENDERED,
function (args) { console.log('ARTICLE_RENDERED: ' + args); return true; });
PluginHost.register(PluginHost.HOOK_ARTICLE_RENDERED_CDM,
function (args) { console.log('ARTICLE_RENDERED_CDM: ' + args); return true; }); */

View File

@@ -139,6 +139,7 @@ function viewfeed(feed, method, is_cat, offset, background, infscroll_req) {
onComplete: function(transport) {
setFeedExpandoIcon(feed, is_cat, 'images/blank_icon.gif');
headlines_callback2(transport, offset, background, infscroll_req);
PluginHost.run(PluginHost.HOOK_FEED_LOADED, [feed, is_cat]);
} });
} catch (e) {
@@ -150,6 +151,8 @@ function feedlist_init() {
try {
console.log("in feedlist init");
loading_set_progress(50);
document.onkeydown = hotkey_handler;
setTimeout("hotkey_prefix_timeout()", 5*1000);

View File

@@ -1,8 +1,8 @@
var notify_silent = false;
var loading_progress = 0;
var sanity_check_done = false;
var init_params = {};
var _label_base_index = -1024;
var notify_hide_timerid = false;
Ajax.Base.prototype.initialize = Ajax.Base.prototype.initialize.wrap(
function (callOriginal, options) {
@@ -50,6 +50,21 @@ function exception_error(location, e, ext_info) {
}
}
try {
new Ajax.Request("backend.php", {
parameters: {op: "rpc", method: "log", logmsg: msg},
onComplete: function (transport) {
console.log(transport.responseText);
} });
} catch (eii) {
console.log("Exception while trying to log the error.");
console.log(eii);
}
msg += "<p>"+ __("The error will be reported to the configured log destination.") +
"</p>";
var content = "<div class=\"fatalError\">" +
"<pre>" + msg + "</pre>";
@@ -106,7 +121,28 @@ function exception_error(location, e, ext_info) {
dialog.show();
} catch (e) {
} catch (ei) {
console.log("Exception while trying to report an exception. Oh boy.");
console.log(ei);
console.log("Original exception:");
console.log(e);
msg += "\n\nAdditional exception caught while trying to show the error dialog.\n\n" + format_exception_error('exception_error', ei);
try {
new Ajax.Request("backend.php", {
parameters: {op: "rpc", method: "log", logmsg: msg},
onComplete: function (transport) {
console.log(transport.responseText);
} });
} catch (eii) {
console.log("Third exception while trying to log the error! Seriously?");
console.log(eii);
}
msg += "\n\nThe error will be reported to the configured log destination.";
alert(msg);
}
@@ -147,42 +183,28 @@ function param_unescape(arg) {
return unescape(arg);
}
var notify_hide_timerid = false;
function hide_notify() {
var n = $("notify");
if (n) {
n.style.display = "none";
}
}
function notify_silent_next() {
notify_silent = true;
Element.hide('notify');
}
function notify_real(msg, no_hide, n_type) {
if (notify_silent) {
notify_silent = false;
return;
}
var n = $("notify");
var nb = $("notify_body");
if (!n || !nb) return;
if (!n) return;
if (notify_hide_timerid) {
window.clearTimeout(notify_hide_timerid);
}
if (msg == "") {
if (n.style.display == "block") {
if (Element.visible(n)) {
notify_hide_timerid = window.setTimeout("hide_notify()", 0);
}
return;
} else {
n.style.display = "block";
Element.show(n);
}
/* types:
@@ -194,33 +216,31 @@ function notify_real(msg, no_hide, n_type) {
*/
msg = __(msg);
msg = "<span class=\"msg\"> " + __(msg) + "</span>";
if (n_type == 1) {
n.className = "notify";
} else if (n_type == 2) {
n.className = "notify progress";
msg = "<img src='images/indicator_white.gif'> " + msg;
msg = "<span><img src='images/indicator_white.gif'></span>" + msg;
no_hide = true;
} else if (n_type == 3) {
n.className = "notify error";
msg = "<img src='images/sign_excl.svg'> " + msg;
msg = "<span><img src='images/sign_excl.svg'></span>" + msg;
} else if (n_type == 4) {
n.className = "notify info";
msg = "<img src='images/sign_info.svg'> " + msg;
}
if (no_hide) {
msg += " <span>(<a href='#' onclick=\"notify('')\">" +
__("close") + "</a>)</span>";
msg = "<span><img src='images/sign_info.svg'></span>" + msg;
}
msg += " <span><img src=\"images/close_notify.svg\" class=\"close\" title=\"" +
__("Click to close") + "\" onclick=\"notify('')\"></span>";
// msg = "<img src='images/live_com_loading.gif'> " + msg;
nb.innerHTML = msg;
n.innerHTML = msg;
if (!no_hide) {
notify_hide_timerid = window.setTimeout("hide_notify()", 3000);
notify_hide_timerid = window.setTimeout("hide_notify()", 5*1000);
}
}
@@ -368,6 +388,9 @@ function toggleSelectRow2(sender, row, is_cdm) {
row.addClassName('Selected');
else
row.removeClassName('Selected');
if (typeof updateSelectedPrompt != undefined)
updateSelectedPrompt();
}
@@ -379,6 +402,9 @@ function toggleSelectRow(sender, row) {
row.addClassName('Selected');
else
row.removeClassName('Selected');
if (typeof updateSelectedPrompt != undefined)
updateSelectedPrompt();
}
function checkboxToggleElement(elem, id) {
@@ -810,7 +836,7 @@ function quickAddFeed() {
notify('');
Element.hide("feed_add_spinner");
console.log("GOT RC: " + rc);
console.log(rc);
switch (parseInt(rc['code'])) {
case 1:
@@ -826,39 +852,6 @@ function quickAddFeed() {
alert(__("Specified URL doesn't seem to contain any feeds."));
break;
case 4:
/* notify_progress("Searching for feed urls...", true);
new Ajax.Request("backend.php", {
parameters: 'op=rpc&method=extractfeedurls&url=' + param_escape(feed_url),
onComplete: function(transport, dialog, feed_url) {
notify('');
var reply = JSON.parse(transport.responseText);
var feeds = reply['urls'];
console.log(transport.responseText);
var select = dijit.byId("feedDlg_feedContainerSelect");
while (select.getOptions().length > 0)
select.removeOption(0);
var count = 0;
for (var feedUrl in feeds) {
select.addOption({value: feedUrl, label: feeds[feedUrl]});
count++;
}
// if (count > 5) count = 5;
// select.size = count;
Effect.Appear('feedDlg_feedsContainer', {duration : 0.5});
}
});
break; */
feeds = rc['feeds'];
var select = dijit.byId("feedDlg_feedContainerSelect");
@@ -866,6 +859,8 @@ function quickAddFeed() {
while (select.getOptions().length > 0)
select.removeOption(0);
select.addOption({value: '', label: __("Expand to select feed")});
var count = 0;
for (var feedUrl in feeds) {
select.addOption({value: feedUrl, label: feeds[feedUrl]});
@@ -879,6 +874,11 @@ function quickAddFeed() {
alert(__("Couldn't download the specified URL: %s").
replace("%s", rc['message']));
break;
case 6:
alert(__("XML validation failed: %s").
replace("%s", rc['message']));
break;
break;
case 0:
alert(__("You are already subscribed to this feed."));
break;
@@ -1269,16 +1269,17 @@ function backend_sanity_check_callback(transport) {
if (params) {
console.log('reading init-params...');
if (params) {
for (k in params) {
var v = params[k];
console.log("IP: " + k + " => " + v);
for (k in params) {
var v = params[k];
console.log("IP: " + k + " => " + v);
if (k == "label_base_index") _label_base_index = parseInt(v);
}
if (k == "label_base_index") _label_base_index = parseInt(v);
}
init_params = params;
// PluginHost might not be available on non-index pages
window.PluginHost && PluginHost.run(PluginHost.HOOK_PARAMS_LOADED, init_params);
}
sanity_check_done = true;

0
js/index.html Normal file
View File

View File

@@ -852,6 +852,15 @@ function updatePrefsList() {
} });
}
function updateSystemList() {
new Ajax.Request("backend.php", {
parameters: "?op=pref-system",
onComplete: function(transport) {
dijit.byId('systemConfigTab').attr('content', transport.responseText);
notify("");
} });
}
function selectTab(id, noupdate, method) {
try {
if (!noupdate) {
@@ -867,6 +876,8 @@ function selectTab(id, noupdate, method) {
updatePrefsList();
} else if (id == "userConfig") {
updateUsersList();
} else if (id == "systemConfig") {
updateSystemList();
}
var tab = dijit.byId(id + "Tab");
@@ -951,8 +962,11 @@ function init() {
dojo.addOnLoad(function() {
loading_set_progress(50);
var clientTzOffset = new Date().getTimezoneOffset() * 60;
new Ajax.Request("backend.php", {
parameters: {op: "rpc", method: "sanityCheck"},
parameters: {op: "rpc", method: "sanityCheck",
clientTzOffset: clientTzOffset },
onComplete: function(transport) {
backend_sanity_check_callback(transport);
} });
@@ -1596,21 +1610,6 @@ function resetCatOrder() {
}
}
function toggleHiddenFeedCats() {
try {
notify_progress("Loading, please wait...");
new Ajax.Request("backend.php", {
parameters: "?op=pref-feeds&method=togglehiddenfeedcats",
onComplete: function(transport) {
updateFeedList();
} });
} catch (e) {
exception_error("toggleHiddenFeedCats");
}
}
function editCat(id, item, event) {
try {
var new_name = prompt(__('Rename category to:'), item.name);
@@ -1819,3 +1818,21 @@ function clearPluginData(name) {
exception_error("clearPluginData", e);
}
}
function clearSqlLog() {
if (confirm(__("Clear all messages in the error log?"))) {
notify_progress("Loading, please wait...");
var query = "?op=pref-system&method=clearLog";
new Ajax.Request("backend.php", {
parameters: query,
onComplete: function(transport) {
updateSystemList();
} });
}
}

View File

@@ -40,6 +40,8 @@ function setActiveFeedId(id, is_cat) {
$("headlines-frame").setAttribute("is-cat", is_cat ? 1 : 0);
selectFeed(id, is_cat);
PluginHost.run(PluginHost.HOOK_FEED_SET_ACTIVE, _active_article_id);
} catch (e) {
exception_error("setActiveFeedId", e);
}
@@ -134,7 +136,8 @@ function catchupAllFeeds() {
new Ajax.Request("backend.php", {
parameters: query_str,
onComplete: function(transport) {
feedlist_callback2(transport);
request_counters(true);
viewCurrentFeed();
} });
global_unread = 0;
@@ -246,13 +249,19 @@ function init() {
if (!genericSanityCheck())
return false;
loading_set_progress(20);
loading_set_progress(30);
var hasAudio = !!((myAudioTag = document.createElement('audio')).canPlayType);
var a = document.createElement('audio');
var hasAudio = !!a.canPlayType;
var hasSandbox = "sandbox" in document.createElement("iframe");
var hasMp3 = !!(a.canPlayType && a.canPlayType('audio/mpeg;').replace(/no/, ''));
var clientTzOffset = new Date().getTimezoneOffset() * 60;
new Ajax.Request("backend.php", {
parameters: {op: "rpc", method: "sanityCheck", hasAudio: hasAudio,
hasMp3: hasMp3,
clientTzOffset: clientTzOffset,
hasSandbox: hasSandbox},
onComplete: function(transport) {
backend_sanity_check_callback(transport);
@@ -302,7 +311,7 @@ function init() {
var id = getActiveArticleId();
var elem = $("CICD-"+id);
if(elem.visible()) {
cdmUnexpandArticle(null, id);
cdmCollapseArticle(null, id, false);
}
else {
cdmExpandArticle(id);
@@ -323,7 +332,7 @@ function init() {
hotkey_actions["edit_tags"] = function() {
var id = getActiveArticleId();
if (id) {
editArticleTags(id, getActiveFeedId(), isCdmMode());
editArticleTags(id);
};
}
hotkey_actions["dismiss_selected"] = function() {
@@ -564,7 +573,7 @@ function init_second_stage() {
setActiveFeedId(hash_feed_id, hash_feed_is_cat);
}
loading_set_progress(30);
loading_set_progress(50);
// can't use cache_clear() here because viewfeed might not have initialized yet
if ('sessionStorage' in window && window['sessionStorage'] !== null)
@@ -744,6 +753,8 @@ function parse_runtime_info(data) {
init_params[k] = v;
notify('');
}
PluginHost.run(PluginHost.HOOK_RUNTIME_INFO_LOADED, data);
}
function collapse_feedlist() {
@@ -983,7 +994,7 @@ function handle_rpc_json(transport, scheduled_call) {
if (counters)
parse_counters(counters, scheduled_call);
var runtime_info = reply['runtime-info'];;
var runtime_info = reply['runtime-info'];
if (runtime_info)
parse_runtime_info(runtime_info);
@@ -1072,7 +1083,7 @@ function hash_get(key) {
kv = window.location.hash.substring(1).toQueryParams();
return kv[key];
} catch (e) {
exception_error("hash_set", e);
exception_error("hash_get", e);
}
}
function hash_set(key, value) {

View File

@@ -20,8 +20,6 @@ function headlines_callback2(transport, offset, background, infscroll_req) {
try {
handle_rpc_json(transport);
loading_set_progress(25);
console.log("headlines_callback2 [offset=" + offset + "] B:" + background + " I:" + infscroll_req);
var is_cat = false;
@@ -43,9 +41,7 @@ function headlines_callback2(transport, offset, background, infscroll_req) {
if (background) {
var content = reply['headlines']['content'];
if (getInitParam("cdm_auto_catchup") == 1) {
content = content + "<div id='headlines-spacer'></div>";
}
content = content + "<div id='headlines-spacer'></div>";
return;
}
@@ -93,11 +89,9 @@ function headlines_callback2(transport, offset, background, infscroll_req) {
}
});
if (getInitParam("cdm_auto_catchup") == 1) {
var hsp = $("headlines-spacer");
if (!hsp) hsp = new Element("DIV", {"id": "headlines-spacer"});
dijit.byId('headlines-frame').domNode.appendChild(hsp);
}
var hsp = $("headlines-spacer");
if (!hsp) hsp = new Element("DIV", {"id": "headlines-spacer"});
dijit.byId('headlines-frame').domNode.appendChild(hsp);
initHeadlinesMenu();
@@ -140,8 +134,6 @@ function headlines_callback2(transport, offset, background, infscroll_req) {
if (!hsp) hsp = new Element("DIV", {"id": "headlines-spacer"});
fixHeadlinesOrder(getLoadedArticleIds());
if (getInitParam("cdm_auto_catchup") == 1) {
c.domNode.appendChild(hsp);
}
@@ -232,6 +224,8 @@ function render_article(article) {
c.domNode.scrollTop = 0;
} catch (e) { };
PluginHost.run(PluginHost.HOOK_ARTICLE_RENDERED, article);
c.attr('content', article);
correctHeadlinesOffset(getActiveArticleId());
@@ -639,11 +633,33 @@ function toggleSelected(id, force_on) {
if (cb) cb.attr("checked", true);
}
}
updateSelectedPrompt();
} catch (e) {
exception_error("toggleSelected", e);
}
}
function updateSelectedPrompt() {
try {
var count = getSelectedArticleIds2().size();
var elem = $("selected_prompt");
if (elem) {
elem.innerHTML = ngettext("%d article selected",
"%d articles selected", count).replace("%d", count);
if (count > 0)
Element.show(elem);
else
Element.hide(elem);
}
} catch (e) {
exception_error("updateSelectedPrompt", e);
}
}
function toggleUnread_afh(effect) {
try {
@@ -960,6 +976,8 @@ function selectArticles(mode) {
}
});
updateSelectedPrompt();
} catch (e) {
exception_error("selectArticles", e);
}
@@ -1169,6 +1187,7 @@ function cdmScrollToArticleId(id, force) {
function setActiveArticleId(id) {
_active_article_id = id;
PluginHost.run(PluginHost.HOOK_ARTICLE_SET_ACTIVE, _active_article_id);
}
function getActiveArticleId() {
@@ -1195,6 +1214,8 @@ function unpackVisibleHeadlines() {
var cencw = $("CENCW-" + child.id.replace("RROW-", ""));
if (cencw) {
PluginHost.run(PluginHost.HOOK_ARTICLE_RENDERED_CDM, child);
cencw.innerHTML = htmlspecialchars_decode(cencw.innerHTML);
cencw.setAttribute('id', '');
Element.show(cencw);
@@ -1370,8 +1391,10 @@ function catchupRelativeToArticle(below, id) {
}
}
function cdmCollapseArticle(event, id) {
function cdmCollapseArticle(event, id, unmark) {
try {
if (unmark == undefined) unmark = true;
var row = $("RROW-" + id);
var elem = $("CICD-" + id);
@@ -1382,15 +1405,22 @@ function cdmCollapseArticle(event, id) {
Element.hide(elem);
Element.show("CEXC-" + id);
Element.hide(collapse);
row.removeClassName("active");
markHeadline(id, false);
if (unmark) {
row.removeClassName("active");
if (id == getActiveArticleId()) {
setActiveArticleId(0);
markHeadline(id, false);
if (id == getActiveArticleId()) {
setActiveArticleId(0);
}
updateSelectedPrompt();
}
if (event) Event.stop(event);
PluginHost.run(PluginHost.HOOK_ARTICLE_COLLAPSED, id);
}
} catch (e) {
@@ -1398,27 +1428,6 @@ function cdmCollapseArticle(event, id) {
}
}
function cdmUnexpandArticle(event, id) {
try {
var row = $("RROW-" + id);
var elem = $("CICD-" + id);
if (elem && row) {
var collapse = $$("div#RROW-" + id +
" span[class='collapseBtn']")[0];
Element.hide(elem);
Element.show("CEXC-" + id);
Element.hide(collapse);
if (event) Event.stop(event);
}
} catch (e) {
exception_error("cdmUnexpandArticle", e);
}
}
function cdmExpandArticle(id, noexpand) {
try {
console.log("cdmExpandArticle " + id);
@@ -1478,6 +1487,8 @@ function cdmExpandArticle(id, noexpand) {
toggleSelected(id);
$("RROW-" + id).addClassName("active");
PluginHost.run(PluginHost.HOOK_ARTICLE_EXPANDED, id);
} catch (e) {
exception_error("cdmExpandArticle", e);
}
@@ -1485,26 +1496,6 @@ function cdmExpandArticle(id, noexpand) {
return false;
}
function fixHeadlinesOrder(ids) {
try {
for (var i = 0; i < ids.length; i++) {
var e = $("RROW-" + ids[i]);
if (e) {
if (i % 2 == 0) {
e.removeClassName("even");
e.addClassName("odd");
} else {
e.removeClassName("odd");
e.addClassName("even");
}
}
}
} catch (e) {
exception_error("fixHeadlinesOrder", e);
}
}
function getArticleUnderPointer() {
return post_under_pointer;
}
@@ -1585,7 +1576,6 @@ function dismissSelectedArticles() {
if (sel.length > 0)
selectionToggleUnread(false);
fixHeadlinesOrder(tmp);
} catch (e) {
exception_error("dismissSelectedArticles", e);
@@ -1610,8 +1600,6 @@ function dismissReadArticles() {
}
}
fixHeadlinesOrder(tmp);
} catch (e) {
exception_error("dismissSelectedArticles", e);
}
@@ -2003,34 +1991,6 @@ function initHeadlinesMenu() {
}
}
function player(elem) {
var aid = elem.getAttribute("audio-id");
var status = elem.getAttribute("status");
var audio = $(aid);
if (audio) {
if (status == 0) {
audio.play();
status = 1;
elem.innerHTML = __("Playing...");
elem.title = __("Click to pause");
elem.addClassName("playing");
} else {
audio.pause();
status = 0;
elem.innerHTML = __("Play");
elem.title = __("Click to play");
elem.removeClassName("playing");
}
elem.setAttribute("status", status);
} else {
alert("Your browser doesn't seem to support HTML5 audio.");
}
}
function cache_set(id, obj) {
//console.log("cache_set: " + id);
if (has_storage)