condenser 1.2 → 1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/lib/condenser/asset.rb +19 -16
  3. data/lib/condenser/build_cache.rb +1 -1
  4. data/lib/condenser/context.rb +9 -25
  5. data/lib/condenser/helpers/parse_helpers.rb +1 -1
  6. data/lib/condenser/manifest.rb +3 -1
  7. data/lib/condenser/pipeline.rb +8 -3
  8. data/lib/condenser/processors/babel_processor.rb +1 -1
  9. data/lib/condenser/processors/css_media_combiner_processor.rb +81 -0
  10. data/lib/condenser/processors/js_analyzer.rb +0 -2
  11. data/lib/condenser/processors/purgecss_processor.rb +6 -4
  12. data/lib/condenser/processors/rollup_processor.rb +37 -35
  13. data/lib/condenser/resolve.rb +1 -3
  14. data/lib/condenser/templating_engine/ejs.rb +1 -1
  15. data/lib/condenser/transformers/dart_sass_transformer.rb +285 -0
  16. data/lib/condenser/transformers/jst_transformer.rb +67 -17
  17. data/lib/condenser/transformers/sass/functions.rb +133 -0
  18. data/lib/condenser/transformers/sass/importer.rb +48 -0
  19. data/lib/condenser/transformers/sass.rb +4 -0
  20. data/lib/condenser/transformers/sass_transformer.rb +124 -281
  21. data/lib/condenser/transformers/svg_transformer/base.rb +26 -0
  22. data/lib/condenser/transformers/svg_transformer/tag.rb +54 -0
  23. data/lib/condenser/transformers/svg_transformer/template.rb +151 -0
  24. data/lib/condenser/transformers/svg_transformer/template_error.rb +2 -0
  25. data/lib/condenser/transformers/svg_transformer/value.rb +13 -0
  26. data/lib/condenser/transformers/svg_transformer/var_generator.rb +10 -0
  27. data/lib/condenser/transformers/svg_transformer.rb +19 -0
  28. data/lib/condenser/version.rb +1 -1
  29. data/lib/condenser.rb +17 -5
  30. data/test/cache_test.rb +46 -2
  31. data/test/dependency_test.rb +2 -2
  32. data/test/manifest_test.rb +34 -0
  33. data/test/minifiers/terser_minifier_test.rb +0 -1
  34. data/test/minifiers/uglify_minifier_test.rb +0 -1
  35. data/test/postprocessors/css_media_combiner_test.rb +107 -0
  36. data/test/postprocessors/purgecss_test.rb +62 -0
  37. data/test/preprocessor/babel_test.rb +693 -299
  38. data/test/preprocessor/js_analyzer_test.rb +0 -2
  39. data/test/processors/rollup_test.rb +50 -20
  40. data/test/resolve_test.rb +8 -9
  41. data/test/server_test.rb +6 -1
  42. data/test/templates/ejs_test.rb +2 -11
  43. data/test/templates/erb_test.rb +0 -5
  44. data/test/test_helper.rb +3 -1
  45. data/test/transformers/dart_scss_test.rb +139 -0
  46. data/test/transformers/jst_test.rb +165 -21
  47. data/test/transformers/scss_test.rb +14 -0
  48. data/test/transformers/svg_test.rb +40 -0
  49. metadata +23 -6
  50. data/lib/condenser/transformers/sass_transformer/importer.rb +0 -50
@@ -0,0 +1,19 @@
1
+ class Condenser::SVGTransformer
2
+
3
+ autoload :Base, File.expand_path('../svg_transformer/base', __FILE__)
4
+ autoload :Tag, File.expand_path('../svg_transformer/tag', __FILE__)
5
+ autoload :Template, File.expand_path('../svg_transformer/template', __FILE__)
6
+ autoload :TemplateError, File.expand_path('../svg_transformer/template_error', __FILE__)
7
+ autoload :Value, File.expand_path('../svg_transformer/value', __FILE__)
8
+ autoload :VarGenerator, File.expand_path('../svg_transformer/var_generator', __FILE__)
9
+
10
+ def self.setup(env)
11
+ end
12
+
13
+ def self.call(environment, input)
14
+ input[:source] = Condenser::SVGTransformer::Template.new(input[:source]).to_module
15
+ end
16
+
17
+ end
18
+
19
+
@@ -1,3 +1,3 @@
1
1
  class Condenser
