middleman 0.99.0.pre → 0.99.1.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +1 -1
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/bin/mm-build +1 -1
- data/bin/mm-init +1 -1
- data/bin/mm-server +3 -3
- data/features/step_definitions/asset_host_steps.rb +3 -3
- data/features/step_definitions/middleman_steps.rb +2 -3
- data/features/step_definitions/page_layout_steps.rb +6 -6
- data/lib/middleman.rb +1 -1
- data/lib/middleman/assets.rb +1 -1
- data/lib/middleman/builder.rb +7 -6
- data/lib/middleman/config.ru +1 -1
- data/lib/middleman/features.rb +7 -5
- data/lib/middleman/features/asset_host.rb +5 -5
- data/lib/middleman/features/automatic_image_sizes.rb +4 -4
- data/lib/middleman/features/automatic_image_sizes/fastimage.rb +214 -209
- data/lib/middleman/features/cache_buster.rb +7 -7
- data/lib/middleman/features/default_helpers.rb +2 -2
- data/lib/middleman/features/livereload.rb +3 -3
- data/lib/middleman/features/minify_css.rb +2 -2
- data/lib/middleman/features/minify_javascript.rb +1 -1
- data/lib/middleman/features/relative_assets.rb +3 -3
- data/lib/middleman/features/slickmap.rb +38 -68
- data/lib/middleman/features/slickmap/template.html.haml +27 -0
- data/lib/middleman/features/smush_pngs.rb +6 -6
- data/lib/middleman/features/ugly_haml.rb +2 -2
- data/lib/middleman/renderers/coffee.rb +1 -1
- data/lib/middleman/renderers/haml.rb +1 -1
- data/lib/middleman/renderers/sass.rb +5 -5
- data/lib/middleman/server.rb +168 -0
- data/lib/middleman/template/{init.rbt → config.rbt} +0 -0
- data/lib/middleman/templater+dynamic_renderer.rb +2 -2
- data/middleman.gemspec +9 -8
- data/spec/fixtures/sample/{init.rb → config.rb} +0 -0
- data/spec/helpers_spec.rb +1 -1
- metadata +11 -10
- data/lib/middleman/base.rb +0 -147
@@ -1,5 +1,5 @@
|
|
1
1
|
class Middleman::Features::CacheBuster
|
2
|
-
def initialize(app)
|
2
|
+
def initialize(app, config)
|
3
3
|
Middleman::Assets.register :cache_buster do |path, prefix, request|
|
4
4
|
http_path = Middleman::Assets.before(:cache_buster, path, prefix, request)
|
5
5
|
|
@@ -7,16 +7,16 @@ class Middleman::Features::CacheBuster
|
|
7
7
|
http_path
|
8
8
|
else
|
9
9
|
begin
|
10
|
-
prefix = Middleman::
|
10
|
+
prefix = Middleman::Server.images_dir if prefix == Middleman::Server.http_images_path
|
11
11
|
rescue
|
12
12
|
end
|
13
13
|
|
14
|
-
real_path_static = File.join(Middleman::
|
14
|
+
real_path_static = File.join(Middleman::Server.public, prefix, path)
|
15
15
|
|
16
16
|
if File.readable?(real_path_static)
|
17
17
|
http_path << "?" + File.mtime(real_path_static).strftime("%s")
|
18
|
-
elsif Middleman::
|
19
|
-
real_path_dynamic = File.join(Middleman::
|
18
|
+
elsif Middleman::Server.environment == :build
|
19
|
+
real_path_dynamic = File.join(Middleman::Server.root, Middleman::Server.build_dir, prefix, path)
|
20
20
|
http_path << "?" + File.mtime(real_path_dynamic).strftime("%s") if File.readable?(real_path_dynamic)
|
21
21
|
end
|
22
22
|
|
@@ -24,11 +24,11 @@ class Middleman::Features::CacheBuster
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
Middleman::
|
27
|
+
Middleman::Server.after_feature_init do
|
28
28
|
::Compass.configuration do |config|
|
29
29
|
config.asset_cache_buster do |path, real_path|
|
30
30
|
real_path = real_path.path if real_path.is_a? File
|
31
|
-
real_path = real_path.gsub(File.join(Middleman::
|
31
|
+
real_path = real_path.gsub(File.join(Middleman::Server.root, Middleman::Server.build_dir), Middleman::Server.public)
|
32
32
|
if File.readable?(real_path)
|
33
33
|
File.mtime(real_path).strftime("%s")
|
34
34
|
else
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class Middleman::Features::LiveReload
|
2
|
-
def initialize(app)
|
3
|
-
return unless Middleman::
|
2
|
+
def initialize(app, config)
|
3
|
+
return unless Middleman::Server.environment == :development
|
4
4
|
|
5
5
|
begin
|
6
6
|
require 'livereload'
|
@@ -12,7 +12,7 @@ class Middleman::Features::LiveReload
|
|
12
12
|
config.exts = %w(haml sass scss coffee less builder)
|
13
13
|
end
|
14
14
|
|
15
|
-
::LiveReload.run [Middleman::
|
15
|
+
::LiveReload.run [Middleman::Server.public, Middleman::Server.views], new_config
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -1,10 +1,10 @@
|
|
1
1
|
class Middleman::Features::RelativeAssets
|
2
|
-
def initialize(app)
|
2
|
+
def initialize(app, config)
|
3
3
|
::Compass.configuration.relative_assets = true
|
4
4
|
|
5
5
|
Middleman::Assets.register :relative_assets do |path, prefix, request|
|
6
6
|
begin
|
7
|
-
prefix = Middleman::
|
7
|
+
prefix = Middleman::Server.images_dir if prefix == Middleman::Server.http_images_path
|
8
8
|
rescue
|
9
9
|
end
|
10
10
|
|
@@ -15,7 +15,7 @@ class Middleman::Features::RelativeAssets
|
|
15
15
|
else
|
16
16
|
path = File.join(prefix, path) if prefix.length > 0
|
17
17
|
request_path = request.path_info.dup
|
18
|
-
request_path << Middleman::
|
18
|
+
request_path << Middleman::Server.index_file if path.match(%r{/$})
|
19
19
|
request_path.gsub!(%r{^/}, '')
|
20
20
|
parts = request_path.split('/')
|
21
21
|
|
@@ -1,44 +1,16 @@
|
|
1
1
|
Entry = Struct.new(:dir, :children)
|
2
2
|
|
3
3
|
class Middleman::Features::Slickmap
|
4
|
-
def initialize(app)
|
4
|
+
def initialize(app, config)
|
5
5
|
require 'slickmap'
|
6
6
|
|
7
|
-
|
8
|
-
Middleman::Builder.template :slickmap, "sitemap.html", "sitemap.html"
|
9
|
-
end
|
10
|
-
|
11
|
-
def build_sitemap(&block)
|
12
|
-
@@utility = []
|
13
|
-
[recurse_sitemap(Middleman::Base.views, &block), @@utility]
|
14
|
-
end
|
15
|
-
|
16
|
-
def recurse_sitemap(path, &block)
|
17
|
-
bad_ext = path.split('.html')[1]
|
18
|
-
path = path.gsub(bad_ext, '') if bad_ext
|
19
|
-
entry = Entry.new(path, [])
|
20
|
-
|
21
|
-
#no "." or ".." dirs
|
22
|
-
Dir[File.join(path, "*")].each do |e|
|
23
|
-
next if !File.directory?(e) && !e.include?(".html")
|
24
|
-
if File.directory?(e)
|
25
|
-
entry.children << recurse_sitemap(e, &block)
|
26
|
-
elsif block_given?
|
27
|
-
how_to_handle = block.call(e)
|
28
|
-
if how_to_handle == :valid
|
29
|
-
entry.children << recurse_sitemap(e, &block)
|
30
|
-
elsif how_to_handle == :utility
|
31
|
-
bad_ext = e.split('.html')[1]
|
32
|
-
e = e.gsub(bad_ext, '') if bad_ext
|
33
|
-
@@utility << e.gsub(Middleman::Base.views + "/", '')
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
7
|
+
@sitemap_url = config[:url] || "sitemap.html"
|
37
8
|
|
38
|
-
|
9
|
+
if Middleman::Server.environment == :build
|
10
|
+
Middleman::Builder.template :slickmap, @sitemap_url, @sitemap_url
|
39
11
|
end
|
40
12
|
|
41
|
-
Middleman::
|
13
|
+
Middleman::Server.helpers do
|
42
14
|
def sitemap_node(n, first=false)
|
43
15
|
if n.children.length < 1
|
44
16
|
if !first && File.extname(n.dir).length > 0
|
@@ -72,47 +44,45 @@ class Middleman::Features::Slickmap
|
|
72
44
|
end
|
73
45
|
end
|
74
46
|
|
75
|
-
Middleman::
|
47
|
+
Middleman::Server.get "/#{@sitemap_url}" do
|
76
48
|
# Return :utility to put it util top menu. False to ignore
|
77
|
-
@tree, @utility = build_sitemap do |file_name|
|
49
|
+
@tree, @utility = Middleman::Features::Slickmap.build_sitemap do |file_name|
|
78
50
|
:valid
|
79
51
|
end
|
80
|
-
|
52
|
+
|
53
|
+
haml "template.html".to_sym, :layout => false, :views => File.expand_path(File.join(File.dirname(__FILE__), "slickmap"))
|
81
54
|
end
|
82
|
-
|
83
|
-
Middleman::Base.use_in_file_templates!
|
84
55
|
end
|
85
|
-
|
56
|
+
|
57
|
+
def self.build_sitemap(&block)
|
58
|
+
@@utility = []
|
59
|
+
[recurse_sitemap(Middleman::Server.views, &block), @@utility]
|
60
|
+
end
|
86
61
|
|
87
|
-
|
62
|
+
def self.recurse_sitemap(path, &block)
|
63
|
+
bad_ext = path.split('.html')[1]
|
64
|
+
path = path.gsub(bad_ext, '') if bad_ext
|
65
|
+
entry = Entry.new(path, [])
|
88
66
|
|
89
|
-
|
67
|
+
#no "." or ".." dirs
|
68
|
+
Dir[File.join(path, "*")].each do |e|
|
69
|
+
next if !File.directory?(e) && !e.include?(".html")
|
70
|
+
if File.directory?(e)
|
71
|
+
entry.children << recurse_sitemap(e, &block)
|
72
|
+
elsif block_given?
|
73
|
+
how_to_handle = block.call(e)
|
74
|
+
if how_to_handle == :valid
|
75
|
+
entry.children << recurse_sitemap(e, &block)
|
76
|
+
elsif how_to_handle == :utility
|
77
|
+
bad_ext = e.split('.html')[1]
|
78
|
+
e = e.gsub(bad_ext, '') if bad_ext
|
79
|
+
@@utility << e.gsub(Middleman::Server.views + "/", '')
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
90
83
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
%head
|
95
|
-
%meta{ :content => "text/html; charset=utf-8", "http-equiv" => "Content-type" }
|
96
|
-
%title Sitemap
|
97
|
-
%style{ :type => "text/css" }
|
98
|
-
:sass
|
99
|
-
@import "slickmap"
|
100
|
-
+slickmap
|
101
|
-
:javascript
|
102
|
-
window.onload = function() {
|
103
|
-
document.getElementById('primaryNav').className = "col" + document.querySelectorAll("#primaryNav > li:not(#home)").length;
|
104
|
-
};
|
84
|
+
entry
|
85
|
+
end
|
86
|
+
end
|
105
87
|
|
106
|
-
|
107
|
-
.logo
|
108
|
-
%h1= @project_name || "Sitemap"
|
109
|
-
- if @project_subtitle
|
110
|
-
%h2= @project_subtitle
|
111
|
-
|
112
|
-
- if @utility.length > 0
|
113
|
-
%ul#utilityNav
|
114
|
-
- @utility.each do |u|
|
115
|
-
%li= link_to u, u
|
116
|
-
|
117
|
-
%ul#primaryNav
|
118
|
-
- sitemap_node(@tree, true)
|
88
|
+
Middleman::Features.register :slickmap, Middleman::Features::Slickmap
|
@@ -0,0 +1,27 @@
|
|
1
|
+
!!!
|
2
|
+
%html{ :xmlns => "http://www.w3.org/1999/xhtml" }
|
3
|
+
%head
|
4
|
+
%meta{ :content => "text/html; charset=utf-8", "http-equiv" => "Content-type" }
|
5
|
+
%title Sitemap
|
6
|
+
%style{ :type => "text/css" }
|
7
|
+
:sass
|
8
|
+
@import "slickmap"
|
9
|
+
+slickmap
|
10
|
+
:javascript
|
11
|
+
window.onload = function() {
|
12
|
+
document.getElementById('primaryNav').className = "col" + document.querySelectorAll("#primaryNav > li:not(#home)").length;
|
13
|
+
};
|
14
|
+
|
15
|
+
%body
|
16
|
+
.logo
|
17
|
+
%h1= @project_name || "Sitemap"
|
18
|
+
- if @project_subtitle
|
19
|
+
%h2= @project_subtitle
|
20
|
+
|
21
|
+
- if @utility.length > 0
|
22
|
+
%ul#utilityNav
|
23
|
+
- @utility.each do |u|
|
24
|
+
%li= link_to u, u
|
25
|
+
|
26
|
+
%ul#primaryNav
|
27
|
+
- sitemap_node(@tree, true)
|
@@ -1,14 +1,14 @@
|
|
1
1
|
class Middleman::Features::SmushPngs
|
2
|
-
def initialize(app)
|
2
|
+
def initialize(app, config)
|
3
3
|
require "middleman/builder"
|
4
4
|
|
5
|
-
Middleman::
|
6
|
-
Middleman::
|
5
|
+
Middleman::Server.alias_method :pre_smush_after_run, :after_run
|
6
|
+
Middleman::Server.define_method :after_run do
|
7
7
|
pre_smush_after_run
|
8
|
-
smush_dir = File.join(Middleman::
|
8
|
+
smush_dir = File.join(Middleman::Server.build_dir, Middleman::Server.images_dir)
|
9
9
|
|
10
10
|
# Read cache
|
11
|
-
cache_file = File.join(Middleman::
|
11
|
+
cache_file = File.join(Middleman::Server.root, ".smush-cache")
|
12
12
|
cache_data = if File.exists?(cache_file)
|
13
13
|
Marshal.restore(File.read(cache_file))
|
14
14
|
else
|
@@ -27,7 +27,7 @@ class Middleman::Features::SmushPngs
|
|
27
27
|
write_optimized_data(file)
|
28
28
|
cache_data[file] = size(file) # Add or update cache
|
29
29
|
File.open(cache_file, "w") { |f| f.write Marshal.dump(cache_data) } # Write cache
|
30
|
-
say "<%= color('#{"[SMUSHED]".rjust(12)}', :yellow) %> " + file.gsub(Middleman::
|
30
|
+
say "<%= color('#{"[SMUSHED]".rjust(12)}', :yellow) %> " + file.gsub(Middleman::Server.build_dir+"/", '')
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class Middleman::Features::UglyHaml
|
2
|
-
def initialize(app)
|
3
|
-
Middleman::
|
2
|
+
def initialize(app, config)
|
3
|
+
Middleman::Server.set :haml, Middleman::Server.settings.haml.merge({ :ugly_haml => true })
|
4
4
|
end
|
5
5
|
end
|
6
6
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require "sass"
|
2
2
|
require "compass"
|
3
3
|
|
4
|
-
class Middleman::
|
4
|
+
class Middleman::Server
|
5
5
|
def scss(template, options={}, locals={})
|
6
6
|
options[:layout] = false
|
7
7
|
render :scss, template, options, locals
|
@@ -34,13 +34,13 @@ end
|
|
34
34
|
|
35
35
|
class Tilt::SassPlusCSSFilenameTemplate < Tilt::SassTemplate
|
36
36
|
def sass_options
|
37
|
-
location_of_sass_file = Middleman::
|
38
|
-
File.join(Middleman::
|
39
|
-
Middleman::
|
37
|
+
location_of_sass_file = Middleman::Server.environment == :build ?
|
38
|
+
File.join(Middleman::Server.root, Middleman::Server.build_dir) :
|
39
|
+
Middleman::Server.public
|
40
40
|
|
41
41
|
parts = basename.split('.')
|
42
42
|
parts.pop
|
43
|
-
css_filename = File.join(location_of_sass_file, Middleman::
|
43
|
+
css_filename = File.join(location_of_sass_file, Middleman::Server.css_dir, parts.join("."))
|
44
44
|
super.merge(::Compass.configuration.to_sass_engine_options).merge(:css_filename => css_filename)
|
45
45
|
end
|
46
46
|
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
# We're riding on Sinatra, so let's include it.
|
2
|
+
require "sinatra/base"
|
3
|
+
|
4
|
+
# The content_for plugin allows Sinatra to use the throw/yield block
|
5
|
+
# system similar to Rails views.
|
6
|
+
require "sinatra/content_for"
|
7
|
+
|
8
|
+
# Monkey-patch Sinatra to expose the layout parameter
|
9
|
+
class Sinatra::Request
|
10
|
+
attr_accessor :layout
|
11
|
+
end
|
12
|
+
|
13
|
+
module Middleman
|
14
|
+
class Server < Sinatra::Base
|
15
|
+
# Basic Sinatra config
|
16
|
+
set :app_file, __FILE__
|
17
|
+
set :root, ENV["MM_DIR"] || Dir.pwd
|
18
|
+
set :reload, false
|
19
|
+
set :sessions, false
|
20
|
+
set :logging, false
|
21
|
+
set :environment, (ENV['MM_ENV'] && ENV['MM_ENV'].to_sym) || :development
|
22
|
+
|
23
|
+
# Import content_for methods
|
24
|
+
helpers Sinatra::ContentFor
|
25
|
+
|
26
|
+
# Middleman-specific options
|
27
|
+
set :index_file, "index.html" # What file responds to folder requests
|
28
|
+
# Such as the homepage (/) or subfolders (/about/)
|
29
|
+
|
30
|
+
# These directories are passed directly to Compass
|
31
|
+
set :js_dir, "javascripts" # Where to look for javascript files
|
32
|
+
set :css_dir, "stylesheets" # Where to look for CSS files
|
33
|
+
set :images_dir, "images" # Where to look for images
|
34
|
+
set :fonts_dir, "fonts" # Where to look for fonts
|
35
|
+
|
36
|
+
set :build_dir, "build" # Which folder are builds output to
|
37
|
+
set :http_prefix, nil # During build, add a prefix for absolute paths
|
38
|
+
|
39
|
+
# A hash of enabled features
|
40
|
+
@@enabled_features = {}
|
41
|
+
|
42
|
+
# Override Sinatra's enable to keep track of enabled features
|
43
|
+
def self.enable(feature_name, config={})
|
44
|
+
@@enabled_features[feature_name] = config
|
45
|
+
super(feature_name)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Disable a feature, then pass to Sinatra's method
|
49
|
+
def self.disable(feature_name)
|
50
|
+
@@enabled_features.delete(feature_name)
|
51
|
+
super(feature_name)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Override Sinatra's set to accept a block
|
55
|
+
def self.set(option, value=self, &block)
|
56
|
+
if block_given?
|
57
|
+
value = Proc.new { block }
|
58
|
+
end
|
59
|
+
|
60
|
+
super(option, value, &nil)
|
61
|
+
end
|
62
|
+
|
63
|
+
# An array of callback procs to run after all features have been setup
|
64
|
+
@@run_after_features = []
|
65
|
+
|
66
|
+
# Add a block/proc to be run after features have been setup
|
67
|
+
def self.after_feature_init(&block)
|
68
|
+
@@run_after_features << block
|
69
|
+
end
|
70
|
+
|
71
|
+
# Rack helper for adding mime-types during local preview
|
72
|
+
def self.mime(ext, type)
|
73
|
+
ext = ".#{ext}" unless ext.to_s[0] == ?.
|
74
|
+
::Rack::Mime::MIME_TYPES[ext.to_s] = type
|
75
|
+
end
|
76
|
+
|
77
|
+
# Keep track of a block-specific layout
|
78
|
+
@@layout = nil
|
79
|
+
|
80
|
+
# Takes a block which allows many pages to have the same layout
|
81
|
+
# with_layout :admin do
|
82
|
+
# page "/admin/"
|
83
|
+
# page "/admin/login.html"
|
84
|
+
# end
|
85
|
+
def self.with_layout(layout, &block)
|
86
|
+
@@layout = layout
|
87
|
+
class_eval(&block) if block_given?
|
88
|
+
ensure
|
89
|
+
@@layout = nil
|
90
|
+
end
|
91
|
+
|
92
|
+
# The page method allows the layout to be set on a specific path
|
93
|
+
# page "/about.html", :layout => false
|
94
|
+
# page "/", :layout => :homepage_layout
|
95
|
+
def self.page(url, options={}, &block)
|
96
|
+
layout = @@layout
|
97
|
+
layout = options[:layout] if !options[:layout].nil?
|
98
|
+
|
99
|
+
get(url) do
|
100
|
+
return yield if block_given?
|
101
|
+
process_request(layout)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# This will match all requests not overridden in the project's config.rb
|
106
|
+
not_found do
|
107
|
+
process_request
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
# Internal method to look for templates and evaluate them if found
|
112
|
+
def process_request(layout = :layout)
|
113
|
+
# Normalize the path and add index if we're looking at a directory
|
114
|
+
path = request.path
|
115
|
+
path << settings.index_file if path.match(%r{/$})
|
116
|
+
path.gsub!(%r{^/}, '')
|
117
|
+
|
118
|
+
if template_path = Dir.glob(File.join(settings.views, "#{path}.*")).first
|
119
|
+
content_type mime_type(File.extname(path)), :charset => 'utf-8'
|
120
|
+
|
121
|
+
renderer = Middleman::Renderers.get_method(template_path)
|
122
|
+
if respond_to? renderer
|
123
|
+
status 200
|
124
|
+
return send(renderer, path.to_sym, { :layout => layout })
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
status 404
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
require "middleman/assets"
|
134
|
+
require "middleman/renderers"
|
135
|
+
require "middleman/features"
|
136
|
+
|
137
|
+
# The Rack App
|
138
|
+
class Middleman::Server
|
139
|
+
def self.new(*args, &block)
|
140
|
+
# If the old init.rb exists, use it, but issue warning
|
141
|
+
old_config = File.join(self.root, "init.rb")
|
142
|
+
if File.exists? old_config
|
143
|
+
$stderr.puts "== Warning: The init.rb file has been renamed to config.rb"
|
144
|
+
local_config = old_config
|
145
|
+
end
|
146
|
+
|
147
|
+
# Check for and evaluate local configuration
|
148
|
+
local_config ||= File.join(self.root, "config.rb")
|
149
|
+
if File.exists? local_config
|
150
|
+
$stderr.puts "== Reading: Local config" if logging?
|
151
|
+
Middleman::Server.class_eval File.read(local_config)
|
152
|
+
set :app_file, File.expand_path(local_config)
|
153
|
+
end
|
154
|
+
|
155
|
+
# loop over enabled feature
|
156
|
+
@@enabled_features.each do |feature_name, feature_config|
|
157
|
+
next unless send(:"#{feature_name}?")
|
158
|
+
$stderr.puts "== Enabling: #{feature_name.to_s.capitalize}" if logging?
|
159
|
+
Middleman::Features.run(feature_name, feature_config, self)
|
160
|
+
end
|
161
|
+
|
162
|
+
use ::Rack::ConditionalGet if environment == :development
|
163
|
+
|
164
|
+
@@run_after_features.each { |block| class_eval(&block) }
|
165
|
+
|
166
|
+
super
|
167
|
+
end
|
168
|
+
end
|