stylo 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -18,7 +18,7 @@ begin
18
18
  gem.add_development_dependency "sinatra", ">= 0"
19
19
  gem.add_development_dependency "rails", ">= 3.0.0"
20
20
  gem.add_runtime_dependency "haml", ">= 3.0.21"
21
- gem.version = "0.6.0"
21
+ gem.version = "0.7.0"
22
22
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
23
23
  end
24
24
  Jeweler::GemcutterTasks.new
@@ -0,0 +1,2 @@
1
+
2
+ function child(){alert('child');}
@@ -24,3 +24,10 @@ Feature: Javascript serving
24
24
  And "child.js" is located at "javascripts" in the asset location
25
25
  When a request is made for "javascripts/grand_parent.js"
26
26
  Then the response body should look like "grand_parent_with_parent_with_child.js"
27
+
28
+ Scenario: Minifying javascript
29
+ Given javascript compression is enabled
30
+ And "child.js" is located at "javascripts" in the asset location
31
+ When a request is made for "javascripts/child.js"
32
+ Then the response body should look like "child-min.js"
33
+
@@ -40,3 +40,7 @@ end
40
40
  When /^css combining is disabled$/ do
41
41
  Stylo::Config.css_combining_enabled = false
42
42
  end
43
+
44
+ Given /^javascript compression is enabled$/ do
45
+ Stylo::Config.javascript_minifying_enabled = true
46
+ end
data/lib/jsmin.rb ADDED
@@ -0,0 +1,209 @@
1
+ # jsmin.rb
2
+ # Author: Mike Wagg
3
+ # This work is a reworking of the ruby port of jsmin produced by
4
+ # Uladzislau Latynski which itself was a translation of the original
5
+ # C version published by Douglas Crockford. Permission is hereby granted to use the Ruby
6
+ # version under the same conditions as the jsmin.c on which it is
7
+ # based.
8
+ #
9
+ # /* jsmin.c
10
+ # 2003-04-21
11
+ #
12
+ # Copyright (c) 2002 Douglas Crockford (www.crockford.com)
13
+ #
14
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
15
+ # this software and associated documentation files (the "Software"), to deal in
16
+ # the Software without restriction, including without limitation the rights to
17
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
18
+ # of the Software, and to permit persons to whom the Software is furnished to do
19
+ # so, subject to the following conditions:
20
+ #
21
+ # The above copyright notice and this permission notice shall be included in all
22
+ # copies or substantial portions of the Software.
23
+ #
24
+ # The Software shall be used for Good, not Evil.
25
+ #
26
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32
+ # SOFTWARE.
33
+
34
+ require 'stringio'
35
+
36
+ class JSMin
37
+ EOF = -1
38
+
39
+ def initialize(original)
40
+ @original = original
41
+ end
42
+
43
+ def minify
44
+ @output = ''
45
+
46
+ @in = StringIO.new(@original)
47
+ @out = StringIO.new(@output)
48
+
49
+ @the_a = ""
50
+ @the_b = ""
51
+
52
+ jsmin
53
+
54
+ @output
55
+ end
56
+
57
+ private
58
+
59
+ def is_alpha_numeric(c)
60
+ return false if !c || c == EOF
61
+
62
+ ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
63
+ (c >= 'A' && c <= 'Z') || c == '_' || c == '$' ||
64
+ c == '\\' || (c[0].class == String ? c[0].ord : c[0]) > 126)
65
+ end
66
+
67
+ # get -- return the next character from stdin. Watch out for lookahead. If
68
+ # the character is a control character, translate it to a space or linefeed.
69
+ def get_next_character()
70
+ c = @in.getc
71
+ return EOF if (!c)
72
+ c = c.chr
73
+ return c if (c >= " " || c == "\n" || c.unpack("c") == EOF)
74
+ return "\n" if (c == "\r")
75
+
76
+ " "
77
+ end
78
+
79
+ def peek()
80
+ lookahead_char = @in.getc
81
+ @in.ungetc(lookahead_char)
82
+ lookahead_char.chr
83
+ end
84
+
85
+ def my_next()
86
+ c = get_next_character
87
+ if (c == "/")
88
+ if (peek == "/")
89
+ while (true)
90
+ c = get_next_character
91
+ if (c <= "\n")
92
+ return c
93
+ end
94
+ end
95
+ end
96
+ if (peek == "*")
97
+ get_next_character
98
+ while (true)
99
+ case get_next_character
100
+ when "*"
101
+ if (peek == "/")
102
+ get_next_character
103
+ return " "
104
+ end
105
+ when EOF
106
+ raise "Unterminated comment"
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ c
113
+ end
114
+
115
+ def action(a)
116
+ if (a==1)
117
+ @out.write @the_a
118
+ end
119
+ if (a==1 || a==2)
120
+ @the_a = @the_b
121
+ if (@the_a == "\'" || @the_a == "\"")
122
+ while (true)
123
+ @out.write @the_a
124
+ @the_a = get_next_character
125
+ break if (@the_a == @the_b)
126
+ raise "Unterminated string literal" if (@the_a <= "\n")
127
+ if (@the_a == "\\")
128
+ @out.write @the_a
129
+ @the_a = get_next_character
130
+ end
131
+ end
132
+ end
133
+ end
134
+ if (a==1 || a==2 || a==3)
135
+ @the_b = my_next
136
+ if (@the_b == "/" && (@the_a == "(" || @the_a == "," || @the_a == "=" ||
137
+ @the_a == ":" || @the_a == "[" || @the_a == "!" ||
138
+ @the_a == "&" || @the_a == "|" || @the_a == "?" ||
139
+ @the_a == "{" || @the_a == "}" || @the_a == ";" ||
140
+ @the_a == "\n"))
141
+ @out.write @the_a
142
+ @out.write @the_b
143
+ while (true)
144
+ @the_a = get_next_character
145
+ if (@the_a == "/")
146
+ break
147
+ elsif (@the_a == "\\")
148
+ @out.write @the_a
149
+ @the_a = get_next_character
150
+ elsif (@the_a <= "\n")
151
+ raise "Unterminated RegExp Literal"
152
+ end
153
+ @out.write @the_a
154
+ end
155
+ @the_b = my_next
156
+ end
157
+ end
158
+ end
159
+
160
+ def jsmin
161
+ @the_a = "\n"
162
+ action(3)
163
+ while (@the_a != EOF)
164
+ case @the_a
165
+ when " "
166
+ if (is_alpha_numeric(@the_b))
167
+ action(1)
168
+ else
169
+ action(2)
170
+ end
171
+ when "\n"
172
+ case (@the_b)
173
+ when "{", "[", "(", "+", "-"
174
+ action(1)
175
+ when " "
176
+ action(3)
177
+ else
178
+ if (is_alpha_numeric(@the_b))
179
+ action(1)
180
+ else
181
+ action(2)
182
+ end
183
+ end
184
+ else
185
+ case (@the_b)
186
+ when " "
187
+ if (is_alpha_numeric(@the_a))
188
+ action(1)
189
+ else
190
+ action(3)
191
+ end
192
+ when "\n"
193
+ case (@the_a)
194
+ when "}", "]", ")", "+", "-", "\"", "\\", "'", '"'
195
+ action(1)
196
+ else
197
+ if (is_alpha_numeric(@the_a))
198
+ action(1)
199
+ else
200
+ action(3)
201
+ end
202
+ end
203
+ else
204
+ action(1)
205
+ end
206
+ end
207
+ end
208
+ end
209
+ end
data/lib/stylo/config.rb CHANGED
@@ -1,18 +1,20 @@
1
1
  module Stylo
