hanami-assets 1.3.5 → 2.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/README.md +92 -314
  4. data/hanami-assets.gemspec +26 -33
  5. data/lib/hanami/assets/asset.rb +83 -0
  6. data/lib/hanami/assets/base_url.rb +64 -0
  7. data/lib/hanami/assets/config.rb +98 -0
  8. data/lib/hanami/assets/errors.rb +46 -0
  9. data/lib/hanami/assets/version.rb +2 -2
  10. data/lib/hanami/assets.rb +61 -143
  11. data/lib/hanami-assets.rb +3 -0
  12. metadata +33 -115
  13. data/lib/hanami/assets/bundler/asset.rb +0 -100
  14. data/lib/hanami/assets/bundler/compressor.rb +0 -63
  15. data/lib/hanami/assets/bundler/manifest_entry.rb +0 -64
  16. data/lib/hanami/assets/bundler.rb +0 -154
  17. data/lib/hanami/assets/cache.rb +0 -102
  18. data/lib/hanami/assets/compiler.rb +0 -287
  19. data/lib/hanami/assets/compilers/less.rb +0 -31
  20. data/lib/hanami/assets/compilers/sass.rb +0 -61
  21. data/lib/hanami/assets/compressors/abstract.rb +0 -119
  22. data/lib/hanami/assets/compressors/builtin_javascript.rb +0 -36
  23. data/lib/hanami/assets/compressors/builtin_stylesheet.rb +0 -57
  24. data/lib/hanami/assets/compressors/closure_javascript.rb +0 -25
  25. data/lib/hanami/assets/compressors/javascript.rb +0 -77
  26. data/lib/hanami/assets/compressors/jsmin.rb +0 -284
  27. data/lib/hanami/assets/compressors/null_compressor.rb +0 -19
  28. data/lib/hanami/assets/compressors/sass_stylesheet.rb +0 -36
  29. data/lib/hanami/assets/compressors/stylesheet.rb +0 -77
  30. data/lib/hanami/assets/compressors/uglifier_javascript.rb +0 -25
  31. data/lib/hanami/assets/compressors/yui_javascript.rb +0 -25
  32. data/lib/hanami/assets/compressors/yui_stylesheet.rb +0 -25
  33. data/lib/hanami/assets/config/global_sources.rb +0 -52
  34. data/lib/hanami/assets/config/manifest.rb +0 -142
  35. data/lib/hanami/assets/config/sources.rb +0 -80
  36. data/lib/hanami/assets/configuration.rb +0 -657
  37. data/lib/hanami/assets/helpers.rb +0 -945
  38. data/lib/hanami/assets/precompiler.rb +0 -97