2
- VERSION = '1.2'
2
+ VERSION = '1.3'
3
3
  end
data/lib/condenser.rb CHANGED
@@ -19,19 +19,25 @@ class Condenser
19
19
  autoload :RollupProcessor, 'condenser/processors/rollup_processor'
20
20
  autoload :JSAnalyzer, 'condenser/processors/js_analyzer'
21
21
  autoload :PurgeCSSProcessor,'condenser/processors/purgecss_processor'
22
+ autoload :CSSMediaCombinerProcessor,'condenser/processors/css_media_combiner_processor'
22
23
  autoload :NodeProcessor, 'condenser/processors/node_processor'
23
24
  autoload :UglifyMinifier, 'condenser/minifiers/uglify_minifier'
24
25
  autoload :TerserMinifier, 'condenser/minifiers/terser_minifier'
25
26
  autoload :Erubi, 'condenser/templating_engine/erb'
27
+ autoload :Sass, 'condenser/transformers/sass'
26
28
  autoload :SassMinifier, 'condenser/minifiers/sass_minifier'
27
- autoload :SassTransformer, 'condenser/transformers/sass_transformer'
29
+ autoload :DartSassTransformer, 'condenser/transformers/dart_sass_transformer'
30
+ autoload :DartScssTransformer, 'condenser/transformers/dart_sass_transformer'
31
+ autoload :SassTransformer, 'condenser/transformers/sass_transformer'
28
32
  autoload :ScssTransformer, 'condenser/transformers/sass_transformer'
29
- autoload :EjsTemplare, 'condenser/templating_engine/ejs'
33
+ autoload :EjsTemplate, 'condenser/templating_engine/ejs'
30
34
  autoload :JstTransformer, 'condenser/transformers/jst_transformer'
35
+ autoload :SVGTransformer, 'condenser/transformers/svg_transformer'
31
36
  autoload :FileWriter, 'condenser/writers/file_writer'
32
37
  autoload :ZlibWriter, 'condenser/writers/zlib_writer'
33
38
  autoload :BrotliWriter, 'condenser/writers/brotli_writer'
34
39
  autoload :BuildCache, 'condenser/build_cache'
40
+ autoload :ParseHelpers, 'condenser/helpers/parse_helpers'
35
41
 
36
42
  def self.configure(&block)
37
43
  instance_eval(&block)
@@ -56,8 +62,8 @@ class Condenser
56
62
  configure(&block)
57
63
  elsif pipeline != false
58
64
  self.configure do
59
- # register_preprocessor 'application/javascript', Condenser::JSAnalyzer
60
- register_preprocessor 'application/javascript', Condenser::BabelProcessor
65
+ register_preprocessor 'application/javascript', Condenser::JSAnalyzer
66
+ # register_preprocessor 'application/javascript', Condenser::BabelProcessor
61
67
  register_exporter 'application/javascript', Condenser::RollupProcessor
62
68
  register_minifier 'application/javascript', Condenser::UglifyMinifier
63
69
 
@@ -132,6 +138,9 @@ Condenser.configure do
132
138
  # CSS
133
139
  register_mime_type 'text/css', extension: '.css', charset: :css
134
140
 
141
+ # PDF
142
+ register_mime_type 'application/pdf', extensions: %w(.pdf)
143
+
135
144
  # SASS
136
145
  register_mime_type 'text/sass', extensions: %w(.sass .css.sass)
137
146
  # register_transformer 'text/sass', 'text/css', SassProcessor
@@ -145,12 +154,15 @@ Condenser.configure do
145
154
 
146
155
  # EJS
147
156
  register_mime_type 'application/ejs', extensions: '.ejs', charset: :unicode
148
- register_template 'application/ejs', Condenser::EjsTemplare
157
+ register_template 'application/ejs', Condenser::EjsTemplate
149
158
 
150
159
  # JST
151
160
  register_mime_type 'application/jst', extensions: '.jst', charset: :unicode