2
2
  class Config
3
3
  class << self
4
- attr_accessor :asset_location, :css_combining_enabled, :javascript_combining_enabled
4
+ attr_accessor :asset_location, :css_combining_enabled, :javascript_combining_enabled, :javascript_minifying_enabled
5
5
 
6
6
  def pipeline
7
7
  [Stylo::PipelineSteps::Stylesheet.new,
8
8
  Stylo::PipelineSteps::Javascript.new,
9
9
  Stylo::PipelineSteps::Sass.new,
10
+ Stylo::PipelineSteps::JavascriptMinifying.new,
10
11
  Stylo::PipelineSteps::Caching.new]
11
12
  end
12
13
 
13
14
  def reset_to_default
14
15
  self.css_combining_enabled = true
15
16
  self.javascript_combining_enabled = true
17
+ self.javascript_minifying_enabled = false
16
18
  end
17
19
  end
18
20
 
@@ -0,0 +1,11 @@
1
+ module Stylo
2
+ module PipelineSteps
3
+ class JavascriptMinifying
4
+ def call(response)
5
+ if Config.javascript_minifying_enabled and response.extension == '.js' and response.has_content?
6
+ response.set_body(JSMin.new(response.body).minify, :javascript)
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe Stylo::PipelineSteps::JavascriptMinifying do
4
+ before(:each) do
5
+ Stylo::Config.javascript_minifying_enabled = true
6
+ end
7
+
8
+ let(:step) { Stylo::PipelineSteps::JavascriptMinifying.new }
9
+ let(:jsmin) { mock(:jsmin) }
10
+
11
+ describe "when the response body is not javascript" do
12
+ it "should not modify the response body" do
13
+ response = Stylo::Response.new('stylesheets/test.css')
14
+ original_body = "html{ color:#000; }"
15
+ response.set_body(original_body, :css)
16
+
17
+ step.call(response)
18
+
19
+ response.body.should == original_body
20
+ end
21
+ end
22
+
23
+ describe "when the response body is javascript" do
24
+ let(:response) { Stylo::Response.new('javascrips/test.js') }
25
+ let(:minified_javascript) { 'I am minified!' }
26
+
27
+ before(:each) do
28
+ response.set_body('some javascript', :javascript)
29
+
30
+ JSMin.stub(:new).with(response.body).and_return(jsmin)
31
+ jsmin.stub(:minify).and_return(minified_javascript)
32
+ end
33
+
34
+ it "should ask jsmin to minify the javascript" do
35
+ JSMin.should_receive(:new).with(response.body).and_return(jsmin)
36
+ jsmin.should_receive(:minify)
37
+
38
+ step.call(response)
39
+ end
40
+
41
+ it "should replace the response body with the minified text" do
42
+ step.call(response)
43
+
44
+ response.body.should == minified_javascript
45
+ end
46
+ end
47
+ end
data/stylo.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{stylo}
8
- s.version = "0.6.0"
8
+ s.version = "0.7.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["mwagg"]
12
- s.date = %q{2010-11-03}
12
+ s.date = %q{2010-11-11}
13
13
  s.description = %q{Server side stylesheet combining for readonly hosting environments}
14
14
  s.email = %q{michael@guerillatactics.co.uk}
15
15
  s.extra_rdoc_files = [
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
26
26
  "TODO",
27
27
  "cucumber.yml",
28
28
  "features/fixtures.rb",
29
+ "features/fixtures/child-min.js",
29
30
  "features/fixtures/child.css",
30
31
  "features/fixtures/child.js",
31
32
  "features/fixtures/grand_parent.css",
@@ -50,12 +51,14 @@ Gem::Specification.new do |s|
50
51
  "features/stylesheets.feature",
51
52
  "features/stylo_cannot_serve_asset.feature",
52
53
  "features/support/env.rb",
54
+ "lib/jsmin.rb",
53
55
  "lib/stylo.rb",
54
56
  "lib/stylo/asset_loader.rb",
55
57
  "lib/stylo/combiner.rb",
56
58
  "lib/stylo/config.rb",
57
59
  "lib/stylo/pipeline_steps/caching.rb",
58
60
  "lib/stylo/pipeline_steps/javascript.rb",
61
+ "lib/stylo/pipeline_steps/javascript_minifying.rb",
59
62
  "lib/stylo/pipeline_steps/sass.rb",
60
63
  "lib/stylo/pipeline_steps/stylesheet.rb",
61
64
  "lib/stylo/processor.rb",
@@ -65,6 +68,7 @@ Gem::Specification.new do |s|
65
68
  "spec/asset_loader_spec.rb",
66
69
  "spec/combiner_spec.rb",
67
70
  "spec/pipeline_steps/caching_spec.rb",
71
+ "spec/pipeline_steps/javascript_minifying_spec.rb",
68
72
  "spec/pipeline_steps/javascript_spec.rb",
69
73
  "spec/pipeline_steps/sass_spec.rb",
70
74
  "spec/pipeline_steps/stylesheet_spec.rb",
@@ -82,6 +86,7 @@ Gem::Specification.new do |s|
82
86
  "spec/asset_loader_spec.rb",
83
87
  "spec/combiner_spec.rb",
84
88
  "spec/pipeline_steps/caching_spec.rb",
89
+ "spec/pipeline_steps/javascript_minifying_spec.rb",
85
90
  "spec/pipeline_steps/javascript_spec.rb",
86
91
  "spec/pipeline_steps/sass_spec.rb",
87
92
  "spec/pipeline_steps/stylesheet_spec.rb",
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stylo
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 3
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 6
8
+ - 7
9
9
  - 0
10
- version: 0.6.0
10
+ version: 0.7.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - mwagg
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-03 00:00:00 +00:00
18
+ date: 2010-11-11 00:00:00 +00:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -125,6 +125,7 @@ files:
125
125
  - TODO
126
126
  - cucumber.yml
127
127
  - features/fixtures.rb
128
+ - features/fixtures/child-min.js
128
129
  - features/fixtures/child.css
129
130
  - features/fixtures/child.js
130
131
  - features/fixtures/grand_parent.css
@@ -149,12 +150,14 @@ files:
149
150
  - features/stylesheets.feature
150
151
  - features/stylo_cannot_serve_asset.feature
151
152
  - features/support/env.rb
153
+ - lib/jsmin.rb
152
154
  - lib/stylo.rb
153
155
  - lib/stylo/asset_loader.rb
154
156
  - lib/stylo/combiner.rb
155
157
  - lib/stylo/config.rb
156
158
  - lib/stylo/pipeline_steps/caching.rb
157
159
  - lib/stylo/pipeline_steps/javascript.rb
160
+ - lib/stylo/pipeline_steps/javascript_minifying.rb
158
161
  - lib/stylo/pipeline_steps/sass.rb
159
162
  - lib/stylo/pipeline_steps/stylesheet.rb
160
163
  - lib/stylo/processor.rb
@@ -164,6 +167,7 @@ files:
164
167
  - spec/asset_loader_spec.rb
165
168
  - spec/combiner_spec.rb
166
169
  - spec/pipeline_steps/caching_spec.rb
170
+ - spec/pipeline_steps/javascript_minifying_spec.rb
167
171
  - spec/pipeline_steps/javascript_spec.rb
168
172
  - spec/pipeline_steps/sass_spec.rb
169
173
  - spec/pipeline_steps/stylesheet_spec.rb
@@ -209,6 +213,7 @@ test_files:
209
213
  - spec/asset_loader_spec.rb
210
214
  - spec/combiner_spec.rb
211
215
  - spec/pipeline_steps/caching_spec.rb
216
+ - spec/pipeline_steps/javascript_minifying_spec.rb
212
217
  - spec/pipeline_steps/javascript_spec.rb
213
218
  - spec/pipeline_steps/sass_spec.rb
214
219
  - spec/pipeline_steps/stylesheet_spec.rb