middleman-core 4.1.7 → 4.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/features/collections.feature +27 -0
  3. data/features/i18n_link_to.feature +34 -34
  4. data/features/relative_assets.feature +1 -1
  5. data/features/relative_assets_helpers_only.feature +123 -0
  6. data/features/template-key-collision.feature +26 -0
  7. data/fixtures/relative-assets-app/source/images/blank2.gif +0 -0
  8. data/lib/middleman-core/config_context.rb +2 -2
  9. data/lib/middleman-core/core_extensions/collections/step_context.rb +8 -5
  10. data/lib/middleman-core/core_extensions/collections.rb +1 -1
  11. data/lib/middleman-core/core_extensions/default_helpers.rb +1 -0
  12. data/lib/middleman-core/core_extensions/front_matter.rb +8 -6
  13. data/lib/middleman-core/core_extensions/inline_url_rewriter.rb +20 -35
  14. data/lib/middleman-core/extension.rb +4 -1
  15. data/lib/middleman-core/extensions/asset_hash.rb +1 -1
  16. data/lib/middleman-core/extensions/asset_host.rb +2 -1
  17. data/lib/middleman-core/extensions/minify_css.rb +9 -1
  18. data/lib/middleman-core/extensions/minify_javascript.rb +8 -0
  19. data/lib/middleman-core/extensions/relative_assets.rb +39 -12
  20. data/lib/middleman-core/file_renderer.rb +4 -4
  21. data/lib/middleman-core/sitemap/resource.rb +3 -3
  22. data/lib/middleman-core/sitemap/store.rb +1 -1
  23. data/lib/middleman-core/sources/source_watcher.rb +6 -0
  24. data/lib/middleman-core/template_context.rb +3 -2
  25. data/lib/middleman-core/template_renderer.rb +22 -9
  26. data/lib/middleman-core/util/data.rb +32 -17
  27. data/lib/middleman-core/util/files.rb +3 -7
  28. data/lib/middleman-core/util/paths.rb +38 -0
  29. data/lib/middleman-core/util/rack.rb +1 -1
  30. data/lib/middleman-core/version.rb +1 -1
  31. data/middleman-core.gemspec +3 -2
  32. data/spec/middleman-core/util_spec.rb +16 -0
  33. metadata +25 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 030311fff277fca785018355eae0d3e841af713f
4
- data.tar.gz: 7bb366e4fd42e9ca58e05fb7c28c16dfb04fdf10
3
+ metadata.gz: 99765b41dbcadb0a1fe8e9017ce95171fe5e7877
4
+ data.tar.gz: 972fcfba7e09229dc557444eba1434d6d42a0346
5
5
  SHA512:
6
- metadata.gz: 36442dc7b91a3e5f0f2cc0d55ee56c9a799b9e37598f42fa9c4a3531905baf55d7bd0771d68969f21dc345dfdf832df8dc0ae0584eecdec1921bad8e73f7ee8a
7
- data.tar.gz: d0cfb1e50a0e23f4c73aaa3bd8995209d5b42dc78af1674429a21c99a98508bdca64d16245f4030dd475cfca9532f41e0bc19cdcffdf130b02d456e8a27da7e0
6
+ metadata.gz: 52e4d9adb600ebb0a3003902d97e349df96d73c4c679c11885f6d867ce178dbe4905b16ae051b5cece2f3fffdee729fd689b8698fbc32fbcbd3067aaa3462dab
7
+ data.tar.gz: cbbe75c5a1fc93a1c201cb2db174be431e766eb519f7bba08ba6ff06ccd4e693c7a4707c1602625fc7ac09337e4ddb0cf73e0b55ac1e6d24eae71ece75e69671
@@ -144,6 +144,33 @@ Feature: Collections
144
144
  And I should see 'Article: Blog3 Another Article'
145
145
  And I should see 'Article: Blog2 Yet Another Article'
146
146
 
