]> git.wh0rd.org Git - tt-rss.git/commitdiff
rework caching, use html5 local storage
authorAndrew Dolgov <fox@madoka.volgo-balt.ru>
Wed, 31 Aug 2011 10:03:52 +0000 (14:03 +0400)
committerAndrew Dolgov <fox@madoka.volgo-balt.ru>
Wed, 31 Aug 2011 10:04:19 +0000 (14:04 +0400)
allow caching of headlines
code cleanup

feedlist.js
functions.js
functions.php
tt-rss.js
viewfeed.js

index fb8a5de289537b0330fc8e0a46f7ece0369c9c96..ab21a30fb4b7ac40573affd8a39b551be97c3d77 100644 (file)
@@ -50,15 +50,22 @@ function loadMoreHeadlines() {
 
 function viewfeed(feed, subop, is_cat, offset) {
        try {
-               if (is_cat == undefined) is_cat = false;
+               if (is_cat == undefined)
+                       is_cat = false;
+               else
+                       is_cat = !!is_cat;
+
                if (subop == undefined) subop = '';
                if (offset == undefined) offset = 0;
 
                last_requested_article = 0;
 
-               if (feed == getActiveFeedId()) {
-                       cache_invalidate("F:" + feed);
-               }
+               var cached_headlines = false;
+
+               if (feed == getActiveFeedId())
+                       cache_delete("feed:" + feed + ":" + is_cat);
+               else
+                       cached_headlines = cache_get("feed:" + feed + ":" + is_cat);
 
                dijit.byId("content-tabs").selectChild(
                        dijit.byId("content-tabs").getChildren()[0]);
@@ -70,6 +77,15 @@ function viewfeed(feed, subop, is_cat, offset) {
                        _infscroll_disable = 0;
                }
 
+               if (!offset && !subop && cached_headlines) {
+                       try {
+                               render_local_headlines(feed, is_cat, JSON.parse(cached_headlines));
+                               return;
+                       } catch (e) {
+                               console.warn("render_local_headlines failed: " + e);
+                       }
+               }
+
                if (offset != 0 && !subop) {
                        var date = new Date();
                        var timestamp = Math.round(date.getTime() / 1000);
@@ -283,6 +299,9 @@ function parse_counters(elems, scheduled_call) {
                                displayNewContentPrompt(id);
                        }
 
+                       if (getFeedUnread(id, (kind == "cat")) != ctr)
+                               cache_delete("feed:" + id + ":" + (kind == "cat"));
+
                        setFeedUnread(id, (kind == "cat"), ctr);
 
                        if (kind != "cat") {
index 1a06a9bf3c606d11bc06e1eb274258a3cd6880c5..1fd421809267b57d0be66ddede63ab1c4cd97640 100644 (file)
@@ -1136,13 +1136,13 @@ function backend_sanity_check_callback(transport) {
        }
 }
 
-function has_local_storage() {
+/*function has_local_storage() {
        try {
                return 'sessionStorage' in window && window['sessionStorage'] != null;
        } catch (e) {
                return false;
        }
-}
+} */
 
 function catSelectOnChange(elem) {
        try {
index e0b5fc9994c25126a1ff21de39645d144a3fbe4d..bb6164d7bc08d1ba32bece776b16ab69a24c2c1d 100644 (file)
 
                $vgroup_last_feed = $vgr_last_feed;
 
-               if (!$offset) {
+//             if (!$offset) {
 
                        if (db_num_rows($result) > 0) {
                                $reply['toolbar'] = format_headline_subtoolbar($link, $feed_site_url,
                                        $feed, $cat_view, $search, $match_on, $search_mode, $view_mode,
                                        $last_error);
                        }
-               }
+//             }
 
                $headlines_count = db_num_rows($result);
 
index 7987be7ab5bce1dd8ab83168c7e44c1dc5cfa1e1..c8f4ab83e8244bc4e80bd01a3d006036c1915e4c 100644 (file)
--- a/tt-rss.js
+++ b/tt-rss.js
@@ -330,8 +330,7 @@ function init_second_stage() {
 
                loading_set_progress(30);
 
-               if (has_local_storage())
-                       sessionStorage.clear();
+               cache_clear();
 
                console.log("second stage ok");
 
@@ -565,12 +564,10 @@ function collapse_feedlist() {
 }
 
 function viewModeChanged() {
-       cache_flush();
        return viewCurrentFeed('')
 }
 
 function viewLimitChanged() {
-       cache_flush();
        return viewCurrentFeed('')
 }
 
index 3a21323da1f208b92d8bd2811d298796d7e1c8c7..0d20faf81cecbe885338a43278028f89f40b776c 100644 (file)
@@ -9,14 +9,11 @@ var post_under_pointer = false;
 
 var last_requested_article = false;
 
-var preload_id_batch = [];
-var preload_timeout_id = false;
-
-var cache_added = [];
-
 var catchup_id_batch = [];
 var catchup_timeout_id = false;
 
+var has_storage = 'sessionStorage' in window && window['sessionStorage'] !== null;
+
 function headlines_callback2(transport, offset) {
        try {
                handle_rpc_json(transport);
@@ -138,10 +135,12 @@ function headlines_callback2(transport, offset) {
                                }
                        }
 
+                       cache_headlines(feed_id, is_cat, reply['headlines']['toolbar'], $("headlines-frame").innerHTML);
+
                        if (articles) {
                                for (var i = 0; i < articles.length; i++) {
                                        var a_id = articles[i]['id'];
-                                       cache_inject(a_id, articles[i]['content']);
+                                       cache_set("article:" + a_id, articles[i]['content']);
                                }
                        } else {
                                console.log("no cached articles received");
@@ -210,14 +209,6 @@ function showArticleInHeadlines(id) {
 
                var upd_img_pic = $("FUPDPIC-" + id);
 
-               var cache_prefix = "";
-
-               if (activeFeedIsCat()) {
-                       cache_prefix = "C:";
-               } else {
-                       cache_prefix = "F:";
-               }
-
                var view_mode = false;
 
                try {
@@ -232,22 +223,10 @@ function showArticleInHeadlines(id) {
 
                        upd_img_pic.src = "images/blank_icon.gif";
 
-                       cache_invalidate(cache_prefix + getActiveFeedId());
-
-                       /* cache_inject(cache_prefix + getActiveFeedId(),
-                               $("headlines-frame").innerHTML,
-                               getFeedUnread(getActiveFeedId())); */
+                       cache_headlines(getActiveFeedId(), activeFeedIsCat(), null, $("headlines-frame").innerHTML);
 
                } else if (article_is_unread && view_mode == "all_articles") {
-
-                       cache_invalidate(cache_prefix + getActiveFeedId());
-
-                       /* cache_inject(cache_prefix + getActiveFeedId(),
-                               $("headlines-frame").innerHTML,
-                               getFeedUnread(getActiveFeedId())-1); */
-
-               } else if (article_is_unread) {
-                       cache_invalidate(cache_prefix + getActiveFeedId());
+                       cache_headlines(getActiveFeedId(), activeFeedIsCat(), null, $("headlines-frame").innerHTML);
                }
 
                markHeadline(id);
@@ -282,7 +261,7 @@ function article_callback2(transport, id) {
                                if (active_post_id == article['id']) {
                                        render_article(article['content']);
                                }
-                               cache_inject(article['id'], article['content']);
+                               cache_set("article:" + article['id'], article['content']);
                        });
 
                } else {
@@ -307,7 +286,7 @@ function view(id) {
        try {
                console.log("loading article: " + id);
 
-               var cached_article = cache_find(id);
+               var cached_article = cache_get("article:" + id);
 
                console.log("cache check result: " + (cached_article != false));
 
@@ -322,7 +301,7 @@ function view(id) {
                var cids_to_request = Array();
 
                for (var i = 0; i < neighbor_ids.length; i++) {
-                       if (!cache_check(neighbor_ids[i])) {
+                       if (!cache_get("article:" + neighbor_ids[i])) {
                                cids_to_request.push(neighbor_ids[i]);
                        }
                }
@@ -356,9 +335,9 @@ function view(id) {
                        query = query + "&mode=prefetch_old";
                        render_article(cached_article);
 
-               }
+                       return; // do not do prefetch_old request
 
-               cache_expire();
+               }
 
                last_requested_article = id;
 
@@ -606,27 +585,17 @@ function selectionRemoveLabel(id, ids) {
                        return;
                }
 
-//             var ok = confirm(__("Remove selected articles from label?"));
+               var query = "?op=rpc&subop=removeFromLabel&ids=" +
+                       param_escape(ids.toString()) + "&lid=" + param_escape(id);
 
-//             if (ok) {
-
-                       var query = "?op=rpc&subop=removeFromLabel&ids=" +
-                               param_escape(ids.toString()) + "&lid=" + param_escape(id);
-
-                       console.log(query);
-
-//                     notify_progress("Loading, please wait...");
-
-                       cache_invalidate("F:" + (-11 - id));
-
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
-                                       handle_rpc_json(transport);
-                                       show_labels_in_headlines(transport);
-                               } });
+               console.log(query);
 
-//             }
+               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);
@@ -644,27 +613,17 @@ function selectionAssignLabel(id, ids) {
                        return;
                }
 
-//             var ok = confirm(__("Assign selected articles to label?"));
-
-//             if (ok) {
-
-                       cache_invalidate("F:" + (-11 - id));
-
-                       var query = "?op=rpc&subop=assignToLabel&ids=" +
-                               param_escape(ids.toString()) + "&lid=" + param_escape(id);
-
-                       console.log(query);
-
-//                     notify_progress("Loading, please wait...");
+               var query = "?op=rpc&subop=assignToLabel&ids=" +
+                       param_escape(ids.toString()) + "&lid=" + param_escape(id);
 
-                       new Ajax.Request("backend.php", {
-                               parameters: query,
-                               onComplete: function(transport) {
-                                       handle_rpc_json(transport);
-                                       show_labels_in_headlines(transport);
-                               } });
+               console.log(query);
 
-//             }
+               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);
@@ -959,7 +918,7 @@ function archiveSelection() {
                console.log(query);
 
                for (var i = 0; i < rows.length; i++) {
-                       cache_invalidate(rows[i]);
+                       cache_delete("article:" + rows[i]);
                }
 
                new Ajax.Request("backend.php", {
@@ -1037,7 +996,7 @@ function editArticleTags(id) {
                                                        if (tags) tags.innerHTML = tags_str.content;
                                                        if (tooltip) tooltip.attr('label', tags_str.content_full);
 
-                                                       cache_invalidate(id);
+                                                       cache_delete("article:" + id);
                                                }
 
                                        }});
@@ -1072,274 +1031,16 @@ function cdmScrollToArticleId(id) {
        }
 }
 
-function cache_inject(id, article, param) {
-
-       try {
-               if (!cache_check_param(id, param)) {
-                       //console.log("cache_article: miss: " + id + " [p=" + param + "]");
-
-                  var date = new Date();
-             var ts = Math.round(date.getTime() / 1000);
-
-                       var cache_obj = {};
-
-                       cache_obj["id"] = id;
-                       cache_obj["data"] = article;
-                       cache_obj["param"] = param;
-
-                       if (param) id = id + ":" + param;
-
-                       cache_added["TS:" + id] = ts;
-
-                       if (has_local_storage())
-                               sessionStorage.setItem(id, JSON.stringify(cache_obj));
-                       else
-                               article_cache.push(cache_obj);
-
-               } else {
-                       //console.log("cache_article: hit: " + id + " [p=" + param + "]");
-               }
-       } catch (e) {
-               exception_error("cache_inject", e);
-       }
-}
-
-function cache_find(id) {
-
-       if (has_local_storage()) {
-               var cache_obj = sessionStorage.getItem(id);
-
-               if (cache_obj) {
-                       cache_obj = JSON.parse(cache_obj);
-
-                       if (cache_obj)
-                               return cache_obj['data'];
-               }
-
-       } else {
-               for (var i = 0; i < article_cache.length; i++) {
-                       if (article_cache[i]["id"] == id) {
-                               return article_cache[i]["data"];
-                       }
-               }
-       }
-       return false;
-}
-
-function cache_find_param(id, param) {
-
-       if (has_local_storage()) {
-
-               if (param) id = id + ":" + param;
-
-               var cache_obj = sessionStorage.getItem(id);
-
-               if (cache_obj) {
-                       cache_obj = JSON.parse(cache_obj);
-
-                       if (cache_obj)
-                               return cache_obj['data'];
-               }
-
-       } else {
-               for (var i = 0; i < article_cache.length; i++) {
-                       if (article_cache[i]["id"] == id && article_cache[i]["param"] == param) {
-                               return article_cache[i]["data"];
-                       }
-               }
-       }
-
-       return false;
-}
-
-function cache_check(id) {
-       if (has_local_storage()) {
-               if (sessionStorage.getItem(id))
-                       return true;
-       } else {
-               for (var i = 0; i < article_cache.length; i++) {
-                       if (article_cache[i]["id"] == id) {
-                               return true;
-                       }
-               }
-       }
-       return false;
-}
-
-function cache_check_param(id, param) {
-       if (has_local_storage()) {
-
-               if (param) id = id + ":" + param;
-
-               if (sessionStorage.getItem(id))
-                       return true;
-
-       } else {
-               for (var i = 0; i < article_cache.length; i++) {
-                       if (article_cache[i]["id"] == id && article_cache[i]["param"] == param) {
-                               return true;
-                       }
-               }
-       }
-       return false;
-}
-
-function cache_expire() {
-if (has_local_storage()) {
-
-               var date = new Date();
-               var timestamp = Math.round(date.getTime() / 1000);
-
-               for (var i = 0; i < sessionStorage.length; i++) {
-
-                       var id = sessionStorage.key(i);
-
-                       if (timestamp - cache_added["TS:" + id] > 180) {
-                               sessionStorage.removeItem(id);
-                       }
-               }
-
-       } else {
-               while (article_cache.length > 25) {
-                       article_cache.shift();
-               }
-       }
-}
-
-function cache_flush() {
-       if (has_local_storage()) {
-               sessionStorage.clear();
-       } else {
-               article_cache = new Array();
-       }
-}
-
-function cache_invalidate(id) {
-       try {
-               if (has_local_storage()) {
-
-                       var found = false;
-
-                       for (var i = 0; i < sessionStorage.length; i++) {
-                               var key = sessionStorage.key(i);
-
-//                                     console.warn("cache_invalidate: " + key_id + " cmp " + id);
-
-                               if (key == id || key.indexOf(id + ":") == 0) {
-                                       sessionStorage.removeItem(key);
-                                       found = true;
-                                       break;
-                               }
-                       }
-
-                       return found;
-
-               } else {
-                       var i = 0
-
-                       while (i < article_cache.length) {
-                               if (article_cache[i]["id"] == id) {
-                                       //console.log("cache_invalidate: removed id " + id);
-                                       article_cache.splice(i, 1);
-                                       return true;
-                               }
-                               i++;
-                       }
-               }
-
-               //console.log("cache_invalidate: id not found: " + id);
-               return false;
-       } catch (e) {
-               exception_error("cache_invalidate", e);
-       }
-}
-
 function getActiveArticleId() {
        return active_post_id;
 }
 
-function preloadBatchedArticles() {
-       try {
-
-               var query = "?op=rpc&subop=getArticles&ids=" +
-                       preload_id_batch.toString();
-
-               new Ajax.Request("backend.php", {
-                       parameters: query,
-                       onComplete: function(transport) {
-
-                               preload_id_batch = [];
-
-                               var articles = JSON.parse(transport.responseText);
-
-                               for (var i = 0; i < articles.length; i++) {
-                                       var id = articles[i]['id'];
-                                       if (!cache_check(id)) {
-                                               cache_inject(id, articles[i]['content']);
-                                               //console.log("preloaded article: " + id);
-                                       }
-                               }
-               } });
-
-       } catch (e) {
-               exception_error("preloadBatchedArticles", e);
-       }
-}
-
-function preloadArticleUnderPointer(id) {
-       try {
-               if (getInitParam("bw_limit") == "1") return;
-
-               if (post_under_pointer == id && !cache_check(id)) {
-
-                       //console.log("trying to preload article " + id);
-
-                       var neighbor_ids = getRelativePostIds(id, 1);
-
-                       /* only request uncached articles */
-
-                       if (preload_id_batch.indexOf(id) == -1) {
-                               for (var i = 0; i < neighbor_ids.length; i++) {
-                                       if (!cache_check(neighbor_ids[i])) {
-                                               preload_id_batch.push(neighbor_ids[i]);
-                                       }
-                               }
-                       }
-
-                       if (preload_id_batch.indexOf(id) == -1)
-                               preload_id_batch.push(id);
-
-                       //console.log("preload ids batch: " + preload_id_batch.toString());
-
-                       window.clearTimeout(preload_timeout_id);
-                       preload_batch_timeout_id = window.setTimeout('preloadBatchedArticles()', 1000);
-
-               }
-       } catch (e) {
-               exception_error("preloadArticleUnderPointer", e);
-       }
-}
-
 function postMouseIn(id) {
-       try {
-               if (post_under_pointer != id) {
-                       post_under_pointer = id;
-                       if (!isCdmMode()) {
-                               window.setTimeout("preloadArticleUnderPointer(" + id + ")", 250);
-                       }
-               }
-
-       } catch (e) {
-               exception_error("postMouseIn", e);
-       }
+       post_under_pointer = id;
 }
 
 function postMouseOut(id) {
-       try {
-               post_under_pointer = false;
-       } catch (e) {
-               exception_error("postMouseOut", e);
-       }
+       post_under_pointer = false;
 }
 
 function headlines_scroll_handler(e) {
@@ -1692,13 +1393,16 @@ function show_labels_in_headlines(transport) {
 
                                if (ctr) ctr.innerHTML = elem.labels;
                        });
+
+                       cache_headlines(getActiveFeedId(), activeFeedIsCat(), null, $("headlines-frame").innerHTML);
+
                }
        } catch (e) {
                exception_error("show_labels_in_headlines", e);
        }
 }
 
-function toggleHeadlineActions() {
+/* function toggleHeadlineActions() {
        try {
                var e = $("headlineActionsBody");
                var p = $("headlineActionsDrop");
@@ -1716,7 +1420,7 @@ function toggleHeadlineActions() {
        } catch (e) {
                exception_error("toggleHeadlineActions", e);
        }
-}
+} */
 
 /* function publishWithNote(id, def_note) {
        try {
@@ -2273,7 +1977,7 @@ function editArticleNote(id) {
 
                                                var reply = JSON.parse(transport.responseText);
 
-                                               cache_invalidate(id);
+                                               cache_delete("article:" + id);
 
                                                var elem = $("POSTNOTE-" + id);
 
@@ -2325,3 +2029,69 @@ function player(elem) {
        }
 }
 
+function cache_set(id, obj) {
+       console.log("cache_set: " + id);
+       if (has_storage)
+               try {
+                       sessionStorage[id] = obj;
+               } catch (e) {
+                       if (e == QUOTA_EXCEEDED_ERR)
+                               sessionStorage.clear();
+               }
+}
+
+function cache_get(id) {
+       if (has_storage)
+               return sessionStorage[id];
+}
+
+function cache_clear() {
+       if (has_storage)
+               sessionStorage.clear();
+}
+
+function cache_delete(id) {
+       if (has_storage)
+               sessionStorage.removeItem(id);
+}
+
+function cache_headlines(feed, is_cat, toolbar_obj, content_obj) {
+       if (toolbar_obj && content_obj) {
+               cache_set("feed:" + feed + ":" + is_cat,
+                       JSON.stringify({toolbar: toolbar_obj, content: content_obj}));
+       } else {
+               try {
+                       obj =   JSON.parse(cache_get("feed:" + feed + ":" + is_cat));
+
+                       if (obj) {
+                               if (toolbar_obj) obj.toolbar = toolbar_obj;
+                               if (content_obj) obj.content = content_obj;
+
+                               cache_set("feed:" + feed + ":" + is_cat, JSON.stringify(obj));
+                       }
+
+               } catch (e) {
+                       console.warn("cache_headlines failed: " + e);
+               }
+       }
+}
+
+function render_local_headlines(feed, is_cat, obj) {
+       try {
+
+               dijit.byId("headlines-toolbar").attr('content',
+                       obj.toolbar);
+
+               dijit.byId("headlines-frame").attr('content',
+                       obj.content);
+
+               dojo.parser.parse('headlines-toolbar');
+
+               $("headlines-frame").scrollTop = 0;
+               selectArticles('none');
+               setActiveFeedId(feed, is_cat);
+               initHeadlinesMenu();
+       } catch (e) {
+               exception_error("render_local_headlines", e);
+       }
+}