Compare commits
6 commits
master
...
feature/pi
Author | SHA1 | Date | |
---|---|---|---|
|
439ecb1887 | ||
|
87e0f240ff | ||
|
2804a61c61 | ||
|
0d3030f28c | ||
|
029de6613b | ||
|
11e478fad9 |
92 changed files with 545 additions and 1162 deletions
|
@ -67,5 +67,3 @@ Style/MultilineBlockChain:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
Style/SpecialGlobalVars:
|
Style/SpecialGlobalVars:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
Style/FrozenStringLiteralComment:
|
|
||||||
Enabled: false
|
|
||||||
|
|
|
@ -7,6 +7,8 @@ rvm:
|
||||||
- ruby-head
|
- ruby-head
|
||||||
- 2.3.1
|
- 2.3.1
|
||||||
- 2.2.4
|
- 2.2.4
|
||||||
|
- 2.1
|
||||||
|
- 2.0
|
||||||
os:
|
os:
|
||||||
- linux
|
- linux
|
||||||
# - osx
|
# - osx
|
||||||
|
|
33
CHANGELOG.md
33
CHANGELOG.md
|
@ -1,41 +1,14 @@
|
||||||
master
|
master
|
||||||
===
|
===
|
||||||
|
|
||||||
# 4.1.13
|
# 4.2.0
|
||||||
|
|
||||||
* Change how config options are passed to Thor. Removes new Thor warnings from #2017
|
* Remove Rack support in favor of `resource.filters << proc { |oldbody| newbody }`
|
||||||
|
* Expose `development?` and `production?` helpers to template context.
|
||||||
# 4.1.12
|
|
||||||
|
|
||||||
* Fix broken `ignore { |p| true }` form.
|
|
||||||
|
|
||||||
# 4.1.11
|
|
||||||
|
|
||||||
* Upgrade to Rack 2.
|
|
||||||
|
|
||||||
# 4.1.10
|
|
||||||
|
|
||||||
* Fix unicode issues in URL deeplinks.
|
|
||||||
* Add prefix option to asset_hash (#1949)
|
|
||||||
|
|
||||||
# 4.1.9
|
|
||||||
|
|
||||||
* Fix `--watcher-*` CLI flags.
|
|
||||||
* Allow spaces in paths to work with `link_to`. Fixes #1914
|
|
||||||
* Add support for dotenv
|
|
||||||
* Fix asset_url with asset_hash (#1919)
|
|
||||||
* Allow partial lookups without a current_resource (#1912)
|
|
||||||
|
|
||||||
# 4.1.8
|
# 4.1.8
|
||||||
|
|
||||||
* Expose `development?` and `production?` helpers to template context.
|
|
||||||
* require the `try` core extension (#1911)
|
|
||||||
* Fix contract for Sitemap::Store.register_resource_list_manipulator (#1907)
|
|
||||||
* Loosen contract on Resource#source_file to Maybe[String] (#1906)
|
|
||||||
* Let collection loops access ConfigContext for helpers. #1879
|
* Let collection loops access ConfigContext for helpers. #1879
|
||||||
* Use https:// to clone templates (#1901)
|
|
||||||
* Allow numbers to be unique page_ids (#1886)
|
|
||||||
* Prevent infinite loop when encountering files where base filename is a possible templating engine
|
|
||||||
|
|
||||||
# 4.1.7
|
# 4.1.7
|
||||||
|
|
||||||
|
|
10
Gemfile
10
Gemfile
|
@ -9,12 +9,6 @@ gem 'byebug'
|
||||||
gem 'aruba', '~> 0.7.4', require: false
|
gem 'aruba', '~> 0.7.4', require: false
|
||||||
gem 'rspec', '~> 3.0', require: false
|
gem 'rspec', '~> 3.0', require: false
|
||||||
gem 'cucumber', '~> 2.0', require: false
|
gem 'cucumber', '~> 2.0', require: false
|
||||||
gem 'addressable', '~> 2.4.0', require: false
|
|
||||||
|
|
||||||
# Pry tools
|
|
||||||
gem 'pry'
|
|
||||||
gem 'pry-stack_explorer'
|
|
||||||
gem 'pry-rescue'
|
|
||||||
|
|
||||||
# Optional middleman dependencies, included for tests
|
# Optional middleman dependencies, included for tests
|
||||||
gem 'haml', '>= 4.0.5', require: false
|
gem 'haml', '>= 4.0.5', require: false
|
||||||
|
@ -24,7 +18,7 @@ gem 'kramdown', '~> 1.2', require: false
|
||||||
gem 'slim', '>= 2.0', require: false
|
gem 'slim', '>= 2.0', require: false
|
||||||
gem 'liquid', '>= 2.6', require: false
|
gem 'liquid', '>= 2.6', require: false
|
||||||
gem 'stylus', '>= 1.0', require: false
|
gem 'stylus', '>= 1.0', require: false
|
||||||
gem 'sinatra', '>= 2.0.0.beta2', require: false
|
gem 'sinatra', '>= 1.4', require: false
|
||||||
gem 'redcarpet', '>= 3.1', require: false
|
gem 'redcarpet', '>= 3.1', require: false
|
||||||
|
|
||||||
# Dns server to test preview server
|
# Dns server to test preview server
|
||||||
|
@ -32,7 +26,7 @@ gem 'rubydns', '~> 1.0.1', require: false
|
||||||
|
|
||||||
# To test javascript
|
# To test javascript
|
||||||
gem 'poltergeist', '~> 1.8', require: false
|
gem 'poltergeist', '~> 1.8', require: false
|
||||||
gem 'phantomjs', '~> 2.1.1.0', require: false
|
gem 'phantomjs', '~> 1.9.8.0', require: false
|
||||||
|
|
||||||
# For less, note there is no compatible JS runtime for windows
|
# For less, note there is no compatible JS runtime for windows
|
||||||
gem 'therubyrhino', '>= 2.0', platforms: :jruby
|
gem 'therubyrhino', '>= 2.0', platforms: :jruby
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
## Expected behavior and actual behavior
|
|
||||||
|
|
||||||
## Steps to reproduce the problem (from a clean middleman installation)
|
|
||||||
|
|
||||||
## Additional information
|
|
||||||
|
|
||||||
- Ruby version:
|
|
||||||
- Middleman version:
|
|
||||||
- OS version:
|
|
|
@ -9,9 +9,6 @@ end
|
||||||
require "middleman-core/load_paths"
|
require "middleman-core/load_paths"
|
||||||
Middleman.setup_load_paths
|
Middleman.setup_load_paths
|
||||||
|
|
||||||
require 'dotenv'
|
|
||||||
::Dotenv.load
|
|
||||||
|
|
||||||
require 'middleman-core'
|
require 'middleman-core'
|
||||||
require 'middleman-core/logger'
|
require 'middleman-core/logger'
|
||||||
|
|
||||||
|
@ -25,10 +22,12 @@ module Middleman::Cli
|
||||||
if setting.default.is_a?(String) || setting.default.is_a?(NilClass)
|
if setting.default.is_a?(String) || setting.default.is_a?(NilClass)
|
||||||
base.class_option setting.key,
|
base.class_option setting.key,
|
||||||
type: :string,
|
type: :string,
|
||||||
|
default: :undefined,
|
||||||
desc: setting.description
|
desc: setting.description
|
||||||
elsif setting.default.is_a?(TrueClass) || setting.default.is_a?(FalseClass)
|
elsif setting.default.is_a?(TrueClass) || setting.default.is_a?(FalseClass)
|
||||||
base.class_option setting.key,
|
base.class_option setting.key,
|
||||||
type: :boolean,
|
type: :boolean,
|
||||||
|
default: :undefined,
|
||||||
desc: setting.description
|
desc: setting.description
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -47,8 +46,6 @@ end
|
||||||
|
|
||||||
::Middleman::Logger.singleton(3)
|
::Middleman::Logger.singleton(3)
|
||||||
::Middleman::Cli.config = ::Middleman::Application.new do
|
::Middleman::Cli.config = ::Middleman::Application.new do
|
||||||
#
|
|
||||||
config[:environment] = (ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development').to_sym
|
|
||||||
config[:mode] = :config
|
config[:mode] = :config
|
||||||
config[:exit_before_ready] = true
|
config[:exit_before_ready] = true
|
||||||
config[:watcher_disable] = true
|
config[:watcher_disable] = true
|
||||||
|
|
|
@ -10,7 +10,7 @@ module Middleman::Cli
|
||||||
|
|
||||||
class_option :environment,
|
class_option :environment,
|
||||||
aliases: '-e',
|
aliases: '-e',
|
||||||
default: ENV['MM_ENV'] || ENV['RACK_ENV'] || :production
|
default: :production
|
||||||
class_option :clean,
|
class_option :clean,
|
||||||
type: :boolean,
|
type: :boolean,
|
||||||
default: true,
|
default: true,
|
||||||
|
@ -29,7 +29,7 @@ module Middleman::Cli
|
||||||
default: false,
|
default: false,
|
||||||
desc: 'Print debug messages'
|
desc: 'Print debug messages'
|
||||||
class_option :instrument,
|
class_option :instrument,
|
||||||
type: :boolean,
|
type: :string,
|
||||||
default: false,
|
default: false,
|
||||||
desc: 'Print instrument messages'
|
desc: 'Print instrument messages'
|
||||||
class_option :profile,
|
class_option :profile,
|
||||||
|
@ -64,7 +64,7 @@ module Middleman::Cli
|
||||||
config[:mode] = :build
|
config[:mode] = :build
|
||||||
config[:show_exceptions] = false
|
config[:show_exceptions] = false
|
||||||
config[:cli_options] = cli_options.each_with_object({}) do |(k, v), sum|
|
config[:cli_options] = cli_options.each_with_object({}) do |(k, v), sum|
|
||||||
sum[k] = v
|
sum[k] = v unless v == :undefined
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -113,7 +113,7 @@ module Middleman::Cli
|
||||||
end
|
end
|
||||||
|
|
||||||
def repository_path(repo)
|
def repository_path(repo)
|
||||||
repo.include?('://') || repo.include?('git@') ? repo : "https://github.com/#{repo}.git"
|
repo.include?('://') || repo.include?('git@') ? repo : "git://github.com/#{repo}.git"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Add to CLI
|
# Add to CLI
|
||||||
|
|
|
@ -17,7 +17,7 @@ module Middleman::Cli
|
||||||
default: false,
|
default: false,
|
||||||
desc: 'Print debug messages'
|
desc: 'Print debug messages'
|
||||||
class_option :instrument,
|
class_option :instrument,
|
||||||
type: :boolean,
|
type: :string,
|
||||||
default: false,
|
default: false,
|
||||||
desc: 'Print instrument messages'
|
desc: 'Print instrument messages'
|
||||||
class_option :profile,
|
class_option :profile,
|
||||||
|
|
|
@ -17,7 +17,7 @@ Gem::Specification.new do |s|
|
||||||
s.test_files = `git ls-files -z -- {fixtures,features}/*`.split("\0")
|
s.test_files = `git ls-files -z -- {fixtures,features}/*`.split("\0")
|
||||||
s.executable = 'middleman'
|
s.executable = 'middleman'
|
||||||
s.require_path = 'lib'
|
s.require_path = 'lib'
|
||||||
s.required_ruby_version = '>= 2.2.0'
|
s.required_ruby_version = '>= 2.0.0'
|
||||||
|
|
||||||
# CLI
|
# CLI
|
||||||
s.add_dependency('thor', ['>= 0.17.0', '< 2.0'])
|
s.add_dependency('thor', ['>= 0.17.0', '< 2.0'])
|
||||||
|
|
|
@ -188,23 +188,6 @@ Feature: Assets get file hashes appended to them and references to them are upda
|
||||||
When I go to "/partials/"
|
When I go to "/partials/"
|
||||||
Then I should see 'href="../stylesheets/uses_partials-ec347271.css'
|
Then I should see 'href="../stylesheets/uses_partials-ec347271.css'
|
||||||
|
|
||||||
Scenario: The asset hash should change when a Rack-based filter changes
|
|
||||||
Given a fixture app "asset-hash-app"
|
|
||||||
And a file named "config.rb" with:
|
|
||||||
"""
|
|
||||||
activate :asset_hash
|
|
||||||
activate :relative_assets
|
|
||||||
activate :directory_indexes
|
|
||||||
require 'lib/middleware.rb'
|
|
||||||
use ::Middleware
|
|
||||||
"""
|
|
||||||
Given the Server is running at "asset-hash-app"
|
|
||||||
When I go to "/"
|
|
||||||
Then I should see 'href="stylesheets/site-5ad7def0.css'
|
|
||||||
When I go to "stylesheets/site-5ad7def0.css"
|
|
||||||
Then I should see 'background-image: url("../images/100px-5fd6fb90.jpg")'
|
|
||||||
Then I should see 'Added by Rack filter'
|
|
||||||
|
|
||||||
Scenario: Hashed-asset files are not produced for ignored paths
|
Scenario: Hashed-asset files are not produced for ignored paths
|
||||||
Given a fixture app "asset-hash-app"
|
Given a fixture app "asset-hash-app"
|
||||||
And a file named "config.rb" with:
|
And a file named "config.rb" with:
|
||||||
|
@ -308,17 +291,3 @@ Feature: Assets get file hashes appended to them and references to them are upda
|
||||||
| javascripts/application.js.map |
|
| javascripts/application.js.map |
|
||||||
|
|
||||||
And the file "javascripts/application-4553338c.js" should contain "//# sourceMappingURL=application.js-22cc2b5f.map"
|
And the file "javascripts/application-4553338c.js" should contain "//# sourceMappingURL=application.js-22cc2b5f.map"
|
||||||
|
|
||||||
Scenario: Hashes can contain a prefix
|
|
||||||
Given a successfully built app at "asset-hash-prefix"
|
|
||||||
When I cd to "build"
|
|
||||||
Then the following files should exist:
|
|
||||||
| index.html |
|
|
||||||
| javascripts/application-myprefix-4553338c.js |
|
|
||||||
| javascripts/application.js-myprefix-22cc2b5f.map |
|
|
||||||
| index.html |
|
|
||||||
And the following files should not exist:
|
|
||||||
| javascripts/application.js |
|
|
||||||
| javascripts/application.js.map |
|
|
||||||
|
|
||||||
And the file "javascripts/application-myprefix-4553338c.js" should contain "//# sourceMappingURL=application.js-myprefix-22cc2b5f.map"
|
|
||||||
|
|
|
@ -25,8 +25,7 @@ Feature: Alternate between multiple asset hosts
|
||||||
And a file named "config.rb" with:
|
And a file named "config.rb" with:
|
||||||
"""
|
"""
|
||||||
activate :asset_host, host: Proc.new { |asset|
|
activate :asset_host, host: Proc.new { |asset|
|
||||||
hash = Digest::MD5.digest(asset).bytes.map!(&:ord).reduce(&:+)
|
"http://assets%d.example.com" % (asset.hash % 4)
|
||||||
"http://assets%d.example.com" % (hash % 4)
|
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
And the Server is running
|
And the Server is running
|
||||||
|
|
17
middleman-core/features/endpoints.feature
Normal file
17
middleman-core/features/endpoints.feature
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
Feature: Generic block based pages
|
||||||
|
|
||||||
|
Scenario: Static Ruby Endpoints
|
||||||
|
Given an empty app
|
||||||
|
And a file named "config.rb" with:
|
||||||
|
"""
|
||||||
|
endpoint "hello.html" do
|
||||||
|
"world"
|
||||||
|
end
|
||||||
|
"""
|
||||||
|
And a file named "source/index.html.erb" with:
|
||||||
|
"""
|
||||||
|
Hi
|
||||||
|
"""
|
||||||
|
And the Server is running at "empty_app"
|
||||||
|
When I go to "/hello.html"
|
||||||
|
Then I should see "world"
|
|
@ -3,8 +3,9 @@ Feature: Extension author could use some hooks
|
||||||
Scenario: When build
|
Scenario: When build
|
||||||
Given a fixture app "extension-api-deprecations-app"
|
Given a fixture app "extension-api-deprecations-app"
|
||||||
When I run `middleman build`
|
When I run `middleman build`
|
||||||
Then the exit status should be 0
|
And the exit status should be 0
|
||||||
And the output should contain "`set :layout` is deprecated"
|
And the output should contain "`set :layout` is deprecated"
|
||||||
|
And the output should contain "Project built successfully"
|
||||||
And the file "build/index.html" should contain "In Index"
|
And the file "build/index.html" should contain "In Index"
|
||||||
And the file "build/index.html" should not contain "In Layout"
|
And the file "build/index.html" should not contain "In Layout"
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ Feature: Extension author could use some hooks
|
||||||
And the output should contain "/// after_configuration ///"
|
And the output should contain "/// after_configuration ///"
|
||||||
And the output should contain "/// ready ///"
|
And the output should contain "/// ready ///"
|
||||||
And the output should contain "/// before_build ///"
|
And the output should contain "/// before_build ///"
|
||||||
And the output should contain "/// before ///"
|
|
||||||
And the output should contain "/// before_render ///"
|
And the output should contain "/// before_render ///"
|
||||||
And the output should contain "/// after_render ///"
|
And the output should contain "/// after_render ///"
|
||||||
And the output should contain "/// after_build ///"
|
And the output should contain "/// after_build ///"
|
||||||
|
|
|
@ -40,29 +40,19 @@ Feature: link_to helper
|
||||||
"""
|
"""
|
||||||
absolute: <%= link_to "Needs Index", "/needs_index.html", relative: true %>
|
absolute: <%= link_to "Needs Index", "/needs_index.html", relative: true %>
|
||||||
relative: <%= link_to "Relative", "needs_index.html", relative: true %>
|
relative: <%= link_to "Relative", "needs_index.html", relative: true %>
|
||||||
|
|
||||||
absolute spaces: <%= link_to "Spaces Index", "/evil spaces.html", relative: true %>
|
|
||||||
relative spaces: <%= link_to "Spaces Relative", "evil spaces.html", relative: true %>
|
|
||||||
"""
|
"""
|
||||||
And a file named "source/link_to/sub.html.erb" with:
|
And a file named "source/link_to/sub.html.erb" with:
|
||||||
"""
|
"""
|
||||||
absolute: <%= link_to "Needs Index", "/needs_index.html", relative: true %>
|
absolute: <%= link_to "Needs Index", "/needs_index.html", relative: true %>
|
||||||
relative: <%= link_to "Relative", "../needs_index.html", relative: true %>
|
relative: <%= link_to "Relative", "../needs_index.html", relative: true %>
|
||||||
|
|
||||||
absolute spaces: <%= link_to "Spaces Index", "/evil spaces.html", relative: true %>
|
|
||||||
relative spaces: <%= link_to "Spaces Relative", "../evil spaces.html", relative: true %>
|
|
||||||
"""
|
"""
|
||||||
And the Server is running at "indexable-app"
|
And the Server is running at "indexable-app"
|
||||||
When I go to "/link_to.html"
|
When I go to "/link_to.html"
|
||||||
Then I should see 'absolute: <a href="needs_index.html">Needs Index</a>'
|
Then I should see 'absolute: <a href="needs_index.html">Needs Index</a>'
|
||||||
Then I should see 'relative: <a href="needs_index.html">Relative</a>'
|
Then I should see 'relative: <a href="needs_index.html">Relative</a>'
|
||||||
Then I should see 'absolute spaces: <a href="evil%20spaces.html">Spaces Index</a>'
|
|
||||||
Then I should see 'relative spaces: <a href="evil%20spaces.html">Spaces Relative</a>'
|
|
||||||
When I go to "/link_to/sub.html"
|
When I go to "/link_to/sub.html"
|
||||||
Then I should see 'absolute: <a href="../needs_index.html">Needs Index</a>'
|
Then I should see 'absolute: <a href="../needs_index.html">Needs Index</a>'
|
||||||
Then I should see 'relative: <a href="../needs_index.html">Relative</a>'
|
Then I should see 'relative: <a href="../needs_index.html">Relative</a>'
|
||||||
Then I should see 'absolute spaces: <a href="../evil%20spaces.html">Spaces Index</a>'
|
|
||||||
Then I should see 'relative spaces: <a href="../evil%20spaces.html">Spaces Relative</a>'
|
|
||||||
|
|
||||||
Scenario: link_to relative works with strip_index_file
|
Scenario: link_to relative works with strip_index_file
|
||||||
Given a fixture app "indexable-app"
|
Given a fixture app "indexable-app"
|
||||||
|
|
|
@ -50,24 +50,24 @@ Feature: i18n Paths
|
||||||
Given the Server is running at "empty-app"
|
Given the Server is running at "empty-app"
|
||||||
When I go to "/hello.html"
|
When I go to "/hello.html"
|
||||||
Then I should see "Page: Hello"
|
Then I should see "Page: Hello"
|
||||||
Then I should see '<a href="/index.html" class="current">Current Home</a>'
|
Then I should see '<a class="current" href="/index.html">Current Home</a>'
|
||||||
Then I should see '<a href="/es/index.html" title="Other Home">Other Home</a>'
|
Then I should see '<a title="Other Home" href="/es/index.html">Other Home</a>'
|
||||||
Then I should see '<a href="/index.html" class="current"><span>Home: Current Block</span></a>'
|
Then I should see '<a class="current" href="/index.html"><span>Home: Current Block</span></a>'
|
||||||
Then I should see '<a href="/es/index.html" title="Other Home"><span>Home: Other Block</span></a>'
|
Then I should see '<a title="Other Home" href="/es/index.html"><span>Home: Other Block</span></a>'
|
||||||
Then I should see '<a href="/hello.html" class="current">Current hello.html</a>'
|
Then I should see '<a class="current" href="/hello.html">Current hello.html</a>'
|
||||||
Then I should see '<a href="/es/hola.html" title="Other hello.html">Other hello.html</a>'
|
Then I should see '<a title="Other hello.html" href="/es/hola.html">Other hello.html</a>'
|
||||||
Then I should see '<a href="/hello.html" class="current"><span>Current Block</span></a>'
|
Then I should see '<a class="current" href="/hello.html"><span>Current Block</span></a>'
|
||||||
Then I should see '<a href="/es/hola.html" title="Other hello.html"><span>Other Block</span></a>'
|
Then I should see '<a title="Other hello.html" href="/es/hola.html"><span>Other Block</span></a>'
|
||||||
When I go to "/es/hola.html"
|
When I go to "/es/hola.html"
|
||||||
Then I should see "Page: Hola"
|
Then I should see "Page: Hola"
|
||||||
Then I should see '<a href="/es/index.html" class="current">Current Home</a>'
|
Then I should see '<a class="current" href="/es/index.html">Current Home</a>'
|
||||||
Then I should see '<a href="/index.html" title="Other Home">Other Home</a>'
|
Then I should see '<a title="Other Home" href="/index.html">Other Home</a>'
|
||||||
Then I should see '<a href="/es/index.html" class="current"><span>Home: Current Block</span></a>'
|
Then I should see '<a class="current" href="/es/index.html"><span>Home: Current Block</span></a>'
|
||||||
Then I should see '<a href="/index.html" title="Other Home"><span>Home: Other Block</span></a>'
|
Then I should see '<a title="Other Home" href="/index.html"><span>Home: Other Block</span></a>'
|
||||||
Then I should see '<a href="/es/hola.html" class="current">Current hello.html</a>'
|
Then I should see '<a class="current" href="/es/hola.html">Current hello.html</a>'
|
||||||
Then I should see '<a href="/hello.html" title="Other hello.html">Other hello.html</a>'
|
Then I should see '<a title="Other hello.html" href="/hello.html">Other hello.html</a>'
|
||||||
Then I should see '<a href="/es/hola.html" class="current"><span>Current Block</span></a>'
|
Then I should see '<a class="current" href="/es/hola.html"><span>Current Block</span></a>'
|
||||||
Then I should see '<a href="/hello.html" title="Other hello.html"><span>Other Block</span></a>'
|
Then I should see '<a title="Other hello.html" href="/hello.html"><span>Other Block</span></a>'
|
||||||
|
|
||||||
Scenario: link_to is i18n aware and supports relative_links
|
Scenario: link_to is i18n aware and supports relative_links
|
||||||
Given a fixture app "empty-app"
|
Given a fixture app "empty-app"
|
||||||
|
@ -124,24 +124,24 @@ Feature: i18n Paths
|
||||||
Then I should see "assets/css/main.css"
|
Then I should see "assets/css/main.css"
|
||||||
When I go to "/hello.html"
|
When I go to "/hello.html"
|
||||||
Then I should see "Page: Hello"
|
Then I should see "Page: Hello"
|
||||||
Then I should see '<a href="index.html" class="current">Current Home</a>'
|
Then I should see '<a class="current" href="index.html">Current Home</a>'
|
||||||
Then I should see '<a href="es/index.html" title="Other Home">Other Home</a>'
|
Then I should see '<a title="Other Home" href="es/index.html">Other Home</a>'
|
||||||
Then I should see '<a href="index.html" class="current"><span>Home: Current Block</span></a>'
|
Then I should see '<a class="current" href="index.html"><span>Home: Current Block</span></a>'
|
||||||
Then I should see '<a href="es/index.html" title="Other Home"><span>Home: Other Block</span></a>'
|
Then I should see '<a title="Other Home" href="es/index.html"><span>Home: Other Block</span></a>'
|
||||||
Then I should see '<a href="hello.html" class="current">Current hello.html</a>'
|
Then I should see '<a class="current" href="hello.html">Current hello.html</a>'
|
||||||
Then I should see '<a href="es/hola.html" title="Other hello.html">Other hello.html</a>'
|
Then I should see '<a title="Other hello.html" href="es/hola.html">Other hello.html</a>'
|
||||||
Then I should see '<a href="hello.html" class="current"><span>Current Block</span></a>'
|
Then I should see '<a class="current" href="hello.html"><span>Current Block</span></a>'
|
||||||
Then I should see '<a href="es/hola.html" title="Other hello.html"><span>Other Block</span></a>'
|
Then I should see '<a title="Other hello.html" href="es/hola.html"><span>Other Block</span></a>'
|
||||||
When I go to "/es/hola.html"
|
When I go to "/es/hola.html"
|
||||||
Then I should see "Page: Hola"
|
Then I should see "Page: Hola"
|
||||||
Then I should see '<a href="index.html" class="current">Current Home</a>'
|
Then I should see '<a class="current" href="index.html">Current Home</a>'
|
||||||
Then I should see '<a href="../index.html" title="Other Home">Other Home</a>'
|
Then I should see '<a title="Other Home" href="../index.html">Other Home</a>'
|
||||||
Then I should see '<a href="index.html" class="current"><span>Home: Current Block</span></a>'
|
Then I should see '<a class="current" href="index.html"><span>Home: Current Block</span></a>'
|
||||||
Then I should see '<a href="../index.html" title="Other Home"><span>Home: Other Block</span></a>'
|
Then I should see '<a title="Other Home" href="../index.html"><span>Home: Other Block</span></a>'
|
||||||
Then I should see '<a href="hola.html" class="current">Current hello.html</a>'
|
Then I should see '<a class="current" href="hola.html">Current hello.html</a>'
|
||||||
Then I should see '<a href="../hello.html" title="Other hello.html">Other hello.html</a>'
|
Then I should see '<a title="Other hello.html" href="../hello.html">Other hello.html</a>'
|
||||||
Then I should see '<a href="hola.html" class="current"><span>Current Block</span></a>'
|
Then I should see '<a class="current" href="hola.html"><span>Current Block</span></a>'
|
||||||
Then I should see '<a href="../hello.html" title="Other hello.html"><span>Other Block</span></a>'
|
Then I should see '<a title="Other hello.html" href="../hello.html"><span>Other Block</span></a>'
|
||||||
|
|
||||||
Scenario: url_for is i18n aware
|
Scenario: url_for is i18n aware
|
||||||
Given a fixture app "empty-app"
|
Given a fixture app "empty-app"
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
Feature: Markdown support in Slim
|
|
||||||
In order to test support of the Slim markdown filter
|
|
||||||
|
|
||||||
Scenario: Markdown filter in Slim works
|
|
||||||
Given a fixture app "markdown-in-slim-app"
|
|
||||||
And a file named "config.rb" with:
|
|
||||||
"""
|
|
||||||
set :markdown_engine, :redcarpet
|
|
||||||
activate :directory_indexes
|
|
||||||
"""
|
|
||||||
And a file named "source/markdown_filter.html.slim" with:
|
|
||||||
"""
|
|
||||||
markdown:
|
|
||||||
# H1
|
|
||||||
|
|
||||||
paragraph
|
|
||||||
"""
|
|
||||||
Given the Server is running at "markdown-in-slim-app"
|
|
||||||
When I go to "/markdown_filter/"
|
|
||||||
Then I should see ">H1</h1>"
|
|
||||||
Then I should see "<p>paragraph</p>"
|
|
||||||
|
|
||||||
|
|
||||||
Scenario: Markdown filter in Slim uses our link_to and image_tag helpers
|
|
||||||
Given a fixture app "markdown-in-slim-app"
|
|
||||||
And a file named "config.rb" with:
|
|
||||||
"""
|
|
||||||
set :markdown_engine, :redcarpet
|
|
||||||
activate :directory_indexes
|
|
||||||
"""
|
|
||||||
And a file named "source/link_and_image.html.slim" with:
|
|
||||||
"""
|
|
||||||
markdown:
|
|
||||||
[A link](/link_target.html)
|
|
||||||
|
|
||||||

|
|
||||||
"""
|
|
||||||
Given the Server is running at "markdown-in-slim-app"
|
|
||||||
When I go to "/link_and_image/"
|
|
||||||
Then I should see "/link_target/"
|
|
||||||
Then I should see 'src="/images/blank.gif"'
|
|
|
@ -1,65 +0,0 @@
|
||||||
Feature: Support Rack apps mounted using map
|
|
||||||
|
|
||||||
Scenario: Mounted Rack App at /sinatra
|
|
||||||
Given the Server is running at "sinatra-app"
|
|
||||||
When I go to "/"
|
|
||||||
Then I should see "Hello World (Middleman)"
|
|
||||||
When I go to "/sinatra/"
|
|
||||||
Then I should see "Hello World (Sinatra)"
|
|
||||||
|
|
||||||
Scenario: Built Mounted Rack App at /sinatra
|
|
||||||
Given a successfully built app at "sinatra-app"
|
|
||||||
When I cd to "build"
|
|
||||||
Then the following files should exist:
|
|
||||||
| index.html |
|
|
||||||
Then the following files should not exist:
|
|
||||||
| sinatra/index.html |
|
|
||||||
| sinatra/index2.html |
|
|
||||||
|
|
||||||
Scenario: Static Ruby Endpoints
|
|
||||||
Given a fixture app "sinatra-app"
|
|
||||||
And a file named "config.rb" with:
|
|
||||||
"""
|
|
||||||
endpoint "hello.html" do
|
|
||||||
"world"
|
|
||||||
end
|
|
||||||
"""
|
|
||||||
And the Server is running at "sinatra-app"
|
|
||||||
When I go to "/hello.html"
|
|
||||||
Then I should see "world"
|
|
||||||
|
|
||||||
Scenario: Built Mounted Rack App at /sinatra (including rack endpoints)
|
|
||||||
Given a fixture app "sinatra-app"
|
|
||||||
And a file named "config.rb" with:
|
|
||||||
"""
|
|
||||||
require "sinatra"
|
|
||||||
|
|
||||||
class MySinatra < Sinatra::Base
|
|
||||||
get "/" do
|
|
||||||
"Hello World (Sinatra)"
|
|
||||||
end
|
|
||||||
get "/derp.html" do
|
|
||||||
"De doo"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
map "/sinatra" do
|
|
||||||
run MySinatra
|
|
||||||
end
|
|
||||||
|
|
||||||
endpoint "sinatra/index2.html", path: "/sinatra/"
|
|
||||||
|
|
||||||
endpoint "dedoo.html", path: "/sinatra/derp.html"
|
|
||||||
|
|
||||||
endpoint "hello.html" do
|
|
||||||
"world"
|
|
||||||
end
|
|
||||||
"""
|
|
||||||
And a successfully built app at "sinatra-app"
|
|
||||||
When I cd to "build"
|
|
||||||
Then the following files should exist:
|
|
||||||
| index.html |
|
|
||||||
| sinatra/index2.html |
|
|
||||||
| dedoo.html |
|
|
||||||
And the file "sinatra/index2.html" should contain 'Hello World (Sinatra)'
|
|
||||||
And the file "dedoo.html" should contain 'De doo'
|
|
|
@ -3,60 +3,14 @@ Feature: Page IDs
|
||||||
Scenario: link_to works with blocks (erb)
|
Scenario: link_to works with blocks (erb)
|
||||||
Given the Server is running at "page-id-app"
|
Given the Server is running at "page-id-app"
|
||||||
When I go to "/index.html"
|
When I go to "/index.html"
|
||||||
Then I should see "I am: index"
|
Then I should see "I am: index.html"
|
||||||
And I should see "URL1: /fm.html"
|
And I should see "URL1: /fm.html"
|
||||||
And I should see "URL2: /2.html"
|
And I should see "URL2: /2.html"
|
||||||
And I should see 'URL3: <a href="/3.html">Hi</a>'
|
And I should see 'URL3: <a href="/3.html">Hi</a>'
|
||||||
And I should see 'URL4: <a href="/overwrites/from-default.html">Sym</a>'
|
And I should see 'URL4: <a href="/overwrites/from-default.html">Sym</a>'
|
||||||
And I should see 'URL5: <a href="/implicit.html">Imp</a>'
|
|
||||||
And I should see 'URL6: <a href="/folder/foldern.html">Foldern</a>'
|
|
||||||
And I should see 'URL7: <a href="/feed.xml">Feed</a>'
|
|
||||||
|
|
||||||
When I go to "/fm.html"
|
When I go to "/fm.html"
|
||||||
Then I should see "I am: frontmatter"
|
Then I should see "I am: frontmatter"
|
||||||
When I go to "/implicit.html"
|
|
||||||
Then I should see "I am: implicit"
|
|
||||||
When I go to "/feed.xml"
|
|
||||||
Then I should see "I am: feed.xml"
|
|
||||||
When I go to "/folder/foldern.html"
|
|
||||||
Then I should see "I am: folder/foldern"
|
|
||||||
|
|
||||||
When I go to "/1.html"
|
|
||||||
Then I should see "I am: page1"
|
|
||||||
When I go to "/2.html"
|
|
||||||
Then I should see "I am: page2"
|
|
||||||
When I go to "/3.html"
|
|
||||||
Then I should see "I am: page3"
|
|
||||||
|
|
||||||
When I go to "/overwrites/from-default.html"
|
|
||||||
Then I should see "I am: something-else"
|
|
||||||
|
|
||||||
When I go to "/overwrites/from-frontmatter.html"
|
|
||||||
Then I should see "I am: from_frontmatter"
|
|
||||||
|
|
||||||
Scenario: Override page ID derivation with a proc
|
|
||||||
Given a fixture app "page-id-app"
|
|
||||||
And app "page-id-app" is using config "proc"
|
|
||||||
And the Server is running at "page-id-app"
|
|
||||||
|
|
||||||
When I go to "/index.html"
|
|
||||||
Then I should see "I am: index.html-foo"
|
|
||||||
And I should see "URL1: /fm.html"
|
|
||||||
And I should see "URL2: /2.html"
|
|
||||||
And I should see 'URL3: <a href="/3.html">Hi</a>'
|
|
||||||
And I should see 'URL4: <a href="/overwrites/from-default.html">Sym</a>'
|
|
||||||
And I should see 'URL8: <a href="/implicit.html">Imp</a>'
|
|
||||||
And I should see 'URL9: <a href="/folder/foldern.html">Foldern</a>'
|
|
||||||
And I should see 'URL10: <a href="/feed.xml">Feed</a>'
|
|
||||||
|
|
||||||
When I go to "/fm.html"
|
|
||||||
Then I should see "I am: frontmatter"
|
|
||||||
When I go to "/implicit.html"
|
|
||||||
Then I should see "I am: implicit.html-foo"
|
|
||||||
When I go to "/feed.xml"
|
|
||||||
Then I should see "I am: feed.xml-foo"
|
|
||||||
When I go to "/folder/foldern.html"
|
|
||||||
Then I should see "I am: folder/foldern.html-foo"
|
|
||||||
|
|
||||||
When I go to "/1.html"
|
When I go to "/1.html"
|
||||||
Then I should see "I am: page1"
|
Then I should see "I am: page1"
|
||||||
|
|
|
@ -120,7 +120,7 @@ Feature: Relative Assets
|
||||||
"""
|
"""
|
||||||
And the Server is running at "relative-assets-app"
|
And the Server is running at "relative-assets-app"
|
||||||
When I go to "/sub/image_tag.html"
|
When I go to "/sub/image_tag.html"
|
||||||
Then I should see '<img src="../img/blank.gif"'
|
Then I should see '<img src="../img/blank.gif" />'
|
||||||
|
|
||||||
Scenario: Relative assets should not break data URIs in image_tag
|
Scenario: Relative assets should not break data URIs in image_tag
|
||||||
Given a fixture app "relative-assets-app"
|
Given a fixture app "relative-assets-app"
|
||||||
|
|
|
@ -72,7 +72,7 @@ Feature: Relative Assets (Helpers Only)
|
||||||
"""
|
"""
|
||||||
And the Server is running at "relative-assets-app"
|
And the Server is running at "relative-assets-app"
|
||||||
When I go to "/sub/image_tag.html"
|
When I go to "/sub/image_tag.html"
|
||||||
Then I should see '<img src="../img/blank.gif"'
|
Then I should see '<img src="../img/blank.gif" />'
|
||||||
|
|
||||||
Scenario: Relative assets should not break data URIs in image_tag
|
Scenario: Relative assets should not break data URIs in image_tag
|
||||||
Given a fixture app "relative-assets-app"
|
Given a fixture app "relative-assets-app"
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
Feature: Sass/SCSS support in Slim
|
|
||||||
In order to test support of the Slim sass and scss filters
|
|
||||||
|
|
||||||
Scenario: Sass filter in Slim works
|
|
||||||
Given a fixture app "sass-in-slim-app"
|
|
||||||
And a file named "config.rb" with:
|
|
||||||
"""
|
|
||||||
activate :directory_indexes
|
|
||||||
"""
|
|
||||||
And a file named "source/sass_filter.html.slim" with:
|
|
||||||
"""
|
|
||||||
sass:
|
|
||||||
.sass
|
|
||||||
margin: 0
|
|
||||||
"""
|
|
||||||
Given the Server is running at "sass-in-slim-app"
|
|
||||||
When I go to "/sass_filter/"
|
|
||||||
Then I should see "text/css"
|
|
||||||
Then I should see ".sass"
|
|
||||||
Then I should see "margin:0"
|
|
||||||
|
|
||||||
|
|
||||||
Scenario: SCSS filter in Slim works
|
|
||||||
Given a fixture app "sass-in-slim-app"
|
|
||||||
And a file named "config.rb" with:
|
|
||||||
"""
|
|
||||||
activate :directory_indexes
|
|
||||||
"""
|
|
||||||
And a file named "source/scss_filter.html.slim" with:
|
|
||||||
"""
|
|
||||||
scss:
|
|
||||||
.scss {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
Given the Server is running at "sass-in-slim-app"
|
|
||||||
When I go to "/scss_filter/"
|
|
||||||
Then I should see "text/css"
|
|
||||||
Then I should see ".scss"
|
|
||||||
Then I should see "margin:0"
|
|
|
@ -1,7 +0,0 @@
|
||||||
|
|
||||||
activate :asset_hash,
|
|
||||||
prefix: "myprefix-"
|
|
||||||
|
|
||||||
activate :relative_assets
|
|
||||||
|
|
||||||
activate :directory_indexes
|
|
|
@ -1,16 +0,0 @@
|
||||||
class Middleware
|
|
||||||
def initialize(app)
|
|
||||||
@app = app
|
|
||||||
end
|
|
||||||
|
|
||||||
def call(env)
|
|
||||||
status, headers, response = @app.call(env)
|
|
||||||
body = ''
|
|
||||||
response.each {|part| body += part }
|
|
||||||
if (env["PATH_INFO"] =~ /css$/)
|
|
||||||
body += "\n/* Added by Rack filter */"
|
|
||||||
status, headers, response = Rack::Response.new(body, status, headers).finish
|
|
||||||
end
|
|
||||||
[status, headers, response]
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,6 +0,0 @@
|
||||||
<% content_for :head do %>
|
|
||||||
<title>The Middleman!</title>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<h1>Testing the sitemap hashing</h1>
|
|
||||||
<br /><br /><br />
|
|
|
@ -1,2 +0,0 @@
|
||||||
function foo(){var message="HEY THERE FRIEND!";var para=document.createElement("p");para.innerHTML=message;var body=document.getElementsByTagName("body")[0];body.insertBefore(para,body.firstChild)}window.onload=foo;
|
|
||||||
//# sourceMappingURL=application.js.map
|
|
|
@ -1 +0,0 @@
|
||||||
{"version":3,"sources":["source/javascripts/application.js"],"names":["foo","message","para","document","createElement","innerHTML","body","getElementsByTagName","insertBefore","firstChild","window","onload"],"mappings":"AAAA,QAASA,OACP,GAAIC,SAAU,mBACd,IAAIC,MAAOC,SAASC,cAAc,IAClCF,MAAKG,UAAYJ,OACb,IAAIK,MAAOH,SAASI,qBAAqB,QAAQ,EAC/CD,MAAKE,aAAaN,KAAMI,KAAKG,YAGpCC,OAAOC,OAASX"}
|
|
|
@ -1,17 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
|
|
||||||
<%= javascript_include_tag "application" %>
|
|
||||||
<%= yield_content :head %>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body class="<%= page_classes %>">
|
|
||||||
|
|
||||||
<div id="main" role="main">
|
|
||||||
<%= yield %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,7 +0,0 @@
|
||||||
%w(1 2 3).each do |n|
|
|
||||||
proxy "/#{n}.html", "/index.html", id: "page#{n}"
|
|
||||||
end
|
|
||||||
|
|
||||||
page "/overwrites/*", id: :"something-else"
|
|
||||||
|
|
||||||
config[:page_id_generator] = ->(path){ path + "-foo" }
|
|
|
@ -1 +0,0 @@
|
||||||
I am: <%= current_resource.page_id %>
|
|
|
@ -1 +0,0 @@
|
||||||
I am: <%= current_resource.page_id %>
|
|
|
@ -1 +0,0 @@
|
||||||
I am: <%= current_resource.page_id %>
|
|
|
@ -4,11 +4,3 @@ URL1: <%= url_for "frontmatter" %>
|
||||||
URL2: <%= url_for "page2" %>
|
URL2: <%= url_for "page2" %>
|
||||||
URL3: <%= link_to "Hi", "page3" %>
|
URL3: <%= link_to "Hi", "page3" %>
|
||||||
URL4: <%= link_to "Sym", :"something-else" %>
|
URL4: <%= link_to "Sym", :"something-else" %>
|
||||||
URL5: <%= link_to "Imp", :implicit %>
|
|
||||||
URL6: <%= link_to "Foldern", "folder/foldern" %>
|
|
||||||
URL7: <%= link_to "Feed", "feed.xml" %>
|
|
||||||
|
|
||||||
<%# If custom proc %>
|
|
||||||
URL8: <%= link_to "Imp", "implicit.html-foo" %>
|
|
||||||
URL9: <%= link_to "Foldern", "folder/foldern.html-foo" %>
|
|
||||||
URL10: <%= link_to "Feed", "feed.xml-foo" %>
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
require "sinatra"
|
|
||||||
|
|
||||||
class MySinatra < Sinatra::Base
|
|
||||||
get "/" do
|
|
||||||
"Hello World (Sinatra)"
|
|
||||||
end
|
|
||||||
get "/derp.html" do
|
|
||||||
"De doo"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
map "/sinatra" do
|
|
||||||
run MySinatra
|
|
||||||
end
|
|
|
@ -1,5 +0,0 @@
|
||||||
---
|
|
||||||
layout: false
|
|
||||||
---
|
|
||||||
|
|
||||||
Hello World (Middleman)
|
|
|
@ -157,12 +157,12 @@ module Middleman
|
||||||
define_setting :layout, :_auto_layout, 'Default layout name'
|
define_setting :layout, :_auto_layout, 'Default layout name'
|
||||||
|
|
||||||
# Which file extensions have a layout by default.
|
# Which file extensions have a layout by default.
|
||||||
# @return [Array.<String>]
|
# @return [Set.<String>]
|
||||||
define_setting :extensions_with_layout, %w(.htm .html .xhtml .php), 'Which file extensions have a layout by default.'
|
define_setting :extensions_with_layout, %w(.htm .html .xhtml .php), 'Which file extensions have a layout by default.', set: true
|
||||||
|
|
||||||
# Which file extensions are "assets."
|
# Which file extensions are "assets."
|
||||||
# @return [Array.<String>]
|
# @return [Array.<String>]
|
||||||
define_setting :asset_extensions, %w(.css .png .jpg .jpeg .webp .svg .svgz .js .gif .ttf .otf .woff .woff2 .eot .ico .map), 'Which file extensions are treated as assets.'
|
define_setting :asset_extensions, %w(.css .png .jpg .jpeg .webp .svg .svgz .js .gif .ttf .otf .woff .woff2 .eot .ico .map), 'Which file extensions are treated as assets.', set: true
|
||||||
|
|
||||||
# Default string encoding for templates and output.
|
# Default string encoding for templates and output.
|
||||||
# @return [String]
|
# @return [String]
|
||||||
|
@ -203,7 +203,6 @@ module Middleman
|
||||||
define_setting :watcher_disable, false, 'If the Listen watcher should not run'
|
define_setting :watcher_disable, false, 'If the Listen watcher should not run'
|
||||||
define_setting :watcher_force_polling, false, 'If the Listen watcher should run in polling mode'
|
define_setting :watcher_force_polling, false, 'If the Listen watcher should run in polling mode'
|
||||||
define_setting :watcher_latency, nil, 'The Listen watcher latency'
|
define_setting :watcher_latency, nil, 'The Listen watcher latency'
|
||||||
define_setting :watcher_wait_for_delay, 0.5, 'The Listen watcher delay between calls when changes exist'
|
|
||||||
|
|
||||||
# Delegate convenience methods off to their implementations
|
# Delegate convenience methods off to their implementations
|
||||||
def_delegator :"::Middleman::Logger", :singleton, :logger
|
def_delegator :"::Middleman::Logger", :singleton, :logger
|
||||||
|
@ -267,8 +266,6 @@ module Middleman
|
||||||
# Evaluate a passed block if given
|
# Evaluate a passed block if given
|
||||||
config_context.instance_exec(&block) if block_given?
|
config_context.instance_exec(&block) if block_given?
|
||||||
|
|
||||||
apply_cli_options
|
|
||||||
|
|
||||||
execute_callbacks(:before_sitemap)
|
execute_callbacks(:before_sitemap)
|
||||||
|
|
||||||
# Initialize the Sitemap
|
# Initialize the Sitemap
|
||||||
|
@ -279,6 +276,8 @@ module Middleman
|
||||||
# Before config is parsed, before extensions get to it.
|
# Before config is parsed, before extensions get to it.
|
||||||
execute_callbacks(:initialized)
|
execute_callbacks(:initialized)
|
||||||
|
|
||||||
|
apply_cli_options
|
||||||
|
|
||||||
# Before config is parsed. Mostly used for extensions.
|
# Before config is parsed. Mostly used for extensions.
|
||||||
execute_callbacks(:before_configuration)
|
execute_callbacks(:before_configuration)
|
||||||
|
|
||||||
|
@ -345,11 +344,11 @@ module Middleman
|
||||||
|
|
||||||
# Clean up missing Tilt exts
|
# Clean up missing Tilt exts
|
||||||
def prune_tilt_templates!
|
def prune_tilt_templates!
|
||||||
::Tilt.default_mapping.lazy_map.each_key do |key|
|
::Tilt.mappings.each_key do |key|
|
||||||
begin
|
begin
|
||||||
::Tilt[".#{key}"]
|
::Tilt[".#{key}"]
|
||||||
rescue LoadError, NameError
|
rescue LoadError, NameError
|
||||||
::Tilt.default_mapping.lazy_map.delete(key)
|
::Tilt.mappings.delete(key)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,6 @@ require 'pathname'
|
||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
require 'tempfile'
|
require 'tempfile'
|
||||||
require 'parallel'
|
require 'parallel'
|
||||||
require 'middleman-core/rack'
|
|
||||||
require 'middleman-core/callback_manager'
|
require 'middleman-core/callback_manager'
|
||||||
require 'middleman-core/contracts'
|
require 'middleman-core/contracts'
|
||||||
|
|
||||||
|
@ -39,9 +38,6 @@ module Middleman
|
||||||
@cleaning = opts.fetch(:clean)
|
@cleaning = opts.fetch(:clean)
|
||||||
@parallel = opts.fetch(:parallel, true)
|
@parallel = opts.fetch(:parallel, true)
|
||||||
|
|
||||||
rack_app = ::Middleman::Rack.new(@app).to_app
|
|
||||||
@rack = ::Rack::MockRequest.new(rack_app)
|
|
||||||
|
|
||||||
@callbacks = ::Middleman::CallbackManager.new
|
@callbacks = ::Middleman::CallbackManager.new
|
||||||
@callbacks.install_methods!(self, [:on_build_event])
|
@callbacks.install_methods!(self, [:on_build_event])
|
||||||
end
|
end
|
||||||
|
@ -227,15 +223,7 @@ module Middleman
|
||||||
if resource.binary?
|
if resource.binary?
|
||||||
export_file!(output_file, resource.file_descriptor[:full_path])
|
export_file!(output_file, resource.file_descriptor[:full_path])
|
||||||
else
|
else
|
||||||
response = @rack.get(::URI.escape(resource.request_path))
|
export_file!(output_file, binary_encode(resource.render))
|
||||||
|
|
||||||
# If we get a response, save it to a tempfile.
|
|
||||||
if response.status == 200
|
|
||||||
export_file!(output_file, binary_encode(response.body))
|
|
||||||
else
|
|
||||||
trigger(:error, output_file, response.body)
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
rescue => e
|
rescue => e
|
||||||
trigger(:error, output_file, "#{e}\n#{e.backtrace.join("\n")}")
|
trigger(:error, output_file, "#{e}\n#{e.backtrace.join("\n")}")
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
require 'set'
|
||||||
|
|
||||||
module Middleman
|
module Middleman
|
||||||
module Configuration
|
module Configuration
|
||||||
# A class that manages a collection of documented settings.
|
# A class that manages a collection of documented settings.
|
||||||
|
@ -129,23 +131,37 @@ module Middleman
|
||||||
|
|
||||||
def initialize(key, default, description, options={})
|
def initialize(key, default, description, options={})
|
||||||
@value_set = false
|
@value_set = false
|
||||||
|
@array_wrapped_value = nil
|
||||||
|
@array_wrapped_default = nil
|
||||||
self.key = key
|
self.key = key
|
||||||
self.default = default
|
self.default = default
|
||||||
self.description = description
|
self.description = description
|
||||||
self.options = options
|
self.options = options
|
||||||
|
|
||||||
|
@array_wrapped_default = if self.default && options[:set] && self.default.is_a?(Array)
|
||||||
|
Set.new(self.default)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# The user-supplied value for this setting, overriding the default
|
# The user-supplied value for this setting, overriding the default
|
||||||
def value=(value)
|
def value=(value)
|
||||||
@value = value
|
@value = value
|
||||||
@value_set = true
|
@value_set = true
|
||||||
|
|
||||||
|
@array_wrapped_value = if @value && options[:set] && @value.is_a?(Array)
|
||||||
|
Set.new(@value)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# The effective value of the setting, which may be the default
|
# The effective value of the setting, which may be the default
|
||||||
# if the user has not set a value themselves. Note that even if the
|
# if the user has not set a value themselves. Note that even if the
|
||||||
# user sets the value to nil it will override the default.
|
# user sets the value to nil it will override the default.
|
||||||
def value
|
def value
|
||||||
value_set? ? @value : default
|
if value_set?
|
||||||
|
@array_wrapped_value ? @array_wrapped_value : @value
|
||||||
|
else
|
||||||
|
@array_wrapped_default ? @array_wrapped_default : default
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Whether or not there has been a value set beyond the default
|
# Whether or not there has been a value set beyond the default
|
||||||
|
|
|
@ -19,12 +19,6 @@ Middleman::Extensions.register :data, auto_activate: :before_sitemap do
|
||||||
Middleman::CoreExtensions::Data
|
Middleman::CoreExtensions::Data
|
||||||
end
|
end
|
||||||
|
|
||||||
# Rewrite embedded URLs via Rack
|
|
||||||
Middleman::Extensions.register :inline_url_rewriter, auto_activate: :before_sitemap do
|
|
||||||
require 'middleman-core/core_extensions/inline_url_rewriter'
|
|
||||||
Middleman::CoreExtensions::InlineURLRewriter
|
|
||||||
end
|
|
||||||
|
|
||||||
# Catch and show exceptions at the Rack level
|
# Catch and show exceptions at the Rack level
|
||||||
Middleman::Extensions.register :show_exceptions, auto_activate: :before_configuration, modes: [:server] do
|
Middleman::Extensions.register :show_exceptions, auto_activate: :before_configuration, modes: [:server] do
|
||||||
require 'middleman-core/core_extensions/show_exceptions'
|
require 'middleman-core/core_extensions/show_exceptions'
|
||||||
|
|
|
@ -28,7 +28,10 @@ module Middleman
|
||||||
super
|
super
|
||||||
|
|
||||||
# Setup source collection.
|
# Setup source collection.
|
||||||
@sources = ::Middleman::Sources.new(app)
|
@sources = ::Middleman::Sources.new(app,
|
||||||
|
disable_watcher: app.config[:watcher_disable],
|
||||||
|
force_polling: app.config[:watcher_force_polling],
|
||||||
|
latency: app.config[:watcher_latency])
|
||||||
|
|
||||||
# Add default ignores.
|
# Add default ignores.
|
||||||
IGNORES.each do |key, value|
|
IGNORES.each do |key, value|
|
||||||
|
@ -52,13 +55,6 @@ module Middleman
|
||||||
# @return [void]
|
# @return [void]
|
||||||
Contract Any
|
Contract Any
|
||||||
def after_configuration
|
def after_configuration
|
||||||
@watcher.update_config(
|
|
||||||
disable_watcher: app.config[:watcher_disable],
|
|
||||||
force_polling: app.config[:watcher_force_polling],
|
|
||||||
latency: app.config[:watcher_latency],
|
|
||||||
wait_for_delay: app.config[:watcher_wait_for_delay]
|
|
||||||
)
|
|
||||||
|
|
||||||
if @original_source_dir != app.config[:source]
|
if @original_source_dir != app.config[:source]
|
||||||
@watcher.update_path(app.config[:source])
|
@watcher.update_path(app.config[:source])
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,135 +0,0 @@
|
||||||
require 'rack'
|
|
||||||
require 'rack/response'
|
|
||||||
require 'memoist'
|
|
||||||
require 'middleman-core/util'
|
|
||||||
require 'middleman-core/contracts'
|
|
||||||
|
|
||||||
module Middleman
|
|
||||||
module CoreExtensions
|
|
||||||
class InlineURLRewriter < ::Middleman::Extension
|
|
||||||
include Contracts
|
|
||||||
|
|
||||||
expose_to_application rewrite_inline_urls: :add
|
|
||||||
|
|
||||||
REWRITER_DESCRIPTOR = {
|
|
||||||
id: Symbol,
|
|
||||||
proc: Or[Proc, Method],
|
|
||||||
url_extensions: ArrayOf[String],
|
|
||||||
source_extensions: ArrayOf[String],
|
|
||||||
ignore: ArrayOf[::Middleman::Util::IGNORE_DESCRIPTOR],
|
|
||||||
after: Maybe[Symbol]
|
|
||||||
}.freeze
|
|
||||||
|
|
||||||
def initialize(app, options_hash={}, &block)
|
|
||||||
super
|
|
||||||
|
|
||||||
@rewriters = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
Contract REWRITER_DESCRIPTOR => Any
|
|
||||||
def add(options)
|
|
||||||
@rewriters[options] = options
|
|
||||||
end
|
|
||||||
|
|
||||||
def after_configuration
|
|
||||||
return if @rewriters.empty?
|
|
||||||
|
|
||||||
rewriters = @rewriters.values.sort do |a, b|
|
|
||||||
if b[:after] && b[:after] == a[:id]
|
|
||||||
1
|
|
||||||
else
|
|
||||||
0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
app.use Rack, rewriters: rewriters, middleman_app: @app
|
|
||||||
end
|
|
||||||
|
|
||||||
class Rack
|
|
||||||
extend Memoist
|
|
||||||
include Contracts
|
|
||||||
|
|
||||||
Contract RespondTo[:call], {
|
|
||||||
middleman_app: IsA['Middleman::Application'],
|
|
||||||
rewriters: ArrayOf[REWRITER_DESCRIPTOR]
|
|
||||||
} => Any
|
|
||||||
def initialize(app, options={})
|
|
||||||
@rack_app = app
|
|
||||||
@middleman_app = options.fetch(:middleman_app)
|
|
||||||
@rewriters = options.fetch(:rewriters)
|
|
||||||
|
|
||||||
all_source_exts = @rewriters
|
|
||||||
.reduce([]) { |sum, rewriter| sum + rewriter[:source_extensions] }
|
|
||||||
.flatten
|
|
||||||
.uniq
|
|
||||||
@source_exts_regex_text = Regexp.union(all_source_exts).to_s
|
|
||||||
|
|
||||||
@all_asset_exts = @rewriters
|
|
||||||
.reduce([]) { |sum, rewriter| sum + rewriter[:url_extensions] }
|
|
||||||
.flatten
|
|
||||||
.uniq
|
|
||||||
end
|
|
||||||
|
|
||||||
def call(env)
|
|
||||||
status, headers, response = @rack_app.call(env)
|
|
||||||
|
|
||||||
# Allow configuration or upstream request to skip all rewriting
|
|
||||||
return [status, headers, response] if env['bypass_inline_url_rewriter'] == 'true'
|
|
||||||
|
|
||||||
path = ::Middleman::Util.full_path(env['PATH_INFO'], @middleman_app)
|
|
||||||
|
|
||||||
return [status, headers, response] unless path =~ /(^\/$)|(#{@source_exts_regex_text}$)/
|
|
||||||
return [status, headers, response] unless body = ::Middleman::Util.extract_response_text(response)
|
|
||||||
|
|
||||||
dirpath = ::Pathname.new(File.dirname(path))
|
|
||||||
|
|
||||||
rewritten = ::Middleman::Util.instrument 'inline_url_rewriter', path: path do
|
|
||||||
::Middleman::Util.rewrite_paths(body, path, @all_asset_exts, @middleman_app) do |asset_path|
|
|
||||||
uri = ::Middleman::Util.parse_uri(asset_path)
|
|
||||||
|
|
||||||
relative_path = uri.host.nil?
|
|
||||||
|
|
||||||
full_asset_path = if relative_path
|
|
||||||
dirpath.join(asset_path).to_s
|
|
||||||
else
|
|
||||||
asset_path
|
|
||||||
end
|
|
||||||
|
|
||||||
@rewriters.each do |rewriter|
|
|
||||||
uid = rewriter.fetch(:id)
|
|
||||||
|
|
||||||
# Allow upstream request to skip this specific rewriting
|
|
||||||
next if env["bypass_inline_url_rewriter_#{uid}"] == 'true'
|
|
||||||
|
|
||||||
exts = rewriter.fetch(:url_extensions)
|
|
||||||
next unless exts.include?(::File.extname(asset_path))
|
|
||||||
|
|
||||||
source_exts = rewriter.fetch(:source_extensions)
|
|
||||||
next unless source_exts.include?(::File.extname(path))
|
|
||||||
|
|
||||||
ignore = rewriter.fetch(:ignore)
|
|
||||||
next if ignore.any? { |r| ::Middleman::Util.should_ignore?(r, full_asset_path) }
|
|
||||||
|
|
||||||
rewrite_ignore = Array(rewriter[:rewrite_ignore] || [])
|
|
||||||
next if rewrite_ignore.any? { |i| ::Middleman::Util.path_match(i, path) }
|
|
||||||
|
|
||||||
proc = rewriter.fetch(:proc)
|
|
||||||
|
|
||||||
result = proc.call(asset_path, dirpath, path)
|
|
||||||
asset_path = result if result
|
|
||||||
end
|
|
||||||
|
|
||||||
asset_path
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
::Rack::Response.new(
|
|
||||||
rewritten,
|
|
||||||
status,
|
|
||||||
headers
|
|
||||||
).finish
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -60,7 +60,7 @@ module Middleman
|
||||||
# There are also some less common hooks that can be listened to from within an extension's `initialize` method:
|
# There are also some less common hooks that can be listened to from within an extension's `initialize` method:
|
||||||
#
|
#
|
||||||
# * `app.before_render {|body, path, locs, template_class| ... }` - Manipulate template sources before they are rendered.
|
# * `app.before_render {|body, path, locs, template_class| ... }` - Manipulate template sources before they are rendered.
|
||||||
# * `app.after_render {|content, path, locs, template_class| ... }` - Manipulate output text after a template has been rendered. It is also common to install a Rack middleware to do this instead.
|
# * `app.after_render {|content, path, locs, template_class| ... }` - Manipulate output text after a template has been rendered.
|
||||||
# * `app.ready { ... }` - Run code once Middleman is ready to serve or build files (after `after_configuration`).
|
# * `app.ready { ... }` - Run code once Middleman is ready to serve or build files (after `after_configuration`).
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,19 +1,15 @@
|
||||||
require 'middleman-core/util'
|
require 'middleman-core/util'
|
||||||
require 'middleman-core/rack'
|
|
||||||
|
|
||||||
class Middleman::Extensions::AssetHash < ::Middleman::Extension
|
class Middleman::Extensions::AssetHash < ::Middleman::Extension
|
||||||
option :sources, %w(.css .htm .html .js .php .xhtml), 'List of extensions that are searched for hashable assets.'
|
option :sources, %w(.css .htm .html .js .php .xhtml), 'List of extensions that are searched for hashable assets.', set: true
|
||||||
option :exts, nil, 'List of extensions that get asset hashes appended to them.'
|
option :exts, nil, 'List of extensions that get asset hashes appended to them.', set: true
|
||||||
option :ignore, [], 'Regexes of filenames to skip adding asset hashes to'
|
option :ignore, [], 'Regexes of filenames to skip adding asset hashes to'
|
||||||
option :rewrite_ignore, [], 'Regexes of filenames to skip processing for path rewrites'
|
option :rewrite_ignore, [], 'Regexes of filenames to skip processing for path rewrites'
|
||||||
option :prefix, '', 'Prefix for hash'
|
|
||||||
|
|
||||||
def initialize(app, options_hash={}, &block)
|
def initialize(app, options_hash={}, &block)
|
||||||
super
|
super
|
||||||
|
|
||||||
require 'addressable/uri'
|
|
||||||
require 'digest/sha1'
|
require 'digest/sha1'
|
||||||
require 'rack/mock'
|
|
||||||
|
|
||||||
# Allow specifying regexes to ignore, plus always ignore apple touch icons
|
# Allow specifying regexes to ignore, plus always ignore apple touch icons
|
||||||
@ignore = Array(options.ignore) + [/^apple-touch-icon/]
|
@ignore = Array(options.ignore) + [/^apple-touch-icon/]
|
||||||
|
@ -21,14 +17,6 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension
|
||||||
# Exclude .ico from the default list because browsers expect it
|
# Exclude .ico from the default list because browsers expect it
|
||||||
# to be named "favicon.ico"
|
# to be named "favicon.ico"
|
||||||
@exts = options.exts || (app.config[:asset_extensions] - %w(.ico))
|
@exts = options.exts || (app.config[:asset_extensions] - %w(.ico))
|
||||||
|
|
||||||
app.rewrite_inline_urls id: :asset_hash,
|
|
||||||
url_extensions: @exts.sort.reverse,
|
|
||||||
source_extensions: options.sources,
|
|
||||||
ignore: @ignore,
|
|
||||||
rewrite_ignore: options.rewrite_ignore,
|
|
||||||
proc: method(:rewrite_url),
|
|
||||||
after: :asset_host
|
|
||||||
end
|
end
|
||||||
|
|
||||||
Contract String, Or[String, Pathname], Any => Maybe[String]
|
Contract String, Or[String, Pathname], Any => Maybe[String]
|
||||||
|
@ -46,7 +34,6 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension
|
||||||
|
|
||||||
replacement_path = "/#{asset_page.destination_path}"
|
replacement_path = "/#{asset_page.destination_path}"
|
||||||
replacement_path = Pathname.new(replacement_path).relative_path_from(dirpath).to_s if relative_path
|
replacement_path = Pathname.new(replacement_path).relative_path_from(dirpath).to_s if relative_path
|
||||||
|
|
||||||
replacement_path
|
replacement_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -54,9 +41,18 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension
|
||||||
# @return Array<Middleman::Sitemap::Resource>
|
# @return Array<Middleman::Sitemap::Resource>
|
||||||
Contract ResourceList => ResourceList
|
Contract ResourceList => ResourceList
|
||||||
def manipulate_resource_list(resources)
|
def manipulate_resource_list(resources)
|
||||||
@rack_client ||= begin
|
resources.each do |r|
|
||||||
rack_app = ::Middleman::Rack.new(app).to_app
|
next unless r.destination_path.end_with?('/', *options.sources)
|
||||||
::Rack::MockRequest.new(rack_app)
|
next if Array(options.rewrite_ignore || []).any? do |i|
|
||||||
|
::Middleman::Util.path_match(i, "/#{r.destination_path}")
|
||||||
|
end
|
||||||
|
|
||||||
|
r.filters << ::Middleman::InlineURLRewriter.new(:asset_hash,
|
||||||
|
app,
|
||||||
|
r,
|
||||||
|
url_extensions: @exts,
|
||||||
|
ignore: options.ignore,
|
||||||
|
proc: method(:rewrite_url))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Process resources in order: binary images and fonts, then SVG, then JS/CSS.
|
# Process resources in order: binary images and fonts, then SVG, then JS/CSS.
|
||||||
|
@ -82,18 +78,12 @@ class Middleman::Extensions::AssetHash < ::Middleman::Extension
|
||||||
digest = if resource.binary?
|
digest = if resource.binary?
|
||||||
::Digest::SHA1.file(resource.source_file).hexdigest[0..7]
|
::Digest::SHA1.file(resource.source_file).hexdigest[0..7]
|
||||||
else
|
else
|
||||||
# Render through the Rack interface so middleware and mounted apps get a shot
|
# Render without asset hash
|
||||||
response = @rack_client.get(
|
body = resource.render { |f| !f.respond_to?(:filter_name) || f.filter_name != :asset_hash }
|
||||||
::URI.escape(resource.destination_path),
|
::Digest::SHA1.hexdigest(body)[0..7]
|
||||||
'bypass_inline_url_rewriter_asset_hash' => 'true'
|
|
||||||
)
|
|
||||||
|
|
||||||
raise "#{resource.path} should be in the sitemap!" unless response.status == 200
|
|
||||||
|
|
||||||
::Digest::SHA1.hexdigest(response.body)[0..7]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
resource.destination_path = resource.destination_path.sub(/\.(\w+)$/) { |ext| "-#{options.prefix}#{digest}#{ext}" }
|
resource.destination_path = resource.destination_path.sub(/\.(\w+)$/) { |ext| "-#{digest}#{ext}" }
|
||||||
resource
|
resource
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
require 'addressable/uri'
|
|
||||||
|
|
||||||
class Middleman::Extensions::AssetHost < ::Middleman::Extension
|
class Middleman::Extensions::AssetHost < ::Middleman::Extension
|
||||||
option :host, nil, 'The asset host to use or a Proc to determine asset host', required: true
|
option :host, nil, 'The asset host to use or a Proc to determine asset host', required: true
|
||||||
option :exts, nil, 'List of extensions that get cache busters strings appended to them.'
|
option :exts, nil, 'List of extensions that get cache busters strings appended to them.'
|
||||||
|
@ -7,15 +5,22 @@ class Middleman::Extensions::AssetHost < ::Middleman::Extension
|
||||||
option :ignore, [], 'Regexes of filenames to skip adding query strings to'
|
option :ignore, [], 'Regexes of filenames to skip adding query strings to'
|
||||||
option :rewrite_ignore, [], 'Regexes of filenames to skip processing for host rewrites'
|
option :rewrite_ignore, [], 'Regexes of filenames to skip processing for host rewrites'
|
||||||
|
|
||||||
def initialize(app, options_hash={}, &block)
|
Contract ResourceList => ResourceList
|
||||||
super
|
def manipulate_resource_list(resources)
|
||||||
|
resources.each do |r|
|
||||||
|
next unless r.destination_path.end_with?('/', *options.sources)
|
||||||
|
next if Array(options.rewrite_ignore || []).any? do |i|
|
||||||
|
::Middleman::Util.path_match(i, "/#{r.destination_path}")
|
||||||
|
end
|
||||||
|
|
||||||
app.rewrite_inline_urls id: :asset_host,
|
r.filters << ::Middleman::InlineURLRewriter.new(:asset_host,
|
||||||
|
app,
|
||||||
|
r,
|
||||||
|
after_filter: :asset_hash,
|
||||||
url_extensions: options.exts || app.config[:asset_extensions],
|
url_extensions: options.exts || app.config[:asset_extensions],
|
||||||
source_extensions: options.sources,
|
|
||||||
ignore: options.ignore,
|
ignore: options.ignore,
|
||||||
rewrite_ignore: options.rewrite_ignore,
|
proc: method(:rewrite_url))
|
||||||
proc: method(:rewrite_url)
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Contract String, Or[String, Pathname], Any => String
|
Contract String, Or[String, Pathname], Any => String
|
||||||
|
|
|
@ -1,19 +1,25 @@
|
||||||
# The Cache Buster extension
|
# The Cache Buster extension
|
||||||
class Middleman::Extensions::CacheBuster < ::Middleman::Extension
|
class Middleman::Extensions::CacheBuster < ::Middleman::Extension
|
||||||
option :exts, nil, 'List of extensions that get cache busters strings appended to them.'
|
option :exts, nil, 'List of extensions that get cache busters strings appended to them.', set: true
|
||||||
option :sources, %w(.css .htm .html .js .php .xhtml), 'List of extensions that are searched for bustable assets.'
|
option :sources, %w(.css .htm .html .js .php .xhtml), 'List of extensions that are searched for bustable assets.', set: true
|
||||||
option :ignore, [], 'Regexes of filenames to skip adding query strings to'
|
option :ignore, [], 'Regexes of filenames to skip adding query strings to'
|
||||||
option :rewrite_ignore, [], 'Regexes of filenames to skip processing for path rewrites'
|
option :rewrite_ignore, [], 'Regexes of filenames to skip processing for path rewrites'
|
||||||
|
|
||||||
def initialize(app, options_hash={}, &block)
|
Contract ResourceList => ResourceList
|
||||||
super
|
def manipulate_resource_list(resources)
|
||||||
|
resources.each do |r|
|
||||||
|
next unless r.destination_path.end_with?('/', *options.sources)
|
||||||
|
next if Array(options.rewrite_ignore || []).any? do |i|
|
||||||
|
::Middleman::Util.path_match(i, "/#{r.destination_path}")
|
||||||
|
end
|
||||||
|
|
||||||
app.rewrite_inline_urls id: :cache_buster,
|
r.filters << ::Middleman::InlineURLRewriter.new(:cache_buster,
|
||||||
|
app,
|
||||||
|
r,
|
||||||
url_extensions: options.exts || app.config[:asset_extensions],
|
url_extensions: options.exts || app.config[:asset_extensions],
|
||||||
source_extensions: options.sources,
|
|
||||||
ignore: options.ignore,
|
ignore: options.ignore,
|
||||||
rewrite_ignore: options.rewrite_ignore,
|
proc: method(:rewrite_url))
|
||||||
proc: method(:rewrite_url)
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Contract String, Or[String, Pathname], Any => String
|
Contract String, Or[String, Pathname], Any => String
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
require 'set'
|
||||||
|
|
||||||
# Directory Indexes extension
|
# Directory Indexes extension
|
||||||
class Middleman::Extensions::DirectoryIndexes < ::Middleman::Extension
|
class Middleman::Extensions::DirectoryIndexes < ::Middleman::Extension
|
||||||
# This should run after most other sitemap manipulators so that it
|
# This should run after most other sitemap manipulators so that it
|
||||||
|
@ -11,7 +13,7 @@ class Middleman::Extensions::DirectoryIndexes < ::Middleman::Extension
|
||||||
index_file = app.config[:index_file]
|
index_file = app.config[:index_file]
|
||||||
new_index_path = "/#{index_file}"
|
new_index_path = "/#{index_file}"
|
||||||
|
|
||||||
extensions = %w(.htm .html .php .xhtml)
|
extensions = Set.new(%w(.htm .html .php .xhtml))
|
||||||
|
|
||||||
resources.each do |resource|
|
resources.each do |resource|
|
||||||
# Check if it would be pointless to reroute
|
# Check if it would be pointless to reroute
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
# to .css, .htm, .html, .js, and .xhtml
|
# to .css, .htm, .html, .js, and .xhtml
|
||||||
#
|
#
|
||||||
class Middleman::Extensions::Gzip < ::Middleman::Extension
|
class Middleman::Extensions::Gzip < ::Middleman::Extension
|
||||||
option :exts, %w(.css .htm .html .js .svg .xhtml), 'File extensions to Gzip when building.'
|
option :exts, %w(.css .htm .html .js .svg .xhtml), 'File extensions to Gzip when building.', set: true
|
||||||
option :ignore, [], 'Patterns to avoid gzipping'
|
option :ignore, [], 'Patterns to avoid gzipping'
|
||||||
option :overwrite, false, 'Overwrite original files instead of adding .gz extension.'
|
option :overwrite, false, 'Overwrite original files instead of adding .gz extension.'
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
require 'active_support/core_ext/object/try'
|
|
||||||
require 'memoist'
|
|
||||||
require 'middleman-core/contracts'
|
require 'middleman-core/contracts'
|
||||||
|
require 'rack/mime'
|
||||||
|
|
||||||
# Minify CSS Extension
|
# Minify CSS Extension
|
||||||
class Middleman::Extensions::MinifyCss < ::Middleman::Extension
|
class Middleman::Extensions::MinifyCss < ::Middleman::Extension
|
||||||
|
@ -10,17 +9,10 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension
|
||||||
require 'sass'
|
require 'sass'
|
||||||
SassCompressor
|
SassCompressor
|
||||||
}, 'Set the CSS compressor to use.'
|
}, 'Set the CSS compressor to use.'
|
||||||
option :content_types, %w(text/css), 'Content types of resources that contain CSS'
|
option :content_types, %w(text/css), 'Content types of resources that contain CSS', set: true
|
||||||
option :inline_content_types, %w(text/html text/php), 'Content types of resources that contain inline CSS'
|
option :inline_content_types, %w(text/html text/php), 'Content types of resources that contain inline CSS', set: true
|
||||||
|
|
||||||
def ready
|
INLINE_CSS_REGEX = /(<style[^>]*>\s*(?:\/\*<!\[CDATA\[\*\/\n)?)(.*?)((?:(?:\n\s*)?\/\*\]\]>\*\/)?\s*<\/style>)/m
|
||||||
# Setup Rack middleware to minify CSS
|
|
||||||
app.use Rack, compressor: options[:compressor],
|
|
||||||
ignore: Array(options[:ignore]) + [/\.min\./],
|
|
||||||
inline: options[:inline],
|
|
||||||
content_types: options[:content_types],
|
|
||||||
inline_content_types: options[:inline_content_types]
|
|
||||||
end
|
|
||||||
|
|
||||||
class SassCompressor
|
class SassCompressor
|
||||||
def self.compress(style, options={})
|
def self.compress(style, options={})
|
||||||
|
@ -30,97 +22,61 @@ class Middleman::Extensions::MinifyCss < ::Middleman::Extension
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Rack middleware to look for CSS and compress it
|
def initialize(app, options_hash={}, &block)
|
||||||
class Rack
|
super
|
||||||
extend Memoist
|
|
||||||
include Contracts
|
|
||||||
INLINE_CSS_REGEX = /(<style[^>]*>\s*(?:\/\*<!\[CDATA\[\*\/\n)?)(.*?)((?:(?:\n\s*)?\/\*\]\]>\*\/)?\s*<\/style>)/m
|
|
||||||
|
|
||||||
# Init
|
@ignore = Array(options[:ignore]) + [/\.min\./]
|
||||||
# @param [Class] app
|
@compressor = options[:compressor]
|
||||||
# @param [Hash] options
|
|
||||||
Contract RespondTo[:call], {
|
|
||||||
ignore: ArrayOf[PATH_MATCHER],
|
|
||||||
inline: Bool,
|
|
||||||
compressor: Or[Proc, RespondTo[:to_proc], RespondTo[:compress]]
|
|
||||||
} => Any
|
|
||||||
def initialize(app, options={})
|
|
||||||
@app = app
|
|
||||||
@ignore = options.fetch(:ignore)
|
|
||||||
@inline = options.fetch(:inline)
|
|
||||||
|
|
||||||
@compressor = options.fetch(:compressor)
|
|
||||||
@compressor = @compressor.to_proc if @compressor.respond_to? :to_proc
|
@compressor = @compressor.to_proc if @compressor.respond_to? :to_proc
|
||||||
@compressor = @compressor.call if @compressor.is_a? Proc
|
@compressor = @compressor.call if @compressor.is_a? Proc
|
||||||
@content_types = options[:content_types]
|
|
||||||
@inline_content_types = options[:inline_content_types]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Rack interface
|
Contract ResourceList => ResourceList
|
||||||
# @param [Rack::Environmemt] env
|
def manipulate_resource_list(resources)
|
||||||
# @return [Array]
|
resources.each do |r|
|
||||||
def call(env)
|
type = r.content_type.try(:slice, /^[^;]*/)
|
||||||
status, headers, response = @app.call(env)
|
if options[:inline] && minifiable_inline?(type)
|
||||||
|
r.filters << method(:minify_inline)
|
||||||
content_type = headers['Content-Type'].try(:slice, /^[^;]*/)
|
elsif minifiable?(type) && !ignore?(r.destination_path)
|
||||||
path = env['PATH_INFO']
|
r.filters << method(:minify)
|
||||||
|
|
||||||
minified = if @inline && minifiable_inline?(content_type)
|
|
||||||
minify_inline(::Middleman::Util.extract_response_text(response))
|
|
||||||
elsif minifiable?(content_type) && !ignore?(path)
|
|
||||||
minify(::Middleman::Util.extract_response_text(response))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if minified
|
|
||||||
headers['Content-Length'] = minified.bytesize.to_s
|
|
||||||
response = [minified]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
[status, headers, response]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
# Whether the path should be ignored
|
# Whether the path should be ignored
|
||||||
# @param [String] path
|
Contract String => Bool
|
||||||
# @return [Boolean]
|
|
||||||
def ignore?(path)
|
def ignore?(path)
|
||||||
@ignore.any? { |ignore| ::Middleman::Util.path_match(ignore, path) }
|
@ignore.any? { |ignore| ::Middleman::Util.path_match(ignore, path) }
|
||||||
end
|
end
|
||||||
memoize :ignore?
|
memoize :ignore?
|
||||||
|
|
||||||
# Whether this type of content can be minified
|
# Whether this type of content can be minified
|
||||||
# @param [String, nil] content_type
|
Contract Maybe[String] => Bool
|
||||||
# @return [Boolean]
|
|
||||||
def minifiable?(content_type)
|
def minifiable?(content_type)
|
||||||
@content_types.include?(content_type)
|
options[:content_types].include?(content_type)
|
||||||
end
|
end
|
||||||
memoize :minifiable?
|
memoize :minifiable?
|
||||||
|
|
||||||
# Whether this type of content contains inline content that can be minified
|
# Whether this type of content contains inline content that can be minified
|
||||||
# @param [String, nil] content_type
|
Contract Maybe[String] => Bool
|
||||||
# @return [Boolean]
|
|
||||||
def minifiable_inline?(content_type)
|
def minifiable_inline?(content_type)
|
||||||
@inline_content_types.include?(content_type)
|
options[:inline_content_types].include?(content_type)
|
||||||
end
|
end
|
||||||
memoize :minifiable_inline?
|
memoize :minifiable_inline?
|
||||||
|
|
||||||
# Minify the content
|
# Minify the content
|
||||||
# @param [String] content
|
Contract String => String
|
||||||
# @return [String]
|
|
||||||
def minify(content)
|
def minify(content)
|
||||||
@compressor.compress(content)
|
@compressor.compress(content)
|
||||||
end
|
end
|
||||||
memoize :minify
|
memoize :minify
|
||||||
|
|
||||||
# Detect and minify inline content
|
# Detect and minify inline content
|
||||||
# @param [String] content
|
Contract String => String
|
||||||
# @return [String]
|
|
||||||
def minify_inline(content)
|
def minify_inline(content)
|
||||||
content.gsub(INLINE_CSS_REGEX) do
|
content.gsub(INLINE_CSS_REGEX) do
|
||||||
$1 + minify($2) + $3
|
$1 + minify($2) + $3
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
memoize :minify_inline
|
memoize :minify_inline
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
require 'active_support/core_ext/object/try'
|
|
||||||
require 'middleman-core/contracts'
|
require 'middleman-core/contracts'
|
||||||
require 'memoist'
|
require 'memoist'
|
||||||
|
|
||||||
|
@ -10,107 +9,65 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension
|
||||||
require 'uglifier'
|
require 'uglifier'
|
||||||
::Uglifier.new
|
::Uglifier.new
|
||||||
}, 'Set the JS compressor to use.'
|
}, 'Set the JS compressor to use.'
|
||||||
option :content_types, %w(application/javascript), 'Content types of resources that contain JS'
|
option :content_types, %w(application/javascript), 'Content types of resources that contain JS', set: true
|
||||||
option :inline_content_types, %w(text/html text/php), 'Content types of resources that contain inline JS'
|
option :inline_content_types, %w(text/html text/php), 'Content types of resources that contain inline JS', set: true
|
||||||
|
|
||||||
def ready
|
|
||||||
# Setup Rack middleware to minify JS
|
|
||||||
app.use Rack, compressor: options[:compressor],
|
|
||||||
ignore: Array(options[:ignore]) + [/\.min\./],
|
|
||||||
inline: options[:inline],
|
|
||||||
content_types: options[:content_types],
|
|
||||||
inline_content_types: options[:inline_content_types]
|
|
||||||
end
|
|
||||||
|
|
||||||
# Rack middleware to look for JS and compress it
|
|
||||||
class Rack
|
|
||||||
extend Memoist
|
|
||||||
include Contracts
|
|
||||||
INLINE_JS_REGEX = /(<script[^>]*>\s*(?:\/\/(?:(?:<!--)|(?:<!\[CDATA\[))\n)?)(.*?)((?:(?:\n\s*)?\/\/(?:(?:-->)|(?:\]\]>)))?\s*<\/script>)/m
|
INLINE_JS_REGEX = /(<script[^>]*>\s*(?:\/\/(?:(?:<!--)|(?:<!\[CDATA\[))\n)?)(.*?)((?:(?:\n\s*)?\/\/(?:(?:-->)|(?:\]\]>)))?\s*<\/script>)/m
|
||||||
|
|
||||||
# Init
|
def initialize(app, options_hash={}, &block)
|
||||||
# @param [Class] app
|
super
|
||||||
# @param [Hash] options
|
|
||||||
Contract RespondTo[:call], {
|
|
||||||
ignore: ArrayOf[PATH_MATCHER],
|
|
||||||
inline: Bool,
|
|
||||||
compressor: Or[Proc, RespondTo[:to_proc], RespondTo[:compress]]
|
|
||||||
} => Any
|
|
||||||
def initialize(app, options={})
|
|
||||||
@app = app
|
|
||||||
@ignore = options.fetch(:ignore)
|
|
||||||
@inline = options.fetch(:inline)
|
|
||||||
|
|
||||||
@compressor = options.fetch(:compressor)
|
@ignore = Array(options[:ignore]) + [/\.min\./]
|
||||||
|
@compressor = options[:compressor]
|
||||||
@compressor = @compressor.to_proc if @compressor.respond_to? :to_proc
|
@compressor = @compressor.to_proc if @compressor.respond_to? :to_proc
|
||||||
@compressor = @compressor.call if @compressor.is_a? Proc
|
@compressor = @compressor.call if @compressor.is_a? Proc
|
||||||
@content_types = options[:content_types]
|
|
||||||
@inline_content_types = options[:inline_content_types]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Rack interface
|
Contract ResourceList => ResourceList
|
||||||
# @param [Rack::Environmemt] env
|
def manipulate_resource_list(resources)
|
||||||
# @return [Array]
|
resources.each do |r|
|
||||||
def call(env)
|
type = r.content_type.try(:slice, /^[^;]*/)
|
||||||
status, headers, response = @app.call(env)
|
if options[:inline] && minifiable_inline?(type)
|
||||||
|
r.filters << method(:minify_inline)
|
||||||
type = headers['Content-Type'].try(:slice, /^[^;]*/)
|
elsif minifiable?(type) && !ignore?(r.destination_path)
|
||||||
@path = env['PATH_INFO']
|
r.filters << method(:minify)
|
||||||
|
|
||||||
minified = if @inline && minifiable_inline?(type)
|
|
||||||
minify_inline(::Middleman::Util.extract_response_text(response))
|
|
||||||
elsif minifiable?(type) && !ignore?(@path)
|
|
||||||
minify(::Middleman::Util.extract_response_text(response))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if minified
|
|
||||||
headers['Content-Length'] = minified.bytesize.to_s
|
|
||||||
response = [minified]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
[status, headers, response]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
# Whether the path should be ignored
|
# Whether the path should be ignored
|
||||||
# @param [String] path
|
Contract String => Bool
|
||||||
# @return [Boolean]
|
|
||||||
def ignore?(path)
|
def ignore?(path)
|
||||||
@ignore.any? { |ignore| Middleman::Util.path_match(ignore, path) }
|
@ignore.any? { |ignore| ::Middleman::Util.path_match(ignore, path) }
|
||||||
end
|
end
|
||||||
memoize :ignore?
|
memoize :ignore?
|
||||||
|
|
||||||
# Whether this type of content can be minified
|
# Whether this type of content can be minified
|
||||||
# @param [String, nil] content_type
|
Contract Maybe[String] => Bool
|
||||||
# @return [Boolean]
|
|
||||||
def minifiable?(content_type)
|
def minifiable?(content_type)
|
||||||
@content_types.include?(content_type)
|
options[:content_types].include?(content_type)
|
||||||
end
|
end
|
||||||
memoize :minifiable?
|
memoize :minifiable?
|
||||||
|
|
||||||
# Whether this type of content contains inline content that can be minified
|
# Whether this type of content contains inline content that can be minified
|
||||||
# @param [String, nil] content_type
|
Contract Maybe[String] => Bool
|
||||||
# @return [Boolean]
|
|
||||||
def minifiable_inline?(content_type)
|
def minifiable_inline?(content_type)
|
||||||
@inline_content_types.include?(content_type)
|
options[:inline_content_types].include?(content_type)
|
||||||
end
|
end
|
||||||
memoize :minifiable_inline?
|
memoize :minifiable_inline?
|
||||||
|
|
||||||
# Minify the content
|
# Minify the content
|
||||||
# @param [String] content
|
Contract String => String
|
||||||
# @return [String]
|
|
||||||
def minify(content)
|
def minify(content)
|
||||||
@compressor.compress(content)
|
@compressor.compress(content)
|
||||||
rescue ExecJS::ProgramError => e
|
rescue ::ExecJS::ProgramError => e
|
||||||
warn "WARNING: Couldn't compress JavaScript in #{@path}: #{e.message}"
|
warn "WARNING: Couldn't compress JavaScript in #{@path}: #{e.message}"
|
||||||
content
|
content
|
||||||
end
|
end
|
||||||
memoize :minify
|
memoize :minify
|
||||||
|
|
||||||
# Detect and minify inline content
|
# Detect and minify inline content
|
||||||
# @param [String] content
|
Contract String => String
|
||||||
# @return [String]
|
|
||||||
def minify_inline(content)
|
def minify_inline(content)
|
||||||
content.gsub(INLINE_JS_REGEX) do |match|
|
content.gsub(INLINE_JS_REGEX) do |match|
|
||||||
first = $1
|
first = $1
|
||||||
|
@ -127,5 +84,4 @@ class Middleman::Extensions::MinifyJavascript < ::Middleman::Extension
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
memoize :minify_inline
|
memoize :minify_inline
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,24 +1,28 @@
|
||||||
require 'addressable/uri'
|
|
||||||
|
|
||||||
# Relative Assets extension
|
# Relative Assets extension
|
||||||
class Middleman::Extensions::RelativeAssets < ::Middleman::Extension
|
class Middleman::Extensions::RelativeAssets < ::Middleman::Extension
|
||||||
option :exts, nil, 'List of extensions that get converted to relative paths.'
|
option :exts, nil, 'List of extensions that get converted to relative paths.', set: true
|
||||||
option :sources, %w(.css .htm .html .xhtml), 'List of extensions that are searched for relative assets.'
|
option :sources, %w(.css .htm .html .xhtml), 'List of extensions that are searched for relative assets.', set: true
|
||||||
option :ignore, [], 'Regexes of filenames to skip converting to relative paths.'
|
option :ignore, [], 'Regexes of filenames to skip converting to relative paths.'
|
||||||
option :rewrite_ignore, [], 'Regexes of filenames to skip processing for path rewrites.'
|
option :rewrite_ignore, [], 'Regexes of filenames to skip processing for path rewrites.'
|
||||||
option :helpers_only, false, 'Allow only Ruby helpers to change paths.'
|
option :helpers_only, false, 'Allow only Ruby helpers to change paths.'
|
||||||
|
|
||||||
def initialize(app, options_hash={}, &block)
|
Contract ResourceList => ResourceList
|
||||||
super
|
def manipulate_resource_list(resources)
|
||||||
|
return resources if options[:helpers_only]
|
||||||
|
|
||||||
return if options[:helpers_only]
|
resources.each do |r|
|
||||||
|
next unless r.destination_path.end_with?('/', *options.sources)
|
||||||
|
next if Array(options.rewrite_ignore || []).any? do |i|
|
||||||
|
::Middleman::Util.path_match(i, "/#{r.destination_path}")
|
||||||
|
end
|
||||||
|
|
||||||
app.rewrite_inline_urls id: :relative_assets,
|
r.filters << ::Middleman::InlineURLRewriter.new(:relative_assets,
|
||||||
|
app,
|
||||||
|
r,
|
||||||
url_extensions: options.exts || app.config[:asset_extensions],
|
url_extensions: options.exts || app.config[:asset_extensions],
|
||||||
source_extensions: options.sources,
|
|
||||||
ignore: options.ignore,
|
ignore: options.ignore,
|
||||||
rewrite_ignore: options.rewrite_ignore,
|
proc: method(:rewrite_url))
|
||||||
proc: method(:rewrite_url)
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def mark_as_relative(file_path, opts, current_resource)
|
def mark_as_relative(file_path, opts, current_resource)
|
||||||
|
|
|
@ -3,8 +3,8 @@ require 'active_support/core_ext/string/output_safety'
|
||||||
require 'active_support/core_ext/module/delegation'
|
require 'active_support/core_ext/module/delegation'
|
||||||
require 'middleman-core/contracts'
|
require 'middleman-core/contracts'
|
||||||
|
|
||||||
::Tilt.default_mapping.lazy_map.delete('html')
|
::Tilt.mappings.delete('html') # WTF, Tilt?
|
||||||
::Tilt.default_mapping.lazy_map.delete('csv')
|
::Tilt.mappings.delete('csv')
|
||||||
|
|
||||||
module Middleman
|
module Middleman
|
||||||
class FileRenderer
|
class FileRenderer
|
||||||
|
@ -123,8 +123,8 @@ module Middleman
|
||||||
# Find all the engines which handle this extension in tilt. Look for
|
# Find all the engines which handle this extension in tilt. Look for
|
||||||
# config variables of that name and merge it
|
# config variables of that name and merge it
|
||||||
extension_class = ::Middleman::Util.tilt_class(ext)
|
extension_class = ::Middleman::Util.tilt_class(ext)
|
||||||
|
::Tilt.mappings.each do |mapping_ext, engines|
|
||||||
::Tilt.default_mapping.extensions_for(extension_class).each do |mapping_ext|
|
next unless engines.include? extension_class
|
||||||
engine_options = @app.config[mapping_ext.to_sym] || {}
|
engine_options = @app.config[mapping_ext.to_sym] || {}
|
||||||
options.merge!(engine_options)
|
options.merge!(engine_options)
|
||||||
end
|
end
|
||||||
|
|
49
middleman-core/lib/middleman-core/inline_url_rewriter.rb
Normal file
49
middleman-core/lib/middleman-core/inline_url_rewriter.rb
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
require 'middleman-core/util'
|
||||||
|
require 'middleman-core/contracts'
|
||||||
|
|
||||||
|
module Middleman
|
||||||
|
class InlineURLRewriter
|
||||||
|
include Contracts
|
||||||
|
|
||||||
|
attr_reader :filter_name
|
||||||
|
attr_reader :after_filter
|
||||||
|
|
||||||
|
def initialize(filter_name, app, resource, options={})
|
||||||
|
@filter_name = filter_name
|
||||||
|
@app = app
|
||||||
|
@resource = resource
|
||||||
|
@options = options
|
||||||
|
|
||||||
|
@after_filter = @options.fetch(:after_filter, nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
Contract String => String
|
||||||
|
def execute_filter(body)
|
||||||
|
path = "/#{@resource.destination_path}"
|
||||||
|
dirpath = ::Pathname.new(File.dirname(path))
|
||||||
|
|
||||||
|
::Middleman::Util.instrument 'inline_url_rewriter', path: path do
|
||||||
|
::Middleman::Util.rewrite_paths(body, path, @options.fetch(:url_extensions), @app) do |asset_path|
|
||||||
|
uri = ::Middleman::Util.parse_uri(asset_path)
|
||||||
|
|
||||||
|
relative_path = uri.host.nil?
|
||||||
|
full_asset_path = if relative_path
|
||||||
|
dirpath.join(asset_path).to_s
|
||||||
|
else
|
||||||
|
asset_path
|
||||||
|
end
|
||||||
|
|
||||||
|
exts = @options.fetch(:url_extensions)
|
||||||
|
next unless exts.include?(::File.extname(asset_path))
|
||||||
|
|
||||||
|
next if @options.fetch(:ignore).any? { |r| ::Middleman::Util.should_ignore?(r, full_asset_path) }
|
||||||
|
|
||||||
|
result = @options.fetch(:proc).call(asset_path, dirpath, path)
|
||||||
|
asset_path = result if result
|
||||||
|
|
||||||
|
asset_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -143,7 +143,7 @@ module Middleman
|
||||||
|
|
||||||
app = ::Middleman::Application.new do
|
app = ::Middleman::Application.new do
|
||||||
config[:cli_options] = cli_options.each_with_object({}) do |(k, v), sum|
|
config[:cli_options] = cli_options.each_with_object({}) do |(k, v), sum|
|
||||||
sum[k] = v
|
sum[k] = v unless v == :undefined
|
||||||
end
|
end
|
||||||
|
|
||||||
ready do
|
ready do
|
||||||
|
@ -160,9 +160,6 @@ module Middleman
|
||||||
path: root,
|
path: root,
|
||||||
only: match_against
|
only: match_against
|
||||||
|
|
||||||
# Hack around bower_components in root.
|
|
||||||
watcher.listener.ignore(/^bower_components/)
|
|
||||||
|
|
||||||
# Hack around node_modules in root.
|
# Hack around node_modules in root.
|
||||||
watcher.listener.ignore(/^node_modules/)
|
watcher.listener.ignore(/^node_modules/)
|
||||||
|
|
||||||
|
@ -207,7 +204,7 @@ module Middleman
|
||||||
end
|
end
|
||||||
|
|
||||||
def possible_from_cli(key, config)
|
def possible_from_cli(key, config)
|
||||||
if @cli_options[key]
|
if @cli_options[key] && @cli_options[key] != :undefined
|
||||||
@cli_options[key]
|
@cli_options[key]
|
||||||
else
|
else
|
||||||
config[key]
|
config[key]
|
||||||
|
|
|
@ -93,9 +93,6 @@ module Middleman
|
||||||
request_path = ::Middleman::Util.full_path(request_path, @middleman)
|
request_path = ::Middleman::Util.full_path(request_path, @middleman)
|
||||||
full_request_path = File.join(env['SCRIPT_NAME'], request_path) # Path including rack mount
|
full_request_path = File.join(env['SCRIPT_NAME'], request_path) # Path including rack mount
|
||||||
|
|
||||||
# Run before callbacks
|
|
||||||
@middleman.execute_callbacks(:before)
|
|
||||||
|
|
||||||
# Get the resource object for this path
|
# Get the resource object for this path
|
||||||
resource = @middleman.sitemap.find_resource_by_destination_path(request_path.gsub(' ', '%20'))
|
resource = @middleman.sitemap.find_resource_by_destination_path(request_path.gsub(' ', '%20'))
|
||||||
|
|
||||||
|
@ -134,14 +131,8 @@ module Middleman
|
||||||
# Immediately send static file
|
# Immediately send static file
|
||||||
def send_file(resource, env)
|
def send_file(resource, env)
|
||||||
file = ::Rack::File.new nil
|
file = ::Rack::File.new nil
|
||||||
path = resource.file_descriptor[:full_path]
|
file.path = resource.file_descriptor[:full_path]
|
||||||
if !file.respond_to?(:path=)
|
|
||||||
request = ::Rack::Request.new(env)
|
|
||||||
response = file.serving(request, path)
|
|
||||||
else
|
|
||||||
file.path = path
|
|
||||||
response = file.serving(env)
|
response = file.serving(env)
|
||||||
end
|
|
||||||
status = response[0]
|
status = response[0]
|
||||||
response[1]['Content-Encoding'] = 'gzip' if %w(.svgz .gz).include?(resource.ext)
|
response[1]['Content-Encoding'] = 'gzip' if %w(.svgz .gz).include?(resource.ext)
|
||||||
# Do not set Content-Type if status is 1xx, 204, 205 or 304, otherwise
|
# Do not set Content-Type if status is 1xx, 204, 205 or 304, otherwise
|
||||||
|
|
|
@ -3,7 +3,7 @@ require 'active_support/core_ext/module/attribute_accessors'
|
||||||
|
|
||||||
module Middleman
|
module Middleman
|
||||||
module Renderers
|
module Renderers
|
||||||
class RedcarpetTemplate < ::Tilt::RedcarpetTemplate
|
class RedcarpetTemplate < ::Tilt::RedcarpetTemplate::Redcarpet2
|
||||||
# because tilt has decided to convert these
|
# because tilt has decided to convert these
|
||||||
# in the wrong direction
|
# in the wrong direction
|
||||||
ALIASES = {
|
ALIASES = {
|
||||||
|
|
|
@ -105,8 +105,10 @@ module Middleman
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if defined?(::SassC)
|
SASS_MODULE = if defined?(::SassC)
|
||||||
::SassC::Script::Functions.send :include, ::Middleman::Sass::Functions
|
::SassC
|
||||||
elsif defined?(::Sass)
|
else
|
||||||
::Sass::Script::Functions.send :include, ::Middleman::Sass::Functions
|
::Sass
|
||||||
end
|
end
|
||||||
|
|
||||||
|
SASS_MODULE::Script::Functions.send :include, ::Middleman::Sass::Functions
|
||||||
|
|
|
@ -12,9 +12,13 @@ class ::Slim::Template
|
||||||
|
|
||||||
def initialize(file, line, opts, &block)
|
def initialize(file, line, opts, &block)
|
||||||
if opts.key?(:context)
|
if opts.key?(:context)
|
||||||
|
context_hack = {
|
||||||
|
context: opts[:context]
|
||||||
|
}
|
||||||
|
|
||||||
::Slim::Embedded::SassEngine.disable_option_validator!
|
::Slim::Embedded::SassEngine.disable_option_validator!
|
||||||
%w(sass scss markdown).each do |engine|
|
%w(sass scss markdown).each do |engine|
|
||||||
(::Slim::Embedded.options[engine.to_sym] ||= {})[:context] = opts[:context]
|
::Slim::Embedded.options[engine.to_sym] = context_hack
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -14,31 +14,16 @@ module Middleman
|
||||||
Contract Or[String, Regexp, Proc] => RespondTo[:execute_descriptor]
|
Contract Or[String, Regexp, Proc] => RespondTo[:execute_descriptor]
|
||||||
def ignore(path=nil, &block)
|
def ignore(path=nil, &block)
|
||||||
@app.sitemap.invalidate_resources_not_ignored_cache!
|
@app.sitemap.invalidate_resources_not_ignored_cache!
|
||||||
|
|
||||||
if path.is_a? Regexp
|
|
||||||
RegexpIgnoreDescriptor.new(path)
|
|
||||||
elsif path.is_a? String
|
|
||||||
path_clean = ::Middleman::Util.normalize_path(path)
|
|
||||||
|
|
||||||
if path_clean.include?('*') # It's a glob
|
|
||||||
GlobIgnoreDescriptor.new(path_clean)
|
|
||||||
else
|
|
||||||
StringIgnoreDescriptor.new(path_clean)
|
|
||||||
end
|
|
||||||
elsif block
|
|
||||||
BlockIgnoreDescriptor.new(nil, block)
|
|
||||||
else
|
|
||||||
IgnoreDescriptor.new(path, block)
|
IgnoreDescriptor.new(path, block)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
IgnoreDescriptor = Struct.new(:path, :block) do
|
IgnoreDescriptor = Struct.new(:path, :block) do
|
||||||
def execute_descriptor(_app, resources)
|
def execute_descriptor(_app, resources)
|
||||||
resources.map do |r|
|
resources.map do |r|
|
||||||
# Ignore based on the source path (without template extensions)
|
# Ignore based on the source path (without template extensions)
|
||||||
if ignored?(r.normalized_path)
|
if ignored?(r.path)
|
||||||
r.ignore!
|
r.ignore!
|
||||||
elsif !r.is_a?(ProxyResource) && r.file_descriptor && ignored?(r.file_descriptor.normalized_relative_path)
|
elsif !r.is_a?(ProxyResource) && r.file_descriptor && ignored?(r.file_descriptor[:relative_path].to_s)
|
||||||
# This allows files to be ignored by their source file name (with template extensions)
|
# This allows files to be ignored by their source file name (with template extensions)
|
||||||
r.ignore!
|
r.ignore!
|
||||||
end
|
end
|
||||||
|
@ -48,38 +33,27 @@ module Middleman
|
||||||
end
|
end
|
||||||
|
|
||||||
def ignored?(match_path)
|
def ignored?(match_path)
|
||||||
raise NotImplementedError
|
match_path = ::Middleman::Util.normalize_path(match_path)
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class RegexpIgnoreDescriptor < IgnoreDescriptor
|
if path.is_a? Regexp
|
||||||
def ignored?(match_path)
|
|
||||||
match_path =~ path
|
match_path =~ path
|
||||||
end
|
elsif path.is_a? String
|
||||||
end
|
path_clean = ::Middleman::Util.normalize_path(path)
|
||||||
|
|
||||||
class GlobIgnoreDescriptor < IgnoreDescriptor
|
if path_clean.include?('*') # It's a glob
|
||||||
def ignored?(match_path)
|
|
||||||
if defined?(::File::FNM_EXTGLOB)
|
if defined?(::File::FNM_EXTGLOB)
|
||||||
::File.fnmatch(path, match_path, ::File::FNM_EXTGLOB)
|
::File.fnmatch(path_clean, match_path, ::File::FNM_EXTGLOB)
|
||||||
else
|
else
|
||||||
::File.fnmatch(path, match_path)
|
::File.fnmatch(path_clean, match_path)
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
match_path == path_clean
|
||||||
end
|
end
|
||||||
end
|
elsif block
|
||||||
|
|
||||||
class StringIgnoreDescriptor < IgnoreDescriptor
|
|
||||||
def ignored?(match_path)
|
|
||||||
match_path == path
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class BlockIgnoreDescriptor < IgnoreDescriptor
|
|
||||||
def ignored?(match_path)
|
|
||||||
block.call(match_path)
|
block.call(match_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -47,7 +47,7 @@ module Middleman
|
||||||
)
|
)
|
||||||
|
|
||||||
if should_ignore
|
if should_ignore
|
||||||
d = ::Middleman::Sitemap::Extensions::Ignores::StringIgnoreDescriptor.new(target)
|
d = ::Middleman::Sitemap::Extensions::Ignores::IgnoreDescriptor.new(target)
|
||||||
d.execute_descriptor(app, resources)
|
d.execute_descriptor(app, resources)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,8 @@ module Middleman
|
||||||
def render(*)
|
def render(*)
|
||||||
url = ::Middleman::Util.url_for(@store.app, @request_path,
|
url = ::Middleman::Util.url_for(@store.app, @request_path,
|
||||||
relative: false,
|
relative: false,
|
||||||
find_resource: true)
|
find_resource: true
|
||||||
|
)
|
||||||
|
|
||||||
if output
|
if output
|
||||||
output.call(path, url)
|
output.call(path, url)
|
||||||
|
|
|
@ -9,14 +9,13 @@ module Middleman
|
||||||
# Expose `endpoint`
|
# Expose `endpoint`
|
||||||
expose_to_config :endpoint
|
expose_to_config :endpoint
|
||||||
|
|
||||||
EndpointDescriptor = Struct.new(:path, :request_path, :block) do
|
EndpointDescriptor = Struct.new(:path, :block) do
|
||||||
def execute_descriptor(app, resources)
|
def execute_descriptor(app, resources)
|
||||||
r = EndpointResource.new(
|
r = ::Middleman::Sitemap::CallbackResource.new(
|
||||||
app.sitemap,
|
app.sitemap,
|
||||||
path,
|
path,
|
||||||
request_path
|
&block
|
||||||
)
|
)
|
||||||
r.output = block if block
|
|
||||||
|
|
||||||
resources + [r]
|
resources + [r]
|
||||||
end
|
end
|
||||||
|
@ -24,43 +23,10 @@ module Middleman
|
||||||
|
|
||||||
# Setup a proxy from a path to a target
|
# Setup a proxy from a path to a target
|
||||||
# @param [String] path
|
# @param [String] path
|
||||||
# @param [Hash] opts The :path value gives a request path if it
|
|
||||||
# differs from the output path
|
# differs from the output path
|
||||||
Contract String, Or[{ path: String }, Proc] => EndpointDescriptor
|
Contract String, Proc => EndpointDescriptor
|
||||||
def endpoint(path, opts={}, &block)
|
def endpoint(path, &block)
|
||||||
if block_given?
|
EndpointDescriptor.new(path, block)
|
||||||
EndpointDescriptor.new(path, path, block)
|
|
||||||
else
|
|
||||||
EndpointDescriptor.new(path, opts[:path] || path, nil)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class EndpointResource < ::Middleman::Sitemap::Resource
|
|
||||||
Contract Maybe[Proc]
|
|
||||||
attr_accessor :output
|
|
||||||
|
|
||||||
def initialize(store, path, request_path)
|
|
||||||
super(store, path)
|
|
||||||
@request_path = ::Middleman::Util.normalize_path(request_path)
|
|
||||||
end
|
|
||||||
|
|
||||||
Contract String
|
|
||||||
attr_reader :request_path
|
|
||||||
|
|
||||||
Contract Bool
|
|
||||||
def template?
|
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
Contract Args[Any] => String
|
|
||||||
def render(*)
|
|
||||||
return output.call if output
|
|
||||||
end
|
|
||||||
|
|
||||||
Contract Bool
|
|
||||||
def ignored?
|
|
||||||
false
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,7 @@ require 'middleman-core/sitemap/extensions/traversal'
|
||||||
require 'middleman-core/file_renderer'
|
require 'middleman-core/file_renderer'
|
||||||
require 'middleman-core/template_renderer'
|
require 'middleman-core/template_renderer'
|
||||||
require 'middleman-core/contracts'
|
require 'middleman-core/contracts'
|
||||||
|
require 'middleman-core/inline_url_rewriter'
|
||||||
|
|
||||||
module Middleman
|
module Middleman
|
||||||
# Sitemap namespace
|
# Sitemap namespace
|
||||||
|
@ -39,24 +40,26 @@ module Middleman
|
||||||
attr_reader :metadata
|
attr_reader :metadata
|
||||||
|
|
||||||
attr_accessor :ignored
|
attr_accessor :ignored
|
||||||
|
attr_accessor :filters
|
||||||
|
|
||||||
# Initialize resource with parent store and URL
|
# Initialize resource with parent store and URL
|
||||||
# @param [Middleman::Sitemap::Store] store
|
# @param [Middleman::Sitemap::Store] store
|
||||||
# @param [String] path
|
# @param [String] path
|
||||||
# @param [String] source
|
# @param [String] source
|
||||||
Contract IsA['Middleman::Sitemap::Store'], String, Maybe[Or[IsA['Middleman::SourceFile'], String]] => Any
|
Contract IsA['Middleman::Sitemap::Store'], String, Maybe[Any] => Any
|
||||||
def initialize(store, path, source=nil)
|
def initialize(store, path, source_file=nil)
|
||||||
@store = store
|
@store = store
|
||||||
@app = @store.app
|
@app = @store.app
|
||||||
@path = path
|
@path = path
|
||||||
@ignored = false
|
@ignored = false
|
||||||
|
@filters = []
|
||||||
|
|
||||||
source = Pathname(source) if source && source.is_a?(String)
|
source_file = Pathname(source_file) if source_file && source_file.is_a?(String)
|
||||||
|
|
||||||
@file_descriptor = if source && source.is_a?(Pathname)
|
@file_descriptor = if source_file && source_file.is_a?(Pathname)
|
||||||
::Middleman::SourceFile.new(source.relative_path_from(@app.source_dir), source, @app.source_dir, Set.new([:source]), 0)
|
::Middleman::SourceFile.new(source_file.relative_path_from(@app.source_dir), source_file, @app.source_dir, Set.new([:source]), 0)
|
||||||
else
|
else
|
||||||
source
|
source_file
|
||||||
end
|
end
|
||||||
|
|
||||||
@destination_path = @path
|
@destination_path = @path
|
||||||
|
@ -80,14 +83,14 @@ module Middleman
|
||||||
|
|
||||||
# Backwards compatible method for turning descriptor into a string.
|
# Backwards compatible method for turning descriptor into a string.
|
||||||
# @return [String]
|
# @return [String]
|
||||||
Contract Maybe[String]
|
Contract String
|
||||||
def source_file
|
def source_file
|
||||||
file_descriptor && file_descriptor[:full_path].to_s
|
file_descriptor && file_descriptor[:full_path].to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
Contract Or[Symbol, String, Fixnum]
|
Contract Or[Symbol, String, Fixnum]
|
||||||
def page_id
|
def page_id
|
||||||
metadata[:page][:id] || make_implicit_page_id(destination_path)
|
metadata[:page][:id] || destination_path
|
||||||
end
|
end
|
||||||
|
|
||||||
# Merge in new metadata specific to this resource.
|
# Merge in new metadata specific to this resource.
|
||||||
|
@ -138,8 +141,45 @@ module Middleman
|
||||||
|
|
||||||
# Render this resource
|
# Render this resource
|
||||||
# @return [String]
|
# @return [String]
|
||||||
Contract Hash, Hash => String
|
# Contract Maybe[Hash], Maybe[Hash], Maybe[Proc] => String
|
||||||
def render(opts={}, locs={})
|
def render(opts={}, locs={})
|
||||||
|
body = render_without_filters(opts, locs)
|
||||||
|
|
||||||
|
return body if @filters.empty?
|
||||||
|
|
||||||
|
sortable_filters = @filters.select { |f| f.respond_to?(:filter_name) }.sort do |a, b|
|
||||||
|
if b.after_filter == a.filter_name
|
||||||
|
1
|
||||||
|
else
|
||||||
|
-1
|
||||||
|
end
|
||||||
|
end.reverse
|
||||||
|
|
||||||
|
n = 0
|
||||||
|
sorted_filters = @filters.sort_by do |m|
|
||||||
|
n += 1
|
||||||
|
idx = sortable_filters.index(m)
|
||||||
|
|
||||||
|
[idx.nil? ? 0 : idx, n]
|
||||||
|
end
|
||||||
|
|
||||||
|
sorted_filters.reduce(body) do |output, filter|
|
||||||
|
if block_given? && !yield(filter)
|
||||||
|
output
|
||||||
|
elsif filter.respond_to?(:execute_filter)
|
||||||
|
filter.execute_filter(output)
|
||||||
|
elsif filter.respond_to?(:call)
|
||||||
|
filter.call(output)
|
||||||
|
else
|
||||||
|
output
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Render this resource without content filters
|
||||||
|
# @return [String]
|
||||||
|
Contract Hash, Hash => String
|
||||||
|
def render_without_filters(opts={}, locs={})
|
||||||
return ::Middleman::FileRenderer.new(@app, file_descriptor[:full_path].to_s).template_data_for_file unless template?
|
return ::Middleman::FileRenderer.new(@app, file_descriptor[:full_path].to_s).template_data_for_file unless template?
|
||||||
|
|
||||||
md = metadata
|
md = metadata
|
||||||
|
@ -151,7 +191,7 @@ module Middleman
|
||||||
opts[:layout] = false if !opts.key?(:layout) && !@app.config.extensions_with_layout.include?(ext)
|
opts[:layout] = false if !opts.key?(:layout) && !@app.config.extensions_with_layout.include?(ext)
|
||||||
|
|
||||||
renderer = ::Middleman::TemplateRenderer.new(@app, file_descriptor[:full_path].to_s)
|
renderer = ::Middleman::TemplateRenderer.new(@app, file_descriptor[:full_path].to_s)
|
||||||
renderer.render(locs, opts)
|
renderer.render(locs, opts).to_str
|
||||||
end
|
end
|
||||||
|
|
||||||
# A path without the directory index - so foo/index.html becomes
|
# A path without the directory index - so foo/index.html becomes
|
||||||
|
@ -197,47 +237,17 @@ module Middleman
|
||||||
options[:content_type] || ::Rack::Mime.mime_type(ext, nil)
|
options[:content_type] || ::Rack::Mime.mime_type(ext, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
# The normalized source path of this resource (relative to the source directory,
|
|
||||||
# without template extensions)
|
|
||||||
# @return [String]
|
|
||||||
def normalized_path
|
|
||||||
@normalized_path ||= ::Middleman::Util.normalize_path @path
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
"#<#{self.class} path=#{@path}>"
|
"#<#{self.class} path=#{@path}>"
|
||||||
end
|
end
|
||||||
alias inspect to_s # Ruby 2.0 calls inspect for NoMethodError instead of to_s
|
alias inspect to_s # Ruby 2.0 calls inspect for NoMethodError instead of to_s
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
# Makes a page id based on path (when not otherwise given)
|
|
||||||
#
|
|
||||||
# Removes .html extension and potential leading slashes or dots
|
|
||||||
# eg. "foo/bar/baz.foo.html" => "foo/bar/baz.foo"
|
|
||||||
Contract String => String
|
|
||||||
def make_implicit_page_id(path)
|
|
||||||
@id ||= begin
|
|
||||||
if prok = @app.config[:page_id_generator]
|
|
||||||
return prok.call(path)
|
|
||||||
end
|
|
||||||
|
|
||||||
basename = if ext == ".html"
|
|
||||||
File.basename(path, ext)
|
|
||||||
else
|
|
||||||
File.basename(path)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Remove leading dot or slash if present
|
|
||||||
File.join(File.dirname(path), basename).gsub(/^\.?\//, '')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class StringResource < Resource
|
class StringResource < Resource
|
||||||
def initialize(store, path, contents=nil, &block)
|
Contract IsA['Middleman::Sitemap::Store'], String, Maybe[Or[String, Proc]] => Any
|
||||||
|
def initialize(store, path, contents)
|
||||||
@request_path = path
|
@request_path = path
|
||||||
@contents = block_given? ? block : contents
|
@contents = contents
|
||||||
super(store, path)
|
super(store, path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -246,7 +256,28 @@ module Middleman
|
||||||
end
|
end
|
||||||
|
|
||||||
def render(*)
|
def render(*)
|
||||||
@contents.respond_to?(:call) ? @contents.call : @contents
|
@contents
|
||||||
|
end
|
||||||
|
|
||||||
|
def binary?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class CallbackResource < Resource
|
||||||
|
Contract IsA['Middleman::Sitemap::Store'], String, Proc => Any
|
||||||
|
def initialize(store, path, &block)
|
||||||
|
@request_path = path
|
||||||
|
@contents = block
|
||||||
|
super(store, path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def template?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def render(*)
|
||||||
|
@contents.call
|
||||||
end
|
end
|
||||||
|
|
||||||
def binary?
|
def binary?
|
||||||
|
|
|
@ -102,7 +102,7 @@ module Middleman
|
||||||
# @param [Numeric] priority Sets the order of this resource list manipulator relative to the rest. By default this is 50, and manipulators run in the order they are registered, but if a priority is provided then this will run ahead of or behind other manipulators.
|
# @param [Numeric] priority Sets the order of this resource list manipulator relative to the rest. By default this is 50, and manipulators run in the order they are registered, but if a priority is provided then this will run ahead of or behind other manipulators.
|
||||||
# @param [Symbol] custom_name The method name to execute.
|
# @param [Symbol] custom_name The method name to execute.
|
||||||
# @return [void]
|
# @return [void]
|
||||||
Contract Symbol, RespondTo[:manipulate_resource_list], Maybe[Num, Bool], Maybe[Symbol] => Any
|
Contract Symbol, RespondTo[:manipulate_resource_list], Maybe[Num], Maybe[Symbol] => Any
|
||||||
def register_resource_list_manipulator(name, manipulator, priority=50, custom_name=nil)
|
def register_resource_list_manipulator(name, manipulator, priority=50, custom_name=nil)
|
||||||
# The third argument used to be a boolean - handle those who still pass one
|
# The third argument used to be a boolean - handle those who still pass one
|
||||||
priority = 50 unless priority.is_a? Numeric
|
priority = 50 unless priority.is_a? Numeric
|
||||||
|
|
|
@ -8,10 +8,6 @@ module Middleman
|
||||||
::Middleman::Sources.file_cache[full_path] ||= {}
|
::Middleman::Sources.file_cache[full_path] ||= {}
|
||||||
::Middleman::Sources.file_cache[full_path][version] ||= ::File.read(full_path)
|
::Middleman::Sources.file_cache[full_path][version] ||= ::File.read(full_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
def normalized_relative_path
|
|
||||||
@normalized_relative_path ||= ::Middleman::Util.normalize_path relative_path.to_s
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sources handle multiple on-disk collections of files which make up
|
# Sources handle multiple on-disk collections of files which make up
|
||||||
|
@ -56,13 +52,15 @@ module Middleman
|
||||||
# @param [Hash] options Global options.
|
# @param [Hash] options Global options.
|
||||||
# @param [Array] watchers Default watchers.
|
# @param [Array] watchers Default watchers.
|
||||||
Contract IsA['Middleman::Application'], Maybe[Hash], Maybe[Array] => Any
|
Contract IsA['Middleman::Application'], Maybe[Hash], Maybe[Array] => Any
|
||||||
def initialize(app, _options={}, watchers=[])
|
def initialize(app, options={}, watchers=[])
|
||||||
@app = app
|
@app = app
|
||||||
@watchers = watchers
|
@watchers = watchers
|
||||||
@sorted_watchers = @watchers.dup.freeze
|
@sorted_watchers = @watchers.dup.freeze
|
||||||
|
|
||||||
::Middleman::Sources.file_cache = {}
|
::Middleman::Sources.file_cache = {}
|
||||||
|
|
||||||
|
@options = options
|
||||||
|
|
||||||
# Set of procs wanting to be notified of changes
|
# Set of procs wanting to be notified of changes
|
||||||
@on_change_callbacks = ::Hamster::Vector.empty
|
@on_change_callbacks = ::Hamster::Vector.empty
|
||||||
|
|
||||||
|
@ -170,7 +168,7 @@ module Middleman
|
||||||
# @return [Middleman::Sources]
|
# @return [Middleman::Sources]
|
||||||
Contract Symbol => ::Middleman::Sources
|
Contract Symbol => ::Middleman::Sources
|
||||||
def by_type(type)
|
def by_type(type)
|
||||||
self.class.new @app, nil, watchers.select { |d| d.type == type }
|
self.class.new @app, @options, watchers.select { |d| d.type == type }
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get all files for this collection of watchers.
|
# Get all files for this collection of watchers.
|
||||||
|
|
|
@ -75,10 +75,9 @@ module Middleman
|
||||||
@ignored = options.fetch(:ignored, proc { false })
|
@ignored = options.fetch(:ignored, proc { false })
|
||||||
@only = Array(options.fetch(:only, []))
|
@only = Array(options.fetch(:only, []))
|
||||||
|
|
||||||
@disable_watcher = app.build?
|
@disable_watcher = app.build? || @parent.options.fetch(:disable_watcher, false)
|
||||||
@force_polling = false
|
@force_polling = @parent.options.fetch(:force_polling, false)
|
||||||
@latency = nil
|
@latency = @parent.options.fetch(:latency, nil)
|
||||||
@wait_for_delay = nil
|
|
||||||
|
|
||||||
@listener = nil
|
@listener = nil
|
||||||
|
|
||||||
|
@ -96,20 +95,13 @@ module Middleman
|
||||||
def update_path(directory)
|
def update_path(directory)
|
||||||
@directory = Pathname(File.expand_path(directory, app.root))
|
@directory = Pathname(File.expand_path(directory, app.root))
|
||||||
|
|
||||||
without_listener_running do
|
stop_listener! if @listener
|
||||||
|
|
||||||
update([], @files.values.map { |source_file| source_file[:full_path] })
|
update([], @files.values.map { |source_file| source_file[:full_path] })
|
||||||
end
|
|
||||||
|
|
||||||
poll_once!
|
poll_once!
|
||||||
end
|
|
||||||
|
|
||||||
def update_config(options={})
|
listen! unless @disable_watcher
|
||||||
without_listener_running do
|
|
||||||
@disable_watcher = options.fetch(:disable_watcher, false)
|
|
||||||
@force_polling = options.fetch(:force_polling, false)
|
|
||||||
@latency = options.fetch(:latency, nil)
|
|
||||||
@wait_for_delay = options.fetch(:wait_for_delay, nil)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Stop watching.
|
# Stop watching.
|
||||||
|
@ -168,10 +160,10 @@ module Middleman
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
force_polling: @force_polling,
|
force_polling: @force_polling,
|
||||||
|
wait_for_delay: 0.5
|
||||||
}
|
}
|
||||||
|
|
||||||
config[:wait_for_delay] = @wait_for_delay.try(:to_f) || 0.5
|
config[:latency] = @latency if @latency
|
||||||
config[:latency] = @latency.to_f if @latency
|
|
||||||
|
|
||||||
@listener = ::Listen.to(@directory.to_s, config, &method(:on_listener_change))
|
@listener = ::Listen.to(@directory.to_s, config, &method(:on_listener_change))
|
||||||
|
|
||||||
|
@ -207,7 +199,7 @@ module Middleman
|
||||||
Contract ArrayOf[Pathname]
|
Contract ArrayOf[Pathname]
|
||||||
def poll_once!
|
def poll_once!
|
||||||
updated = ::Middleman::Util.all_files_under(@directory.to_s, &method(:should_not_recurse?))
|
updated = ::Middleman::Util.all_files_under(@directory.to_s, &method(:should_not_recurse?))
|
||||||
removed = @files.keys - updated
|
removed = @files.keys.reject { |p| updated.include?(p) }
|
||||||
|
|
||||||
result = update(updated, removed)
|
result = update(updated, removed)
|
||||||
|
|
||||||
|
@ -351,20 +343,5 @@ module Middleman
|
||||||
@only.any? { |reg| file[:relative_path].to_s =~ reg }
|
@only.any? { |reg| file[:relative_path].to_s =~ reg }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def without_listener_running
|
|
||||||
listener_running = @listener && @listener.processing?
|
|
||||||
|
|
||||||
stop_listener! if listener_running
|
|
||||||
|
|
||||||
yield
|
|
||||||
|
|
||||||
if listener_running
|
|
||||||
poll_once!
|
|
||||||
listen!
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -127,34 +127,30 @@ module Middleman
|
||||||
# @return [String]
|
# @return [String]
|
||||||
Contract String, Maybe[Bool] => Maybe[IsA['Middleman::SourceFile']]
|
Contract String, Maybe[Bool] => Maybe[IsA['Middleman::SourceFile']]
|
||||||
def locate_partial(partial_path, try_static=true)
|
def locate_partial(partial_path, try_static=true)
|
||||||
partial_file = nil
|
return unless resource = sitemap.find_resource_by_destination_path(current_path)
|
||||||
lookup_stack = []
|
|
||||||
non_root = partial_path.to_s.sub(/^\//, '')
|
|
||||||
non_root_no_underscore = non_root.sub(/^_/, '').sub(/\/_/, '/')
|
|
||||||
|
|
||||||
if resource = current_resource
|
# Look for partials relative to the current path
|
||||||
current_dir = resource.file_descriptor[:relative_path].dirname
|
current_dir = resource.file_descriptor[:relative_path].dirname
|
||||||
|
non_root = partial_path.to_s.sub(/^\//, '')
|
||||||
relative_dir = current_dir + Pathname(non_root)
|
relative_dir = current_dir + Pathname(non_root)
|
||||||
|
|
||||||
|
non_root_no_underscore = non_root.sub(/^_/, '').sub(/\/_/, '/')
|
||||||
relative_dir_no_underscore = current_dir + Pathname(non_root_no_underscore)
|
relative_dir_no_underscore = current_dir + Pathname(non_root_no_underscore)
|
||||||
end
|
|
||||||
|
|
||||||
lookup_stack.push [relative_dir.to_s,
|
partial_file = nil
|
||||||
{ preferred_engine: resource.file_descriptor[:relative_path]
|
|
||||||
.extname[1..-1].to_sym }] if relative_dir
|
|
||||||
lookup_stack.push [non_root]
|
|
||||||
lookup_stack.push [non_root,
|
|
||||||
{ try_static: try_static }]
|
|
||||||
lookup_stack.push [relative_dir_no_underscore.to_s,
|
|
||||||
{ try_static: try_static }] if relative_dir_no_underscore
|
|
||||||
lookup_stack.push [non_root_no_underscore,
|
|
||||||
{ try_static: try_static }]
|
|
||||||
|
|
||||||
lookup_stack.each do |args|
|
[
|
||||||
|
[relative_dir.to_s, { preferred_engine: resource.file_descriptor[:relative_path].extname[1..-1].to_sym }],
|
||||||
|
[non_root],
|
||||||
|
[non_root, { try_static: try_static }],
|
||||||
|
[relative_dir_no_underscore.to_s, { try_static: try_static }],
|
||||||
|
[non_root_no_underscore, { try_static: try_static }]
|
||||||
|
].each do |args|
|
||||||
partial_file = ::Middleman::TemplateRenderer.resolve_template(@app, *args)
|
partial_file = ::Middleman::TemplateRenderer.resolve_template(@app, *args)
|
||||||
break if partial_file
|
break if partial_file
|
||||||
end
|
end
|
||||||
|
|
||||||
partial_file
|
partial_file || nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def current_path
|
def current_path
|
||||||
|
|
|
@ -64,7 +64,9 @@ module Middleman
|
||||||
extension_class = ::Middleman::Util.tilt_class(options[:preferred_engine])
|
extension_class = ::Middleman::Util.tilt_class(options[:preferred_engine])
|
||||||
|
|
||||||
# Get a list of extensions for a preferred engine
|
# Get a list of extensions for a preferred engine
|
||||||
preferred_engines += ::Tilt.default_mapping.extensions_for(extension_class)
|
preferred_engines += ::Tilt.mappings.select do |_, engines|
|
||||||
|
engines.include? extension_class
|
||||||
|
end.keys
|
||||||
end
|
end
|
||||||
|
|
||||||
preferred_engines << '*'
|
preferred_engines << '*'
|
||||||
|
|
|
@ -47,13 +47,14 @@ module Middleman
|
||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
Contract String => Bool
|
Contract String => Bool
|
||||||
def nonbinary_mime?(mime)
|
def nonbinary_mime?(mime)
|
||||||
if mime.start_with?('text/')
|
case
|
||||||
|
when mime.start_with?('text/')
|
||||||
true
|
true
|
||||||
elsif mime.include?('xml') && !mime.include?('officedocument')
|
when mime.include?('xml') && !mime.include?('officedocument')
|
||||||
true
|
true
|
||||||
elsif mime.include?('json')
|
when mime.include?('json')
|
||||||
true
|
true
|
||||||
elsif mime.include?('javascript')
|
when mime.include?('javascript')
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
|
|
|
@ -56,10 +56,8 @@ module Middleman
|
||||||
|
|
||||||
Contract String => String
|
Contract String => String
|
||||||
def step_through_extensions(path)
|
def step_through_extensions(path)
|
||||||
while ::Middleman::Util.tilt_class(path)
|
while ext = File.extname(path)
|
||||||
ext = ::File.extname(path)
|
break if ext.empty? || !::Middleman::Util.tilt_class(ext)
|
||||||
break if ext.empty?
|
|
||||||
|
|
||||||
yield ext if block_given?
|
yield ext if block_given?
|
||||||
|
|
||||||
# Strip templating extensions as long as Tilt knows them
|
# Strip templating extensions as long as Tilt knows them
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# Core Pathname library used for traversal
|
# Core Pathname library used for traversal
|
||||||
require 'pathname'
|
require 'pathname'
|
||||||
require 'uri'
|
require 'uri'
|
||||||
require 'addressable/uri'
|
|
||||||
require 'memoist'
|
require 'memoist'
|
||||||
|
require 'addressable'
|
||||||
require 'tilt'
|
require 'tilt'
|
||||||
|
|
||||||
require 'middleman-core/contracts'
|
require 'middleman-core/contracts'
|
||||||
|
@ -25,13 +25,15 @@ module Middleman
|
||||||
def tilt_class(path)
|
def tilt_class(path)
|
||||||
::Tilt[path]
|
::Tilt[path]
|
||||||
end
|
end
|
||||||
memoize :tilt_class
|
# memoize :tilt_class
|
||||||
|
|
||||||
# Normalize a path to not include a leading slash
|
# Normalize a path to not include a leading slash
|
||||||
# @param [String] path
|
# @param [String] path
|
||||||
# @return [String]
|
# @return [String]
|
||||||
Contract String => String
|
Contract Any => String
|
||||||
def normalize_path(path)
|
def normalize_path(path)
|
||||||
|
return path unless path.is_a?(String)
|
||||||
|
|
||||||
# The tr call works around a bug in Ruby's Unicode handling
|
# The tr call works around a bug in Ruby's Unicode handling
|
||||||
::URI.decode(path).sub(%r{^/}, '').tr('', '')
|
::URI.decode(path).sub(%r{^/}, '').tr('', '')
|
||||||
end
|
end
|
||||||
|
@ -111,16 +113,14 @@ module Middleman
|
||||||
raise ArgumentError, '#asset_url must be run in a context with current_resource if relative: true'
|
raise ArgumentError, '#asset_url must be run in a context with current_resource if relative: true'
|
||||||
end
|
end
|
||||||
|
|
||||||
uri = ::Middleman::Util.parse_uri(path)
|
uri = URI(path)
|
||||||
path = uri.path
|
path = uri.path
|
||||||
|
|
||||||
# Ensure the url we pass into find_resource_by_destination_path is not a
|
# Ensure the url we pass into find_resource_by_destination_path is not a
|
||||||
# relative path, since it only takes absolute url paths.
|
# relative path, since it only takes absolute url paths.
|
||||||
dest_path = url_for(app, path, options.merge(relative: false))
|
dest_path = url_for(app, path, options.merge(relative: false))
|
||||||
|
|
||||||
result = if resource = app.sitemap.find_resource_by_path(dest_path)
|
result = if resource = app.sitemap.find_resource_by_destination_path(dest_path)
|
||||||
resource.url
|
|
||||||
elsif resource = app.sitemap.find_resource_by_destination_path(dest_path)
|
|
||||||
resource.url
|
resource.url
|
||||||
else
|
else
|
||||||
path = ::File.join(prefix, path)
|
path = ::File.join(prefix, path)
|
||||||
|
@ -131,15 +131,9 @@ module Middleman
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
final_result = ::Addressable::URI.encode(
|
final_result = ::URI.encode(relative_path_from_resource(options[:current_resource], result, options[:relative]))
|
||||||
relative_path_from_resource(
|
|
||||||
options[:current_resource],
|
|
||||||
result,
|
|
||||||
options[:relative]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
result_uri = ::Middleman::Util.parse_uri(final_result)
|
result_uri = URI(final_result)
|
||||||
result_uri.query = uri.query
|
result_uri.query = uri.query
|
||||||
result_uri.fragment = uri.fragment
|
result_uri.fragment = uri.fragment
|
||||||
result_uri.to_s
|
result_uri.to_s
|
||||||
|
@ -152,8 +146,7 @@ module Middleman
|
||||||
def url_for(app, path_or_resource, options={})
|
def url_for(app, path_or_resource, options={})
|
||||||
if path_or_resource.is_a?(String) || path_or_resource.is_a?(Symbol)
|
if path_or_resource.is_a?(String) || path_or_resource.is_a?(Symbol)
|
||||||
r = app.sitemap.find_resource_by_page_id(path_or_resource)
|
r = app.sitemap.find_resource_by_page_id(path_or_resource)
|
||||||
|
path_or_resource = r if r
|
||||||
path_or_resource = r ? r : path_or_resource.to_s
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Handle Resources and other things which define their own url method
|
# Handle Resources and other things which define their own url method
|
||||||
|
@ -165,8 +158,8 @@ module Middleman
|
||||||
|
|
||||||
# Try to parse URL
|
# Try to parse URL
|
||||||
begin
|
begin
|
||||||
uri = ::Middleman::Util.parse_uri(url)
|
uri = URI(url)
|
||||||
rescue ::Addressable::URI::InvalidURIError
|
rescue ::URI::InvalidURIError
|
||||||
# Nothing we can do with it, it's not really a URI
|
# Nothing we can do with it, it's not really a URI
|
||||||
return url
|
return url
|
||||||
end
|
end
|
||||||
|
@ -209,13 +202,7 @@ module Middleman
|
||||||
|
|
||||||
if resource
|
if resource
|
||||||
uri.path = if this_resource
|
uri.path = if this_resource
|
||||||
::Addressable::URI.encode(
|
::URI.encode(relative_path_from_resource(this_resource, resource_url, effective_relative))
|
||||||
relative_path_from_resource(
|
|
||||||
this_resource,
|
|
||||||
resource_url,
|
|
||||||
effective_relative
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else
|
else
|
||||||
resource_url
|
resource_url
|
||||||
end
|
end
|
||||||
|
@ -293,15 +280,16 @@ module Middleman
|
||||||
# @return [Boolean] Whether the path matches the matcher
|
# @return [Boolean] Whether the path matches the matcher
|
||||||
Contract PATH_MATCHER, String => Bool
|
Contract PATH_MATCHER, String => Bool
|
||||||
def path_match(matcher, path)
|
def path_match(matcher, path)
|
||||||
if matcher.is_a?(String)
|
case
|
||||||
|
when matcher.is_a?(String)
|
||||||
if matcher.include? '*'
|
if matcher.include? '*'
|
||||||
::File.fnmatch(matcher, path)
|
::File.fnmatch(matcher, path)
|
||||||
else
|
else
|
||||||
path == matcher
|
path == matcher
|
||||||
end
|
end
|
||||||
elsif matcher.respond_to?(:match)
|
when matcher.respond_to?(:match)
|
||||||
!!(path =~ matcher)
|
!!(path =~ matcher)
|
||||||
elsif matcher.respond_to?(:call)
|
when matcher.respond_to?(:call)
|
||||||
matcher.call(path)
|
matcher.call(path)
|
||||||
else
|
else
|
||||||
::File.fnmatch(matcher.to_s, path)
|
::File.fnmatch(matcher.to_s, path)
|
||||||
|
|
|
@ -6,22 +6,9 @@ module Middleman
|
||||||
|
|
||||||
module_function
|
module_function
|
||||||
|
|
||||||
# Extract the text of a Rack response as a string.
|
Contract String, String, SetOf[String], IsA['::Middleman::Application'], Proc => String
|
||||||
# Useful for extensions implemented as Rack middleware.
|
|
||||||
# @param response The response from #call
|
|
||||||
# @return [String] The whole response as a string.
|
|
||||||
Contract RespondTo[:each] => String
|
|
||||||
def extract_response_text(response)
|
|
||||||
# The rack spec states all response bodies must respond to each
|
|
||||||
result = ''
|
|
||||||
response.each do |part, _|
|
|
||||||
result << part
|
|
||||||
end
|
|
||||||
result
|
|
||||||
end
|
|
||||||
|
|
||||||
Contract String, String, ArrayOf[String], IsA['::Middleman::Application'], Proc => String
|
|
||||||
def rewrite_paths(body, path, exts, app, &_block)
|
def rewrite_paths(body, path, exts, app, &_block)
|
||||||
|
exts = exts.sort_by(&:length).reverse
|
||||||
matcher = /([\'\"\(,]\s*|# sourceMappingURL=)([^\s\'\"\)\(>]+(#{::Regexp.union(exts)}))/
|
matcher = /([\'\"\(,]\s*|# sourceMappingURL=)([^\s\'\"\)\(>]+(#{::Regexp.union(exts)}))/
|
||||||
|
|
||||||
url_fn_prefix = 'url('
|
url_fn_prefix = 'url('
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
module Middleman
|
module Middleman
|
||||||
# Current Version
|
# Current Version
|
||||||
# @return [String]
|
# @return [String]
|
||||||
VERSION = '4.1.14'.freeze unless const_defined?(:VERSION)
|
VERSION = '4.2.0'.freeze unless const_defined?(:VERSION)
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,20 +16,19 @@ Gem::Specification.new do |s|
|
||||||
s.files = `git ls-files -z`.split("\0")
|
s.files = `git ls-files -z`.split("\0")
|
||||||
s.test_files = `git ls-files -z -- {fixtures,features}/*`.split("\0")
|
s.test_files = `git ls-files -z -- {fixtures,features}/*`.split("\0")
|
||||||
s.require_path = 'lib'
|
s.require_path = 'lib'
|
||||||
s.required_ruby_version = '>= 2.2.0'
|
s.required_ruby_version = '>= 2.0.0'
|
||||||
|
|
||||||
# Core
|
# Core
|
||||||
s.add_dependency('bundler', ['~> 1.1'])
|
s.add_dependency('bundler', ['~> 1.1'])
|
||||||
s.add_dependency('rack', ['>= 1.4.5', '< 3'])
|
s.add_dependency('rack', ['>= 1.4.5', '< 2.0'])
|
||||||
s.add_dependency('tilt', ['~> 2.0'])
|
s.add_dependency('tilt', ['~> 1.4.1'])
|
||||||
s.add_dependency('erubis')
|
s.add_dependency('erubis')
|
||||||
s.add_dependency('fast_blank')
|
s.add_dependency('fast_blank')
|
||||||
s.add_dependency('parallel')
|
s.add_dependency('parallel')
|
||||||
s.add_dependency('servolux')
|
s.add_dependency('servolux')
|
||||||
s.add_dependency('dotenv')
|
|
||||||
|
|
||||||
# Helpers
|
# Helpers
|
||||||
s.add_dependency('activesupport', ['>= 4.2', '< 5.1'])
|
s.add_dependency('activesupport', ['~> 4.2'])
|
||||||
s.add_dependency('padrino-helpers', ['~> 0.13.0'])
|
s.add_dependency('padrino-helpers', ['~> 0.13.0'])
|
||||||
s.add_dependency("addressable", ["~> 2.3"])
|
s.add_dependency("addressable", ["~> 2.3"])
|
||||||
s.add_dependency('memoist', ['~> 0.14'])
|
s.add_dependency('memoist', ['~> 0.14'])
|
||||||
|
@ -38,7 +37,7 @@ Gem::Specification.new do |s|
|
||||||
s.add_dependency('listen', ['~> 3.0.0'])
|
s.add_dependency('listen', ['~> 3.0.0'])
|
||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
s.add_development_dependency("capybara", ["~> 2.5.0"])
|
s.add_dependency("capybara", ["~> 2.5.0"])
|
||||||
|
|
||||||
# i18n
|
# i18n
|
||||||
s.add_dependency('i18n', ['~> 0.7.0'])
|
s.add_dependency('i18n', ['~> 0.7.0'])
|
||||||
|
|
|
@ -162,13 +162,6 @@ describe Middleman::Util do
|
||||||
expect( Middleman::Util.asset_url( @mm, '/how/about/that.html' ) ).to eq '/how/about/that/'
|
expect( Middleman::Util.asset_url( @mm, '/how/about/that.html' ) ).to eq '/how/about/that/'
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns a resource url when asset_hash is on" do
|
|
||||||
Given.fixture 'asset-hash-app'
|
|
||||||
@mm = Middleman::Application.new
|
|
||||||
|
|
||||||
expect( Middleman::Util.asset_url( @mm, '100px.png', 'images') ).to match %r|/images/100px-[a-f0-9]+.png|
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "::find_related_files" do
|
describe "::find_related_files" do
|
||||||
|
@ -220,7 +213,7 @@ describe Middleman::Util do
|
||||||
|
|
||||||
it "does not loop infinitely when file name is a possible templating engine" do
|
it "does not loop infinitely when file name is a possible templating engine" do
|
||||||
expect do
|
expect do
|
||||||
Timeout::timeout(3.0) do
|
Timeout::timeout(0.5) do
|
||||||
result = Middleman::Util.step_through_extensions("markdown.scss")
|
result = Middleman::Util.step_through_extensions("markdown.scss")
|
||||||
expect(result).to eq "markdown"
|
expect(result).to eq "markdown"
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,7 +16,7 @@ Gem::Specification.new do |s|
|
||||||
s.files = `git ls-files -z`.split("\0")
|
s.files = `git ls-files -z`.split("\0")
|
||||||
s.test_files = `git ls-files -z -- {fixtures,features}/*`.split("\0")
|
s.test_files = `git ls-files -z -- {fixtures,features}/*`.split("\0")
|
||||||
s.require_path = 'lib'
|
s.require_path = 'lib'
|
||||||
s.required_ruby_version = '>= 2.2.0'
|
s.required_ruby_version = '>= 2.0.0'
|
||||||
|
|
||||||
s.add_dependency('middleman-core', Middleman::VERSION)
|
s.add_dependency('middleman-core', Middleman::VERSION)
|
||||||
s.add_dependency('middleman-cli', Middleman::VERSION)
|
s.add_dependency('middleman-cli', Middleman::VERSION)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue