fistface 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ *.swp
2
+ *.swo
3
+ pkg
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in fistface.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,37 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ fistface (1.0.1)
5
+ sinatra (~> 1.1)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ diff-lcs (1.1.2)
11
+ rack (1.3.1)
12
+ rack-test (0.6.0)
13
+ rack (>= 1.0)
14
+ rake (0.9.2.2)
15
+ rspec (2.6.0)
16
+ rspec-core (~> 2.6.0)
17
+ rspec-expectations (~> 2.6.0)
18
+ rspec-mocks (~> 2.6.0)
19
+ rspec-core (2.6.4)
20
+ rspec-expectations (2.6.0)
21
+ diff-lcs (~> 1.1.2)
22
+ rspec-mocks (2.6.0)
23
+ sinatra (1.2.7)
24
+ rack (~> 1.1)
25
+ tilt (< 2.0, >= 1.2.2)
26
+ tilt (1.3.3)
27
+ timecop (0.3.5)
28
+
29
+ PLATFORMS
30
+ ruby
31
+
32
+ DEPENDENCIES
33
+ fistface!
34
+ rack-test
35
+ rake
36
+ rspec
37
+ timecop
data/MIT-LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright 2011 thoughtbot, inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR of the Software, and to
21
+ permit
data/README.md ADDED
@@ -0,0 +1,109 @@
1
+ Fist Face
2
+ =========
3
+
4
+ DIY @font-face web service.
5
+
6
+ Usage
7
+ -----
8
+
9
+ In your web app:
10
+
11
+ <link href="http://replace-me.com/font-name.css" rel="stylesheet" type="text/css">
12
+
13
+ Replace the href with the URL of your @font-face web service.
14
+
15
+ Features
16
+ --------
17
+
18
+ * Fixes the Access-Control-Allow-Origin problem in Firefox and other browsers
19
+ * HTTP caches fonts so they are downloaded only once by the same browser
20
+ * Content-Type always correct for .ttf, .otf, .woff, .eot, and .svg fonts
21
+
22
+ Setup
23
+ -----
24
+
25
+ Create a Gemfile:
26
+
27
+ source "http://rubygems.org"
28
+ gem "sinatra", "~> 1.1"
29
+ gem "fistface", "~> 1.0"
30
+
31
+ Create a rackup file (config.ru):
32
+
33
+ require 'rubygems'
34
+ require 'bundler'
35
+ Bundler.require
36
+ run FistFace
37
+
38
+ Prepare the production environment:
39
+
40
+ bundle install
41
+ git init
42
+ git add .
43
+ git commit -m "Creating a Fist Face instance"
44
+ heroku create
45
+ heroku config:add S3_URL=https://your-bucket.s3.amazonaws.com
46
+
47
+ Do not include a trailing slash.
48
+
49
+ S3_URL is the URL of the asset host which stores your @font-face definitions in CSS files.
50
+
51
+ For each font you want to serve, upload a CSS file to your asset host like:
52
+
53
+ @font-face {
54
+ font-family: 'Chunk';
55
+ font-weight: normal;
56
+ font-style: normal;
57
+ src: local('☺'), url('http://replace-me.com/chunk/chunk.ttf') format('truetype');
58
+ }
59
+
60
+ Fist Face uses a directory-and-file convention like this:
61
+
62
+ font-name.css
63
+ font-name/
64
+ font-name.eot
65
+ font-name.otf
66
+ font-name.svg
67
+ font-name.ttf
68
+ font-name.woff
69
+
70
+ It is up to you to determine how many formats you need to include in your CSS file.
71
+
72
+ Upload each font file using that convention.
73
+
74
+ Deploy your @font-face web service:
75
+
76
+ git push heroku master
77
+
78
+ Start serving fonts!
79
+
80
+ Patches
81
+ -------
82
+
83
+ Please use Github Issues and Pull Requests for any patches.
84
+
85
+ To run the Sinatra app locally:
86
+
87
+ gem install bundler
88
+ bundle install
89
+ S3_URL=https://your-bucket.s3.amazonaws.com rackup
90
+
91
+ To run the specs:
92
+
93
+ rspec spec/app_spec.rb
94
+
95
+ Credits
96
+ -------
97
+
98
+ ![thoughtbot](http://thoughtbot.com/images/tm/logo.png)
99
+
100
+ Fist Face is maintained and funded by [thoughtbot, inc](http://thoughtbot.com/community)
101
+
102
+ Thank you to all [the contributors](https://github.com/thoughtbot/fistface/contributors)!
103
+
104
+ The names and logos for thoughtbot are trademarks of thoughtbot, inc.
105
+
106
+ License
107
+ -------
108
+
109
+ Fist Face is Copyright © 2011 thoughtbot. It is free software, and may be redistributed under the terms specified in the MIT-LICENSE file.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/setup'
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ desc "Default task: run specs"
8
+ task :default => :spec
data/fistface.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "fistface/version"
4
+
5
+ Gem::Specification.new do |s|
6
+
7
+ # Dependencies
8
+ s.add_dependency('sinatra', '~> 1.1')
9
+ s.add_development_dependency("rspec")
10
+ s.add_development_dependency("rack-test")
11
+ s.add_development_dependency("timecop")
12
+ s.add_development_dependency("rake")
13
+
14
+ #Configuration
15
+ s.name = 'fistface'
16
+ s.version = Fistface::VERSION
17
+ s.authors = ['Dan Croak']
18
+ s.email = 'support@thoughtbot.com'
19
+ s.homepage = 'http://github.com/thoughtbot/fistface'
20
+ s.summary = 'DIY @font-face web service'
21
+ s.description = 'Pow. Right in the kisser.'
22
+
23
+ s.files = `git ls-files`.split("\n")
24
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
25
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
26
+ s.require_paths = ["lib"]
27
+ end
data/lib/fistface.rb CHANGED
@@ -1,30 +1,35 @@
1
1
  require 'sinatra/base'
2
- require 'open-uri'
3
2
 
4
- class FistFace < Sinatra::Base
5
- set :app_file, __FILE__
3
+ module Sinatra
4
+ module FistFace
5
+ require 'open-uri'
6
6
 
7
- before do
8
- one_year_in_seconds = 31536000
7
+ def self.registered(app)
8
+ app.before do
9
+ one_year_in_seconds = 31536000
9
10
 
10
- headers 'Cache-Control' => "public, max-age=#{one_year_in_seconds}",
11
- 'Expires' => (Time.now + one_year_in_seconds).httpdate,
12
- 'Access-Control-Allow-Origin' => '*'
13
- end
11
+ headers 'Cache-Control' => "public, max-age=#{one_year_in_seconds}",
12
+ 'Expires' => (Time.now + one_year_in_seconds).httpdate,
13
+ 'Access-Control-Allow-Origin' => '*'
14
+ end
14
15
 
15
- get '/:font_face.css' do
16
- headers['Content-Type'] = 'text/css'
17
- open("#{ENV['S3_URL']}/#{params[:font_face]}.css").read
18
- end
16
+ app.get '/:font_face.css' do
17
+ headers['Content-Type'] = 'text/css'
18
+ open("#{ENV['S3_URL']}/#{params[:font_face]}.css").read
19
+ end
20
+
21
+ app.get '/:directory/:font_face' do
22
+ headers['Content-Type'] = case params[:font_face]
23
+ when /\.ttf$/ then 'font/truetype'
24
+ when /\.otf$/ then 'font/opentype'
25
+ when /\.woff$/ then 'font/woff'
26
+ when /\.eot$/ then 'application/vnd.ms-fontobject'
27
+ when /\.svg$/ then 'image/svg+xml'
28
+ end
29
+ open("#{ENV['S3_URL']}/#{params[:directory]}/#{params[:font_face]}").read
30
+ end
19
31
 
20
- get '/:directory/:font_face' do
21
- headers['Content-Type'] = case params[:font_face]
22
- when /\.ttf$/ then 'font/truetype'
23
- when /\.otf$/ then 'font/opentype'
24
- when /\.woff$/ then 'font/woff'
25
- when /\.eot$/ then 'application/vnd.ms-fontobject'
26
- when /\.svg$/ then 'image/svg+xml'
27
- end
28
- open("#{ENV['S3_URL']}/#{params[:directory]}/#{params[:font_face]}").read
32
+ end
29
33
  end
30
- end
34
+ register FistFace
35
+ end
@@ -0,0 +1,3 @@
1
+ module Fistface
2
+ VERSION = "1.0.1"
3
+ end
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+
3
+ describe "FistFace" do
4
+ include Rack::Test::Methods
5
+
6
+ def app
7
+ @app ||= Sinatra::Application
8
+ end
9
+
10
+ context "when I GET a font stylesheet by convention of font-name.css" do
11
+ before do
12
+ Timecop.freeze(first_of_january)
13
+
14
+ get "chunk.css"
15
+ end
16
+
17
+ after { Timecop.return }
18
+
19
+ it "responds with HTTP status OK" do
20
+ last_response.should be_ok
21
+ end
22
+
23
+ it "has the @font-face declaration in the CSS body" do
24
+ last_response.body.should == File.read('spec/fixtures/chunk.css')
25
+ end
26
+
27
+ it "is in the CSS Content-Type" do
28
+ last_response.content_type.should == 'text/css'
29
+ end
30
+
31
+ it "wildcards the Access-Control-Allow-Origin header so Firefox can access the file" do
32
+ last_response.headers['Access-Control-Allow-Origin'].should == '*'
33
+ end
34
+
35
+ it "HTTP caches the file for a year in Varnish" do
36
+ last_response.headers['Cache-Control'].should == 'public, max-age=31536000'
37
+ end
38
+
39
+ it "HTTP caches the file for a year in the user's browser" do
40
+ last_response.headers['Expires'].should == (Time.now + 31536000).httpdate
41
+ end
42
+ end
43
+
44
+ context "when I GET a font file by convention of font-name/font-name.ttf" do
45
+ before do
46
+ Timecop.freeze(first_of_january)
47
+
48
+ get "chunk/chunk.ttf"
49
+ end
50
+
51
+ after { Timecop.return }
52
+
53
+ it "responds with HTTP status OK" do
54
+ last_response.should be_ok
55
+ end
56
+
57
+ it "is in the truetype Content-Type" do
58
+ last_response.content_type.should == 'font/truetype'
59
+ end
60
+
61
+ it "wildcards the Access-Control-Allow-Origin header so Firefox can access the file" do
62
+ last_response.headers['Access-Control-Allow-Origin'].should == '*'
63
+ end
64
+
65
+ it "HTTP caches the file for a year in Varnish" do
66
+ last_response.headers['Cache-Control'].should == 'public, max-age=31536000'
67
+ end
68
+
69
+ it "HTTP caches the file for a year in the user's browser" do
70
+ last_response.headers['Expires'].should == (Time.now + 31536000).httpdate
71
+ end
72
+ end
73
+
74
+ context "when I GET an opentype font" do
75
+ before { get "chunk/chunk.otf" }
76
+
77
+ it "is in the opentype Content-Type" do
78
+ last_response.content_type.should == 'font/opentype'
79
+ end
80
+ end
81
+
82
+ context "when I GET a web open font format font" do
83
+ before { get "chunk/chunk.woff" }
84
+
85
+ it "is in the web open font format Content-Type" do
86
+ last_response.content_type.should == 'font/woff'
87
+ end
88
+ end
89
+
90
+ context "when I GET an embedded opentype font" do
91
+ before { get "chunk/chunk.eot" }
92
+
93
+ it "is in the embedded opentype Content-Type" do
94
+ last_response.content_type.should == 'application/vnd.ms-fontobject'
95
+ end
96
+ end
97
+
98
+ context "when I GET an svg font" do
99
+ before { get "chunk/chunk.svg" }
100
+
101
+ it "is in the svg Content-Type" do
102
+ last_response.content_type.should == 'image/svg+xml'
103
+ end
104
+ end
105
+
106
+ def first_of_january
107
+ Date.parse("January 1, 2011")
108
+ end
109
+ end
@@ -0,0 +1,7 @@
1
+ @font-face {
2
+ font-family: 'Chunk';
3
+ font-weight: normal;
4
+ font-style: normal;
5
+ src: url('chunk/chunk.otf');
6
+ src: local('☺'), url('chunk/chunk.ttf') format('truetype');
7
+ }
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,8 @@
1
+ $: << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+
3
+ require 'fistface'
4
+ require 'rack/test'
5
+ require 'timecop'
6
+
7
+ ENV['RACK_ENV'] = 'test'
8
+ ENV['S3_URL'] = 'spec/fixtures'
metadata CHANGED
@@ -1,81 +1,130 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: fistface
3
- version: !ruby/object:Gem::Version
4
- hash: 23
5
- prerelease: false
6
- segments:
7
- - 1
8
- - 0
9
- - 0
10
- version: 1.0.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Dan Croak
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-01-12 00:00:00 -05:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2011-12-03 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: sinatra
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70296433657120 !ruby/object:Gem::Requirement
25
17
  none: false
26
- requirements:
18
+ requirements:
27
19
  - - ~>
28
- - !ruby/object:Gem::Version
29
- hash: 13
30
- segments:
31
- - 1
32
- - 1
33
- version: "1.1"
20
+ - !ruby/object:Gem::Version
21
+ version: '1.1'
34
22
  type: :runtime
35
- version_requirements: *id001
23
+ prerelease: false
24
+ version_requirements: *70296433657120
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &70296433656700 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70296433656700
36
+ - !ruby/object:Gem::Dependency
37
+ name: rack-test
38
+ requirement: &70296433656240 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70296433656240
47
+ - !ruby/object:Gem::Dependency
48
+ name: timecop
49
+ requirement: &70296433655820 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70296433655820
58
+ - !ruby/object:Gem::Dependency
59
+ name: rake
60
+ requirement: &70296433655400 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70296433655400
36
69
  description: Pow. Right in the kisser.
37
70
  email: support@thoughtbot.com
38
71
  executables: []
39
-
40
72
  extensions: []
41
-
42
73
  extra_rdoc_files: []
43
-
44
- files:
74
+ files:
75
+ - .gitignore
76
+ - Gemfile
77
+ - Gemfile.lock
78
+ - MIT-LICENSE
79
+ - README.md
80
+ - Rakefile
81
+ - fistface.gemspec
45
82
  - lib/fistface.rb
46
- has_rdoc: true
83
+ - lib/fistface/version.rb
84
+ - spec/fistface_spec.rb
85
+ - spec/fixtures/chunk.css
86
+ - spec/fixtures/chunk/chunk.eot
87
+ - spec/fixtures/chunk/chunk.otf
88
+ - spec/fixtures/chunk/chunk.svg
89
+ - spec/fixtures/chunk/chunk.ttf
90
+ - spec/fixtures/chunk/chunk.woff
91
+ - spec/spec_helper.rb
47
92
  homepage: http://github.com/thoughtbot/fistface
48
93
  licenses: []
49
-
50
94
  post_install_message:
51
95
  rdoc_options: []
52
-
53
- require_paths:
96
+ require_paths:
54
97
  - lib
55
- required_ruby_version: !ruby/object:Gem::Requirement
98
+ required_ruby_version: !ruby/object:Gem::Requirement
56
99
  none: false
57
- requirements:
58
- - - ">="
59
- - !ruby/object:Gem::Version
60
- hash: 3
61
- segments:
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ segments:
62
105
  - 0
63
- version: "0"
64
- required_rubygems_version: !ruby/object:Gem::Requirement
106
+ hash: 1911532667743223418
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
108
  none: false
66
- requirements:
67
- - - ">="
68
- - !ruby/object:Gem::Version
69
- hash: 3
70
- segments:
109
+ requirements:
110
+ - - ! '>='
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ segments:
71
114
  - 0
72
- version: "0"
115
+ hash: 1911532667743223418
73
116
  requirements: []
74
-
75
117
  rubyforge_project:
76
- rubygems_version: 1.3.7
118
+ rubygems_version: 1.8.6
77
119
  signing_key:
78
120
  specification_version: 3
79
121
  summary: DIY @font-face web service
80
- test_files: []
81
-
122
+ test_files:
123
+ - spec/fistface_spec.rb
124
+ - spec/fixtures/chunk.css
125
+ - spec/fixtures/chunk/chunk.eot
126
+ - spec/fixtures/chunk/chunk.otf
127
+ - spec/fixtures/chunk/chunk.svg
128
+ - spec/fixtures/chunk/chunk.ttf
129
+ - spec/fixtures/chunk/chunk.woff
130
+ - spec/spec_helper.rb