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,144 +1,33 @@
1
1
  # Frozen-string-literal: true
2
- # Copyright: 2012 - 2016 - MIT License
2
+ # Copyright: 2012 - 2017 - MIT License
3
3
  # Encoding: utf-8
4
4
 
5
- require 'concurrent/future'
5
+ require "sprockets/manifest"
6
6
 
7
7
  module Jekyll
8
8
  module Assets
9
9
  class Manifest < Sprockets::Manifest
10
- extend Forwardable::Extended
11
- rb_delegate :add, {
12
- :to => :used
13
- }
10
+ attr_reader :data
14
11
 
15
12
  # --
16
- # The assets to be compiled.
17
- # @return [Set]
13
+ # Works around some weird behavior in Sprockets 3.x that seemd to make
14
+ # it so that when you use an absolute path, it was automatically a filter
15
+ # and so you could never find an asset that was dynamically added.
18
16
  # --
19
- def used
20
- return @used ||= Set.new
17
+ def self.simple_logical_path?(file)
18
+ super || File.file?(file)
21
19
  end
22
20
 
23
21
  # --
24
- # All the assets, plus the used.
25
- # @return [Set]
22
+ # Allows you to add a manifest key for us to keep.
23
+ # @note the format should be `key: { hashKey: hashVal }` or `key: []`
24
+ # @note complex keys aren't supported.
25
+ # @return [Array<String>]
26
26
  # --
