ramaze-asset 0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ require 'bacon'
2
+ require File.expand_path('../bacon/color_output', __FILE__)
3
+ require 'ramaze/spec/bacon'
4
+
5
+ Bacon.extend(Bacon::ColorOutput)
6
+ Bacon.summary_on_exit
7
+
8
+ shared(:asset_manager) do
9
+ behaves_like :rack_test
10
+
11
+ after do
12
+ path = __DIR__('../../../../spec/fixtures/public/minified/*')
13
+
14
+ Dir.glob(path).each do |file|
15
+ File.unlink(file)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ module Ramaze
2
+ module Asset
3
+ Version = '0.2'
4
+ end # Asset
5
+ end # Ramaze
@@ -0,0 +1,110 @@
1
+ #--
2
+ # Copyright (c) 2008 Ryan Grove <ryan@wonko.com>
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # * Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ # * Redistributions in binary form must reproduce the above copyright notice,
11
+ # this list of conditions and the following disclaimer in the documentation
12
+ # and/or other materials provided with the distribution.
13
+ # * Neither the name of this project nor the names of its contributors may be
14
+ # used to endorse or promote products derived from this software without
15
+ # specific prior written permission.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
21
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ #++
28
+
29
+ # = CSSMin
30
+ #
31
+ # Minifies CSS using a fast, safe routine adapted from Julien Lecomte's YUI
32
+ # Compressor, which was in turn adapted from Isaac Schlueter's cssmin PHP
33
+ # script.
34
+ #
35
+ # Author:: Ryan Grove (mailto:ryan@wonko.com)
36
+ # Version:: 1.0.2 (2008-08-23)
37
+ # Copyright:: Copyright (c) 2008 Ryan Grove. All rights reserved.
38
+ # License:: New BSD License (http://opensource.org/licenses/bsd-license.php)
39
+ # Website:: http://github.com/rgrove/cssmin/
40
+ #
41
+ # == Example
42
+ #
43
+ # require 'rubygems'
44
+ # require 'cssmin'
45
+ #
46
+ # File.open('example.css', 'r') {|file| puts CSSMin.minify(file) }
47
+ #
48
+ module CSSMin
49
+
50
+ # Reads CSS from +input+ (which can be a String or an IO object) and
51
+ # returns a String containing minified CSS.
52
+ def self.minify(input)
53
+ css = input.is_a?(IO) ? input.read : input.dup.to_s
54
+
55
+ # Remove comments.
56
+ css.gsub!(/\/\*[\s\S]*?\*\//, '')
57
+
58
+ # Compress all runs of whitespace to a single space to make things easier
59
+ # to work with.
60
+ css.gsub!(/\s+/, ' ')
61
+
62
+ # Replace box model hacks with placeholders.
63
+ css.gsub!(/"\\"\}\\""/, '___BMH___')
64
+
65
+ # Remove unnecessary spaces, but be careful not to turn "p :link {...}"
66
+ # into "p:link{...}".
67
+ css.gsub!(/(?:^|\})[^\{:]+\s+:+[^\{]*\{/) do |match|
68
+ match.gsub(':', '___PSEUDOCLASSCOLON___')
69
+ end
70
+ css.gsub!(/\s+([!\{\};:>+\(\)\],])/, '\1')
71
+ css.gsub!('___PSEUDOCLASSCOLON___', ':')
72
+ css.gsub!(/([!\{\}:;>+\(\[,])\s+/, '\1')
73
+
74
+ # Add missing semicolons.
75
+ css.gsub!(/([^;\}])\}/, '\1;}')
76
+
77
+ # Replace 0(%, em, ex, px, in, cm, mm, pt, pc) with just 0.
78
+ css.gsub!(/([\s:])([+-]?0)(?:%|em|ex|px|in|cm|mm|pt|pc)/i, '\1\2')
79
+
80
+ # Replace 0 0 0 0; with 0.
81
+ css.gsub!(/:(?:0 )+0;/, ':0;')
82
+
83
+ # Replace background-position:0; with background-position:0 0;
84
+ css.gsub!('background-position:0;', 'background-position:0 0;')
85
+
86
+ # Replace 0.6 with .6, but only when preceded by : or a space.
87
+ css.gsub!(/(:|\s)0+\.(\d+)/, '\1.\2')
88
+
89
+ # Convert rgb color values to hex values.
90
+ css.gsub!(/rgb\s*\(\s*([0-9,\s]+)\s*\)/) do |match|
91
+ '#' << $1.scan(/\d+/).map{|n| n.to_i.to_s(16).rjust(2, '0') }.join
92
+ end
93
+
94
+ # Compress color hex values, making sure not to touch values used in IE
95
+ # filters, since they would break.
96
+ css.gsub!(/([^"'=\s])(\s?)\s*#([0-9a-f])\3([0-9a-f])\4([0-9a-f])\5/i, '\1\2#\3\4\5')
97
+
98
+ # Remove empty rules.
99
+ css.gsub!(/[^\}]+\{;\}\n/, '')
100
+
101
+ # Re-insert box model hacks.
102
+ css.gsub!('___BMH___', '"\"}\""')
103
+
104
+ # Prevent redundant semicolons.
105
+ css.gsub!(/;;+/, ';')
106
+
107
+ css.strip
108
+ end
109
+
110
+ end
@@ -0,0 +1,280 @@
1
+ #--
2
+ # jsmin.rb - Ruby implementation of Douglas Crockford's JSMin.
3
+ #
4
+ # This is a port of jsmin.c, and is distributed under the same terms, which are
5
+ # as follows:
6
+ #
7
+ # Copyright (c) 2002 Douglas Crockford (www.crockford.com)
8
+ #
9
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ # of this software and associated documentation files (the "Software"), to deal
11
+ # in the Software without restriction, including without limitation the rights
12
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ # copies of the Software, and to permit persons to whom the Software is
14
+ # furnished to do so, subject to the following conditions:
15
+ #
16
+ # The above copyright notice and this permission notice shall be included in all
17
+ # copies or substantial portions of the Software.
18
+ #
19
+ # The Software shall be used for Good, not Evil.
20
+ #
21
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ # SOFTWARE.
28
+ #++
29
+
30
+ require 'strscan'
31
+
32
+ # = JSMin
33
+ #
34
+ # Ruby implementation of Douglas Crockford's JavaScript minifier, JSMin.
35
+ #
36
+ # *Author*:: Ryan Grove (mailto:ryan@wonko.com)
37
+ # *Version*:: 1.0.1 (2008-11-10)
38
+ # *Copyright*:: Copyright (c) 2008 Ryan Grove. All rights reserved.
39
+ # *Website*:: http://github.com/rgrove/jsmin
40
+ #
41
+ # == Example
42
+ #
43
+ # require 'rubygems'
44
+ # require 'jsmin'
45
+ #
46
+ # File.open('example.js', 'r') {|file| puts JSMin.minify(file) }
47
+ #
48
+ module JSMin
49
+ CHR_APOS = "'".freeze
50
+ CHR_ASTERISK = '*'.freeze
51
+ CHR_BACKSLASH = '\\'.freeze
52
+ CHR_CR = "\r".freeze
53
+ CHR_FRONTSLASH = '/'.freeze
54
+ CHR_LF = "\n".freeze
55
+ CHR_QUOTE = '"'.freeze
56
+ CHR_SPACE = ' '.freeze
57
+
58
+ ORD_LF = ?\n
59
+ ORD_SPACE = ?\ # Prevents editors from removing trailing whitespace
60
+ ORD_TILDE = ?~
61
+
62
+ class ParseError < RuntimeError
63
+ attr_accessor :source, :line
64
+ def initialize(err, source, line)
65
+ @source = source,
66
+ @line = line
67
+ super "JSMin Parse Error: #{err} at line #{line} of #{source}"
68
+ end
69
+ end
70
+
71
+ class << self
72
+ def raise(err)
73
+ super ParseError.new(err, @source, @line)
74
+ end
75
+
76
+ # Reads JavaScript from _input_ (which can be a String or an IO object) and
77
+ # returns a String containing minified JS.
78
+ def minify(input)
79
+ @js = StringScanner.new(input.is_a?(IO) ? input.read : input.to_s)
80
+ @source = input.is_a?(IO) ? input.inspect : input.to_s[0..100]
81
+ @line = 1
82
+
83
+ @a = "\n"
84
+ @b = nil
85
+ @lookahead = nil
86
+ @output = ''
87
+
88
+ action_get
89
+
90
+ while !@a.nil? do
91
+ case @a
92
+ when CHR_SPACE
93
+ if alphanum?(@b)
94
+ action_output
95
+ else
96
+ action_copy
97
+ end
98
+
99
+ when CHR_LF
100
+ if @b == CHR_SPACE
101
+ action_get
102
+ elsif @b =~ /[{\[\(+-]/
103
+ action_output
104
+ else
105
+ if alphanum?(@b)
106
+ action_output
107
+ else
108
+ action_copy
109
+ end
110
+ end
111
+
112
+ else
113
+ if @b == CHR_SPACE
114
+ if alphanum?(@a)
115
+ action_output
116
+ else
117
+ action_get
118
+ end
119
+ elsif @b == CHR_LF
120
+ if @a =~ /[}\]\)\\"+-]/
121
+ action_output
122
+ else
123
+ if alphanum?(@a)
124
+ action_output
125
+ else
126
+ action_get
127
+ end
128
+ end
129
+ else
130
+ action_output
131
+ end
132
+ end
133
+ end
134
+
135
+ @output
136
+ end
137
+
138
+ private
139
+
140
+ # Corresponds to action(1) in jsmin.c.
141
+ def action_output
142
+ @output << @a
143
+ action_copy
144
+ end
145
+
146
+ # Corresponds to action(2) in jsmin.c.
147
+ def action_copy
148
+ @a = @b
149
+
150
+ if @a == CHR_APOS || @a == CHR_QUOTE
151
+ loop do
152
+ @output << @a
153
+ @a = get
154
+
155
+ break if @a == @b
156
+
157
+ if @a[0] <= ORD_LF
158
+ raise "unterminated string literal: #{@a.inspect}"
159
+ end
160
+
161
+ if @a == CHR_BACKSLASH
162
+ @output << @a
163
+ @a = get
164
+
165
+ if @a[0] <= ORD_LF
166
+ raise "unterminated string literal: #{@a.inspect}"
167
+ end
168
+ end
169
+ end
170
+ end
171
+
172
+ action_get
173
+ end
174
+
175
+ # Corresponds to action(3) in jsmin.c.
176
+ def action_get
177
+ @b = nextchar
178
+
179
+ if @b == CHR_FRONTSLASH && (@a == CHR_LF || @a =~ /[\(,=:\[!&|?{};]/)
180
+ @output << @a
181
+ @output << @b
182
+
183
+ loop do
184
+ @a = get
185
+
186
+ # Inside a regex [...] set, which MAY contain a '/' itself.
187
+ # Example:
188
+ # mootools Form.Validator near line 460:
189
+ # return Form.Validator.getValidator('IsEmpty').test(element) || (/^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]\.?){0,63}[a-z0-9!#$%&'*+/=?^_`{|}~-]@(?:(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\])$/i).test(element.get('value'));
190
+ if @a == '['
191
+ loop do
192
+ @output << @a
193
+ @a = get
194
+ case @a
195
+ when ']' then break
196
+ when CHR_BACKSLASH then
197
+ @output << @a
198
+ @a = get
199
+ when @a[0] <= ORD_LF
200
+ raise "JSMin parse error: unterminated regular expression " +
201
+ "literal: #{@a}"
202
+ end
203
+ end
204
+ elsif @a == CHR_FRONTSLASH
205
+ break
206
+ elsif @a == CHR_BACKSLASH
207
+ @output << @a
208
+ @a = get
209
+ elsif @a[0] <= ORD_LF
210
+ raise "unterminated regular expression : #{@a.inspect}"
211
+ end
212
+
213
+ @output << @a
214
+ end
215
+
216
+ @b = nextchar
217
+ end
218
+ end
219
+
220
+ # Returns true if +c+ is a letter, digit, underscore, dollar sign,
221
+ # backslash, or non-ASCII character.
222
+ def alphanum?(c)
223
+ c.is_a?(String) && !c.empty? && (c[0] > ORD_TILDE || c =~ /[0-9a-z_$\\]/i)
224
+ end
225
+
226
+ # Returns the next character from the input. If the character is a control
227
+ # character, it will be translated to a space or linefeed.
228
+ def get
229
+ if @lookahead
230
+ c = @lookahead
231
+ @lookahead = nil
232
+ else
233
+ c = @js.getch
234
+ if c == CHR_LF || c == CHR_CR
235
+ @line += 1
236
+ return CHR_LF
237
+ end
238
+ return ' ' unless c.nil? || c[0] >= ORD_SPACE
239
+ end
240
+ c
241
+ end
242
+
243
+ # Gets the next character, excluding comments.
244
+ def nextchar
245
+ c = get
246
+ return c unless c == CHR_FRONTSLASH
247
+
248
+ case peek
249
+ when CHR_FRONTSLASH
250
+ loop do
251
+ c = get
252
+ return c if c[0] <= ORD_LF
253
+ end
254
+
255
+ when CHR_ASTERISK
256
+ get
257
+ loop do
258
+ case get
259
+ when CHR_ASTERISK
260
+ if peek == CHR_FRONTSLASH
261
+ get
262
+ return ' '
263
+ end
264
+
265
+ when nil
266
+ raise 'unterminated comment'
267
+ end
268
+ end
269
+
270
+ else
271
+ return c
272
+ end
273
+ end
274
+
275
+ # Gets the next character without getting it.
276
+ def peek
277
+ @lookahead = get
278
+ end
279
+ end
280
+ end
data/pkg/.gitkeep ADDED
File without changes
@@ -0,0 +1,24 @@
1
+ require File.expand_path('../lib/ramaze/asset/version', __FILE__)
2
+
3
+ path = File.expand_path('../', __FILE__)
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'ramaze-asset'
7
+ s.version = Ramaze::Asset::Version
8
+ s.date = '2011-09-11'
9
+ s.authors = ['Yorick Peterse']
10
+ s.email = 'yorickpeterse@gmail.com'
11
+ s.summary = 'A simple yet powerful asset manager for Ramaze.'
12
+ s.homepage = 'https://github.com/yorickpeterse/ramaze-asset'
13
+ s.description = s.summary
14
+ s.files = `cd #{path}; git ls-files`.split("\n").sort
15
+ s.has_rdoc = 'yard'
16
+
17
+ s.add_dependency('ramaze', ['>= 2011.07.25'])
18
+
19
+ s.add_development_dependency('rake' , ['>= 0.9.2'])
20
+ s.add_development_dependency('yard' , ['>= 0.7.2'])
21
+ s.add_development_dependency('bacon' , ['>= 1.1.0'])
22
+ s.add_development_dependency('rdiscount', ['>= 1.6.8'])
23
+ s.add_development_dependency('rack-test', ['>= 0.6.1'])
24
+ end
data/spec/.gitkeep ADDED
File without changes
@@ -0,0 +1,126 @@
1
+ /*
2
+ github.com style (c) Vasily Polovnyov <vast@whiteants.net>
3
+ */
4
+ pre code {
5
+ display: block; padding: 0.5em;
6
+ color: #000;
7
+ background: #f8f8ff
8
+ }
9
+
10
+ pre .comment,
11
+ pre .template_comment,
12
+ pre .diff .header,
13
+ pre .javadoc {
14
+ color: #998;
15
+ font-style: italic
16
+ }
17
+
18
+ pre .keyword,
19
+ pre .css .rule .keyword,
20
+ pre .winutils,
21
+ pre .javascript .title,
22
+ pre .lisp .title,
23
+ pre .subst {
24
+ color: #000;
25
+ font-weight: bold
26
+ }
27
+
28
+ pre .number,
29
+ pre .hexcolor {
30
+ color: #40a070
31
+ }
32
+
33
+ pre .string,
34
+ pre .tag .value,
35
+ pre .phpdoc,
36
+ pre .tex .formula {
37
+ color: #d14
38
+ }
39
+
40
+ pre .title,
41
+ pre .id {
42
+ color: #900;
43
+ font-weight: bold
44
+ }
45
+
46
+ pre .javascript .title,
47
+ pre .lisp .title,
48
+ pre .subst {
49
+ font-weight: normal
50
+ }
51
+
52
+ pre .class .title,
53
+ pre .haskell .label,
54
+ pre .tex .command {
55
+ color: #458;
56
+ font-weight: bold
57
+ }
58
+
59
+ pre .tag,
60
+ pre .tag .title,
61
+ pre .rules .property,
62
+ pre .django .tag .keyword {
63
+ color: #000080;
64
+ font-weight: normal
65
+ }
66
+
67
+ pre .attribute,
68
+ pre .variable,
69
+ pre .instancevar,
70
+ pre .lisp .body {
71
+ color: #008080
72
+ }
73
+
74
+ pre .regexp {
75
+ color: #009926
76
+ }
77
+
78
+ pre .class {
79
+ color: #458;
80
+ font-weight: bold
81
+ }
82
+
83
+ pre .symbol,
84
+ pre .ruby .symbol .string,
85
+ pre .ruby .symbol .keyword,
86
+ pre .ruby .symbol .keymethods,
87
+ pre .lisp .keyword,
88
+ pre .tex .special,
89
+ pre .input_number {
90
+ color: #990073
91
+ }
92
+
93
+ pre .builtin,
94
+ pre .built_in,
95
+ pre .lisp .title {
96
+ color: #0086b3
97
+ }
98
+
99
+ pre .preprocessor,
100
+ pre .pi,
101
+ pre .doctype,
102
+ pre .shebang,
103
+ pre .cdata {
104
+ color: #999;
105
+ font-weight: bold
106
+ }
107
+
108
+ pre .deletion {
109
+ background: #fdd
110
+ }
111
+
112
+ pre .addition {
113
+ background: #dfd
114
+ }
115
+
116
+ pre .diff .change {
117
+ background: #0086b3
118
+ }
119
+
120
+ pre .chunk {
121
+ color: #aaa
122
+ }
123
+
124
+ pre .tex .formula {
125
+ opacity: 0.5;
126
+ }