147
+ Scenario: Work with local helpers
148
+ Given a fixture app "collections-app"
149
+ And a file named "config.rb" with:
150
+ """
151
+ module TestHelper
152
+ def help_me
153
+ "ok"
154
+ end
155
+ end
156
+
157
+ include TestHelper
158
+
159
+ data.articles.each_with_index do |a, i|
160
+ proxy "/#{i}-#{help_me}.html", a
161
+ end
162
+ """
163
+ And a file named "data/articles.yaml" with:
164
+ """
165
+ ---
166
+ - "/blog1/2011-01-01-new-article.html"
167
+ - "/blog2/2011-01-02-another-article.html"
168
+ """
169
+ Given the Server is running at "collections-app"
170
+ When I go to "0-ok.html"
171
+ Then I should see 'Newer Article Content'
172
+ When I go to "1-ok.html"
173
+ Then I should see 'Another Article Content'
147
174
 
148
175
  Scenario: Collected data update with file changes
149
176
  Given a fixture app "collections-app"
@@ -4,7 +4,7 @@ Feature: i18n Paths
4
4
  Given a fixture app "empty-app"
5
5
  And a file named "data/pages.yml" with:
6
6
  """
7
- - hello.html
7
+ - hello.html
8
8
  """
9
9
  And a file named "locales/en.yml" with:
10
10
  """
@@ -50,24 +50,24 @@ Feature: i18n Paths
50
50
  Given the Server is running at "empty-app"
51
51
  When I go to "/hello.html"
52
52
  Then I should see "Page: Hello"
53
- Then I should see '<a class="current" href="/index.html">Current Home</a>'
54
- Then I should see '<a title="Other Home" href="/es/index.html">Other Home</a>'
55
- Then I should see '<a class="current" href="/index.html"><span>Home: Current Block</span></a>'
56
- Then I should see '<a title="Other Home" href="/es/index.html"><span>Home: Other Block</span></a>'
57
- Then I should see '<a class="current" href="/hello.html">Current hello.html</a>'
58
- Then I should see '<a title="Other hello.html" href="/es/hola.html">Other hello.html</a>'
59
- Then I should see '<a class="current" href="/hello.html"><span>Current Block</span></a>'
60
- Then I should see '<a title="Other hello.html" href="/es/hola.html"><span>Other Block</span></a>'
53
+ Then I should see '<a href="/index.html" class="current">Current Home</a>'
54
+ Then I should see '<a href="/es/index.html" title="Other Home">Other Home</a>'
55
+ Then I should see '<a href="/index.html" class="current"><span>Home: Current Block</span></a>'
56
+ Then I should see '<a href="/es/index.html" title="Other Home"><span>Home: Other Block</span></a>'
57
+ Then I should see '<a href="/hello.html" class="current">Current hello.html</a>'
58
+ Then I should see '<a href="/es/hola.html" title="Other hello.html">Other hello.html</a>'
59
+ Then I should see '<a href="/hello.html" class="current"><span>Current Block</span></a>'
60
+ Then I should see '<a href="/es/hola.html" title="Other hello.html"><span>Other Block</span></a>'
61
61
  When I go to "/es/hola.html"
62
62
  Then I should see "Page: Hola"
63
- Then I should see '<a class="current" href="/es/index.html">Current Home</a>'
64
- Then I should see '<a title="Other Home" href="/index.html">Other Home</a>'
65
- Then I should see '<a class="current" href="/es/index.html"><span>Home: Current Block</span></a>'
66
- Then I should see '<a title="Other Home" href="/index.html"><span>Home: Other Block</span></a>'
67
- Then I should see '<a class="current" href="/es/hola.html">Current hello.html</a>'
68
- Then I should see '<a title="Other hello.html" href="/hello.html">Other hello.html</a>'
69
- Then I should see '<a class="current" href="/es/hola.html"><span>Current Block</span></a>'
70
- Then I should see '<a title="Other hello.html" href="/hello.html"><span>Other Block</span></a>'
63
+ Then I should see '<a href="/es/index.html" class="current">Current Home</a>'
64
+ Then I should see '<a href="/index.html" title="Other Home">Other Home</a>'
65
+ Then I should see '<a href="/es/index.html" class="current"><span>Home: Current Block</span></a>'
66
+ Then I should see '<a href="/index.html" title="Other Home"><span>Home: Other Block</span></a>'
67
+ Then I should see '<a href="/es/hola.html" class="current">Current hello.html</a>'
68
+ Then I should see '<a href="/hello.html" title="Other hello.html">Other hello.html</a>'
69
+ Then I should see '<a href="/es/hola.html" class="current"><span>Current Block</span></a>'
70
+ Then I should see '<a href="/hello.html" title="Other hello.html"><span>Other Block</span></a>'
71
71
 
72
72
  Scenario: link_to is i18n aware and supports relative_links
73
73
  Given a fixture app "empty-app"
@@ -124,30 +124,30 @@ Feature: i18n Paths
124
124
  Then I should see "assets/css/main.css"
125
125
  When I go to "/hello.html"
126
126
  Then I should see "Page: Hello"
127
- Then I should see '<a class="current" href="index.html">Current Home</a>'
128
- Then I should see '<a title="Other Home" href="es/index.html">Other Home</a>'
129
- Then I should see '<a class="current" href="index.html"><span>Home: Current Block</span></a>'
130
- Then I should see '<a title="Other Home" href="es/index.html"><span>Home: Other Block</span></a>'
131
- Then I should see '<a class="current" href="hello.html">Current hello.html</a>'
132
- Then I should see '<a title="Other hello.html" href="es/hola.html">Other hello.html</a>'
133
- Then I should see '<a class="current" href="hello.html"><span>Current Block</span></a>'
134
- Then I should see '<a title="Other hello.html" href="es/hola.html"><span>Other Block</span></a>'
127
+ Then I should see '<a href="index.html" class="current">Current Home</a>'
128
+ Then I should see '<a href="es/index.html" title="Other Home">Other Home</a>'
129
+ Then I should see '<a href="index.html" class="current"><span>Home: Current Block</span></a>'
130
+ Then I should see '<a href="es/index.html" title="Other Home"><span>Home: Other Block</span></a>'
131
+ Then I should see '<a href="hello.html" class="current">Current hello.html</a>'
132
+ Then I should see '<a href="es/hola.html" title="Other hello.html">Other hello.html</a>'
133
+ Then I should see '<a href="hello.html" class="current"><span>Current Block</span></a>'
134
+ Then I should see '<a href="es/hola.html" title="Other hello.html"><span>Other Block</span></a>'
135
135
  When I go to "/es/hola.html"
136
136
  Then I should see "Page: Hola"
137
- Then I should see '<a class="current" href="index.html">Current Home</a>'
138
- Then I should see '<a title="Other Home" href="../index.html">Other Home</a>'
139
- Then I should see '<a class="current" href="index.html"><span>Home: Current Block</span></a>'
140
- Then I should see '<a title="Other Home" href="../index.html"><span>Home: Other Block</span></a>'
141
- Then I should see '<a class="current" href="hola.html">Current hello.html</a>'
142
- Then I should see '<a title="Other hello.html" href="../hello.html">Other hello.html</a>'
143
- Then I should see '<a class="current" href="hola.html"><span>Current Block</span></a>'
144
- Then I should see '<a title="Other hello.html" href="../hello.html"><span>Other Block</span></a>'
137
+ Then I should see '<a href="index.html" class="current">Current Home</a>'
138
+ Then I should see '<a href="../index.html" title="Other Home">Other Home</a>'
139
+ Then I should see '<a href="index.html" class="current"><span>Home: Current Block</span></a>'
140
+ Then I should see '<a href="../index.html" title="Other Home"><span>Home: Other Block</span></a>'
141
+ Then I should see '<a href="hola.html" class="current">Current hello.html</a>'
142
+ Then I should see '<a href="../hello.html" title="Other hello.html">Other hello.html</a>'
143
+ Then I should see '<a href="hola.html" class="current"><span>Current Block</span></a>'
144
+ Then I should see '<a href="../hello.html" title="Other hello.html"><span>Other Block</span></a>'
145
145
 
146
146
  Scenario: url_for is i18n aware
147
147
  Given a fixture app "empty-app"
148
148
  And a file named "data/pages.yml" with:
149
149
  """
150
- - hello.html
150
+ - hello.html
151
151
  - article.html
