-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) {
try {
- if (ext_info) {
- if (ext_info.responseText) {
- ext_info = ext_info.responseText;
- }
+ if (ext_info)
+ ext_info = JSON.stringify(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>";
title: "Unhandled exception",
style: "width: 600px",
report: function() {
- if (confirm(__("Are you sure to report this exception to tt-rss.org? The report will include your browser information. Your IP would be saved in the database."))) {
+ if (confirm(__("Are you sure to report this exception to tt-rss.org? The report will include information about your web browser and tt-rss configuration. Your IP will be saved in the database."))) {
document.forms['exceptionForm'].params.value = $H({
browserName: navigator.appName,
browserVersion: navigator.appVersion,
browserPlatform: navigator.platform,
browserCookies: navigator.cookieEnabled,
+ ttrssVersion: __ttrss_version,
+ initParams: JSON.stringify(init_params),
}).toQueryString();
document.forms['exceptionForm'].submit();
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);
}
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;
-}
-
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") {
- notify_hide_timerid = window.setTimeout("hide_notify()", 0);
+ if (n.hasClassName("visible")) {
+ notify_hide_timerid = window.setTimeout(function() {
+ n.removeClassName("visible") }, 0);
}
return;
- } else {
- n.style.display = "block";
}
/* types:
*/
- if (typeof __ != 'undefined') {
- msg = __(msg);
- }
+ msg = "<span class=\"msg\"> " + __(msg) + "</span>";
- if (n_type == 1) {
- n.className = "notify";
- } else if (n_type == 2) {
- n.className = "notifyProgress";
- msg = "<img src='"+getInitParam("sign_progress")+"'> " + msg;
+ if (n_type == 2) {
+ msg = "<span><img src='images/indicator_white.gif'></span>" + msg;
+ no_hide = true;
} else if (n_type == 3) {
- n.className = "notifyError";
- msg = "<img src='"+getInitParam("sign_excl")+"'> " + msg;
+ msg = "<span><img src='images/alert.png'></span>" + msg;
} else if (n_type == 4) {
- n.className = "notifyInfo";
- msg = "<img src='"+getInitParam("sign_info")+"'> " + msg;
+ msg = "<span><img src='images/information.png'></span>" + msg;
}
-// msg = "<img src='images/live_com_loading.gif'> " + msg;
+ msg += " <span><img src=\"images/cross.png\" class=\"close\" title=\"" +
+ __("Click to close") + "\" onclick=\"notify('')\"></span>";
- nb.innerHTML = msg;
+ n.innerHTML = msg;
+
+ window.setTimeout(function() {
+ // goddamnit firefox
+ if (n_type == 2) {
+ n.className = "notify notify_progress visible";
+ } else if (n_type == 3) {
+ n.className = "notify notify_error visible";
+ msg = "<span><img src='images/alert.png'></span>" + msg;
+ } else if (n_type == 4) {
+ n.className = "notify notify_info visible";
+ } else {
+ n.className = "notify visible";
+ }
+
+ if (!no_hide) {
+ notify_hide_timerid = window.setTimeout(function() {
+ n.removeClassName("visible") }, 5*1000);
+ }
+
+ }, 10);
- if (!no_hide) {
- notify_hide_timerid = window.setTimeout("hide_notify()", 3000);
- }
}
function notify(msg, no_hide) {
row.addClassName('Selected');
else
row.removeClassName('Selected');
+
+ if (typeof updateSelectedPrompt != undefined)
+ updateSelectedPrompt();
}
row.addClassName('Selected');
else
row.removeClassName('Selected');
+
+ if (typeof updateSelectedPrompt != undefined)
+ updateSelectedPrompt();
}
function checkboxToggleElement(elem, id) {
}
-function displayDlg(id, param, callback) {
+function displayDlg(title, id, param, callback) {
notify_progress("Loading, please wait...", true);
new Ajax.Request("backend.php", {
parameters: query,
onComplete: function (transport) {
- infobox_callback2(transport);
+ infobox_callback2(transport, title);
if (callback) callback(transport);
} });
return false;
}
-function infobox_callback2(transport) {
+function infobox_callback2(transport, title) {
try {
var dialog = false;
//console.log("infobox_callback2");
notify('');
- var title = transport.responseXML.getElementsByTagName("title")[0];
- if (title)
- title = title.firstChild.nodeValue;
-
- var content = transport.responseXML.getElementsByTagName("content")[0];
-
- content = content.firstChild.nodeValue;
+ var content = transport.responseText;
if (!dialog) {
dialog = new dijit.Dialog({
}
}
-function filterCR(e, f)
-{
- var key;
-
- if(window.event)
- key = window.event.keyCode; //IE
- else
- key = e.which; //firefox
-
- if (key == 13) {
- if (typeof f != 'undefined') {
- f();
- return false;
- } else {
- return false;
- }
- } else {
- return true;
- }
-}
-
function getInitParam(key) {
return init_params[key];
}
if (code == 6) {
window.location.href = "index.php";
} else if (code == 5) {
- window.location.href = "db-updater.php";
+ window.location.href = "public.php?op=dbupdate";
} else {
if (msg == "") msg = "Unknown error";
}
}
-/* function filterDlgCheckType(sender) {
-
- try {
-
- var ftype = sender.value;
-
- // if selected filter type is 5 (Date) enable the modifier dropbox
- if (ftype == 5) {
- Element.show("filterDlg_dateModBox");
- Element.show("filterDlg_dateChkBox");
- } else {
- Element.hide("filterDlg_dateModBox");
- Element.hide("filterDlg_dateChkBox");
-
- }
-
- } catch (e) {
- exception_error("filterDlgCheckType", e);
- }
-
-} */
-
function filterDlgCheckAction(sender) {
try {
}
// if selected action supports parameters, enable params field
- if (action == 4 || action == 6 || action == 7) {
+ 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_actionParam").domNode);
- Element.hide(dijit.byId("filterDlg_actionParamLabel").domNode);
- } else {
+
+ 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);
- Element.hide(dijit.byId("filterDlg_actionParam").domNode);
+ } else if (action == 9) {
+ Element.show(dijit.byId("filterDlg_actionParamPlugin").domNode);
+ } else {
+ Element.show(dijit.byId("filterDlg_actionParam").domNode);
}
+
} else {
Element.hide(action_param);
}
}
-function filterDlgCheckDate() {
- try {
- var dialog = dijit.byId("filterEditDlg");
-
- var reg_exp = dialog.attr('value').reg_exp;
-
- var query = "?op=rpc&method=checkDate&date=" + reg_exp;
-
- new Ajax.Request("backend.php", {
- parameters: query,
- onComplete: function(transport) {
-
- var reply = JSON.parse(transport.responseText);
-
- if (reply['result'] == true) {
- alert(__("Date syntax appears to be correct:") + " " + reply['date']);
- return;
- } else {
- alert(__("Date syntax is incorrect."));
- }
-
- } });
-
-
- } catch (e) {
- exception_error("filterDlgCheckDate", e);
- }
-}
function explainError(code) {
- return displayDlg("explainError", code);
+ return displayDlg(__("Error explained"), "explainError", code);
}
function loading_set_progress(p) {
}
}
-function hideAuxDlg() {
- try {
- Element.hide('auxDlg');
- } catch (e) {
- exception_error("hideAuxDlg", e);
- }
-}
-
-
function uploadIconHandler(rc) {
try {
switch (rc) {
function quickAddFeed() {
try {
- var query = "backend.php?op=dlg&method=quickAddFeed";
+ var query = "backend.php?op=feeds&method=quickAddFeed";
// overlapping widgets
if (dijit.byId("batchSubDlg")) dijit.byId("batchSubDlg").destroyRecursive();
onComplete: function(transport) {
try {
- var reply = JSON.parse(transport.responseText);
+ try {
+ var reply = JSON.parse(transport.responseText);
+ } catch (e) {
+ Element.hide("feed_add_spinner");
+ alert(__("Failed to parse output. This can indicate server timeout and/or network issues. Backend output was logged to browser console."));
+ console.log('quickAddFeed, backend returned:' + transport.responseText);
+ return;
+ }
var rc = reply['result'];
notify('');
Element.hide("feed_add_spinner");
- console.log("GOT RC: " + rc);
+ console.log(rc);
switch (parseInt(rc['code'])) {
case 1:
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'];
+ Element.show("fadd_multiple_notify");
+
var select = dijit.byId("feedDlg_feedContainerSelect");
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]});
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;
try {
var form = document.forms["filter_new_rule_form"];
- form.reg_exp.value = form.reg_exp.value.replace(/(<([^>]+)>)/ig,"");
+ //form.reg_exp.value = form.reg_exp.value.replace(/(<([^>]+)>)/ig,"");
var query = "backend.php?op=pref-filters&method=printrulename&rule="+
param_escape(dojo.formToJson(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;
}
var query = "backend.php?op=pref-filters&method=printactionname&action="+
}
}
+function editFilterTest(query) {
+ try {
+
+ if (dijit.byId("filterTestDlg"))
+ dijit.byId("filterTestDlg").destroyRecursive();
+
+ var test_dlg = new dijit.Dialog({
+ id: "filterTestDlg",
+ title: "Test Filter",
+ style: "width: 600px",
+ results: 0,
+ limit: 100,
+ max_offset: 10000,
+ getTestResults: function(query, offset) {
+ var updquery = query + "&offset=" + offset + "&limit=" + test_dlg.limit;
+
+ console.log("getTestResults:" + offset);
+
+ new Ajax.Request("backend.php", {
+ parameters: updquery,
+ onComplete: function (transport) {
+ try {
+ var result = JSON.parse(transport.responseText);
+
+ if (result && dijit.byId("filterTestDlg") && dijit.byId("filterTestDlg").open) {
+ test_dlg.results += result.size();
+
+ console.log("got results:" + result.size());
+
+ $("prefFilterProgressMsg").innerHTML = __("Looking for articles (%d processed, %f found)...")
+ .replace("%f", test_dlg.results)
+ .replace("%d", offset);
+
+ console.log(offset + " " + test_dlg.max_offset);
+
+ for (var i = 0; i < result.size(); i++) {
+ var tmp = new Element("table");
+ tmp.innerHTML = result[i];
+ dojo.parser.parse(tmp);
+
+ $("prefFilterTestResultList").innerHTML += tmp.innerHTML;
+ }
+
+ if (test_dlg.results < 30 && offset < test_dlg.max_offset) {
+
+ // get the next batch
+ window.setTimeout(function () {
+ test_dlg.getTestResults(query, offset + test_dlg.limit);
+ }, 0);
+
+ } else {
+ // all done
+
+ Element.hide("prefFilterLoadingIndicator");
+
+ 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 if (!result) {
+ console.log("getTestResults: can't parse results object");
+
+ Element.hide("prefFilterLoadingIndicator");
+
+ notify_error("Error while trying to get filter test results.");
+
+ } else {
+ console.log("getTestResults: dialog closed, bailing out.");
+ }
+ } catch (e) {
+ exception_error("editFilterTest/inner", e);
+ }
+
+ } });
+ },
+ href: query});
+
+ dojo.connect(test_dlg, "onLoad", null, function(e) {
+ test_dlg.getTestResults(query, 0);
+ });
+
+ test_dlg.show();
+
+ } catch (e) {
+ exception_error("editFilterTest", e);
+ }
+}
+
function quickAddFilter() {
try {
var query = "";
test: function() {
var query = "backend.php?" + dojo.formToQuery("filter_new_form") + "&savemode=test";
- if (dijit.byId("filterTestDlg"))
- dijit.byId("filterTestDlg").destroyRecursive();
-
- var test_dlg = new dijit.Dialog({
- id: "filterTestDlg",
- title: "Test Filter",
- style: "width: 600px",
- href: query});
-
- test_dlg.show();
+ editFilterTest(query);
},
selectRules: function(select) {
$$("#filterDlg_Matches input[type=checkbox]").each(function(e) {
href: query});
if (!inPreferences()) {
+ var selectedText = getSelectionText();
+
var lh = dojo.connect(dialog, "onLoad", function(){
dojo.disconnect(lh);
- var title = $("PTITLE-FULL-" + getActiveArticleId());
-
- if (title || getActiveFeedId() || activeFeedIsCat()) {
- if (title) title = title.innerHTML;
-
- console.log(title + " " + getActiveFeedId());
+ if (selectedText != "") {
var feed_id = activeFeedIsCat() ? 'CAT:' + parseInt(getActiveFeedId()) :
getActiveFeedId();
- var rule = { reg_exp: title, feed_id: feed_id, filter_type: 1 };
+ var rule = { reg_exp: selectedText, feed_id: feed_id, filter_type: 1 };
addFilterRule(null, dojo.toJson(rule));
+
+ } else {
+
+ var query = "op=rpc&method=getlinktitlebyid&id=" + getActiveArticleId();
+
+ new Ajax.Request("backend.php", {
+ parameters: query,
+ onComplete: function(transport) {
+ var reply = JSON.parse(transport.responseText);
+
+ var title = false;
+
+ if (reply && reply) title = reply.title;
+
+ if (title || getActiveFeedId() || activeFeedIsCat()) {
+
+ console.log(title + " " + getActiveFeedId());
+
+ var feed_id = activeFeedIsCat() ? 'CAT:' + parseInt(getActiveFeedId()) :
+ getActiveFeedId();
+
+ var rule = { reg_exp: title, feed_id: feed_id, filter_type: 1 };
+
+ addFilterRule(null, dojo.toJson(rule));
+ }
+
+ } });
+
}
+
});
}
updateFeedList();
} else {
if (feed_id == getActiveFeedId())
- setTimeout("viewfeed(-5)", 100);
+ setTimeout("viewfeed({feed:-5})", 100);
if (feed_id < 0) updateFeedList();
}
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) {
+ console.log("IP: " + k + " => " + JSON.stringify(params[k]));
+ if (k == "label_base_index") _label_base_index = parseInt(params[k]);
}
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;
notify_progress("Trying to change address...", true);
- var query = "?op=rpc&method=regenFeedKey&id=" + param_escape(feed) +
+ var query = "?op=pref-feeds&method=regenFeedKey&id=" + param_escape(feed) +
"&is_cat=" + param_escape(is_cat);
new Ajax.Request("backend.php", {
function feedBrowser() {
try {
- var query = "backend.php?op=dlg&method=feedBrowser";
+ var query = "backend.php?op=feeds&method=feedBrowser";
if (dijit.byId("feedAddDlg"))
dijit.byId("feedAddDlg").hide();
} });
},
removeFromArchive: function() {
- var selected = this.getSelectedFeeds();
+ var selected = this.getSelectedFeedIds();
if (selected.length > 0) {
if (confirm(pr)) {
Element.show('feed_browser_spinner');
- var query = "?op=rpc&method=remarchived&ids=" +
+ var query = "?op=rpc&method=remarchive&ids=" +
param_escape(selected.toString());;
new Ajax.Request("backend.php", {
}
}
+function htmlspecialchars_decode (string, quote_style) {
+ // http://kevin.vanzonneveld.net
+ // + original by: Mirek Slugen
+ // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
+ // + bugfixed by: Mateusz "loonquawl" Zalega
+ // + input by: ReverseSyntax
+ // + input by: Slawomir Kaniecki
+ // + input by: Scott Cariss
+ // + input by: Francois
+ // + bugfixed by: Onno Marsman
+ // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
+ // + bugfixed by: Brett Zamir (http://brett-zamir.me)
+ // + input by: Ratheous
+ // + input by: Mailfaker (http://www.weedem.fr/)
+ // + reimplemented by: Brett Zamir (http://brett-zamir.me)
+ // + bugfixed by: Brett Zamir (http://brett-zamir.me)
+ // * example 1: htmlspecialchars_decode("<p>this -> "</p>", 'ENT_NOQUOTES');
+ // * returns 1: '<p>this -> "</p>'
+ // * example 2: htmlspecialchars_decode("&quot;");
+ // * returns 2: '"'
+ var optTemp = 0,
+ i = 0,
+ noquotes = false;
+ if (typeof quote_style === 'undefined') {
+ quote_style = 2;
+ }
+ string = string.toString().replace(/</g, '<').replace(/>/g, '>');
+ var OPTS = {
+ 'ENT_NOQUOTES': 0,
+ 'ENT_HTML_QUOTE_SINGLE': 1,
+ 'ENT_HTML_QUOTE_DOUBLE': 2,
+ 'ENT_COMPAT': 2,
+ 'ENT_QUOTES': 3,
+ 'ENT_IGNORE': 4
+ };
+ if (quote_style === 0) {
+ noquotes = true;
+ }
+ if (typeof quote_style !== 'number') { // Allow for a single string or an array of string flags
+ quote_style = [].concat(quote_style);
+ for (i = 0; i < quote_style.length; i++) {
+ // Resolve string input to bitwise e.g. 'PATHINFO_EXTENSION' becomes 4
+ if (OPTS[quote_style[i]] === 0) {
+ noquotes = true;
+ } else if (OPTS[quote_style[i]]) {
+ optTemp = optTemp | OPTS[quote_style[i]];
+ }
+ }
+ quote_style = optTemp;
+ }
+ if (quote_style & OPTS.ENT_HTML_QUOTE_SINGLE) {
+ string = string.replace(/�*39;/g, "'"); // PHP doesn't currently escape if more than one 0, but it should
+ // string = string.replace(/'|�*27;/g, "'"); // This would also be useful here, but not a part of PHP
+ }
+ if (!noquotes) {
+ string = string.replace(/"/g, '"');
+ }
+ // Put this in last place to avoid escape being double-decoded
+ string = string.replace(/&/g, '&');
+
+ return string;
+}
+
+
+function label_to_feed_id(label) {
+ return _label_base_index - 1 - Math.abs(label);
+}
+
+function feed_to_label_id(feed) {
+ return _label_base_index - 1 + Math.abs(feed);
+}
+
+// http://stackoverflow.com/questions/6251937/how-to-get-selecteduser-highlighted-text-in-contenteditable-element-and-replac
+
+function getSelectionText() {
+ var text = "";
+
+ if (typeof window.getSelection != "undefined") {
+ var sel = window.getSelection();
+ if (sel.rangeCount) {
+ var container = document.createElement("div");
+ for (var i = 0, len = sel.rangeCount; i < len; ++i) {
+ container.appendChild(sel.getRangeAt(i).cloneContents());
+ }
+ text = container.innerHTML;
+ }
+ } else if (typeof document.selection != "undefined") {
+ if (document.selection.type == "Text") {
+ text = document.selection.createRange().textText;
+ }
+ }
+
+ return text.stripTags();
+}
+
+function openArticlePopup(id) {
+ window.open("backend.php?op=article&method=view&mode=raw&html=1&zoom=1&id=" + id +
+ "&csrf_token=" + getInitParam("csrf_token"),
+ "ttrss_article_popup",
+ "height=900,width=900,resizable=yes,status=no,location=no,menubar=no,directories=no,scrollbars=yes,toolbar=no");
+}
\ No newline at end of file