]> git.wh0rd.org - tt-rss.git/commitdiff
simplify error handling
authorAndrew Dolgov <noreply@fakecake.org>
Sat, 4 Mar 2017 11:34:44 +0000 (14:34 +0300)
committerAndrew Dolgov <noreply@fakecake.org>
Sat, 4 Mar 2017 11:34:44 +0000 (14:34 +0300)
* less convoluted exception dialogs
* use window.onerror for the majority of exception catching/reporting
* remove most of now useless try/catch blocks
* report stacktrace instead of manually specified error locations

classes/pref/prefs.php
include/functions.php
include/functions2.php
js/FeedTree.js
js/deprecated.js
js/feedlist.js
js/functions.js
js/prefs.js
js/tt-rss.js
js/viewfeed.js

index ece9e8078cf9467fab3fc8bc7d991cc3b4315a94..5ec7079dc8a405b4cd67816b5096f6a7d15bd434 100644 (file)
@@ -686,16 +686,6 @@ class Pref_Prefs extends Handler_Protected {
 
                print "&nbsp;";
 
-               /* $checked = $_SESSION["prefs_show_advanced"] ? "checked='1'" : "";
-
-               print "<input onclick='toggleAdvancedPrefs()'
-                               id='prefs_show_advanced'
-                               dojoType=\"dijit.form.CheckBox\"
-                               $checked
-                               type=\"checkbox\"></input>
-                               <label for='prefs_show_advanced'>" .
-                               __("Show additional preferences") . "</label>"; */
-
                PluginHost::getInstance()->run_hooks(PluginHost::HOOK_PREFS_TAB_SECTION,
                        "hook_prefs_tab_section", "prefPrefsPrefsOutside");
 
index cdd783cdc826b08defa7ac48fe6406bb36b31e42..c6de853d41df01263fd85783322579e35b2fb55d 100644 (file)
                $attributes, $include_all_cats = true, $root_id = false, $nest_level = 0) {
 
                        if (!$root_id) {
-                                       print "<select id=\"$id\" name=\"$id\" default=\"$default_id\" onchange=\"catSelectOnChange(this)\" $attributes>";
+                                       print "<select id=\"$id\" name=\"$id\" default=\"$default_id\" $attributes>";
                        }
 
                        if ($root_id)
index f3570e56bb1d463621cc2ea6d0e104a8d6bd8fae..d68d1ecc3b2589d4ebfecae7274807e85d5e8728 100644 (file)
                        WHERE owner_uid = '".$_SESSION["uid"]."' ORDER BY caption");
 
                print "<select default=\"$value\" name=\"" . htmlspecialchars($name) .
-                       "\" $attributes onchange=\"labelSelectOnChange(this)\" >";
+                       "\" $attributes>";
 
                while ($line = db_fetch_assoc($result)) {
 
index 336f2b5f04ba12b9acf80c3db7bd0ef12d0cfdc0..e93882304e823e89cd7172abbec816fee1193c4e 100644 (file)
@@ -302,7 +302,7 @@ require(["dojo/_base/declare", "dojo/dom-construct", "dijit/Tree", "dijit/Menu"]
                                        }
                                }
                        } catch (e) {
-                               exception_error("expandParentNodes", e);
+                               exception_error(e);
                        }
                },
                findNodeParentsAndExpandThem: function(feed, is_cat, root, parents) {
@@ -341,7 +341,7 @@ require(["dojo/_base/declare", "dojo/dom-construct", "dijit/Tree", "dijit/Menu"]
                                        }
                                }
                        } catch (e) {
-                               exception_error("findNodeParentsAndExpandThem", e);
+                               exception_error(e);
                        }
                },
                selectFeed: function(feed, is_cat) {
index 1d04a1adc4e532434a234a0b5b40e0f4c98e0f66..dd286aa7f86f9f3e067e84efe9c4368e49e2b54e 100644 (file)
@@ -8,22 +8,16 @@ function selectTableRow(r, do_select) {
 }
 
 function selectTableRowById(elem_id, check_id, do_select) {
+       var row = $(elem_id);
 
-       try {
-
-               var row = $(elem_id);
-
-               if (row) {
-                       selectTableRow(row, do_select);
-               }               
+       if (row) {
+               selectTableRow(row, do_select);
+       }
 
-               var check = $(check_id);
+       var check = $(check_id);
 
-               if (check) {
-                       check.checked = do_select;
-               }
-       } catch (e) {
-               exception_error("selectTableRowById", e);
+       if (check) {
+               check.checked = do_select;
        }
 }
 
index 6d37377a45b327868bf4f4b1f838408d5927e400..941fe9e8bfae4bbba5342ed131796bac5da7265f 100644 (file)
@@ -8,253 +8,226 @@ var _viewfeed_timeout = false;
 var counters_last_request = 0;
 var _counters_prev = [];
 
-/*function viewCategory(cat) {
-       viewfeed({feed: cat, is_cat: true});
-       return false;
-}*/
-
 function resetCounterCache() {
        _counters_prev = [];
 }
 
 function loadMoreHeadlines() {
-       try {
-               console.log("loadMoreHeadlines");
-
-               var offset = 0;
-
-               var view_mode = document.forms["main_toolbar_form"].view_mode.value;
-               var unread_in_buffer = $$("#headlines-frame > div[id*=RROW][class*=Unread]").length;
-               var num_all = $$("#headlines-frame > div[id*=RROW]").length;
-               var num_unread = getFeedUnread(getActiveFeedId(), activeFeedIsCat());
-
-               // TODO implement marked & published
-
-               if (view_mode == "marked") {
-                       console.warn("loadMoreHeadlines: marked is not implemented, falling back.");
-                       offset = num_all;
-               } else if (view_mode == "published") {
-                       console.warn("loadMoreHeadlines: published is not implemented, falling back.");
-                       offset = num_all;
-               } else if (view_mode == "unread") {
-                       offset = unread_in_buffer;
-               } else if (_search_query) {
-                       offset = num_all;
-               } else if (view_mode == "adaptive" && !(getActiveFeedId() == -1 && !activeFeedIsCat())) {
-                       // ^ starred feed shows both unread & read articles in adaptive mode
-                       offset = num_unread > 0 ? unread_in_buffer : num_all;
-               } else {
-                       offset = num_all;
-               }
+       console.log("loadMoreHeadlines");
+
+       var offset = 0;
+
+       var view_mode = document.forms["main_toolbar_form"].view_mode.value;
+       var unread_in_buffer = $$("#headlines-frame > div[id*=RROW][class*=Unread]").length;
+       var num_all = $$("#headlines-frame > div[id*=RROW]").length;
+       var num_unread = getFeedUnread(getActiveFeedId(), activeFeedIsCat());
+
+       // TODO implement marked & published
+
+       if (view_mode == "marked") {
+               console.warn("loadMoreHeadlines: marked is not implemented, falling back.");
+               offset = num_all;
+       } else if (view_mode == "published") {
+               console.warn("loadMoreHeadlines: published is not implemented, falling back.");
+               offset = num_all;
+       } else if (view_mode == "unread") {
+               offset = unread_in_buffer;
+       } else if (_search_query) {
+               offset = num_all;
+       } else if (view_mode == "adaptive" && !(getActiveFeedId() == -1 && !activeFeedIsCat())) {
+               // ^ starred feed shows both unread & read articles in adaptive mode
+               offset = num_unread > 0 ? unread_in_buffer : num_all;
+       } else {
+               offset = num_all;
+       }
 
-               console.log("offset: " + offset);
+       console.log("offset: " + offset);
 
-               viewfeed({feed: getActiveFeedId(), is_cat: activeFeedIsCat(), offset: offset, infscroll_req: true});
+       viewfeed({feed: getActiveFeedId(), is_cat: activeFeedIsCat(), offset: offset, infscroll_req: true});
 
-       } catch (e) {
-               exception_error("viewNextFeedPage", e);
-       }
 }
 
 function cleanup_memory(root) {
-       try {
-               var dijits = dojo.query("[widgetid]", dijit.byId(root).domNode).map(dijit.byNode);
+       var dijits = dojo.query("[widgetid]", dijit.byId(root).domNode).map(dijit.byNode);
 
-               dijits.each(function (d) {
-                       dojo.destroy(d.domNode);
-               });
+       dijits.each(function (d) {
+               dojo.destroy(d.domNode);
+       });
 
-               $$("#" + root + " *").each(function (i) {
-                       i.parentNode ? i.parentNode.removeChild(i) : true;
-               });
-       } catch (e) {
-               console.log("cleanup_memory: exception");
-               console.log(e);
-       }
+       $$("#" + root + " *").each(function (i) {
+               i.parentNode ? i.parentNode.removeChild(i) : true;
+       });
 }
 
 function viewfeed(params) {
-       try {
-               var feed = params.feed;
-               var is_cat = params.is_cat;
-               var offset = params.offset;
-               var background = params.background;
-               var infscroll_req = params.infscroll_req;
-               var can_wait = params.can_wait;
-               var viewfeed_debug = params.viewfeed_debug;
-               var method = params.method;
-
-               if (is_cat == undefined)
-                       is_cat = false;
-               else
-                       is_cat = !!is_cat;
-
-               if (offset == undefined) offset = 0;
-               if (background == undefined) background = false;
-               if (infscroll_req == undefined) infscroll_req = false;
-
-               last_requested_article = 0;
-
-               if (feed != getActiveFeedId() || activeFeedIsCat() != is_cat) {
-                       if (!background && _search_query) _search_query = false;
-               }
-
-               if (!background) {
-                       _viewfeed_last = get_timestamp();
+       var feed = params.feed;
+       var is_cat = params.is_cat;
+       var offset = params.offset;
+       var background = params.background;
+       var infscroll_req = params.infscroll_req;
+       var can_wait = params.can_wait;
+       var viewfeed_debug = params.viewfeed_debug;
+       var method = params.method;
+
+       if (is_cat == undefined)
+               is_cat = false;
+       else
+               is_cat = !!is_cat;
+
+       if (offset == undefined) offset = 0;
+       if (background == undefined) background = false;
+       if (infscroll_req == undefined) infscroll_req = false;
+
+       last_requested_article = 0;
+
+       if (feed != getActiveFeedId() || activeFeedIsCat() != is_cat) {
+               if (!background && _search_query) _search_query = false;
+       }
 
-                       if (getActiveFeedId() != feed || !infscroll_req) {
-                               setActiveArticleId(0);
-                               _infscroll_disable = 0;
+       if (!background) {
+               _viewfeed_last = get_timestamp();
 
-                               cleanup_memory("headlines-frame");
-                               _headlines_scroll_offset = 0;
-                       }
+               if (getActiveFeedId() != feed || !infscroll_req) {
+                       setActiveArticleId(0);
+                       _infscroll_disable = 0;
 
-                       if (infscroll_req) {
-                               var timestamp = get_timestamp();
+                       cleanup_memory("headlines-frame");
+                       _headlines_scroll_offset = 0;
+               }
 
-                               if (_infscroll_request_sent && _infscroll_request_sent + 30 > timestamp) {
-                                       //console.log("infscroll request in progress, aborting");
-                                       return;
-                               }
+               if (infscroll_req) {
+                       var timestamp = get_timestamp();
 
-                               _infscroll_request_sent = timestamp;
+                       if (_infscroll_request_sent && _infscroll_request_sent + 30 > timestamp) {
+                               //console.log("infscroll request in progress, aborting");
+                               return;
                        }
+
+                       _infscroll_request_sent = timestamp;
                }
+       }
 
-               Form.enable("main_toolbar_form");
+       Form.enable("main_toolbar_form");
 
-               var toolbar_query = Form.serialize("main_toolbar_form");
+       var toolbar_query = Form.serialize("main_toolbar_form");
 
-               var query = "?op=feeds&method=view&feed=" + param_escape(feed) + "&" +
-                       toolbar_query;
+       var query = "?op=feeds&method=view&feed=" + param_escape(feed) + "&" +
+               toolbar_query;
 
-               if (method) query += "&m=" + param_escape(method);
+       if (method) query += "&m=" + param_escape(method);
 
-               if (offset > 0) {
-                       if (current_first_id) {
-                               query = query + "&fid=" + param_escape(current_first_id);
-                       }
+       if (offset > 0) {
+               if (current_first_id) {
+                       query = query + "&fid=" + param_escape(current_first_id);
                }
+       }
 
-               if (!background) {
-                       if (_search_query) {
-                               force_nocache = true;
-                               query = query + "&" + _search_query;
-                               //_search_query = false;
-                       }
+       if (!background) {
+               if (_search_query) {
+                       force_nocache = true;
+                       query = query + "&" + _search_query;
+                       //_search_query = false;
+               }
 
-                       if (offset != 0) {
-                               query = query + "&skip=" + offset;
+               if (offset != 0) {
+                       query = query + "&skip=" + offset;
 
-                               // to prevent duplicate feed titles when showing grouped vfeeds
-                               if (vgroup_last_feed) {
-                                       query = query + "&vgrlf=" + param_escape(vgroup_last_feed);
-                               }
-                       } else {
-                               if (!is_cat && feed == getActiveFeedId() && !params.method) {
-                                       query = query + "&m=ForceUpdate";
-                               }
+                       // to prevent duplicate feed titles when showing grouped vfeeds
+                       if (vgroup_last_feed) {
+                               query = query + "&vgrlf=" + param_escape(vgroup_last_feed);
                        }
+               } else {
+                       if (!is_cat && feed == getActiveFeedId() && !params.method) {
+                               query = query + "&m=ForceUpdate";
+                       }
+               }
 
-                       Form.enable("main_toolbar_form");
+               Form.enable("main_toolbar_form");
 
-                       if (!setFeedExpandoIcon(feed, is_cat,
-                               (is_cat) ? 'images/indicator_tiny.gif' : 'images/indicator_white.gif'))
-                                       notify_progress("Loading, please wait...", true);
-               }
+               if (!setFeedExpandoIcon(feed, is_cat,
+                       (is_cat) ? 'images/indicator_tiny.gif' : 'images/indicator_white.gif'))
+                               notify_progress("Loading, please wait...", true);
+       }
 
-               query += "&cat=" + is_cat;
+       query += "&cat=" + is_cat;
 
-               console.log(query);
+       console.log(query);
 
-               if (can_wait && _viewfeed_timeout) {
-                       setFeedExpandoIcon(getActiveFeedId(), activeFeedIsCat(), 'images/blank_icon.gif');
-                       clearTimeout(_viewfeed_timeout);
-               }
+       if (can_wait && _viewfeed_timeout) {
+               setFeedExpandoIcon(getActiveFeedId(), activeFeedIsCat(), 'images/blank_icon.gif');
+               clearTimeout(_viewfeed_timeout);
+       }
 
-               setActiveFeedId(feed, is_cat);
+       setActiveFeedId(feed, is_cat);
 
-               if (viewfeed_debug) {
-                       window.open("backend.php" + query + "&debug=1&csrf_token=" + getInitParam("csrf_token"));
-               }
+       if (viewfeed_debug) {
+               window.open("backend.php" + query + "&debug=1&csrf_token=" + getInitParam("csrf_token"));
+       }
 
-               timeout_ms = can_wait ? 250 : 0;
-               _viewfeed_timeout = setTimeout(function() {
+       timeout_ms = can_wait ? 250 : 0;
+       _viewfeed_timeout = setTimeout(function() {
 
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
+               new Ajax.Request("backend.php", {
+                       parameters: query,
+                       onComplete: function(transport) {
+                               try {
                                        setFeedExpandoIcon(feed, is_cat, 'images/blank_icon.gif');
                                        headlines_callback2(transport, offset, background, infscroll_req);
                                        PluginHost.run(PluginHost.HOOK_FEED_LOADED, [feed, is_cat]);
-                               } });
-               }, timeout_ms); // Wait 250ms
+                               } catch (e) {
+                                       exception_error(e);
+                               }
+                       } });
+       }, timeout_ms); // Wait 250ms
 
-       } catch (e) {
-               exception_error("viewfeed", e);
-       }
 }
 
 function feedlist_init() {
-       try {
-               console.log("in feedlist init");
+       console.log("in feedlist init");
 
-               loading_set_progress(50);
+       loading_set_progress(50);
 
-               document.onkeydown = hotkey_handler;
-               setTimeout(hotkey_prefix_timeout, 5*1000);
+       document.onkeydown = hotkey_handler;
+       setTimeout(hotkey_prefix_timeout, 5*1000);
 
-               if (!getActiveFeedId()) {
-                       viewfeed({feed: -3});
-               } else {
-                       viewfeed({feed: getActiveFeedId(), is_cat: activeFeedIsCat()});
-               }
+       if (!getActiveFeedId()) {
+               viewfeed({feed: -3});
+       } else {
+               viewfeed({feed: getActiveFeedId(), is_cat: activeFeedIsCat()});
+       }
 
-               hideOrShowFeeds(getInitParam("hide_read_feeds") == 1);
+       hideOrShowFeeds(getInitParam("hide_read_feeds") == 1);
 
-               request_counters(true);
-               timeout();
+       request_counters(true);
+       timeout();
 
-       } catch (e) {
-               exception_error("feedlist/init", e);
-       }
 }
 
 
 function request_counters(force) {
-       try {
-               var date = new Date();
-               var timestamp = Math.round(date.getTime() / 1000);
-
-               if (force || timestamp - counters_last_request > 5) {
-                       console.log("scheduling request of counters...");
+       var date = new Date();
+       var timestamp = Math.round(date.getTime() / 1000);
 
-                       counters_last_request = timestamp;
+       if (force || timestamp - counters_last_request > 5) {
+               console.log("scheduling request of counters...");
 
-                       var query = "?op=rpc&method=getAllCounters&seq=" + next_seq();
+               counters_last_request = timestamp;
 
-                       if (!force)
-                               query = query + "&last_article_id=" + getInitParam("last_article_id");
+               var query = "?op=rpc&method=getAllCounters&seq=" + next_seq();
 
-                       console.log(query);
+               if (!force)
+                       query = query + "&last_article_id=" + getInitParam("last_article_id");
 
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
-                                       try {
-                                               handle_rpc_json(transport);
-                                       } catch (e) {
-                                               exception_error("request_counters", e);
-                                       }
-                               } });
+               console.log(query);
 
-               } else {
-                       console.log("request_counters: rate limit reached: " + (timestamp - counters_last_request));
-               }
+               new Ajax.Request("backend.php", {
+                       parameters: query,
+                       onComplete: function(transport) {
+                               handle_rpc_json(transport);
+                       } });
 
-       } catch (e) {
-               exception_error("request_counters", e);
+       } else {
+               console.log("request_counters: rate limit reached: " + (timestamp - counters_last_request));
        }
 }
 
@@ -289,61 +262,56 @@ function counter_is_equal(a, b) {
 
 
 function parse_counters(elems) {
-       try {
-               for (var l = 0; l < elems.length; l++) {
+       for (var l = 0; l < elems.length; l++) {
 
-                       if (_counters_prev[l] && counter_is_equal(elems[l], _counters_prev[l])) {
-                               continue;
-                       }
+               if (_counters_prev[l] && counter_is_equal(elems[l], _counters_prev[l])) {
+                       continue;
+               }
 
-                       var id = elems[l].id;
-                       var kind = elems[l].kind;
-                       var ctr = parseInt(elems[l].counter);
-                       var error = elems[l].error;
-                       var has_img = elems[l].has_img;
-                       var updated = elems[l].updated;
-                       var auxctr = parseInt(elems[l].auxcounter);
-
-                       if (id == "global-unread") {
-                               global_unread = ctr;
-                               updateTitle();
-                               continue;
-                       }
+               var id = elems[l].id;
+               var kind = elems[l].kind;
+               var ctr = parseInt(elems[l].counter);
+               var error = elems[l].error;
+               var has_img = elems[l].has_img;
+               var updated = elems[l].updated;
+               var auxctr = parseInt(elems[l].auxcounter);
 
-                       if (id == "subscribed-feeds") {
-                               /* feeds_found = ctr; */
-                               continue;
-                       }
+               if (id == "global-unread") {
+                       global_unread = ctr;
+                       updateTitle();
+                       continue;
+               }
 
-                       /*if (getFeedUnread(id, (kind == "cat")) != ctr ||
-                                       (kind == "cat")) {
-                       }*/
+               if (id == "subscribed-feeds") {
+                       /* feeds_found = ctr; */
+                       continue;
+               }
 
-                       setFeedUnread(id, (kind == "cat"), ctr);
-                       setFeedValue(id, (kind == "cat"), 'auxcounter', auxctr);
+               /*if (getFeedUnread(id, (kind == "cat")) != ctr ||
+                               (kind == "cat")) {
+               }*/
 
-                       if (kind != "cat") {
-                               setFeedValue(id, false, 'error', error);
-                               setFeedValue(id, false, 'updated', updated);
+               setFeedUnread(id, (kind == "cat"), ctr);
+               setFeedValue(id, (kind == "cat"), 'auxcounter', auxctr);
 
-                               if (id > 0) {
-                                       if (has_img) {
-                                               setFeedIcon(id, false,
-                                                       getInitParam("icons_url") + "/" + id + ".ico");
-                                       } else {
-                                               setFeedIcon(id, false, 'images/blank_icon.gif');
-                                       }
+               if (kind != "cat") {
+                       setFeedValue(id, false, 'error', error);
+                       setFeedValue(id, false, 'updated', updated);
+
+                       if (id > 0) {
+                               if (has_img) {
+                                       setFeedIcon(id, false,
+                                               getInitParam("icons_url") + "/" + id + ".ico");
+                               } else {
+                                       setFeedIcon(id, false, 'images/blank_icon.gif');
                                }
                        }
                }
+       }
 
-               hideOrShowFeeds(getInitParam("hide_read_feeds") == 1);
-
-               _counters_prev = elems;
+       hideOrShowFeeds(getInitParam("hide_read_feeds") == 1);
 
-       } catch (e) {
-               exception_error("parse_counters", e);
-       }
+       _counters_prev = elems;
 }
 
 function getFeedUnread(feed, is_cat) {
@@ -405,15 +373,10 @@ function getFeedValue(feed, is_cat, key) {
 }
 
 function setFeedUnread(feed, is_cat, unread) {
-       try {
-               var tree = dijit.byId("feedTree");
-
-               if (tree && tree.model)
-                       return tree.model.setFeedUnread(feed, is_cat, unread);
+       var tree = dijit.byId("feedTree");
 
-       } catch (e) {
-               exception_error("setFeedUnread", e);
-       }
+       if (tree && tree.model)
+               return tree.model.setFeedUnread(feed, is_cat, unread);
 }
 
 function setFeedValue(feed, is_cat, key, value) {
@@ -429,50 +392,31 @@ function setFeedValue(feed, is_cat, key, value) {
 }
 
 function selectFeed(feed, is_cat) {
-       try {
-               var tree = dijit.byId("feedTree");
-
-               if (tree) return tree.selectFeed(feed, is_cat);
+       var tree = dijit.byId("feedTree");
 
-       } catch (e) {
-               exception_error("selectFeed", e);
-       }
+       if (tree) return tree.selectFeed(feed, is_cat);
 }
 
 function setFeedIcon(feed, is_cat, src) {
-       try {
-               var tree = dijit.byId("feedTree");
-
-               if (tree) return tree.setFeedIcon(feed, is_cat, src);
+       var tree = dijit.byId("feedTree");
 
-       } catch (e) {
-               exception_error("setFeedIcon", e);
-       }
+       if (tree) return tree.setFeedIcon(feed, is_cat, src);
 }
 
 function setFeedExpandoIcon(feed, is_cat, src) {
-       try {
-               var tree = dijit.byId("feedTree");
+       var tree = dijit.byId("feedTree");
 
-               if (tree) return tree.setFeedExpandoIcon(feed, is_cat, src);
+       if (tree) return tree.setFeedExpandoIcon(feed, is_cat, src);
 
-       } catch (e) {
-               exception_error("setFeedIcon", e);
-       }
        return false;
 }
 
 function getNextUnreadFeed(feed, is_cat) {
-       try {
-               var tree = dijit.byId("feedTree");
-               var nuf = tree.model.getNextUnreadFeed(feed, is_cat);
-
-               if (nuf)
-                       return tree.model.store.getValue(nuf, 'bare_id');
+       var tree = dijit.byId("feedTree");
+       var nuf = tree.model.getNextUnreadFeed(feed, is_cat);
 
-       } catch (e) {
-               exception_error("getNextUnreadFeed", e);
-       }
+       if (nuf)
+               return tree.model.store.getValue(nuf, 'bare_id');
 }
 
 function catchupCurrentFeed(mode) {
@@ -480,152 +424,138 @@ function catchupCurrentFeed(mode) {
 }
 
 function catchupFeedInGroup(id) {
-       try {
-
-               var title = getFeedName(id);
+       var title = getFeedName(id);
 
-               var str = __("Mark all articles in %s as read?").replace("%s", title);
+       var str = __("Mark all articles in %s as read?").replace("%s", title);
 
-               if (getInitParam("confirm_feed_catchup") != 1 || confirm(str)) {
+       if (getInitParam("confirm_feed_catchup") != 1 || confirm(str)) {
 
-                       var rows = $$("#headlines-frame > div[id*=RROW][data-orig-feed-id='"+id+"']");
+               var rows = $$("#headlines-frame > div[id*=RROW][data-orig-feed-id='"+id+"']");
 
-                       if (rows.length > 0) {
+               if (rows.length > 0) {
 
-                               rows.each(function (row) {
-                                       row.removeClassName("Unread");
+                       rows.each(function (row) {
+                               row.removeClassName("Unread");
 
-                                       if (row.getAttribute("data-article-id") != getActiveArticleId()) {
-                                               new Effect.Fade(row, {duration: 0.5});
-                                       }
-
-                               });
+                               if (row.getAttribute("data-article-id") != getActiveArticleId()) {
+                                       new Effect.Fade(row, {duration: 0.5});
+                               }
 
-                               var feedTitles = $$("#headlines-frame > div[class='cdmFeedTitle']");
+                       });
 
-                               for (var i = 0; i < feedTitles.length; i++) {
-                                       if (feedTitles[i].getAttribute("data-feed-id") == id) {
+                       var feedTitles = $$("#headlines-frame > div[class='cdmFeedTitle']");
 
-                                               if (i < feedTitles.length - 1) {
-                                                       new Effect.Fade(feedTitles[i], {duration: 0.5});
-                                               }
+                       for (var i = 0; i < feedTitles.length; i++) {
+                               if (feedTitles[i].getAttribute("data-feed-id") == id) {
 
-                                               break;
+                                       if (i < feedTitles.length - 1) {
+                                               new Effect.Fade(feedTitles[i], {duration: 0.5});
                                        }
-                               }
 
-                               updateFloatingTitle(true);
+                                       break;
+                               }
                        }
 
-                       var catchup_query = "?op=rpc&method=catchupFeed&feed_id=" +
-                                       id + "&is_cat=false";
+                       updateFloatingTitle(true);
+               }
 
-                       console.log(catchup_query);
+               var catchup_query = "?op=rpc&method=catchupFeed&feed_id=" +
+                               id + "&is_cat=false";
 
-                       notify_progress("Loading, please wait...", true);
+               console.log(catchup_query);
 
-                       new Ajax.Request("backend.php", {
-                               parameters: catchup_query,
-                               onComplete: function (transport) {
-                                       handle_rpc_json(transport);
-                               }
-                       } );
+               notify_progress("Loading, please wait...", true);
 
-                       //return viewCurrentFeed('MarkAllReadGR:' + id);
-               }
+               new Ajax.Request("backend.php", {
+                       parameters: catchup_query,
+                       onComplete: function (transport) {
+                               handle_rpc_json(transport);
+                       }
+               } );
 
-       } catch (e) {
-               exception_error("catchupFeedInGroup", e);
+               //return viewCurrentFeed('MarkAllReadGR:' + id);
        }
 }
 
 function catchupFeed(feed, is_cat, mode) {
-       try {
-               if (is_cat == undefined) is_cat = false;
-
-               var str = false;
-
-               switch (mode) {
-               case "1day":
-                       str = __("Mark all articles in %s older than 1 day as read?");
-                       break;
-               case "1week":
-                       str = __("Mark all articles in %s older than 1 week as read?");
-                       break;
-               case "2week":
-                       str = __("Mark all articles in %s older than 2 weeks as read?");
-                       break;
-               default:
-                       str = __("Mark all articles in %s as read?");
-               }
+       if (is_cat == undefined) is_cat = false;
+
+       var str = false;
+
+       switch (mode) {
+       case "1day":
+               str = __("Mark all articles in %s older than 1 day as read?");
+               break;
+       case "1week":
+               str = __("Mark all articles in %s older than 1 week as read?");
+               break;
+       case "2week":
+               str = __("Mark all articles in %s older than 2 weeks as read?");
+               break;
+       default:
+               str = __("Mark all articles in %s as read?");
+       }
 
-               var fn = getFeedName(feed, is_cat);
+       var fn = getFeedName(feed, is_cat);
 
-               str = str.replace("%s", fn);
+       str = str.replace("%s", fn);
 
-               if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
-                       return;
-               }
+       if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
+               return;
+       }
 
-               var catchup_query = "?op=rpc&method=catchupFeed&feed_id=" +
-                       feed + "&is_cat=" + is_cat + "&mode=" + mode;
+       var catchup_query = "?op=rpc&method=catchupFeed&feed_id=" +
+               feed + "&is_cat=" + is_cat + "&mode=" + mode;
 
-               console.log(catchup_query);
+       console.log(catchup_query);
 
-               notify_progress("Loading, please wait...", true);
+       notify_progress("Loading, please wait...", true);
 
-               new Ajax.Request("backend.php", {
-                       parameters: catchup_query,
-                       onComplete: function(transport) {
-                                       handle_rpc_json(transport);
+       new Ajax.Request("backend.php", {
+               parameters: catchup_query,
+               onComplete: function(transport) {
+                               handle_rpc_json(transport);
 
-                                       var show_next_feed = getInitParam("on_catchup_show_next_feed") == "1";
+                               var show_next_feed = getInitParam("on_catchup_show_next_feed") == "1";
 
-                                       if (show_next_feed) {
-                                               var nuf = getNextUnreadFeed(feed, is_cat);
+                               if (show_next_feed) {
+                                       var nuf = getNextUnreadFeed(feed, is_cat);
 
-                                               if (nuf) {
-                                                       viewfeed({feed: nuf, is_cat: is_cat});
-                                               }
-                                       } else {
-                                               if (feed == getActiveFeedId() && is_cat == activeFeedIsCat()) {
-                                                       viewCurrentFeed();
-                                               }
+                                       if (nuf) {
+                                               viewfeed({feed: nuf, is_cat: is_cat});
                                        }
+                               } else {
+                                       if (feed == getActiveFeedId() && is_cat == activeFeedIsCat()) {
+                                               viewCurrentFeed();
+                                       }
+                               }
 
-                                       notify("");
-                               } });
+                               notify("");
+                       } });
 
-       } catch (e) {
-               exception_error("catchupFeed", e);
-       }
 }
 
 function decrementFeedCounter(feed, is_cat) {
-       try {
-               var ctr = getFeedUnread(feed, is_cat);
+       var ctr = getFeedUnread(feed, is_cat);
 
-               if (ctr > 0) {
-                       setFeedUnread(feed, is_cat, ctr - 1);
-                       global_unread = global_unread - 1;
-                       updateTitle();
+       if (ctr > 0) {
+               setFeedUnread(feed, is_cat, ctr - 1);
+               global_unread = global_unread - 1;
+               updateTitle();
 
-                       if (!is_cat) {
-                               var cat = parseInt(getFeedCategory(feed));
+               if (!is_cat) {
+                       var cat = parseInt(getFeedCategory(feed));
 
-                               if (!isNaN(cat)) {
-                                       ctr = getFeedUnread(cat, true);
+                       if (!isNaN(cat)) {
+                               ctr = getFeedUnread(cat, true);
 
-                                       if (ctr > 0) {
-                                               setFeedUnread(cat, true, ctr - 1);
-                                       }
+                               if (ctr > 0) {
+                                       setFeedUnread(cat, true, ctr - 1);
                                }
                        }
                }
-
-       } catch (e) {
-               exception_error("decrement_feed_counter", e);
        }
+
 }
 
 
index 88d8e331edfd25f8437c70e9b7961b75ccb414d5..134ce0b18f51ae2764e34d2c76e756de120d3011 100755 (executable)
@@ -30,23 +30,18 @@ Array.prototype.remove = function(s) {
        }
 };
 
-/* create console.log if it doesn't exist */
 
-if (!window.console) console = {};
-console.log = console.log || function(msg) { };
-console.warn = console.warn || function(msg) { };
-console.error = console.error || function(msg) { };
+function report_error(message, filename, lineno, colno, error) {
+       exception_error(error);
+}
 
-function exception_error(location, e, ext_info) {
-       var msg = format_exception_error(location, e);
+function exception_error(e, e_compat) {
+       if (typeof e == "string") e = e_compat;
 
-       if (!ext_info) ext_info = false;
+       if (!e) return; // no exception object, nothing to report.
 
        try {
 
-               if (ext_info)
-                       ext_info = JSON.stringify(ext_info);
-
                try {
                        new Ajax.Request("backend.php", {
                                parameters: {op: "rpc", method: "log", logmsg: msg},
@@ -54,14 +49,17 @@ function exception_error(location, e, ext_info) {
                                        console.log(transport.responseText);
                                } });
 
-               } catch (eii) {
-                       console.log("Exception while trying to log the error.");
-                       console.log(eii);
+               } catch (e) {
+                       console.error("Exception while trying to log the error.", e);
                }
 
+               var msg = e.toString();
+
                msg += "<p>"+ __("The error will be reported to the configured log destination.") +
                        "</p>";
 
+               console.error(msg);
+
                var content = "<div class=\"fatalError\">" +
                        "<pre>" + msg + "</pre>";
 
@@ -71,14 +69,11 @@ function exception_error(location, e, ext_info) {
                content += "<textarea style=\"display : none\" name=\"message\">" + msg + "</textarea>";
                content += "<textarea style=\"display : none\" name=\"params\">N/A</textarea>";
 
-               if (ext_info) {
-                       content += "<div><b>Additional information:</b></div>" +
-                       "<textarea name=\"xinfo\" readonly=\"1\">" + ext_info + "</textarea>";
+               if (e) {
+                       content += "<div><b>Stack trace:</b></div>" +
+                               "<textarea name=\"stack\" readonly=\"1\">" + e.stack + "</textarea>";
                }
 
-               content += "<div><b>Stack trace:</b></div>" +
-                       "<textarea name=\"stack\" readonly=\"1\">" + e.stack + "</textarea>";
-
                content += "</form>";
 
                content += "</div>";
@@ -121,51 +116,13 @@ function exception_error(location, e, ext_info) {
                dialog.show();
 
        } 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);
-               }
+               console.error("Exception while trying to report an exception:", ei);
+               console.error("Original exception:", e);
 
-               msg += "\n\nThe error will be reported to the configured log destination.";
-
-               alert(msg);
-       }
-
-}
-
-function format_exception_error(location, e) {
-       var msg;
-
-       if (e.fileName) {
-               var base_fname = e.fileName.substring(e.fileName.lastIndexOf("/") + 1);
-
-               msg = "Exception: " + e.name + ", " + e.message +
-                       "\nFunction: " + location + "()" +
-                       "\nLocation: " + base_fname + ":" + e.lineNumber;
-
-       } else if (e.description) {
-               msg = "Exception: " + e.description + "\nFunction: " + location + "()";
-       } else {
-               msg = "Exception: " + e + "\nFunction: " + location + "()";
+               alert("Exception occured while trying to report an exception.\n" +
+                       ei.stack + "\n\nOriginal exception:\n" + e.stack);
        }
 
-       console.error("EXCEPTION: " + msg);
-
-       return msg;
 }
 
 function param_escape(arg) {
@@ -432,14 +389,10 @@ function getURLParam(param){
 }
 
 function closeInfoBox(cleanup) {
-       try {
-               dialog = dijit.byId("infoBox");
+       dialog = dijit.byId("infoBox");
 
-               if (dialog)     dialog.hide();
+       if (dialog)     dialog.hide();
 
-       } catch (e) {
-               //exception_error("closeInfoBox", e);
-       }
        return false;
 }
 
@@ -462,44 +415,40 @@ function displayDlg(title, id, param, callback) {
 }
 
 function infobox_callback2(transport, title) {
-       try {
-               var dialog = false;
+       var dialog = false;
 
-               if (dijit.byId("infoBox")) {
-                       dialog = dijit.byId("infoBox");
-               }
+       if (dijit.byId("infoBox")) {
+               dialog = dijit.byId("infoBox");
+       }
 
-               //console.log("infobox_callback2");
-               notify('');
+       //console.log("infobox_callback2");
+       notify('');
 
-               var content = transport.responseText;
+       var content = transport.responseText;
 
-               if (!dialog) {
-                       dialog = new dijit.Dialog({
-                               title: title,
-                               id: 'infoBox',
-                               style: "width: 600px",
-                               onCancel: function() {
-                                       return true;
-                               },
-                               onExecute: function() {
-                                       return true;
+       if (!dialog) {
+               dialog = new dijit.Dialog({
+                       title: title,
+                       id: 'infoBox',
+                       style: "width: 600px",
+                       onCancel: function() {
+                               return true;
+                       },
+                       onExecute: function() {
+                               return true;
+                       },
+                       onClose: function() {
+                               return true;
                                },
-                               onClose: function() {
-                                       return true;
-                                       },
-                               content: content});
-               } else {
-                       dialog.attr('title', title);
-                       dialog.attr('content', content);
-               }
+                       content: content});
+       } else {
+               dialog.attr('title', title);
+               dialog.attr('content', content);
+       }
 
-               dialog.show();
+       dialog.show();
 
-               notify("");
-       } catch (e) {
-               exception_error("infobox_callback2", e);
-       }
+       notify("");
 }
 
 function getInitParam(key) {
@@ -511,88 +460,75 @@ function setInitParam(key, value) {
 }
 
 function fatalError(code, msg, ext_info) {
-       try {
-
-               if (code == 6) {
-                       window.location.href = "index.php";
-               } else if (code == 5) {
-                       window.location.href = "public.php?op=dbupdate";
-               } else {
+       if (code == 6) {
+               window.location.href = "index.php";
+       } else if (code == 5) {
+               window.location.href = "public.php?op=dbupdate";
+       } else {
 
-                       if (msg == "") msg = "Unknown error";
+               if (msg == "") msg = "Unknown error";
 
-                       if (ext_info) {
-                               if (ext_info.responseText) {
-                                       ext_info = ext_info.responseText;
-                               }
+               if (ext_info) {
+                       if (ext_info.responseText) {
+                               ext_info = ext_info.responseText;
                        }
+               }
 
-                       if (ERRORS && ERRORS[code] && !msg) {
-                               msg = ERRORS[code];
-                       }
+               if (ERRORS && ERRORS[code] && !msg) {
+                       msg = ERRORS[code];
+               }
 
-                       var content = "<div><b>Error code:</b> " + code + "</div>" +
-                               "<p>" + msg + "</p>";
+               var content = "<div><b>Error code:</b> " + code + "</div>" +
+                       "<p>" + msg + "</p>";
 
-                       if (ext_info) {
-                               content = content + "<div><b>Additional information:</b></div>" +
-                                       "<textarea style='width: 100%' readonly=\"1\">" +
-                                       ext_info + "</textarea>";
-                       }
+               if (ext_info) {
+                       content = content + "<div><b>Additional information:</b></div>" +
+                               "<textarea style='width: 100%' readonly=\"1\">" +
+                               ext_info + "</textarea>";
+               }
 
-                       var dialog = new dijit.Dialog({
-                               title: "Fatal error",
-                               style: "width: 600px",
-                               content: content});
+               var dialog = new dijit.Dialog({
+                       title: "Fatal error",
+                       style: "width: 600px",
+                       content: content});
 
-                       dialog.show();
+               dialog.show();
 
-               }
+       }
 
-               return false;
+       return false;
 
-       } catch (e) {
-               exception_error("fatalError", e);
-       }
 }
 
 function filterDlgCheckAction(sender) {
+       var action = sender.value;
 
-       try {
-
-               var action = sender.value;
-
-               var action_param = $("filterDlg_paramBox");
+       var action_param = $("filterDlg_paramBox");
 
-               if (!action_param) {
-                       console.log("filterDlgCheckAction: can't find action param box!");
-                       return;
-               }
-
-               // 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);
                }
 
-       } catch (e) {
-               exception_error("filterDlgCheckAction", e);
+       } else {
+               Element.hide(action_param);
        }
-
 }
 
 
@@ -601,18 +537,14 @@ function explainError(code) {
 }
 
 function loading_set_progress(p) {
-       try {
-               loading_progress += p;
+       loading_progress += p;
 
-               if (dijit.byId("loading_bar"))
-                       dijit.byId("loading_bar").update({progress: loading_progress});
+       if (dijit.byId("loading_bar"))
+               dijit.byId("loading_bar").update({progress: loading_progress});
 
-               if (loading_progress >= 90)
-                       remove_splash();
+       if (loading_progress >= 90)
+               remove_splash();
 
-       } catch (e) {
-               exception_error("loading_set_progress", e);
-       }
 }
 
 function remove_splash() {
@@ -624,26 +556,6 @@ function remove_splash() {
        }
 }
 
-function transport_error_check(transport) {
-       try {
-               if (transport.responseXML) {
-                       var error = transport.responseXML.getElementsByTagName("error")[0];
-
-                       if (error) {
-                               var code = error.getAttribute("error-code");
-                               var msg = error.getAttribute("error-msg");
-                               if (code != 0) {
-                                       fatalError(code, msg);
-                                       return false;
-                               }
-                       }
-               }
-       } catch (e) {
-               exception_error("check_for_error_xml", e);
-       }
-       return true;
-}
-
 function strip_tags(s) {
        return s.replace(/<\/?[^>]+(>|$)/g, "");
 }
@@ -656,643 +568,589 @@ function truncate_string(s, length) {
 }
 
 function hotkey_prefix_timeout() {
-       try {
 
-               var date = new Date();
-               var ts = Math.round(date.getTime() / 1000);
+       var date = new Date();
+       var ts = Math.round(date.getTime() / 1000);
 
-               if (hotkey_prefix_pressed && ts - hotkey_prefix_pressed >= 5) {
-                       console.log("hotkey_prefix seems to be stuck, aborting");
-                       hotkey_prefix_pressed = false;
-                       hotkey_prefix = false;
-                       Element.hide('cmdline');
-               }
+       if (hotkey_prefix_pressed && ts - hotkey_prefix_pressed >= 5) {
+               console.log("hotkey_prefix seems to be stuck, aborting");
+               hotkey_prefix_pressed = false;
+               hotkey_prefix = false;
+               Element.hide('cmdline');
+       }
 
-               setTimeout(hotkey_prefix_timeout, 1000);
+       setTimeout(hotkey_prefix_timeout, 1000);
 
-       } catch  (e) {
-               exception_error("hotkey_prefix_timeout", e);
-       }
 }
 
 function uploadIconHandler(rc) {
-       try {
-               switch (rc) {
-                       case 0:
-                               notify_info("Upload complete.");
-                               if (inPreferences()) {
-                                       updateFeedList();
-                               } else {
-                                       setTimeout('updateFeedList(false, false)', 50);
-                               }
-                               break;
-                       case 1:
-                               notify_error("Upload failed: icon is too big.");
-                               break;
-                       case 2:
-                               notify_error("Upload failed.");
-                               break;
-               }
-
-       } catch (e) {
-               exception_error("uploadIconHandler", e);
+       switch (rc) {
+               case 0:
+                       notify_info("Upload complete.");
+                       if (inPreferences()) {
+                               updateFeedList();
+                       } else {
+                               setTimeout('updateFeedList(false, false)', 50);
+                       }
+                       break;
+               case 1:
+                       notify_error("Upload failed: icon is too big.");
+                       break;
+               case 2:
+                       notify_error("Upload failed.");
+                       break;
        }
 }
 
 function removeFeedIcon(id) {
+       if (confirm(__("Remove stored feed icon?"))) {
+               var query = "backend.php?op=pref-feeds&method=removeicon&feed_id=" + param_escape(id);
 
-       try {
+               console.log(query);
 
-               if (confirm(__("Remove stored feed icon?"))) {
-                       var query = "backend.php?op=pref-feeds&method=removeicon&feed_id=" + param_escape(id);
+               notify_progress("Removing feed icon...", true);
 
-                       console.log(query);
+               new Ajax.Request("backend.php", {
+                       parameters: query,
+                       onComplete: function(transport) {
+                               notify_info("Feed icon removed.");
+                               if (inPreferences()) {
+                                       updateFeedList();
+                               } else {
+                                       setTimeout('updateFeedList(false, false)', 50);
+                               }
+                       } });
+       }
 
-                       notify_progress("Removing feed icon...", true);
+       return false;
+}
 
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
-                                       notify_info("Feed icon removed.");
-                                       if (inPreferences()) {
-                                               updateFeedList();
-                                       } else {
-                                               setTimeout('updateFeedList(false, false)', 50);
-                                       }
-                               } });
-               }
+function uploadFeedIcon() {
+       var file = $("icon_file");
 
-               return false;
-       } catch (e) {
-               exception_error("removeFeedIcon", e);
+       if (file.value.length == 0) {
+               alert(__("Please select an image file to upload."));
+       } else {
+               if (confirm(__("Upload new icon for this feed?"))) {
+                       notify_progress("Uploading, please wait...", true);
+                       return true;
+               }
        }
+
+       return false;
 }
 
-function uploadFeedIcon() {
+function addLabel(select, callback) {
 
-       try {
+       var caption = prompt(__("Please enter label caption:"), "");
 
-               var file = $("icon_file");
+       if (caption != undefined) {
 
-               if (file.value.length == 0) {
-                       alert(__("Please select an image file to upload."));
-               } else {
-                       if (confirm(__("Upload new icon for this feed?"))) {
-                               notify_progress("Uploading, please wait...", true);
-                               return true;
-                       }
+               if (caption == "") {
+                       alert(__("Can't create label: missing caption."));
+                       return false;
                }
 
-               return false;
+               var query = "?op=pref-labels&method=add&caption=" +
+                       param_escape(caption);
 
-       } catch (e) {
-               exception_error("uploadFeedIcon", e);
-       }
-}
+               if (select)
+                       query += "&output=select";
 
-function addLabel(select, callback) {
+               notify_progress("Loading, please wait...", true);
 
-       try {
+               if (inPreferences() && !select) active_tab = "labelConfig";
 
-               var caption = prompt(__("Please enter label caption:"), "");
+               new Ajax.Request("backend.php", {
+                       parameters: query,
+                       onComplete: function(transport) {
+                               if (callback) {
+                                       callback(transport);
+                               } else if (inPreferences()) {
+                                       updateLabelList();
+                               } else {
+                                       updateFeedList();
+                               }
+               } });
 
-               if (caption != undefined) {
+       }
 
-                       if (caption == "") {
-                               alert(__("Can't create label: missing caption."));
-                               return false;
-                       }
+}
 
-                       var query = "?op=pref-labels&method=add&caption=" +
-                               param_escape(caption);
+function quickAddFeed() {
+       var query = "backend.php?op=feeds&method=quickAddFeed";
 
-                       if (select)
-                               query += "&output=select";
+       // overlapping widgets
+       if (dijit.byId("batchSubDlg")) dijit.byId("batchSubDlg").destroyRecursive();
+       if (dijit.byId("feedAddDlg"))   dijit.byId("feedAddDlg").destroyRecursive();
 
-                       notify_progress("Loading, please wait...", true);
+       var dialog = new dijit.Dialog({
+               id: "feedAddDlg",
+               title: __("Subscribe to Feed"),
+               style: "width: 600px",
+               show_error: function(msg) {
+                       var elem = $("fadd_error_message");
 
-                       if (inPreferences() && !select) active_tab = "labelConfig";
+                       elem.innerHTML = msg;
 
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
-                                       if (callback) {
-                                               callback(transport);
-                                       } else if (inPreferences()) {
-                                               updateLabelList();
-                                       } else {
-                                               updateFeedList();
-                                       }
-                       } });
+                       if (!Element.visible(elem))
+                               new Effect.Appear(elem);
 
-               }
+               },
+               execute: function() {
+                       if (this.validate()) {
+                               console.log(dojo.objectToQuery(this.attr('value')));
 
-       } catch (e) {
-               exception_error("addLabel", e);
-       }
-}
+                               var feed_url = this.attr('value').feed;
 
-function quickAddFeed() {
-       try {
-               var query = "backend.php?op=feeds&method=quickAddFeed";
+                               Element.show("feed_add_spinner");
+                               Element.hide("fadd_error_message");
 
-               // overlapping widgets
-               if (dijit.byId("batchSubDlg")) dijit.byId("batchSubDlg").destroyRecursive();
-               if (dijit.byId("feedAddDlg"))   dijit.byId("feedAddDlg").destroyRecursive();
+                               new Ajax.Request("backend.php", {
+                                       parameters: dojo.objectToQuery(this.attr('value')),
+                                       onComplete: function(transport) {
+                                               try {
 
-               var dialog = new dijit.Dialog({
-                       id: "feedAddDlg",
-                       title: __("Subscribe to Feed"),
-                       style: "width: 600px",
-                       show_error: function(msg) {
-                               var elem = $("fadd_error_message");
+                                                       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;
+                                                       }
 
-                               elem.innerHTML = msg;
+                                                       var rc = reply['result'];
 
-                               if (!Element.visible(elem))
-                                       new Effect.Appear(elem);
+                                                       notify('');
+                                                       Element.hide("feed_add_spinner");
 
-                       },
-                       execute: function() {
-                               if (this.validate()) {
-                                       console.log(dojo.objectToQuery(this.attr('value')));
+                                                       console.log(rc);
 
-                                       var feed_url = this.attr('value').feed;
+                                                       switch (parseInt(rc['code'])) {
+                                                       case 1:
+                                                               dialog.hide();
+                                                               notify_info(__("Subscribed to %s").replace("%s", feed_url));
 
-                                       Element.show("feed_add_spinner");
-                                       Element.hide("fadd_error_message");
+                                                               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:
+                                                               feeds = rc['feeds'];
 
-                                       new Ajax.Request("backend.php", {
-                                               parameters: dojo.objectToQuery(this.attr('value')),
-                                               onComplete: function(transport) {
-                                                       try {
+                                                               Element.show("fadd_multiple_notify");
 
-                                                               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 select = dijit.byId("feedDlg_feedContainerSelect");
 
-                                                               var rc = reply['result'];
+                                                               while (select.getOptions().length > 0)
+                                                                       select.removeOption(0);
 
-                                                               notify('');
-                                                               Element.hide("feed_add_spinner");
+                                                               select.addOption({value: '', label: __("Expand to select feed")});
 
-                                                               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:
-                                                                       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]});
-                                                                               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;
-                                                                       break;
-                                                               case 0:
-                                                                       dialog.show_error(__("You are already subscribed to this feed."));
-                                                                       break;
+                                                               var count = 0;
+                                                               for (var feedUrl in feeds) {
+                                                                       select.addOption({value: feedUrl, label: feeds[feedUrl]});
+                                                                       count++;
                                                                }
 
-                                                       } catch (e) {
-                                                               exception_error("subscribeToFeed", e, transport);
+                                                               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;
+                                                               break;
+                                                       case 0:
+                                                               dialog.show_error(__("You are already subscribed to this feed."));
+                                                               break;
                                                        }
 
-                                               } });
+                                               } catch (e) {
+                                                       console.error(transport.responseText);
+                                                       exception_error(e);
+                                               }
 
-                                       }
-                       },
-                       href: query});
+                                       } });
 
-               dialog.show();
-       } catch (e) {
-               exception_error("quickAddFeed", e);
-       }
+                               }
+               },
+               href: query});
+
+       dialog.show();
 }
 
 function createNewRuleElement(parentNode, replaceNode) {
-       try {
-               var form = document.forms["filter_new_rule_form"];
+       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));
+       var query = "backend.php?op=pref-filters&method=printrulename&rule="+
+               param_escape(dojo.formToJson(form));
 
-               console.log(query);
+       console.log(query);
 
-               new Ajax.Request("backend.php", {
-                       parameters: query,
-                       onComplete: function (transport) {
-                               try {
-                                       var li = dojo.create("li");
+       new Ajax.Request("backend.php", {
+               parameters: query,
+               onComplete: function (transport) {
+                       try {
+                               var li = dojo.create("li");
 
-                                       var cb = dojo.create("input", { type: "checkbox" }, li);
+                               var cb = dojo.create("input", { type: "checkbox" }, li);
 
-                                       new dijit.form.CheckBox({
-                                               onChange: function() {
-                                                       toggleSelectListRow2(this) },
-                                       }, cb);
+                               new dijit.form.CheckBox({
+                                       onChange: function() {
+                                               toggleSelectListRow2(this) },
+                               }, cb);
 
-                                       dojo.create("input", { type: "hidden",
-                                               name: "rule[]",
-                                               value: dojo.formToJson(form) }, li);
+                               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);
+                               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) {
-                                       exception_error("createNewRuleElement", e);
+                               if (replaceNode) {
+                                       parentNode.replaceChild(li, replaceNode);
+                               } else {
+                                       parentNode.appendChild(li);
                                }
-               } });
-       } catch (e) {
-               exception_error("createNewRuleElement", e);
-       }
+                       } catch (e) {
+                               exception_error(e);
+                       }
+       } });
 }
 
 function createNewActionElement(parentNode, replaceNode) {
-       try {
-               var 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;
-               }
+       var form = document.forms["filter_new_action_form"];
 
-               var query = "backend.php?op=pref-filters&method=printactionname&action="+
-                       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;
+       }
 
-               console.log(query);
+       var query = "backend.php?op=pref-filters&method=printactionname&action="+
+               param_escape(dojo.formToJson(form));
 
-               new Ajax.Request("backend.php", {
-                       parameters: query,
-                       onComplete: function (transport) {
-                               try {
-                                       var li = dojo.create("li");
+       console.log(query);
 
-                                       var cb = dojo.create("input", { type: "checkbox" }, li);
+       new Ajax.Request("backend.php", {
+               parameters: query,
+               onComplete: function (transport) {
+                       try {
+                               var li = dojo.create("li");
 
-                                       new dijit.form.CheckBox({
-                                               onChange: function() {
-                                                       toggleSelectListRow2(this) },
-                                       }, cb);
+                               var cb = dojo.create("input", { type: "checkbox" }, li);
 
-                                       dojo.create("input", { type: "hidden",
-                                               name: "action[]",
-                                               value: dojo.formToJson(form) }, li);
+                               new dijit.form.CheckBox({
+                                       onChange: function() {
+                                               toggleSelectListRow2(this) },
+                               }, cb);
 
-                                       dojo.create("span", {
-                                               onclick: function() {
-                                                       dijit.byId('filterEditDlg').editAction(this);
-                                               },
-                                               innerHTML: transport.responseText }, li);
+                               dojo.create("input", { type: "hidden",
+                                       name: "action[]",
+                                       value: dojo.formToJson(form) }, li);
 
-                                       if (replaceNode) {
-                                               parentNode.replaceChild(li, replaceNode);
-                                       } else {
-                                               parentNode.appendChild(li);
-                                       }
+                               dojo.create("span", {
+                                       onclick: function() {
+                                               dijit.byId('filterEditDlg').editAction(this);
+                                       },
+                                       innerHTML: transport.responseText }, li);
 
-                               } catch (e) {
-                                       exception_error("createNewActionElement", e);
+                               if (replaceNode) {
+                                       parentNode.replaceChild(li, replaceNode);
+                               } else {
+                                       parentNode.appendChild(li);
                                }
-                       } });
-       } catch (e) {
-               exception_error("createNewActionElement", e);
-       }
+
+                       } catch (e) {
+                               exception_error(e);
+                       }
+               } });
 }
 
 
 function addFilterRule(replaceNode, ruleStr) {
-       try {
-               if (dijit.byId("filterNewRuleDlg"))
-                       dijit.byId("filterNewRuleDlg").destroyRecursive();
-
-               var query = "backend.php?op=pref-filters&method=newrule&rule=" +
-                       param_escape(ruleStr);
-
-               var rule_dlg = new dijit.Dialog({
-                       id: "filterNewRuleDlg",
-                       title: ruleStr ? __("Edit rule") : __("Add rule"),
-                       style: "width: 600px",
-                       execute: function() {
-                               if (this.validate()) {
-                                       createNewRuleElement($("filterDlg_Matches"), replaceNode);
-                                       this.hide();
-                               }
-                       },
-                       href: query});
+       if (dijit.byId("filterNewRuleDlg"))
+               dijit.byId("filterNewRuleDlg").destroyRecursive();
+
+       var query = "backend.php?op=pref-filters&method=newrule&rule=" +
+               param_escape(ruleStr);
+
+       var rule_dlg = new dijit.Dialog({
+               id: "filterNewRuleDlg",
+               title: ruleStr ? __("Edit rule") : __("Add rule"),
+               style: "width: 600px",
+               execute: function() {
+                       if (this.validate()) {
+                               createNewRuleElement($("filterDlg_Matches"), replaceNode);
+                               this.hide();
+                       }
+               },
+               href: query});
 
-               rule_dlg.show();
-       } catch (e) {
-               exception_error("addFilterRule", e);
-       }
+       rule_dlg.show();
 }
 
 function addFilterAction(replaceNode, actionStr) {
-       try {
-               if (dijit.byId("filterNewActionDlg"))
-                       dijit.byId("filterNewActionDlg").destroyRecursive();
-
-               var query = "backend.php?op=pref-filters&method=newaction&action=" +
-                       param_escape(actionStr);
-
-               var rule_dlg = new dijit.Dialog({
-                       id: "filterNewActionDlg",
-                       title: actionStr ? __("Edit action") : __("Add action"),
-                       style: "width: 600px",
-                       execute: function() {
-                               if (this.validate()) {
-                                       createNewActionElement($("filterDlg_Actions"), replaceNode);
-                                       this.hide();
-                               }
-                       },
-                       href: query});
+       if (dijit.byId("filterNewActionDlg"))
+               dijit.byId("filterNewActionDlg").destroyRecursive();
+
+       var query = "backend.php?op=pref-filters&method=newaction&action=" +
+               param_escape(actionStr);
+
+       var rule_dlg = new dijit.Dialog({
+               id: "filterNewActionDlg",
+               title: actionStr ? __("Edit action") : __("Add action"),
+               style: "width: 600px",
+               execute: function() {
+                       if (this.validate()) {
+                               createNewActionElement($("filterDlg_Actions"), replaceNode);
+                               this.hide();
+                       }
+               },
+               href: query});
 
-               rule_dlg.show();
-       } catch (e) {
-               exception_error("addFilterAction", e);
-       }
+       rule_dlg.show();
 }
 
 function editFilterTest(query) {
-       try {
 
-               if (dijit.byId("filterTestDlg"))
-                       dijit.byId("filterTestDlg").destroyRecursive();
+       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;
+       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);
+                       console.log("getTestResults:" + offset);
 
-                               new Ajax.Request("backend.php", {
-                                       parameters: updquery,
-                                       onComplete: function (transport) {
-                                               try {
-                                                       var result = JSON.parse(transport.responseText);
+                       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();
+                                               if (result && dijit.byId("filterTestDlg") && dijit.byId("filterTestDlg").open) {
+                                                       test_dlg.results += result.size();
 
-                                                               console.log("got 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);
+                                                       $("prefFilterProgressMsg").innerHTML = __("Looking for articles (%d processed, %f found)...")
+                                                               .replace("%f", test_dlg.results)
+                                                               .replace("%d", offset);
 
-                                                               console.log(offset + " " + test_dlg.max_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);
+                                                       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;
-                                                               }
+                                                               $("prefFilterTestResultList").innerHTML += tmp.innerHTML;
+                                                       }
 
-                                                               if (test_dlg.results < 30 && offset < test_dlg.max_offset) {
+                                                       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);
+                                                               // get the next batch
+                                                               window.setTimeout(function () {
+                                                                       test_dlg.getTestResults(query, offset + test_dlg.limit);
+                                                               }, 0);
 
-                                                               } else {
-                                                                       // all done
-
-                                                                       Element.hide("prefFilterLoadingIndicator");
+                                                       } else {
+                                                               // all done
 
-                                                                       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);
-                                                                       }
+                                                               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");
+                                               } else if (!result) {
+                                                       console.log("getTestResults: can't parse results object");
 
-                                                               notify_error("Error while trying to get filter test results.");
+                                                       Element.hide("prefFilterLoadingIndicator");
 
-                                                       } else {
-                                                               console.log("getTestResults: dialog closed, bailing out.");
-                                                       }
-                                               } catch (e) {
-                                                       exception_error("editFilterTest/inner", e);
+                                                       notify_error("Error while trying to get filter test results.");
+
+                                               } else {
+                                                       console.log("getTestResults: dialog closed, bailing out.");
                                                }
+                                       } catch (e) {
+                                               exception_error(e);
+                                       }
 
-                                       } });
-                       },
-                       href: query});
+                               } });
+               },
+               href: query});
 
