middleman-core 4.1.7 → 4.1.8

Sign up to get free protection for your applications and to get access to all the features.
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