152
161
  register_transformer 'application/jst', 'application/javascript', Condenser::JstTransformer
153
162
 
163
+ # SVG
164
+ register_transformer 'image/svg+xml', 'application/javascript', Condenser::SVGTransformer
165
+
154
166
  # Writers
155
167
  register_mime_type 'application/gzip', extensions: %w(.gz .gzip)
156
168
  register_mime_type 'application/brotli', extension: %w(.br)
data/test/cache_test.rb CHANGED
@@ -142,7 +142,7 @@ class CacheTest < ActiveSupport::TestCase
142
142
 
143
143
  end
144
144
 
145
- test 'a dependency is supurceeded by a new file' do
145
+ test 'a dependency is superceeded by a new file' do
146
146
  Dir.mkdir(File.join(@path, 'a'))
147
147
  Dir.mkdir(File.join(@path, 'b'))
148
148
  @env.clear_path
@@ -221,6 +221,21 @@ class CacheTest < ActiveSupport::TestCase
221
221
  CSS
222
222
  end
223
223
 
224
+ test '2a new dependency for a glob call is reflected in the next call' do
225
+ file "dir/a.svg", "<svg>test</svg>"
226
+ file 'test.scss', 'body { background: image-url("dir/a.svg") }'
227
+
228
+ assert_exported_file 'test.css', 'text/css', <<~CSS
229
+ body{background:url(/assets/dir/a-01a4bd3cb9faa518c5df2d2fcc8e6cd0ba24cfc3e9438dd01455ab1e59a39068.svg)}
230
+ CSS
231
+
232
+ file "dir/a.svg", "<svg>tests</svg>"
233
+
234
+ assert_exported_file 'test.css', 'text/css', <<~CSS
235
+ body{background:url(/assets/dir/a-1d7d038c7ace080963e116cbb962075a38d5e5dc68c6ff688e42d213dd432256.svg)}
236
+ CSS
237
+ end
238
+
224
239
  test 'a dependency is removed for a glob call when one of it dependencies is delted' do
225
240
  file "css/a.scss", "body { color: blue; }"
226
241
  file "css/b.scss", "body { color: green; }"
@@ -237,7 +252,7 @@ class CacheTest < ActiveSupport::TestCase
237
252
  CSS
238
253
  end
239
254
 
240
- test 'a dependency is added then changed should flush the parent' do
255
+ test 'a dependency is added then changed should flush the parent (JS)' do
241
256
  file 'a.js', "console.log('a');\n"
242
257
  file 'b.js', <<~JS
243
258
  export default function b () { console.log('b'); }
@@ -265,4 +280,33 @@ class CacheTest < ActiveSupport::TestCase
265
280
  !function(){"use strict";console.log("a"),console.log("c")}();
266
281
  JS
267
282
  end
283
+
284
+ test 'a dependency is added then changed should flush the parent (CSS)' do
285
+ file 'a.scss', "body { background: aqua; }"
286
+ file 'b.scss', <<~JS
287
+ body { background: blue; }
288
+ JS
289
+
290
+ assert_exported_file 'a.css', 'text/css', <<~JS
291
+ body{background:aqua}
292
+ JS
293
+
294
+ file 'a.scss', <<~JS
295
+ @import "b";
296
+ body { background: aqua; }
297
+ JS
298
+
299
+ assert_exported_file 'a.css', 'text/css', <<~JS
300
+ body{background:blue}body{background:aqua}
301
+ JS
302
+
303
+ file 'b.scss', <<~JS
304
+ body { background: green; }
305
+ JS
306
+
307
+ assert_exported_file 'a.css', 'text/css', <<~JS
308
+ body{background:green}body{background:aqua}
309
+ JS
310
+ end
311
+
268
312
  end
@@ -17,7 +17,7 @@ class DependencyTest < ActiveSupport::TestCase
17
17
  JS
18
18
 
19
19
  asset = @env.find('name.js')
20
- assert_equal asset.instance_variable_get(:@process_dependencies), ["models/*.js","helpers/*.js"]
20
+ assert_equal asset.instance_variable_get(:@process_dependencies).to_a, ["models/*.js","helpers/*.js"]
21
21
 
