let loading_progress = 0;
let notify_hide_timerid = false;
+let hotkey_prefix = 0;
+let hotkey_prefix_pressed = false;
+
Ajax.Base.prototype.initialize = Ajax.Base.prototype.initialize.wrap(
function (callOriginal, options) {
function xhrPost(url, params, complete) {
console.log("xhrPost:", params);
- new Ajax.Request(url, {
- parameters: params,
- onComplete: complete
- });
+ return new Ajax.Request(url, {
+ parameters: params,
+ onComplete: complete
+ });
}
function xhrJson(url, params, complete) {
- xhrPost(url, params, (reply) => {
- try {
- const obj = JSON.parse(reply.responseText);
- complete(obj);
- } catch (e) {
- console.error("xhrJson", e, reply);
- complete(null);
- }
-
- })
+ return xhrPost(url, params, (reply) => {
+ try {
+ const obj = JSON.parse(reply.responseText);
+ complete(obj);
+ } catch (e) {
+ console.error("xhrJson", e, reply);
+ complete(null);
+ }
+
+ })
}
/* add method to remove element from array */
const prefix = name + "=";
let begin = dc.indexOf("; " + prefix);
if (begin == -1) {
- begin = dc.indexOf(prefix);
- if (begin != 0) return null;
+ begin = dc.indexOf(prefix);
+ if (begin != 0) return null;
}
else {
- begin += 2;
+ begin += 2;
}
let end = document.cookie.indexOf(";", begin);
if (end == -1) {
- end = dc.length;
+ end = dc.length;
}
return unescape(dc.substring(begin + prefix.length, end));
}
const query = { op: "dlg", method: id, param: param };
xhrPost("backend.php", query, (transport) => {
- infobox_callback2(transport, title);
- if (callback) callback(transport);
+ infobox_callback2(transport, title);
+ if (callback) callback(transport);
});
return false;
dijit.byId("loading_bar").update({progress: loading_progress});
if (loading_progress >= 90)
- remove_splash();
-
-}
+ Element.hide("overlay");
-function remove_splash() {
- Element.hide("overlay");
}
function strip_tags(s) {
hotkey_prefix = false;
Element.hide('cmdline');
}
-
- setTimeout(hotkey_prefix_timeout, 1000);
-
}
function uploadIconHandler(rc) {
notify_progress("Removing feed icon...", true);
- const query = { op: "pref-feeds", method: "removeicon", feed_id: id };
+ const query = { op: "pref-feeds", method: "removeicon", feed_id: id };
xhrPost("backend.php", query, (transport) => {
- notify_info("Feed icon removed.");
- if (inPreferences()) {
- updateFeedList();
- } else {
- setTimeout('updateFeedList(false, false)', 50);
- }
- });
+ notify_info("Feed icon removed.");
+ if (inPreferences()) {
+ updateFeedList();
+ } else {
+ setTimeout('updateFeedList(false, false)', 50);
+ }
+ });
}
return false;
notify_progress("Loading, please wait...", true);
xhrPost("backend.php", query, (transport) => {
- if (callback) {
- callback(transport);
- } else if (inPreferences()) {
- updateLabelList();
- } else {
- updateFeedList();
- }
- });
+ if (callback) {
+ callback(transport);
+ } else if (inPreferences()) {
+ updateLabelList();
+ } else {
+ updateFeedList();
+ }
+ });
}
}
Element.hide("fadd_error_message");
xhrPost("backend.php", this.attr('value'), (transport) => {
- try {
-
- try {
- var reply = JSON.parse(transport.responseText);
- } catch (e) {
- Element.hide("feed_add_spinner");
- alert(__("Failed to parse output. This can indicate server timeout and/or network issues. Backend output was logged to browser console."));
- console.log('quickAddFeed, backend returned:' + transport.responseText);
- return;
- }
-
- const rc = reply['result'];
-
- notify('');
- Element.hide("feed_add_spinner");
-
- console.log(rc);
-
- switch (parseInt(rc['code'])) {
- case 1:
- dialog.hide();
- notify_info(__("Subscribed to %s").replace("%s", feed_url));
-
- updateFeedList();
- break;
- case 2:
- dialog.show_error(__("Specified URL seems to be invalid."));
- break;
- case 3:
- dialog.show_error(__("Specified URL doesn't seem to contain any feeds."));
- break;
- case 4:
- const feeds = rc['feeds'];
-
- Element.show("fadd_multiple_notify");
-
- const select = dijit.byId("feedDlg_feedContainerSelect");
-
- while (select.getOptions().length > 0)
- select.removeOption(0);
-
- select.addOption({value: '', label: __("Expand to select feed")});
-
- let count = 0;
- for (const feedUrl in feeds) {
- select.addOption({value: feedUrl, label: feeds[feedUrl]});
- count++;
- }
-
- Effect.Appear('feedDlg_feedsContainer', {duration : 0.5});
-
- break;
- case 5:
- dialog.show_error(__("Couldn't download the specified URL: %s").
- replace("%s", rc['message']));
- break;
- case 6:
- dialog.show_error(__("XML validation failed: %s").
- replace("%s", rc['message']));
- break;
- case 0:
- dialog.show_error(__("You are already subscribed to this feed."));
- break;
- }
-
- } catch (e) {
- console.error(transport.responseText);
- exception_error(e);
- }
+ try {
+
+ try {
+ var reply = JSON.parse(transport.responseText);
+ } catch (e) {
+ Element.hide("feed_add_spinner");
+ alert(__("Failed to parse output. This can indicate server timeout and/or network issues. Backend output was logged to browser console."));
+ console.log('quickAddFeed, backend returned:' + transport.responseText);
+ return;
+ }
+
+ const rc = reply['result'];
+
+ notify('');
+ Element.hide("feed_add_spinner");
+
+ console.log(rc);
+
+ switch (parseInt(rc['code'])) {
+ case 1:
+ dialog.hide();
+ notify_info(__("Subscribed to %s").replace("%s", feed_url));
+
+ updateFeedList();
+ break;
+ case 2:
+ dialog.show_error(__("Specified URL seems to be invalid."));
+ break;
+ case 3:
+ dialog.show_error(__("Specified URL doesn't seem to contain any feeds."));
+ break;
+ case 4:
+ const feeds = rc['feeds'];
+
+ Element.show("fadd_multiple_notify");
+
+ const select = dijit.byId("feedDlg_feedContainerSelect");
+
+ while (select.getOptions().length > 0)
+ select.removeOption(0);
+
+ select.addOption({value: '', label: __("Expand to select feed")});
+
+ let count = 0;
+ for (const feedUrl in feeds) {
+ select.addOption({value: feedUrl, label: feeds[feedUrl]});
+ count++;
+ }
+
+ Effect.Appear('feedDlg_feedsContainer', {duration : 0.5});
+
+ break;
+ case 5:
+ dialog.show_error(__("Couldn't download the specified URL: %s").
+ replace("%s", rc['message']));
+ break;
+ case 6:
+ dialog.show_error(__("XML validation failed: %s").
+ replace("%s", rc['message']));
+ break;
+ case 0:
+ dialog.show_error(__("You are already subscribed to this feed."));
+ break;
+ }
+
+ } catch (e) {
+ console.error(transport.responseText);
+ exception_error(e);
+ }
});
}
},
console.log('reading init-params...');
for (const k in params) {
+ switch (k) {
+ case "label_base_index":
+ _label_base_index = parseInt(params[k])
+ break;
+ case "hotkeys":
+ // filter mnemonic definitions (used for help panel) from hotkeys map
+ // i.e. *(191)|Ctrl-/ -> *(191)
+
+ const tmp = [];
+ for (const sequence in params[k][1]) {
+ const filtered = sequence.replace(/\|.*$/, "");
+ tmp[filtered] = params[k][1][sequence];
+ }
+
+ params[k][1] = tmp;
+ break;
+ }
+
console.log("IP:", k, "=>", params[k]);
- if (k == "label_base_index") _label_base_index = parseInt(params[k]);
}
init_params = params;
}
function genUrlChangeKey(feed, is_cat) {
- const ok = confirm(__("Generate new syndication address for this feed?"));
-
- if (ok) {
+ if (confirm(__("Generate new syndication address for this feed?"))) {
notify_progress("Trying to change address...", true);
removeSelected: function() {
const sel_rows = this.getSelectedFeeds();
- console.log(sel_rows);
-
if (sel_rows.length > 0) {
- const ok = confirm(__("Remove selected feeds?"));
-
- if (ok) {
+ if (confirm(__("Remove selected feeds?"))) {
notify_progress("Removing selected feeds...", true);
const query = { op: "pref-feeds", method: "remove",
ids: sel_rows.toString() };
xhrPost("backend.php", query, () => {
- notify('');
- dialog.hide();
- updateFeedList();
- });
+ notify('');
+ dialog.hide();
+ updateFeedList();
+ });
}
} else {
dialog.show();
}
-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: '"'
- let optTemp = 0,
- i = 0,
- noquotes = false;
- if (typeof quote_style === 'undefined') {
- quote_style = 2;
- }
- string = string.toString().replace(/</g, '<').replace(/>/g, '>');
- const 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);
}
w.opener = null;
w.location = "backend.php?op=article&method=view&mode=raw&html=1&zoom=1&id=" + id + "&csrf_token=" + getInitParam("csrf_token");
}
+
+function keyevent_to_action(e) {
+
+ const hotkeys_map = getInitParam("hotkeys");
+ const keycode = e.which;
+ const keychar = String.fromCharCode(keycode).toLowerCase();
+
+ if (keycode == 27) { // escape and drop prefix
+ hotkey_prefix = false;
+ }
+
+ if (keycode == 16 || keycode == 17) return; // ignore lone shift / ctrl
+
+ if (!hotkey_prefix && hotkeys_map[0].indexOf(keychar) != -1) {
+
+ const date = new Date();
+ const ts = Math.round(date.getTime() / 1000);
+
+ hotkey_prefix = keychar;
+ hotkey_prefix_pressed = ts;
+
+ $("cmdline").innerHTML = keychar;
+ Element.show("cmdline");
+
+ e.stopPropagation();
+
+ return false;
+ }
+
+ Element.hide("cmdline");
+
+ let hotkey_name = keychar.search(/[a-zA-Z0-9]/) != -1 ? keychar : "(" + keycode + ")";
+
+ // ensure ^*char notation
+ if (e.shiftKey) hotkey_name = "*" + hotkey_name;
+ if (e.ctrlKey) hotkey_name = "^" + hotkey_name;
+ if (e.altKey) hotkey_name = "+" + hotkey_name;
+ if (e.metaKey) hotkey_name = "%" + hotkey_name;
+
+ const hotkey_full = hotkey_prefix ? hotkey_prefix + " " + hotkey_name : hotkey_name;
+ hotkey_prefix = false;
+
+ let action_name = false;
+
+ for (const sequence in hotkeys_map[1]) {
+ if (sequence == hotkey_full) {
+ action_name = hotkeys_map[1][sequence];
+ break;
+ }
+ }
+
+ console.log('keyevent_to_action', hotkey_full, '=>', action_name);
+
+ return action_name;
+}
\ No newline at end of file