jekyll-assets 2.4.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +21 -17
  3. data/LICENSE +1 -1
  4. data/README.md +365 -297
  5. data/Rakefile +13 -2
  6. data/lib/jekyll/assets.rb +15 -11
  7. data/lib/jekyll/assets/config.rb +91 -55
  8. data/lib/jekyll/assets/context.rb +32 -0
  9. data/lib/jekyll/assets/default.rb +98 -0
  10. data/lib/jekyll/assets/drop.rb +62 -0
  11. data/lib/jekyll/assets/env.rb +135 -278
  12. data/lib/jekyll/assets/extensible.rb +86 -0
  13. data/lib/jekyll/assets/filters.rb +22 -0
  14. data/lib/jekyll/assets/hook.rb +115 -48
  15. data/lib/jekyll/assets/html.rb +88 -0
  16. data/lib/jekyll/assets/logger.rb +17 -59
  17. data/lib/jekyll/assets/manifest.rb +15 -126
  18. data/lib/jekyll/assets/map.rb +57 -0
  19. data/lib/jekyll/assets/map/css.rb +43 -0
  20. data/lib/jekyll/assets/map/javascript.rb +43 -0
  21. data/lib/jekyll/assets/map/writer.rb +192 -0
  22. data/lib/jekyll/assets/patches/cached_env.rb +79 -0
  23. data/lib/jekyll/assets/patches/functions.rb +31 -0
  24. data/lib/jekyll/assets/patches/obsolete_files.rb +42 -0
  25. data/lib/jekyll/assets/patches/sprockets.rb +9 -0
  26. data/lib/jekyll/assets/patches/sprockets_data_uri.rb +12 -0
  27. data/lib/jekyll/assets/plugins.rb +9 -0
  28. data/lib/jekyll/assets/plugins/bootstrap.rb +5 -0
  29. data/lib/jekyll/assets/plugins/font-awesome.rb +8 -0
  30. data/lib/jekyll/assets/plugins/frontmatter.rb +28 -0
  31. data/lib/jekyll/assets/plugins/html/audio.rb +32 -0
  32. data/lib/jekyll/assets/plugins/html/css.rb +24 -0
  33. data/lib/jekyll/assets/plugins/html/defaults/audio.rb +69 -0
  34. data/lib/jekyll/assets/plugins/html/defaults/css.rb +48 -0
  35. data/lib/jekyll/assets/plugins/html/defaults/img.rb +54 -0
  36. data/lib/jekyll/assets/plugins/html/defaults/js.rb +48 -0
  37. data/lib/jekyll/assets/plugins/html/defaults/vid.rb +63 -0
  38. data/lib/jekyll/assets/plugins/html/img.rb +76 -0
  39. data/lib/jekyll/assets/plugins/html/js.rb +30 -0
  40. data/lib/jekyll/assets/plugins/html/pic.rb +125 -0
  41. data/lib/jekyll/assets/plugins/html/svg.rb +37 -0
  42. data/lib/jekyll/assets/plugins/html/vid.rb +26 -0
  43. data/lib/jekyll/assets/plugins/liquid.rb +57 -0
  44. data/lib/jekyll/assets/plugins/magick.rb +7 -0
  45. data/lib/jekyll/assets/plugins/optim.rb +7 -0
  46. data/lib/jekyll/assets/plugins/prefixer.rb +28 -0
  47. data/lib/jekyll/assets/plugins/proxy/magick.rb +131 -0
  48. data/lib/jekyll/assets/plugins/proxy/optim.rb +64 -0
  49. data/lib/jekyll/assets/plugins/searcher.rb +72 -0
  50. data/lib/jekyll/assets/proxy.rb +109 -0
  51. data/lib/jekyll/assets/tag.rb +176 -0
  52. data/lib/jekyll/assets/url.rb +23 -0
  53. data/lib/jekyll/assets/utils.rb +348 -0
  54. data/lib/jekyll/assets/version.rb +2 -2
  55. data/lib/jekyll/assets/writer.rb +36 -0
  56. metadata +102 -81
  57. data/lib/jekyll-assets.rb +0 -7
  58. data/lib/jekyll/assets/addons/autoprefixer.rb +0 -11
  59. data/lib/jekyll/assets/addons/bootstrap.rb +0 -9
  60. data/lib/jekyll/assets/addons/fontawesome.rb +0 -9
  61. data/lib/jekyll/assets/addons/javascript.rb +0 -11
  62. data/lib/jekyll/assets/cached.rb +0 -30
  63. data/lib/jekyll/assets/helpers.rb +0 -74
  64. data/lib/jekyll/assets/hooks/cache.rb +0 -21
  65. data/lib/jekyll/assets/hooks/compression.rb +0 -25
  66. data/lib/jekyll/assets/hooks/config.rb +0 -12
  67. data/lib/jekyll/assets/hooks/erb.rb +0 -15
  68. data/lib/jekyll/assets/hooks/jekyll/drops.rb +0 -9
  69. data/lib/jekyll/assets/hooks/jekyll/setup.rb +0 -11
  70. data/lib/jekyll/assets/hooks/jekyll/write.rb +0 -11
  71. data/lib/jekyll/assets/hooks/logger.rb +0 -11
  72. data/lib/jekyll/assets/hooks/sources.rb +0 -13
  73. data/lib/jekyll/assets/hooks/sprockets.rb +0 -9
  74. data/lib/jekyll/assets/hooks/version.rb +0 -11
  75. data/lib/jekyll/assets/liquid/context.rb +0 -19
  76. data/lib/jekyll/assets/liquid/drop.rb +0 -81
  77. data/lib/jekyll/assets/liquid/filters.rb +0 -49
  78. data/lib/jekyll/assets/liquid/tag.rb +0 -244
  79. data/lib/jekyll/assets/liquid/tag/defaults.rb +0 -27
  80. data/lib/jekyll/assets/liquid/tag/defaults/image.rb +0 -81
  81. data/lib/jekyll/assets/liquid/tag/defaults/sha.rb +0 -58
  82. data/lib/jekyll/assets/liquid/tag/parser.rb +0 -202
  83. data/lib/jekyll/assets/liquid/tag/proxied_asset.rb +0 -166
  84. data/lib/jekyll/assets/liquid/tag/proxies.rb +0 -130
  85. data/lib/jekyll/assets/patches/jekyll/cleaner.rb +0 -15
  86. data/lib/jekyll/assets/patches/jekyll/site.rb +0 -5
  87. data/lib/jekyll/assets/patches/kernel.rb +0 -29
  88. data/lib/jekyll/assets/patches/sprockets/asset.rb +0 -28
  89. data/lib/jekyll/assets/processors/less.rb +0 -70
  90. data/lib/jekyll/assets/processors/liquid.rb +0 -46
  91. data/lib/jekyll/assets/proxies/image_optim.rb +0 -80
  92. data/lib/jekyll/assets/proxies/magick.rb +0 -194