152
152
  """
153
153
  And a file named "locales/en.yml" with:
@@ -120,7 +120,7 @@ Feature: Relative Assets
120
120
  """
121
121
  And the Server is running at "relative-assets-app"
122
122
  When I go to "/sub/image_tag.html"
123
- Then I should see '<img src="../img/blank.gif" />'
123
+ Then I should see '<img src="../img/blank.gif"'
124
124
 
125
125
  Scenario: Relative assets should not break data URIs in image_tag
126
126
  Given a fixture app "relative-assets-app"
@@ -0,0 +1,123 @@
1
+ Feature: Relative Assets (Helpers Only)
2
+
3
+ Scenario: Rendering css with the feature enabled
4
+ Given a fixture app "relative-assets-app"
5
+ And a file named "config.rb" with:
6
+ """
7
+ activate :relative_assets, helpers_only: true
8
+ """
9
+ And a file named "source/stylesheets/relative_assets.css.sass.erb" with:
10
+ """
11
+ h1
12
+ background: url("<%= asset_url('images/blank.gif') %>")
13
+ h2
14
+ background: url("<%= asset_url('/images/blank2.gif') %>")
15
+ """
16
+ And a file named "source/javascripts/application.js.erb" with:
17
+ """
18
+ function foo() {
19
+ var img = document.createElement('img');
20
+ img.src = '<%= asset_url("images/100px.jpg") %>';
21
+ var body = document.getElementsByTagName('body')[0];
22
+ body.insertBefore(img, body.firstChild);
23
+ }
24
+
25
+ window.onload = foo;
26
+ """
27
+ And a file named "source/stylesheets/fonts3.css.erb" with:
28
+ """
29
+ @font-face {
30
+ font-family: 'Roboto2';
31
+ src: url(<%= asset_url("/fonts/roboto/roboto-regular-webfont.eot") %>);
32
+ src: url(<%= asset_url("/fonts/roboto/roboto-regular-webfont.eot?#iefix") %>) format('embedded-opentype'),
33
+ url(<%= asset_url("/fonts/roboto/roboto-regular-webfont.woff") %>) format('woff'),
34
+ url(<%= asset_url("/fonts/roboto/roboto-regular-webfont.ttf") %>) format('truetype'),
35
+ url(<%= asset_url("/fonts/roboto/roboto-regular-webfont.svg#robotoregular") %>) format('svg');
36
+ font-weight: normal;
37
+ font-style: normal;
38
+ }
39
+ """
40
+ And the Server is running at "relative-assets-app"
41
+ When I go to "/stylesheets/relative_assets.css"
42
+ Then I should see 'url("../images/blank.gif'
43
+ And I should see 'url("../images/blank2.gif'
44
+ When I go to "/javascripts/application.js"
45
+ Then I should not see "../"
46
+ When I go to "/stylesheets/fonts3.css"
47
+ Then I should see 'url(../fonts/roboto/roboto-regular-webfont.eot'
48
+ And I should see 'url(../fonts/roboto/roboto-regular-webfont.woff'
49
+ And I should see 'url(../fonts/roboto/roboto-regular-webfont.ttf'
50
+ And I should see 'url(../fonts/roboto/roboto-regular-webfont.svg'
51
+
52
+ Scenario: Relative css reference with directory indexes
53
+ Given a fixture app "relative-assets-app"
54
+ And a file named "config.rb" with:
55
+ """
56
+ activate :directory_indexes
57
+ activate :relative_assets, helpers_only: true
58
+ """
59
+ And the Server is running at "relative-assets-app"
60
+ When I go to "/relative_image/index.html"
61
+ Then I should see "../stylesheets/relative_assets.css"
62
+
63
+ Scenario: Relative assets via image_tag
64
+ Given a fixture app "relative-assets-app"
65
+ And a file named "config.rb" with:
66
+ """
67
+ activate :relative_assets, helpers_only: true
68
+ """
69
+ And a file named "source/sub/image_tag.html.erb" with:
70
+ """
71
+ <%= image_tag '/img/blank.gif' %>
72
+ """
73
+ And the Server is running at "relative-assets-app"
74
+ When I go to "/sub/image_tag.html"
75
+ Then I should see '<img src="../img/blank.gif"'
76
+
77
+ Scenario: Relative assets should not break data URIs in image_tag
78
+ Given a fixture app "relative-assets-app"
79
+ And a file named "config.rb" with:
80
+ """
81
+ activate :relative_assets, helpers_only: true
82
+ """
83
+ And a file named "source/sub/image_tag.html.erb" with:
84
+ """
85
+ <%= image_tag "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" %>
86
+ """
87
+ And the Server is running at "relative-assets-app"
88
+ When I go to "/sub/image_tag.html"
89
+ Then I should see '<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" />'
90
+
91
+ Scenario: URLs are not rewritten for rewrite ignored paths
92
+ Given a fixture app "relative-assets-app"
93
+ And a file named "config.rb" with:
94
+ """
95
+ activate :relative_assets, rewrite_ignore: [
96
+ '/stylesheets/fonts3.css',
97
+ ], helpers_only: true
98
+ """
99
+ And a file named "source/stylesheets/relative_assets.css.sass.erb" with:
100
+ """
101
+ h1
102
+ background: url("<%= asset_url('images/blank.gif') %>")
103
+ h2
104
+ background: url("<%= asset_url('/images/blank2.gif') %>")
105
+ """
106
+ And a file named "source/stylesheets/fonts3.css.erb" with:
107
+ """
108
+ @font-face {
109
+ font-family: 'Roboto2';
110
+ src: url(<%= asset_url("/fonts/roboto/roboto-regular-webfont.eot") %>);
111
+ src: url(<%= asset_url("/fonts/roboto/roboto-regular-webfont.eot?#iefix") %>) format('embedded-opentype'),
112
+ url(<%= asset_url("/fonts/roboto/roboto-regular-webfont.woff") %>) format('woff'),
113
+ url(<%= asset_url("/fonts/roboto/roboto-regular-webfont.ttf") %>) format('truetype'),
114
+ url(<%= asset_url("/fonts/roboto/roboto-regular-webfont.svg#robotoregular") %>) format('svg');
115
+ font-weight: normal;
116
+ font-style: normal;
117
+ }
118
+ """
119
+ And the Server is running at "relative-assets-app"
120
+ When I go to "/stylesheets/relative_assets.css"
121
+ Then I should see 'url("../images/blank.gif'
122
+ When I go to "/stylesheets/fonts3.css"
123
+ Then I should see 'url(/fonts/roboto/roboto-regular-webfont.eot'
@@ -0,0 +1,26 @@
1
+ Feature: Don't allow template locals to overwrite template helpers
2
+
3
+ Scenario: Normal Template
4
+ Given an empty app
5
+ And a file named "config.rb" with:
6
+ """
7
+ class TestExt < ::Middleman::Extension
8
+ expose_to_template foo: :foo
9
+
10
+ def foo
11
+ "bar"
12
+ end
13
+ end
14
+
15
+ ::Middleman::Extensions.register :test, TestExt
16
+
17
+ activate :test
18
+
19
+ page "/index.html", locals: { foo: false }
20
+ """
21
+ And a file named "source/index.html.erb" with:
22
+ """
23
+ <%= foo %>
24
+ """
25
+ Given a built app at "empty_app"
26
+ Then the exit status should be 1
@@ -8,7 +8,7 @@ module Middleman
8
8
  attr_reader :app
9
9
 
10
10
  # Whitelist methods that can reach out.
11
- def_delegators :@app, :config, :logger, :use, :map, :mime_type, :files, :root, :build?, :server?, :environment?
11
+ def_delegators :@app, :config, :logger, :use, :map, :mime_type, :files, :root, :build?, :server?, :environment?, :extensions
12
12
  def_delegator :"@app.extensions", :activate
13
13
 
14
14
  def initialize(app, template_context_class)
@@ -23,7 +23,7 @@ module Middleman
23
23
  end
24
24
 
25
25
  def include(mod)
26
- self.extend(mod)
26
+ extend(mod)
27
27
  end
28
28
 
29
29
  def helpers(*helper_modules, &block)
@@ -12,17 +12,20 @@ module Middleman
12
12
 
13
13
  attr_reader :descriptors
14
14
 
15
- def initialize
15
+ def initialize(app)
16
+ @app = app
16
17
  @descriptors = []
17
18
  end
18
19
 
19
20
  def method_missing(name, *args, &block)
20
21
  internal = :"_internal_#{name}"
21
22
 
22
- return super unless respond_to?(internal)
23
-
24
- send(internal, *args, &block).tap do |r|
25
- @descriptors << r if r.respond_to?(:execute_descriptor)
23
+ if respond_to?(internal)
24
+ send(internal, *args, &block).tap do |r|
25
+ @descriptors << r if r.respond_to?(:execute_descriptor)
26
+ end
27
+ else
28
+ @app.config_context.send(name, *args, &block)
26
29
  end