-               dojo.connect(test_dlg, "onLoad", null, function(e) {
-                       test_dlg.getTestResults(query, 0);
-               });
+       dojo.connect(test_dlg, "onLoad", null, function(e) {
+               test_dlg.getTestResults(query, 0);
+       });
 
-               test_dlg.show();
+       test_dlg.show();
 
-       } catch (e) {
-               exception_error("editFilterTest", e);
-       }
 }
 
 function quickAddFilter() {
-       try {
-               var query = "";
-               if (!inPreferences()) {
-                       query = "backend.php?op=pref-filters&method=newfilter&feed=" +
-                               param_escape(getActiveFeedId()) + "&is_cat=" +
-                               param_escape(activeFeedIsCat());
-               } else {
-                       query = "backend.php?op=pref-filters&method=newfilter";
-               }
+       var query = "";
+       if (!inPreferences()) {
+               query = "backend.php?op=pref-filters&method=newfilter&feed=" +
+                       param_escape(getActiveFeedId()) + "&is_cat=" +
+                       param_escape(activeFeedIsCat());
+       } else {
+               query = "backend.php?op=pref-filters&method=newfilter";
+       }
 
-               console.log(query);
+       console.log(query);
 
-               if (dijit.byId("feedEditDlg"))
-                       dijit.byId("feedEditDlg").destroyRecursive();
+       if (dijit.byId("feedEditDlg"))
+               dijit.byId("feedEditDlg").destroyRecursive();
 
-               if (dijit.byId("filterEditDlg"))
-                       dijit.byId("filterEditDlg").destroyRecursive();
+       if (dijit.byId("filterEditDlg"))
+               dijit.byId("filterEditDlg").destroyRecursive();
 
-               dialog = new dijit.Dialog({
-                       id: "filterEditDlg",
-                       title: __("Create Filter"),
-                       style: "width: 600px",
-                       test: function() {
-                               var query = "backend.php?" + dojo.formToQuery("filter_new_form") + "&savemode=test";
+       dialog = new dijit.Dialog({
+               id: "filterEditDlg",
+               title: __("Create Filter"),
+               style: "width: 600px",
+               test: function() {
+                       var query = "backend.php?" + dojo.formToQuery("filter_new_form") + "&savemode=test";
 
-                               editFilterTest(query);
-                       },
-                       selectRules: function(select) {
-                               $$("#filterDlg_Matches input[type=checkbox]").each(function(e) {
-                                       e.checked = select;
-                                       if (select)
-                                               e.parentNode.addClassName("Selected");
-                                       else
-                                               e.parentNode.removeClassName("Selected");
-                               });
-                       },
-                       selectActions: function(select) {
-                               $$("#filterDlg_Actions input[type=checkbox]").each(function(e) {
-                                       e.checked = select;
-
-                                       if (select)
-                                               e.parentNode.addClassName("Selected");
-                                       else
-                                               e.parentNode.removeClassName("Selected");
-
-                               });
-                       },
-                       editRule: function(e) {
-                               var li = e.parentNode;
-                               var rule = li.getElementsByTagName("INPUT")[1].value;
-                               addFilterRule(li, rule);
-                       },
-                       editAction: function(e) {
-                               var li = e.parentNode;
-                               var action = li.getElementsByTagName("INPUT")[1].value;
-                               addFilterAction(li, action);
-                       },
-                       addAction: function() { addFilterAction(); },
-                       addRule: function() { 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()) {
+                       editFilterTest(query);
+               },
+               selectRules: function(select) {
+                       $$("#filterDlg_Matches input[type=checkbox]").each(function(e) {
+                               e.checked = select;
+                               if (select)
+                                       e.parentNode.addClassName("Selected");
+                               else
+                                       e.parentNode.removeClassName("Selected");
+                       });
+               },
+               selectActions: function(select) {
+                       $$("#filterDlg_Actions input[type=checkbox]").each(function(e) {
+                               e.checked = select;
 
-                                       var query = dojo.formToQuery("filter_new_form");
+                               if (select)
+                                       e.parentNode.addClassName("Selected");
+                               else
+                                       e.parentNode.removeClassName("Selected");
 
-                                       console.log(query);
+                       });
+               },
+               editRule: function(e) {
+                       var li = e.parentNode;
+                       var rule = li.getElementsByTagName("INPUT")[1].value;
+                       addFilterRule(li, rule);
+               },
+               editAction: function(e) {
+                       var li = e.parentNode;
+                       var action = li.getElementsByTagName("INPUT")[1].value;
+                       addFilterAction(li, action);
+               },
+               addAction: function() { addFilterAction(); },
+               addRule: function() { 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()) {
+
+                               var query = dojo.formToQuery("filter_new_form");
+
+                               console.log(query);
 
-                                       new Ajax.Request("backend.php", {
-                                               parameters: query,
-                                               onComplete: function (transport) {
-                                                       if (inPreferences()) {
-                                                               updateFilterList();
-                                                       }
+                               new Ajax.Request("backend.php", {
+                                       parameters: query,
+                                       onComplete: function (transport) {
+                                               if (inPreferences()) {
+                                                       updateFilterList();
+                                               }
 
-                                                       dialog.hide();
-                                       } });
-                               }
-                       },
-                       href: query});
+                                               dialog.hide();
+                               } });
+                       }
+               },
+               href: query});
 
-               if (!inPreferences()) {
-                       var selectedText = getSelectionText();
+       if (!inPreferences()) {
+               var selectedText = getSelectionText();
 
-                       var lh = dojo.connect(dialog, "onLoad", function(){
-                               dojo.disconnect(lh);
+               var lh = dojo.connect(dialog, "onLoad", function(){
+                       dojo.disconnect(lh);
 
-                               if (selectedText != "") {
+                       if (selectedText != "") {
 
-                                       var feed_id = activeFeedIsCat() ? 'CAT:' + parseInt(getActiveFeedId()) :
-                                               getActiveFeedId();
+                               var feed_id = activeFeedIsCat() ? 'CAT:' + parseInt(getActiveFeedId()) :
+                                       getActiveFeedId();
 
-                                       var rule = { reg_exp: selectedText, feed_id: feed_id, filter_type: 1 };
+                               var rule = { reg_exp: selectedText, feed_id: feed_id, filter_type: 1 };
 
-                                       addFilterRule(null, dojo.toJson(rule));
+                               addFilterRule(null, dojo.toJson(rule));
 
-                               } else {
+                       } else {
 
-                                       var query = "op=rpc&method=getlinktitlebyid&id=" + getActiveArticleId();
+                               var query = "op=rpc&method=getlinktitlebyid&id=" + getActiveArticleId();
 
-                                       new Ajax.Request("backend.php", {
-                                       parameters: query,
-                                       onComplete: function(transport) {
-                                               var reply = JSON.parse(transport.responseText);
+                               new Ajax.Request("backend.php", {
+                               parameters: query,
+                               onComplete: function(transport) {
+                                       var reply = JSON.parse(transport.responseText);
 
-                                               var title = false;
+                                       var title = false;
 
-                                               if (reply && reply) title = reply.title;
+                                       if (reply && reply) title = reply.title;
 
-                                               if (title || getActiveFeedId() || activeFeedIsCat()) {
+                                       if (title || getActiveFeedId() || activeFeedIsCat()) {
 
-                                                       console.log(title + " " + getActiveFeedId());
+                                               console.log(title + " " + getActiveFeedId());
 
-                                                       var feed_id = activeFeedIsCat() ? 'CAT:' + parseInt(getActiveFeedId()) :
-                                                               getActiveFeedId();
+                                               var feed_id = activeFeedIsCat() ? 'CAT:' + parseInt(getActiveFeedId()) :
+                                                       getActiveFeedId();
 
-                                                       var rule = { reg_exp: title, feed_id: feed_id, filter_type: 1 };
+                                               var rule = { reg_exp: title, feed_id: feed_id, filter_type: 1 };
 
-                                                       addFilterRule(null, dojo.toJson(rule));
-                                               }
+                                               addFilterRule(null, dojo.toJson(rule));
+                                       }
 
-                                       } });
+                               } });
 
-                               }
+                       }
 
-                       });
-               }
+               });
+       }
 
-               dialog.show();
+       dialog.show();
 
-       } catch (e) {
-               exception_error("quickAddFilter", e);
-       }
 }
 
 function resetPubSub(feed_id, title) {
@@ -1349,598 +1207,442 @@ function unsubscribeFeed(feed_id, title) {
 
 function backend_sanity_check_callback(transport) {
 
-       try {
-
-               if (sanity_check_done) {
-                       fatalError(11, "Sanity check request received twice. This can indicate "+
-                     "presence of Firebug or some other disrupting extension. "+
-                               "Please disable it and try again.");
-                       return;
-               }
-
-               var reply = JSON.parse(transport.responseText);
-
-               if (!reply) {
-                       fatalError(3, "Sanity check: invalid RPC reply", transport.responseText);
-                       return;
-               }
+       if (sanity_check_done) {
+               fatalError(11, "Sanity check request received twice. This can indicate "+
+                 "presence of Firebug or some other disrupting extension. "+
+                       "Please disable it and try again.");
+               return;
+       }
 
-               var error_code = reply['error']['code'];
+       var reply = JSON.parse(transport.responseText);
 
-               if (error_code && error_code != 0) {
-                       return fatalError(error_code, reply['error']['message']);
-               }
+       if (!reply) {
+               fatalError(3, "Sanity check: invalid RPC reply", transport.responseText);
+               return;
+       }
 
-               console.log("sanity check ok");
+       var error_code = reply['error']['code'];
 
-               var params = reply['init-params'];
+       if (error_code && error_code != 0) {
+               return fatalError(error_code, reply['error']['message']);
+       }
 
-               if (params) {
-                       console.log('reading init-params...');
+       console.log("sanity check ok");
 
-                       for (k in params) {
-                               console.log("IP: " + k + " => " + JSON.stringify(params[k]));
-                               if (k == "label_base_index") _label_base_index = parseInt(params[k]);
-                       }
+       var params = reply['init-params'];
 
-                       init_params = params;
+       if (params) {
+               console.log('reading init-params...');
 
-                       // PluginHost might not be available on non-index pages
-                       window.PluginHost && PluginHost.run(PluginHost.HOOK_PARAMS_LOADED, init_params);
+               for (k in params) {
+                       console.log("IP: " + k + " => " + JSON.stringify(params[k]));
+                       if (k == "label_base_index") _label_base_index = parseInt(params[k]);
                }
 
-               sanity_check_done = true;
-
-               init_second_stage();
+               init_params = params;
 
-       } catch (e) {
-               exception_error("backend_sanity_check_callback", e, transport);
-       }
-}
-
-/*function has_local_storage() {
-       try {
-               return 'sessionStorage' in window && window['sessionStorage'] != null;
-       } catch (e) {
-               return false;
+               // PluginHost might not be available on non-index pages
+               window.PluginHost && PluginHost.run(PluginHost.HOOK_PARAMS_LOADED, init_params);
        }
-} */
 
-function catSelectOnChange(elem) {
-       try {
-/*             var value = elem[elem.selectedIndex].value;
-               var def = elem.getAttribute('default');
-
-               if (value == "ADD_CAT") {
+       sanity_check_done = true;
 
-                       if (def)
-                               dropboxSelect(elem, def);
-                       else
-                               elem.selectedIndex = 0;
+       init_second_stage();
 
-                       quickAddCat(elem);
-               } */
-
-       } catch (e) {
-               exception_error("catSelectOnChange", e);
-       }
 }
 
 function quickAddCat(elem) {
-       try {
-               var cat = prompt(__("Please enter category title:"));
-
-               if (cat) {
+       var cat = prompt(__("Please enter category title:"));
 
-                       var query = "?op=rpc&method=quickAddCat&cat=" + param_escape(cat);
+       if (cat) {
 
-                       notify_progress("Loading, please wait...", true);
+               var query = "?op=rpc&method=quickAddCat&cat=" + param_escape(cat);
 
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function (transport) {
-                                       var response = transport.responseXML;
-                                       var select = response.getElementsByTagName("select")[0];
-                                       var options = select.getElementsByTagName("option");
+               notify_progress("Loading, please wait...", true);
 
-                                       dropbox_replace_options(elem, options);
+               new Ajax.Request("backend.php", {
+                       parameters: query,
+                       onComplete: function (transport) {
+                               var response = transport.responseXML;
+                               var select = response.getElementsByTagName("select")[0];
+                               var options = select.getElementsByTagName("option");
 
-                                       notify('');
+                               dropbox_replace_options(elem, options);
 
-                       } });
+                               notify('');
 
-               }
+               } });
 
-       } catch (e) {
-               exception_error("quickAddCat", e);
        }
 }
 
 function genUrlChangeKey(feed, is_cat) {
+       var ok = confirm(__("Generate new syndication address for this feed?"));
 
-       try {
-               var ok = confirm(__("Generate new syndication address for this feed?"));
-
-               if (ok) {
+       if (ok) {
 
-                       notify_progress("Trying to change address...", true);
+               notify_progress("Trying to change address...", true);
 
-                       var query = "?op=pref-feeds&method=regenFeedKey&id=" + param_escape(feed) +
-                               "&is_cat=" + param_escape(is_cat);
+               var query = "?op=pref-feeds&method=regenFeedKey&id=" + param_escape(feed) +
+                       "&is_cat=" + param_escape(is_cat);
 
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
-                                               var reply = JSON.parse(transport.responseText);
-                                               var new_link = reply.link;
-
-                                               var e = $('gen_feed_url');
-
-                                               if (new_link) {
-
-                                                       e.innerHTML = e.innerHTML.replace(/\&amp;key=.*$/,
-                                                               "&amp;key=" + new_link);
-
-                                                       e.href = e.href.replace(/\&key=.*$/,
-                                                               "&key=" + new_link);
-
-                                                       new Effect.Highlight(e);
-
-                                                       notify('');
-
-                                               } else {
-                                                       notify_error("Could not change feed URL.");
-                                               }
-                               } });
-               }
-       } catch (e) {
-               exception_error("genUrlChangeKey", e);
-       }
-       return false;
-}
-
-function labelSelectOnChange(elem) {
-       try {
-/*             var value = elem[elem.selectedIndex].value;
-               var def = elem.getAttribute('default');
-
-               if (value == "ADD_LABEL") {
+               new Ajax.Request("backend.php", {
+                       parameters: query,
+                       onComplete: function(transport) {
+                                       var reply = JSON.parse(transport.responseText);
+                                       var new_link = reply.link;
 
-                       if (def)
-                               dropboxSelect(elem, def);
-                       else
-                               elem.selectedIndex = 0;
+                                       var e = $('gen_feed_url');
 
-                       addLabel(elem, function(transport) {
+                                       if (new_link) {
 
-                                       try {
+                                               e.innerHTML = e.innerHTML.replace(/\&amp;key=.*$/,
+                                                       "&amp;key=" + new_link);
 
-                                               var response = transport.responseXML;
-                                               var select = response.getElementsByTagName("select")[0];
-                                               var options = select.getElementsByTagName("option");
+                                               e.href = e.href.replace(/\&key=.*$/,
+                                                       "&key=" + new_link);
 
-                                               dropbox_replace_options(elem, options);
+                                               new Effect.Highlight(e);
 
                                                notify('');
-                                       } catch (e) {
-                                               exception_error("addLabel", e);
-                                       }
-                       });
-               } */
 
-       } catch (e) {
-               exception_error("labelSelectOnChange", e);
+                                       } else {
+                                               notify_error("Could not change feed URL.");
+                                       }
+                       } });
        }