@@ -1,244 +0,0 @@
1
- # ----------------------------------------------------------------------------
2
- # Frozen-string-literal: true
3
- # Copyright: 2012 - 2016 - MIT License
4
- # Encoding: utf-8
5
- # ----------------------------------------------------------------------------
6
-
7
- require "fastimage"
8
-
9
- module Jekyll
10
- module Assets
11
- module Liquid
12
- class Tag < ::Liquid::Tag
13
- require_relative "tag/proxies"
14
- require_relative "tag/proxied_asset"
15
- require_relative "tag/defaults"
16
- require_relative "tag/parser"
17
- attr_reader :args
18
-
19
- # --------------------------------------------------------------------
20
-
21
- class << self
22
- public :new
23
- end
24
-
25
- # --------------------------------------------------------------------
26
-
27
- class AssetNotFoundError < StandardError
28
- def initialize(asset)
29
- super "Could not find the asset `#{asset}'"
30
- end
31
- end
32
-
33
- # --------------------------------------------------------------------
34
- # Tags that we allow our users to use.
35
- # --------------------------------------------------------------------
36
-
37
- AcceptableTags = %W(
38
- img
39
- image
40
- javascript
41
- asset_source
42
- stylesheet
43
- asset_path
44
- style
45
- asset
46
- css
47
- js
48
- ).freeze
49
-
50
- # --------------------------------------------------------------------
51
- # The HTML version of every tag that we accept.
52
- # --------------------------------------------------------------------
53
-
54
- Tags = {
55
- "css" => %(<link type="text/css" rel="stylesheet" href="%s"%s>),
56
- "js" => %(<script type="text/javascript" src="%s"%s></script>),
57
- "img" => %(<img src="%s"%s>)
58
- }.freeze
59
-
60
- # --------------------------------------------------------------------
61
- # Allows us to normalize tags so we can simplify logic.
62
- # --------------------------------------------------------------------
63
-
64
- Alias = {
65
- "image" => "img",
66
- "stylesheet" => "css",
67
- "javascript" => "js",
68
- "style" => "css"
69
- }.freeze
70
-
71
- # --------------------------------------------------------------------
72
-
73
- def initialize(tag, args, tokens)
74
- tag = tag.to_s
75
- @tokens = tokens
76
- @tag = from_alias(tag)
77
- @args = Parser.new(args, @tag)
78
- @og_tag = tag
79
- super
80
- end
81
-
82
- # --------------------------------------------------------------------
83
- # NOTE: We only attach to the regenerator if you are using digested
84
- # assets, otherwise we forego any association with it so that we keep
85
- # your builds ultra fast, this is ideal in dev. Disable digests and
86
- # let us process independent so the entire site isn't regenerated
87
- # because of a single asset change.
88
- # --------------------------------------------------------------------
89
-
90
- def render(context)
91
- site = context.registers[:site]
92
- page = context.registers.fetch(:page, {})
93
- args = @args.parse_liquid(context)
94
- sprockets = site.sprockets
95
- page = page["path"]
96
-
97
- asset = find_asset(args, sprockets)
98
- add_as_jekyll_dependency(site, sprockets, page, asset)
99
- process_tag(args, sprockets, asset)
100
-
101
- rescue => e
102
- capture_and_out_error(
103
- site, e
104
- )
105
- end
106
-
107
- # --------------------------------------------------------------------
108
-
109
- private
110
- def from_alias(tag)
111
- Alias.key?(tag) ? Alias[tag] : tag
112
- end
113
-
114
- # --------------------------------------------------------------------
115
-
116
- private
117
- def process_tag(args, sprockets, asset)
118
- sprockets.manifest.add(asset) unless @tag == "asset_source"
119
- Defaults.set_defaults_for!(@tag, args ||= {}, asset, sprockets)
120
- build_html(args, sprockets, asset)
121
- end
122
-
123
- # --------------------------------------------------------------------
124
-
125
- private
126
- def build_html(args, sprockets, asset, path = get_path(sprockets, asset))
127
- return path if @tag == "asset_path"
128
- return asset.to_s if @tag == "asset" || @tag == "asset_source"
129
- data = args.key?(:data) && args[:data].key?(:uri) ? asset.data_uri : path
130
- format(Tags[@tag], data, args.to_html)
131
- end
132
-
133
- # --------------------------------------------------------------------
134
-
135
- private
136
- def get_path(sprockets, asset)
137
- sprockets.prefix_path(
138
- sprockets.digest?? asset.digest_path : asset.logical_path
139
- )
140
- end
141
-
142
- # --------------------------------------------------------------------
143
-
144
- private
145
- def add_as_jekyll_dependency(site, sprockets, page, asset)
146
- if page && sprockets.digest?
147
- site.regenerator.add_dependency(
148
- site.in_source_dir(page), site.in_source_dir(asset.logical_path)
149
- )
150
- end
151
- end
152
-
153
- # --------------------------------------------------------------------
154
-
155
- private
156
- def find_asset(args, sprockets)
157
- out = _find_asset(args[:file],
158
- args[:sprockets] ||= {}, sprockets
159
- )
160
-
161
- if !out
162
- raise(
163
- AssetNotFoundError, args[
164
- :file
165
- ]
166
- )
167
-
168
- else
169
- out.liquid_tags << self
170
- !args.proxies?? out : ProxiedAsset.new(
171
- out, args, sprockets, self
172
- )
173
- end
174
- end
175
-
176
- # --------------------------------------------------------------------
177
-
178
- private
179
- def _find_asset(file, args, sprockets)
180
- if args.empty? then sprockets.manifest.find(file).first
181
- elsif args.size == 1 && args.key?(:accept)
182
- if File.extname(file) == ""
183
- file = file + _ext_for(args[
184
- :accept
185
- ])
186
- end
187
-
188
- sprockets.manifest.find(file).find do |asset|
189
- asset.content_type == args[
190
- :accept
191
- ]
192
- end
193
- else
194
- sprockets.find_asset(
195
- file, args
196
- )
197
- end
198
- end
199
-
200
- # --------------------------------------------------------------------
201
-
202
- private
203
- def _ext_for(type)
204
- out = Sprockets.mime_exts.select do |k, v|
205
- v == type
206
- end
207
-
208
- out.keys \
209
- .first
210
- end
211
-
212
- # --------------------------------------------------------------------
213
- # There is no guarantee that Jekyll will pass on the error for some
214
- # reason (unless you are just booting up) so we capture that error and
215
- # always output it, it can lead to some double errors but I would
216
- # rather there be a double error than no error.
217
- # --------------------------------------------------------------------
218
-
219
- private
220
- def capture_and_out_error(site, error)
221
- if error.is_a?(Sass::SyntaxError)
222
- file = error.sass_filename.gsub(/#{Regexp.escape(site.source)}\//, "")
223
- Jekyll.logger.error(%(Error in #{file}:#{error.sass_line} #{
224
- error
225
- }))
226
-
227
- else
228
- Jekyll.logger.error(
229
- "", error.to_s
230
- )
231
- end
232
-
233
- raise error
234
- end
235
- end
236
- end
237
- end
238
- end
239
-
240
- # ----------------------------------------------------------------------------
241
-
242
- Jekyll::Assets::Liquid::Tag::AcceptableTags.each do |tag|
243
- Liquid::Template.register_tag tag, Jekyll::Assets::Liquid::Tag
244
- end
@@ -1,27 +0,0 @@
1
- # Frozen-string-literal: true
2
- # Copyright: 2012 - 2016 - MIT License
3
- # Encoding: utf-8
4
-
5
- module Jekyll
6
- module Assets
7
- module Liquid
8
- class Tag
9
- module Defaults
10
- require_relative "defaults/image"
11
- require_relative "defaults/sha"
12
-
13
- # --
14
- # TODO: In 3.0 env needs to be enforced, right now it's not
15
- # because it's maintain 2.0 API.
16
- # --
17
- module_function
18
- def set_defaults_for!(tag, args, asset, env = nil)
19
- constants.select { |const| const_get(const).for?(tag) }.each do |const|
20
- const_get(const).new(args, asset, env).set!
21
- end
22
- end
23
- end
24
- end
25
- end
26
- end
27
- end
@@ -1,81 +0,0 @@
1
- # ----------------------------------------------------------------------------
2
- # Frozen-string-literal: true
3
- # Copyright: 2012 - 2016 - MIT License
4
- # Encoding: utf-8
5
- # ----------------------------------------------------------------------------
6
-
7
- module Jekyll
8
- module Assets
9
- module Liquid
10
- class Tag
11
- module Defaults
12
- class Image
13
- def self.for?(tag)
14
- tag == "img" || tag == "image"
15
- end
16
-
17
- # ----------------------------------------------------------------
18
- # TODO: In 3.0 env needs to be enforced if this is not changed,
19
- # for now it's not enforced to maintain the 2.0 API.
20
- # ----------------------------------------------------------------
21
-
22
- def initialize(args, asset, env = nil)
23
- @args = args
24
- @asset = asset
25
- @env = env
26
- end
27
-
28
- # ----------------------------------------------------------------
29
-
30
- def set!
31
- set_img_dimensions
32
- set_img_alt
33
- end
34
-
35
- # ----------------------------------------------------------------
36
- # TODO: 3.0 - Remove the `!@env`
37
- # ----------------------------------------------------------------
38
-
39
- private
40
- def set_img_alt
41
- if !@env || @env.asset_config["features"]["automatic_img_alt"]
42
- @args[:html] ||= {}
43
- unless @args[:html].key?("alt")
44
- @args[:html]["alt"] = @asset.logical_path
45
- end
46
- end
47
- end
48
-
49
- # ----------------------------------------------------------------
50
- # TODO: 3.0 - Remove the `!@env`
51
- # ----------------------------------------------------------------
52
-
53
- private
54
- def set_img_dimensions
55
- resize_image = @env.asset_config["features"]["automatic_img_size"]
56
-
57
- if !@env || resize_image
58
- dimensions = FastImage.size(@asset.filename.to_s)
59
- return unless dimensions
60
- @args[:html] ||= {}
61
-
62
- if resize_image =~ /^\d+$/
63
- width = (dimensions.first / resize_image.to_f).floor
64
- height = (dimensions. last / resize_image.to_f).floor
65
-
66
- else
67
- width = dimensions.first
68
- height = dimensions. last
69
- end
70
-
71
-
72
- @args[:html][ "width"] ||= width
73
- @args[:html]["height"] ||= height
74
- end
75
- end
76
- end
77
- end
78
- end
79
- end
80
- end
81
- end
@@ -1,58 +0,0 @@
1
- # Frozen-string-literal: true
2
- # Copyright: 2012 - 2016 - MIT License
3
- # Encoding: utf-8
4
-
5
- module Jekyll
6
- module Assets
7
- module Liquid
8
- class Tag
9
- module Defaults
10
- class Sha
11
-
12
- # --
13
- # What we plan to accept for.
14
- # --
15
- def self.for?(tag)
16
- return tag == "css" || tag == "js"
17
- end
18
-
19
- # --
20
- # Initialize a new instance.
21
- # --
22
- def initialize(args, asset, env)
23
- @args = args
24
- @asset = asset
25
- @env = env
26
- end
27
-
28
- # --
29
- # Run the defaults.
30
- # --
31
- def set!
32
- set_integrity
33
- end
34
-
35
- # --
36
- # Set the integrity attribute.
37
- # @return [nil]
38
- # --
39
- def set_integrity
40
- digest = Sprockets::DigestUtils.integrity_uri(
41
- Digest::SHA384.digest(
42
- @asset.to_s
43
- )
44
- )
45
-
46
- @args.args[:html] ||= {}
47
- if @env.asset_config["features"]["integrity"]
48
- @args.args[:html]["integrity"] = digest
49
- @args.args[:html]["crossorigin"] = "anonymous" \
50
- unless @args.args[:html]["crossorigin"]
51
- end
52
- end
53
- end
54
- end
55
- end
56
- end
57
- end
58
- end
@@ -1,202 +0,0 @@
1
- # ----------------------------------------------------------------------------
2
- # Frozen-string-literal: true
3
- # Copyright: 2012 - 2016 - MIT License
4
- # Encoding: utf-8
5
- # ----------------------------------------------------------------------------
6
-
7
- require_relative "proxies"
8
- require "forwardable"
9
-
10
- module Jekyll
11
- module Assets
12
- module Liquid
13
-
14
- # ----------------------------------------------------------------------
15
- # Examples:
16
- # - {% tag value argument:value %}
17
- # - {% tag value "argument:value" %}
18
- # - {% tag value argument:"I have spaces" %}
19
- # - {% tag value argument:value\:with\:colon %}
20
- # - {% tag value argument:"I can even escape \\: here too!" %}
21
- # - {% tag value proxy:key:value %}
22
- # ----------------------------------------------------------------------
23
-
24
- class Tag
25
- class Parser
26
- attr_reader :args, :raw_args
27
- extend Forwardable
28
-
29
- def_delegator :@args, :each
30
- def_delegator :@args, :key?
31
- def_delegator :@args, :fetch
32
- def_delegator :@args, :store
33
- def_delegator :@args, :to_h
34
- def_delegator :@args, :[]=
35
- def_delegator :@args, :[]
36
-
37
- # ------------------------------------------------------------------
38
-
39
- ACCEPT = {
40
- "css" => "text/css", "js" => "application/javascript"
41
- }
42
-
43
- # ------------------------------------------------------------------
44
-
45
- class UnescapedColonError < StandardError
46
- def initialize
47
- super "Unescaped double colon argument."
48
- end
49
- end
50
-
51
- # ------------------------------------------------------------------
52
-
53
- class UnknownProxyError < StandardError
54
- def initialize
55
- super "Unknown proxy argument."
56
- end
57
- end
58
-
59
- # ------------------------------------------------------------------
60
-
61
- def initialize(args, tag, processed: false, raw_args: nil)
62
- if processed && raw_args
63
- @args = args
64
- @raw_args = raw_args
65
- @tag = tag
66
-
67
- elsif processed && !raw_args
68
- raise ArgumentError, "You must provide raw_args if you pre-process." \
69
- "Please provide the raw args."
70
-
71
- else
72
- @tag = tag
73
- @raw_args = args
74
- parse_raw
75
- set_accept
76
- end
77
- end
78
-
79
- # ------------------------------------------------------------------
80
-
81
- def parse_liquid(context)
82
- return self unless context.is_a?(Object::Liquid::Context)
83
- liquid = context.registers[:site].liquid_renderer.file("(jekyll:assets)")
84
- out = parse_hash_liquid(to_h, liquid, context)
85
- self.class.new(out, @tag, {
86
- :raw_args => @raw_args,
87
- :processed => true
88
- })
89
- end
90
-
91
- # ------------------------------------------------------------------
92
-
93
- def to_html
94
- (self[:html] || {}).map do |key, val|
95
- val == true || val == "true" ? " #{key}" : %( #{key}="#{val}")
96
- end.join
97
- end
98
-
99
- # ------------------------------------------------------------------
100
-
101
- def proxies
102
- keys = (args.keys - Proxies.base_keys - [:file, :html])
103
- args.select do |key, _|
104
- keys.include?(key)
105
- end
106
- end
107
-
108
- # ------------------------------------------------------------------
109
-
110
- def proxies?
111
- proxies.any?
112
- end
113
-
114
- # ------------------------------------------------------------------
115
-
116
- private
117
- def parse_hash_liquid(hash_, liquid, context)
118
- hash_.each_with_object({}) do |(key, val), hash|
119
- val = liquid.parse(val).render(context) if val.is_a?(String)
120
- val = parse_hash_liquid(val, liquid, context) if val.is_a?(Hash)
121
- hash[key] = val
122
- end
123
- end
124
-
125
- # ------------------------------------------------------------------
126
-
127
- private
128
- def parse_raw
129
- @args = from_shellwords.each_with_index.each_with_object({}) do |(key, index), hash|
130
- if index == 0 then hash.store(:file, key)
131
- elsif key =~ /:/ && (key = key.split(/(?<!\\):/))
132
- parse_col hash, key
133
-
134
- else
135
- (hash[:html] ||= {})[key] = true
136
- end
137
-
138
- hash
139
- end
140
- end
141
-
142
- # ------------------------------------------------------------------
143
-
144
- private
145
- def parse_col(hash, key)
146
- key.push(key.delete_at(-1).gsub(/\\:/, ":"))
147
- return as_proxy hash, key if key.size == 3
148
- return as_bool_or_html hash, key if key.size == 2 || key.size == 1
149
- raise UnescapedColonError
150
- end
151
-
152
- # ------------------------------------------------------------------
153
-
154
- private
155
- def as_bool_or_html(hash, key)
156
- okey = key
157
- key, sub_key = key
158
- if Proxies.has?(key, @tag, "@#{sub_key}")
159
- (hash[key.to_sym] ||= {})[sub_key.to_sym] = true
160
- else
161
- (hash[:html] ||= {})[key] = \
162
- okey[1]
163
- end
164
- end
165
-
166
- # ------------------------------------------------------------------
167
-
168
- private
169
- def as_proxy(hash, key)
170
- key, sub_key, val = key
171
- if Proxies.has?(key, @tag, sub_key)
172
- (hash[key.to_sym] ||= {})[sub_key.to_sym] = \
173
- val
174
-
175
- elsif Proxies.has?(key)
176
- raise UnknownProxyError
177
- end
178
- end
179
-
180
- # ------------------------------------------------------------------
181
-
182
- private
183
- def set_accept
184
- if ACCEPT.key?(@tag) && (!@args.key?(:sprockets) || \
185
- !@args[:sprockets].key?(:accept))
186
-
187
- (@args[:sprockets] ||= {})[:accept] = \
188
- ACCEPT[@tag]
189
- end
190
- end
191
-
192
- # ------------------------------------------------------------------
193
-
194
- private
195
- def from_shellwords
196
- Shellwords.shellwords(@raw_args)
197
- end
198
- end
199
- end
200
- end
201
- end
202
- end