jekyll-simple-assets 0.2.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bbe1fbd068c7784ca4ed4d4ea3777ef10c45a6ed3b960d9fcfdcb843bdff8a1d
4
- data.tar.gz: 44b828531c73f697e539740ee38389626d8aa7560316c2fdff63c663b3a26592
3
+ metadata.gz: 066a9158d842b14dd87beb951baa1012dc97eb74e68009b97ebce1fc75d114dd
4
+ data.tar.gz: a78b84504fdff45054e89b9b3f017692460d9c74c3ed0017df0c45d4605f6950
5
5
  SHA512:
6
- metadata.gz: 7749e0e9835f7891e154438f8dddff62be167d2d1ac1102a6c1c999485f653a1b4b7ef057b7983bd630605306d75245c66e9f0b7667b19be178d09079c353c29
7
- data.tar.gz: 447cfa3bb7e120ae5c9626e25124202932c6e7c66e8fbeb948d2ab749225850391a346aeb25919e69fd702fbc250f1c06548fc2292e2937f28d3170bd6aadcac
6
+ metadata.gz: 556175bc3e9f81311e942242ac3b00574fdb6ac1fd979fe37cb74bd392b170ac14e49c893e917a870ed9714951e65a53e560bb1a76855bb647c2c945a8513528
7
+ data.tar.gz: 2e081620199cdf8ec5330678311d260da6b9405c25b7121324955be887018180c643a5e87cb80d2c1abb8b23fe3d28ae39233d20b00e07e0a9fc78d6549e213a
data/Gemfile.lock ADDED
@@ -0,0 +1,77 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ jekyll-simple-assets (0.2.0)
5
+ css_parser
6
+ jekyll
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ addressable (2.7.0)
12
+ public_suffix (>= 2.0.2, < 5.0)
13
+ colorator (1.1.0)
14
+ concurrent-ruby (1.1.6)
15
+ css_parser (1.7.1)
16
+ addressable
17
+ em-websocket (0.5.1)
18
+ eventmachine (>= 0.12.9)
19
+ http_parser.rb (~> 0.6.0)
20
+ eventmachine (1.2.7)
21
+ ffi (1.13.1)
22
+ forwardable-extended (2.6.0)
23
+ http_parser.rb (0.6.0)
24
+ i18n (1.8.3)
25
+ concurrent-ruby (~> 1.0)
26
+ jekyll (4.1.0)
27
+ addressable (~> 2.4)
28
+ colorator (~> 1.0)
29
+ em-websocket (~> 0.5)
30
+ i18n (~> 1.0)
31
+ jekyll-sass-converter (~> 2.0)
32
+ jekyll-watch (~> 2.0)
33
+ kramdown (~> 2.1)
34
+ kramdown-parser-gfm (~> 1.0)
35
+ liquid (~> 4.0)
36
+ mercenary (~> 0.4.0)
37
+ pathutil (~> 0.9)
38
+ rouge (~> 3.0)
39
+ safe_yaml (~> 1.0)
40
+ terminal-table (~> 1.8)
41
+ jekyll-sass-converter (2.1.0)
42
+ sassc (> 2.0.1, < 3.0)
43
+ jekyll-watch (2.2.1)
44
+ listen (~> 3.0)
45
+ kramdown (2.2.1)
46
+ rexml
47
+ kramdown-parser-gfm (1.1.0)
48
+ kramdown (~> 2.0)
49
+ liquid (4.0.3)
50
+ listen (3.2.1)
51
+ rb-fsevent (~> 0.10, >= 0.10.3)
52
+ rb-inotify (~> 0.9, >= 0.9.10)
53
+ mercenary (0.4.0)
54
+ pathutil (0.16.2)
55
+ forwardable-extended (~> 2.6)
56
+ public_suffix (4.0.5)
57
+ rb-fsevent (0.10.4)
58
+ rb-inotify (0.10.1)
59
+ ffi (~> 1.0)
60
+ rexml (3.2.4)
61
+ rouge (3.20.0)
62
+ safe_yaml (1.0.5)
63
+ sassc (2.4.0)
64
+ ffi (~> 1.9)
65
+ terminal-table (1.8.0)
66
+ unicode-display_width (~> 1.1, >= 1.1.1)
67
+ unicode-display_width (1.7.0)
68
+
69
+ PLATFORMS
70
+ ruby
71
+
72
+ DEPENDENCIES
73
+ bundler
74
+ jekyll-simple-assets!
75
+
76
+ BUNDLED WITH
77
+ 2.1.4
data/README.md CHANGED
@@ -71,6 +71,12 @@ to manipulate the output of the contenthash or asset tags.
71
71
  By default the generation of content hashes is only enabled for production
