From 14a8fd526e74211f083f08377426b77215172d2e Mon Sep 17 00:00:00 2001 From: Max Goodman Date: Sat, 23 Mar 2013 23:59:17 -0700 Subject: [PATCH] Add JSPreload system for including JSON data at the bottoms of pages. --- r2/r2/controllers/reddit_base.py | 5 ++++- r2/r2/lib/js.py | 1 + r2/r2/lib/template_helpers.py | 17 +++++++++++++++++ r2/r2/public/static/js/base.js | 14 ++++++++++++++ r2/r2/public/static/js/preload.js | 29 +++++++++++++++++++++++++++++ r2/r2/templates/reddit.html | 1 + 6 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 r2/r2/public/static/js/preload.js diff --git a/r2/r2/controllers/reddit_base.py b/r2/r2/controllers/reddit_base.py index e2e6b6141..59f31f5f7 100644 --- a/r2/r2/controllers/reddit_base.py +++ b/r2/r2/controllers/reddit_base.py @@ -57,7 +57,7 @@ from r2.lib.errors import ( ) from r2.lib.filters import _force_utf8 from r2.lib.strings import strings -from r2.lib.template_helpers import add_sr +from r2.lib.template_helpers import add_sr, JSPreload from r2.lib.tracking import encrypt, decrypt from r2.lib.translation import set_lang from r2.lib.utils import ( @@ -888,6 +888,9 @@ class RedditController(MinimalController): if admin_bar_eligible and record_timings: g.stats.start_logging_timings() + # set up stuff needed in base templates at error time here. + c.js_preload = JSPreload() + MinimalController.pre(self) set_cnameframe() diff --git a/r2/r2/lib/js.py b/r2/r2/lib/js.py index 94b619a34..dc344e291 100755 --- a/r2/r2/lib/js.py +++ b/r2/r2/lib/js.py @@ -352,6 +352,7 @@ module["reddit-init"] = Module("reddit-init.js", "lib/underscore-1.4.4.js", "lib/store.js", "base.js", + "preload.js", "uibase.js", "strings.js", "analytics.js", diff --git a/r2/r2/lib/template_helpers.py b/r2/r2/lib/template_helpers.py index c94ddfd0c..feda1ad65 100755 --- a/r2/r2/lib/template_helpers.py +++ b/r2/r2/lib/template_helpers.py @@ -27,6 +27,7 @@ from r2.lib.utils import vote_hash, UrlParser, timesince, is_subdomain from r2.lib import hooks from r2.lib.static import static_mtime from r2.lib.media import s3_direct_url +from r2.lib import js import babel.numbers import simplejson @@ -159,6 +160,22 @@ def js_config(extra_config=None): return config +class JSPreload(js.DataSource): + def __init__(self, data=None): + if data is None: + data = {} + js.DataSource.__init__(self, "r.preload.set({content})", data) + + def set(self, url, data): + self.data[url] = data + + def use(self): + if self.data: + return js.DataSource.use(self) + else: + return '' + + def class_dict(): t_cls = [Link, Comment, Message, Subreddit] l_cls = [Listing, OrganicListing] diff --git a/r2/r2/public/static/js/base.js b/r2/r2/public/static/js/base.js index 8b60ad142..d5b1d9340 100644 --- a/r2/r2/public/static/js/base.js +++ b/r2/r2/public/static/js/base.js @@ -17,7 +17,21 @@ r.setup = function(config) { r.analytics.breadcrumbs.init() } +r.setupBackbone = function() { + Backbone.ajax = function(request) { + var preloaded = r.preload.read(request.url) + if (preloaded != null) { + request.success(preloaded) + return + } + + return Backbone.$.ajax(request) + } +} + $(function() { + r.setupBackbone() + r.login.ui.init() r.analytics.init() r.ui.init() diff --git a/r2/r2/public/static/js/preload.js b/r2/r2/public/static/js/preload.js new file mode 100644 index 000000000..837cba64c --- /dev/null +++ b/r2/r2/public/static/js/preload.js @@ -0,0 +1,29 @@ +r.preload = { + timestamp: new Date(), + maxAge: 5 * 60 * 1000, + data: {}, + + isExpired: function() { + return new Date() - this.timestamp < this.maxAge + }, + + set: function(data) { + _.extend(this.data, data) + }, + + read: function(url) { + var data = this.data[url] + + // short circuit "client side" fragment urls (which don't expire) + if (url[0] == '#') { + return data + } + + if (this.isExpired()) { + return + } + + return data + } +} + diff --git a/r2/r2/templates/reddit.html b/r2/r2/templates/reddit.html index dfeb8f738..13f611d79 100644 --- a/r2/r2/templates/reddit.html +++ b/r2/r2/templates/reddit.html @@ -118,6 +118,7 @@ <%def name="javascript_bottom()"> <% from r2.lib import js %> ${unsafe(js.use('reddit'))} + ${unsafe(c.js_preload.use())} <%def name="javascript_run()">