Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
125 lines (109 sloc) 4.59 KB
# Notes:
# I tried to avoid frameworks as much as possible but
# have opted for a few external dependencies. If you
# see anything unfamiliar to you please note that
# this project relies on the following libraries:
# modernizr.js (
# domReady.js (
# radio.js (
# The ArticleController manages the current document
# fetches adjacent articles. And essentially repeats
# this process when the current article changes.
class @ArticleController
constructor: () ->
# The nav buttons are wrapped in a custom class to control their
# presentation.
@nextButton = new NavButton(element: document.querySelector("#next a"), direction: NavButton.DIRECTION_NEXT)
@prevButton = new NavButton(element:document.querySelector("#previous a"), direction: NavButton.DIRECTION_PREV)
# This radio subscription will handle page navigation via the
# directional buttons in the page UI.
radio(NavButton.CLICK_EVENT).subscribe (direction) =>
if direction == NavButton.DIRECTION_NEXT
if @nextArticle.tableOfContents
window.location = "/"
if @prevArticle.tableOfContents
window.location = "/"
# Reacting to the HTML5 popstate event. This is when
# the user navigates with the browser's forward and
# back button.
window.addEventListener("popstate", (e) =>
if @nextArticle.href == location.href
else if @prevArticle.href == location.href
# Setup the current article based on the current document.
@setCurrentArticle(new Article(
html: document.body.innerHTML
element: document.querySelector("")
# Set's the current article and grabs it's adjacent
setCurrentArticle: (@currentArticle) ->
# Make the current article current.
# Run any analytics code we may need.
if @analyticsCallback? and typeof(@analyticsCallback) == "function"
category: "articleChange"
action: "asynchronous"
pathname: location.pathname
# Grab the next and previous articles.
@nextArticle = Article.fetchFromURL(@currentArticle.nextURL)
@prevArticle = Article.fetchFromURL(@currentArticle.prevURL)
if @nextArticle?
if @nextArticle.tableOfContents
else if @nextButton.hidden()
if @prevArticle?
if @prevArticle.tableOfContents
else if @prevButton.hidden()
# The page slider manages the movement of various posts.
if @pageSlider?
@pageSlider = new PageSlider(article: @currentArticle)
# We'll listen to the page slider, check to see which direction it's
# moving toward, and display the appropriate article.
radio(PageSlider.DIRECTION_CHANGE).subscribe (direction) =>
if direction == PageSlider.DIRECTION_RIGHT
else if direction == PageSlider.DIRECTION_LEFT
# If the swipe completed we'll need to let the article controller
# to update the current article.
radio(PageSlider.DIRECTION_FINISHED).subscribe (completed) =>
@setStagedToCurrent() if completed
# Replaces the current article with the article on stage.
setStagedToCurrent: ->
if @nextArticle.isStaged()
else if @prevArticle.isStaged()
# Ensures the current article's next article is displayed
# beneath the current article. (note: next_date > current_date)
showNextArticle: ->
@prevArticle.unstage() if @prevArticle?
# Ensures the current article's previous article is displayed
# beneath the current article. (note: prev_date < current_date)
showPrevArticle: ->
@nextArticle.unstage() if @nextArticle?
# I just like to be explicit when letting people set properties
# on instances of JS based classes.
setAnalyticsCallback: (@analyticsCallback) -> typeof(@analyticsCallback) == "function"