22
22
 
23
23
  assert_file 'name.js', 'application/javascript', <<~JS
@@ -54,7 +54,7 @@ class DependencyTest < ActiveSupport::TestCase
54
54
  JS
55
55
 
56
56
  asset = @env.find('name.js')
57
- assert_equal asset.instance_variable_get(:@process_dependencies), ["models/*.js","helpers/*.js"]
57
+ assert_equal asset.instance_variable_get(:@process_dependencies).to_a, ["models/*.js","helpers/*.js"]
58
58
 
59
59
 
60
60
  assert_file 'name.js', 'application/javascript', <<~JS
@@ -66,6 +66,40 @@ class ManifestTest < ActiveSupport::TestCase
66
66
  assert_equal asset.path, data['application.js']['path']
67
67
  end
68
68
 
69
+ test "compile asset dependencies includes the dependencies" do
70
+ file 'foo.svg', <<-SVG
71
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
72
+ <path d="M6 18L18 6M6 6l12 12" />
73
+ </svg>
74
+ SVG
75
+
76
+ file 'test.scss', <<-SCSS
77
+ body {
78
+ background: asset-url("foo.svg");
79
+ }
80
+ SCSS
81
+
82
+ manifest = Condenser::Manifest.new(@env, File.join(@dir, 'manifest.json'))
83
+
84
+ main_digest_path = @env['test.css'].path
85
+ dep_digest_path = @env['foo.svg'].path
86
+
87
+ assert !File.exist?("#{@dir}/#{main_digest_path}")
88
+ assert !File.exist?("#{@dir}/#{dep_digest_path}")
89
+
90
+ manifest.compile('test.css')
91
+ assert File.directory?(manifest.dir)
92
+ assert File.file?(manifest.filename)
93
+
94
+ assert File.exist?("#{@dir}/manifest.json")
95
+ assert File.exist?("#{@dir}/#{main_digest_path}")
96
+ assert File.exist?("#{@dir}/#{dep_digest_path}")
97
+
98
+ data = JSON.parse(File.read(manifest.filename))
99
+ assert_equal main_digest_path, data['test.css']['path']
100
+ assert_equal dep_digest_path, data['foo.svg']['path']
101
+ end
102
+
69
103
  # TODO:
70
104
  # test "compile asset with aliased index links" do
71
105
  # manifest = Sprockets::Manifest.new(@env, File.join(@dir, 'manifest.json'))
@@ -4,7 +4,6 @@ class TerserMinifierTest < ActiveSupport::TestCase
4
4
 
5
5
  def setup
6
6
  super
7
- @env.unregister_preprocessor('application/javascript', Condenser::BabelProcessor)
8
7
  @env.unregister_exporter('application/javascript', Condenser::RollupProcessor)
9
8
  @env.register_minifier('application/javascript', Condenser::TerserMinifier)
10
9
  end
@@ -4,7 +4,6 @@ class UglifyMinifierTest < ActiveSupport::TestCase
4
4
 
5
5
  def setup
6
6
  super
7
- @env.unregister_preprocessor('application/javascript', Condenser::BabelProcessor)
8
7
  @env.unregister_exporter('application/javascript', Condenser::RollupProcessor)
9
8
  end
10
9
 