@@ -1,25 +0,0 @@
1
- require 'hanami/assets/compressors/javascript'
2
- require 'closure-compiler'
3
-
4
- module Hanami
5
- module Assets
6
- module Compressors
7
- # Google Closure Compiler for JavaScript
8
- #
9
- # Depends on <tt>closure-compiler</tt> gem
10
- #
11
- # @see https://developers.google.com/closure/compiler
12
- # @see https://rubygems.org/gems/closure-compiler
13
- #
14
- # @since 0.1.0
15
- # @api private
16
- class ClosureJavascript < Javascript
17
- # @since 0.1.0
18
- # @api private
19
- def initialize
20
- @compressor = Closure::Compiler.new
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,77 +0,0 @@
1
- require 'hanami/assets/compressors/abstract'
2
-
3
- module Hanami
4
- module Assets
5
- module Compressors
6
- # Base class for JavaScript compressors
7
- #
8
- # @since 0.1.0
9
- # @api private
10
- class Javascript < Abstract
11
- # Factory for Javascript compressors.
12
- #
13
- # It loads a compressor for the given name.
14
- #
15
- # @param engine_name [Symbol,String,NilClass,#compress] the name of the
16
- # engine to load or an instance of an engine
17
- #
18
- # @return [Hanami::Assets::Compressors::Abstract] returns a concrete
19
- # implementation of a compressor
20
- #
21
- # @raise [Hanami::Assets::Compressors::UnknownCompressorError] when the
22
- # given name refers to an unknown compressor engine
23
- #
24
- # @since 0.1.0
25
- # @api private
26
- #
27
- # @see Hanami::Assets::Compressors::Abstract#for
28
- # @see Hanami::Assets::Configuration#javascript_compressor
29
- #
30
- # @example Basic Usage
31
- # require 'hanami/assets'
32
- # require 'hanami/assets/compressors/javascript'
33
- #
34
- # Hanami::Assets::Compressors::Javascript.for(:closure)
35
- # # => #<Hanami::Assets::Compressors::ClosureJavascript:0x007fa32a32e108 ...>
36
- #
37
- # @example Null Compressor
38
- # require 'hanami/assets'
39
- # require 'hanami/assets/compressors/javascript'
40
- #
41
- # Hanami::Assets::Compressors::Javascript.for(nil)
42
- # # => #<Hanami::Assets::Compressors::NullCompressor:0x007fa32a314258>
43
- #
44
- # @example Custom Compressor
45
- # require 'hanami/assets'
46
- # require 'hanami/assets/compressors/javascript'
47
- #
48
- # class CustomJavascriptCompressor
49
- # def compress(filename)
50
- # # ...
51
- # end
52
- # end
53
- #
54
- # Hanami::Assets::Compressors::Javascript.for(CustomJavascriptCompressor.new)
55
- # # => #<CustomJavascriptCompressor:0x007fa32a2cdf10>
56
- #
57
- # @example Third Party Compressor
58
- # require 'hanami/assets'
59
- # require 'hanami/assets/compressors/javascript'
60
- # require 'hanami/foo/compressor' # third party gem
61
- #
62
- # Hanami::Assets::Compressors::Javascript.for(:foo)
63
- # # => #<Hanami::Assets::Compressors::FooJavascript:0x007fa3dd9ed968>
64
- #
65
- # @example Unknown Engine
66
- # require 'hanami/assets'
67
- # require 'hanami/assets/compressors/javascript'
68
- #
69
- # Hanami::Assets::Compressors::Javascript.for(:wat)
70
- # # => Hanami::Assets::Compressors::UnknownCompressorError: Unknown Javascript compressor: :wat
71
- def self.for(engine_name)
72
- super
73
- end
74
- end
75
- end
76
- end
77
- end
@@ -1,284 +0,0 @@
1
- #--
2
- # jsmin.rb - Ruby implementation of Douglas Crockford's JSMin.
3
- #
4
- # This port of jsmin.c was made by Ryan Grove (@rgrove) as work for <tt>jsmin</tt> gem.
5
- # Copyright (c) 2008-2012 Ryan Grove
6
- #
7
- # This is a port of jsmin.c, and is distributed under the same terms, which are
8
- # as follows:
9
- #
10
- # Copyright (c) 2002 Douglas Crockford (www.crockford.com)
11
- #
12
- # Permission is hereby granted, free of charge, to any person obtaining a copy
13
- # of this software and associated documentation files (the "Software"), to deal
14
- # in the Software without restriction, including without limitation the rights
15
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
- # copies of the Software, and to permit persons to whom the Software is
17
- # furnished to do so, subject to the following conditions:
18
- #
19
- # The above copyright notice and this permission notice shall be included in all
20
- # copies or substantial portions of the Software.
21
- #
22
- # The Software shall be used for Good, not Evil.
23
- #
24
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
- # SOFTWARE.
31
- #++
32
-
33
- require 'strscan'
34
-
35
- # = JSMin
36
- #
37
- # Ruby implementation of Douglas Crockford's JavaScript minifier, JSMin.
38
- #
39
- # *Author*:: Ryan Grove (mailto:ryan@wonko.com)
40
- # *Version*:: 1.0.1 (2008-11-10)
41
- # *Copyright*:: Copyright (c) 2008 Ryan Grove. All rights reserved.
42
- # *Website*:: http://github.com/rgrove/jsmin
43
- #
44
- # == Example
45
- #
46
- # require 'rubygems'
47
- # require 'jsmin'
48
- #
49
- # File.open('example.js', 'r') {|file| puts JSMin.minify(file) }
50
- #
51
- # @api private
52
- module JSMin
53
- CHR_APOS = "'".freeze
54
- CHR_ASTERISK = '*'.freeze
55
- CHR_BACKSLASH = '\\'.freeze
56
- CHR_CR = "\r".freeze
57
- CHR_FRONTSLASH = '/'.freeze
58
- CHR_LF = "\n".freeze
59
- CHR_QUOTE = '"'.freeze
60
- CHR_SPACE = ' '.freeze
61
-
62
- ORD_LF = ?\n
63
- ORD_SPACE = ?\
64
- ORD_TILDE = ?~
65
-
66
- class ParseError < RuntimeError
67
- attr_accessor :source, :line
68
- def initialize(err, source, line)
69
- @source = source,
70
- @line = line
71
- super "JSMin Parse Error: #{err} at line #{line} of #{source}"
72
- end
73
- end
74
-
75
- class << self
76
- def raise(err)
77
- super ParseError.new(err, @source, @line)
78
- end
79
-
80
- # Reads JavaScript from _input_ (which can be a String or an IO object) and
81
- # returns a String containing minified JS.
82
- def minify(input)
83
- @js = StringScanner.new(input.is_a?(IO) ? input.read : input.to_s)
84
- @source = input.is_a?(IO) ? input.inspect : input.to_s[0..100]
85
- @line = 1
86
-
87
- @a = "\n"
88
- @b = nil
89
- @lookahead = nil
90
- @output = ''
91
-
92
- action_get
93
-
94
- while !@a.nil? do
95
- case @a
96
- when CHR_SPACE
97
- if alphanum?(@b)
98
- action_output
99
- else
100
- action_copy
101
- end
102
-
103
- when CHR_LF
104
- if @b == CHR_SPACE
105
- action_get
106
- elsif @b =~ /[{\[\(+-]/
107
- action_output
108
- else
109
- if alphanum?(@b)
110
- action_output
111
- else
112
- action_copy
113
- end
114
- end
115
-
116
- else
117
- if @b == CHR_SPACE
118
- if alphanum?(@a)
119
- action_output
120
- else
121
- action_get
122
- end
123
- elsif @b == CHR_LF
124
- if @a =~ /[}\]\)\\"+-]/
125
- action_output
126
- else
127
- if alphanum?(@a)
128
- action_output
129
- else
130
- action_get
131
- end
132
- end
133
- else
134
- action_output
135
- end
136
- end
137
- end
138
-
139
- @output
140
- end
141
-
142
- private
143
-
144
- # Corresponds to action(1) in jsmin.c.
145
- def action_output
146
- @output << @a
147
- action_copy
148
- end
149
-
150
- # Corresponds to action(2) in jsmin.c.
151
- def action_copy
152
- @a = @b
153
-
154
- if @a == CHR_APOS || @a == CHR_QUOTE
155
- loop do
156
- @output << @a
157
- @a = get
158
-
159
- break if @a == @b
160
-
161
- if @a[0] <= ORD_LF
162
- raise "unterminated string literal: #{@a.inspect}"
163
- end
164
-
165
- if @a == CHR_BACKSLASH
166
- @output << @a
167
- @a = get
168
-
169
- if @a[0] <= ORD_LF
170
- raise "unterminated string literal: #{@a.inspect}"
171
- end
172
- end
173
- end
174
- end
175
-
176
- action_get
177
- end
178
-
179
- # Corresponds to action(3) in jsmin.c.
180
- def action_get
181
- @b = nextchar
182
-
183
- if @b == CHR_FRONTSLASH && (@a == CHR_LF || @a =~ /[\(,=:\[!&|?{};]/)
184
- @output << @a
185
- @output << @b
186
-
187
- loop do
188
- @a = get
189
-
190
- # Inside a regex [...] set, which MAY contain a '/' itself.
191
- # Example:
192
- # mootools Form.Validator near line 460:
193
- # 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'));
194
- if @a == '['
195
- loop do
196
- @output << @a
197
- @a = get
198
- case @a
199
- when ']' then break
200
- when CHR_BACKSLASH then
201
- @output << @a
202
- @a = get
203
- when @a[0] <= ORD_LF
204
- raise "JSMin parse error: unterminated regular expression " +
205
- "literal: #{@a}"
206
- end
207
- end
208
- elsif @a == CHR_FRONTSLASH
209
- break
210
- elsif @a == CHR_BACKSLASH
211
- @output << @a
212
- @a = get
213
- elsif @a[0] <= ORD_LF
214
- raise "unterminated regular expression : #{@a.inspect}"
215
- end
216
-
217
- @output << @a
218
- end
219
-
220
- @b = nextchar
221
- end
222
- end
223
-
224
- # Returns true if +c+ is a letter, digit, underscore, dollar sign,
225
- # backslash, or non-ASCII character.
226
- def alphanum?(c)
227
- c.is_a?(String) && !c.empty? && (c[0] > ORD_TILDE || c =~ /[0-9a-z_$\\]/i)
228
- end
229
-
230
- # Returns the next character from the input. If the character is a control
231
- # character, it will be translated to a space or linefeed.
232
- def get
233
- if @lookahead
234
- c = @lookahead
235
- @lookahead = nil
236
- else
237
- c = @js.getch
238
- if c == CHR_LF || c == CHR_CR
239
- @line += 1
240
- return CHR_LF
241
- end
242
- return ' ' unless c.nil? || c[0] >= ORD_SPACE
243
- end
244
- c
245
- end
246
-
247
- # Gets the next character, excluding comments.
248
- def nextchar
249
- c = get
250
- return c unless c == CHR_FRONTSLASH
251
-
252
- case peek
253
- when CHR_FRONTSLASH
254
- loop do
255
- c = get
256
- return c if c[0] <= ORD_LF
257
- end
258
-
259
- when CHR_ASTERISK
260
- get
261
- loop do
262
- case get
263
- when CHR_ASTERISK
264
- if peek == CHR_FRONTSLASH
265
- get
266
- return ' '
267
- end
268
-
269
- when nil
270
- raise 'unterminated comment'
271
- end
272
- end
273
-
274
- else
275
- return c
276
- end
277
- end
278
-
279
- # Gets the next character without getting it.
280
- def peek
281
- @lookahead = get
282
- end
283
- end
284
- end
@@ -1,19 +0,0 @@
1
- require 'hanami/assets/compressors/abstract'
2
-
3
- module Hanami
4
- module Assets
5
- module Compressors
6
- # No-op, it returns the asset contents without to compress them.
7
- #
8
- # @since 0.1.0
9
- # @api private
10
- class NullCompressor < Abstract
11
- # @since 0.1.0
12
- # @api private
13
- def compress(filename)
14
- read(filename)
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,36 +0,0 @@
1
- require 'hanami/assets/compressors/stylesheet'
2
-
3
- module Hanami
4
- module Assets
5
- module Compressors
6
- # Sass compressor for stylesheet
7
- #
8
- # It depends on <tt>sassc</tt> gem.
9
- #
10
- # @since 0.1.0
11
- # @api private
12
- #
13
- # @see http://sass-lang.com
14
- # @see https://rubygems.org/gems/sass
15
- class SassStylesheet < Stylesheet
16
- # @since 0.1.0
17
- # @api private
18
- def initialize
19
- require 'sassc'
20
- @compressor = ::SassC::Engine
21
- end
22
-
23
- # @since 0.1.0
24
- # @api private
25
- def compress(filename)
26
- compressor.new(
27
- read(filename),
28
- filename: filename,
29
- syntax: :scss,
30
- style: :compressed
31
- ).render
32
- end
33
- end
34
- end
35
- end
36
- end
@@ -1,77 +0,0 @@
1
- require 'hanami/assets/compressors/abstract'
2
-
3
- module Hanami
4
- module Assets
5
- module Compressors
6
- # Base class for stylesheet compressors
7
- #
8
- # @since 0.1.0
9
- # @api private
10
- class Stylesheet < Abstract
11
- # Factory for Stylesheet compressors.
12
- #
13
- # It loads a compressor for the given name.
14
- #
15
- # @param engine_name [Symbol,String,NilClass,#compress] the name of the
16
- # engine to load or an instance of an engine
17
- #
18
- # @return [Hanami::Assets::Compressors::Abstract] returns a concrete
19
- # implementation of a compressor
20
- #
21
- # @raise [Hanami::Assets::Compressors::UnknownCompressorError] when the
22
- # given name refers to an unknown compressor engine
23
- #
24
- # @since 0.1.0
25
- # @api private
26
- #
27
- # @see Hanami::Assets::Compressors::Abstract#for
28
- # @see Hanami::Assets::Configuration#stylesheet_compressor
29
- #
30
- # @example Basic Usage
31
- # require 'hanami/assets'
32
- # require 'hanami/assets/compressors/stylesheet'
33
- #
34
- # Hanami::Assets::Compressors::Stylesheet.for(:sass)
35
- # # => #<Hanami::Assets::Compressors::SassStylesheet:0x007f8674cc4a50 ...>
36
- #
37
- # @example Null Compressor
38
- # require 'hanami/assets'
39
- # require 'hanami/assets/compressors/stylesheet'
40
- #
41
- # Hanami::Assets::Compressors::Stylesheet.for(nil)
42
- # # => #<Hanami::Assets::Compressors::NullCompressor:0x007fa32a314258>
43
- #
44
- # @example Custom Compressor
45
- # require 'hanami/assets'
46
- # require 'hanami/assets/compressors/stylesheet'
47
- #
48
- # class CustomStylesheetCompressor
49
- # def compress(filename)
50
- # # ...
51
- # end
52
- # end
53
- #
54
- # Hanami::Assets::Compressors::Stylesheet.for(CustomStylesheetCompressor.new)
55
- # # => #<CustomStylesheetCompressor:0x007fa32a2cdf10>
56
- #
57
- # @example Third Party Compressor
58
- # require 'hanami/assets'
59
- # require 'hanami/assets/compressors/stylesheet'
60
- # require 'hanami/foo/compressor' # third party gem
61
- #
62
- # Hanami::Assets::Compressors::Stylesheet.for(:foo)
63
- # # => #<Hanami::Assets::Compressors::FooStylesheet:0x007fa3dd9ed968>
64
- #
65
- # @example Unknown Engine
66
- # require 'hanami/assets'
67
- # require 'hanami/assets/compressors/stylesheet'
68
- #
69
- # Hanami::Assets::Compressors::Stylesheet.for(:wat)
70
- # # => Hanami::Assets::Compressors::UnknownCompressorError: Unknown Stylesheet compressor: :wat
71
- def self.for(engine_name)
72
- super
73
- end
74
- end
75
- end
76
- end
77
- end
@@ -1,25 +0,0 @@
1
- require 'hanami/assets/compressors/javascript'
2
- require 'uglifier'
3
-
4
- module Hanami
5
- module Assets
6
- module Compressors
7
- # Uglifier compressor for JavaScript
8
- #
9
- # It depends on <tt>uglifier</tt> gem
10
- #
11
- # @since 0.1.0
12
- # @api private
13
- #
14
- # @see http://lisperator.net/uglifyjs
15
- # @see https://rubygems.org/gems/uglifier
16
- class UglifierJavascript < Javascript
17
- # @since 0.1.0
18
- # @api private
19
- def initialize
20
- @compressor = Uglifier.new
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,25 +0,0 @@
1
- require 'hanami/assets/compressors/javascript'
2
- require 'yui/compressor'
3
-
4
- module Hanami
5
- module Assets
6
- module Compressors
7
- # YUI Compressor for JavaScript
8
- #
9
- # It depends on <tt>yui-compressor</tt> gem
10
- #
11
- # @since 0.1.0
12
- # @api private
13
- #
14
- # @see http://yui.github.io/yuicompressor
15
- # @see https://rubygems.org/gems/yui-compressor
16
- class YuiJavascript < Javascript
17
- # @since 0.1.0
18
- # @api private
19
- def initialize
20
- @compressor = YUI::JavaScriptCompressor.new(munge: true)
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,25 +0,0 @@
1
- require 'hanami/assets/compressors/stylesheet'
2
- require 'yui/compressor'
3
-
4
- module Hanami
5
- module Assets
6
- module Compressors
7
- # YUI Compressor for stylesheet
8
- #
9
- # It depends on <tt>yui-compressor</tt> gem
10
- #
11
- # @since 0.1.0
12
- # @api private
13
- #
14
- # @see http://yui.github.io/yuicompressor
15
- # @see https://rubygems.org/gems/yui-compressor
16
- class YuiStylesheet < Stylesheet
17
- # @since 0.1.0
18
- # @api private
19
- def initialize
20
- @compressor = YUI::CssCompressor.new
21
- end
22
- end
23
- end
24
- end
25
- end
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "hanami/utils/load_paths"
4
-
5
- module Hanami
6
- module Assets
7
- # Configuration settings
8
- #
9
- # @since 0.1.0
10
- # @api private
11
- module Config
12
- # Global asset sources across all the duplicated <tt>Hanami::Assets</tt>
13
- # instances.
14
- #
15
- # @since 0.1.0
16
- # @api private
17
- #
18
- # @see Hanami::Assets.duplicate
19
- # @see http://www.rubydoc.info/gems/hanami-utils/Hanami/Utils/LoadPaths
20
- class GlobalSources < Utils::LoadPaths
21
- # @since 0.1.0
22
- # @api private
23
- def push(*paths)
24
- super
25
-
26
- sync_configuration
27
- sync_duplicated_frameworks
28
- end
29
-
30
- # @since 0.1.0
31
- # @api private
32
- alias_method :<<, :push
33
-
34
- private
35
-
36
- # @since 0.1.0
37
- # @api private
38
- def sync_configuration
39
- Hanami::Assets.configuration.sources << @paths
40
- end
41
-
42
- # @since 0.1.0
43
- # @api private
44
- def sync_duplicated_frameworks
45
- Hanami::Assets.duplicates.each do |duplicate|
46
- duplicate.configuration.sources << @paths
47
- end
48
- end
49
- end
50
- end
51
- end
52
- end