72
72
  builds (if JEKYLL_ENV is set to 'production').
73
73
 
74
+ ## Critical CSS
75
+
76
+ This plugin can also be used to generate critical css stylesheets. See
77
+ configuration for more information on doing this. To generate critical css,
78
+ [critical](https://github.com/addyosmani/critical) must be installed.
79
+
74
80
  ## Configuration
75
81
 
76
82
  ```
@@ -83,4 +89,24 @@ simple_assets:
83
89
  # The length of the content hashes generated.
84
90
  # default: 16
85
91
  hash_length: 8
92
+
93
+ # Options for generating a critical css file using the `critical` npm module
94
+ critical_css:
95
+
96
+ # Array of source css files used to take the critical css from
97
+ css_files:
98
+ - assets/css/style.css
99
+
100
+ # Array of critical css files to generate
101
+ files:
102
+ # The path of the critical css file output
103
+ - output_file: assets/css/critical.css
104
+ # The path of the input page used to generate the critical css
105
+ # either this option or layout can be used
106
+ input_page_path: _drafts/webmentions-static-site.md
107
+ # The layout to use to generate critical css
108
+ # (will use the first page found with this layout)
109
+ layout: post
110
+ # If the rules should be removed from the original source css files
111
+ extract: true
86
112
  ```
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.required_ruby_version = ">= 2.3.0"
20
20
 
21
21
  spec.add_runtime_dependency "jekyll"
22
+ spec.add_runtime_dependency "css_parser"
22
23
 
23
24
  spec.add_development_dependency "bundler"
24
25
  end
@@ -2,6 +2,11 @@
2
2
 
3
3
  require 'digest'
4
4
  require 'pathname'
5
+ require 'open3'
6
+ require 'shellwords'
7
+
8
+ require 'jekyll-simple-assets/content-hash'
9
+ require 'jekyll-simple-assets/critical'
5
10
 
6
11
  module Jekyll
7
12
  module SimpleAssets
@@ -13,14 +18,14 @@ module Jekyll
13
18
  @@config ||= @@site.config['simple_assets']
14
19
  end
15
20
 
16
- def self.hash_length
17
- config['hash_length'] || 16
18
- end
19
-
20
21
  def self.hashing_enabled?
21
22
  config['hashing_enabled'] || ENV['JEKYLL_ENV'] == 'production'
22
23
  end
23
24
 
25
+ def self.critical_css_enabled?
26
+ config.key?('critical_css')
27
+ end
28
+
24
29
  module SimpleAssetsFilters
25
30
  def md5 (input)
26
31
  Digest::MD5.hexdigest(input)
@@ -56,200 +61,69 @@ module Jekyll
56
61
  content
57
62
  end
58
63
  end
64
+ end
65
+ end
59
66
 
60
- def self.page_assets_map
61
- @@page_assets_map ||= {}
62
- end
63
-
64
- def self.asset_placeholder_map
65
- @@asset_placeholder_map ||= {}
66
- end
67
-
68
- def self.asset_contenthash_map
69
- @@asset_contenthash_map ||= {}
70
- end
71
-
72
- def self.get_placeholder (asset_path)
73
- asset_placeholder_map[asset_path] ||= Digest::MD5.base64digest(asset_path)
74
- end
75
-
76
- def self.relative_url (path)
77
- "#{ @@site.config['baseurl'] || '' }/#{ path }".gsub(%r{/{2,}}, '/')
78
- end
79
-
80
- class AssetTag < Liquid::Tag
81
- def initialize (tag_name, text, tokens)
82
- super
83
- @text = text
84
- end
85
-
86
- def get_value (context, expression)
87
- result = nil
88
-
89
- unless expression.empty?
90
- lookup_path = expression.split('.')
91
- result = context
92
- lookup_path.each do |variable|
93
- result = result[variable] if result
94
- end
95
- end
96
-
97
- case result
98
- when 'true'
99
- result = true
100
- when 'false'
101
- result = false
102
- end
103
-
104
- result || expression
105
- end
106
-
107
- def render (context)
108
- site = SimpleAssets::site(context.registers[:site])
109
-
110
- page = context.environments.first['page']
111
-
112
- args = Shellwords.split(@text)
67
+ Liquid::Template.register_tag('bundle', Jekyll::SimpleAssets::BundleTag)
68
+ Liquid::Template.register_tag('bundle_raw', Jekyll::SimpleAssets::BundleRawTag)
113
69
 
114
- page_path = context['page']['path'].sub(/^\//, '')
70
+ Liquid::Template.register_filter(Jekyll::SimpleAssets::SimpleAssetsFilters)
115
71
 
116
- asset_path = get_value(context, args[0]).sub(/^\//, '')
72
+ Jekyll::Hooks.register :site, :post_render, priority: :low do |site, payload|
73
+ Jekyll::SimpleAssets::site(site)
117
74
 
118
- if SimpleAssets::hashing_enabled?
119
- SimpleAssets::page_assets_map[page_path] ||= {}
120
- SimpleAssets::page_assets_map[page_path][asset_path] ||= {}
121
- SimpleAssets::page_assets_map[page_path][asset_path][@type] ||= []
75
+ potential_assets = []
122
76
 
123
- placeholder = SimpleAssets::get_placeholder(asset_path)
77
+ potential_assets += site.pages
78
+ potential_assets += site.static_files
124
79
 
125
- unless SimpleAssets::page_assets_map[page_path][asset_path][@type].include? placeholder
126
- SimpleAssets::page_assets_map[page_path][asset_path][@type] << placeholder
127
- end
80
+ potential_pages = potential_assets
128
81
 
129
- "#{ @type }::#{ placeholder }"
130
- else
131
- if @type == 'path'
132
- SimpleAssets::relative_url(asset_path)
133
- else
134
- placeholder[0, SimpleAssets::hash_length]
135
- end
136
- end
137
- end
138
- end
82
+ site.collections.each do |collection_name, collection|
83
+ potential_pages = potential_pages + collection.docs
84
+ end
139
85
 
140
- class PathTag < AssetTag
141
- def initialize (tag_name, text, tokens)
142
- super
143
- @type = 'path'
144
- end
86
+ if Jekyll::SimpleAssets::critical_css_enabled?
87
+ potential_assets.each do |asset|
88
+ Jekyll::SimpleAssets::make_temp_css_files_for_critical(asset)
145
89
  end
146
90
 
147
- class ContentHashTag < AssetTag
148
- def initialize (tag_name, text, tokens)
149
- super
150
- @type = 'contenthash'
151
- end
91
+ potential_pages.each do |doc|
92
+ Jekyll::SimpleAssets::get_html_input_for_critical(doc, site)
152
93
  end
153
94
 
154
- def self.resolve_asset_content_hashes (asset, site)
155
- asset_path = asset.path.sub("#{ site.config['source'] }/", '')
156
-
157
- if File.extname(asset_path) == '.scss'
158
- asset_path = Pathname.new(asset_path).sub_ext('.css').to_path()
159
- elsif File.extname(asset_path) == '.ts'
160
- asset_path = Pathname.new(asset_path).sub_ext('.js').to_path()
161
- end
162
-
163
- return unless SimpleAssets::asset_placeholder_map[asset_path]
164
- return if SimpleAssets::asset_contenthash_map[asset_path]
165
-
166
- content = ""
167
-
168
- # Prefer reading from output if available, because in theory should
169
- # be faster than from disk, but fall back to reading from disk for
170
- # static assets.
171
- if asset.respond_to? :output
172
- content = asset.output
173
- elsif File.file? asset_path
174
- content = File.read asset_path
175
- elsif File.file? asset.path
176
- content = File.read asset.path
177
- else
178
- Jekyll.logger.warn "SimpleAssets", "File: #{ asset_path } not found"
179
- end
180
-
181
- if content.nil?
182
- Jekyll.logger.warn "SimpleAssets", "#{ asset_path } has no content"
183
- end
184
-
185
- base64hash = Digest::MD5.base64digest(content)
186
-
187
- hash = base64hash[0, SimpleAssets::hash_length]
95
+ Jekyll::SimpleAssets::generate_critical_css(site)
96
+ end
188
97
 
189
- SimpleAssets::asset_contenthash_map[asset_path] = hash
98
+ if Jekyll::SimpleAssets::hashing_enabled?
99
+ potential_assets.each do |asset|
100
+ Jekyll::SimpleAssets::resolve_asset_content_hashes(asset, site)
190
101
  end
191
102
 
192
- def self.replace_placeholders_for_asset (doc, site)
193
- page_path = doc.path.sub("#{ site.config['source'] }/", '')
194
-
195
- return unless SimpleAssets::page_assets_map[page_path]
196
-
197
- SimpleAssets::page_assets_map[page_path].each do |asset_path, types|
198
- types.each do |type, placeholders|
199
- placeholders.each do |placeholder_hash|
200
- unless SimpleAssets::asset_contenthash_map[asset_path]
201
- Jekyll.logger.warn "SimpleAssets", "No contenthash for: #{ asset_path } not found"
202
- end
203
-
204
- replacement = SimpleAssets::asset_contenthash_map[asset_path]
205
-
206
- if type == 'path'
207
- replacement = "#{ asset_path }?v=#{ replacement }"
208
-
209
- replacement = SimpleAssets::relative_url(replacement)
210
- end
211
-
212
- placeholder = "#{ type }::#{ SimpleAssets::asset_placeholder_map[asset_path] }"
103
+ if Jekyll::SimpleAssets::critical_css_enabled?
104
+ Jekyll::SimpleAssets::resolve_critical_css_content_hashes(site)
105
+ end
213
106
 
214
- doc.output = doc.output.gsub(placeholder, replacement)
215
- end
216
- end
217
- end
107
+ potential_pages.each do |doc|
108
+ Jekyll::SimpleAssets::replace_placeholders_for_asset(doc, site)
218
109
  end
219
110
  end
220
111
  end
221
112
 
222
- Liquid::Template.register_tag('asset', Jekyll::SimpleAssets::PathTag)
223
- Liquid::Template.register_tag('contenthash', Jekyll::SimpleAssets::ContentHashTag)
224
- Liquid::Template.register_tag('bundle', Jekyll::SimpleAssets::BundleTag)
225
- Liquid::Template.register_tag('bundle_raw', Jekyll::SimpleAssets::BundleRawTag)
226
-
227
- Liquid::Template.register_filter(Jekyll::SimpleAssets::SimpleAssetsFilters)
228
-
229
- Jekyll::Hooks.register :site, :post_render do |site, payload|
230
- Jekyll::SimpleAssets::site(site)
231
-
232
- return unless Jekyll::SimpleAssets::hashing_enabled?
233
-
234
- potential_assets = []
235
-
236
- potential_assets += site.pages
237
- potential_assets += site.static_files
238
-
239
- potential_assets.each do |asset|
240
- Jekyll::SimpleAssets::resolve_asset_content_hashes(asset, site)
241
- end
242
-
243
- docs = []
113
+ Jekyll::Hooks.register :site, :post_read do |site|
114
+ css_pages = [];
244
115
 
245
116
  site.pages.each do |doc|
246
- Jekyll::SimpleAssets::replace_placeholders_for_asset(doc, site)
247
- end
248
-
249
- site.collections.each do |collection_name, collection|
250
- collection.docs.each do |doc|
251
- Jekyll::SimpleAssets::replace_placeholders_for_asset(doc, site)
117
+ if doc.extname == '.scss'
118
+ css_pages << doc
119
+ site.pages = site.pages - [ doc ]
252
120
  end
253
121
  end
122
+
123
+ site.pages = css_pages + site.pages
254
124
  end
255
125
 
126
+ # Jekyll::Hooks.register :pages, :post_render do |document|
127
+ # puts 'rendered:' + document.path
128
+ # end
129
+
@@ -0,0 +1,186 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jekyll
4
+ module SimpleAssets
5
+
6
+
7
+ def self.hash_length
8
+ config['hash_length'] || 16
9
+ end
10
+
11
+ def self.page_assets_map
12
+ @@page_assets_map ||= {}
13
+ end
14
+
15
+ def self.asset_placeholder_map
16
+ @@asset_placeholder_map ||= {}
17
+ end
18
+
19
+ def self.asset_contenthash_map
20
+ @@asset_contenthash_map ||= {}
21
+ end
22
+
23
+ def self.get_placeholder (asset_path)
24
+ asset_placeholder_map[asset_path] ||= Digest::MD5.base64digest(asset_path)
25
+ end
26
+
27
+ def self.relative_url (path)
28
+ "#{ @@site.config['baseurl'] || '' }/#{ path }".gsub(%r{/{2,}}, '/')
29
+ end
30
+
31
+ class AssetTag < Liquid::Tag
32
+ def initialize (tag_name, text, tokens)
33
+ super
34
+ @text = text
35
+ end
36
+
37
+ def get_value (context, expression)
38
+ result = nil
39
+
40
+ unless expression.empty?
41
+ lookup_path = expression.split('.')
42
+ result = context
43
+ lookup_path.each do |variable|
44
+ result = result[variable] if result
45
+ end
46
+ end
47
+
48
+ case result
49
+ when 'true'
50
+ result = true
51
+ when 'false'
52
+ result = false
53
+ end
54
+
55
+ result || expression
56
+ end
57
+
58
+ def render (context)
59
+ site = SimpleAssets::site(context.registers[:site])
60
+
61
+ page = context.environments.first['page']
62
+
63
+ args = Shellwords.split(@text)
64
+
65
+ page_path = context['page']['path'].sub(/^\//, '')
66
+
67
+ asset_path = get_value(context, args[0]).sub(/^\//, '')
68
+
69
+ if SimpleAssets::hashing_enabled?
70
+ SimpleAssets::page_assets_map[page_path] ||= {}
71
+ SimpleAssets::page_assets_map[page_path][asset_path] ||= {}
72
+ SimpleAssets::page_assets_map[page_path][asset_path][@type] ||= []
73
+
74
+ placeholder = SimpleAssets::get_placeholder(asset_path)
75
+
76
+ unless SimpleAssets::page_assets_map[page_path][asset_path][@type].include? placeholder
77
+ SimpleAssets::page_assets_map[page_path][asset_path][@type] << placeholder
78
+ end
79
+
80
+ "#{ @type }::#{ placeholder }"
81
+ else
82
+ if @type == 'path'
83
+ SimpleAssets::relative_url(asset_path)
84
+ else
85
+ placeholder[0, SimpleAssets::hash_length]
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ class PathTag < AssetTag
92
+ def initialize (tag_name, text, tokens)
93
+ super
94
+ @type = 'path'
95
+ end
96
+ end
97
+
98
+ class ContentHashTag < AssetTag
99
+ def initialize (tag_name, text, tokens)
100
+ super
101
+ @type = 'contenthash'
102
+ end
103
+ end
104
+
105
+ def self.resolve_asset_content_hashes (asset, site)
106
+ asset_path = asset.path.sub("#{ site.config['source'] }/", '')
107
+
108
+ if File.extname(asset_path) == '.scss'
109
+ asset_path = Pathname.new(asset_path).sub_ext('.css').to_path()
110
+ elsif File.extname(asset_path) == '.ts'
111
+ asset_path = Pathname.new(asset_path).sub_ext('.js').to_path()
112
+ end
113
+
114
+ return unless SimpleAssets::asset_placeholder_map[asset_path]
115
+ return if SimpleAssets::asset_contenthash_map[asset_path]
116
+
117
+ content = ""
118
+
119
+ # Prefer reading from output if available, because in theory should
120
+ # be faster than from disk, but fall back to reading from disk for
121
+ # static assets.
122
+ if asset.respond_to? :output
123
+ content = asset.output
124
+ elsif File.file? asset_path
125
+ content = File.read asset_path
126
+ elsif File.file? asset.path
127
+ content = File.read asset.path
128
+ else
129
+ Jekyll.logger.warn "SimpleAssets:", "File: #{ asset_path } not found"
130
+ end
131
+
132
+ if content.nil?
133
+ Jekyll.logger.warn "SimpleAssets:", "#{ asset_path } has no content"
134
+ end
135
+
136
+ base64hash = Digest::MD5.base64digest(content)
137
+
138
+ hash = base64hash[0, SimpleAssets::hash_length].gsub(/[+\/]/, '_')
139
+
140
+ SimpleAssets::asset_contenthash_map[asset_path] = hash
141
+ end
142
+
143
+ def self.replace_placeholders_for_path (page_path, input)
144
+ output = input
145
+
146
+ SimpleAssets::page_assets_map[page_path].each do |asset_path, types|
147
+ types.each do |type, placeholders|
148
+ placeholders.each do |placeholder_hash|
149
+ unless SimpleAssets::asset_contenthash_map[asset_path]
150
+ Jekyll.logger.warn "SimpleAssets:", "No contenthash for: #{ asset_path } not found"
151
+
152
+ next
153
+ end
154
+
155
+ replacement = SimpleAssets::asset_contenthash_map[asset_path]
156
+
157
+ if type == 'path'
158
+ replacement = "#{ asset_path }?v=#{ replacement }"
159
+
160
+ replacement = SimpleAssets::relative_url(replacement)
161
+ end
162
+
163
+ placeholder = "#{ type }::#{ SimpleAssets::asset_placeholder_map[asset_path] }"
164
+
165
+ output = output.gsub(placeholder, replacement)
166
+ end
167
+ end
168
+ end
169
+
170
+ output
171
+ end
172
+
173
+ def self.replace_placeholders_for_asset (doc, site)
174
+ page_path = doc.path.sub("#{ site.config['source'] }/", '')
175
+
176
+ return unless SimpleAssets::page_assets_map[page_path]
177
+
178
+ doc.output = SimpleAssets::replace_placeholders_for_path(page_path, doc.output)
179
+ end
180
+
181
+
182
+ end
183
+ end
184
+
185
+ Liquid::Template.register_tag('asset', Jekyll::SimpleAssets::PathTag)
186
+ Liquid::Template.register_tag('contenthash', Jekyll::SimpleAssets::ContentHashTag)
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'css_parser'
4
+ require 'tempfile'
5
+
6
+ module Jekyll
7
+ module SimpleAssets
8
+
9
+
10
+ def self.critical_css_source_files
11
+ @@critical_css_source_files ||= []
12
+ end
13
+
14
+ def self.make_temp_css_files_for_critical (asset)
15
+ SimpleAssets::config['critical_css']['css_files'].each do |path|
16
+ next unless asset.path == path || asset.path == path.sub(/\.css$/, '.scss')
17
+
18
+ f = Tempfile.new('css-source')
19
+ f.write asset.output
20
+ f.close
21
+
22
+ SimpleAssets::critical_css_source_files << { 'file' => f, 'page' => asset }
23
+ end
24
+ end
25
+
26
+ def self.get_html_input_for_critical (doc, site)
27
+ return unless doc.respond_to? '[]'
28
+
29
+ SimpleAssets::config['critical_css']['files'].each do |file|
30
+ next if file['html']
31
+
32
+ page_path = doc.path.sub("#{ site.config['source'] }/", '')
33
+
34
+ next unless page_path == file['input_page_path'] || file['layout'] == doc['layout']
35
+
36
+ file['html'] = doc.output
37
+ end
38
+ end
39
+
40
+ def self.generate_critical_css (site)
41
+ css_files_str = ''
42
+
43
+ SimpleAssets::critical_css_source_files.each do |f|
44
+ css_files_str += "--css #{ f['file'].path } "
45
+
46
+ f['css'] = CssParser::Parser.new
47
+ f['css'].load_string! f['page'].output
48
+ end
49
+
50
+ SimpleAssets::config['critical_css']['files'].each do |file|
51
+ css_path = File.join(site.config['destination'], file['output_file'])
52
+
53
+ html = file['html']
54
+
55
+ critical_cmd = "npx critical #{ css_files_str }"
56
+
57
+ Jekyll.logger.debug("SimpleAssets:", "Running command: #{ critical_cmd }")
58
+
59
+ Open3.popen3(critical_cmd) do |stdin, stdout, stderr, wait_thr|
60
+ stdin.write(html)
61
+ stdin.close
62
+
63
+ err = stderr.read
64
+ unless wait_thr.value.success?
65
+ Jekyll.logger.error("SimpleAssets:", 'Critical:' + err || stdout.read)
66
+
67
+ next
68
+ else
69
+ Jekyll.logger.warn("SimpleAssets:", 'Critical:' + err) if err
70
+ end
71
+
72
+ critical_css_str = stdout.read
73
+
74
+ asset_path = file['output_file'].sub(/^\//, '')
75
+
76
+ base64hash = Digest::MD5.base64digest(critical_css_str)
77
+
78
+ hash = base64hash[0, SimpleAssets::hash_length].gsub(/[+\/]/, '_')
79
+
80
+ SimpleAssets::asset_contenthash_map[asset_path] = hash
81
+
82
+ IO.write(css_path, critical_css_str)
83
+
84
+ site.keep_files << asset_path
85
+
86
+ if file['extract']
87
+ critical_css = CssParser::Parser.new
88
+
89
+ critical_css.load_string! critical_css_str
90
+
91
+ SimpleAssets::critical_css_source_files.each do |f|
92
+ f['css'].each_rule_set do |source_rule_set, source_media_type|
93
+ critical_css.each_rule_set do |critical_rule_set, critical_media_type|
94
+ if critical_rule_set.selectors.join(',') == source_rule_set.selectors.join(',')
95
+ f['css'].remove_rule_set! source_rule_set, source_media_type
96
+ f['extract'] = true
97
+
98
+ break
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ SimpleAssets::critical_css_source_files.each do |f|
108
+ f['page'].output = f['css'].to_s if f['extract']
109
+ end
110
+ end
111
+
112
+ def self.resolve_critical_css_content_hashes (site)
113
+ SimpleAssets::critical_css_source_files.each do |source_file|
114
+ page = source_file['page']
115
+ page_path = page.path.sub("#{ site.config['source'] }/", '')
116
+
117
+ SimpleAssets::config['critical_css']['files'].each do |file|
118
+ css_path = File.join(site.config['destination'], file['output_file'])
119
+ content = IO.read(css_path)
120
+
121
+ critical = SimpleAssets::replace_placeholders_for_path(page_path, content)
122
+
123
+ IO.write(css_path, critical)
124
+ end
125
+ end
126
+ end
127
+
128
+
129
+ end
130
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Jekyll
4
4
  module SimpleAssets
5
- VERSION = "0.2.0"
5
+ VERSION = "0.3.1"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-simple-assets
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sophie Askew
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-20 00:00:00.000000000 Z
11
+ date: 2020-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: css_parser
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -47,10 +61,13 @@ extra_rdoc_files: []
47
61
  files:
48
62
  - ".gitignore"
49
63
  - Gemfile
64
+ - Gemfile.lock
50
65
  - LICENSE
51
66
  - README.md
52
67
  - jekyll-simple-assets.gemspec
53
68
  - lib/jekyll-simple-assets.rb
69
+ - lib/jekyll-simple-assets/content-hash.rb
70
+ - lib/jekyll-simple-assets/critical.rb
54
71
  - lib/jekyll-simple-assets/version.rb
55
72
  homepage: https://github.com/syldexiahime/jekyll-simple-assets
56
73
  licenses:
@@ -71,8 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
71
88
  - !ruby/object:Gem::Version
72
89
  version: '0'
73
90
  requirements: []
74
- rubyforge_project:
75
- rubygems_version: 2.7.6
91
+ rubygems_version: 3.1.3
76
92
  signing_key:
77
93
  specification_version: 4
78
94
  summary: Some simple asset utils for jekyll