27
- def all
28
- used | (files.map do |_, v|
29
- find(v["logical_path"]).first if v
30
- end).compact
31
- end
32
-
33
- # --
34
- # This is a wholesale rip of Sprockets::Manifest#compkle, we only
35
- # adjust it to care about whether or not we want to digest, we don't
36
- # always digest in development.
37
- # --
38
- def compile(*args)
39
- unless environment
40
- raise(
41
- Error, "manifest requires environment for compilation"
42
- )
43
- end
44
-
45
- # --
46
-
47
- filenames = []
48
- concurrent_compressors = []
49
- concurrent_writers = []
50
-
51
- # --
52
-
53
- find(*args) do |asset|
54
- files[asset.digest_path] = {
55
- "mtime" => asset.mtime.iso8601,
56
- "logical_path" => asset.logical_path,
57
- "integrity" => Sprockets::DigestUtils.hexdigest_integrity_uri(asset.hexdigest),
58
- "digest" => asset.hexdigest,
59
- "size" => asset.bytesize
60
- }
61
-
62
- # --
63
-
64
- assets[asset.logical_path] = asset.digest_path
65
- alias_logical_path = self.class.compute_alias_logical_path(
66
- asset.logical_path
67
- )
68
-
69
- # --
70
-
71
- if alias_logical_path
72
- assets[alias_logical_path] = asset.digest_path
73
- end
74
-
75
- # Unlike upstream, we allow users to disble digesting, this is
76
- # where we actually and truthfully only diverge from upstream in
77
- # that we disable or enable the digested or logical path.
78
-
79
- target = \
80
- if environment.digest?
81
- File.join(dir,
82
- asset.digest_path
83
- )
84
- else
85
- File.join(dir,
86
- asset.logical_path
87
- )
88
- end
89
-
90
- # --
91
-
92
- if !environment.digest? || !File.exist?(target)
93
- logger.info "Writing #{target}"
94
- write_file = Concurrent::Future.execute { asset.write_to target }
95
- concurrent_writers << write_file
96
-
97
- else
98
- logger.debug(
99
- "Skipping #{target}, already exists"
100
- )
101
- end
102
-
103
- # --
104
-
105
- filenames << asset.filename
106
- next if environment.skip_gzip?
107
- gzip = Utils::Gzip.new(asset)
108
- next if gzip.cannot_compress?(
109
- environment.mime_types
110
- )
111
-
112
- # This is technically ignored usptream, we don't allow our
113
- # assets to write `.tar.gz` files by default, however, we leave
114
- # this here just incase someobody overrides that method.
115
-
116
- if File.exist?("#{target}.gz")
117
- logger.debug(
118
- "Skipping #{target}.gz, already exists"
119
- )
120
- else
121
- logger.info "Writing #{target}.gz"
122
- concurrent_compressors << Concurrent::Future.execute do
123
- write_file.wait! if write_file
124
- gzip.compress(
125
- target
126
- )
127
- end
128
- end
129
- end
130
-
131
- # --
132
-
133
- concurrent_writers.each(&:wait!)
134
- concurrent_compressors.each(
135
- &:wait!
27
+ def self.keep_keys
28
+ @keep_keys ||= %w(
29
+ assets
136
30
  )
137
-
138
- # --
139
-
140
- save
141
- filenames
142
31
  end
143
32
  end
144
33
  end
@@ -0,0 +1,57 @@
1
+ # Frozen-string-literal: true
2
+ # Copyright: 2012 - 2017 - MIT License
3
+ # Encoding: utf-8
4
+
5
+ require_relative "map/css"
6
+ require_relative "map/javascript"
7
+ require_relative "map/writer"
8
+ require "pathutil"
9
+
10
+ module Jekyll
11
+ module Assets
12
+ module Map
13
+ NAME = "%s.map"
14
+ DIR_NAME = "source-maps"
15
+ DIR = Pathutil.new(DIR_NAME)
16
+ EXT = ".map"
17
+
18
+ # --
19
+ # @return [String] the map name.
20
+ # Take the path, and attach the map extension.
21
+ # @note this just saves logic.
22
+ # --
23
+ def self.map_path(env:, asset:)
24
+ [
25
+ path({
26
+ asset: asset,
27
+ env: env,
28
+ }),
29
+ EXT,
30
+ ].join
31
+ end
32
+
33
+ # --
34
+ # @note this is used for anything in source-maps.
35
+ # Strip the filename and return a relative sourcemap path.
36
+ # @return [Pathutil] the path.
37
+ # --
38
+ def self.path(env:, asset:)
39
+ DIR.join(env.strip_paths(asset.is_a?(Sprockets::Asset) ?
40
+ asset.filename : asset))
41
+ end
42
+
43
+ # --
44
+ def self.register_on(instance)
45
+ return unless instance.asset_config[:source_maps]
46
+ unless instance.asset_config[:compression]
47
+ instance.logger.warn "Compression is ignored w/ SourceMaps"
48
+ end
49
+
50
+ # Register everything, so we can get this party started.
51
+ [Writer, JavaScript, CSS].map { |v| v.register_on(instance) }
52
+ instance.css_compressor, instance.js_compressor =
53
+ :source_map, :source_map
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,43 @@
1
+ # Frozen-string-literal: true
2
+ # Copyright: 2012 - 2017 - MIT License
3
+ # Encoding: utf-8
4
+
5
+ require "sprockets"
6
+
7
+ module Jekyll
8
+ module Assets
9
+ module Map
10
+ class CSS < Sprockets::SassCompressor
11
+ def call(input)
12
+ out = super(input)
13
+ env = input[:environment]
14
+ asset = env.find_asset!(input[:filename], pipeline: :source)
15
+ path = asset.filename.sub(env.jekyll.in_source_dir + "/", "")
16
+ url = Map.map_path(asset: asset, env: env)
17
+ url = env.prefix_url(url)
18
+
19
+ out.update({
20
+ data: <<~CSS
21
+ #{out[:data].strip}
22
+ /*# sourceMappingURL=#{url} */
23
+ /*# sourceURL=#{path} */
24
+ CSS
25
+ })
26
+ end
27
+
28
+ def self.register_on(instance)
29
+ content_type = "text/css"
30
+ instance.register_compressor content_type,
31
+ :source_map, CSS
32
+ end
33
+ end
34
+
35
+ # --
36
+ # We load late in some cases.
37
+ # You can also register it in a Hook.
38
+ # Globally Register it.
39
+ # --
40
+ CSS.register_on(Sprockets)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,43 @@
1
+ # Frozen-string-literal: true
2
+ # Copyright: 2012 - 2017 - MIT License
3
+ # Encoding: utf-8
4
+
5
+ require "sprockets"
6
+
7
+ module Jekyll
8
+ module Assets
9
+ module Map
10
+ class JavaScript < Sprockets::UglifierCompressor
11
+ def call(input)
12
+ out = super(input)
13
+ env = input[:environment]
14
+ asset = env.find_asset!(input[:filename], pipeline: :source)
15
+ path = asset.filename.sub(env.jekyll.in_source_dir + "/", "")
16
+ url = Map.map_path(asset: asset, env: env)
17
+ url = env.prefix_url(url)
18
+
19
+ out.update({
20
+ data: <<~TXT
21
+ #{input[:data].strip}
22
+ //# sourceMappingURL=#{url}
23
+ //# sourceURL=#{path}
24
+ TXT
25
+ })
26
+ end
27
+
28
+ def self.register_on(instance)
29
+ content_type = "application/javascript"
30
+ instance.register_compressor(content_type,
31
+ :source_map, self)
32
+ end
33
+ end
34
+
35
+ # --
36
+ # We load late in some cases.
37
+ # You can also register it in a Hook.
38
+ # Globally Register it.
39
+ # --
40
+ JavaScript.register_on(Sprockets)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,192 @@
1
+ # Frozen-string-literal: true
2
+ # Copyright: 2012 - 2017 - MIT License
3
+ # Encoding: utf-8
4
+
5
+ require "sprockets"
6
+ require "pathutil"
7
+
8
+ module Jekyll
9
+ module Assets
10
+ module Map
11
+ class Writer < Sprockets::Exporters::Base
12
+ alias env environment
13
+
14
+ def skip?(_)
15
+ !env.asset_config[:source_maps] ||
16
+ !asset.metadata[:map]
17
+ end
18
+
19
+ # --
20
+ def call
21
+ clean_file!
22
+ clean_sources!
23
+ write_map!
24
+ write_src!
25
+ end
26
+
27
+ # --
28
+ # Provides our custom manifest key, full of files.
29
+ # @note We push everything from the file we are writing to the maps.
30
+ # @return [Array<String>]
31
+ # --
32
+ def files
33
+ @files ||= begin
34
+ key = "sourceMapFiles"
35
+ out = env.manifest.data[key] ||= []
36
+ unless Manifest.keep_keys.include?(key)
37
+ Manifest.keep_keys << key
38
+ end
39
+
40
+ out
41
+ end
42
+ end
43
+
44
+ # --
45
+ def self.register_on(instance)
46
+ instance.register_exporter("*/*", self)
47
+ end
48
+
49
+ # --
50
+ # @return [HashWithIndifferentAccess]
51
+ # @note do not modify the original map.
52
+ # Provides a modifible SourceMap
53
+ # --
54
+ private
55
+ def map
56
+ @map ||= asset.metadata[:map]
57
+ .with_indifferent_access
58
+ end
59
+
60
+ # --
61
+ # @return [HashWithIndifferentAccess]
62
+ # @note this is frozen so you can't modify.
63
+ # Provides an unmodifiable SourceMap
64
+ # --
65
+ private
66
+ def original_map
67
+ @original_map ||= asset.metadata[:map]
68
+ .with_indifferent_access.freeze
69
+ end
70
+
71
+ # --
72
+ # @note something like _assets/*
73
+ # Makes sure that the name sits in the asset path.
74
+ # @return [String]
75
+ # --
76
+ private
77
+ def clean_file!
78
+ map[:file] = base.join(map[:file]).to_s
79
+ end
80
+
81
+ # --
82
+ private
83
+ def clean_sources!
84
+ if map[:sources]
85
+ then map[:sources] = map[:sources].map do |v|
86
+ base.join(strip_src(v))
87
+ end
88
+ else
89
+ map[:sections].each do |v|
90
+ v[:map][:sources] = v[:map][:sources].map do |vv|
91
+ base.join(strip_src(vv))
92
+ end
93
+ end
94
+ end
95
+
96
+ map
97
+ end
98
+
99
+ # --
100
+ private
101
+ def strip_src(path)
102
+ path = Pathutil.new(path)
103
+ base = path.basename.gsub(%r!\.source!, "")
104
+ return path.dirname.join(base).to_s unless path.dirname == "."
105
+ base.to_s if path.dirname == "."
106
+ end
107
+
108
+ # --
109
+ # @note we shim this on name.
110
+ # Privates the base directory in the source.
111
+ # @return [String]
112
+ # --
113
+ private
114
+ def base
115
+ Pathutil.new(asset.filename.sub(env.jekyll
116
+ .in_source_dir + "/", "")).dirname
117
+ end
118
+
119
+ # --
120
+ # rubocop:disable Layout/BlockEndNewline
121
+ # rubocop:disable Layout/MultilineBlockLayout
122
+ # rubocop:disable Style/BlockDelimiters
123
+ # --
124
+ private
125
+ def map_files
126
+ return original_map[:sources] if original_map.key?(:sources)
127
+ original_map[:sections].map { |v| v[:map][:sources] \
128
+ if v.key?(:map) }.flatten.compact
129
+ end
130
+
131
+ # --
132
+ # rubocop:enable Layout/BlockEndNewline
133
+ # rubocop:enable Layout/MultilineBlockLayout
134
+ # rubocop:enable Style/BlockDelimiters
135
+ # --
136
+ private
137
+ def write_map!
138
+ path = Map.map_path(asset: asset, env: env)
139
+ write(env.in_dest_dir(path)) do |f|
140
+ files.push(path)
141
+ f.write(map.to_json)
142
+ files.uniq!
143
+ end
144
+ end
145
+
146
+ # --
147
+ private
148
+ def strip_base(asset)
149
+ return asset if asset.is_a?(Sprockets::Asset)
150
+ asset.sub(base + "/", "")
151
+ end
152
+
153
+ # --
154
+ private
155
+ def write_src!
156
+ [asset_path, map_files].flatten.compact.uniq.each do |v|
157
+ v = env.find_asset!(strip_base(v), pipeline: :source)
158
+ path = map_path(v.filename)
159
+
160
+ write(environment.in_dest_dir(path)) do |f|
161
+ f.write(v.source)
162
+ files.push(path.to_s)
163
+ .uniq!
164
+ end
165
+ end
166
+ end
167
+
168
+ # --
169
+ private
170
+ def asset_path
171
+ base.join(env.strip_paths(@asset.filename)).to_s
172
+ end
173
+
174
+ # --
175
+ private
176
+ def map_path(file)
177
+ asset = base.join(env.strip_paths(file))
178
+ Map.path({
179
+ asset: asset, env: env
180
+ })
181
+ end
182
+ end
183
+
184
+ # --
185
+ # We load late in some cases.
186
+ # You can also register it in a Hook.
187
+ # Globally Register it.
188
+ # --
189
+ Writer.register_on(Sprockets)
190
+ end
191
+ end
192
+ end