Class: Middleman::Extensions::AssetHash

Inherits:
Middleman::Extension show all
Defined in:
middleman-core/lib/middleman-core/extensions/asset_hash.rb

Constant Summary

Constants included from Contracts

Contracts::ImmutableSetOf, Contracts::ImmutableSortedSetOf, Contracts::OldResourceList, Contracts::PATH_MATCHER, Contracts::ResourceList, Contracts::VectorOf

Instance Attribute Summary

Attributes inherited from Middleman::Extension

#app, #options

Instance Method Summary collapse

Methods inherited from Middleman::Extension

activated_extension, #add_exposed_to_context, #after_build, #after_configuration, after_extension_activated, #after_extension_activated, #before_build, #before_configuration, clear_after_extension_callbacks, config, define_setting, expose_to_application, expose_to_config, expose_to_template, global_config, helpers, #manipulate_resource_list, option, #ready, resources

Methods included from Contracts

#Contract

Constructor Details

#initialize(app, options_hash = ::Middleman::EMPTY_HASH, &block) ⇒ AssetHash

Returns a new instance of AssetHash



13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'middleman-core/lib/middleman-core/extensions/asset_hash.rb', line 13

def initialize(app, options_hash = ::Middleman::EMPTY_HASH, &block)
  super

  # Allow specifying regexes to ignore, plus always ignore apple touch icons
  @ignore = Array(options.ignore) + [/^apple-touch-icon/]

  require 'set'

  # Exclude .ico from the default list because browsers expect it
  # to be named "favicon.ico"
  @set_of_exts = Set.new(options.exts || (app.config[:asset_extensions] - %w[.ico]))
  @set_of_sources = Set.new options.sources
end

Instance Method Details

#ignored_resource?(resource) ⇒ Boolean

Returns:

  • (Boolean)


102
103
104
105
106
# File 'middleman-core/lib/middleman-core/extensions/asset_hash.rb', line 102

def ignored_resource?(resource)
  @ignore.any? do |ignore|
    Middleman::Util.path_match(ignore, resource.destination_path)
  end
end

#manipulate_resource_list_container!(resource_list) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'middleman-core/lib/middleman-core/extensions/asset_hash.rb', line 49

def manipulate_resource_list_container!(resource_list)
  resource_list.by_extensions(@set_of_sources).each do |r|
    next if Array(options.rewrite_ignore || []).any? do |i|
      ::Middleman::Util.path_match(i, "/#{r.destination_path}")
    end

    r.add_filter ::Middleman::InlineURLRewriter.new(:asset_hash,
                                                    app,
                                                    r,
                                                    create_dependencies: true,
                                                    url_extensions: @set_of_exts,
                                                    ignore: options.ignore,
                                                    proc: method(:rewrite_url))
  end

  # Process resources in order: binary images and fonts, then SVG, then JS/CSS.
  # This is so by the time we get around to the text files (which may reference
  # images and fonts) the static assets' hashes are already calculated.
  sorted_resources = resource_list.by_extensions(@set_of_exts).sort_by do |a|
    if %w[.svg .svgz].include? a.ext
      0
    elsif %w[.js .mjs .css].include? a.ext
      1
    else
      -1
    end
  end

  sorted_resources.each do |resource|
    manipulate_single_resource(resource_list, resource)
  end
end

#manipulate_single_resource(resource_list, resource) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'middleman-core/lib/middleman-core/extensions/asset_hash.rb', line 83

def manipulate_single_resource(resource_list, resource)
  return if ignored_resource?(resource)
  return if resource.ignored?

  digest = if resource.binary? || resource.static_file?
             ::Middleman::Util.hash_file(resource.source_file)[0..7]
           else
             # Render without asset hash
             body = resource.render({}, {}) { |f| !f.respond_to?(:filter_name) || f.filter_name != :asset_hash }
             ::Middleman::Util.hash_string(body)[0..7]
           end

  resource_list.update!(resource, :destination_path) do
    path, basename, extension = split_path(resource.destination_path)
    resource.destination_path = options.rename_proc.call(path, basename, digest, extension, options)
  end
end

#rewrite_url(asset_path, dirpath, _request_path) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'middleman-core/lib/middleman-core/extensions/asset_hash.rb', line 28

def rewrite_url(asset_path, dirpath, _request_path)
  uri = ::Middleman::Util.parse_uri(asset_path)
  relative_path = !uri.path.start_with?('/')

  full_asset_path = if relative_path
                      dirpath.join(asset_path).to_s
                    else
                      asset_path
                    end

  asset_page = app.sitemap.by_destination_path(full_asset_path) || app.sitemap.by_path(full_asset_path)

  return unless asset_page

  replacement_path = "/#{asset_page.destination_path}"
  replacement_path = Pathname.new(replacement_path).relative_path_from(dirpath).to_s if relative_path
  replacement_path
end