27
30
  end
28
31
  end
@@ -90,7 +90,7 @@ module Middleman
90
90
  pair[:root].realize!(dataset)
91
91
  end
92
92
 
93
- ctx = StepContext.new
93
+ ctx = StepContext.new(app)
94
94
  StepContext.current = ctx
95
95
 
96
96
  leaves = @leaves.dup
@@ -1,4 +1,5 @@
1
1
  require 'padrino-helpers'
2
+ require 'middleman-core/contracts'
2
3
 
3
4
  # Don't fail on invalid locale, that's not what our current
4
5
  # users expect.
@@ -73,18 +73,20 @@ module Middleman::CoreExtensions
73
73
 
74
74
  return [{}, nil] unless file
75
75
 
76
- return @cache[file[:full_path]] if @cache.key?(file[:full_path])
76
+ file_path = file[:full_path].to_s
77
77
 
78
- @cache[file[:full_path]] = ::Middleman::Util::Data.parse(
79
- file,
80
- app.config[:frontmatter_delims]
81
- )
78
+ @cache[file_path] ||= begin
79
+ ::Middleman::Util::Data.parse(
80
+ file,
81
+ app.config[:frontmatter_delims]
82
+ )
83
+ end
82
84
  end
83
85
 
84
86
  Contract ArrayOf[IsA['Middleman::SourceFile']], ArrayOf[IsA['Middleman::SourceFile']] => Any
85
87
  def clear_data(updated_files, removed_files)
86
88
  (updated_files + removed_files).each do |file|
87
- @cache.delete(file[:full_path])
89
+ @cache.delete(file[:full_path].to_s)
88
90
  end
89
91
  end
90
92
  end
@@ -1,6 +1,6 @@
1
1
  require 'rack'
2
2
  require 'rack/response'
3
- require 'addressable/uri'
3
+ require 'memoist'
4
4
  require 'middleman-core/util'
5
5
  require 'middleman-core/contracts'
6
6
 
@@ -11,13 +11,12 @@ module Middleman
11
11
 
12
12
  expose_to_application rewrite_inline_urls: :add
13
13
 
14
- IGNORE_DESCRIPTOR = Or[Regexp, RespondTo[:call], String]
15
14
  REWRITER_DESCRIPTOR = {
16
15
  id: Symbol,
17
16
  proc: Or[Proc, Method],
18
17
  url_extensions: ArrayOf[String],
19
18
  source_extensions: ArrayOf[String],
20
- ignore: ArrayOf[IGNORE_DESCRIPTOR],
19
+ ignore: ArrayOf[::Middleman::Util::IGNORE_DESCRIPTOR],
21
20
  after: Maybe[Symbol]
22
21
  }.freeze
23
22
 
@@ -33,6 +32,8 @@ module Middleman
33
32
  end
34
33
 
35
34
  def after_configuration
35
+ return if @rewriters.empty?
36
+
36
37
  rewriters = @rewriters.values.sort do |a, b|
37
38
  if b[:after] && b[:after] == a[:id]
38
39
  1
@@ -45,6 +46,7 @@ module Middleman
45
46
  end
46
47
 
47
48
  class Rack
49
+ extend Memoist
48
50
  include Contracts
49
51
 