@@ -0,0 +1,107 @@
1
+ require 'test_helper'
2
+
3
+ class MediaCombinerTest < ActiveSupport::TestCase
4
+
5
+ def setup
6
+ super
7
+ @env.register_postprocessor('text/css', Condenser::CSSMediaCombinerProcessor)
8
+ @env.unregister_minifier('text/css')
9
+ end
10
+
11
+ test 'combine media queries' do
12
+ file 'main.css', <<~CSS
13
+ .test{
14
+ display: block;
15
+ }
16
+ @media only screen and (max-width: 100px) {
17
+ .test {
18
+ display: inline-block;
19
+ color: blue;
20
+ }
21
+ }
22
+ @media only screen and (max-width: 500px) {
23
+ .test {
24
+ display: inline;
25
+ }
26
+ }
27
+
28
+ .test2{
29
+ display: block;
30
+ }
31
+ @media only screen and (max-width: 100px) {
32
+ .test2 {
33
+ display: inline-block;
34
+ }
35
+ }
36
+ CSS
37
+
38
+ assert_exported_file 'main.css', 'text/css', <<~FILE
39
+ .test{
40
+ display: block;
41
+ }
42
+
43
+
44
+
45
+ .test2{
46
+ display: block;
47
+ }
48
+ @media only screen and (max-width: 100px) {
49
+ .test {
50
+ display: inline-block;
51
+ color: blue;
52
+ }
53
+
54
+ .test2 {
55
+ display: inline-block;
56
+ }
57
+ }@media only screen and (max-width: 500px) {
58
+ .test {
59
+ display: inline;
60
+ }
61
+ }
62
+ FILE
63
+ end
64
+
65
+ test 'single line css' do
66
+ file 'main.css', <<~CSS
67
+ .test{display: block;} @media only screen and (max-width: 100px) {.test {display: inline-block;}}@media only screen and (max-width: 500px) {.test {display: inline;}}.test2{display: block;}@media only screen and (max-width: 100px) {.test2 {display: inline-block;}}
68
+ CSS
69
+
70
+ assert_exported_file 'main.css', 'text/css', <<~FILE
71
+ .test{display: block;} .test2{display: block;}@media only screen and (max-width: 100px) {.test {display: inline-block;}.test2 {display: inline-block;}}@media only screen and (max-width: 500px) {.test {display: inline;}}
72
+ FILE
73
+ end
74
+
75
+
76
+ test 'keyframes' do
77
+ file 'main.css', <<~CSS
78
+ .trobber {
79
+ animation: throb 1s infinite;
80
+ }
81
+ @keyframes throb {
82
+ 0% {
83
+ opacity: 1;
84
+ }
85
+ 100%{
86
+ opacity: 0;
87
+ }
88
+ }
89
+ CSS
90
+
91
+ assert_exported_file 'main.css', 'text/css', <<~FILE
92
+ .trobber {
93
+ animation: throb 1s infinite;
94
+ }
95
+ @keyframes throb {
96
+ 0% {
97
+ opacity: 1;
98
+ }
99
+ 100%{
100
+ opacity: 0;
101
+ }
102
+ }
103
+ FILE
104
+ end
105
+
106
+
107
+ end
@@ -79,5 +79,67 @@ class PurgeCSSTest < ActiveSupport::TestCase
79
79
  }
80
80
  FILE
81
81
  end
82
+
83
+ test 'purge from html with class with /' do
84
+ file 'main.css', <<~CSS
85
+ .test{
86
+ display: block;
87
+ }
88
+ .test2-1\\/2{
89
+ display: inline;
90
+ }
91
+ CSS
92
+ file 'index.html', <<~HTML
93
+ <div class="test2-1/2"></div>
94
+ HTML
95
+
96
+ assert_exported_file 'main.css', 'text/css', <<~FILE
97
+ .test2-1\\/2{
98
+ display: inline;
99
+ }
100
+ FILE
101
+ end
102
+
103
+ test 'purge from html with nested tag' do
104
+ file 'main.css', <<~CSS
105
+ .test pre{
106
+ display: block;
107
+ }
108
+ CSS
109
+ file 'index.html', <<~HTML
110
+ <div class="test">
111
+ <pre>Test</pre>
112
+ </div>
113
+ HTML
114
+
115
+ assert_exported_file 'main.css', 'text/css', <<~FILE
116
+ .test pre{
117
+ display: block;
118
+ }
119
+ FILE
120
+ end
121
+
122
+ test 'purge from html with nested tags' do
123
+ file 'main.css', <<~CSS
124
+ code {
125
+ background: gray;
126
+ }
127
+ pre code{
128
+ background: none;
129
+ }
130
+ CSS
131
+ file 'index.html', <<~HTML
132
+ <pre><code>Test</code></pre>
133
+ HTML
134
+
135
+ assert_exported_file 'main.css', 'text/css', <<~FILE
136
+ code {
137
+ background: gray;
138
+ }
139
+ pre code{
140
+ background: none;
141
+ }
142
+ FILE
143
+ end
82
144
 
83
145
  end