+       return false;
 }
 
 function dropbox_replace_options(elem, options) {
+       while (elem.hasChildNodes())
+               elem.removeChild(elem.firstChild);
 
-       try {
-               while (elem.hasChildNodes())
-                       elem.removeChild(elem.firstChild);
+       var sel_idx = -1;
 
-               var sel_idx = -1;
+       for (var i = 0; i < options.length; i++) {
+               var text = options[i].firstChild.nodeValue;
+               var value = options[i].getAttribute("value");
 
-               for (var i = 0; i < options.length; i++) {
-                       var text = options[i].firstChild.nodeValue;
-                       var value = options[i].getAttribute("value");
+               if (value == undefined) value = text;
 
-                       if (value == undefined) value = text;
+               var issel = options[i].getAttribute("selected") == "1";
 
-                       var issel = options[i].getAttribute("selected") == "1";
+               var option = new Option(text, value, issel);
 
-                       var option = new Option(text, value, issel);
-
-                       if (options[i].getAttribute("disabled"))
-                               option.setAttribute("disabled", true);
-
-                       elem.insert(option);
-
-                       if (issel) sel_idx = i;
-               }
+               if (options[i].getAttribute("disabled"))
+                       option.setAttribute("disabled", true);
 
-               // Chrome doesn't seem to just select stuff when you pass new Option(x, y, true)
-               if (sel_idx >= 0) elem.selectedIndex = sel_idx;
+               elem.insert(option);
 
-       } catch (e) {
-               exception_error("dropbox_replace_options", e);
+               if (issel) sel_idx = i;
        }
+
+       // Chrome doesn't seem to just select stuff when you pass new Option(x, y, true)
+       if (sel_idx >= 0) elem.selectedIndex = sel_idx;
 }
 
 // mode = all, none, invert
 function selectTableRows(id, mode) {
-       try {
-               var rows = $(id).rows;
+       var rows = $(id).rows;
 
-               for (var i = 0; i < rows.length; i++) {
-                       var row = rows[i];
-                       var cb = false;
-                       var dcb = false;
+       for (var i = 0; i < rows.length; i++) {
+               var row = rows[i];
+               var cb = false;
+               var dcb = false;
 
-                       if (row.id && row.className) {
-                               var bare_id = row.id.replace(/^[A-Z]*?-/, "");
-                               var inputs = rows[i].getElementsByTagName("input");
+               if (row.id && row.className) {
+                       var bare_id = row.id.replace(/^[A-Z]*?-/, "");
+                       var inputs = rows[i].getElementsByTagName("input");
 
-                               for (var j = 0; j < inputs.length; j++) {
-                                       var input = inputs[j];
+                       for (var j = 0; j < inputs.length; j++) {
+                               var input = inputs[j];
 
-                                       if (input.getAttribute("type") == "checkbox" &&
-                                                       input.id.match(bare_id)) {
+                               if (input.getAttribute("type") == "checkbox" &&
+                                               input.id.match(bare_id)) {
 
-                                               cb = input;
-                                               dcb = dijit.getEnclosingWidget(cb);
-                                               break;
-                                       }
+                                       cb = input;
+                                       dcb = dijit.getEnclosingWidget(cb);
+                                       break;
                                }
+                       }
 
-                               if (cb || dcb) {
-                                       var issel = row.hasClassName("Selected");
+                       if (cb || dcb) {
+                               var issel = row.hasClassName("Selected");
 
-                                       if (mode == "all" && !issel) {
-                                               row.addClassName("Selected");
-                                               cb.checked = true;
-                                               if (dcb) dcb.set("checked", true);
-                                       } else if (mode == "none" && issel) {
+                               if (mode == "all" && !issel) {
+                                       row.addClassName("Selected");
+                                       cb.checked = true;
+                                       if (dcb) dcb.set("checked", true);
+                               } else if (mode == "none" && issel) {
+                                       row.removeClassName("Selected");
+                                       cb.checked = false;
+                                       if (dcb) dcb.set("checked", false);
+
+                               } else if (mode == "invert") {
+
+                                       if (issel) {
                                                row.removeClassName("Selected");
                                                cb.checked = false;
                                                if (dcb) dcb.set("checked", false);
-
-                                       } else if (mode == "invert") {
-
-                                               if (issel) {
-                                                       row.removeClassName("Selected");
-                                                       cb.checked = false;
-                                                       if (dcb) dcb.set("checked", false);
-                                               } else {
-                                                       row.addClassName("Selected");
-                                                       cb.checked = true;
-                                                       if (dcb) dcb.set("checked", true);
-                                               }
+                                       } else {
+                                               row.addClassName("Selected");
+                                               cb.checked = true;
+                                               if (dcb) dcb.set("checked", true);
                                        }
                                }
                        }
                }
-
-       } catch (e) {
-               exception_error("selectTableRows", e);
-
        }
+
 }
 
 function getSelectedTableRowIds(id) {
        var rows = [];
 
-       try {
-               var elem_rows = $(id).rows;
+       var elem_rows = $(id).rows;
 
-               for (var i = 0; i < elem_rows.length; i++) {
-                       if (elem_rows[i].hasClassName("Selected")) {
-                               var bare_id = elem_rows[i].id.replace(/^[A-Z]*?-/, "");
-                               rows.push(bare_id);
-                       }
+       for (var i = 0; i < elem_rows.length; i++) {
+               if (elem_rows[i].hasClassName("Selected")) {
+                       var bare_id = elem_rows[i].id.replace(/^[A-Z]*?-/, "");
+                       rows.push(bare_id);
                }
-
-       } catch (e) {
-               exception_error("getSelectedTableRowIds", e);
        }
 
        return rows;
 }
 
 function editFeed(feed, event) {
-       try {
-               if (feed <= 0)
-                       return alert(__("You can't edit this kind of feed."));
+       if (feed <= 0)
+               return alert(__("You can't edit this kind of feed."));
 
-               var query = "backend.php?op=pref-feeds&method=editfeed&id=" +
-                       param_escape(feed);
+       var query = "backend.php?op=pref-feeds&method=editfeed&id=" +
+               param_escape(feed);
 
-               console.log(query);
+       console.log(query);
 
-               if (dijit.byId("filterEditDlg"))
-                       dijit.byId("filterEditDlg").destroyRecursive();
+       if (dijit.byId("filterEditDlg"))
+               dijit.byId("filterEditDlg").destroyRecursive();
 
-               if (dijit.byId("feedEditDlg"))
-                       dijit.byId("feedEditDlg").destroyRecursive();
+       if (dijit.byId("feedEditDlg"))
+               dijit.byId("feedEditDlg").destroyRecursive();
 
-               dialog = new dijit.Dialog({
-                       id: "feedEditDlg",
-                       title: __("Edit Feed"),
-                       style: "width: 600px",
-                       execute: function() {
-                               if (this.validate()) {
+       dialog = new dijit.Dialog({
+               id: "feedEditDlg",
+               title: __("Edit Feed"),
+               style: "width: 600px",
+               execute: function() {
+                       if (this.validate()) {
 //                                     console.log(dojo.objectToQuery(this.attr('value')));
 
-                                       notify_progress("Saving data...", true);
+                               notify_progress("Saving data...", true);
 
-                                       new Ajax.Request("backend.php", {
-                                               parameters: dojo.objectToQuery(dialog.attr('value')),
-                                               onComplete: function(transport) {
-                                                       dialog.hide();
-                                                       notify('');
-                                                       updateFeedList();
-                                       }});
-                               }
-                       },
-                       href: query});
-
-               dialog.show();
+                               new Ajax.Request("backend.php", {
+                                       parameters: dojo.objectToQuery(dialog.attr('value')),
+                                       onComplete: function(transport) {
+                                               dialog.hide();
+                                               notify('');
+                                               updateFeedList();
+                               }});
+                       }
+               },
+               href: query});
 
-       } catch (e) {
-               exception_error("editFeed", e);
-       }
+       dialog.show();
 }
 
 function feedBrowser() {
-       try {
-               var query = "backend.php?op=feeds&method=feedBrowser";
+       var query = "backend.php?op=feeds&method=feedBrowser";
 
-               if (dijit.byId("feedAddDlg"))
-                       dijit.byId("feedAddDlg").hide();
+       if (dijit.byId("feedAddDlg"))
+               dijit.byId("feedAddDlg").hide();
 
-               if (dijit.byId("feedBrowserDlg"))
-                       dijit.byId("feedBrowserDlg").destroyRecursive();
+       if (dijit.byId("feedBrowserDlg"))
+               dijit.byId("feedBrowserDlg").destroyRecursive();
 
-               var dialog = new dijit.Dialog({
-                       id: "feedBrowserDlg",
-                       title: __("More Feeds"),
-                       style: "width: 600px",
-                       getSelectedFeedIds: function() {
-                               var list = $$("#browseFeedList li[id*=FBROW]");
-                               var selected = new Array();
-
-                               list.each(function(child) {
-                                       var id = child.id.replace("FBROW-", "");
+       var dialog = new dijit.Dialog({
+               id: "feedBrowserDlg",
+               title: __("More Feeds"),
+               style: "width: 600px",
+               getSelectedFeedIds: function () {
+                       var list = $$("#browseFeedList li[id*=FBROW]");
+                       var selected = new Array();
 
-                                       if (child.hasClassName('Selected')) {
-                                               selected.push(id);
-                                       }
-                               });
+                       list.each(function (child) {
+                               var id = child.id.replace("FBROW-", "");
 
-                               return selected;
-                       },
-                       getSelectedFeeds: function() {
-                               var list = $$("#browseFeedList li.Selected");
-                               var selected = new Array();
-
-                               list.each(function(child) {
-                                       var title = child.getElementsBySelector("span.fb_feedTitle")[0].innerHTML;
-                                       var url = child.getElementsBySelector("a.fb_feedUrl")[0].href;
-
-                                       selected.push([title,url]);
-
-                               });
+                               if (child.hasClassName('Selected')) {
+                                       selected.push(id);
+                               }
+                       });
 
-                               return selected;
-                       },
+                       return selected;
+               },
+               getSelectedFeeds: function () {
+                       var list = $$("#browseFeedList li.Selected");
+                       var selected = new Array();
 
-                       subscribe: function() {
-                               var mode = this.attr('value').mode;
-                               var selected = [];
+                       list.each(function (child) {
+                               var title = child.getElementsBySelector("span.fb_feedTitle")[0].innerHTML;
+                               var url = child.getElementsBySelector("a.fb_feedUrl")[0].href;
 
-                               if (mode == "1")
-                                       selected = this.getSelectedFeeds();
-                               else
-                                       selected = this.getSelectedFeedIds();
+                               selected.push([title, url]);
 
-                               if (selected.length > 0) {
-                                       dijit.byId("feedBrowserDlg").hide();
+                       });
 
-                                       notify_progress("Loading, please wait...", true);
+                       return selected;
+               },
 
-                                       // we use dojo.toJson instead of JSON.stringify because
-                                       // it somehow escapes everything TWICE, at least in Chrome 9
+               subscribe: function () {
+                       var mode = this.attr('value').mode;
+                       var selected = [];
 
-                                       var query = "?op=rpc&method=massSubscribe&payload="+
-                                               param_escape(dojo.toJson(selected)) + "&mode=" + param_escape(mode);
+                       if (mode == "1")
+                               selected = this.getSelectedFeeds();
+                       else
+                               selected = this.getSelectedFeedIds();
 
-                                       console.log(query);
+                       if (selected.length > 0) {
+                               dijit.byId("feedBrowserDlg").hide();
 
-                                       new Ajax.Request("backend.php", {
-                                               parameters: query,
-                                               onComplete: function(transport) {
-                                                       notify('');
-                                                       updateFeedList();
-                                               } });
+                               notify_progress("Loading, please wait...", true);
 
-                               } else {
-                                       alert(__("No feeds are selected."));
-                               }
+                               // we use dojo.toJson instead of JSON.stringify because
+                               // it somehow escapes everything TWICE, at least in Chrome 9
 
-                       },
-                       update: function() {
-                               var query = dojo.objectToQuery(dialog.attr('value'));
+                               var query = "?op=rpc&method=massSubscribe&payload=" +
+                                       param_escape(dojo.toJson(selected)) + "&mode=" + param_escape(mode);
 
-                               Element.show('feed_browser_spinner');
+                               console.log(query);
 
                                new Ajax.Request("backend.php", {
                                        parameters: query,
-                                       onComplete: function(transport) {
+                                       onComplete: function (transport) {
                                                notify('');
+                                               updateFeedList();
+                                       }
+                               });
 
-                                               Element.hide('feed_browser_spinner');
-
-                                               var c = $("browseFeedList");
-
-                                               var reply = JSON.parse(transport.responseText);
-
-                                               var r = reply['content'];
-                                               var mode = reply['mode'];
-
-                                               if (c && r) {
-                                                       c.innerHTML = r;
-                                               }
+                       } else {
+                               alert(__("No feeds are selected."));
+                       }
 
-                                               dojo.parser.parse("browseFeedList");
+               },
+               update: function () {
+                       var query = dojo.objectToQuery(dialog.attr('value'));
 
-                                               if (mode == 2) {
-                                                       Element.show(dijit.byId('feed_archive_remove').domNode);
-                                               } else {
-                                                       Element.hide(dijit.byId('feed_archive_remove').domNode);
-                                               }
+                       Element.show('feed_browser_spinner');
 
-                                       } });
-                       },
-                       removeFromArchive: function() {
-                               var selected = this.getSelectedFeedIds();
+                       new Ajax.Request("backend.php", {
+                               parameters: query,
+                               onComplete: function (transport) {
+                                       notify('');
 
-                               if (selected.length > 0) {
+                                       Element.hide('feed_browser_spinner');
 
-                                       var pr = __("Remove selected feeds from the archive? Feeds with stored articles will not be removed.");
+                                       var c = $("browseFeedList");
 
-                                       if (confirm(pr)) {
-                                               Element.show('feed_browser_spinner');
+                                       var reply = JSON.parse(transport.responseText);
 
-                                               var query = "?op=rpc&method=remarchive&ids=" +
-                                                       param_escape(selected.toString());;
+                                       var r = reply['content'];
+                                       var mode = reply['mode'];
 
-                                               new Ajax.Request("backend.php", {
-                                                       parameters: query,
-                                                       onComplete: function(transport) {
-                                                               dialog.update();
-                                                       } });
+                                       if (c && r) {
+                                               c.innerHTML = r;
                                        }
-                               }
-                       },
-                       execute: function() {
-                               if (this.validate()) {
-                                       this.subscribe();
-                               }
-                       },
-                       href: query});
-
-               dialog.show();
-
-       } catch (e) {
-               exception_error("editFeed", e);
-       }
-}
-
-function showFeedsWithErrors() {
-       try {
-               var query = "backend.php?op=pref-feeds&method=feedsWithErrors";
 
-               if (dijit.byId("errorFeedsDlg"))
-                       dijit.byId("errorFeedsDlg").destroyRecursive();
+                                       dojo.parser.parse("browseFeedList");
 
-               dialog = new dijit.Dialog({
-                       id: "errorFeedsDlg",
-                       title: __("Feeds with update errors"),
-                       style: "width: 600px",
-                       getSelectedFeeds: function() {
-                               return getSelectedTableRowIds("prefErrorFeedList");
-                       },
-                       removeSelected: function() {
-                               var sel_rows = this.getSelectedFeeds();
+                                       if (mode == 2) {
+                                               Element.show(dijit.byId('feed_archive_remove').domNode);
+                                       } else {
+                                               Element.hide(dijit.byId('feed_archive_remove').domNode);
+                                       }
 
-                               console.log(sel_rows);
+                               }
+                       });
+               },
+               removeFromArchive: function () {
+                       var selected = this.getSelectedFeedIds();
 
-                               if (sel_rows.length > 0) {
-                                       var ok = confirm(__("Remove selected feeds?"));
+                       if (selected.length > 0) {
 
-                                       if (ok) {
-                                               notify_progress("Removing selected feeds...", true);
+                               var pr = __("Remove selected feeds from the archive? Feeds with stored articles will not be removed.");
 
-                                               var query = "?op=pref-feeds&method=remove&ids="+
-                                                       param_escape(sel_rows.toString());
+                               if (confirm(pr)) {
+                                       Element.show('feed_browser_spinner');
 
-                                               new Ajax.Request("backend.php", {
-                                                       parameters: query,
-                                                       onComplete: function(transport) {
-                                                               notify('');
-                                                               dialog.hide();
-                                                               updateFeedList();
-                                                       } });
-                                       }
+                                       var query = "?op=rpc&method=remarchive&ids=" +
+                                               param_escape(selected.toString());
+                                       ;
 
-                               } else {
-                                       alert(__("No feeds are selected."));
-                               }
-                       },
-                       execute: function() {
-                               if (this.validate()) {
+                                       new Ajax.Request("backend.php", {
+                                               parameters: query,
+                                               onComplete: function (transport) {
+                                                       dialog.update();
+                                               }
+                                       });
                                }
-                       },
-                       href: query});
-
-               dialog.show();
-
-       } catch (e) {
-               exception_error("showFeedsWithErrors", e);
-       }
+                       }
+               },
+               execute: function () {
+                       if (this.validate()) {
+                               this.subscribe();
+                       }
+               },
+               href: query
+       });
 
+       dialog.show();
 }
 
-/* new support functions for SelectByTag */
+function showFeedsWithErrors() {
+       var query = "backend.php?op=pref-feeds&method=feedsWithErrors";
 
-function get_all_tags(selObj){
-       try {
-               if( !selObj ) return "";
+       if (dijit.byId("errorFeedsDlg"))
+               dijit.byId("errorFeedsDlg").destroyRecursive();
 
-               var result = "";
-               var len = selObj.options.length;
+       dialog = new dijit.Dialog({
+               id: "errorFeedsDlg",
+               title: __("Feeds with update errors"),
+               style: "width: 600px",
+               getSelectedFeeds: function() {
+                       return getSelectedTableRowIds("prefErrorFeedList");
+               },
+               removeSelected: function() {
+                       var sel_rows = this.getSelectedFeeds();
 
-               for (var i=0; i < len; i++){
-                       if (selObj.options[i].selected) {
-                               result += selObj[i].value + "%2C";   // is really a comma
-                       }
-               }
+                       console.log(sel_rows);
 
-               if (result.length > 0){
-                       result = result.substr(0, result.length-3);  // remove trailing %2C
-               }
+                       if (sel_rows.length > 0) {
+                               var ok = confirm(__("Remove selected feeds?"));
 
-               return(result);
+                               if (ok) {
+                                       notify_progress("Removing selected feeds...", true);
 
-       } catch (e) {
-               exception_error("get_all_tags", e);
-       }
-}
-
-function get_radio_checked(radioObj) {
-       try {
-               if (!radioObj) return "";
+                                       var query = "?op=pref-feeds&method=remove&ids="+
+                                               param_escape(sel_rows.toString());
 
-               var len = radioObj.length;
+                                       new Ajax.Request("backend.php", {
+                                               parameters: query,
+                                               onComplete: function(transport) {
+                                                       notify('');
+                                                       dialog.hide();
+                                                       updateFeedList();
+                                               } });
+                               }
 
-               if (len == undefined){
-                       if(radioObj.checked){
-                               return(radioObj.value);
                        } else {
-                               return("");
+                               alert(__("No feeds are selected."));
                        }
-               }
-
-               for( var i=0; i < len; i++ ){
-                       if( radioObj[i].checked ){
-                               return( radioObj[i].value);
+               },
+               execute: function() {
+                       if (this.validate()) {
                        }
-               }
+               },
+               href: query});
 
-       } catch (e) {
-               exception_error("get_radio_checked", e);
-       }
-       return("");
+       dialog.show();
 }
 
 function get_timestamp() {
@@ -1949,24 +1651,19 @@ function get_timestamp() {
 }
 
 function helpDialog(topic) {
-       try {
-               var query = "backend.php?op=backend&method=help&topic=" + param_escape(topic);
+       var query = "backend.php?op=backend&method=help&topic=" + param_escape(topic);
 
-               if (dijit.byId("helpDlg"))
-                       dijit.byId("helpDlg").destroyRecursive();
+       if (dijit.byId("helpDlg"))
+               dijit.byId("helpDlg").destroyRecursive();
 
-               dialog = new dijit.Dialog({
-                       id: "helpDlg",
-                       title: __("Help"),
-                       style: "width: 600px",
-                       href: query,
-               });
+       dialog = new dijit.Dialog({
+               id: "helpDlg",
+               title: __("Help"),
+               style: "width: 600px",
+               href: query,
+       });
 
-               dialog.show();
-
-       } catch (e) {
-               exception_error("helpDialog", e);
-       }
+       dialog.show();
 }
 
 function htmlspecialchars_decode (string, quote_style) {
@@ -2077,4 +1774,4 @@ function openArticlePopup(id) {
 
        w.opener = null;
        w.location = "backend.php?op=article&method=view&mode=raw&html=1&zoom=1&id=" + id + "&csrf_token=" + getInitParam("csrf_token");
-}
\ No newline at end of file
+}
index 83444b7d068955e15ce5f168bbb2e83451d23017..974170d9ba78a2c38b7952293ccc44f20a1c4e74 100755 (executable)
@@ -25,218 +25,209 @@ function updateFeedList(sort_key) {
 }
 
 function checkInactiveFeeds() {
-       try {
-               new Ajax.Request("backend.php", {
-                       parameters: "?op=pref-feeds&method=getinactivefeeds",
-                       onComplete: function(transport) {
-                               if (parseInt(transport.responseText) > 0) {
-                                       Element.show(dijit.byId("pref_feeds_inactive_btn").domNode);
-                               }
-                       } });
-
-       } catch (e) {
-               exception_error("checkInactiveFeeds", e);
-       }
+       new Ajax.Request("backend.php", {
+               parameters: "?op=pref-feeds&method=getinactivefeeds",
+               onComplete: function (transport) {
+                       if (parseInt(transport.responseText) > 0) {
+                               Element.show(dijit.byId("pref_feeds_inactive_btn").domNode);
+                       }
+               }
+       });
 }
 
 function updateUsersList(sort_key) {
-       try {
-               var user_search = $("user_search");
-               var search = "";
-               if (user_search) { search = user_search.value; }
-
-               var query = "?op=pref-users&sort="
-                       + param_escape(sort_key) +
-                       "&search=" + param_escape(search);
+       var user_search = $("user_search");
+       var search = "";
+       if (user_search) {
+               search = user_search.value;
+       }
 
-               new Ajax.Request("backend.php", {
-                       parameters: query,
-                       onComplete: function(transport) {
-                               dijit.byId('userConfigTab').attr('content', transport.responseText);
-                               selectTab("userConfig", true)
-                               notify("");
-                       } });
+       var query = "?op=pref-users&sort="
+               + param_escape(sort_key) +
+               "&search=" + param_escape(search);
 
-       } catch (e) {
-               exception_error("updateUsersList", e);
-       }
+       new Ajax.Request("backend.php", {
+               parameters: query,
+               onComplete: function (transport) {
+                       dijit.byId('userConfigTab').attr('content', transport.responseText);
+                       selectTab("userConfig", true)
+                       notify("");
+               }
+       });
 }
 
 function addUser() {
+       var login = prompt(__("Please enter login:"), "");
 
-       try {
-
-               var login = prompt(__("Please enter login:"), "");
-
-               if (login == null) {
-                       return false;
-               }
+       if (login == null) {
+               return false;
+       }
 
-               if (login == "") {
-                       alert(__("Can't create user: no login specified."));
-                       return false;
-               }
+       if (login == "") {
+               alert(__("Can't create user: no login specified."));
+               return false;
+       }
 
-               notify_progress("Adding user...");
+       notify_progress("Adding user...");
 
-               var query = "?op=pref-users&method=add&login=" +
-                       param_escape(login);
+       var query = "?op=pref-users&method=add&login=" +
+               param_escape(login);
 
-               new Ajax.Request("backend.php", {
-                       parameters: query,
-                       onComplete: function(transport) {
-                               notify_callback2(transport);
-                               updateUsersList();
-                       } });
+       new Ajax.Request("backend.php", {
+               parameters: query,
+               onComplete: function (transport) {
+                       notify_callback2(transport);
+                       updateUsersList();
+               }
+       });
 
-       } catch (e) {
-               exception_error("addUser", e);
-       }
 }
 
 function editUser(id, event) {
 
-       try {
-               var query = "backend.php?op=pref-users&method=edit&id=" +
-                       param_escape(id);
-
-               if (dijit.byId("userEditDlg"))
-                       dijit.byId("userEditDlg").destroyRecursive();
-
-               dialog = new dijit.Dialog({
-                       id: "userEditDlg",
-                       title: __("User Editor"),
-                       style: "width: 600px",
-                       execute: function() {
-                               if (this.validate()) {
-                                       notify_progress("Saving data...", true);
+       var query = "backend.php?op=pref-users&method=edit&id=" +
+               param_escape(id);
 
-                                       var query = dojo.formToQuery("user_edit_form");
+       if (dijit.byId("userEditDlg"))
+               dijit.byId("userEditDlg").destroyRecursive();
 
-                                       new Ajax.Request("backend.php", {
-                                               parameters: query,
-                                               onComplete: function(transport) {
-                                                       dialog.hide();
-                                                       updateUsersList();
-                                               }});
-                               }
-                       },
-                       href: query});
+       dialog = new dijit.Dialog({
+               id: "userEditDlg",
+               title: __("User Editor"),
+               style: "width: 600px",
+               execute: function () {
+                       if (this.validate()) {
+                               notify_progress("Saving data...", true);
 
-               dialog.show();
+                               var query = dojo.formToQuery("user_edit_form");
 
-       } catch (e) {
-               exception_error("editUser", e);
-       }
+                               new Ajax.Request("backend.php", {
+                                       parameters: query,
+                                       onComplete: function (transport) {
+                                               dialog.hide();
+                                               updateUsersList();
+                                       }
+                               });
+                       }
+               },
+               href: query
+       });
 
+       dialog.show();
 }
 
 function editFilter(id) {
-       try {
-
-               var query = "backend.php?op=pref-filters&method=edit&id=" + param_escape(id);
 
-               if (dijit.byId("feedEditDlg"))
-                       dijit.byId("feedEditDlg").destroyRecursive();
+       var query = "backend.php?op=pref-filters&method=edit&id=" + param_escape(id);
 
-               if (dijit.byId("filterEditDlg"))
-                       dijit.byId("filterEditDlg").destroyRecursive();
+       if (dijit.byId("feedEditDlg"))
+               dijit.byId("feedEditDlg").destroyRecursive();
 
-               dialog = new dijit.Dialog({
-                       id: "filterEditDlg",
-                       title: __("Edit Filter"),
-                       style: "width: 600px",
-
-                       test: function() {
-                               var query = "backend.php?" + dojo.formToQuery("filter_edit_form") + "&savemode=test";
-
-                               editFilterTest(query);
-                       },
-                       selectRules: function(select) {
-                               $$("#filterDlg_Matches input[type=checkbox]").each(function(e) {
-                                       e.checked = select;
-                                       if (select)
-                                               e.parentNode.addClassName("Selected");
-                                       else
-                                               e.parentNode.removeClassName("Selected");
-                               });
-                       },
-                       selectActions: function(select) {
-                               $$("#filterDlg_Actions input[type=checkbox]").each(function(e) {
-                                       e.checked = select;
+       if (dijit.byId("filterEditDlg"))
+               dijit.byId("filterEditDlg").destroyRecursive();
 
-                                       if (select)
-                                               e.parentNode.addClassName("Selected");
-                                       else
-                                               e.parentNode.removeClassName("Selected");
+       dialog = new dijit.Dialog({
+               id: "filterEditDlg",
+               title: __("Edit Filter"),
+               style: "width: 600px",
 
-                               });
-                       },
-                       editRule: function(e) {
-                               var li = e.parentNode;
-                               var rule = li.getElementsByTagName("INPUT")[1].value;
-                               addFilterRule(li, rule);
-                       },
-                       editAction: function(e) {
-                               var li = e.parentNode;
-                               var action = li.getElementsByTagName("INPUT")[1].value;
-                               addFilterAction(li, action);
-                       },
-                       removeFilter: function() {
-                               var msg = __("Remove filter?");
+               test: function () {
+                       var query = "backend.php?" + dojo.formToQuery("filter_edit_form") + "&savemode=test";
 
-                               if (confirm(msg)) {
-                                       this.hide();
+                       editFilterTest(query);
+               },
+               selectRules: function (select) {
+                       $$("#filterDlg_Matches input[type=checkbox]").each(function (e) {
+                               e.checked = select;
+                               if (select)
+                                       e.parentNode.addClassName("Selected");
+                               else
+                                       e.parentNode.removeClassName("Selected");
+                       });
+               },
+               selectActions: function (select) {
+                       $$("#filterDlg_Actions input[type=checkbox]").each(function (e) {
+                               e.checked = select;
 
-                                       notify_progress("Removing filter...");
+                               if (select)
+                                       e.parentNode.addClassName("Selected");
+                               else
+                                       e.parentNode.removeClassName("Selected");
 
-                                       var id = this.attr('value').id;
+                       });
+               },
+               editRule: function (e) {
+                       var li = e.parentNode;
+                       var rule = li.getElementsByTagName("INPUT")[1].value;
+                       addFilterRule(li, rule);
+               },
+               editAction: function (e) {
+                       var li = e.parentNode;
+                       var action = li.getElementsByTagName("INPUT")[1].value;
+                       addFilterAction(li, action);
+               },
+               removeFilter: function () {
+                       var msg = __("Remove filter?");
+
+                       if (confirm(msg)) {
+                               this.hide();
 
-                                       var query = "?op=pref-filters&method=remove&ids="+
-                                               param_escape(id);
+                               notify_progress("Removing filter...");
 
-                                       new Ajax.Request("backend.php", {
-                                               parameters: query,
-                                               onComplete: function(transport) {
-                                                       updateFilterList();
-                                               } });
-                               }
-                       },
-                       addAction: function() { addFilterAction(); },
-                       addRule: function() { 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()) {
+                               var id = this.attr('value').id;
 
-                                       notify_progress("Saving data...", true);
+                               var query = "?op=pref-filters&method=remove&ids=" +
+                                       param_escape(id);
 
-                                       var query = dojo.formToQuery("filter_edit_form");
+                               new Ajax.Request("backend.php", {
+                                       parameters: query,
+                                       onComplete: function (transport) {
+                                               updateFilterList();
+                                       }
+                               });
+                       }
+               },
+               addAction: function () {
+                       addFilterAction();
+               },
+               addRule: function () {
+                       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()) {
 
-                                       console.log(query);
+                               notify_progress("Saving data...", true);
 
-                                       new Ajax.Request("backend.php", {
-                                               parameters: query,
-                                               onComplete: function(transport) {
-                                                       dialog.hide();
-                                                       updateFilterList();
-                                               }});
-                               }
-                       },
-                       href: query});
+                               var query = dojo.formToQuery("filter_edit_form");
 
-               dialog.show();
+                               console.log(query);
 
+                               new Ajax.Request("backend.php", {
+                                       parameters: query,
+                                       onComplete: function (transport) {
+                                               dialog.hide();
+                                               updateFilterList();
+                                       }
+                               });
+                       }
+               },
+               href: query
+       });
 
-       } catch (e) {
-               exception_error("editFilter", e);
-       }
+       dialog.show();
 }
 
+
 function getSelectedLabels() {
        var tree = dijit.byId("labelTree");
        var items = tree.model.getCheckedItems();
@@ -322,34 +313,29 @@ function removeSelectedLabels() {
 
 function removeSelectedUsers() {
 
-       try {
-
-               var sel_rows = getSelectedUsers();
-
-               if (sel_rows.length > 0) {
+       var sel_rows = getSelectedUsers();
 
-                       var ok = confirm(__("Remove selected users? Neither default admin nor your account will be removed."));
+       if (sel_rows.length > 0) {
 
-                       if (ok) {
-                               notify_progress("Removing selected users...");
+               var ok = confirm(__("Remove selected users? Neither default admin nor your account will be removed."));
 
-                               var query = "?op=pref-users&method=remove&ids="+
-                                       param_escape(sel_rows.toString());
+               if (ok) {
+                       notify_progress("Removing selected users...");
 
-                               new Ajax.Request("backend.php", {
-                                       parameters: query,
-                                       onComplete: function(transport) {
-                                               updateUsersList();
-                                       } });
+                       var query = "?op=pref-users&method=remove&ids=" +
+                               param_escape(sel_rows.toString());
 
-                       }
+                       new Ajax.Request("backend.php", {
+                               parameters: query,
+                               onComplete: function (transport) {
+                                       updateUsersList();
+                               }
+                       });
 
-               } else {
-                       alert(__("No users are selected."));
                }
 
-       } catch (e) {
-               exception_error("removeSelectedUsers", e);
+       } else {
+               alert(__("No users are selected."));
        }
 
        return false;
@@ -357,70 +343,59 @@ function removeSelectedUsers() {
 
 function removeSelectedFilters() {
 
-       try {
-
-               var sel_rows = getSelectedFilters();
+       var sel_rows = getSelectedFilters();
 
-               if (sel_rows.length > 0) {
+       if (sel_rows.length > 0) {
 
-                       var ok = confirm(__("Remove selected filters?"));
+               var ok = confirm(__("Remove selected filters?"));
 
-                       if (ok) {
-                               notify_progress("Removing selected filters...");
+               if (ok) {
+                       notify_progress("Removing selected filters...");
 
-                               var query = "?op=pref-filters&method=remove&ids="+
-                                       param_escape(sel_rows.toString());
+                       var query = "?op=pref-filters&method=remove&ids=" +
+                               param_escape(sel_rows.toString());
 
-                               new Ajax.Request("backend.php", {
-                                               parameters: query,
-                                               onComplete: function(transport) {
-                                                       updateFilterList();
-                                               } });
-                       }
-               } else {
-                       alert(__("No filters are selected."));
+                       new Ajax.Request("backend.php", {
+                               parameters: query,
+                               onComplete: function (transport) {
+                                       updateFilterList();
+                               }
+                       });
                }
-
-       } catch (e) {
-               exception_error("removeSelectedFilters", e);
+       } else {
+               alert(__("No filters are selected."));
        }
 
        return false;
 }
 
-
 function removeSelectedFeeds() {
 
-       try {
-
-               var sel_rows = getSelectedFeeds();
-
-               if (sel_rows.length > 0) {
+       var sel_rows = getSelectedFeeds();
 
-                       var ok = confirm(__("Unsubscribe from selected feeds?"));
+       if (sel_rows.length > 0) {
 
-                       if (ok) {
+               var ok = confirm(__("Unsubscribe from selected feeds?"));
 
-                               notify_progress("Unsubscribing from selected feeds...", true);
+               if (ok) {
 
-                               var query = "?op=pref-feeds&method=remove&ids="+
-                                       param_escape(sel_rows.toString());
+                       notify_progress("Unsubscribing from selected feeds...", true);
 
-                               console.log(query);
+                       var query = "?op=pref-feeds&method=remove&ids=" +
+                               param_escape(sel_rows.toString());
 
-                               new Ajax.Request("backend.php", {
-                                       parameters: query,
-                                       onComplete: function(transport) {
-                                               updateFeedList();
-                                               } });
-                       }
+                       console.log(query);
 
-               } else {
-                       alert(__("No feeds are selected."));
+                       new Ajax.Request("backend.php", {
+                               parameters: query,
+                               onComplete: function (transport) {
+                                       updateFeedList();
+                               }
+                       });
                }
 
-       } catch (e) {
-               exception_error("removeSelectedFeeds", e);
+       } else {
+               alert(__("No feeds are selected."));
        }
 
        return false;
@@ -505,80 +480,70 @@ function editSelectedUser() {
 
 function resetSelectedUserPass() {
 
-       try {
-
-               var rows = getSelectedUsers();
-
-               if (rows.length == 0) {
-                       alert(__("No users are selected."));
-                       return;
-               }
+       var rows = getSelectedUsers();
 
-               if (rows.length > 1) {
-                       alert(__("Please select only one user."));
-                       return;
-               }
+       if (rows.length == 0) {
+               alert(__("No users are selected."));
+               return;
+       }
 
-               var ok = confirm(__("Reset password of selected user?"));
+       if (rows.length > 1) {
+               alert(__("Please select only one user."));
+               return;
+       }
 
-               if (ok) {
-                       notify_progress("Resetting password for selected user...");
+       var ok = confirm(__("Reset password of selected user?"));
 
-                       var id = rows[0];
+       if (ok) {
+               notify_progress("Resetting password for selected user...");
 
-                       var query = "?op=pref-users&method=resetPass&id=" +
-                               param_escape(id);
+               var id = rows[0];
 
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
-                                       notify_info(transport.responseText, true);
-                               } });
+               var query = "?op=pref-users&method=resetPass&id=" +
+                       param_escape(id);
 
-               }
+               new Ajax.Request("backend.php", {
+                       parameters: query,
+                       onComplete: function (transport) {
+                               notify_info(transport.responseText, true);
+                       }
+               });
 
-       } catch (e) {
-               exception_error("resetSelectedUserPass", e);
        }
 }
 
 function selectedUserDetails() {
 
-       try {
-
-               var rows = getSelectedUsers();
-
-               if (rows.length == 0) {
-                       alert(__("No users are selected."));
-                       return;
-               }
+       var rows = getSelectedUsers();
 
-               if (rows.length > 1) {
-                       alert(__("Please select only one user."));
-                       return;
-               }
+       if (rows.length == 0) {
+               alert(__("No users are selected."));
+               return;
+       }
 
-               var id = rows[0];
+       if (rows.length > 1) {
+               alert(__("Please select only one user."));
+               return;
+       }
 
-               var query = "backend.php?op=pref-users&method=userdetails&id=" + id;
+       var id = rows[0];
 
-               if (dijit.byId("userDetailsDlg"))
-                       dijit.byId("userDetailsDlg").destroyRecursive();
+       var query = "backend.php?op=pref-users&method=userdetails&id=" + id;
 
-               dialog = new dijit.Dialog({
-                       id: "userDetailsDlg",
-                       title: __("User details"),
-                       style: "width: 600px",
-                       execute: function() {
-                               dialog.hide();
-                       },
-                       href: query});
+       if (dijit.byId("userDetailsDlg"))
+               dijit.byId("userDetailsDlg").destroyRecursive();
 
-               dialog.show();
+       dialog = new dijit.Dialog({
+               id: "userDetailsDlg",
+               title: __("User details"),
+               style: "width: 600px",
+               execute: function () {
+                       dialog.hide();
+               },
+               href: query
+       });
 
-       } catch (e) {
-               exception_error("selectedUserDetails", e);
-       }
+       dialog.show();
 }
 
 
@@ -646,154 +611,149 @@ function editSelectedFeed() {
 }
 
 function editSelectedFeeds() {
+       var rows = getSelectedFeeds();
 
-       try {
-               var rows = getSelectedFeeds();
-
-               if (rows.length == 0) {
-                       alert(__("No feeds are selected."));
-                       return;
-               }
-
-               notify_progress("Loading, please wait...");
-
-               var query = "backend.php?op=pref-feeds&method=editfeeds&ids=" +
-                       param_escape(rows.toString());
-
-               console.log(query);
-
-               if (dijit.byId("feedEditDlg"))
-                       dijit.byId("feedEditDlg").destroyRecursive();
+       if (rows.length == 0) {
+               alert(__("No feeds are selected."));
+               return;
+       }
 
-               new Ajax.Request("backend.php", {
-                       parameters: query,
-                       onComplete: function(transport) {
+       notify_progress("Loading, please wait...");
 
-                               notify("");
-
-                               var dialog = new dijit.Dialog({
-                                       id: "feedEditDlg",
-                                       title: __("Edit Multiple Feeds"),
-                                       style: "width: 600px",
-                                       getChildByName: function (name) {
-                                               var rv = null;
-                                               this.getChildren().each(
-                                                       function(child) {
-                                                               if (child.name == name) {
-                                                                       rv = child;
-                                                                       return;
-                                                               }
-                                                       });
-                                               return rv;
-                                       },
-                                       toggleField: function (checkbox, elem, label) {
-                                               this.getChildByName(elem).attr('disabled', !checkbox.checked);
+       var query = "backend.php?op=pref-feeds&method=editfeeds&ids=" +
+               param_escape(rows.toString());
 
-                                               if ($(label))
-                                                       if (checkbox.checked)
-                                                               $(label).removeClassName('insensitive');
-                                                       else
-                                                               $(label).addClassName('insensitive');
+       console.log(query);
 
-                                       },
-                                       execute: function() {
-                                               if (this.validate() && confirm(__("Save changes to selected feeds?"))) {
-                                                       var query = dojo.objectToQuery(this.attr('value'));
+       if (dijit.byId("feedEditDlg"))
+               dijit.byId("feedEditDlg").destroyRecursive();
 
-                                                       /* Form.serialize ignores unchecked checkboxes */
+       new Ajax.Request("backend.php", {
+               parameters: query,
+               onComplete: function (transport) {
 
-                                                       if (!query.match("&private=") &&
-                                                                       this.getChildByName('private').attr('disabled') == false) {
-                                                               query = query + "&private=false";
-                                                       }
+                       notify("");
 
-                                                       try {
-                                                               if (!query.match("&cache_images=") &&
-                                                                               this.getChildByName('cache_images').attr('disabled') == false) {
-                                                                       query = query + "&cache_images=false";
-                                                               }
-                                                       } catch (e) { }
-
-                                                       try {
-                                                               if (!query.match("&hide_images=") &&
-                                                                               this.getChildByName('hide_images').attr('disabled') == false) {
-                                                                       query = query + "&hide_images=false";
-                                                               }
-                                                       } catch (e) { }
-
-                                                       if (!query.match("&include_in_digest=") &&
-                                                                       this.getChildByName('include_in_digest').attr('disabled') == false) {
-                                                               query = query + "&include_in_digest=false";
+                       var dialog = new dijit.Dialog({
+                               id: "feedEditDlg",
+                               title: __("Edit Multiple Feeds"),
+                               style: "width: 600px",
+                               getChildByName: function (name) {
+                                       var rv = null;
+                                       this.getChildren().each(
+                                               function (child) {
+                                                       if (child.name == name) {
+                                                               rv = child;
+                                                               return;
                                                        }
+                                               });
+                                       return rv;
+                               },
+                               toggleField: function (checkbox, elem, label) {
+                                       this.getChildByName(elem).attr('disabled', !checkbox.checked);
+
+                                       if ($(label))
+                                               if (checkbox.checked)
+                                                       $(label).removeClassName('insensitive');
+                                               else
+                                                       $(label).addClassName('insensitive');
+
+                               },
+                               execute: function () {
+                                       if (this.validate() && confirm(__("Save changes to selected feeds?"))) {
+                                               var query = dojo.objectToQuery(this.attr('value'));
+
+                                               /* Form.serialize ignores unchecked checkboxes */
+
+                                               if (!query.match("&private=") &&
+                                                       this.getChildByName('private').attr('disabled') == false) {
+                                                       query = query + "&private=false";
+                                               }
 
-                                                       if (!query.match("&always_display_enclosures=") &&
-                                                                       this.getChildByName('always_display_enclosures').attr('disabled') == false) {
-                                                               query = query + "&always_display_enclosures=false";
+                                               try {
+                                                       if (!query.match("&cache_images=") &&
+                                                               this.getChildByName('cache_images').attr('disabled') == false) {
+                                                               query = query + "&cache_images=false";
                                                        }
+                                               } catch (e) {
+                                               }
 
-                                                       if (!query.match("&mark_unread_on_update=") &&
-                                                                       this.getChildByName('mark_unread_on_update').attr('disabled') == false) {
-                                                               query = query + "&mark_unread_on_update=false";
+                                               try {
+                                                       if (!query.match("&hide_images=") &&
+                                                               this.getChildByName('hide_images').attr('disabled') == false) {
+                                                               query = query + "&hide_images=false";
                                                        }
+                                               } catch (e) {
+                                               }
 
-                                                       console.log(query);
+                                               if (!query.match("&include_in_digest=") &&
+                                                       this.getChildByName('include_in_digest').attr('disabled') == false) {
+                                                       query = query + "&include_in_digest=false";
+                                               }
 
-                                                       notify_progress("Saving data...", true);
+                                               if (!query.match("&always_display_enclosures=") &&
+                                                       this.getChildByName('always_display_enclosures').attr('disabled') == false) {
+                                                       query = query + "&always_display_enclosures=false";
+                                               }
 
-                                                       new Ajax.Request("backend.php", {
-                                                               parameters: query,
-                                                               onComplete: function(transport) {
-                                                                       dialog.hide();
-                                                                       updateFeedList();
-                                                       }});
+                                               if (!query.match("&mark_unread_on_update=") &&
+                                                       this.getChildByName('mark_unread_on_update').attr('disabled') == false) {
+                                                       query = query + "&mark_unread_on_update=false";
                                                }
-                                       },
-                                       content: transport.responseText});
 
-                                       dialog.show();
+                                               console.log(query);
 
-                       } });
+                                               notify_progress("Saving data...", true);
 
-       } catch (e) {
-               exception_error("editSelectedFeeds", e);
-       }
-}
+                                               new Ajax.Request("backend.php", {
+                                                       parameters: query,
+                                                       onComplete: function (transport) {
+                                                               dialog.hide();
+                                                               updateFeedList();
+                                                       }
+                                               });
+                                       }
+                               },
+                               content: transport.responseText
+                       });
 
-function opmlImportComplete(iframe) {
-       try {
-               if (!iframe.contentDocument.body.innerHTML) return false;
+                       dialog.show();
 
-               Element.show(iframe);
-
-               notify('');
-
-               if (dijit.byId('opmlImportDlg'))
-                       dijit.byId('opmlImportDlg').destroyRecursive();
-
-               var content = iframe.contentDocument.body.innerHTML;
-
-               dialog = new dijit.Dialog({
-                       id: "opmlImportDlg",
-                       title: __("OPML Import"),
-                       style: "width: 600px",
-                       onCancel: function() {
-                               updateFeedList();
-                               updateFilterList();
-                               updateLabelList();
-                       },
-                       execute: function() {
-                               updateFeedList();
-                               updateFilterList();
-                               updateLabelList();
-                               this.hide();
-                       },
-                       content: content});
+               }
+       });
+}
 
-               dialog.show();
+function opmlImportComplete(iframe) {
+       if (!iframe.contentDocument.body.innerHTML) return false;
+
+       Element.show(iframe);
+
+       notify('');
+
+       if (dijit.byId('opmlImportDlg'))
+               dijit.byId('opmlImportDlg').destroyRecursive();
+
+       var content = iframe.contentDocument.body.innerHTML;
+
+       dialog = new dijit.Dialog({
+               id: "opmlImportDlg",
+               title: __("OPML Import"),
+               style: "width: 600px",
+               onCancel: function () {
+                       updateFeedList();
+                       updateFilterList();
+                       updateLabelList();
+               },
+               execute: function () {
+                       updateFeedList();
+                       updateFilterList();
+                       updateLabelList();
+                       this.hide();
+               },
+               content: content
+       });
 
-       } catch (e) {
-               exception_error("opmlImportComplete", e);
-       }
+       dialog.show();
 }
 
 function opmlImport() {
@@ -854,142 +814,131 @@ function updateSystemList() {
 }
 
 function selectTab(id, noupdate, method) {
-       try {
-               if (!noupdate) {
-                       notify_progress("Loading, please wait...");
-
-                       if (id == "feedConfig") {
-                               updateFeedList();
-                       } else if (id == "filterConfig") {
-                               updateFilterList();
-                       } else if (id == "labelConfig") {
-                               updateLabelList();
-                       } else if (id == "genConfig") {
-                               updatePrefsList();
-                       } else if (id == "userConfig") {
-                               updateUsersList();
-                       } else if (id == "systemConfig") {
-                               updateSystemList();
-                       }
-
-                       var tab = dijit.byId(id + "Tab");
-                       dijit.byId("pref-tabs").selectChild(tab);
+       if (!noupdate) {
+               notify_progress("Loading, please wait...");
 
+               if (id == "feedConfig") {
+                       updateFeedList();
+               } else if (id == "filterConfig") {
+                       updateFilterList();
+               } else if (id == "labelConfig") {
+                       updateLabelList();
+               } else if (id == "genConfig") {
+                       updatePrefsList();
+               } else if (id == "userConfig") {
+                       updateUsersList();
+               } else if (id == "systemConfig") {
+                       updateSystemList();
                }
 
-       } catch (e) {
-               exception_error("selectTab", e);
+               var tab = dijit.byId(id + "Tab");
+               dijit.byId("pref-tabs").selectChild(tab);
+
        }
 }
 
 function init_second_stage() {
-       try {
-
-               document.onkeydown = pref_hotkey_handler;
-               loading_set_progress(50);
-               notify("");
-
-               var tab = getURLParam('tab');
-
-               if (tab) {
-                       tab = dijit.byId(tab + "Tab");
-                       if (tab) dijit.byId("pref-tabs").selectChild(tab);
-               }
+       document.onkeydown = pref_hotkey_handler;
+       loading_set_progress(50);
+       notify("");
 
-               var method = getURLParam('method');
+       var tab = getURLParam('tab');
 
-               if (method == 'editFeed') {
-                       var param = getURLParam('methodparam');
+       if (tab) {
+               tab = dijit.byId(tab + "Tab");
+               if (tab) dijit.byId("pref-tabs").selectChild(tab);
+       }
 
-                       window.setTimeout(function() { editFeed(param) }, 100);
-               }
+       var method = getURLParam('method');
 
-               setTimeout(hotkey_prefix_timeout, 5*1000);
+       if (method == 'editFeed') {
+               var param = getURLParam('methodparam');
 
-       } catch (e) {
-               exception_error("init_second_stage", e);
+               window.setTimeout(function() { editFeed(param) }, 100);
        }
+
+       setTimeout(hotkey_prefix_timeout, 5*1000);
 }
 
 function init() {
+       window.onerror = function (message, filename, lineno, colno, error) {
+               report_error(message, filename, lineno, colno, error);
+       };
+
+       require(["dojo/_base/kernel",
+               "dojo/ready",
+               "dojo/parser",
+               "dojo/_base/loader",
+               "dojo/_base/html",
+               "dijit/ColorPalette",
+               "dijit/Dialog",
+               "dijit/form/Button",
+               "dijit/form/CheckBox",
+               "dijit/form/DropDownButton",
+               "dijit/form/FilteringSelect",
+               "dijit/form/Form",
+               "dijit/form/RadioButton",
+               "dijit/form/ComboButton",
+               "dijit/form/Select",
+               "dijit/form/SimpleTextarea",
+               "dijit/form/TextBox",
+               "dijit/form/ValidationTextBox",
+               "dijit/InlineEditBox",
+               "dijit/layout/AccordionContainer",
+               "dijit/layout/AccordionPane",
+               "dijit/layout/BorderContainer",
+               "dijit/layout/ContentPane",
+               "dijit/layout/TabContainer",
+               "dijit/Menu",
+               "dijit/ProgressBar",
+               "dijit/Toolbar",
+               "dijit/Tree",
+               "dijit/tree/dndSource",
+               "dojo/data/ItemFileWriteStore",
+               "fox/PrefFeedTree",
+               "fox/PrefFilterTree",
+               "fox/PrefLabelTree"], function (dojo, ready, parser) {
+
+               ready(function () {
+                       try {
+                               parser.parse();
+
+                               loading_set_progress(50);
+
+                               var clientTzOffset = new Date().getTimezoneOffset() * 60;
 
-       try {
-
-               require(["dojo/_base/kernel",
-                       "dojo/ready",
-                       "dojo/parser",
-                       "dojo/_base/loader",
-                       "dojo/_base/html",
-                       "dijit/ColorPalette",
-                       "dijit/Dialog",
-                       "dijit/form/Button",
-                       "dijit/form/CheckBox",
-                       "dijit/form/DropDownButton",
-                       "dijit/form/FilteringSelect",
-                       "dijit/form/Form",
-                       "dijit/form/RadioButton",
-                       "dijit/form/ComboButton",
-                       "dijit/form/Select",
-                       "dijit/form/SimpleTextarea",
-                       "dijit/form/TextBox",
-                       "dijit/form/ValidationTextBox",
-                       "dijit/InlineEditBox",
-                       "dijit/layout/AccordionContainer",
-                       "dijit/layout/AccordionPane",
-                       "dijit/layout/BorderContainer",
-                       "dijit/layout/ContentPane",
-                       "dijit/layout/TabContainer",
-                       "dijit/Menu",
-                       "dijit/ProgressBar",
-                       "dijit/Toolbar",
-                       "dijit/Tree",
-                       "dijit/tree/dndSource",
-                       "dojo/data/ItemFileWriteStore",
-                       "fox/PrefFeedTree",
-                       "fox/PrefFilterTree",
-                       "fox/PrefLabelTree" ], function (dojo, ready, parser) {
-
-                               ready(function() {
-                                       parser.parse();
-
-                                       loading_set_progress(50);
-
-                                       var clientTzOffset = new Date().getTimezoneOffset() * 60;
-
-                                       new Ajax.Request("backend.php", {
-                                               parameters: {op: "rpc", method: "sanityCheck",
-                                                       clientTzOffset: clientTzOffset },
-                                               onComplete: function(transport) {
-                                                       backend_sanity_check_callback(transport);
-                                               } });
+                               new Ajax.Request("backend.php", {
+                                       parameters: {
+                                               op: "rpc", method: "sanityCheck",
+                                               clientTzOffset: clientTzOffset
+                                       },
+                                       onComplete: function (transport) {
+                                               backend_sanity_check_callback(transport);
+                                       }
                                });
-                       });
-
-       } catch (e) {
-               exception_error("init", e);
-       }
+                       } catch (e) {
+                               exception_error(e);
+                       }
+               });
+       });
 }
 
-function validatePrefsReset() {
-       try {
-               var ok = confirm(__("Reset to defaults?"));
 
-               if (ok) {
+function validatePrefsReset() {
+       var ok = confirm(__("Reset to defaults?"));
 
-                       query = "?op=pref-prefs&method=resetconfig";
-                       console.log(query);
+       if (ok) {
 
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
-                                       updatePrefsList();
-                                       notify_info(transport.responseText);
-                               } });
+               query = "?op=pref-prefs&method=resetconfig";
+               console.log(query);
 
-               }
+               new Ajax.Request("backend.php", {
+                       parameters: query,
+                       onComplete: function(transport) {
+                               updatePrefsList();
+                               notify_info(transport.responseText);
+                       } });
 
-       } catch (e) {
-               exception_error("validatePrefsReset", e);
        }
 
        return false;
@@ -997,71 +946,70 @@ function validatePrefsReset() {
 }
 
 function pref_hotkey_handler(e) {
-       try {
 
-               if (e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA") return;
+       if (e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA") return;
 
-               var keycode = false;
-               var shift_key = false;
+       var keycode = false;
+       var shift_key = false;
 
-               var cmdline = $('cmdline');
+       var cmdline = $('cmdline');
 
-               try {
-                       shift_key = e.shiftKey;
-               } catch (e) {
+       try {
+               shift_key = e.shiftKey;
+       } catch (e) {
 
-               }
+       }
 
-               if (window.event) {
-                       keycode = window.event.keyCode;
-               } else if (e) {
-                       keycode = e.which;
-               }
+       if (window.event) {
+               keycode = window.event.keyCode;
+       } else if (e) {
+               keycode = e.which;
+       }
 
-               var keychar = String.fromCharCode(keycode);
+       var keychar = String.fromCharCode(keycode);
 
-               if (keycode == 27) { // escape
-                       hotkey_prefix = false;
-               }
+       if (keycode == 27) { // escape
+               hotkey_prefix = false;
+       }
 
-               if (keycode == 16) return; // ignore lone shift
-               if (keycode == 17) return; // ignore lone ctrl
+       if (keycode == 16) return; // ignore lone shift
+       if (keycode == 17) return; // ignore lone ctrl
 
-               if (!shift_key) keychar = keychar.toLowerCase();
+       if (!shift_key) keychar = keychar.toLowerCase();
 
-               var hotkeys = getInitParam("hotkeys");
+       var hotkeys = getInitParam("hotkeys");
 
-               if (!hotkey_prefix && hotkeys[0].indexOf(keychar) != -1) {
+       if (!hotkey_prefix && hotkeys[0].indexOf(keychar) != -1) {
 
-                       var date = new Date();
-                       var ts = Math.round(date.getTime() / 1000);
+               var date = new Date();
+               var ts = Math.round(date.getTime() / 1000);
 
-                       hotkey_prefix = keychar;
-                       hotkey_prefix_pressed = ts;
+               hotkey_prefix = keychar;
+               hotkey_prefix_pressed = ts;
 
-                       cmdline.innerHTML = keychar;
-                       Element.show(cmdline);
+               cmdline.innerHTML = keychar;
+               Element.show(cmdline);
 
-                       return true;
-               }
+               return true;
+       }
 
-               Element.hide(cmdline);
+       Element.hide(cmdline);
 
-               var hotkey = keychar.search(/[a-zA-Z0-9]/) != -1 ? keychar : "(" + keycode + ")";
-               hotkey = hotkey_prefix ? hotkey_prefix + " " + hotkey : hotkey;
-               hotkey_prefix = false;
+       var hotkey = keychar.search(/[a-zA-Z0-9]/) != -1 ? keychar : "(" + keycode + ")";
+       hotkey = hotkey_prefix ? hotkey_prefix + " " + hotkey : hotkey;
+       hotkey_prefix = false;
 
-               var hotkey_action = false;
-               var hotkeys = getInitParam("hotkeys");
+       var hotkey_action = false;
+       var hotkeys = getInitParam("hotkeys");
 
-               for (sequence in hotkeys[1]) {
-                       if (sequence == hotkey) {
-                               hotkey_action = hotkeys[1][sequence];
-                               break;
-                       }
+       for (sequence in hotkeys[1]) {
+               if (sequence == hotkey) {
+                       hotkey_action = hotkeys[1][sequence];
+                       break;
                }
+       }
 
-               switch (hotkey_action) {
+       switch (hotkey_action) {
                case "feed_subscribe":
                        quickAddFeed();
                        return false;
@@ -1076,34 +1024,26 @@ function pref_hotkey_handler(e) {
                        return false;
                default:
                        console.log("unhandled action: " + hotkey_action + "; hotkey: " + hotkey);
-               }
-
-       } catch (e) {
-               exception_error("hotkey_handler", e);
        }
 }
 
 function removeCategory(id, item) {
-       try {
 
-               var ok = confirm(__("Remove category %s? Any nested feeds would be placed into Uncategorized.").replace("%s", item.name));
+       var ok = confirm(__("Remove category %s? Any nested feeds would be placed into Uncategorized.").replace("%s", item.name));
 
-               if (ok) {
-                       var query = "?op=pref-feeds&method=removeCat&ids="+
-                               param_escape(id);
+       if (ok) {
+               var query = "?op=pref-feeds&method=removeCat&ids=" +
+                       param_escape(id);
 
-                       notify_progress("Removing category...");
+               notify_progress("Removing category...");
 
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
-                                       notify('');
-                                       updateFeedList();
-                               } });
+               new Ajax.Request("backend.php", {
+                       parameters: query,
+                       onComplete: function (transport) {
+                               notify('');
+                               updateFeedList();
                        }
-
-       } catch (e) {
-               exception_error("removeCategory", e);
+               });
        }
 }
 
@@ -1136,171 +1076,149 @@ function removeSelectedCategories() {
 }
 
 function createCategory() {
-       try {
-               var title = prompt(__("Category title:"));
+       var title = prompt(__("Category title:"));
 
-               if (title) {
+       if (title) {
 
-                       notify_progress("Creating category...");
+               notify_progress("Creating category...");
 
-                       var query = "?op=pref-feeds&method=addCat&cat=" +
-                               param_escape(title);
+               var query = "?op=pref-feeds&method=addCat&cat=" +
+                       param_escape(title);
 
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
-                                       notify('');
-                                       updateFeedList();
-                               } });
-               }
-
-       } catch (e) {
-               exception_error("createCategory", e);
+               new Ajax.Request("backend.php", {
+                       parameters: query,
+                       onComplete: function (transport) {
+                               notify('');
+                               updateFeedList();
+                       }
+               });
        }
 }
 
 function showInactiveFeeds() {
-       try {
-               var query = "backend.php?op=pref-feeds&method=inactiveFeeds";
+       var query = "backend.php?op=pref-feeds&method=inactiveFeeds";
 
-               if (dijit.byId("inactiveFeedsDlg"))
-                       dijit.byId("inactiveFeedsDlg").destroyRecursive();
+       if (dijit.byId("inactiveFeedsDlg"))
+               dijit.byId("inactiveFeedsDlg").destroyRecursive();
 
-               dialog = new dijit.Dialog({
-                       id: "inactiveFeedsDlg",
-                       title: __("Feeds without recent updates"),
-                       style: "width: 600px",
-                       getSelectedFeeds: function() {
-                               return getSelectedTableRowIds("prefInactiveFeedList");
-                       },
-                       removeSelected: function() {
-                               var sel_rows = this.getSelectedFeeds();
-
-                               console.log(sel_rows);
+       dialog = new dijit.Dialog({
+               id: "inactiveFeedsDlg",
+               title: __("Feeds without recent updates"),
+               style: "width: 600px",
+               getSelectedFeeds: function () {
+                       return getSelectedTableRowIds("prefInactiveFeedList");
+               },
+               removeSelected: function () {
+                       var sel_rows = this.getSelectedFeeds();
 
-                               if (sel_rows.length > 0) {
-                                       var ok = confirm(__("Remove selected feeds?"));
+                       console.log(sel_rows);
 
-                                       if (ok) {
-                                               notify_progress("Removing selected feeds...", true);
+                       if (sel_rows.length > 0) {
+                               var ok = confirm(__("Remove selected feeds?"));
 
-                                               var query = "?op=pref-feeds&method=remove&ids="+
-                                                       param_escape(sel_rows.toString());
+                               if (ok) {
+                                       notify_progress("Removing selected feeds...", true);
 
-                                               new Ajax.Request("backend.php", {
-                                                       parameters: query,
-                                                       onComplete: function(transport) {
-                                                               notify('');
-                                                               dialog.hide();
-                                                               updateFeedList();
-                                                       } });
-                                       }
+                                       var query = "?op=pref-feeds&method=remove&ids=" +
+                                               param_escape(sel_rows.toString());
 
-                               } else {
-                                       alert(__("No feeds are selected."));
-                               }
-                       },
-                       execute: function() {
-                               if (this.validate()) {
+                                       new Ajax.Request("backend.php", {
+                                               parameters: query,
+                                               onComplete: function (transport) {
+                                                       notify('');
+                                                       dialog.hide();
+                                                       updateFeedList();
+                                               }
+                                       });
                                }
-                       },
-                       href: query});
-
-               dialog.show();
 
-       } catch (e) {
-               exception_error("showInactiveFeeds", e);
-       }
+                       } else {
+                               alert(__("No feeds are selected."));
+                       }
+               },
+               execute: function () {
+                       if (this.validate()) {
+                       }
+               },
+               href: query
+       });
 
+       dialog.show();
 }
 
 function opmlRegenKey() {
+       var ok = confirm(__("Replace current OPML publishing address with a new one?"));
 
-       try {
-               var ok = confirm(__("Replace current OPML publishing address with a new one?"));
-
-               if (ok) {
+       if (ok) {
 
-                       notify_progress("Trying to change address...", true);
+               notify_progress("Trying to change address...", true);
 
-                       var query = "?op=pref-feeds&method=regenOPMLKey";
+               var query = "?op=pref-feeds&method=regenOPMLKey";
 
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
-                                               var reply = JSON.parse(transport.responseText);
+               new Ajax.Request("backend.php", {
+                       parameters: query,
+                       onComplete: function (transport) {
+                               var reply = JSON.parse(transport.responseText);
 
-                                               var new_link = reply.link;
+                               var new_link = reply.link;
 
-                                               var e = $('pub_opml_url');
+                               var e = $('pub_opml_url');
 
-                                               if (new_link) {
-                                                       e.href = new_link;
-                                                       e.innerHTML = new_link;
+                               if (new_link) {
+                                       e.href = new_link;
+                                       e.innerHTML = new_link;
 
-                                                       new Effect.Highlight(e);
+                                       new Effect.Highlight(e);
 
-                                                       notify('');
+                                       notify('');
 
-                                               } else {
-                                                       notify_error("Could not change feed URL.");
-                                               }
-                               } });
-               }
-       } catch (e) {
-               exception_error("opmlRegenKey", e);
+                               } else {
+                                       notify_error("Could not change feed URL.");
+                               }
+                       }
+               });
        }
        return false;
 }
 
 function feedActionChange() {
-       try {
-               var chooser = $("feedActionChooser");
-               var opid = chooser[chooser.selectedIndex].value;
+       var chooser = $("feedActionChooser");
+       var opid = chooser[chooser.selectedIndex].value;
 
-               chooser.selectedIndex = 0;
-               feedActionGo(opid);
-       } catch (e) {
-               exception_error("feedActionChange", e);
-       }
+       chooser.selectedIndex = 0;
+       feedActionGo(opid);
 }
 
 function feedActionGo(op) {
-       try {
-               if (op == "facEdit") {
-
-                       var rows = getSelectedFeeds();
+       if (op == "facEdit") {
 
-                       if (rows.length > 1) {
-                               editSelectedFeeds();
-                       } else {
-                               editSelectedFeed();
-                       }
-               }
-
-               if (op == "facClear") {
-                       clearSelectedFeeds();
-               }
+               var rows = getSelectedFeeds();
 
-               if (op == "facPurge") {
-                       purgeSelectedFeeds();
+               if (rows.length > 1) {
+                       editSelectedFeeds();
+               } else {
+                       editSelectedFeed();
                }
+       }
 
-               if (op == "facEditCats") {
-                       editFeedCats();
-               }
+       if (op == "facClear") {
+               clearSelectedFeeds();
+       }
 
-               if (op == "facRescore") {
-                       rescoreSelectedFeeds();
-               }
+       if (op == "facPurge") {
+               purgeSelectedFeeds();
+       }
 
-               if (op == "facUnsubscribe") {
-                       removeSelectedFeeds();
-               }
+       if (op == "facEditCats") {
+               editFeedCats();
+       }
 
-       } catch (e) {
-               exception_error("feedActionGo", e);
+       if (op == "facRescore") {
+               rescoreSelectedFeeds();
+       }
 
+       if (op == "facUnsubscribe") {
+               removeSelectedFeeds();
        }
 }
 
@@ -1365,127 +1283,122 @@ function rescore_all_feeds() {
 }
 
 function labelColorReset() {
-       try {
-               var labels = getSelectedLabels();
-
-               if (labels.length > 0) {
-                       var ok = confirm(__("Reset selected labels to default colors?"));
+       var labels = getSelectedLabels();
 
-                       if (ok) {
-                               var query = "?op=pref-labels&method=colorreset&ids="+
-                                       param_escape(labels.toString());
+       if (labels.length > 0) {
+               var ok = confirm(__("Reset selected labels to default colors?"));
 
-                               new Ajax.Request("backend.php", {
-                                       parameters: query,
-                                       onComplete: function(transport) {
-                                               updateLabelList();
-                                       } });
-                       }
+               if (ok) {
+                       var query = "?op=pref-labels&method=colorreset&ids=" +
+                               param_escape(labels.toString());
 
-               } else {
-                       alert(__("No labels are selected."));
+                       new Ajax.Request("backend.php", {
+                               parameters: query,
+                               onComplete: function (transport) {
+                                       updateLabelList();
+                               }
+                       });
                }
 
-       } catch (e) {
-               exception_error("labelColorReset", e);
+       } else {
+               alert(__("No labels are selected."));
        }
 }
 
-
 function inPreferences() {
        return true;
 }
 
 function editProfiles() {
-       try {
 
-               if (dijit.byId("profileEditDlg"))
-                       dijit.byId("profileEditDlg").destroyRecursive();
+       if (dijit.byId("profileEditDlg"))
+               dijit.byId("profileEditDlg").destroyRecursive();
 
-               var query = "backend.php?op=pref-prefs&method=editPrefProfiles";
+       var query = "backend.php?op=pref-prefs&method=editPrefProfiles";
 
-               dialog = new dijit.Dialog({
-                       id: "profileEditDlg",
-                       title: __("Settings Profiles"),
-                       style: "width: 600px",
-                       getSelectedProfiles: function() {
-                               return getSelectedTableRowIds("prefFeedProfileList");
-                       },
-                       removeSelected: function() {
-                               var sel_rows = this.getSelectedProfiles();
+       dialog = new dijit.Dialog({
+               id: "profileEditDlg",
+               title: __("Settings Profiles"),
+               style: "width: 600px",
+               getSelectedProfiles: function () {
+                       return getSelectedTableRowIds("prefFeedProfileList");
+               },
+               removeSelected: function () {
+                       var sel_rows = this.getSelectedProfiles();
 
-                               if (sel_rows.length > 0) {
-                                       var ok = confirm(__("Remove selected profiles? Active and default profiles will not be removed."));
+                       if (sel_rows.length > 0) {
+                               var ok = confirm(__("Remove selected profiles? Active and default profiles will not be removed."));
 
-                                       if (ok) {
-                                               notify_progress("Removing selected profiles...", true);
+                               if (ok) {
+                                       notify_progress("Removing selected profiles...", true);
 
-                                               var query = "?op=rpc&method=remprofiles&ids="+
-                                                       param_escape(sel_rows.toString());
+                                       var query = "?op=rpc&method=remprofiles&ids=" +
+                                               param_escape(sel_rows.toString());
 
-                                               new Ajax.Request("backend.php", {
-                                                       parameters: query,
-                                                       onComplete: function(transport) {
-                                                               notify('');
-                                                               editProfiles();
-                                                       } });
-
-                                       }
+                                       new Ajax.Request("backend.php", {
+                                               parameters: query,
+                                               onComplete: function (transport) {
+                                                       notify('');
+                                                       editProfiles();
+                                               }
+                                       });
 
-                               } else {
-                                       alert(__("No profiles are selected."));
                                }
-                       },
-                       activateProfile: function() {
-                               var sel_rows = this.getSelectedProfiles();
 
-                               if (sel_rows.length == 1) {
+                       } else {
+                               alert(__("No profiles are selected."));
+                       }
+               },
+               activateProfile: function () {
+                       var sel_rows = this.getSelectedProfiles();
 
-                                       var ok = confirm(__("Activate selected profile?"));
+                       if (sel_rows.length == 1) {
 
-                                       if (ok) {
-                                               notify_progress("Loading, please wait...");
+                               var ok = confirm(__("Activate selected profile?"));
 
-                                               var query = "?op=rpc&method=setprofile&id="+
-                                                       param_escape(sel_rows.toString());
+                               if (ok) {
+                                       notify_progress("Loading, please wait...");
 
-                                               new Ajax.Request("backend.php", {
-                                                       parameters: query,
-                                                       onComplete: function(transport) {
-                                                               window.location.reload();
-                                                       } });
-                                       }
+                                       var query = "?op=rpc&method=setprofile&id=" +
+                                               param_escape(sel_rows.toString());
 
-                               } else {
-                                       alert(__("Please choose a profile to activate."));
+                                       new Ajax.Request("backend.php", {
+                                               parameters: query,
+                                               onComplete: function (transport) {
+                                                       window.location.reload();
+                                               }
+                                       });
                                }
-                       },
-                       addProfile: function() {
-                               if (this.validate()) {
-                                       notify_progress("Creating profile...", true);
 
-                                       var query = "?op=rpc&method=addprofile&title=" +
-                                               param_escape(dialog.attr('value').newprofile);
+                       } else {
+                               alert(__("Please choose a profile to activate."));
+                       }
+               },
+               addProfile: function () {
+                       if (this.validate()) {
+                               notify_progress("Creating profile...", true);
 
-                                       new Ajax.Request("backend.php", {
-                                               parameters: query,
-                                               onComplete: function(transport) {
-                                                       notify('');
-                                                       editProfiles();
-                                               } });
+                               var query = "?op=rpc&method=addprofile&title=" +
+                                       param_escape(dialog.attr('value').newprofile);
 
-                               }
-                       },
-                       execute: function() {
-                               if (this.validate()) {
-                               }
-                       },
-                       href: query});
+                               new Ajax.Request("backend.php", {
+                                       parameters: query,
+                                       onComplete: function (transport) {
+                                               notify('');
+                                               editProfiles();
+                                       }
+                               });
 
-               dialog.show();
-       } catch (e) {
-               exception_error("editProfiles", e);
-       }
+                       }
+               },
+               execute: function () {
+                       if (this.validate()) {
+                       }
+               },
+               href: query
+       });
+
+       dialog.show();
 }
 
 function activatePrefProfile() {
@@ -1536,187 +1449,159 @@ function clearFeedAccessKeys() {
 }
 
 function resetFilterOrder() {
-       try {
-               notify_progress("Loading, please wait...");
+       notify_progress("Loading, please wait...");
 
-               new Ajax.Request("backend.php", {
-                       parameters: "?op=pref-filters&method=filtersortreset",
-                       onComplete: function(transport) {
-                               updateFilterList();
-                       } });
-
-
-       } catch (e) {
-               exception_error("resetFilterOrder");
-       }
+       new Ajax.Request("backend.php", {
+               parameters: "?op=pref-filters&method=filtersortreset",
+               onComplete: function (transport) {
+                       updateFilterList();
+               }
+       });
 }
 
 
-function resetFeedOrder() {
-       try {
-               notify_progress("Loading, please wait...");
-
-               new Ajax.Request("backend.php", {
-                       parameters: "?op=pref-feeds&method=feedsortreset",
-                       onComplete: function(transport) {
-                               updateFeedList();
-                       } });
 
+function resetFeedOrder() {
+       notify_progress("Loading, please wait...");
 
-       } catch (e) {
-               exception_error("resetFeedOrder");
-       }
+       new Ajax.Request("backend.php", {
+               parameters: "?op=pref-feeds&method=feedsortreset",
+               onComplete: function (transport) {
+                       updateFeedList();
+               }
+       });
 }
 
 function resetCatOrder() {
-       try {
-               notify_progress("Loading, please wait...");
-
-               new Ajax.Request("backend.php", {
-                       parameters: "?op=pref-feeds&method=catsortreset",
-                       onComplete: function(transport) {
-                               updateFeedList();
-                       } });
-
+       notify_progress("Loading, please wait...");
 
-       } catch (e) {
-               exception_error("resetCatOrder");
-       }
+       new Ajax.Request("backend.php", {
+               parameters: "?op=pref-feeds&method=catsortreset",
+               onComplete: function (transport) {
+                       updateFeedList();
+               }
+       });
 }
 
 function editCat(id, item, event) {
-       try {
-               var new_name = prompt(__('Rename category to:'), item.name);
+       var new_name = prompt(__('Rename category to:'), item.name);
 
-               if (new_name && new_name != item.name) {
+       if (new_name && new_name != item.name) {
 
-                       notify_progress("Loading, please wait...");
+               notify_progress("Loading, please wait...");
 
-                       new Ajax.Request("backend.php", {
+               new Ajax.Request("backend.php", {
                        parameters: {
                                op: 'pref-feeds',
                                method: 'renamecat',
                                id: id,
                                title: new_name,
                        },
-                       onComplete: function(transport) {
-                               updateFeedList();
-                       } });
-               }
-
-       } catch (e) {
-               exception_error("editCat", e);
+                       onComplete: function (transport) {
+                               updateFeedList();
+                       }
+               });
        }
 }
 
 function editLabel(id, event) {
-       try {
-               var query = "backend.php?op=pref-labels&method=edit&id=" +
-                       param_escape(id);
-
-               if (dijit.byId("labelEditDlg"))
-                       dijit.byId("labelEditDlg").destroyRecursive();
-
-               dialog = new dijit.Dialog({
-                       id: "labelEditDlg",
-                       title: __("Label Editor"),
-                       style: "width: 600px",
-                       setLabelColor: function(id, fg, bg) {
-
-                               var kind = '';
-                               var color = '';
-
-                               if (fg && bg) {
-                                       kind = 'both';
-                               } else if (fg) {
-                                       kind = 'fg';
-                                       color = fg;
-                               } else if (bg) {
-                                       kind = 'bg';
-                                       color = bg;
-                               }
+       var query = "backend.php?op=pref-labels&method=edit&id=" +
+               param_escape(id);
+
+       if (dijit.byId("labelEditDlg"))
+               dijit.byId("labelEditDlg").destroyRecursive();
+
+       dialog = new dijit.Dialog({
+               id: "labelEditDlg",
+               title: __("Label Editor"),
+               style: "width: 600px",
+               setLabelColor: function (id, fg, bg) {
+
+                       var kind = '';
+                       var color = '';
+
+                       if (fg && bg) {
+                               kind = 'both';
+                       } else if (fg) {
+                               kind = 'fg';
+                               color = fg;
+                       } else if (bg) {
+                               kind = 'bg';
+                               color = bg;
+                       }
 
-                               var query = "?op=pref-labels&method=colorset&kind="+kind+
-                                       "&ids=" + param_escape(id) + "&fg=" + param_escape(fg) +
-                                       "&bg=" + param_escape(bg) + "&color=" + param_escape(color);
+                       var query = "?op=pref-labels&method=colorset&kind=" + kind +
+                               "&ids=" + param_escape(id) + "&fg=" + param_escape(fg) +
+                               "&bg=" + param_escape(bg) + "&color=" + param_escape(color);
 
-               //              console.log(query);
+                       //              console.log(query);
 
-                               var e = $("LICID-" + id);
+                       var e = $("LICID-" + id);
 
-                               if (e) {
-                                       if (fg) e.style.color = fg;
-                                       if (bg) e.style.backgroundColor = bg;
-                               }
-
-                               new Ajax.Request("backend.php", { parameters: query });
+                       if (e) {
+                               if (fg) e.style.color = fg;
+                               if (bg) e.style.backgroundColor = bg;
+                       }
 
-                               updateFilterList();
-                       },
-                       execute: function() {
-                               if (this.validate()) {
-                                       var caption = this.attr('value').caption;
-                                       var fg_color = this.attr('value').fg_color;
-                                       var bg_color = this.attr('value').bg_color;
-                                       var query = dojo.objectToQuery(this.attr('value'));
+                       new Ajax.Request("backend.php", {parameters: query});
 
-                                       dijit.byId('labelTree').setNameById(id, caption);
-                                       this.setLabelColor(id, fg_color, bg_color);
-                                       this.hide();
+                       updateFilterList();
+               },
+               execute: function () {
+                       if (this.validate()) {
+                               var caption = this.attr('value').caption;
+                               var fg_color = this.attr('value').fg_color;
+                               var bg_color = this.attr('value').bg_color;
+                               var query = dojo.objectToQuery(this.attr('value'));
 
-                                       new Ajax.Request("backend.php", {
-                                               parameters: query,
-                                               onComplete: function(transport) {
-                                                       updateFilterList();
-                                       } });
-                               }
-                       },
-                       href: query});
+                               dijit.byId('labelTree').setNameById(id, caption);
+                               this.setLabelColor(id, fg_color, bg_color);
+                               this.hide();
 
-               dialog.show();
+                               new Ajax.Request("backend.php", {
+                                       parameters: query,
+                                       onComplete: function (transport) {
+                                               updateFilterList();
+                                       }
+                               });
+                       }
+               },
+               href: query
+       });
 
-       } catch (e) {
-               exception_error("editLabel", e);
-       }
+       dialog.show();
 }
 
 
 function customizeCSS() {
-       try {
-               var query = "backend.php?op=pref-prefs&method=customizeCSS";
-
-               if (dijit.byId("cssEditDlg"))
-                       dijit.byId("cssEditDlg").destroyRecursive();
+       var query = "backend.php?op=pref-prefs&method=customizeCSS";
 
-               dialog = new dijit.Dialog({
-                       id: "cssEditDlg",
-                       title: __("Customize stylesheet"),
-                       style: "width: 600px",
-                       execute: function() {
-                               notify_progress('Saving data...', true);
-                               new Ajax.Request("backend.php", {
-                                       parameters: dojo.objectToQuery(this.attr('value')),
-                                       onComplete: function(transport) {
-                                               notify('');
-                                               window.location.reload();
-                               } });
+       if (dijit.byId("cssEditDlg"))
+               dijit.byId("cssEditDlg").destroyRecursive();
 
-                       },
-                       href: query});
+       dialog = new dijit.Dialog({
+               id: "cssEditDlg",
+               title: __("Customize stylesheet"),
+               style: "width: 600px",
+               execute: function () {
+                       notify_progress('Saving data...', true);
+                       new Ajax.Request("backend.php", {
+                               parameters: dojo.objectToQuery(this.attr('value')),
+                               onComplete: function (transport) {
+                                       notify('');
+                                       window.location.reload();
+                               }
+                       });
 
-               dialog.show();
+               },
+               href: query
+       });
 
-       } catch (e) {
-               exception_error("customizeCSS", e);
-       }
+       dialog.show();
 }
 
 function insertSSLserial(value) {
-       try {
-               dijit.byId("SSL_CERT_SERIAL").attr('value', value);
-       } catch (e) {
-               exception_error("insertSSLcerial", e);
-       }
+       dijit.byId("SSL_CERT_SERIAL").attr('value', value);
 }
 
 function gotoExportOpml(filename, settings) {
@@ -1726,70 +1611,48 @@ function gotoExportOpml(filename, settings) {
 
 
 function batchSubscribe() {
-       try {
-               var query = "backend.php?op=pref-feeds&method=batchSubscribe";
+       var query = "backend.php?op=pref-feeds&method=batchSubscribe";
 
-               // overlapping widgets
-               if (dijit.byId("batchSubDlg")) dijit.byId("batchSubDlg").destroyRecursive();
-               if (dijit.byId("feedAddDlg"))   dijit.byId("feedAddDlg").destroyRecursive();
+       // overlapping widgets
+       if (dijit.byId("batchSubDlg")) dijit.byId("batchSubDlg").destroyRecursive();
+       if (dijit.byId("feedAddDlg"))    dijit.byId("feedAddDlg").destroyRecursive();
 
-               var dialog = new dijit.Dialog({
-                       id: "batchSubDlg",
-                       title: __("Batch subscribe"),
-                       style: "width: 600px",
-                       execute: function() {
-                               if (this.validate()) {
-                                       console.log(dojo.objectToQuery(this.attr('value')));
+       var dialog = new dijit.Dialog({
+               id: "batchSubDlg",
+               title: __("Batch subscribe"),
+               style: "width: 600px",
+               execute: function () {
+                       if (this.validate()) {
+                               console.log(dojo.objectToQuery(this.attr('value')));
 
-                                       notify_progress(__("Subscribing to feeds..."), true);
+                               notify_progress(__("Subscribing to feeds..."), true);
 
-                                       new Ajax.Request("backend.php", {
-                                               parameters: dojo.objectToQuery(this.attr('value')),
-                                               onComplete: function(transport) {
-                                                       notify("");
-                                                       updateFeedList();
-                                                       dialog.hide();
-                                               } });
+                               new Ajax.Request("backend.php", {
+                                       parameters: dojo.objectToQuery(this.attr('value')),
+                                       onComplete: function (transport) {
+                                               notify("");
+                                               updateFeedList();
+                                               dialog.hide();
                                        }
-                       },
-                       href: query});
+                               });
+                       }
+               },
+               href: query
+       });
 
-               dialog.show();
-       } catch (e) {
-               exception_error("batchSubscribe", e);
-       }
+       dialog.show();
 }
 
-
-function toggleAdvancedPrefs() {
-       try {
+function clearPluginData(name) {
+       if (confirm(__("Clear stored data for this plugin?"))) {
                notify_progress("Loading, please wait...");
 
                new Ajax.Request("backend.php", {
-                       parameters: "?op=pref-prefs&method=toggleadvanced",
+                       parameters: "?op=pref-prefs&method=clearplugindata&name=" + param_escape(name),
                        onComplete: function(transport) {
+                               notify('');
                                updatePrefsList();
                        } });
-
-       } catch (e) {
-               exception_error("toggleAdvancedPrefs", e);
-       }
-}
-
-function clearPluginData(name) {
-       try {
-               if (confirm(__("Clear stored data for this plugin?"))) {
-                       notify_progress("Loading, please wait...");
-
-                       new Ajax.Request("backend.php", {
-                               parameters: "?op=pref-prefs&method=clearplugindata&name=" + param_escape(name),
-                               onComplete: function(transport) {
-                                       notify('');
-                                       updatePrefsList();
-                               } });
-               }
-       } catch (e) {
-               exception_error("clearPluginData", e);
        }
 }
 
index f481d39a3872ef6b588ba9db1e058b93dba3a457..ed305a8bbd9d19758fa9d4c7c390f1f4f60def93 100644 (file)
@@ -21,108 +21,92 @@ function activeFeedIsCat() {
 }
 
 function getActiveFeedId() {
-       try {
-               return _active_feed_id;
-       } catch (e) {
-               exception_error("getActiveFeedId", e);
-       }
+       return _active_feed_id;
 }
 
 function setActiveFeedId(id, is_cat) {
-       try {
-               hash_set('f', id);
-               hash_set('c', is_cat ? 1 : 0);
+       hash_set('f', id);
+       hash_set('c', is_cat ? 1 : 0);
 
-               _active_feed_id = id;
-               _active_feed_is_cat = is_cat;
+       _active_feed_id = id;
+       _active_feed_is_cat = is_cat;
 
-               $("headlines-frame").setAttribute("feed-id", id);
-               $("headlines-frame").setAttribute("is-cat", is_cat ? 1 : 0);
+       $("headlines-frame").setAttribute("feed-id", id);
+       $("headlines-frame").setAttribute("is-cat", is_cat ? 1 : 0);
 
-               selectFeed(id, is_cat);
+       selectFeed(id, is_cat);
 
-               PluginHost.run(PluginHost.HOOK_FEED_SET_ACTIVE, _active_article_id);
-       } catch (e) {
-               exception_error("setActiveFeedId", e);
-       }
+       PluginHost.run(PluginHost.HOOK_FEED_SET_ACTIVE, _active_article_id);
 }
 
 
 function updateFeedList() {
-       try {
 
-//             $("feeds-holder").innerHTML = "<div id=\"feedlistLoading\">" +
-//                     __("Loading, please wait...") + "</div>";
+       Element.show("feedlistLoading");
 
-               Element.show("feedlistLoading");
-               
-               resetCounterCache();
+       resetCounterCache();
 
-               if (dijit.byId("feedTree")) {
-                       dijit.byId("feedTree").destroyRecursive();
-               }
+       if (dijit.byId("feedTree")) {
+               dijit.byId("feedTree").destroyRecursive();
+       }
 
-               var store = new dojo.data.ItemFileWriteStore({
+       var store = new dojo.data.ItemFileWriteStore({
          url: "backend.php?op=pref_feeds&method=getfeedtree&mode=2"});
 
-               var treeModel = new fox.FeedStoreModel({
-                       store: store,
-                       query: {
-                               "type": getInitParam('enable_feed_cats') == 1 ? "category" : "feed"
-                       },
-                       rootId: "root",
-                       rootLabel: "Feeds",
-                       childrenAttrs: ["items"]
-               });
-
-               var tree = new fox.FeedTree({
-               model: treeModel,
-               onClick: function (item, node) {
-                       var id = String(item.id);
-                       var is_cat = id.match("^CAT:");
-                       var feed = id.substr(id.indexOf(":")+1);
-                       viewfeed({feed: feed, is_cat: is_cat});
-                       return false;
+       var treeModel = new fox.FeedStoreModel({
+               store: store,
+               query: {
+                       "type": getInitParam('enable_feed_cats') == 1 ? "category" : "feed"
                },
-               openOnClick: false,
-               showRoot: false,
-               persist: true,
-               id: "feedTree",
-               }, "feedTree");
+               rootId: "root",
+               rootLabel: "Feeds",
+               childrenAttrs: ["items"]
+       });
+
+       var tree = new fox.FeedTree({
+       model: treeModel,
+       onClick: function (item, node) {
+               var id = String(item.id);
+               var is_cat = id.match("^CAT:");
+               var feed = id.substr(id.indexOf(":")+1);
+               viewfeed({feed: feed, is_cat: is_cat});
+               return false;
+       },
+       openOnClick: false,
+       showRoot: false,
+       persist: true,
+       id: "feedTree",
+       }, "feedTree");
 
 /*             var menu = new dijit.Menu({id: 'feedMenu'});
 
-               menu.addChild(new dijit.MenuItem({
+       menu.addChild(new dijit.MenuItem({
           label: "Simple menu item"
-               }));
+       }));
 
 //             menu.bindDomNode(tree.domNode); */
 
-               var tmph = dojo.connect(dijit.byId('feedMenu'), '_openMyself', function (event) {
-                       console.log(dijit.getEnclosingWidget(event.target));
-                       dojo.disconnect(tmph);
-               });
+       var tmph = dojo.connect(dijit.byId('feedMenu'), '_openMyself', function (event) {
+               console.log(dijit.getEnclosingWidget(event.target));
+               dojo.disconnect(tmph);
+       });
 
-               $("feeds-holder").appendChild(tree.domNode);
+       $("feeds-holder").appendChild(tree.domNode);
 
-               var tmph = dojo.connect(tree, 'onLoad', function() {
-                       dojo.disconnect(tmph);
-                       Element.hide("feedlistLoading");
+       var tmph = dojo.connect(tree, 'onLoad', function() {
+               dojo.disconnect(tmph);
+               Element.hide("feedlistLoading");
 
+               try {
                        feedlist_init();
 
-//                     var node = dijit.byId("feedTree")._itemNodesMap['FEED:-2'][0].domNode
-//                     menu.bindDomNode(node);
-
                        loading_set_progress(25);
-               });
-
-               tree.startup();
-
+               } catch (e) {
+                       exception_error(e);
+               }
+       });
 
-       } catch (e) {
-               exception_error("updateFeedList", e);
-       }
+       tree.startup();
 }
 
 function catchupAllFeeds() {
@@ -218,46 +202,49 @@ function genericSanityCheck() {
 
 
 function init() {
-       try {
-               //dojo.registerModulePath("fox", "../../js/");
-
-               require(["dojo/_base/kernel",
-                               "dojo/ready",
-                               "dojo/parser",
-                               "dojo/_base/loader",
-                               "dojo/_base/html",
-                               "dojo/query",
-                               "dijit/ProgressBar",
-                               "dijit/ColorPalette",
-                               "dijit/Dialog",
-                               "dijit/form/Button",
-                               "dijit/form/ComboButton",
-                               "dijit/form/CheckBox",
-                               "dijit/form/DropDownButton",
-                               "dijit/form/FilteringSelect",
-                               "dijit/form/Form",
-                               "dijit/form/RadioButton",
-                               "dijit/form/Select",
-                               "dijit/form/SimpleTextarea",
-                               "dijit/form/TextBox",
-                               "dijit/form/ComboBox",
-                               "dijit/form/ValidationTextBox",
-                               "dijit/InlineEditBox",
-                               "dijit/layout/AccordionContainer",
-                               "dijit/layout/BorderContainer",
-                               "dijit/layout/ContentPane",
-                               "dijit/layout/TabContainer",
-                               "dijit/PopupMenuItem",
-                               "dijit/Menu",
-                               "dijit/Toolbar",
-                               "dijit/Tree",
-                               "dijit/tree/dndSource",
-                               "dijit/tree/ForestStoreModel",
-                               "dojo/data/ItemFileWriteStore",
-                               "fox/FeedTree" ], function (dojo, ready, parser) {
-
-                               ready(function() {
 
+       window.onerror = function(message, filename, lineno, colno, error) {
+               report_error(message, filename, lineno, colno, error);
+       };
+
+       require(["dojo/_base/kernel",
+                       "dojo/ready",
+                       "dojo/parser",
+                       "dojo/_base/loader",
+                       "dojo/_base/html",
+                       "dojo/query",
+                       "dijit/ProgressBar",
+                       "dijit/ColorPalette",
+                       "dijit/Dialog",
+                       "dijit/form/Button",
+                       "dijit/form/ComboButton",
+                       "dijit/form/CheckBox",
+                       "dijit/form/DropDownButton",
+                       "dijit/form/FilteringSelect",
+                       "dijit/form/Form",
+                       "dijit/form/RadioButton",
+                       "dijit/form/Select",
+                       "dijit/form/SimpleTextarea",
+                       "dijit/form/TextBox",
+                       "dijit/form/ComboBox",
+                       "dijit/form/ValidationTextBox",
+                       "dijit/InlineEditBox",
+                       "dijit/layout/AccordionContainer",
+                       "dijit/layout/BorderContainer",
+                       "dijit/layout/ContentPane",
+                       "dijit/layout/TabContainer",
+                       "dijit/PopupMenuItem",
+                       "dijit/Menu",
+                       "dijit/Toolbar",
+                       "dijit/Tree",
+                       "dijit/tree/dndSource",
+                       "dijit/tree/ForestStoreModel",
+                       "dojo/data/ItemFileWriteStore",
+                       "fox/FeedTree" ], function (dojo, ready, parser) {
+
+                       ready(function() {
+
+                               try {
                                        parser.parse();
 
                                        if (!genericSanityCheck())
@@ -274,24 +261,25 @@ function init() {
 
                                        init_hotkey_actions();
 
-                                       new Ajax.Request("backend.php", {
-                                               parameters: {op: "rpc", method: "sanityCheck", hasAudio: hasAudio,
+                                       new Ajax.Request("backend.php", {
+                                               parameters: {
+                                                       op: "rpc", method: "sanityCheck", hasAudio: hasAudio,
                                                        hasMp3: hasMp3,
                                                        clientTzOffset: clientTzOffset,
-                                                       hasSandbox: hasSandbox},
-                                               onComplete: function(transport) {
+                                                       hasSandbox: hasSandbox
+                                               },
+                                               onComplete: function (transport) {
                                                        backend_sanity_check_callback(transport);
-                                               } });
-
-
-                               });
+                                               }
+                                       });
+                               } catch (e) {
+                                       exception_error(e);
+                               }
 
+                       });
 
-               });
 
-       } catch (e) {
-               exception_error("init", e);
-       }
+       });
 }
 
 function init_hotkey_actions() {
@@ -587,192 +575,177 @@ function init_hotkey_actions() {
 }
 
 function init_second_stage() {
+       updateFeedList();
+       closeArticlePanel();
 
-       try {
-               updateFeedList();
-               closeArticlePanel();
-
-               if (parseInt(getCookie("ttrss_fh_width")) > 0) {
-                       dijit.byId("feeds-holder").domNode.setStyle(
-                               {width: getCookie("ttrss_fh_width") + "px" });
-               }
-
-               dijit.byId("main").resize();
+       if (parseInt(getCookie("ttrss_fh_width")) > 0) {
+               dijit.byId("feeds-holder").domNode.setStyle(
+                       {width: getCookie("ttrss_fh_width") + "px" });
+       }
 
-               var tmph = dojo.connect(dijit.byId('feeds-holder'), 'resize',
-                       function (args) {
-                               if (args && args.w >= 0) {
-                                       setCookie("ttrss_fh_width", args.w, getInitParam("cookie_lifetime"));
-                               }
-               });
+       dijit.byId("main").resize();
 
-               var tmph = dojo.connect(dijit.byId('content-insert'), 'resize',
-                       function (args) {
-                               if (args && args.w >= 0 && args.h >= 0) {
-                                       setCookie("ttrss_ci_width", args.w, getInitParam("cookie_lifetime"));
-                                       setCookie("ttrss_ci_height", args.h, getInitParam("cookie_lifetime"));
-                               }
-               });
+       var tmph = dojo.connect(dijit.byId('feeds-holder'), 'resize',
+               function (args) {
+                       if (args && args.w >= 0) {
+                               setCookie("ttrss_fh_width", args.w, getInitParam("cookie_lifetime"));
+                       }
+       });
 
-               delCookie("ttrss_test");
+       var tmph = dojo.connect(dijit.byId('content-insert'), 'resize',
+               function (args) {
+                       if (args && args.w >= 0 && args.h >= 0) {
+                               setCookie("ttrss_ci_width", args.w, getInitParam("cookie_lifetime"));
+                               setCookie("ttrss_ci_height", args.h, getInitParam("cookie_lifetime"));
+                       }
+       });
 
-               var toolbar = document.forms["main_toolbar_form"];
+       delCookie("ttrss_test");
 
-               dijit.getEnclosingWidget(toolbar.view_mode).attr('value',
-                       getInitParam("default_view_mode"));
+       var toolbar = document.forms["main_toolbar_form"];
 
-               dijit.getEnclosingWidget(toolbar.order_by).attr('value',
-                       getInitParam("default_view_order_by"));
+       dijit.getEnclosingWidget(toolbar.view_mode).attr('value',
+               getInitParam("default_view_mode"));
 
-               feeds_sort_by_unread = getInitParam("feeds_sort_by_unread") == 1;
+       dijit.getEnclosingWidget(toolbar.order_by).attr('value',
+               getInitParam("default_view_order_by"));
 
-               var hash_feed_id = hash_get('f');
-               var hash_feed_is_cat = hash_get('c') == "1";
+       feeds_sort_by_unread = getInitParam("feeds_sort_by_unread") == 1;
 
-               if (hash_feed_id != undefined) {
-                       setActiveFeedId(hash_feed_id, hash_feed_is_cat);
-               }
+       var hash_feed_id = hash_get('f');
+       var hash_feed_is_cat = hash_get('c') == "1";
 
-               loading_set_progress(50);
+       if (hash_feed_id != undefined) {
+               setActiveFeedId(hash_feed_id, hash_feed_is_cat);
+       }
 
-               // can't use cache_clear() here because viewfeed might not have initialized yet
-               if ('sessionStorage' in window && window['sessionStorage'] !== null)
-                       sessionStorage.clear();
+       loading_set_progress(50);
 
-               var hotkeys = getInitParam("hotkeys");
-               var tmp = [];
+       // can't use cache_clear() here because viewfeed might not have initialized yet
+       if ('sessionStorage' in window && window['sessionStorage'] !== null)
+               sessionStorage.clear();
 
-               for (sequence in hotkeys[1]) {
-                       filtered = sequence.replace(/\|.*$/, "");
-                       tmp[filtered] = hotkeys[1][sequence];
-               }
+       var hotkeys = getInitParam("hotkeys");
+       var tmp = [];
 
-               hotkeys[1] = tmp;
-               setInitParam("hotkeys", hotkeys);
+       for (sequence in hotkeys[1]) {
+               filtered = sequence.replace(/\|.*$/, "");
+               tmp[filtered] = hotkeys[1][sequence];
+       }
 
-               _widescreen_mode = getInitParam("widescreen");
-               switchPanelMode(_widescreen_mode);
+       hotkeys[1] = tmp;
+       setInitParam("hotkeys", hotkeys);
 
-               console.log("second stage ok");
+       _widescreen_mode = getInitParam("widescreen");
+       switchPanelMode(_widescreen_mode);
 
-               if (getInitParam("simple_update")) {
-                       console.log("scheduling simple feed updater...");
-                       window.setTimeout(update_random_feed, 30*1000);
-               }
+       console.log("second stage ok");
 
-       } catch (e) {
-               exception_error("init_second_stage", e);
+       if (getInitParam("simple_update")) {
+               console.log("scheduling simple feed updater...");
+               window.setTimeout(update_random_feed, 30*1000);
        }
 }
 
 function quickMenuGo(opid) {
-       try {
-               switch (opid) {
-               case "qmcPrefs":
-                       gotoPreferences();
-                       break;
-               case "qmcLogout":
-                       gotoLogout();
-                       break;
-               case "qmcTagCloud":
-                       displayDlg(__("Tag cloud"), "printTagCloud");
-                       break;
-               case "qmcSearch":
-                       search();
-                       break;
-               case "qmcAddFeed":
-                       quickAddFeed();
-                       break;
-               case "qmcDigest":
-                       window.location.href = "backend.php?op=digest";
-                       break;
-               case "qmcEditFeed":
-                       if (activeFeedIsCat())
-                               alert(__("You can't edit this kind of feed."));
-                       else
-                               editFeed(getActiveFeedId());
-                       break;
-               case "qmcRemoveFeed":
-                       var actid = getActiveFeedId();
+       switch (opid) {
+       case "qmcPrefs":
+               gotoPreferences();
+               break;
+       case "qmcLogout":
+               gotoLogout();
+               break;
+       case "qmcTagCloud":
+               displayDlg(__("Tag cloud"), "printTagCloud");
+               break;
+       case "qmcSearch":
+               search();
+               break;
+       case "qmcAddFeed":
+               quickAddFeed();
+               break;
+       case "qmcDigest":
+               window.location.href = "backend.php?op=digest";
+               break;
+       case "qmcEditFeed":
+               if (activeFeedIsCat())
+                       alert(__("You can't edit this kind of feed."));
+               else
+                       editFeed(getActiveFeedId());
+               break;
+       case "qmcRemoveFeed":
+               var actid = getActiveFeedId();
 
-                       if (activeFeedIsCat()) {
-                               alert(__("You can't unsubscribe from the category."));
-                               return;
-                       }
+               if (activeFeedIsCat()) {
+                       alert(__("You can't unsubscribe from the category."));
+                       return;
+               }
 
-                       if (!actid) {
-                               alert(__("Please select some feed first."));
-                               return;
-                       }
+               if (!actid) {
+                       alert(__("Please select some feed first."));
+                       return;
+               }
 
-                       var fn = getFeedName(actid);
+               var fn = getFeedName(actid);
 
-                       var pr = __("Unsubscribe from %s?").replace("%s", fn);
+               var pr = __("Unsubscribe from %s?").replace("%s", fn);
 
-                       if (confirm(pr)) {
-                               unsubscribeFeed(actid);
-                       }
-                       break;
-               case "qmcCatchupAll":
-                       catchupAllFeeds();
-                       break;
-               case "qmcShowOnlyUnread":
-                       toggleDispRead();
-                       break;
-               case "qmcAddFilter":
-                       quickAddFilter();
-                       break;
-               case "qmcAddLabel":
-                       addLabel();
-                       break;
-               case "qmcRescoreFeed":
-                       rescoreCurrentFeed();
-                       break;
-               case "qmcToggleWidescreen":
-                       if (!isCdmMode()) {
-                               _widescreen_mode = !_widescreen_mode;
+               if (confirm(pr)) {
+                       unsubscribeFeed(actid);
+               }
+               break;
+       case "qmcCatchupAll":
+               catchupAllFeeds();
+               break;
+       case "qmcShowOnlyUnread":
+               toggleDispRead();
+               break;
+       case "qmcAddFilter":
+               quickAddFilter();
+               break;
+       case "qmcAddLabel":
+               addLabel();
+               break;
+       case "qmcRescoreFeed":
+               rescoreCurrentFeed();
+               break;
+       case "qmcToggleWidescreen":
+               if (!isCdmMode()) {
+                       _widescreen_mode = !_widescreen_mode;
 
-                               // reset stored sizes because geometry changed
-                               setCookie("ttrss_ci_width", 0);
-                               setCookie("ttrss_ci_height", 0);
+                       // reset stored sizes because geometry changed
+                       setCookie("ttrss_ci_width", 0);
+                       setCookie("ttrss_ci_height", 0);
 
-                               switchPanelMode(_widescreen_mode);
-                       } else {
-                               alert(__("Widescreen is not available in combined mode."));
-                       }
-                       break;
-               case "qmcHKhelp":
-                       helpDialog("main");
-                       break;
-               default:
-                       console.log("quickMenuGo: unknown action: " + opid);
+                       switchPanelMode(_widescreen_mode);
+               } else {
+                       alert(__("Widescreen is not available in combined mode."));
                }
-
-       } catch (e) {
-               exception_error("quickMenuGo", e);
+               break;
+       case "qmcHKhelp":
+               helpDialog("main");
+               break;
+       default:
+               console.log("quickMenuGo: unknown action: " + opid);
        }
 }
 
 function toggleDispRead() {
-       try {
 
-               var hide = !(getInitParam("hide_read_feeds") == "1");
+       var hide = !(getInitParam("hide_read_feeds") == "1");
 
-               hideOrShowFeeds(hide);
+       hideOrShowFeeds(hide);
 
-               var query = "?op=rpc&method=setpref&key=HIDE_READ_FEEDS&value=" +
-                       param_escape(hide);
+       var query = "?op=rpc&method=setpref&key=HIDE_READ_FEEDS&value=" +
+               param_escape(hide);
 
-               setInitParam("hide_read_feeds", hide);
+       setInitParam("hide_read_feeds", hide);
 
-               new Ajax.Request("backend.php", {
-                       parameters: query,
-                       onComplete: function(transport) {
-                       } });
+       new Ajax.Request("backend.php", {
+               parameters: query,
+               onComplete: function(transport) {
+               } });
 
-       } catch (e) {
-               exception_error("toggleDispRead", e);
-       }
 }
 
 function parse_runtime_info(data) {
@@ -825,18 +798,13 @@ function parse_runtime_info(data) {
 }
 
 function collapse_feedlist() {
-       try {
-               Element.toggle("feeds-holder");
+       Element.toggle("feeds-holder");
 
-               var splitter = $("feeds-holder_splitter");
+       var splitter = $("feeds-holder_splitter");
 
-               Element.visible("feeds-holder") ? splitter.show() : splitter.hide();
+       Element.visible("feeds-holder") ? splitter.show() : splitter.hide();
 
-               dijit.byId("main").resize();
-
-       } catch (e) {
-               exception_error("collapse_feedlist", e);
-       }
+       dijit.byId("main").resize();
 }
 
 function viewModeChanged() {
@@ -875,88 +843,83 @@ function rescoreCurrentFeed() {
 }
 
 function hotkey_handler(e) {
-       try {
 
-               if (e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA") return;
+       if (e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA") return;
 
-               var keycode = false;
-               var shift_key = false;
-               var ctrl_key = false;
-               var alt_key = false;
-               var meta_key = false;
+       var keycode = false;
+       var shift_key = false;
+       var ctrl_key = false;
+       var alt_key = false;
+       var meta_key = false;
 
-               var cmdline = $('cmdline');
+       var cmdline = $('cmdline');
 
-               shift_key = e.shiftKey;
-               ctrl_key = e.ctrlKey;
-               alt_key = e.altKey;
-               meta_key = e.metaKey;
+       shift_key = e.shiftKey;
+       ctrl_key = e.ctrlKey;
+       alt_key = e.altKey;
+       meta_key = e.metaKey;
 
-               if (window.event) {
-                       keycode = window.event.keyCode;
-               } else if (e) {
-                       keycode = e.which;
-               }
+       if (window.event) {
+               keycode = window.event.keyCode;
+       } else if (e) {
+               keycode = e.which;
+       }
 
-               var keychar = String.fromCharCode(keycode);
+       var keychar = String.fromCharCode(keycode);
 
-               if (keycode == 27) { // escape
-                       hotkey_prefix = false;
-               }
+       if (keycode == 27) { // escape
+               hotkey_prefix = false;
+       }
 
-               if (keycode == 16) return; // ignore lone shift
-               if (keycode == 17) return; // ignore lone ctrl
+       if (keycode == 16) return; // ignore lone shift
+       if (keycode == 17) return; // ignore lone ctrl
 
-               keychar = keychar.toLowerCase();
+       keychar = keychar.toLowerCase();
 
-               var hotkeys = getInitParam("hotkeys");
+       var hotkeys = getInitParam("hotkeys");
 
-               if (!hotkey_prefix && hotkeys[0].indexOf(keychar) != -1) {
+       if (!hotkey_prefix && hotkeys[0].indexOf(keychar) != -1) {
 
-                       var date = new Date();
-                       var ts = Math.round(date.getTime() / 1000);
+               var date = new Date();
+               var ts = Math.round(date.getTime() / 1000);
 
-                       hotkey_prefix = keychar;
-                       hotkey_prefix_pressed = ts;
+               hotkey_prefix = keychar;
+               hotkey_prefix_pressed = ts;
 
-                       cmdline.innerHTML = keychar;
-                       Element.show(cmdline);
+               cmdline.innerHTML = keychar;
+               Element.show(cmdline);
 
-                       return true;
-               }
+               return true;
+       }
 
-               Element.hide(cmdline);
+       Element.hide(cmdline);
 
-               var hotkey = keychar.search(/[a-zA-Z0-9]/) != -1 ? keychar : "(" + keycode + ")";
+       var hotkey = keychar.search(/[a-zA-Z0-9]/) != -1 ? keychar : "(" + keycode + ")";
 
-               // ensure ^*char notation
-               if (shift_key) hotkey = "*" + hotkey;
-               if (ctrl_key) hotkey = "^" + hotkey;
-               if (alt_key) hotkey = "+" + hotkey;
-               if (meta_key) hotkey = "%" + hotkey;
+       // ensure ^*char notation
+       if (shift_key) hotkey = "*" + hotkey;
+       if (ctrl_key) hotkey = "^" + hotkey;
+       if (alt_key) hotkey = "+" + hotkey;
+       if (meta_key) hotkey = "%" + hotkey;
 
-               hotkey = hotkey_prefix ? hotkey_prefix + " " + hotkey : hotkey;
-               hotkey_prefix = false;
+       hotkey = hotkey_prefix ? hotkey_prefix + " " + hotkey : hotkey;
+       hotkey_prefix = false;
 
-               var hotkey_action = false;
-               var hotkeys = getInitParam("hotkeys");
+       var hotkey_action = false;
+       var hotkeys = getInitParam("hotkeys");
 
-               for (sequence in hotkeys[1]) {
-                       if (sequence == hotkey) {
-                               hotkey_action = hotkeys[1][sequence];
-                               break;
-                       }
+       for (sequence in hotkeys[1]) {
+               if (sequence == hotkey) {
+                       hotkey_action = hotkeys[1][sequence];
+                       break;
                }
+       }
 
-               var action = hotkey_actions[hotkey_action];
-
-               if (action != null) {
-                       action();
-                       return false;
-               }
+       var action = hotkey_actions[hotkey_action];
 
-       } catch (e) {
-               exception_error("hotkey_handler", e);
+       if (action != null) {
+               action();
+               return false;
        }
 }
 
@@ -965,33 +928,21 @@ function inPreferences() {
 }
 
 function reverseHeadlineOrder() {
-       try {
-
-               /* var query_str = "?op=rpc&method=togglepref&key=REVERSE_HEADLINES";
-
-               new Ajax.Request("backend.php", {
-                       parameters: query_str,
-                       onComplete: function(transport) {
-                                       viewCurrentFeed();
-                               } }); */
 
-               var toolbar = document.forms["main_toolbar_form"];
-               var order_by = dijit.getEnclosingWidget(toolbar.order_by);
+       var toolbar = document.forms["main_toolbar_form"];
+       var order_by = dijit.getEnclosingWidget(toolbar.order_by);
 
-               var value = order_by.attr('value');
+       var value = order_by.attr('value');
 
-               if (value == "date_reverse")
-                       value = "default";
-               else
-                       value = "date_reverse";
+       if (value == "date_reverse")
+               value = "default";
+       else
+               value = "date_reverse";
 
-               order_by.attr('value', value);
+       order_by.attr('value', value);
 
-               viewCurrentFeed();
+       viewCurrentFeed();
 
-       } catch (e) {
-               exception_error("reverseHeadlineOrder", e);
-       }
 }
 
 function handle_rpc_json(transport, scheduled_call) {
@@ -1065,99 +1016,79 @@ function handle_rpc_json(transport, scheduled_call) {
                else
                        notify_error("Communication problem with server.");
 
-               console.log(e);
-               //exception_error("handle_rpc_json", e, transport);
+               console.error(e);
        }
 
        return true;
 }
 
 function switchPanelMode(wide) {
-       try {
-               if (isCdmMode()) return;
-
-               article_id = getActiveArticleId();
+       if (isCdmMode()) return;
 
-               if (wide) {
-                       dijit.byId("headlines-wrap-inner").attr("design", 'sidebar');
-                       dijit.byId("content-insert").attr("region", "trailing");
+       article_id = getActiveArticleId();
 
-                       dijit.byId("content-insert").domNode.setStyle({width: '50%',
-                               height: 'auto',
-                               borderTopWidth: '0px' });
-
-                       if (parseInt(getCookie("ttrss_ci_width")) > 0) {
-                               dijit.byId("content-insert").domNode.setStyle(
-                                       {width: getCookie("ttrss_ci_width") + "px" });
-                       }
+       if (wide) {
+               dijit.byId("headlines-wrap-inner").attr("design", 'sidebar');
+               dijit.byId("content-insert").attr("region", "trailing");
 
-                       $("headlines-frame").setStyle({ borderBottomWidth: '0px' });
-                       $("headlines-frame").addClassName("wide");
+               dijit.byId("content-insert").domNode.setStyle({width: '50%',
+                       height: 'auto',
+                       borderTopWidth: '0px' });
 
-               } else {
+               if (parseInt(getCookie("ttrss_ci_width")) > 0) {
+                       dijit.byId("content-insert").domNode.setStyle(
+                               {width: getCookie("ttrss_ci_width") + "px" });
+               }
 
-                       dijit.byId("content-insert").attr("region", "bottom");
+               $("headlines-frame").setStyle({ borderBottomWidth: '0px' });
+               $("headlines-frame").addClassName("wide");
 
-                       dijit.byId("content-insert").domNode.setStyle({width: 'auto',
-                               height: '50%',
-                               borderTopWidth: '0px'});
+       } else {
 
-                       if (parseInt(getCookie("ttrss_ci_height")) > 0) {
-                               dijit.byId("content-insert").domNode.setStyle(
-                                       {height: getCookie("ttrss_ci_height") + "px" });
-                       }
+               dijit.byId("content-insert").attr("region", "bottom");
 
-                       $("headlines-frame").setStyle({ borderBottomWidth: '1px' });
-                       $("headlines-frame").removeClassName("wide");
+               dijit.byId("content-insert").domNode.setStyle({width: 'auto',
+                       height: '50%',
+                       borderTopWidth: '0px'});
 
+               if (parseInt(getCookie("ttrss_ci_height")) > 0) {
+                       dijit.byId("content-insert").domNode.setStyle(
+                               {height: getCookie("ttrss_ci_height") + "px" });
                }
 
-               closeArticlePanel();
+               $("headlines-frame").setStyle({ borderBottomWidth: '1px' });
+               $("headlines-frame").removeClassName("wide");
 
-               if (article_id) view(article_id);
+       }
 
-               new Ajax.Request("backend.php", {
-                       parameters: "op=rpc&method=setpanelmode&wide=" + (wide ? 1 : 0),
-                       onComplete: function(transport) {
-                               console.log(transport.responseText);
-                       } });
+       closeArticlePanel();
 
+       if (article_id) view(article_id);
 
-       } catch (e) {
-               exception_error("switchPanelMode", e);
-       }
+       new Ajax.Request("backend.php", {
+               parameters: "op=rpc&method=setpanelmode&wide=" + (wide ? 1 : 0),
+               onComplete: function(transport) {
+                       console.log(transport.responseText);
+               } });
 }
 
 function update_random_feed() {
-       try {
-               console.log("in update_random_feed");
-
-               new Ajax.Request("backend.php", {
-                       parameters: "op=rpc&method=updateRandomFeed",
-                       onComplete: function(transport) {
-                               handle_rpc_json(transport, true);
-                               window.setTimeout(update_random_feed, 30*1000);
-                       } });
+       console.log("in update_random_feed");
 
-       } catch (e) {
-               exception_error("update_random_feed", e);
-       }
+       new Ajax.Request("backend.php", {
+               parameters: "op=rpc&method=updateRandomFeed",
+               onComplete: function(transport) {
+                       handle_rpc_json(transport, true);
+                       window.setTimeout(update_random_feed, 30*1000);
+               } });
 }
 
 function hash_get(key) {
-       try {
-               kv = window.location.hash.substring(1).toQueryParams();
-               return kv[key];
-       } catch (e) {
-               exception_error("hash_get", e);
-       }
+       kv = window.location.hash.substring(1).toQueryParams();
+       return kv[key];
 }
 function hash_set(key, value) {
-       try {
-               kv = window.location.hash.substring(1).toQueryParams();
-               kv[key] = value;
-               window.location.hash = $H(kv).toQueryString();
-       } catch (e) {
-               exception_error("hash_set", e);
-       }
+       kv = window.location.hash.substring(1).toQueryParams();
+       kv[key] = value;
+       window.location.hash = $H(kv).toQueryString();
 }
index c420a1a5a9fd8d3a3894518ba17ad55fa2aa7dbc..abf56c185f5238b0919aa146d42311152cb0c954 100755 (executable)
@@ -1,5 +1,3 @@
-var article_cache = new Array();
-
 var _active_article_id = 0;
 
 var vgroup_last_feed = false;
@@ -21,87 +19,129 @@ var _catchup_request_sent = false;
 var has_storage = 'sessionStorage' in window && window['sessionStorage'] !== null;
 
 function headlines_callback2(transport, offset, background, infscroll_req) {
+       handle_rpc_json(transport);
+
+       console.log("headlines_callback2 [offset=" + offset + "] B:" + background + " I:" + infscroll_req);
+
+       var is_cat = false;
+       var feed_id = false;
+
+       var reply = false;
+
        try {
-               handle_rpc_json(transport);
+               reply = JSON.parse(transport.responseText);
+       } catch (e) {
+               console.error(e);
+       }
 
-               console.log("headlines_callback2 [offset=" + offset + "] B:" + background + " I:" + infscroll_req);
+       if (reply) {
 
-               var is_cat = false;
-               var feed_id = false;
+               is_cat = reply['headlines']['is_cat'];
+               feed_id = reply['headlines']['id'];
 
-               var reply = false;
+               if (background) {
+                       var content = reply['headlines']['content'];
 
-               try {
-                       reply = JSON.parse(transport.responseText);
-               } catch (e) {
-                       console.error(e);
+                       content = content + "<div id='headlines-spacer'></div>";
+                       return;
                }
 
-               if (reply) {
+               if (feed_id != -7 && (feed_id != getActiveFeedId() || is_cat != activeFeedIsCat()))
+                       return;
 
-                       is_cat = reply['headlines']['is_cat'];
-                       feed_id = reply['headlines']['id'];
+               /* dijit.getEnclosingWidget(
+                       document.forms["main_toolbar_form"].update).attr('disabled',
+                               is_cat || feed_id <= 0); */
 
-                       if (background) {
-                               var content = reply['headlines']['content'];
+               try {
+                       if (infscroll_req == false) {
+                               $("headlines-frame").scrollTop = 0;
 
-                               content = content + "<div id='headlines-spacer'></div>";
-                               return;
+                               $("floatingTitle").style.visibility = "hidden";
+                               $("floatingTitle").setAttribute("data-article-id", 0);
+                               $("floatingTitle").innerHTML = "";
                        }
+               } catch (e) { };
 
-                       if (feed_id != -7 && (feed_id != getActiveFeedId() || is_cat != activeFeedIsCat()))
-                               return;
+               $("headlines-frame").removeClassName("cdm");
+               $("headlines-frame").removeClassName("normal");
 
-                       /* dijit.getEnclosingWidget(
-                               document.forms["main_toolbar_form"].update).attr('disabled',
-                                       is_cat || feed_id <= 0); */
+               $("headlines-frame").addClassName(isCdmMode() ? "cdm" : "normal");
 
-                       try {
-                               if (infscroll_req == false) {
-                                       $("headlines-frame").scrollTop = 0;
+               var headlines_count = reply['headlines-info']['count'];
 
-                                       $("floatingTitle").style.visibility = "hidden";
-                                       $("floatingTitle").setAttribute("data-article-id", 0);
-                                       $("floatingTitle").innerHTML = "";
-                               }
-                       } catch (e) { };
+               vgroup_last_feed = reply['headlines-info']['vgroup_last_feed'];
 
-                       $("headlines-frame").removeClassName("cdm");
-                       $("headlines-frame").removeClassName("normal");
+               if (parseInt(headlines_count) < 30) {
+                       _infscroll_disable = 1;
+               } else {
+                       _infscroll_disable = 0;
+               }
 
-                       $("headlines-frame").addClassName(isCdmMode() ? "cdm" : "normal");
+               current_first_id = reply['headlines']['first_id'];
+               var counters = reply['counters'];
+               var articles = reply['articles'];
+               //var runtime_info = reply['runtime-info'];
 
-                       var headlines_count = reply['headlines-info']['count'];
+               if (infscroll_req == false) {
+                       loaded_article_ids = [];
 
-                       vgroup_last_feed = reply['headlines-info']['vgroup_last_feed'];
+                       dojo.html.set($("headlines-toolbar"),
+                                       reply['headlines']['toolbar'],
+                                       {parseContent: true});
 
-                       if (parseInt(headlines_count) < 30) {
-                               _infscroll_disable = 1;
-                       } else {
-                               _infscroll_disable = 0;
-                       }
+                       /*dojo.html.set($("headlines-frame"),
+                               reply['headlines']['content'],
+                               {parseContent: true});
 
-                       current_first_id = reply['headlines']['first_id'];
-                       var counters = reply['counters'];
-                       var articles = reply['articles'];
-                       //var runtime_info = reply['runtime-info'];
+                       $$("#headlines-frame div[id*='RROW']").each(function(row) {
+                               loaded_article_ids.push(row.id);
+                       });*/
 
-                       if (infscroll_req == false) {
-                               loaded_article_ids = [];
+                       $("headlines-frame").innerHTML = '';
 
-                               dojo.html.set($("headlines-toolbar"),
-                                               reply['headlines']['toolbar'],
-                                               {parseContent: true});
+                       var tmp = new Element("div");
+                       tmp.innerHTML = reply['headlines']['content'];
+                       dojo.parser.parse(tmp);
 
-                               /*dojo.html.set($("headlines-frame"),
-                                       reply['headlines']['content'],
-                                       {parseContent: true});
+                       while (tmp.hasChildNodes()) {
+                               var row = tmp.removeChild(tmp.firstChild);
+
+                               if (loaded_article_ids.indexOf(row.id) == -1 || row.hasClassName("cdmFeedTitle")) {
+                                       dijit.byId("headlines-frame").domNode.appendChild(row);
 
-                               $$("#headlines-frame div[id*='RROW']").each(function(row) {
                                        loaded_article_ids.push(row.id);
-                               });*/
+                               }
+                       }
+
+                       var hsp = $("headlines-spacer");
+                       if (!hsp) hsp = new Element("DIV", {"id": "headlines-spacer"});
+                       dijit.byId('headlines-frame').domNode.appendChild(hsp);
+
+                       initHeadlinesMenu();
+
+                       if (_infscroll_disable)
+                               hsp.innerHTML = "<a href='#' onclick='openNextUnreadFeed()'>" +
+                                       __("Click to open next unread feed.") + "</a>";
+
+                       if (_search_query) {
+                               $("feed_title").innerHTML += "<span id='cancel_search'>" +
+                                       " (<a href='#' onclick='cancelSearch()'>" + __("Cancel search") + "</a>)" +
+                                       "</span>";
+                       }
+
+               } else {
 
-                               $("headlines-frame").innerHTML = '';
+                       if (headlines_count > 0 && feed_id == getActiveFeedId() && is_cat == activeFeedIsCat()) {
+                               console.log("adding some more headlines: " + headlines_count);
+
+                               var c = dijit.byId("headlines-frame");
+                               var ids = getSelectedArticleIds2();
+
+                               var hsp = $("headlines-spacer");
+
+                               if (hsp)
+                                       c.domNode.removeChild(hsp);
 
                                var tmp = new Element("div");
                                tmp.innerHTML = reply['headlines']['content'];
@@ -117,796 +157,672 @@ function headlines_callback2(transport, offset, background, infscroll_req) {
                                        }
                                }
 
-                               var hsp = $("headlines-spacer");
                                if (!hsp) hsp = new Element("DIV", {"id": "headlines-spacer"});
-                               dijit.byId('headlines-frame').domNode.appendChild(hsp);
+                               c.domNode.appendChild(hsp);
 
-                               initHeadlinesMenu();
+                               if (headlines_count < 30) _infscroll_disable = true;
 
-                               if (_infscroll_disable)
-                                       hsp.innerHTML = "<a href='#' onclick='openNextUnreadFeed()'>" +
-                                               __("Click to open next unread feed.") + "</a>";
+                               console.log("restore selected ids: " + ids);
 
-                               if (_search_query) {
-                                       $("feed_title").innerHTML += "<span id='cancel_search'>" +
-                                               " (<a href='#' onclick='cancelSearch()'>" + __("Cancel search") + "</a>)" +
-                                               "</span>";
+                               for (var i = 0; i < ids.length; i++) {
+                                       markHeadline(ids[i]);
                                }
 
-                       } else {
-
-                               if (headlines_count > 0 && feed_id == getActiveFeedId() && is_cat == activeFeedIsCat()) {
-                                       console.log("adding some more headlines: " + headlines_count);
-
-                                       var c = dijit.byId("headlines-frame");
-                                       var ids = getSelectedArticleIds2();
-
-                                       var hsp = $("headlines-spacer");
-
-                                       if (hsp)
-                                               c.domNode.removeChild(hsp);
-
-                                       var tmp = new Element("div");
-                                       tmp.innerHTML = reply['headlines']['content'];
-                                       dojo.parser.parse(tmp);
-
-                                       while (tmp.hasChildNodes()) {
-                                               var row = tmp.removeChild(tmp.firstChild);
-
-                                               if (loaded_article_ids.indexOf(row.id) == -1 || row.hasClassName("cdmFeedTitle")) {
-                                                       dijit.byId("headlines-frame").domNode.appendChild(row);
-
-                                                       loaded_article_ids.push(row.id);
-                                               }
-                                       }
-
-                                       if (!hsp) hsp = new Element("DIV", {"id": "headlines-spacer"});
-                                       c.domNode.appendChild(hsp);
+                               initHeadlinesMenu();
 
-                                       if (headlines_count < 30) _infscroll_disable = true;
+                               if (_infscroll_disable) {
+                                       hsp.innerHTML = "<a href='#' onclick='openNextUnreadFeed()'>" +
+                                       __("Click to open next unread feed.") + "</a>";
+                               }
 
-                                       console.log("restore selected ids: " + ids);
+                       } else {
+                               console.log("no new headlines received");
 
-                                       for (var i = 0; i < ids.length; i++) {
-                                               markHeadline(ids[i]);
-                                       }
+                               var first_id_changed = reply['headlines']['first_id_changed'];
+                               console.log("first id changed:" + first_id_changed);
 
-                                       initHeadlinesMenu();
+                               var hsp = $("headlines-spacer");
 
-                                       if (_infscroll_disable) {
+                               if (hsp) {
+                                       if (first_id_changed) {
+                                               hsp.innerHTML = "<a href='#' onclick='viewCurrentFeed()'>" +
+                                               __("New articles found, reload feed to continue.") + "</a>";
+                                       } else {
                                                hsp.innerHTML = "<a href='#' onclick='openNextUnreadFeed()'>" +
                                                __("Click to open next unread feed.") + "</a>";
                                        }
 
-                               } else {
-                                       console.log("no new headlines received");
-
-                                       var first_id_changed = reply['headlines']['first_id_changed'];
-                                       console.log("first id changed:" + first_id_changed);
-
-                                       var hsp = $("headlines-spacer");
-
-                                       if (hsp) {
-                                               if (first_id_changed) {
-                                                       hsp.innerHTML = "<a href='#' onclick='viewCurrentFeed()'>" +
-                                                       __("New articles found, reload feed to continue.") + "</a>";
-                                               } else {
-                                                       hsp.innerHTML = "<a href='#' onclick='openNextUnreadFeed()'>" +
-                                                       __("Click to open next unread feed.") + "</a>";
-                                               }
-
-                                       }
-
                                }
-                       }
 
-                       if (articles) {
-                               for (var i = 0; i < articles.length; i++) {
-                                       var a_id = articles[i]['id'];
-                                       cache_set("article:" + a_id, articles[i]['content']);
-                               }
-                       } else {
-                               console.log("no cached articles received");
                        }
+               }
 
-                       if (counters)
-                               parse_counters(counters);
-                       else
-                               request_counters(true);
-
+               if (articles) {
+                       for (var i = 0; i < articles.length; i++) {
+                               var a_id = articles[i]['id'];
+                               cache_set("article:" + a_id, articles[i]['content']);
+                       }
                } 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>");
+                       console.log("no cached articles received");
                }
 
-               _infscroll_request_sent = 0;
-               _last_headlines_update = new Date().getTime();
+               if (counters)
+                       parse_counters(counters);
+               else
+                       request_counters(true);
 
-               unpackVisibleHeadlines();
+       } 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 we have some more space in the buffer, why not try to fill it
+       _infscroll_request_sent = 0;
+       _last_headlines_update = new Date().getTime();
 
-               if (!_infscroll_disable && $("headlines-spacer") &&
-                               $("headlines-spacer").offsetTop < $("headlines-frame").offsetHeight) {
+       unpackVisibleHeadlines();
 
-                       window.setTimeout(function() {
-                               loadMoreHeadlines();
-                       }, 250);
-               }
+       // if we have some more space in the buffer, why not try to fill it
 
-               notify("");
+       if (!_infscroll_disable && $("headlines-spacer") &&
+                       $("headlines-spacer").offsetTop < $("headlines-frame").offsetHeight) {
 
-       } catch (e) {
-               exception_error("headlines_callback2", e, transport);
+               window.setTimeout(function() {
+                       loadMoreHeadlines();
+               }, 250);
        }
+
+       notify("");
 }
 
 function render_article(article) {
-       try {
-               cleanup_memory("content-insert");
+       cleanup_memory("content-insert");
 
-               dijit.byId("headlines-wrap-inner").addChild(
-                               dijit.byId("content-insert"));
+       dijit.byId("headlines-wrap-inner").addChild(
+                       dijit.byId("content-insert"));
 
-               var c = dijit.byId("content-insert");
+       var c = dijit.byId("content-insert");
 
-               try {
-                       c.domNode.scrollTop = 0;
-               } catch (e) { };
-
-               c.attr('content', article);
-               PluginHost.run(PluginHost.HOOK_ARTICLE_RENDERED, c.domNode);
+       try {
+               c.domNode.scrollTop = 0;
+       } catch (e) { };
 
-               correctHeadlinesOffset(getActiveArticleId());
+       c.attr('content', article);
+       PluginHost.run(PluginHost.HOOK_ARTICLE_RENDERED, c.domNode);
 
-               try {
-                       c.focus();
-               } catch (e) { };
+       correctHeadlinesOffset(getActiveArticleId());
 
-       } catch (e) {
-               exception_error("render_article", e);
-       }
+       try {
+               c.focus();
+       } catch (e) { };
 }
 
 function showArticleInHeadlines(id, noexpand) {
+       var row = $("RROW-" + id);
+       if (!row) return;
 
-       try {
-               var row = $("RROW-" + id);
-               if (!row) return;
-
-               if (!noexpand)
-                       row.removeClassName("Unread");
-
-               row.addClassName("active");
+       if (!noexpand)
+               row.removeClassName("Unread");
 
-               selectArticles('none');
+       row.addClassName("active");
 
-               markHeadline(id);
+       selectArticles('none');
 
-       } catch (e) {
-               exception_error("showArticleInHeadlines", e);
-       }
+       markHeadline(id);
 }
 
 function article_callback2(transport, id) {
-       try {
-               console.log("article_callback2 " + id);
+       console.log("article_callback2 " + id);
 
-               handle_rpc_json(transport);
+       handle_rpc_json(transport);
 
-               var reply = false;
+       var reply = false;
 
-               try {
-                       reply = JSON.parse(transport.responseText);
-               } catch (e) {
-                       console.error(e);
-               }
+       try {
+               reply = JSON.parse(transport.responseText);
+       } catch (e) {
+               console.error(e);
+       }
 
-               if (reply) {
+       if (reply) {
 
-                       reply.each(function(article) {
-                               if (getActiveArticleId() == article['id']) {
-                                       render_article(article['content']);
-                               }
-                               cids_requested.remove(article['id']);
+               reply.each(function(article) {
+                       if (getActiveArticleId() == article['id']) {
+                               render_article(article['content']);
+                       }
+                       cids_requested.remove(article['id']);
 
-                               cache_set("article:" + article['id'], article['content']);
-                       });
+                       cache_set("article:" + article['id'], article['content']);
+               });
 
 //                     if (id != last_requested_article) {
 //                             console.log("requested article id is out of sequence, aborting");
 //                             return;
 //                     }
 
-               } else {
-                       console.error("Invalid object received: " + transport.responseText);
+       } else {
+               console.error("Invalid object received: " + transport.responseText);
 
-                       render_article("<div class='whiteBox'>" +
-                                       __('Could not display article (invalid object received - see error console for details)') + "</div>");
-               }
+               render_article("<div class='whiteBox'>" +
+                               __('Could not display article (invalid object received - see error console for details)') + "</div>");
+       }
 
-               var unread_in_buffer = $$("#headlines-frame > div[id*=RROW][class*=Unread]").length
-               request_counters(unread_in_buffer == 0);
+       var unread_in_buffer = $$("#headlines-frame > div[id*=RROW][class*=Unread]").length
+       request_counters(unread_in_buffer == 0);
 
-               notify("");
-       } catch (e) {
-               exception_error("article_callback2", e, transport);
-       }
+       notify("");
 }
 
 function view(id, activefeed, noexpand) {
-       try {
-               var oldrow = $("RROW-" + getActiveArticleId());
-               if (oldrow) oldrow.removeClassName("active");
+       var oldrow = $("RROW-" + getActiveArticleId());
+       if (oldrow) oldrow.removeClassName("active");
 
-               var crow = $("RROW-" + id);
+       var crow = $("RROW-" + id);
 
-               if (!crow) return;
-               if (noexpand) {
-                       setActiveArticleId(id);
-                       showArticleInHeadlines(id, noexpand);
-                       return;
-               }
+       if (!crow) return;
+       if (noexpand) {
+               setActiveArticleId(id);
+               showArticleInHeadlines(id, noexpand);
+               return;
+       }
 
-               console.log("loading article: " + id);
+       console.log("loading article: " + id);
 
-               var cached_article = cache_get("article:" + id);
+       var cached_article = cache_get("article:" + id);
 
-               console.log("cache check result: " + (cached_article != false));
+       console.log("cache check result: " + (cached_article != false));
 
-               var query = "?op=article&method=view&id=" + param_escape(id);
+       var query = "?op=article&method=view&id=" + param_escape(id);
 
-               var neighbor_ids = getRelativePostIds(id);
+       var neighbor_ids = getRelativePostIds(id);
 
-               /* only request uncached articles */
+       /* only request uncached articles */
 
-               var cids_to_request = [];
+       var cids_to_request = [];
 
-               for (var i = 0; i < neighbor_ids.length; i++) {
-                       if (cids_requested.indexOf(neighbor_ids[i]) == -1)
-                               if (!cache_get("article:" + neighbor_ids[i])) {
-                                       cids_to_request.push(neighbor_ids[i]);
-                                       cids_requested.push(neighbor_ids[i]);
-                               }
-               }
+       for (var i = 0; i < neighbor_ids.length; i++) {
+               if (cids_requested.indexOf(neighbor_ids[i]) == -1)
+                       if (!cache_get("article:" + neighbor_ids[i])) {
+                               cids_to_request.push(neighbor_ids[i]);
+                               cids_requested.push(neighbor_ids[i]);
+                       }
+       }
 
-               console.log("additional ids: " + cids_to_request.toString());
+       console.log("additional ids: " + cids_to_request.toString());
 
-               query = query + "&cids=" + cids_to_request.toString();
+       query = query + "&cids=" + cids_to_request.toString();
 
-               var article_is_unread = crow.hasClassName("Unread");
+       var article_is_unread = crow.hasClassName("Unread");
 
-               setActiveArticleId(id);
-               showArticleInHeadlines(id);
+       setActiveArticleId(id);
+       showArticleInHeadlines(id);
 
-               if (cached_article && article_is_unread) {
+       if (cached_article && article_is_unread) {
 
-                       query = query + "&mode=prefetch";
+               query = query + "&mode=prefetch";
 
-                       render_article(cached_article);
+               render_article(cached_article);
 
-               } else if (cached_article) {
+       } else if (cached_article) {
 
-                       query = query + "&mode=prefetch_old";
-                       render_article(cached_article);
+               query = query + "&mode=prefetch_old";
+               render_article(cached_article);
 
-                       // if we don't need to request any relative ids, we might as well skip
-                       // the server roundtrip altogether
-                       if (cids_to_request.length == 0) {
-                               return;
-                       }
+               // if we don't need to request any relative ids, we might as well skip
+               // the server roundtrip altogether
+               if (cids_to_request.length == 0) {
+                       return;
                }
+       }
 
-               last_requested_article = id;
+       last_requested_article = id;
 
-               console.log(query);
+       console.log(query);
 
-               if (article_is_unread) {
-                       decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
-               }
+       if (article_is_unread) {
+               decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
+       }
 
-               new Ajax.Request("backend.php", {
-                       parameters: query,
-                       onComplete: function(transport) {
-                               article_callback2(transport, id);
-                       } });
+       new Ajax.Request("backend.php", {
+               parameters: query,
+               onComplete: function(transport) {
+                       article_callback2(transport, id);
+               } });
 
-               return false;
+       return false;
 
-       } catch (e) {
-               exception_error("view", e);
-       }
 }
 
 function toggleMark(id, client_only) {
-       try {
-               var query = "?op=rpc&id=" + id + "&method=mark";
+       var query = "?op=rpc&id=" + id + "&method=mark";
 
-               var row = $("RROW-" + id);
-               if (!row) return;
+       var row = $("RROW-" + id);
+       if (!row) return;
 
-               var imgs = [];
+       var imgs = [];
 
-               var row_imgs = row.getElementsByClassName("markedPic");
+       var row_imgs = row.getElementsByClassName("markedPic");
 
-               for (var i = 0; i < row_imgs.length; i++)
-                       imgs.push(row_imgs[i]);
+       for (var i = 0; i < row_imgs.length; i++)
+               imgs.push(row_imgs[i]);
 
-               var ft = $("floatingTitle");
+       var ft = $("floatingTitle");
 
-               if (ft && ft.getAttribute("data-article-id") == id) {
-                       var fte = ft.getElementsByClassName("markedPic");
+       if (ft && ft.getAttribute("data-article-id") == id) {
+               var fte = ft.getElementsByClassName("markedPic");
 
-                       for (var i = 0; i < fte.length; i++)
-                               imgs.push(fte[i]);
-               }
+               for (var i = 0; i < fte.length; i++)
+                       imgs.push(fte[i]);
+       }
 
-               for (i = 0; i < imgs.length; i++) {
-                       var img = imgs[i];
+       for (i = 0; i < imgs.length; i++) {
+               var img = imgs[i];
 
-                       if (!row.hasClassName("marked")) {
-                               img.src = img.src.replace("mark_unset", "mark_set");
-                               img.alt = __("Unstar article");
-                               query = query + "&mark=1";
-                       } else {
-                               img.src = img.src.replace("mark_set", "mark_unset");
-                               img.alt = __("Star article");
-                               query = query + "&mark=0";
-                       }
+               if (!row.hasClassName("marked")) {
+                       img.src = img.src.replace("mark_unset", "mark_set");
+                       img.alt = __("Unstar article");
+                       query = query + "&mark=1";
+               } else {
+                       img.src = img.src.replace("mark_set", "mark_unset");
+                       img.alt = __("Star article");
+                       query = query + "&mark=0";
                }
+       }
 
-               row.toggleClassName("marked");
+       row.toggleClassName("marked");
 
-               if (!client_only) {
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
-                                       handle_rpc_json(transport);
-                               } });
-               }
-
-       } catch (e) {
-               exception_error("toggleMark", e);
+       if (!client_only) {
+               new Ajax.Request("backend.php", {
+                       parameters: query,
+                       onComplete: function (transport) {
+                               handle_rpc_json(transport);
+                       }
+               });
        }
 }
 
 function togglePub(id, client_only, no_effects, note) {
-       try {
-               var query = "?op=rpc&id=" + id + "&method=publ";
+       var query = "?op=rpc&id=" + id + "&method=publ";
 
-               if (note != undefined) {
-                       query = query + "&note=" + param_escape(note);
-               } else {
-                       query = query + "&note=undefined";
-               }
+       if (note != undefined) {
+               query = query + "&note=" + param_escape(note);
+       } else {
+               query = query + "&note=undefined";
+       }
 
-               var row = $("RROW-" + id);
-               if (!row) return;
+       var row = $("RROW-" + id);
+       if (!row) return;
 
-               var imgs = [];
+       var imgs = [];
 
-               var row_imgs = row.getElementsByClassName("pubPic");
+       var row_imgs = row.getElementsByClassName("pubPic");
 
-               for (var i = 0; i < row_imgs.length; i++)
-                       imgs.push(row_imgs[i]);
+       for (var i = 0; i < row_imgs.length; i++)
+               imgs.push(row_imgs[i]);
 
-               var ft = $("floatingTitle");
+       var ft = $("floatingTitle");
 
-               if (ft && ft.getAttribute("data-article-id") == id) {
-                       var fte = ft.getElementsByClassName("pubPic");
+       if (ft && ft.getAttribute("data-article-id") == id) {
+               var fte = ft.getElementsByClassName("pubPic");
 
-                       for (var i = 0; i < fte.length; i++)
-                               imgs.push(fte[i]);
-               }
+               for (var i = 0; i < fte.length; i++)
+                       imgs.push(fte[i]);
+       }
 
-               for (i = 0; i < imgs.length; i++) {
-                       var img = imgs[i];
+       for (i = 0; i < imgs.length; i++) {
+               var img = imgs[i];
 
-                       if (!row.hasClassName("published") || note != undefined) {
-                               img.src = img.src.replace("pub_unset", "pub_set");
-                               img.alt = __("Unpublish article");
-                               query = query + "&pub=1";
-                       } else {
-                               img.src = img.src.replace("pub_set", "pub_unset");
-                               img.alt = __("Publish article");
-                               query = query + "&pub=0";
-                       }
+               if (!row.hasClassName("published") || note != undefined) {
+                       img.src = img.src.replace("pub_unset", "pub_set");
+                       img.alt = __("Unpublish article");
+                       query = query + "&pub=1";
+               } else {
+                       img.src = img.src.replace("pub_set", "pub_unset");
+                       img.alt = __("Publish article");
+                       query = query + "&pub=0";
                }
+       }
 
-               if (note != undefined)
-                       row.addClassName("published");
-               else
-                       row.toggleClassName("published");
-
-               if (!client_only) {
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
-                                       handle_rpc_json(transport);
-                               } });
-               }
+       if (note != undefined)
+               row.addClassName("published");
+       else
+               row.toggleClassName("published");
 
-       } catch (e) {
-               exception_error("togglePub", e);
+       if (!client_only) {
+               new Ajax.Request("backend.php", {
+                       parameters: query,
+                       onComplete: function(transport) {
+                               handle_rpc_json(transport);
+                       } });
        }
+
 }
 
 function moveToPost(mode, noscroll, noexpand) {
+       var rows = getLoadedArticleIds();
 
-       try {
-
-               var rows = getLoadedArticleIds();
-
-               var prev_id = false;
-               var next_id = false;
+       var prev_id = false;
+       var next_id = false;
 
-               if (!$('RROW-' + getActiveArticleId())) {
-                       setActiveArticleId(0);
-               }
+       if (!$('RROW-' + getActiveArticleId())) {
+               setActiveArticleId(0);
+       }
 
-               if (!getActiveArticleId()) {
-                       next_id = rows[0];
-                       prev_id = rows[rows.length-1]
-               } else {
-                       for (var i = 0; i < rows.length; i++) {
-                               if (rows[i] == getActiveArticleId()) {
+       if (!getActiveArticleId()) {
+               next_id = rows[0];
+               prev_id = rows[rows.length-1]
+       } else {
+               for (var i = 0; i < rows.length; i++) {
+                       if (rows[i] == getActiveArticleId()) {
 
-                                       // Account for adjacent identical article ids.
-                                       if (i > 0) prev_id = rows[i-1];
+                               // Account for adjacent identical article ids.
+                               if (i > 0) prev_id = rows[i-1];
 
-                                       for (var j = i+1; j < rows.length; j++) {
-                                               if (rows[j] != getActiveArticleId()) {
-                                                       next_id = rows[j];
-                                                       break;
-                                               }
+                               for (var j = i+1; j < rows.length; j++) {
+                                       if (rows[j] != getActiveArticleId()) {
+                                               next_id = rows[j];
+                                               break;
                                        }
-                                       break;
                                }
+                               break;
                        }
                }
+       }
 
-               console.log("cur: " + getActiveArticleId() + " next: " + next_id);
-
-               if (mode == "next") {
-                       if (next_id || getActiveArticleId()) {
-                               if (isCdmMode()) {
+       console.log("cur: " + getActiveArticleId() + " next: " + next_id);
 
-                                       var article = $("RROW-" + getActiveArticleId());
-                                       var ctr = $("headlines-frame");
+       if (mode == "next") {
+               if (next_id || getActiveArticleId()) {
+                       if (isCdmMode()) {
 
-                                       if (!noscroll && article && article.offsetTop + article.offsetHeight >
-                                                       ctr.scrollTop + ctr.offsetHeight) {
+                               var article = $("RROW-" + getActiveArticleId());
+                               var ctr = $("headlines-frame");
 
-                                               scrollArticle(ctr.offsetHeight/4);
+                               if (!noscroll && article && article.offsetTop + article.offsetHeight >
+                                               ctr.scrollTop + ctr.offsetHeight) {
 
-                                       } else if (next_id) {
-                                               cdmExpandArticle(next_id, noexpand);
-                                               cdmScrollToArticleId(next_id, true);
-                                       }
+                                       scrollArticle(ctr.offsetHeight/4);
 
                                } else if (next_id) {
-                                       correctHeadlinesOffset(next_id);
-                                       view(next_id, getActiveFeedId(), noexpand);
+                                       cdmExpandArticle(next_id, noexpand);
+                                       cdmScrollToArticleId(next_id, true);
                                }
+
+                       } else if (next_id) {
+                               correctHeadlinesOffset(next_id);
+                               view(next_id, getActiveFeedId(), noexpand);
                        }
                }
+       }
 
-               if (mode == "prev") {
-                       if (prev_id || getActiveArticleId()) {
-                               if (isCdmMode()) {
+       if (mode == "prev") {
+               if (prev_id || getActiveArticleId()) {
+                       if (isCdmMode()) {
 
-                                       var article = $("RROW-" + getActiveArticleId());
-                                       var prev_article = $("RROW-" + prev_id);
-                                       var ctr = $("headlines-frame");
+                               var article = $("RROW-" + getActiveArticleId());
+                               var prev_article = $("RROW-" + prev_id);
+                               var ctr = $("headlines-frame");
 
-                                       if (!getInitParam("cdm_expanded")) {
+                               if (!getInitParam("cdm_expanded")) {
 
-                                               if (!noscroll && article && article.offsetTop < ctr.scrollTop) {
-                                                       scrollArticle(-ctr.offsetHeight/4);
-                                               } else {
-                                                       cdmExpandArticle(prev_id, noexpand);
-                                                       cdmScrollToArticleId(prev_id, true);
-                                               }
+                                       if (!noscroll && article && article.offsetTop < ctr.scrollTop) {
+                                               scrollArticle(-ctr.offsetHeight/4);
                                        } else {
-
-                                               if (!noscroll && article && article.offsetTop < ctr.scrollTop) {
-                                                       scrollArticle(-ctr.offsetHeight/3);
-                                               } else if (!noscroll && prev_article &&
-                                                               prev_article.offsetTop < ctr.scrollTop) {
-                                                       cdmExpandArticle(prev_id, noexpand);
-                                                       scrollArticle(-ctr.offsetHeight/4);
-                                               } else if (prev_id) {
-                                                       cdmExpandArticle(prev_id, noexpand);
-                                                       cdmScrollToArticleId(prev_id, noscroll);
-                                               }
+                                               cdmExpandArticle(prev_id, noexpand);
+                                               cdmScrollToArticleId(prev_id, true);
                                        }
+                               } else {
 
-                               } else if (prev_id) {
-                                       correctHeadlinesOffset(prev_id);
-                                       view(prev_id, getActiveFeedId(), noexpand);
+                                       if (!noscroll && article && article.offsetTop < ctr.scrollTop) {
+                                               scrollArticle(-ctr.offsetHeight/3);
+                                       } else if (!noscroll && prev_article &&
+                                                       prev_article.offsetTop < ctr.scrollTop) {
+                                               cdmExpandArticle(prev_id, noexpand);
+                                               scrollArticle(-ctr.offsetHeight/4);
+                                       } else if (prev_id) {
+                                               cdmExpandArticle(prev_id, noexpand);
+                                               cdmScrollToArticleId(prev_id, noscroll);
+                                       }
                                }
+
+                       } else if (prev_id) {
+                               correctHeadlinesOffset(prev_id);
+                               view(prev_id, getActiveFeedId(), noexpand);
                        }
                }
-
-       } catch (e) {
-               exception_error("moveToPost", e);
        }
+
 }
 
 function toggleSelected(id, force_on) {
-       try {
-               var row = $("RROW-" + id);
+       var row = $("RROW-" + id);
 
-               if (row) {
-                       var cb = dijit.getEnclosingWidget(
-                                       row.getElementsByClassName("rchk")[0]);
+       if (row) {
+               var cb = dijit.getEnclosingWidget(
+                               row.getElementsByClassName("rchk")[0]);
 
-                       if (row.hasClassName('Selected') && !force_on) {
-                               row.removeClassName('Selected');
-                               if (cb) cb.attr("checked", false);
-                       } else {
-                               row.addClassName('Selected');
-                               if (cb) cb.attr("checked", true);
-                       }
+               if (row.hasClassName('Selected') && !force_on) {
+                       row.removeClassName('Selected');
+                       if (cb) cb.attr("checked", false);
+               } else {
+                       row.addClassName('Selected');
+                       if (cb) cb.attr("checked", true);
                }
-
-               updateSelectedPrompt();
-       } catch (e) {
-               exception_error("toggleSelected", e);
        }
+
+       updateSelectedPrompt();
 }
 
 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);
+       var count = getSelectedArticleIds2().size();
+       var elem = $("selected_prompt");
 
-                       if (count > 0)
-                               Element.show(elem);
-                       else
-                               Element.hide(elem);
-               }
+       if (elem) {
+               elem.innerHTML = ngettext("%d article selected",
+                               "%d articles selected", count).replace("%d", count);
 
-       } catch (e) {
-               exception_error("updateSelectedPrompt", e);
+               if (count > 0)
+                       Element.show(elem);
+               else
+                       Element.hide(elem);
        }
+
 }
 
 function toggleUnread(id, cmode, effect) {
-       try {
-
-               var row = $("RROW-" + id);
-               if (row) {
-                       var tmpClassName = row.className;
-
-                       if (cmode == undefined || cmode == 2) {
-                               if (row.hasClassName("Unread")) {
-                                       row.removeClassName("Unread");
-
-                               } else {
-                                       row.addClassName("Unread");
-                               }
-
-                       } else if (cmode == 0) {
+       var row = $("RROW-" + id);
+       if (row) {
+               var tmpClassName = row.className;
 
+               if (cmode == undefined || cmode == 2) {
+                       if (row.hasClassName("Unread")) {
                                row.removeClassName("Unread");
 
-                       } else if (cmode == 1) {
+                       } else {
                                row.addClassName("Unread");
                        }
 
-                       if (cmode == undefined) cmode = 2;
-
-                       var query = "?op=rpc&method=catchupSelected" +
-                               "&cmode=" + param_escape(cmode) + "&ids=" + param_escape(id);
-
-//                     notify_progress("Loading, please wait...");
-
-                       if (tmpClassName != row.className) {
-                               new Ajax.Request("backend.php", {
-                                       parameters: query,
-                                       onComplete: function (transport) {
-                                               handle_rpc_json(transport);
-                                       }
-                               });
-                       }
-
-               }
-
-       } catch (e) {
-               exception_error("toggleUnread", e);
-       }
-}
-
-function selectionRemoveLabel(id, ids) {
-       try {
+               } else if (cmode == 0) {
 
-               if (!ids) ids = getSelectedArticleIds2();
+                       row.removeClassName("Unread");
 
-               if (ids.length == 0) {
-                       alert(__("No articles are selected."));
-                       return;
+               } else if (cmode == 1) {
+                       row.addClassName("Unread");
                }
 
-               var query = "?op=article&method=removeFromLabel&ids=" +
-                       param_escape(ids.toString()) + "&lid=" + param_escape(id);
+               if (cmode == undefined) cmode = 2;
 
-               console.log(query);
+               var query = "?op=rpc&method=catchupSelected" +
+                       "&cmode=" + param_escape(cmode) + "&ids=" + param_escape(id);
 
-               new Ajax.Request("backend.php", {
-                       parameters: query,
-                       onComplete: function(transport) {
-                               handle_rpc_json(transport);
-                               show_labels_in_headlines(transport);
-                       } });
+//                     notify_progress("Loading, please wait...");
 
-       } catch (e) {
-               exception_error("selectionAssignLabel", e);
+               if (tmpClassName != row.className) {
+                       new Ajax.Request("backend.php", {
+                               parameters: query,
+                               onComplete: function (transport) {
+                                       handle_rpc_json(transport);
+                               }
+                       });
+               }
 
        }
 }
 
-function selectionAssignLabel(id, ids) {
-       try {
+function selectionRemoveLabel(id, ids) {
+       if (!ids) ids = getSelectedArticleIds2();
 
-               if (!ids) ids = getSelectedArticleIds2();
+       if (ids.length == 0) {
+               alert(__("No articles are selected."));
+               return;
+       }
 
-               if (ids.length == 0) {
-                       alert(__("No articles are selected."));
-                       return;
-               }
+       var query = "?op=article&method=removeFromLabel&ids=" +
+               param_escape(ids.toString()) + "&lid=" + param_escape(id);
 
-               var query = "?op=article&method=assignToLabel&ids=" +
-                       param_escape(ids.toString()) + "&lid=" + param_escape(id);
+       console.log(query);
 
-               console.log(query);
+       new Ajax.Request("backend.php", {
+               parameters: query,
+               onComplete: function(transport) {
+                       handle_rpc_json(transport);
+                       show_labels_in_headlines(transport);
+               } });
 
-               new Ajax.Request("backend.php", {
-                       parameters: query,
-                       onComplete: function(transport) {
-                               handle_rpc_json(transport);
-                               show_labels_in_headlines(transport);
-                       } });
+}
 
-       } catch (e) {
-               exception_error("selectionAssignLabel", e);
+function selectionAssignLabel(id, ids) {
+       if (!ids) ids = getSelectedArticleIds2();
 
+       if (ids.length == 0) {
+               alert(__("No articles are selected."));
+               return;
        }
+
+       var query = "?op=article&method=assignToLabel&ids=" +
+               param_escape(ids.toString()) + "&lid=" + param_escape(id);
+
+       console.log(query);
+
+       new Ajax.Request("backend.php", {
+               parameters: query,
+               onComplete: function(transport) {
+                       handle_rpc_json(transport);
+                       show_labels_in_headlines(transport);
+               } });
 }
 
 function selectionToggleUnread(set_state, callback, no_error, ids) {
-       try {
-               var rows = ids ? ids : getSelectedArticleIds2();
-
-               if (rows.length == 0 && !no_error) {
-                       alert(__("No articles are selected."));
-                       return;
-               }
+       var rows = ids ? ids : getSelectedArticleIds2();
 
-               for (var i = 0; i < rows.length; i++) {
-                       var row = $("RROW-" + rows[i]);
-                       if (row) {
-                               if (set_state == undefined) {
-                                       if (row.hasClassName("Unread")) {
-                                               row.removeClassName("Unread");
-                                       } else {
-                                               row.addClassName("Unread");
-                                       }
-                               }
+       if (rows.length == 0 && !no_error) {
+               alert(__("No articles are selected."));
+               return;
+       }
 
-                               if (set_state == false) {
+       for (var i = 0; i < rows.length; i++) {
+               var row = $("RROW-" + rows[i]);
+               if (row) {
+                       if (set_state == undefined) {
+                               if (row.hasClassName("Unread")) {
                                        row.removeClassName("Unread");
-                               }
-
-                               if (set_state == true) {
+                               } else {
                                        row.addClassName("Unread");
                                }
                        }
-               }
 
-               updateFloatingTitle(true);
-
-               if (rows.length > 0) {
-
-                       var cmode = "";
+                       if (set_state == false) {
+                               row.removeClassName("Unread");
+                       }
 
-                       if (set_state == undefined) {
-                               cmode = "2";
-                       } else if (set_state == true) {
-                               cmode = "1";
-                       } else if (set_state == false) {
-                               cmode = "0";
+                       if (set_state == true) {
+                               row.addClassName("Unread");
                        }
+               }
+       }
 
-                       var query = "?op=rpc&method=catchupSelected" +
-                               "&cmode=" + cmode + "&ids=" + param_escape(rows.toString());
+       updateFloatingTitle(true);
 
-                       notify_progress("Loading, please wait...");
+       if (rows.length > 0) {
 
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
-                                       handle_rpc_json(transport);
-                                       if (callback) callback(transport);
-                               } });
+               var cmode = "";
 
+               if (set_state == undefined) {
+                       cmode = "2";
+               } else if (set_state == true) {
+                       cmode = "1";
+               } else if (set_state == false) {
+                       cmode = "0";
                }
 
-       } catch (e) {
-               exception_error("selectionToggleUnread", e);
+               var query = "?op=rpc&method=catchupSelected" +
+                       "&cmode=" + cmode + "&ids=" + param_escape(rows.toString());
+
+               notify_progress("Loading, please wait...");
+
+               new Ajax.Request("backend.php", {
+                       parameters: query,
+                       onComplete: function(transport) {
+                               handle_rpc_json(transport);
+                               if (callback) callback(transport);
+                       } });
+
        }
 }
 
 // sel_state ignored
 function selectionToggleMarked(sel_state, callback, no_error, ids) {
-       try {
-
-               var rows = ids ? ids : getSelectedArticleIds2();
+       var rows = ids ? ids : getSelectedArticleIds2();
 
-               if (rows.length == 0 && !no_error) {
-                       alert(__("No articles are selected."));
-                       return;
-               }
-
-               for (var i = 0; i < rows.length; i++) {
-                       toggleMark(rows[i], true, true);
-               }
+       if (rows.length == 0 && !no_error) {
+               alert(__("No articles are selected."));
+               return;
+       }
 
-               if (rows.length > 0) {
+       for (var i = 0; i < rows.length; i++) {
+               toggleMark(rows[i], true, true);
+       }
 
-                       var query = "?op=rpc&method=markSelected&ids=" +
-                               param_escape(rows.toString()) + "&cmode=2";
+       if (rows.length > 0) {
 
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
-                                       handle_rpc_json(transport);
-                                       if (callback) callback(transport);
-                               } });
+               var query = "?op=rpc&method=markSelected&ids=" +
+                       param_escape(rows.toString()) + "&cmode=2";
 
-               }
+               new Ajax.Request("backend.php", {
+                       parameters: query,
+                       onComplete: function(transport) {
+                               handle_rpc_json(transport);
+                               if (callback) callback(transport);
+                       } });
 
-       } catch (e) {
-               exception_error("selectionToggleMarked", e);
        }
 }
 
 // sel_state ignored
 function selectionTogglePublished(sel_state, callback, no_error, ids) {
-       try {
-
-               var rows = ids ? ids : getSelectedArticleIds2();
+       var rows = ids ? ids : getSelectedArticleIds2();
 
-               if (rows.length == 0 && !no_error) {
-                       alert(__("No articles are selected."));
-                       return;
-               }
-
-               for (var i = 0; i < rows.length; i++) {
-                       togglePub(rows[i], true, true);
-               }
+       if (rows.length == 0 && !no_error) {
+               alert(__("No articles are selected."));
+               return;
+       }
 
-               if (rows.length > 0) {
+       for (var i = 0; i < rows.length; i++) {
+               togglePub(rows[i], true, true);
+       }
 
-                       var query = "?op=rpc&method=publishSelected&ids=" +
-                               param_escape(rows.toString()) + "&cmode=2";
+       if (rows.length > 0) {
 
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
-                                       handle_rpc_json(transport);
-                               } });
+               var query = "?op=rpc&method=publishSelected&ids=" +
+                       param_escape(rows.toString()) + "&cmode=2";
 
-               }
+               new Ajax.Request("backend.php", {
+                       parameters: query,
+                       onComplete: function(transport) {
+                               handle_rpc_json(transport);
+                       } });
 
-       } catch (e) {
-               exception_error("selectionToggleMarked", e);
        }
 }
 
@@ -939,267 +855,240 @@ function getLoadedArticleIds() {
 
 // mode = all,none,unread,invert,marked,published
 function selectArticles(mode, query) {
-       try {
-
-               if (!query) query = "#headlines-frame > div[id*=RROW]";
+       if (!query) query = "#headlines-frame > div[id*=RROW]";
 
-               var children = $$(query);
+       var children = $$(query);
 
-               children.each(function(child) {
-                       var id = child.getAttribute("data-article-id");
+       children.each(function(child) {
+               var id = child.getAttribute("data-article-id");
 
-                       var cb = dijit.getEnclosingWidget(
-                                       child.getElementsByClassName("rchk")[0]);
+               var cb = dijit.getEnclosingWidget(
+                               child.getElementsByClassName("rchk")[0]);
 
-                       if (mode == "all") {
+               if (mode == "all") {
+                       child.addClassName("Selected");
+                       if (cb) cb.attr("checked", true);
+               } else if (mode == "unread") {
+                       if (child.hasClassName("Unread")) {
                                child.addClassName("Selected");
                                if (cb) cb.attr("checked", true);
-                       } else if (mode == "unread") {
-                               if (child.hasClassName("Unread")) {
-                                       child.addClassName("Selected");
-                                       if (cb) cb.attr("checked", true);
-                               } else {
-                                       child.removeClassName("Selected");
-                                       if (cb) cb.attr("checked", false);
-                               }
-                       } else if (mode == "marked") {
-                               if (child.hasClassName("marked")) {
-                                       child.addClassName("Selected");
-                                       if (cb) cb.attr("checked", true);
-                               } else {
-                                       child.removeClassName("Selected");
-                                       if (cb) cb.attr("checked", false);
-                               }
-                       } else if (mode == "published") {
-                               if (child.hasClassName("published")) {
-                                       child.addClassName("Selected");
-                                       if (cb) cb.attr("checked", true);
-                               } else {
-                                       child.removeClassName("Selected");
-                                       if (cb) cb.attr("checked", false);
-                               }
-
-                       } else if (mode == "invert") {
-                               if (child.hasClassName("Selected")) {
-                                       child.removeClassName("Selected");
-                                       if (cb) cb.attr("checked", false);
-                               } else {
-                                       child.addClassName("Selected");
-                                       if (cb) cb.attr("checked", true);
-                               }
-
                        } else {
                                child.removeClassName("Selected");
                                if (cb) cb.attr("checked", false);
                        }
-               });
+               } else if (mode == "marked") {
+                       if (child.hasClassName("marked")) {
+                               child.addClassName("Selected");
+                               if (cb) cb.attr("checked", true);
+                       } else {
+                               child.removeClassName("Selected");
+                               if (cb) cb.attr("checked", false);
+                       }
+               } else if (mode == "published") {
+                       if (child.hasClassName("published")) {
+                               child.addClassName("Selected");
+                               if (cb) cb.attr("checked", true);
+                       } else {
+                               child.removeClassName("Selected");
+                               if (cb) cb.attr("checked", false);
+                       }
+
+               } else if (mode == "invert") {
+                       if (child.hasClassName("Selected")) {
+                               child.removeClassName("Selected");
+                               if (cb) cb.attr("checked", false);
+                       } else {
+                               child.addClassName("Selected");
+                               if (cb) cb.attr("checked", true);
+                       }
 
-               updateSelectedPrompt();
+               } else {
+                       child.removeClassName("Selected");
+                       if (cb) cb.attr("checked", false);
+               }
+       });
 
-       } catch (e) {
-               exception_error("selectArticles", e);
-       }
+       updateSelectedPrompt();
 }
 
 function deleteSelection() {
 
-       try {
-
-               var rows = getSelectedArticleIds2();
-
-               if (rows.length == 0) {
-                       alert(__("No articles are selected."));
-                       return;
-               }
+       var rows = getSelectedArticleIds2();
 
-               var fn = getFeedName(getActiveFeedId(), activeFeedIsCat());
-               var str;
+       if (rows.length == 0) {
+               alert(__("No articles are selected."));
+               return;
+       }
 
-               if (getActiveFeedId() != 0) {
-                       str = ngettext("Delete %d selected article in %s?", "Delete %d selected articles in %s?" , rows.length);
-               } else {
-                       str = ngettext("Delete %d selected article?", "Delete %d selected articles?", rows.length);
-               }
+       var fn = getFeedName(getActiveFeedId(), activeFeedIsCat());
+       var str;
 
-               str = str.replace("%d", rows.length);
-               str = str.replace("%s", fn);
+       if (getActiveFeedId() != 0) {
+               str = ngettext("Delete %d selected article in %s?", "Delete %d selected articles in %s?", rows.length);
+       } else {
+               str = ngettext("Delete %d selected article?", "Delete %d selected articles?", rows.length);
+       }
 
-               if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
-                       return;
-               }
+       str = str.replace("%d", rows.length);
+       str = str.replace("%s", fn);
 
-               query = "?op=rpc&method=delete&ids=" + param_escape(rows);
+       if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
+               return;
+       }
 
-               console.log(query);
+       query = "?op=rpc&method=delete&ids=" + param_escape(rows);
 
-               new Ajax.Request("backend.php", {
-                       parameters: query,
-                       onComplete: function(transport) {
-                                       handle_rpc_json(transport);
-                                       viewCurrentFeed();
-                               } });
+       console.log(query);
 
-       } catch (e) {
-               exception_error("deleteSelection", e);
-       }
+       new Ajax.Request("backend.php", {
+               parameters: query,
+               onComplete: function (transport) {
+                       handle_rpc_json(transport);
+                       viewCurrentFeed();
+               }
+       });
 }
 
 function archiveSelection() {
 
-       try {
-
-               var rows = getSelectedArticleIds2();
+       var rows = getSelectedArticleIds2();
 
-               if (rows.length == 0) {
-                       alert(__("No articles are selected."));
-                       return;
-               }
+       if (rows.length == 0) {
+               alert(__("No articles are selected."));
+               return;
+       }
 
-               var fn = getFeedName(getActiveFeedId(), activeFeedIsCat());
-               var str;
-               var op;
+       var fn = getFeedName(getActiveFeedId(), activeFeedIsCat());
+       var str;
+       var op;
 
-               if (getActiveFeedId() != 0) {
-                       str = ngettext("Archive %d selected article in %s?", "Archive %d selected articles in %s?", rows.length);
-                       op = "archive";
-               } else {
-                       str = ngettext("Move %d archived article back?", "Move %d archived articles back?", rows.length);
+       if (getActiveFeedId() != 0) {
+               str = ngettext("Archive %d selected article in %s?", "Archive %d selected articles in %s?", rows.length);
+               op = "archive";
+       } else {
+               str = ngettext("Move %d archived article back?", "Move %d archived articles back?", rows.length);
 
-                       str += " " + __("Please note that unstarred articles might get purged on next feed update.");
+               str += " " + __("Please note that unstarred articles might get purged on next feed update.");
 
-                       op = "unarchive";
-               }
+               op = "unarchive";
+       }
 
-               str = str.replace("%d", rows.length);
-               str = str.replace("%s", fn);
+       str = str.replace("%d", rows.length);
+       str = str.replace("%s", fn);
 
-               if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
-                       return;
-               }
+       if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
+               return;
+       }
 
-               query = "?op=rpc&method="+op+"&ids=" + param_escape(rows);
+       query = "?op=rpc&method="+op+"&ids=" + param_escape(rows);
 
-               console.log(query);
+       console.log(query);
 
-               for (var i = 0; i < rows.length; i++) {
-                       cache_delete("article:" + rows[i]);
-               }
+       for (var i = 0; i < rows.length; i++) {
+               cache_delete("article:" + rows[i]);
+       }
 
-               new Ajax.Request("backend.php", {
-                       parameters: query,
-                       onComplete: function(transport) {
-                                       handle_rpc_json(transport);
-                                       viewCurrentFeed();
-                               } });
+       new Ajax.Request("backend.php", {
+               parameters: query,
+               onComplete: function(transport) {
+                               handle_rpc_json(transport);
+                               viewCurrentFeed();
+                       } });
 
-       } catch (e) {
-               exception_error("archiveSelection", e);
-       }
 }
 
 function catchupSelection() {
 
-       try {
-
-               var rows = getSelectedArticleIds2();
-
-               if (rows.length == 0) {
-                       alert(__("No articles are selected."));
-                       return;
-               }
-
-               var fn = getFeedName(getActiveFeedId(), activeFeedIsCat());
+       var rows = getSelectedArticleIds2();
 
-               var str = ngettext("Mark %d selected article in %s as read?", "Mark %d selected articles in %s as read?", rows.length);
+       if (rows.length == 0) {
+               alert(__("No articles are selected."));
+               return;
+       }
 
-               str = str.replace("%d", rows.length);
-               str = str.replace("%s", fn);
+       var fn = getFeedName(getActiveFeedId(), activeFeedIsCat());
 
-               if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
-                       return;
-               }
+       var str = ngettext("Mark %d selected article in %s as read?", "Mark %d selected articles in %s as read?", rows.length);
 
-               selectionToggleUnread(false, 'viewCurrentFeed()', true);
+       str = str.replace("%d", rows.length);
+       str = str.replace("%s", fn);
 
-       } catch (e) {
-               exception_error("catchupSelection", e);
+       if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
+               return;
        }
+
+       selectionToggleUnread(false, 'viewCurrentFeed()', true);
 }
 
 function editArticleTags(id) {
-               var query = "backend.php?op=article&method=editArticleTags&param=" + param_escape(id);
+       var query = "backend.php?op=article&method=editArticleTags&param=" + param_escape(id);
 
-               if (dijit.byId("editTagsDlg"))
-                       dijit.byId("editTagsDlg").destroyRecursive();
+       if (dijit.byId("editTagsDlg"))
+               dijit.byId("editTagsDlg").destroyRecursive();
 
-               dialog = new dijit.Dialog({
-                       id: "editTagsDlg",
-                       title: __("Edit article Tags"),
-                       style: "width: 600px",
-                       execute: function() {
-                               if (this.validate()) {
-                                       var query = dojo.objectToQuery(this.attr('value'));
+       dialog = new dijit.Dialog({
+               id: "editTagsDlg",
+               title: __("Edit article Tags"),
+               style: "width: 600px",
+               execute: function() {
+                       if (this.validate()) {
+                               var query = dojo.objectToQuery(this.attr('value'));
 
-                                       notify_progress("Saving article tags...", true);
+                               notify_progress("Saving article tags...", true);
 
-                                       new Ajax.Request("backend.php", {
-                                       parameters: query,
-                                       onComplete: function(transport) {
-                                               try {
-                                                       notify('');
-                                                       dialog.hide();
+                               new Ajax.Request("backend.php", {
+                               parameters: query,
+                               onComplete: function(transport) {
+                                       try {
+                                               notify('');
+                                               dialog.hide();
 
-                                                       var data = JSON.parse(transport.responseText);
+                                               var data = JSON.parse(transport.responseText);
 
-                                                       if (data) {
-                                                               var id = data.id;
+                                               if (data) {
+                                                       var id = data.id;
 
-                                                               console.log(id);
+                                                       console.log(id);
 
-                                                               var tags = $("ATSTR-" + id);
-                                                               var tooltip = dijit.byId("ATSTRTIP-" + id);
+                                                       var tags = $("ATSTR-" + id);
+                                                       var tooltip = dijit.byId("ATSTRTIP-" + id);
 
-                                                               if (tags) tags.innerHTML = data.content;
-                                                               if (tooltip) tooltip.attr('label', data.content_full);
-                                                       }
-                                               } catch (e) {
-                                                       exception_error("editArticleTags/inner", e);
+                                                       if (tags) tags.innerHTML = data.content;
+                                                       if (tooltip) tooltip.attr('label', data.content_full);
                                                }
+                                       } catch (e) {
+                                               exception_error(e);
+                                       }
 
-                                       }});
-                               }
-                       },
-                       href: query
-               });
+                               }});
+                       }
+               },
+               href: query
+       });
 
-               var tmph = dojo.connect(dialog, 'onLoad', function() {
-                       dojo.disconnect(tmph);
+       var 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();
+       dialog.show();
 
 }
 
 function cdmScrollToArticleId(id, force) {
-       try {
-               var ctr = $("headlines-frame");
-               var e = $("RROW-" + id);
-
-               if (!e || !ctr) return;
+       var ctr = $("headlines-frame");
+       var e = $("RROW-" + id);
 
-               if (force || e.offsetTop+e.offsetHeight > (ctr.scrollTop+ctr.offsetHeight) ||
-                               e.offsetTop < ctr.scrollTop) {
+       if (!e || !ctr) return;
 
-                       // expanded cdm has a 4px margin now
-                       ctr.scrollTop = parseInt(e.offsetTop) - 4;
-               }
+       if (force || e.offsetTop+e.offsetHeight > (ctr.scrollTop+ctr.offsetHeight) ||
+                       e.offsetTop < ctr.scrollTop) {
 
-       } catch (e) {
-               exception_error("cdmScrollToArticleId", e);
+               // expanded cdm has a 4px margin now
+               ctr.scrollTop = parseInt(e.offsetTop) - 4;
        }
 }
 
@@ -1223,31 +1112,26 @@ function postMouseOut(id) {
 }
 
 function unpackVisibleHeadlines() {
-       try {
-               if (!isCdmMode() || !getInitParam("cdm_expanded")) return;
+       if (!isCdmMode() || !getInitParam("cdm_expanded")) return;
 
-               $$("#headlines-frame span.cencw[id]").each(
-                       function(child) {
-                               var row = $("RROW-" + child.id.replace("CENCW-", ""));
+       $$("#headlines-frame span.cencw[id]").each(
+               function (child) {
+                       var row = $("RROW-" + child.id.replace("CENCW-", ""));
 
-                               if (row && row.offsetTop <= $("headlines-frame").scrollTop +
-                                       $("headlines-frame").offsetHeight) {
+                       if (row && row.offsetTop <= $("headlines-frame").scrollTop +
+                               $("headlines-frame").offsetHeight) {
 
-                                       //console.log("unpacking: " + child.id);
+                               //console.log("unpacking: " + child.id);
 
-                                       child.innerHTML = htmlspecialchars_decode(child.innerHTML);
-                                       child.removeAttribute('id');
+                               child.innerHTML = htmlspecialchars_decode(child.innerHTML);
+                               child.removeAttribute('id');
 
-                                       PluginHost.run(PluginHost.HOOK_ARTICLE_RENDERED_CDM, row);
+                               PluginHost.run(PluginHost.HOOK_ARTICLE_RENDERED_CDM, row);
 
-                                       Element.show(child);
-                               }
+                               Element.show(child);
                        }
-               );
-
-       } catch (e) {
-               exception_error("unpackVisibleHeadlines", e);
-       }
+               }
+       );
 }
 
 function headlines_scroll_handler(e) {
@@ -1351,238 +1235,215 @@ function headlines_scroll_handler(e) {
 }
 
 function openNextUnreadFeed() {
-       try {
-               var is_cat = activeFeedIsCat();
-               var nuf = getNextUnreadFeed(getActiveFeedId(), is_cat);
-               if (nuf) viewfeed({feed: nuf, is_cat: is_cat});
-       } catch (e) {
-               exception_error("openNextUnreadFeed", e);
-       }
+       var is_cat = activeFeedIsCat();
+       var nuf = getNextUnreadFeed(getActiveFeedId(), is_cat);
+       if (nuf) viewfeed({feed: nuf, is_cat: is_cat});
 }
 
 function catchupBatchedArticles() {
-       try {
-               if (catchup_id_batch.length > 0 && !_infscroll_request_sent && !_catchup_request_sent) {
+       if (catchup_id_batch.length > 0 && !_infscroll_request_sent && !_catchup_request_sent) {
 
-                       console.log("catchupBatchedArticles: working");
-
-                       // make a copy of the array
-                       var batch = catchup_id_batch.slice();
-                       var query = "?op=rpc&method=catchupSelected" +
-                               "&cmode=0&ids=" + param_escape(batch.toString());
+               console.log("catchupBatchedArticles: working");
 
-                       console.log(query);
+               // make a copy of the array
+               var batch = catchup_id_batch.slice();
+               var query = "?op=rpc&method=catchupSelected" +
+                       "&cmode=0&ids=" + param_escape(batch.toString());
 
-                       _catchup_request_sent = true;
+               console.log(query);
 
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
-                                       handle_rpc_json(transport);
+               _catchup_request_sent = true;
 
-                                       _catchup_request_sent = false;
+               new Ajax.Request("backend.php", {
+                       parameters: query,
+                       onComplete: function (transport) {
+                               handle_rpc_json(transport);
 
-                                       reply = JSON.parse(transport.responseText);
-                                       var batch = reply.ids;
+                               _catchup_request_sent = false;
 
-                                       batch.each(function(id) {
-                                               console.log(id);
-                                               var elem = $("RROW-" + id);
-                                               if (elem) elem.removeClassName("Unread");
-                                               catchup_id_batch.remove(id);
-                                       });
+                               reply = JSON.parse(transport.responseText);
+                               var batch = reply.ids;
 
-                                       updateFloatingTitle(true);
+                               batch.each(function (id) {
+                                       console.log(id);
+                                       var elem = $("RROW-" + id);
+                                       if (elem) elem.removeClassName("Unread");
+                                       catchup_id_batch.remove(id);
+                               });
 
-                               } });
-               }
+                               updateFloatingTitle(true);
 
-       } catch (e) {
-               exception_error("catchupBatchedArticles", e);
+                       }
+               });
        }
 }
 
 function catchupRelativeToArticle(below, id) {
 
-       try {
-
-               if (!id) id = getActiveArticleId();
+       if (!id) id = getActiveArticleId();
 
-               if (!id) {
-                       alert(__("No article is selected."));
-                       return;
-               }
+       if (!id) {
+               alert(__("No article is selected."));
+               return;
+       }
 
-               var visible_ids = getLoadedArticleIds();
+       var visible_ids = getLoadedArticleIds();
 
-               var ids_to_mark = new Array();
+       var ids_to_mark = new Array();
 
-               if (!below) {
-                       for (var i = 0; i < visible_ids.length; i++) {
-                               if (visible_ids[i] != id) {
-                                       var e = $("RROW-" + visible_ids[i]);
+       if (!below) {
+               for (var i = 0; i < visible_ids.length; i++) {
+                       if (visible_ids[i] != id) {
+                               var 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 (var i = visible_ids.length-1; i >= 0; i--) {
-                               if (visible_ids[i] != id) {
-                                       var e = $("RROW-" + visible_ids[i]);
+               }
+       } else {
+               for (var i = visible_ids.length - 1; i >= 0; i--) {
+                       if (visible_ids[i] != id) {
+                               var 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 {
-                       var 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 {
+               var msg = ngettext("Mark %d article as read?", "Mark %d articles as read?", ids_to_mark.length).replace("%d", ids_to_mark.length);
 
-                       if (getInitParam("confirm_feed_catchup") != 1 || confirm(msg)) {
+               if (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");
+                       }
 
-                               var query = "?op=rpc&method=catchupSelected" +
-                                       "&cmode=0" + "&ids=" + param_escape(ids_to_mark.toString());
+                       var query = "?op=rpc&method=catchupSelected" +
+                               "&cmode=0" + "&ids=" + param_escape(ids_to_mark.toString());
 
-                               new Ajax.Request("backend.php", {
-                                       parameters: query,
-                                       onComplete: function(transport) {
-                                               handle_rpc_json(transport);
-                                       } });
+                       new Ajax.Request("backend.php", {
+                               parameters: query,
+                               onComplete: function (transport) {
+                                       handle_rpc_json(transport);
+                               }
+                       });
 
-                       }
                }
-
-       } catch (e) {
-               exception_error("catchupRelativeToArticle", e);
        }
 }
 
 function cdmCollapseArticle(event, id, unmark) {
-       try {
-               if (unmark == undefined) unmark = true;
+       if (unmark == undefined) unmark = true;
 
-               var row = $("RROW-" + id);
-               var elem = $("CICD-" + id);
-
-               if (elem && row) {
-                       var collapse = row.select("span[class='collapseBtn']")[0];
+       var row = $("RROW-" + id);
+       var elem = $("CICD-" + id);
 
-                       Element.hide(elem);
-                       Element.show("CEXC-" + id);
-                       Element.hide(collapse);
+       if (elem && row) {
+               var collapse = row.select("span[class='collapseBtn']")[0];
 
-                       if (unmark) {
-                               row.removeClassName("active");
+               Element.hide(elem);
+               Element.show("CEXC-" + id);
+               Element.hide(collapse);
 
-                               markHeadline(id, false);
+               if (unmark) {
+                       row.removeClassName("active");
 
-                               if (id == getActiveArticleId()) {
-                                       setActiveArticleId(0);
-                               }
+                       markHeadline(id, false);
 
-                               updateSelectedPrompt();
+                       if (id == getActiveArticleId()) {
+                               setActiveArticleId(0);
                        }
 
-                       if (event) Event.stop(event);
+                       updateSelectedPrompt();
+               }
 
-                       PluginHost.run(PluginHost.HOOK_ARTICLE_COLLAPSED, id);
+               if (event) Event.stop(event);
 
-                       if (row.offsetTop < $("headlines-frame").scrollTop)
-                               scrollToRowId(row.id);
+               PluginHost.run(PluginHost.HOOK_ARTICLE_COLLAPSED, id);
 
-                       $("floatingTitle").style.visibility = "hidden";
-                       $("floatingTitle").setAttribute("data-article-id", 0);
-               }
+               if (row.offsetTop < $("headlines-frame").scrollTop)
+                       scrollToRowId(row.id);
 
-       } catch (e) {
-               exception_error("cdmCollapseArticle", e);
+               $("floatingTitle").style.visibility = "hidden";
+               $("floatingTitle").setAttribute("data-article-id", 0);
        }
 }
 
 function cdmExpandArticle(id, noexpand) {
-       try {
-               console.log("cdmExpandArticle " + id);
+       console.log("cdmExpandArticle " + id);
 
-               var row = $("RROW-" + id);
-
-               if (!row) return false;
+       var row = $("RROW-" + id);
 
-               var oldrow = $("RROW-" + getActiveArticleId());
+       if (!row) return false;
 
-               var elem = $("CICD-" + getActiveArticleId());
+       var oldrow = $("RROW-" + getActiveArticleId());
 
-               if (id == getActiveArticleId() && Element.visible(elem))
-                       return true;
+       var elem = $("CICD-" + getActiveArticleId());
 
-               selectArticles("none");
+       if (id == getActiveArticleId() && Element.visible(elem))
+               return true;
 
-               var old_offset = row.offsetTop;
+       selectArticles("none");
 
-               if (getActiveArticleId() && elem && !getInitParam("cdm_expanded")) {
-                       var collapse = oldrow.select("span[class='collapseBtn']")[0];
+       var old_offset = row.offsetTop;
 
-                       Element.hide(elem);
-                       Element.show("CEXC-" + getActiveArticleId());
-                       Element.hide(collapse);
-               }
+       if (getActiveArticleId() && elem && !getInitParam("cdm_expanded")) {
+               var collapse = oldrow.select("span[class='collapseBtn']")[0];
 
-               if (oldrow) oldrow.removeClassName("active");
+               Element.hide(elem);
+               Element.show("CEXC-" + getActiveArticleId());
+               Element.hide(collapse);
+       }
 
-               setActiveArticleId(id);
+       if (oldrow) oldrow.removeClassName("active");
 
-               elem = $("CICD-" + id);
+       setActiveArticleId(id);
 
-               var collapse = row.select("span[class='collapseBtn']")[0];
+       elem = $("CICD-" + id);
 
-               var cencw = $("CENCW-" + id);
+       var collapse = row.select("span[class='collapseBtn']")[0];
 
-               if (!Element.visible(elem) && !noexpand) {
-                       if (cencw) {
-                               cencw.innerHTML = htmlspecialchars_decode(cencw.innerHTML);
-                               cencw.setAttribute('id', '');
-                               Element.show(cencw);
-                       }
+       var cencw = $("CENCW-" + id);
 
-                       Element.show(elem);
-                       Element.hide("CEXC-" + id);
-                       Element.show(collapse);
+       if (!Element.visible(elem) && !noexpand) {
+               if (cencw) {
+                       cencw.innerHTML = htmlspecialchars_decode(cencw.innerHTML);
+                       cencw.setAttribute('id', '');
+                       Element.show(cencw);
                }
 
-               var new_offset = row.offsetTop;
+               Element.show(elem);
+               Element.hide("CEXC-" + id);
+               Element.show(collapse);
+       }
 
-               if (old_offset > new_offset)
-                       $("headlines-frame").scrollTop -= (old_offset-new_offset);
+       var new_offset = row.offsetTop;
 
-               if (!noexpand) {
-                       if (catchup_id_batch.indexOf(id) == -1)
-                               catchup_id_batch.push(id);
+       if (old_offset > new_offset)
+               $("headlines-frame").scrollTop -= (old_offset - new_offset);
 
-                       catchupCurrentBatchIfNeeded();
-               }
+       if (!noexpand) {
+               if (catchup_id_batch.indexOf(id) == -1)
+                       catchup_id_batch.push(id);
 
-               toggleSelected(id);
-               row.addClassName("active");
+               catchupCurrentBatchIfNeeded();
+       }
 
-               PluginHost.run(PluginHost.HOOK_ARTICLE_EXPANDED, id);
+       toggleSelected(id);
+       row.addClassName("active");
 
-       } catch (e) {
-               exception_error("cdmExpandArticle", e);
-       }
+       PluginHost.run(PluginHost.HOOK_ARTICLE_EXPANDED, id);
 
        return false;
 }
@@ -1592,125 +1453,108 @@ function getArticleUnderPointer() {
 }
 
 function scrollArticle(offset) {
-       try {
-               if (!isCdmMode()) {
-                       var ci = $("content-insert");
-                       if (ci) {
-                               ci.scrollTop += offset;
-                       }
-               } else {
-                       var hi = $("headlines-frame");
-                       if (hi) {
-                               hi.scrollTop += offset;
-                       }
-
+       if (!isCdmMode()) {
+               var ci = $("content-insert");
+               if (ci) {
+                       ci.scrollTop += offset;
                }
-       } catch (e) {
-               exception_error("scrollArticle", e);
+       } else {
+               var hi = $("headlines-frame");
+               if (hi) {
+                       hi.scrollTop += offset;
+               }
+
        }
 }
 
 function show_labels_in_headlines(transport) {
-       try {
-               var data = JSON.parse(transport.responseText);
+       var data = JSON.parse(transport.responseText);
 
-               if (data) {
-                       data['info-for-headlines'].each(function(elem) {
-                               $$(".HLLCTR-" + elem.id).each(function(ctr) {
-                                       ctr.innerHTML = elem.labels;
-                               });
+       if (data) {
+               data['info-for-headlines'].each(function (elem) {
+                       $$(".HLLCTR-" + elem.id).each(function (ctr) {
+                               ctr.innerHTML = elem.labels;
                        });
-               }
-       } catch (e) {
-               exception_error("show_labels_in_headlines", e);
+               });
        }
 }
 
 function cdmClicked(event, id) {
-       try {
-               //var shift_key = event.shiftKey;
+       //var shift_key = event.shiftKey;
 
-               if (!event.ctrlKey && !event.metaKey) {
+       if (!event.ctrlKey && !event.metaKey) {
 
-                       if (!getInitParam("cdm_expanded")) {
-                               return cdmExpandArticle(id);
-                       } else {
-
-                               var elem = $("RROW-" + getActiveArticleId());
-
-                               if (elem) elem.removeClassName("active");
-
-                               selectArticles("none");
-                               toggleSelected(id);
+               if (!getInitParam("cdm_expanded")) {
+                       return cdmExpandArticle(id);
+               } else {
 
-                               var elem = $("RROW-" + id);
-                               var article_is_unread = elem.hasClassName("Unread");
+                       var elem = $("RROW-" + getActiveArticleId());
 
-                               elem.removeClassName("Unread");
-                               elem.addClassName("active");
+                       if (elem) elem.removeClassName("active");
 
-                               setActiveArticleId(id);
+                       selectArticles("none");
+                       toggleSelected(id);
 
-                               if (article_is_unread) {
-                                       decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
-                                       updateFloatingTitle(true);
-                               }
+                       var elem = $("RROW-" + id);
+                       var article_is_unread = elem.hasClassName("Unread");
 
-                               var query = "?op=rpc&method=catchupSelected" +
-                                       "&cmode=0&ids=" + param_escape(id);
+                       elem.removeClassName("Unread");
+                       elem.addClassName("active");
 
-                               new Ajax.Request("backend.php", {
-                                       parameters: query,
-                                       onComplete: function(transport) {
-                                               handle_rpc_json(transport);
-                                       } });
+                       setActiveArticleId(id);
 
-                               return !event.shiftKey;
+                       if (article_is_unread) {
+                               decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
+                               updateFloatingTitle(true);
                        }
 
-               } else if (event.target.parents(".cdmHeader").length > 0) {
+                       var query = "?op=rpc&method=catchupSelected" +
+                               "&cmode=0&ids=" + param_escape(id);
 
-                       toggleSelected(id, true);
+                       new Ajax.Request("backend.php", {
+                               parameters: query,
+                               onComplete: function (transport) {
+                                       handle_rpc_json(transport);
+                               }
+                       });
 
-                       var elem = $("RROW-" + id);
-                       var article_is_unread = elem.hasClassName("Unread");
+                       return !event.shiftKey;
+               }
 
-                       if (article_is_unread) {
-                               decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
-                       }
+       } else if (event.target.parents(".cdmHeader").length > 0) {
 
-                       toggleUnread(id, 0, false);
+               toggleSelected(id, true);
 
-                       openArticleInNewWindow(id);
+               var elem = $("RROW-" + id);
+               var article_is_unread = elem.hasClassName("Unread");
+
+               if (article_is_unread) {
+                       decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
                }
 
-               var unread_in_buffer = $$("#headlines-frame > div[id*=RROW][class*=Unread]").length
-               request_counters(unread_in_buffer == 0);
+               toggleUnread(id, 0, false);
 
-       } catch (e) {
-               exception_error("cdmClicked");
+               openArticleInNewWindow(id);
        }
 
+       var unread_in_buffer = $$("#headlines-frame > div[id*=RROW][class*=Unread]").length
+       request_counters(unread_in_buffer == 0);
+
        return false;
 }
 
 function hlClicked(event, id) {
-       try {
-               if (event.which == 2) {
-                       view(id);
-                       return true;
-               } else if (event.ctrlKey || event.metaKey) {
-                       toggleSelected(id, true);
-                       toggleUnread(id, 0, false);
-                       openArticleInNewWindow(id);
-                       return false;
-               } else {
-                       view(id);
-                       return false;
-               }
-
-       } catch (e) {
-               exception_error("hlClicked");
+       if (event.which == 2) {
+               view(id);
+               return true;
+       } else if (event.ctrlKey || event.metaKey) {
+               toggleSelected(id, true);
+               toggleUnread(id, 0, false);
+               openArticleInNewWindow(id);
+               return false;
+       } else {
+               view(id);
+               return false;
        }
 }
 
@@ -1749,24 +1593,18 @@ function getRelativePostIds(id, limit) {
 
        var tmp = [];
 
-       try {
-
-               if (!limit) limit = 6; //3
+       if (!limit) limit = 6; //3
 
-               var ids = getLoadedArticleIds();
+       var ids = getLoadedArticleIds();
 
-               for (var i = 0; i < ids.length; i++) {
-                       if (ids[i] == id) {
-                               for (var k = 1; k <= limit; k++) {
-                                       //if (i > k-1) tmp.push(ids[i-k]);
-                                       if (i < ids.length-k) tmp.push(ids[i+k]);
-                               }
-                               break;
+       for (var i = 0; i < ids.length; i++) {
+               if (ids[i] == id) {
+                       for (var k = 1; k <= limit; k++) {
+                               //if (i > k-1) tmp.push(ids[i-k]);
+                               if (i < ids.length - k) tmp.push(ids[i + k]);
                        }
+                       break;
                }
-
-       } catch (e) {
-               exception_error("getRelativePostIds", e);
        }
 
        return tmp;
@@ -1774,44 +1612,33 @@ function getRelativePostIds(id, limit) {
 
 function correctHeadlinesOffset(id) {
 
-       try {
-
-               var container = $("headlines-frame");
-               var row = $("RROW-" + id);
-
-               if (!container || !row) return;
+       var container = $("headlines-frame");
+       var row = $("RROW-" + id);
 
-               var viewport = container.offsetHeight;
+       if (!container || !row) return;
 
-               var rel_offset_top = row.offsetTop - container.scrollTop;
-               var rel_offset_bottom = row.offsetTop + row.offsetHeight - container.scrollTop;
+       var viewport = container.offsetHeight;
 
-               //console.log("Rtop: " + rel_offset_top + " Rbtm: " + rel_offset_bottom);
-               //console.log("Vport: " + viewport);
+       var rel_offset_top = row.offsetTop - container.scrollTop;
+       var rel_offset_bottom = row.offsetTop + row.offsetHeight - container.scrollTop;
 
-               if (rel_offset_top <= 0 || rel_offset_top > viewport) {
-                       container.scrollTop = row.offsetTop;
-               } else if (rel_offset_bottom > viewport) {
+       //console.log("Rtop: " + rel_offset_top + " Rbtm: " + rel_offset_bottom);
+       //console.log("Vport: " + viewport);
 
-                       /* doesn't properly work with Opera in some cases because
-                               Opera fucks up element scrolling */
+       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;
-               }
+               /* doesn't properly work with Opera in some cases because
+                Opera fucks up element scrolling */
 
-       } catch (e) {
-               exception_error("correctHeadlinesOffset", e);
+               container.scrollTop = row.offsetTop + row.offsetHeight - viewport;
        }
-
 }
 
 function headlineActionsChange(elem) {
-       try {
-               eval(elem.value);
-               elem.attr('value', 'false');
-       } catch (e) {
-               exception_error("headlineActionsChange", e);
-       }
+       eval(elem.value);
+       elem.attr('value', 'false');
 }
 
 function closeArticlePanel() {
@@ -1822,219 +1649,212 @@ function closeArticlePanel() {
 }
 
 function initFloatingMenu() {
-       try {
-               if (!dijit.byId("floatingMenu")) {
-
-                       var menu = new dijit.Menu({
-                               id: "floatingMenu",
-                               targetNodeIds: ["floatingTitle"]
-                       });
+       if (!dijit.byId("floatingMenu")) {
 
-                       headlinesMenuCommon(menu);
+               var menu = new dijit.Menu({
+                       id: "floatingMenu",
+                       targetNodeIds: ["floatingTitle"]
+               });
 
-                       menu.startup();
-               }
+               headlinesMenuCommon(menu);
 
-       } catch (e) {
-               exception_error("initFloatingMenu", e);
+               menu.startup();
        }
 }
 
 function headlinesMenuCommon(menu) {
-       try {
-
-               menu.addChild(new dijit.MenuItem({
-                       label: __("Open original article"),
-                       onClick: function(event) {
-                               openArticleInNewWindow(this.getParent().currentTarget.getAttribute("data-article-id"));
-                       }}));
-
-               menu.addChild(new dijit.MenuItem({
-                       label: __("Display article URL"),
-                       onClick: function(event) {
-                               displayArticleUrl(this.getParent().currentTarget.getAttribute("data-article-id"));
-                       }}));
 
-               menu.addChild(new dijit.MenuSeparator());
+       menu.addChild(new dijit.MenuItem({
+               label: __("Open original article"),
+               onClick: function (event) {
+                       openArticleInNewWindow(this.getParent().currentTarget.getAttribute("data-article-id"));
+               }
+       }));
 
-               menu.addChild(new dijit.MenuItem({
-                       label: __("Toggle unread"),
-                       onClick: function(event) {
+       menu.addChild(new dijit.MenuItem({
+               label: __("Display article URL"),
+               onClick: function (event) {
+                       displayArticleUrl(this.getParent().currentTarget.getAttribute("data-article-id"));
+               }
+       }));
 
-                               var ids = getSelectedArticleIds2();
-                               // cast to string
-                               var id = (this.getParent().currentTarget.getAttribute("data-article-id")) + "";
-                               ids = ids.size() != 0 && ids.indexOf(id) != -1 ? ids : [id];
+       menu.addChild(new dijit.MenuSeparator());
 
-                               selectionToggleUnread(undefined, false, true, ids);
-                               }}));
+       menu.addChild(new dijit.MenuItem({
+               label: __("Toggle unread"),
+               onClick: function (event) {
 
-               menu.addChild(new dijit.MenuItem({
-                       label: __("Toggle starred"),
-                       onClick: function(event) {
-                               var ids = getSelectedArticleIds2();
-                               // cast to string
-                               var id = (this.getParent().currentTarget.getAttribute("data-article-id")) + "";
-                               ids = ids.size() != 0 && ids.indexOf(id) != -1 ? ids : [id];
+                       var ids = getSelectedArticleIds2();
+                       // cast to string
+                       var id = (this.getParent().currentTarget.getAttribute("data-article-id")) + "";
+                       ids = ids.size() != 0 && ids.indexOf(id) != -1 ? ids : [id];
 
-                               selectionToggleMarked(undefined, false, true, ids);
-                               }}));
+                       selectionToggleUnread(undefined, false, true, ids);
+               }
+       }));
 
-               menu.addChild(new dijit.MenuItem({
-                       label: __("Toggle published"),
-                       onClick: function(event) {
-                               var ids = getSelectedArticleIds2();
-                               // cast to string
-                               var id = (this.getParent().currentTarget.getAttribute("data-article-id")) + "";
-                               ids = ids.size() != 0 && ids.indexOf(id) != -1 ? ids : [id];
+       menu.addChild(new dijit.MenuItem({
+               label: __("Toggle starred"),
+               onClick: function (event) {
+                       var ids = getSelectedArticleIds2();
+                       // cast to string
+                       var id = (this.getParent().currentTarget.getAttribute("data-article-id")) + "";
+                       ids = ids.size() != 0 && ids.indexOf(id) != -1 ? ids : [id];
 
-                               selectionTogglePublished(undefined, false, true, ids);
-                               }}));
+                       selectionToggleMarked(undefined, false, true, ids);
+               }
+       }));
 
-               menu.addChild(new dijit.MenuSeparator());
+       menu.addChild(new dijit.MenuItem({
+               label: __("Toggle published"),
+               onClick: function (event) {
+                       var ids = getSelectedArticleIds2();
+                       // cast to string
+                       var id = (this.getParent().currentTarget.getAttribute("data-article-id")) + "";
+                       ids = ids.size() != 0 && ids.indexOf(id) != -1 ? ids : [id];
 
-               menu.addChild(new dijit.MenuItem({
-                       label: __("Mark above as read"),
-                       onClick: function(event) {
-                               catchupRelativeToArticle(0, this.getParent().currentTarget.getAttribute("data-article-id"));
-                               }}));
+                       selectionTogglePublished(undefined, false, true, ids);
+               }
+       }));
 
-               menu.addChild(new dijit.MenuItem({
-                       label: __("Mark below as read"),
-                       onClick: function(event) {
-                               catchupRelativeToArticle(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 (event) {
+                       catchupRelativeToArticle(0, this.getParent().currentTarget.getAttribute("data-article-id"));
+               }
+       }));
 
-               var labels = dijit.byId("feedTree").model.getItemsInCategory(-2);
+       menu.addChild(new dijit.MenuItem({
+               label: __("Mark below as read"),
+               onClick: function (event) {
+                       catchupRelativeToArticle(1, this.getParent().currentTarget.getAttribute("data-article-id"));
+               }
+       }));
 
-               if (labels) {
 
-                       menu.addChild(new dijit.MenuSeparator());
+       var labels = dijit.byId("feedTree").model.getItemsInCategory(-2);
 
-                       var labelAddMenu = new dijit.Menu({ownerMenu: menu});
-                       var labelDelMenu = new dijit.Menu({ownerMenu: menu});
+       if (labels) {
 
-                       labels.each(function(label) {
-                               var id = label.id[0];
-                               var bare_id = id.substr(id.indexOf(":")+1);
-                               var name = label.name[0];
+               menu.addChild(new dijit.MenuSeparator());
 
-                               bare_id = feed_to_label_id(bare_id);
+               var labelAddMenu = new dijit.Menu({ownerMenu: menu});
+               var labelDelMenu = new dijit.Menu({ownerMenu: menu});
 
-                               labelAddMenu.addChild(new dijit.MenuItem({
-                                       label: name,
-                                       labelId: bare_id,
-                                       onClick: function(event) {
+               labels.each(function (label) {
+                       var id = label.id[0];
+                       var bare_id = id.substr(id.indexOf(":") + 1);
+                       var name = label.name[0];
 
-                                               var ids = getSelectedArticleIds2();
-                                               // cast to string
-                                               var id = (this.getParent().ownerMenu.currentTarget.getAttribute("data-article-id")) + "";
+                       bare_id = feed_to_label_id(bare_id);
 
-                                               ids = ids.size() != 0 && ids.indexOf(id) != -1 ? ids : [id];
+                       labelAddMenu.addChild(new dijit.MenuItem({
+                               label: name,
+                               labelId: bare_id,
+                               onClick: function (event) {
 
-                                               selectionAssignLabel(this.labelId, ids);
-                               }}));
+                                       var ids = getSelectedArticleIds2();
+                                       // cast to string
+                                       var id = (this.getParent().ownerMenu.currentTarget.getAttribute("data-article-id")) + "";
 
-                               labelDelMenu.addChild(new dijit.MenuItem({
-                                       label: name,
-                                       labelId: bare_id,
-                                       onClick: function(event) {
-                                               var ids = getSelectedArticleIds2();
-                                               // cast to string
-                                               var id = (this.getParent().ownerMenu.currentTarget.getAttribute("data-article-id")) + "";
+                                       ids = ids.size() != 0 && ids.indexOf(id) != -1 ? ids : [id];
 
-                                               ids = ids.size() != 0 && ids.indexOf(id) != -1 ? ids : [id];
+                                       selectionAssignLabel(this.labelId, ids);
+                               }
+                       }));
 
-                                               selectionRemoveLabel(this.labelId, ids);
-                               }}));
+                       labelDelMenu.addChild(new dijit.MenuItem({
+                               label: name,
+                               labelId: bare_id,
+                               onClick: function (event) {
+                                       var ids = getSelectedArticleIds2();
+                                       // cast to string
+                                       var id = (this.getParent().ownerMenu.currentTarget.getAttribute("data-article-id")) + "";
 
-                       });
+                                       ids = ids.size() != 0 && ids.indexOf(id) != -1 ? ids : [id];
 
-                       menu.addChild(new dijit.PopupMenuItem({
-                               label: __("Assign label"),
-                               popup: labelAddMenu
+                                       selectionRemoveLabel(this.labelId, ids);
+                               }
                        }));
 
-                       menu.addChild(new dijit.PopupMenuItem({
-                               label: __("Remove label"),
-                               popup: labelDelMenu
-                       }));
+               });
 
-               }
+               menu.addChild(new dijit.PopupMenuItem({
+                       label: __("Assign label"),
+                       popup: labelAddMenu
+               }));
 
+               menu.addChild(new dijit.PopupMenuItem({
+                       label: __("Remove label"),
+                       popup: labelDelMenu
+               }));
 
-       } catch (e) {
-               exception_error("headlinesMenuCommon", e);
        }
 }
 
 function initHeadlinesMenu() {
-       try {
-               if (!dijit.byId("headlinesMenu")) {
-
-                       var menu = new dijit.Menu({
-                               id: "headlinesMenu",
-                               targetNodeIds: ["headlines-frame"],
-                               selector: ".hlMenuAttach"
-                       });
+       if (!dijit.byId("headlinesMenu")) {
 
-                       headlinesMenuCommon(menu);
+               var menu = new dijit.Menu({
+                       id: "headlinesMenu",
+                       targetNodeIds: ["headlines-frame"],
+                       selector: ".hlMenuAttach"
+               });
 
-                       menu.startup();
-               }
+               headlinesMenuCommon(menu);
 
-               /* vgroup feed title menu */
+               menu.startup();
+       }
 
-               if (!dijit.byId("headlinesFeedTitleMenu")) {
+       /* vgroup feed title menu */
 
-                       var 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) {
-                                       selectArticles("all",
-                                               "#headlines-frame > div[id*=RROW]" +
-                                               "[data-orig-feed-id='" + this.getParent().currentTarget.getAttribute("data-feed-id") + "']");
+               var 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) {
+                               selectArticles("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 (event) {
-                                       selectArticles("none");
-                                       selectArticles("all",
-                                               "#headlines-frame > div[id*=RROW]" +
-                                               "[data-orig-feed-id='" + this.getParent().currentTarget.getAttribute("data-feed-id") + "']");
+                       }
+               }));
 
-                                       catchupSelection();
-                               }
-                       }));
+               menu.addChild(new dijit.MenuItem({
+                       label: __("Mark group as read"),
+                       onClick: function (event) {
+                               selectArticles("none");
+                               selectArticles("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 (event) {
-                                       catchupFeedInGroup(this.getParent().currentTarget.getAttribute("data-feed-id"));
-                               }
-                       }));
+                               catchupSelection();
+                       }
+               }));
 
-                       menu.addChild(new dijit.MenuItem({
-                               label: __("Edit feed"),
-                               onClick: function (event) {
-                                       editFeed(this.getParent().currentTarget.getAttribute("data-feed-id"));
-                               }
-                       }));
+               menu.addChild(new dijit.MenuItem({
+                       label: __("Mark feed as read"),
+                       onClick: function (event) {
+                               catchupFeedInGroup(this.getParent().currentTarget.getAttribute("data-feed-id"));
+                       }
+               }));
 
-                       menu.startup();
-               }
+               menu.addChild(new dijit.MenuItem({
+                       label: __("Edit feed"),
+                       onClick: function (event) {
+                               editFeed(this.getParent().currentTarget.getAttribute("data-feed-id"));
+                       }
+               }));
 
-       } catch (e) {
-               exception_error("initHeadlinesMenu", e);
+               menu.startup();
        }
 }
 
@@ -2064,198 +1884,171 @@ function cache_delete(id) {
 }
 
 function cancelSearch() {
-       try {
-               _search_query = "";
-               viewCurrentFeed();
-       } catch (e) {
-               exception_error("cancelSearch", e);
-       }
+       _search_query = "";
+       viewCurrentFeed();
 }
 
 function setSelectionScore() {
-       try {
-               var ids = getSelectedArticleIds2();
+       var ids = getSelectedArticleIds2();
 
-               if (ids.length > 0) {
-                       console.log(ids);
+       if (ids.length > 0) {
+               console.log(ids);
 
-                       var score = prompt(__("Please enter new score for selected articles:"), score);
+               var score = prompt(__("Please enter new score for selected articles:"), score);
 
-                       if (score != undefined) {
-                               var query = "op=article&method=setScore&id=" + param_escape(ids.toString()) +
-                                       "&score=" + param_escape(score);
+               if (score != undefined) {
+                       var query = "op=article&method=setScore&id=" + param_escape(ids.toString()) +
+                               "&score=" + param_escape(score);
 
-                               new Ajax.Request("backend.php", {
-                                       parameters: query,
-                                       onComplete: function(transport) {
-                                               var reply = JSON.parse(transport.responseText);
-                                               if (reply) {
-                                                       console.log(ids);
+                       new Ajax.Request("backend.php", {
+                               parameters: query,
+                               onComplete: function (transport) {
+                                       var reply = JSON.parse(transport.responseText);
+                                       if (reply) {
+                                               console.log(ids);
 
-                                                       ids.each(function(id) {
-                                                               var row = $("RROW-" + id);
+                                               ids.each(function (id) {
+                                                       var row = $("RROW-" + id);
 
-                                                               if (row) {
-                                                                       var pic = row.getElementsByClassName("hlScorePic")[0];
+                                                       if (row) {
+                                                               var pic = row.getElementsByClassName("hlScorePic")[0];
 
-                                                                       if (pic) {
-                                                                               pic.src = pic.src.replace(/score_.*?\.png/,
-                                                                                       reply["score_pic"]);
-                                                                               pic.setAttribute("score", score);
-                                                                       }
+                                                               if (pic) {
+                                                                       pic.src = pic.src.replace(/score_.*?\.png/,
+                                                                               reply["score_pic"]);
+                                                                       pic.setAttribute("score", score);
                                                                }
-                                                       });
-                                               }
-                                       } });
-                       }
-
-               } else {
-                       alert(__("No articles are selected."));
+                                                       }
+                                               });
+                                       }
+                               }
+                       });
                }
-       } catch (e) {
-               exception_error("setSelectionScore", e);
+
+       } else {
+               alert(__("No articles are selected."));
        }
 }
 
 function updateScore(id) {
-       try {
-               var pic = $$("#RROW-" + id + " .hlScorePic")[0];
-
-               if (pic) {
+       var pic = $$("#RROW-" + id + " .hlScorePic")[0];
 
-                       var query = "op=article&method=getScore&id=" + param_escape(id);
+       if (pic) {
 
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
-                                       console.log(transport.responseText);
+               var query = "op=article&method=getScore&id=" + param_escape(id);
 
-                                       var reply = JSON.parse(transport.responseText);
+               new Ajax.Request("backend.php", {
+                       parameters: query,
+                       onComplete: function (transport) {
+                               console.log(transport.responseText);
 
-                                       if (reply) {
-                                               pic.src = pic.src.replace(/score_.*?\.png/, reply["score_pic"]);
-                                               pic.setAttribute("score", reply["score"]);
-                                               pic.setAttribute("title", reply["score"]);
-                                       }
-                               } });
-               }
+                               var reply = JSON.parse(transport.responseText);
 
-       } catch (e) {
-               exception_error("updateScore", e);
+                               if (reply) {
+                                       pic.src = pic.src.replace(/score_.*?\.png/, reply["score_pic"]);
+                                       pic.setAttribute("score", reply["score"]);
+                                       pic.setAttribute("title", reply["score"]);
+                               }
+                       }
+               });
        }
 }
 
 function changeScore(id, pic) {
-       try {
-               var score = pic.getAttribute("score");
+       var score = pic.getAttribute("score");
 
-               var new_score = prompt(__("Please enter new score for this article:"), score);
+       var new_score = prompt(__("Please enter new score for this article:"), score);
 
-               if (new_score != undefined) {
+       if (new_score != undefined) {
 
-                       var query = "op=article&method=setScore&id=" + param_escape(id) +
-                               "&score=" + param_escape(new_score);
+               var query = "op=article&method=setScore&id=" + param_escape(id) +
+                       "&score=" + param_escape(new_score);
 
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
-                                       var reply = JSON.parse(transport.responseText);
+               new Ajax.Request("backend.php", {
+                       parameters: query,
+                       onComplete: function (transport) {
+                               var reply = JSON.parse(transport.responseText);
 
-                                       if (reply) {
-                                               pic.src = pic.src.replace(/score_.*?\.png/, reply["score_pic"]);
-                                               pic.setAttribute("score", new_score);
-                                               pic.setAttribute("title", new_score);
-                                       }
-                               } });
-               }
-       } catch (e) {
-               exception_error("changeScore", e);
+                               if (reply) {
+                                       pic.src = pic.src.replace(/score_.*?\.png/, reply["score_pic"]);
+                                       pic.setAttribute("score", new_score);
+                                       pic.setAttribute("title", new_score);
+                               }
+                       }
+               });
        }
 }
 
 function displayArticleUrl(id) {
-       try {
-               var query = "op=rpc&method=getlinktitlebyid&id=" + param_escape(id);
+       var query = "op=rpc&method=getlinktitlebyid&id=" + param_escape(id);
 
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
-                                       var reply = JSON.parse(transport.responseText);
+       new Ajax.Request("backend.php", {
+               parameters: query,
+               onComplete: function (transport) {
+                       var reply = JSON.parse(transport.responseText);
 
-                                       if (reply && reply.link) {
-                                               prompt(__("Article URL:"), reply.link);
-                                       }
-                               } });
-       } catch (e) {
-               exception_error("changeScore", e);
-       }
+                       if (reply && reply.link) {
+                               prompt(__("Article URL:"), reply.link);
+                       }
+               }
+       });
 }
 
 function scrollToRowId(id) {
-       try {
-               var row = $(id);
-
-               if (row)
-                       $("headlines-frame").scrollTop = row.offsetTop - 4;
+       var row = $(id);
 
-       } catch (e) {
-               exception_error("scrollToRowId", e);
-       }
+       if (row)
+               $("headlines-frame").scrollTop = row.offsetTop - 4;
 }
 
 function updateFloatingTitle(unread_only) {
-       try {
-               if (!isCdmMode()) return;
-
-               var hf = $("headlines-frame");
+       if (!isCdmMode()) return;
 
-               var elems = $$("#headlines-frame > div[id*=RROW]");
+       var hf = $("headlines-frame");
 
-               for (var i = 0; i < elems.length; i++) {
+       var elems = $$("#headlines-frame > div[id*=RROW]");
 
-                       var child = elems[i];
+       for (var i = 0; i < elems.length; i++) {
 
-                       if (child && child.offsetTop + child.offsetHeight > hf.scrollTop) {
+               var child = elems[i];
 
-                               var header = child.getElementsByClassName("cdmHeader")[0];
+               if (child && child.offsetTop + child.offsetHeight > hf.scrollTop) {
 
-                               if (unread_only || child.getAttribute("data-article-id") != $("floatingTitle").getAttribute("data-article-id")) {
-                                       if (child.getAttribute("data-article-id") != $("floatingTitle").getAttribute("data-article-id")) {
+                       var header = child.getElementsByClassName("cdmHeader")[0];
 
-                                               $("floatingTitle").setAttribute("data-article-id", child.getAttribute("data-article-id"));
-                                               $("floatingTitle").innerHTML = header.innerHTML;
-                                               $("floatingTitle").firstChild.innerHTML = "<img class='anchor markedPic' src='images/page_white_go.png' onclick=\"scrollToRowId('"+child.id+"')\">" + $("floatingTitle").firstChild.innerHTML;
+                       if (unread_only || child.getAttribute("data-article-id") != $("floatingTitle").getAttribute("data-article-id")) {
+                               if (child.getAttribute("data-article-id") != $("floatingTitle").getAttribute("data-article-id")) {
 
-                                               initFloatingMenu();
+                                       $("floatingTitle").setAttribute("data-article-id", child.getAttribute("data-article-id"));
+                                       $("floatingTitle").innerHTML = header.innerHTML;
+                                       $("floatingTitle").firstChild.innerHTML = "<img class='anchor markedPic' src='images/page_white_go.png' onclick=\"scrollToRowId('" + child.id + "')\">" + $("floatingTitle").firstChild.innerHTML;
 
-                                               var cb = $$("#floatingTitle .dijitCheckBox")[0];
+                                       initFloatingMenu();
 
-                                               if (cb)
-                                                       cb.parentNode.removeChild(cb);
-                                       }
-
-                                       if (child.hasClassName("Unread"))
-                                               $("floatingTitle").addClassName("Unread");
-                                       else
-                                               $("floatingTitle").removeClassName("Unread");
+                                       var cb = $$("#floatingTitle .dijitCheckBox")[0];
 
-                                       PluginHost.run(PluginHost.HOOK_FLOATING_TITLE, child);
+                                       if (cb)
+                                               cb.parentNode.removeChild(cb);
                                }
 
-                               $("floatingTitle").style.marginRight = hf.offsetWidth - child.offsetWidth + "px";
-                               if (header.offsetTop + header.offsetHeight < hf.scrollTop + $("floatingTitle").offsetHeight - 5 &&
-                                   child.offsetTop + child.offsetHeight >= hf.scrollTop + $("floatingTitle").offsetHeight - 5)
-                                       $("floatingTitle").style.visibility = "visible";
+                               if (child.hasClassName("Unread"))
+                                       $("floatingTitle").addClassName("Unread");
                                else
-                                       $("floatingTitle").style.visibility = "hidden";
-
-                               return;
+                                       $("floatingTitle").removeClassName("Unread");
 
+                               PluginHost.run(PluginHost.HOOK_FLOATING_TITLE, child);
                        }
-               }
 
-       } catch (e) {
-               exception_error("updateFloatingTitle", e);
+                       $("floatingTitle").style.marginRight = hf.offsetWidth - child.offsetWidth + "px";
+                       if (header.offsetTop + header.offsetHeight < hf.scrollTop + $("floatingTitle").offsetHeight - 5 &&
+                               child.offsetTop + child.offsetHeight >= hf.scrollTop + $("floatingTitle").offsetHeight - 5)
+                               $("floatingTitle").style.visibility = "visible";
+                       else
+                               $("floatingTitle").style.visibility = "hidden";
+
+                       return;
+
+               }
        }
 }
 
@@ -2272,4 +2065,4 @@ function catchupCurrentBatchIfNeeded() {
 
 function cdmFooterClick(event) {
        event.stopPropagation();
-}
\ No newline at end of file
+}