50
52
  Contract RespondTo[:call], {
@@ -55,6 +57,17 @@ module Middleman
55
57
  @rack_app = app
56
58
  @middleman_app = options.fetch(:middleman_app)
57
59
  @rewriters = options.fetch(:rewriters)
60
+
61
+ all_source_exts = @rewriters
62
+ .reduce([]) { |sum, rewriter| sum + rewriter[:source_extensions] }
63
+ .flatten
64
+ .uniq
65
+ @source_exts_regex_text = Regexp.union(all_source_exts).to_s
66
+
67
+ @all_asset_exts = @rewriters
68
+ .reduce([]) { |sum, rewriter| sum + rewriter[:url_extensions] }
69
+ .flatten
70
+ .uniq
58
71
  end
59
72
 
60
73
  def call(env)
@@ -63,27 +76,16 @@ module Middleman
63
76
  # Allow configuration or upstream request to skip all rewriting
64
77
  return [status, headers, response] if env['bypass_inline_url_rewriter'] == 'true'
65
78
 
66
- all_source_exts = @rewriters
67
- .reduce([]) { |sum, rewriter| sum + rewriter[:source_extensions] }
68
- .flatten
69
- .uniq
70
- source_exts_regex_text = Regexp.union(all_source_exts).to_s
71
-
72
- all_asset_exts = @rewriters
73
- .reduce([]) { |sum, rewriter| sum + rewriter[:url_extensions] }
74
- .flatten
75
- .uniq
76
-
77
79
  path = ::Middleman::Util.full_path(env['PATH_INFO'], @middleman_app)
78
80
 
79
- return [status, headers, response] unless path =~ /(^\/$)|(#{source_exts_regex_text}$)/
81
+ return [status, headers, response] unless path =~ /(^\/$)|(#{@source_exts_regex_text}$)/
80
82
  return [status, headers, response] unless body = ::Middleman::Util.extract_response_text(response)
81
83
 
82
84
  dirpath = ::Pathname.new(File.dirname(path))
83
85
 
84
86
  rewritten = ::Middleman::Util.instrument 'inline_url_rewriter', path: path do
85
- ::Middleman::Util.rewrite_paths(body, path, all_asset_exts, @middleman_app) do |asset_path|
86
- uri = ::Addressable::URI.parse(asset_path)
87
+ ::Middleman::Util.rewrite_paths(body, path, @all_asset_exts, @middleman_app) do |asset_path|
88
+ uri = ::Middleman::Util.parse_uri(asset_path)
87
89
 
88
90
  relative_path = uri.host.nil?
89
91
 
@@ -106,7 +108,7 @@ module Middleman
106
108
  next unless source_exts.include?(::File.extname(path))
107
109
 
108
110
  ignore = rewriter.fetch(:ignore)
109
- next if ignore.any? { |r| should_ignore?(r, full_asset_path) }
111
+ next if ignore.any? { |r| ::Middleman::Util.should_ignore?(r, full_asset_path) }
110
112
 
111
113
  rewrite_ignore = Array(rewriter[:rewrite_ignore] || [])
112
114
  next if rewrite_ignore.any? { |i| ::Middleman::Util.path_match(i, path) }
@@ -127,23 +129,6 @@ module Middleman
127
129
  headers
128
130
  ).finish
129
131
  end
130
-
131
- Contract IGNORE_DESCRIPTOR, String => Bool
132
- def should_ignore?(validator, value)
133
- if validator.is_a? Regexp
134
- # Treat as Regexp
135
- !!(value =~ validator)
136
- elsif validator.respond_to? :call
137
- # Treat as proc
138
- validator.call(value)
139
- elsif validator.is_a? String
140
- # Treat as glob
141
- File.fnmatch(value, validator)
142
- else
143
- # If some unknown thing, don't ignore
144
- false
145
- end
146
- end
147
132
  end
148
133
  end
149
134
  end
@@ -1,4 +1,5 @@
1
1
  require 'forwardable'
2
+ require 'memoist'
2
3
  require 'active_support/core_ext/class/attribute'
3
4
  require 'middleman-core/configuration'
4
5
  require 'middleman-core/contracts'
@@ -66,6 +67,8 @@ module Middleman
66
67
  # @see http://middlemanapp.com/advanced/custom/ Middleman Custom Extensions Documentation
67
68
  class Extension
68
69
  extend Forwardable
70
+ extend Memoist
71
+
69
72
  include Contracts
70
73
 
71
74
  def_delegator :@app, :logger
@@ -510,7 +513,7 @@ module Middleman
510
513
  self.class.exposed_to_config.each do |k, v|
511
514
  ::Middleman::CoreExtensions::Collections::StepContext.add_to_context(k) do |*args, &b|
512
515
  r = context.method(:"__original_#{v}").call(*args, &b)
513
- self.descriptors << r if r.respond_to?(:execute_descriptor)
516
+ descriptors << r if r.respond_to?(:execute_descriptor)
514
517
  end
515
518
  end
516
519
  end
@@ -32,7 +32,7 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension
32
32
 
33
33
  Contract String, Or[String, Pathname], Any => Maybe[String]
34
34
  def rewrite_url(asset_path, dirpath, _request_path)
35
- uri = ::Addressable::URI.parse(asset_path)
35
+ uri = ::Middleman::Util.parse_uri(asset_path)
36
36
  relative_path = !uri.path.start_with?('/')
37
37
 
38
38
  full_asset_path = if relative_path
@@ -20,7 +20,7 @@ class Middleman::Extensions::AssetHost < ::Middleman::Extension
20
20
 
21
21
  Contract String, Or[String, Pathname], Any => String
22
22
  def rewrite_url(asset_path, dirpath, _request_path)
23
- uri = ::Addressable::URI.parse(asset_path)
23
+ uri = ::Middleman::Util.parse_uri(asset_path)
24
24
  relative_path = uri.path[0..0] != '/'
25
25
 
26
26
  full_asset_path = if relative_path
@@ -37,4 +37,5 @@ class Middleman::Extensions::AssetHost < ::Middleman::Extension
37
37
 
38
38
  File.join(asset_prefix, full_asset_path)
39
39
  end
40
+ memoize :rewrite_url
40
41
  end
@@ -1,3 +1,5 @@
1
+ require 'active_support/core_ext/object/try'
2
+ require 'memoist'
1
3
  require 'middleman-core/contracts'
2
4
 
3
5
  # Minify CSS Extension
@@ -30,6 +32,7 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension
30
32
 
31
33
  # Rack middleware to look for CSS and compress it
32
34
  class Rack
35
+ extend Memoist
33
36
  include Contracts
34
37
  INLINE_CSS_REGEX = /(<style[^>]*>\s*(?:\/\*<!\[CDATA\[\*\/\n)?)(.*?)((?:(?:\n\s*)?\/\*\]\]>\*\/)?\s*<\/style>)/m
35
38
 
@@ -82,8 +85,9 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension
82
85
  # @param [String] path
83
86
  # @return [Boolean]
84
87
  def ignore?(path)
85
- @ignore.any? { |ignore| Middleman::Util.path_match(ignore, path) }
88
+ @ignore.any? { |ignore| ::Middleman::Util.path_match(ignore, path) }
86
89
  end
90
+ memoize :ignore?
87
91
 
88
92
  # Whether this type of content can be minified
89
93
  # @param [String, nil] content_type
@@ -91,6 +95,7 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension
91
95
  def minifiable?(content_type)
92
96
  @content_types.include?(content_type)
93
97
  end
98
+ memoize :minifiable?
94
99
 
95
100
  # Whether this type of content contains inline content that can be minified
96
101
  # @param [String, nil] content_type
@@ -98,6 +103,7 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension
98
103
  def minifiable_inline?(content_type)
99
104
  @inline_content_types.include?(content_type)
100
105
  end
106
+ memoize :minifiable_inline?
101
107
 
102
108
  # Minify the content
103
109
  # @param [String] content
@@ -105,6 +111,7 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension
105
111
  def minify(content)
106
112
  @compressor.compress(content)
107
113
  end
114
+ memoize :minify
108
115
 
109
116
  # Detect and minify inline content
110
117
  # @param [String] content
@@ -114,5 +121,6 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension
114
121
  $1 + minify($2) + $3
115
122
  end
116
123
  end
124
+ memoize :minify_inline
117
125
  end
118
126
  end