fannypack 0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.ruby-version +1 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +127 -0
- data/Guardfile +6 -0
- data/LICENSE +22 -0
- data/Procfile +1 -0
- data/README.md +166 -0
- data/Rakefile +50 -0
- data/config.rb +74 -0
- data/fannypack.gemspec +22 -0
- data/lib/assets/javascripts/fanny_pack.coffee +21 -0
- data/lib/assets/javascripts/fanny_pack/ajax.js.coffee +58 -0
- data/lib/assets/javascripts/fanny_pack/env.js.coffee +4 -0
- data/lib/assets/javascripts/fanny_pack/models/environment.js.coffee +15 -0
- data/lib/assets/javascripts/fanny_pack/namespace.coffee +10 -0
- data/lib/assets/javascripts/fanny_pack/routers/base.coffee +82 -0
- data/lib/assets/javascripts/fanny_pack/version.js.coffee +2 -0
- data/lib/assets/javascripts/fanny_pack/views/app.coffee +19 -0
- data/lib/assets/javascripts/fanny_pack/views/base.coffee +90 -0
- data/lib/assets/javascripts/fanny_pack/views/list.coffee +29 -0
- data/lib/fanny_pack.rb +4 -0
- data/lib/fanny_pack/assets.rb +24 -0
- data/lib/fanny_pack/version.rb +4 -0
- data/source/images/background.png +0 -0
- data/source/images/middleman.png +0 -0
- data/source/index.html.haml +9 -0
- data/source/javascripts/application.js.coffee +2 -0
- data/source/javascripts/lib/.gitkeep +0 -0
- data/source/javascripts/vendor/.gitkeep +0 -0
- data/source/layouts/layout.html.haml +49 -0
- data/source/stylesheets/application.css.sass +2 -0
- data/source/stylesheets/lib/_fonts.css.sass +0 -0
- data/source/stylesheets/lib/_mixins.css.sass +0 -0
- data/source/stylesheets/lib/_variables.css.sass +0 -0
- data/source/stylesheets/lib/common.css.sass +1 -0
- data/source/stylesheets/vendor/all.css +55 -0
- data/source/stylesheets/vendor/normalize.css +375 -0
- data/spec/javascripts/helpers/spec_helper.coffee +11 -0
- data/spec/javascripts/support/jasmine-jquery.js +812 -0
- data/spec/javascripts/support/jasmine-sinon.coffee +246 -0
- data/spec/javascripts/support/jasmine.yml +10 -0
- data/spec/javascripts/support/jasmine_helper.rb +3 -0
- data/spec/javascripts/support/sinon-1.7.3.js +4290 -0
- data/spec/javascripts/views/base_spec.coffee +130 -0
- data/spec/javascripts/views/list_spec.coffee +31 -0
- data/vendor/assets/javascripts/backbone-1.1.2.js +1608 -0
- data/vendor/assets/javascripts/jquery-1.11.0.js +10337 -0
- data/vendor/assets/javascripts/json2.js +487 -0
- data/vendor/assets/javascripts/ppx.js +391 -0
- data/vendor/assets/javascripts/underscore-1.5.1.js +1246 -0
- data/vendor/assets/javascripts/uri.js +1803 -0
- data/vendor/assets/javascripts/zepto-detect.js +66 -0
- metadata +150 -0
data/fannypack.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/fanny_pack/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "fannypack"
|
6
|
+
s.version = FannyPack::VERSION
|
7
|
+
s.authors = ["Matt Diebolt", "Steel Fu", "Brad Gessler"]
|
8
|
+
s.email = ["matt@polleverywhere.com", "steel@polleverywhere.com", "brad@polleverywhere.com"]
|
9
|
+
s.homepage = "http://getfannypack.com"
|
10
|
+
s.summary = %q{A simple set of base views to help develop Backbone applications.}
|
11
|
+
s.description = %q{A simple set of base views to help develop Backbone applications.}
|
12
|
+
|
13
|
+
# Manifest
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
s.add_development_dependency 'middleman', '~> 3.3'
|
20
|
+
s.add_development_dependency 'growl'
|
21
|
+
s.add_development_dependency 'rb-fsevent'
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Handle lots of commond URL parsing concerns so that we can easily
|
2
|
+
# do stuff like URI('google.com/hi').params({search: 'football'})
|
3
|
+
#= require uri
|
4
|
+
|
5
|
+
# IE8 JSON parsing compatability.
|
6
|
+
# TODO - Remove when we no longer care about IE8.
|
7
|
+
#= require json2
|
8
|
+
|
9
|
+
# Provides $.os support, which jQuery ditched.
|
10
|
+
#= require zepto-detect
|
11
|
+
|
12
|
+
# Fanny Pack prerequisites
|
13
|
+
#= require fanny_pack/namespace
|
14
|
+
#= require fanny_pack/version
|
15
|
+
#= require fanny_pack/models/environment
|
16
|
+
#= require fanny_pack/env
|
17
|
+
|
18
|
+
# Fanny Pack assets
|
19
|
+
#= require_tree ./fanny_pack/routers
|
20
|
+
#= require_tree ./fanny_pack/models
|
21
|
+
#= require_tree ./fanny_pack/views
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#= require ppx
|
2
|
+
|
3
|
+
FannyPack.namespace "FannyPack", (FannyPack) ->
|
4
|
+
FannyPack.BasicAuth =
|
5
|
+
setCredentials: (username, password) ->
|
6
|
+
FannyPack.BasicAuth.username = username
|
7
|
+
FannyPack.BasicAuth.password = password
|
8
|
+
FannyPack.AJAX_DEFAULTS.headers['Authorization'] = "Basic #{btoa(FannyPack.BasicAuth.username + ':' + FannyPack.BasicAuth.password)}"
|
9
|
+
|
10
|
+
FannyPack.AJAX_DEFAULTS =
|
11
|
+
xhrFields: {}
|
12
|
+
headers: {}
|
13
|
+
dataType: 'json'
|
14
|
+
type: 'GET'
|
15
|
+
|
16
|
+
# Deep clone the ajax defaults
|
17
|
+
ajaxDefaults = ->
|
18
|
+
clone = _.clone FannyPack.AJAX_DEFAULTS
|
19
|
+
clone.xhrFields = _.clone FannyPack.AJAX_DEFAULTS.xhrFields
|
20
|
+
clone.headers = _.clone FannyPack.AJAX_DEFAULTS.headers
|
21
|
+
clone
|
22
|
+
|
23
|
+
# Cross Domain polyfill for IE8
|
24
|
+
# ---
|
25
|
+
# IMPORTANT: We MUST call toString() on this method or IE will barf on allow
|
26
|
+
# other URLS to access the domain. For example, IE would request the URL
|
27
|
+
# 'multiple_choice_polls/[object]' without throwing an error message.
|
28
|
+
|
29
|
+
# PPX Proxy JS will determine whether iframe needs SSL or not
|
30
|
+
polyfillCORS = (options, xhr) ->
|
31
|
+
# A PPX end-point lives in our rails_app server at the /ppx location.
|
32
|
+
path = FannyPack.env.get('api_url').path()
|
33
|
+
ppxUrl = FannyPack.env.get('api_url').path("/ppx#{path}")
|
34
|
+
|
35
|
+
FannyPack.PPXRequest ||= PPX.buildClientConstructor ppxUrl.toString()
|
36
|
+
|
37
|
+
if (options.crossDomain && !$.support.cors) || options.usePostMessage
|
38
|
+
options.xhr = FannyPack.PPXRequest
|
39
|
+
options.crossDomain = false
|
40
|
+
xhr.isProxiedThroughPostMessage = true
|
41
|
+
|
42
|
+
$.ajaxPrefilter (options, originalOptions, xhr) ->
|
43
|
+
_.defaults options, ajaxDefaults()
|
44
|
+
|
45
|
+
# Only set this up if we're given a relative path. Paths with domains
|
46
|
+
# should just flow through to the next uri mutations.
|
47
|
+
url = URI(options.url).absoluteTo(FannyPack.env.get('api_url'))
|
48
|
+
url.setQuery 'cache_buster', (new Date).getTime().toString() if $.os?.android
|
49
|
+
options.url = url.toString()
|
50
|
+
|
51
|
+
# Check if this is a cross domain request.
|
52
|
+
# CORS PPX polyfill uses this to determine if PPX should be used.
|
53
|
+
options.crossDomain = !url.absoluteTo('/').equals(URI(window.location.href).absoluteTo('/'))
|
54
|
+
|
55
|
+
# We need this for CORS + Cookies to work when using jQuery
|
56
|
+
options.xhrFields.withCredentials ?= true
|
57
|
+
|
58
|
+
polyfillCORS(options, xhr)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
FannyPack.namespace "FannyPack.Model", (Model) ->
|
2
|
+
class Model.Environment extends Backbone.Model
|
3
|
+
currentHost = window?.location?.host
|
4
|
+
protocol = window?.location?.protocol
|
5
|
+
defaults:
|
6
|
+
api_url: "//#{currentHost}"
|
7
|
+
ssl: protocol is 'https:'
|
8
|
+
|
9
|
+
get: (key) ->
|
10
|
+
switch
|
11
|
+
# When a key ends with _url, wrap it in an URI.js object so we can mutate it.
|
12
|
+
when key.match(/_url$/)
|
13
|
+
URI(super(key))
|
14
|
+
else
|
15
|
+
super(key)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
if module?.exports?
|
2
|
+
global.FannyPack ||= {}
|
3
|
+
else
|
4
|
+
window.FannyPack ||= {}
|
5
|
+
|
6
|
+
FannyPack.namespace = (target, name, block) ->
|
7
|
+
[target, name, block] = [(if global? then global else window), arguments...]
|
8
|
+
top = target
|
9
|
+
target = target[item] or= {} for item in name.split '.'
|
10
|
+
block target, name
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# The FannyPack.Router.Base is considered our most global application
|
2
|
+
# state for applications. Its assumed that only one router should
|
3
|
+
# be running at a given time within the context of a single runtime.
|
4
|
+
#
|
5
|
+
# Views and Templates all have access to the router via the `@app`
|
6
|
+
# method.
|
7
|
+
FannyPack.namespace "FannyPack.Router", (Router) ->
|
8
|
+
{Model} = FannyPack
|
9
|
+
|
10
|
+
class Router.Base extends Backbone.Router
|
11
|
+
# Default app name. Sets the default <title> on the page and
|
12
|
+
# is used in error messaging.
|
13
|
+
appName: "FannyPack App"
|
14
|
+
|
15
|
+
constructor: ->
|
16
|
+
# Lets prevent confusion for the clowns out there who try
|
17
|
+
# initializing 2 routers in the same runtime.
|
18
|
+
throw Error "FannyPack.app already initialized with '#{@appName}'" if FannyPack.app
|
19
|
+
FannyPack.app = @
|
20
|
+
|
21
|
+
# Convient access to the FannyPack.env from
|
22
|
+
# applications
|
23
|
+
@env = FannyPack.env
|
24
|
+
|
25
|
+
# What's that? You turned logging on? SWEET! You
|
26
|
+
# get to hear about everything that's happening in the
|
27
|
+
# event bus.
|
28
|
+
if @env.get('logging_enabled')
|
29
|
+
@on 'all', =>
|
30
|
+
@log 'App Event', arguments
|
31
|
+
|
32
|
+
# View manager responsible for de-activating old views and activating new ones
|
33
|
+
@view = new View.App
|
34
|
+
|
35
|
+
# We call super last since this calls the `initialize` method,
|
36
|
+
# which assumes everything above is all set and ready to go.
|
37
|
+
super
|
38
|
+
|
39
|
+
# Take care of all the messy bootstrapping of browser globals and singletons to
|
40
|
+
# the router, render a view, bootstrap user data from the server, and start
|
41
|
+
# Backbone.history routing. Basically all of the gross browser bootstrapping should
|
42
|
+
# go here.
|
43
|
+
#
|
44
|
+
# If you're trying to setup the router for testing, you should either decompose this
|
45
|
+
# method or manually start the browser's history.
|
46
|
+
start: (opts={pushState: true}) =>
|
47
|
+
throw Error "Specify a view property in the initialize method of the router" unless @view
|
48
|
+
|
49
|
+
{pushState, el} = opts
|
50
|
+
|
51
|
+
# Render the view first on the element since the login state could
|
52
|
+
# change what's rendered.
|
53
|
+
el.append @view.render().$el
|
54
|
+
|
55
|
+
# Start the router
|
56
|
+
Backbone.history.start(pushState: pushState)
|
57
|
+
|
58
|
+
@
|
59
|
+
|
60
|
+
# Returns the current location of the application.
|
61
|
+
location: ->
|
62
|
+
# This assumes that we're in a web browser context.
|
63
|
+
window.location.pathname.substring(1)
|
64
|
+
|
65
|
+
# Go "back" through the browsers history.
|
66
|
+
navigateBack: ->
|
67
|
+
Backbone.history.history.back()
|
68
|
+
|
69
|
+
# Default in backbone is to *not* trigger to execute the route handler,
|
70
|
+
# which is undesirable and feels like unexpected behavior for our devs.
|
71
|
+
navigate: (fragment, options = {trigger: true}) ->
|
72
|
+
super fragment, options
|
73
|
+
|
74
|
+
# Log tracing messages to a logging device if enabled.
|
75
|
+
log: =>
|
76
|
+
console.log(arguments...) if @env.get('logging_enabled')
|
77
|
+
|
78
|
+
# Change the title of the page and notify views/models that
|
79
|
+
# care about a title change what's up.
|
80
|
+
title: (title = @appName) =>
|
81
|
+
document?.title = title
|
82
|
+
@trigger "change:title", title
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#= require_tree ../views
|
2
|
+
|
3
|
+
FannyPack.namespace "FannyPack.View", (View) ->
|
4
|
+
class View.App extends View.Base
|
5
|
+
className: 'fannypack'
|
6
|
+
|
7
|
+
initialize: (opts = {}) ->
|
8
|
+
@currentView = null
|
9
|
+
|
10
|
+
activate: (view) =>
|
11
|
+
@currentView?.remove()
|
12
|
+
@currentView = view
|
13
|
+
@$el.append view.render().$el
|
14
|
+
|
15
|
+
currentPage: =>
|
16
|
+
@currentView
|
17
|
+
|
18
|
+
render: =>
|
19
|
+
@
|
@@ -0,0 +1,90 @@
|
|
1
|
+
FannyPack.namespace 'FannyPack.View', (View) ->
|
2
|
+
class View.Base extends Backbone.View
|
3
|
+
include: (modules...) ->
|
4
|
+
for module in modules
|
5
|
+
_.extend this, module(this)
|
6
|
+
|
7
|
+
constructor: (options = {}) ->
|
8
|
+
# Set the app for this view to the base application
|
9
|
+
# that FannyPack.Router.Base sets up in its initialize method.
|
10
|
+
@app ||= FannyPack.app
|
11
|
+
|
12
|
+
{title, template} = options
|
13
|
+
|
14
|
+
# Set the page title if we're given one.
|
15
|
+
@title = title if title?
|
16
|
+
|
17
|
+
# Override the template if specified
|
18
|
+
@template = template if template?
|
19
|
+
|
20
|
+
# TODO - Figure out how to show the full namespace
|
21
|
+
# of the view that's being rendered (and not just the prototype name)
|
22
|
+
# Make it easier for non-lib devs to find views.
|
23
|
+
@app.log "Constructing View", @
|
24
|
+
|
25
|
+
# Tell the router what the title of our window should be.
|
26
|
+
@app.title @title if @title
|
27
|
+
|
28
|
+
# make sure we have an external events hash
|
29
|
+
# if the child class hasn't defined one
|
30
|
+
@appEvents ?= {}
|
31
|
+
|
32
|
+
# Setup Backbone.View last since it fires the
|
33
|
+
# subclasses' `initialize` method, which assumes
|
34
|
+
# everything above is setup.
|
35
|
+
super
|
36
|
+
|
37
|
+
# Listen to a list of events and fire callback only once
|
38
|
+
# e.g. @listenToChanges @poll, "max_votes web_enabled sms_enabled", @refreshPage
|
39
|
+
# The above will call @refreshPage only once instead of 3 times for each attribute
|
40
|
+
# change event
|
41
|
+
listenToChanges: (model, attributes, callback) =>
|
42
|
+
attributes = attributes.split /\s+/
|
43
|
+
@listenTo model, 'change', (model) ->
|
44
|
+
changedAttributes = _.keys model.changed
|
45
|
+
|
46
|
+
if _.intersection(changedAttributes, attributes).length
|
47
|
+
callback.apply(@, model)
|
48
|
+
|
49
|
+
pageTitle: =>
|
50
|
+
if _.isFunction(@title)
|
51
|
+
@title.apply(@)
|
52
|
+
else
|
53
|
+
@title
|
54
|
+
|
55
|
+
_configureAppEvents: =>
|
56
|
+
for action, handler of @appEvents
|
57
|
+
try
|
58
|
+
method = @[handler]
|
59
|
+
method = handler if _.isFunction(handler)
|
60
|
+
boundMethod = _.bind(method, @)
|
61
|
+
|
62
|
+
@app.on action, boundMethod
|
63
|
+
catch
|
64
|
+
name = "'#{@constructor?.name || ''}'"
|
65
|
+
message = "View #{name} has no method named '#{handler}'. It cannot be registered as a handler for application events."
|
66
|
+
throw new Error(message)
|
67
|
+
|
68
|
+
@
|
69
|
+
|
70
|
+
delegateEvents: (events) =>
|
71
|
+
super
|
72
|
+
@_configureAppEvents()
|
73
|
+
@
|
74
|
+
|
75
|
+
undelegateEvents: =>
|
76
|
+
super
|
77
|
+
for action, handler of @appEvents
|
78
|
+
@app.off action, _.bind @[handler], @
|
79
|
+
@
|
80
|
+
|
81
|
+
renderTemplate: (template = @template) =>
|
82
|
+
@app.log "Rendering Template", template
|
83
|
+
@$el.html JST[template]()
|
84
|
+
|
85
|
+
renderTitle: =>
|
86
|
+
@$(".title").text @pageTitle()
|
87
|
+
@app.title @pageTitle()
|
88
|
+
|
89
|
+
pageClass: =>
|
90
|
+
""
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#= require ../namespace
|
2
|
+
|
3
|
+
FannyPack.namespace 'FannyPack.View', (View) ->
|
4
|
+
class View.List extends View.Base
|
5
|
+
initialize: (options={}) ->
|
6
|
+
@collection = options.collection
|
7
|
+
@subView = options.subView
|
8
|
+
|
9
|
+
@subViews = []
|
10
|
+
|
11
|
+
# always blow away existing subViews.
|
12
|
+
# call this only if you want a full re-render
|
13
|
+
render: =>
|
14
|
+
@remove()
|
15
|
+
|
16
|
+
@collection.each (item) =>
|
17
|
+
v = new @subView
|
18
|
+
model: item
|
19
|
+
|
20
|
+
@subViews.push v
|
21
|
+
|
22
|
+
@$el.append v.render().$el
|
23
|
+
|
24
|
+
@
|
25
|
+
|
26
|
+
remove: =>
|
27
|
+
_.invoke @subViews, 'remove'
|
28
|
+
|
29
|
+
super
|
data/lib/fanny_pack.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module FannyPack
|
2
|
+
# Deal with bundling Sprocket assets into environments (like Rails or Sprockets)
|
3
|
+
module Assets
|
4
|
+
def self.path(*segs)
|
5
|
+
File.join File.expand_path('../../assets', __FILE__), segs
|
6
|
+
end
|
7
|
+
|
8
|
+
# Integrate FannyPack ./lib/assets files into a sprocket-enabled environment.
|
9
|
+
module Sprockets
|
10
|
+
# Drop flash and javascript paths to FannyPack assets into a sprockets environment.
|
11
|
+
def self.configure(env)
|
12
|
+
env.append_path FannyPack::Assets.path('javascripts')
|
13
|
+
env
|
14
|
+
end
|
15
|
+
|
16
|
+
# Try to automatically configure Sprockets if its detected in the project.
|
17
|
+
def self.auto_detect
|
18
|
+
if defined? ::Sprockets and ::Sprockets.respond_to? :append_path
|
19
|
+
FannyPack::Assets::Sprockets.configure ::Sprockets
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,4 @@
|
|
1
|
+
module FannyPack
|
2
|
+
# Read the FannyPack.version attribute from lib/assets/javascripts/fanny_pack/version.js.coffee
|
3
|
+
VERSION = File.read(File.expand_path('../../assets/javascripts/fanny_pack/version.js.coffee', __FILE__)).match(/Package.version \= '(.+)'/m).captures.first
|
4
|
+
end
|
Binary file
|
Binary file
|
File without changes
|
File without changes
|
@@ -0,0 +1,49 @@
|
|
1
|
+
!!! 5
|
2
|
+
/[if lt IE 7] <html class="no-js lt-ie10 lt-ie9 lt-ie8 lt-ie7" lang="en-us">
|
3
|
+
/[if IE 7] <html class="no-js lt-ie10 lt-ie9 lt-ie8" lang="en-us">
|
4
|
+
/[if IE 8] <html class="no-js lt-ie10 lt-ie9" lang="en-us">
|
5
|
+
/[if IE 9] <html class="no-js lt-ie10 lt-ie9" lang="en-us">
|
6
|
+
/[if lt IE 10] <html class="no-js lt-ie10" lang="en-us">
|
7
|
+
/[if !IE]>
|
8
|
+
%html{lang: 'en', class: 'no-js'}
|
9
|
+
/<![endif]
|
10
|
+
%head
|
11
|
+
%title #{data.page.title || "The Middleman"}
|
12
|
+
%meta(http-equiv="content-type" content="text/html" charset="utf-8")
|
13
|
+
%meta(http-equiv="x-ua-compatible" content="ie=edge,chrome=1")
|
14
|
+
%meta(name="description" content="")
|
15
|
+
%meta(name="author" content="")
|
16
|
+
|
17
|
+
-# Standard viewport tag to set the viewport to the device's width,
|
18
|
+
-# Android 2.3 devices need this so 100% width works properly and
|
19
|
+
-# doesn't allow children to blow up the viewport width
|
20
|
+
%meta{content: "initial-scale=1.0,user-scalable=no,maximum-scale=1,width=device-width", name: "viewport"}
|
21
|
+
|
22
|
+
-# Fix for iPhone 5 fullscreen web apps
|
23
|
+
%meta(name="viewport" content="initial-scale=1.0,user-scalable=no,maximum-scale=1" media="(device-height: 568px)")
|
24
|
+
%meta(name='apple-mobile-web-app-capable' content='yes')
|
25
|
+
%meta(name='apple-mobile-web-app-status-bar-style' content='translucent-black')
|
26
|
+
|
27
|
+
-# App Icons
|
28
|
+
%link(rel="shortcut icon" href="/images/favicon.ico")
|
29
|
+
%link(rel="apple-touch-icon-precomposed" href="/images/apple-touch-icon-precomposed.png")
|
30
|
+
%link(rel="apple-touch-icon-precomposed" sizes="57x57" href="/images/apple-touch-icon-57x57-precomposed.png")
|
31
|
+
%link(rel="apple-touch-icon-precomposed" sizes="72x72" href="/images/apple-touch-icon-72x72-precomposed.png")
|
32
|
+
%link(rel="apple-touch-icon-precomposed" sizes="114x114" href="/images/apple-touch-icon-114x114-precomposed.png")
|
33
|
+
|
34
|
+
-# Stylesheets
|
35
|
+
= stylesheet_link_tag 'application'
|
36
|
+
%body{class: current_page.data.body_class || 'page'}
|
37
|
+
= yield
|
38
|
+
-# Javascripts
|
39
|
+
= javascript_include_tag '//cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js'
|
40
|
+
= javascript_include_tag '//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js'
|
41
|
+
= javascript_include_tag 'application'
|
42
|
+
|
43
|
+
- if build?
|
44
|
+
-# Google Analytics
|
45
|
+
:javascript
|
46
|
+
var _gaq=[['_setAccount','UA-XXXXX-X'],['_trackPageview']];
|
47
|
+
(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
|
48
|
+
g.src=('https:'==location.protocol?'//ssl':'//www')+'.google-analytics.com/ga.js';
|
49
|
+
s.parentNode.insertBefore(g,s)}(document,'script'));
|