Created
September 20, 2012 14:06
-
-
Save jdjkelly/3756151 to your computer and use it in GitHub Desktop.
Core Pitchfork Backbone App
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is the core part of Pitchfork.com's Backbone app. | |
// The autobahn object in particular is a great example of how to layer backbone on to a traditional, CMS-driven media site while maintaing server-side view rendering. | |
var p4k = window.p4k || {}; | |
$(function() { | |
var a = p4k.core = p4k.core || {}; | |
a.Task = function(c, b) { | |
this.fn = c; | |
this.initialize(b) | |
}; | |
a.Task.auto_id = 0; | |
a.Task.prototype = { | |
initialize: function(b) { | |
b = b || {}; | |
this.id = ++a.Task.auto_id; | |
this.url = location.href; | |
this.suppress = false; | |
if (b.persist != null) { | |
this.persist = b.persist | |
} else { | |
this.persist = false | |
} | |
}, | |
delay: function(b) { | |
setTimeout(_.bind(function() { | |
if (!this.suppress) { | |
if (!this.persist && this.url != location.href) { | |
return | |
} else { | |
this.fn(this) | |
} | |
} | |
}, this), b); | |
return this | |
}, | |
same: function(b) { | |
return b && b.id == this.id | |
}, | |
cancel: function() { | |
this.suppress = true; | |
return this | |
} | |
}; | |
a.keys = { | |
soundcloud: "3ae6bc27002808463649550a768cca8f", | |
bandcamp: "anamannthrotiuppburdreinbreidr" | |
}; | |
_.extend(a, { | |
async: function(c, d, b) { | |
return new a.Task(c, b).delay(d) | |
}, | |
init: function() { | |
p4k.init = p4k.init || []; | |
p4k.init_once = p4k.init_once || []; | |
_(p4k.init).each(function(b) { | |
b() | |
}); | |
_(p4k.init_once).each(function(b) { | |
b() | |
}); | |
p4k.init_once = [] | |
} | |
}); | |
p4k.init_once.push(function() { | |
p4k.autobahn.router.on("load", p4k.core.init) | |
}) | |
}); | |
$(function() { | |
p4k.compat = function() { | |
if (typeof window.localStorage == "undefined") { | |
$("body").addClass("no-storage") | |
} | |
}; | |
p4k.init.push(p4k.compat) | |
}); | |
$(function() { | |
var a = p4k.autobahn = p4k.autobahn || {}; | |
a.Page = Backbone.Model.extend({ | |
compile: function() { | |
var f = document.createElement("div"); | |
var c = this.get("source"); | |
f.innerHTML = c; | |
var b = f.getElementsByTagName("title"); | |
if (b.length) { | |
b = b[0].innerHTML | |
} else { | |
b = document.title | |
} | |
function e(g) { | |
if (g.id == "page") { | |
return g | |
} else { | |
for (var d = 0; d < g.childNodes.length; d++) { | |
var h = e(g.childNodes[d]); | |
if (h != null) { | |
return h | |
} | |
} | |
} | |
} | |
return { | |
title: b, | |
source: c, | |
document: f, | |
fragment: e(f), | |
url: this.get("url") | |
} | |
} | |
}); | |
a.PageCollection = Backbone.Collection.extend({ | |
model: a.Page, | |
limit: 20, | |
retries: 5, | |
throttle: 1000, | |
comparator: function(b) { | |
return -b.get("time") | |
}, | |
get_page: function(c, g, e, d) { | |
d = d != undefined ? d : this.retries; | |
var b = _.bind(function(h) { | |
this.models = this.models.slice(0, this.limit); | |
e(h) | |
}, this); | |
var f = this.find(function(h) { | |
return h.get("url") == c | |
}); | |
if (!f || g) { | |
$.ajax(c, { | |
type: "GET", | |
dataType: "html", | |
success: _.bind(function(i, h, k) { | |
var j = new a.Page({ | |
url: c, | |
source: i, | |
time: (new Date()).getTime() | |
}); | |
if (f) { | |
this.remove(f) | |
} | |
this.add(j); | |
b(j) | |
}, this), | |
error: _.bind(function() { | |
if (d > 0) { | |
p4k.core.async(_.bind(function(h) { | |
this.get_page(c, g, e, d - 1) | |
}, this), this.throttle) | |
} else { | |
location.reload() | |
} | |
}, this) | |
}) | |
} else { | |
f.set({ | |
time: (new Date()).getTime() | |
}); | |
b(f) | |
} | |
} | |
}); | |
a.Router = Backbone.Router.extend({ | |
via_link: false, | |
current_page: null, | |
pages: new a.PageCollection(), | |
routes: { | |
"*actions": "on_page" | |
}, | |
initialize: function(b) { | |
this.current_page = new a.Page({ | |
url: location.href.replace(location.protocol + "//" + location.host, ""), | |
source: document.getElementsByTagName("html")[0].innerHTML, | |
time: (new Date()).getTime() | |
}); | |
this.pages.add(this.current_page) | |
}, | |
on_page: function(b) { | |
this.render(b) | |
}, | |
render: function(b) { | |
this.trigger("unload", this.current_page); | |
b = (b.charAt(0) != "/") ? "/" + b : b; | |
if (history.pushState) { | |
$("#page-load").addClass("active") | |
} | |
this.pages.get_page(b, this.via_link, _.bind(function(d) { | |
this.current_page = d; | |
if (history.pushState) { | |
$("#page-load").removeClass("active") | |
} | |
var c = d.compile(); | |
document.title = c.title; | |
$("#page").replaceWith(c.fragment); | |
if (this.via_link) { | |
this.via_link = false; | |
$(document).scrollTop(0) | |
} | |
this.trigger("load", c) | |
}, this)) | |
} | |
}); | |
a.routing = { | |
init: function() { | |
a.router = new a.Router(); | |
this.capture_links(); | |
Backbone.history.start({ | |
pushState: true, | |
silent: true, | |
hashChange: false | |
}) | |
}, | |
capture_links: function() { | |
var b = this; | |
$(document).on("click", "a", function(c) { | |
var d = c.currentTarget; | |
if (c.which > 1 || c.metaKey || c.ctrlKey) { | |
return | |
} | |
if (d.hash && d.href.replace(d.hash, "") === location.href.replace(location.hash, "")) { | |
return | |
} | |
if (location.protocol != d.protocol || location.hostname != d.hostname) { | |
return | |
} | |
if ((d.pathname.indexOf("/tv/") == 0) || (location.pathname.indexOf("/tv/") == 0) || (d.pathname.indexOf("/festivals/") == 0) || (location.pathname.indexOf("/festivals/") == 0) || (d.pathname.indexOf("/features/5-10-15-20/") == 0) || (location.pathname.indexOf("/features/5-10-15-20/") == 0) || (location.pathname.indexOf("/features/cover-story/reader/") == 0)) { | |
return | |
} | |
c.preventDefault(); | |
b.to(d.pathname + d.search, { | |
trigger: true | |
}) | |
}) | |
}, | |
to: function(c, b) { | |
if (window.history.pushState !== undefined) { | |
a.router.via_link = true; | |
if (c == a.router.current_page.get("url")) { | |
a.router.render(c) | |
} else { | |
Backbone.history.navigate(c, b) | |
} | |
} else { | |
location.href = c | |
} | |
} | |
}; | |
if (window.history.pushState !== undefined) { | |
a.routing.init() | |
} else { | |
a.router = {}; | |
a.router.on = function() {} | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment