collage 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.html ADDED
@@ -0,0 +1,23 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC
3
+ "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
4
+ "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">
5
+ <html xmlns:svg='http://www.w3.org/2000/svg' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'>
6
+ <head><meta content='application/xhtml+xml;charset=utf-8' http-equiv='Content-type' /><title>Collage</title></head>
7
+ <body>
8
+ <h1 id='collage'>Collage</h1>
9
+
10
+ <p>This is a Rack middleware that will package all your Javascript into a single file (very much inspired by Rails&#8217; <code>javascript_include_tag(:all, :cache =&gt; true)</code>.</p>
11
+
12
+ <p>Examples:</p>
13
+
14
+ <pre><code>use Collage, :path =&gt; File.dirname(__FILE__) + &quot;/public&quot;
15
+
16
+ use Collage,
17
+ :path =&gt; File.dirname(__FILE__) + &quot;/public&quot;,
18
+ :files =&gt; [&quot;jquery*.js&quot;, &quot;*.js&quot;]</code></pre>
19
+
20
+ <p>Collage also provides a handy helper for your views:</p>
21
+
22
+ <pre><code>&lt;%= Collage.html_tag(&quot;/public&quot;) %&gt;</code></pre>
23
+ </body></html>
data/README.markdown ADDED
@@ -0,0 +1,51 @@
1
+ Collage
2
+ =======
3
+
4
+ Rack middleware that packages your JS into a single file.
5
+
6
+ Usage
7
+ -----
8
+
9
+ This middleware will package all your JavaScript into a single file – very much inspired by Rails' `javascript_include_tag(:all, :cache => true)`.
10
+
11
+ use Collage, :path => File.dirname(__FILE__) + "/public"
12
+
13
+ use Collage,
14
+ :path => File.dirname(__FILE__) + "/public",
15
+ :files => ["jquery*.js", "*.js"]
16
+
17
+ Collage also provides a handy helper for your views. This is useful because it appends the correct timestamp to the `src` attribute, so you won't have any issues with intermediate caches.
18
+
19
+ <%= Collage.html_tag("./public") %>
20
+
21
+ Installation
22
+ ------------
23
+
24
+ $ gem sources -a http://gems.github.com (you only have to do this once)
25
+ $ sudo gem install djanowski-collage
26
+
27
+ License
28
+ -------
29
+
30
+ Copyright (c) 2009 Damian Janowski for Citrusbyte
31
+
32
+ Permission is hereby granted, free of charge, to any person
33
+ obtaining a copy of this software and associated documentation
34
+ files (the "Software"), to deal in the Software without
35
+ restriction, including without limitation the rights to use,
36
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
37
+ copies of the Software, and to permit persons to whom the
38
+ Software is furnished to do so, subject to the following
39
+ conditions:
40
+
41
+ The above copyright notice and this permission notice shall be
42
+ included in all copies or substantial portions of the Software.
43
+
44
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
45
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
46
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
47
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
48
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
49
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
50
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
51
+ OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ gem_spec_file = "collage.gemspec"
2
+
3
+ gem_spec = eval(File.read(gem_spec_file)) rescue nil
4
+
5
+ task :default => :test
6
+
7
+ task :test do
8
+ Dir["test/**/*_test.rb"].each { |file| load file }
9
+ end
data/example/config.ru ADDED
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + "/../lib/collage"
2
+
3
+ app = proc do |env|
4
+ [200, { 'Content-Type' => 'text/html' }, ['Hi there!'] ]
5
+ end
6
+
7
+ use Collage, :path => File.dirname(__FILE__) + "/public"
8
+ run app
@@ -0,0 +1,3 @@
1
+ $(document).ready(function() {
2
+ // Something useful
3
+ });
@@ -0,0 +1,3 @@
1
+ //
2
+ // jQuery here
3
+ //
@@ -0,0 +1,10 @@
1
+ $(document).ready(function() {
2
+ // Something useful
3
+ });
4
+
5
+
6
+ //
7
+ // jQuery here
8
+ //
9
+
10
+
data/lib/collage.rb ADDED
@@ -0,0 +1,147 @@
1
+ class Collage
2
+ def initialize(app, options)
3
+ @app = app
4
+ @path = File.expand_path(options[:path])
5
+ @files = options[:files]
6
+ end
7
+
8
+ def call(env)
9
+ return @app.call(env) unless env['PATH_INFO'] == "/#{Collage.filename}"
10
+
11
+ result = Packager.new(@path, @files)
12
+
13
+ result.ignore(filename)
14
+
15
+ File.open(filename, 'w') {|f| f.write(result) }
16
+
17
+ [200, {'Content-Type' => 'text/javascript', 'Content-Length' => result.size.to_s, 'Last-Modified' => File.mtime(filename).httpdate}, result]
18
+ end
19
+
20
+ def filename
21
+ File.join(@path, Collage.filename)
22
+ end
23
+
24
+ class << self
25
+ def filename
26
+ "js.js"
27
+ end
28
+
29
+ def timestamp(path)
30
+ Packager.new(path).timestamp
31
+ end
32
+
33
+ def html_tag(path)
34
+ %Q{<script type="text/javascript" src="/#{filename}?#{timestamp(path)}"></script>}
35
+ end
36
+ end
37
+
38
+ class Packager
39
+ def initialize(path, patterns = nil)
40
+ @path = path
41
+ @patterns = Array(patterns || "**/*.js")
42
+ end
43
+
44
+ def package
45
+ files.inject("") do |contents,file|
46
+ contents += package_file(file) + "\n\n"
47
+ contents
48
+ end
49
+ end
50
+
51
+ def package_file(file)
52
+ File.read(file)
53
+ end
54
+
55
+ def files
56
+ @files ||= @patterns.map do |pattern|
57
+ File.exist?(pattern) ? pattern : Dir[File.join(@path, pattern)]
58
+ end.flatten.uniq
59
+ end
60
+
61
+ def timestamp
62
+ mtime.to_i.to_s
63
+ end
64
+
65
+ def mtime
66
+ @mtime ||= files.map {|f| File.mtime(f) }.max
67
+ end
68
+
69
+ def size
70
+ result.size
71
+ end
72
+
73
+ def result
74
+ @result ||= package
75
+ end
76
+
77
+ def each(&block)
78
+ result.each_line(&block)
79
+ end
80
+
81
+ def to_s
82
+ result.to_s
83
+ end
84
+
85
+ def inspect
86
+ "#<Collage::Packager (#{size} files)>"
87
+ end
88
+
89
+ def ignore(file)
90
+ if files.delete(file)
91
+ @result = nil
92
+ end
93
+ end
94
+
95
+ def write(path, minify = false)
96
+ contents = minify ? self.minify : result
97
+
98
+ File.open(path, "w") do |f|
99
+ f.write(contents.to_s)
100
+ end
101
+
102
+ FileUtils.touch(path, :mtime => mtime)
103
+ end
104
+
105
+ COMPRESSOR = File.expand_path("../vendor/yuicompressor-2.4.2.jar", File.dirname(__FILE__))
106
+
107
+ def minify
108
+ minified = IO.popen("java -jar #{COMPRESSOR} --type #{type}", "r+") do |io|
109
+ io.write(result.to_s)
110
+ io.close_write
111
+ io.read
112
+ end
113
+
114
+ $?.success? or raise RuntimeError.new("Error minifying #{files.inspect}.")
115
+
116
+ minified
117
+ end
118
+
119
+ def type
120
+ :js
121
+ end
122
+
123
+ class Sass < self
124
+ def package_file(file)
125
+ contents = File.read(file)
126
+
127
+ contents = ::Sass::Engine.new(contents).render if File.extname(file) == ".sass"
128
+
129
+ inject_timestamps(contents)
130
+ end
131
+
132
+ def type
133
+ :css
134
+ end
135
+
136
+ protected
137
+ def inject_timestamps(css)
138
+ css.gsub(/(url\(\"?)(.+?)(\"?\))/) do
139
+ path = File.join(@path, $2)
140
+ stamp = "?#{File.mtime(File.join(@path, $2)).to_i}" if File.exist?(path)
141
+
142
+ "#{$1}#{$2}#{stamp}#{$3}"
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
Binary file
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: collage
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 4
9
+ version: 0.1.4
10
+ platform: ruby
11
+ authors:
12
+ - Damian Janowski
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2009-03-01 00:00:00 -02:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description:
22
+ email: damian.janowski@gmail.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - README.markdown
29
+ files:
30
+ - lib/collage.rb
31
+ - README.html
32
+ - README.markdown
33
+ - Rakefile
34
+ - vendor/yuicompressor-2.4.2.jar
35
+ - example/config.ru
36
+ - example/public/app.js
37
+ - example/public/jquery.js
38
+ - example/public/js.js
39
+ has_rdoc: true
40
+ homepage:
41
+ licenses: []
42
+
43
+ post_install_message:
44
+ rdoc_options:
45
+ - --line-numbers
46
+ - --inline-source
47
+ - --title
48
+ - collage
49
+ - --main
50
+ - README.markdown
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ segments:
67
+ - 0
68
+ version: "0"
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.3.7
73
+ signing_key:
74
+ specification_version: 2
75
+ summary: Rack middleware that packages your JS into a single file.
76
+ test_files: []
77
+