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.
- checksums.yaml +4 -4
- data/features/collections.feature +27 -0
- data/features/i18n_link_to.feature +34 -34
- data/features/relative_assets.feature +1 -1
- data/features/relative_assets_helpers_only.feature +123 -0
- data/features/template-key-collision.feature +26 -0
- data/fixtures/relative-assets-app/source/images/blank2.gif +0 -0
- data/lib/middleman-core/config_context.rb +2 -2
- data/lib/middleman-core/core_extensions/collections/step_context.rb +8 -5
- data/lib/middleman-core/core_extensions/collections.rb +1 -1
- data/lib/middleman-core/core_extensions/default_helpers.rb +1 -0
- data/lib/middleman-core/core_extensions/front_matter.rb +8 -6
- data/lib/middleman-core/core_extensions/inline_url_rewriter.rb +20 -35
- data/lib/middleman-core/extension.rb +4 -1
- data/lib/middleman-core/extensions/asset_hash.rb +1 -1
- data/lib/middleman-core/extensions/asset_host.rb +2 -1
- data/lib/middleman-core/extensions/minify_css.rb +9 -1
- data/lib/middleman-core/extensions/minify_javascript.rb +8 -0
- data/lib/middleman-core/extensions/relative_assets.rb +39 -12
- data/lib/middleman-core/file_renderer.rb +4 -4
- data/lib/middleman-core/sitemap/resource.rb +3 -3
- data/lib/middleman-core/sitemap/store.rb +1 -1
- data/lib/middleman-core/sources/source_watcher.rb +6 -0
- data/lib/middleman-core/template_context.rb +3 -2
- data/lib/middleman-core/template_renderer.rb +22 -9
- data/lib/middleman-core/util/data.rb +32 -17
- data/lib/middleman-core/util/files.rb +3 -7
- data/lib/middleman-core/util/paths.rb +38 -0
- data/lib/middleman-core/util/rack.rb +1 -1
- data/lib/middleman-core/version.rb +1 -1
- data/middleman-core.gemspec +3 -2
- data/spec/middleman-core/util_spec.rb +16 -0
- metadata +25 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99765b41dbcadb0a1fe8e9017ce95171fe5e7877
|
4
|
+
data.tar.gz: 972fcfba7e09229dc557444eba1434d6d42a0346
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
54
|
-
Then I should see '<a
|
55
|
-
Then I should see '<a
|
56
|
-
Then I should see '<a
|
57
|
-
Then I should see '<a
|
58
|
-
Then I should see '<a
|
59
|
-
Then I should see '<a
|
60
|
-
Then I should see '<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
|
64
|
-
Then I should see '<a
|
65
|
-
Then I should see '<a
|
66
|
-
Then I should see '<a
|
67
|
-
Then I should see '<a
|
68
|
-
Then I should see '<a
|
69
|
-
Then I should see '<a
|
70
|
-
Then I should see '<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
|
128
|
-
Then I should see '<a
|
129
|
-
Then I should see '<a
|
130
|
-
Then I should see '<a
|
131
|
-
Then I should see '<a
|
132
|
-
Then I should see '<a
|
133
|
-
Then I should see '<a
|
134
|
-
Then I should see '<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
|
138
|
-
Then I should see '<a
|
139
|
-
Then I should see '<a
|
140
|
-
Then I should see '<a
|
141
|
-
Then I should see '<a
|
142
|
-
Then I should see '<a
|
143
|
-
Then I should see '<a
|
144
|
-
Then I should see '<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
|
File without changes
|
@@ -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
|
-
|
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
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
@@ -73,18 +73,20 @@ module Middleman::CoreExtensions
|
|
73
73
|
|
74
74
|
return [{}, nil] unless file
|
75
75
|
|
76
|
-
|
76
|
+
file_path = file[:full_path].to_s
|
77
77
|
|
78
|
-
@cache[
|
79
|
-
|
80
|
-
|
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 '
|
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 = ::
|
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
|
-
|
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 = ::
|
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 = ::
|
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
|