ramaze-asset 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.
@@ -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
+ }