-
Notifications
You must be signed in to change notification settings - Fork 79
/
engine.rb
110 lines (95 loc) · 4.08 KB
/
engine.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
module Xray
# This is the main point of integration with Rails. This engine hooks into
# Sprockets and monkey patches ActionView in order to augment the app's JS
# and HTML templates with filepath information that can be used by xray.js
# in the browser. It also hooks in a middleware responsible for injecting
# xray.js and the xray bar into the app's response bodies.
class Engine < ::Rails::Engine
initializer "xray.initialize" do |app|
app.middleware.use Xray::Middleware
# Required by Rails 4.1
app.config.assets.precompile += %w(xray.js xray-backbone.js xray.css)
end
config.after_initialize do |app|
ensure_asset_pipeline_enabled! app
# Register as a Sprockets processor to augment JS files, including
# compiled coffeescript, with filepath information. See
# `Xray.augment_js` for details.
app.assets.register_postprocessor 'application/javascript', :xray do |context, data|
path = context.pathname.to_s
if path =~ /^#{app.root}.+\.(js|coffee)(\.|$)/
Xray.augment_js(data, path)
else
data
end
end
# Monkey patch ActionView::Template to augment server-side templates
# with filepath information. See `Xray.augment_template` for details.
ActionView::Template.class_eval do
def render_with_xray(*args, &block)
path = identifier
view = args.first
source = render_without_xray(*args, &block)
suitable_template = !(view.respond_to?(:mailer) && view.mailer) &&
!path.include?('_xray_bar') &&
path =~ /\.(html|slim|haml|hamlc)(\.|$)/ &&
path !~ /\.(js|json|css)(\.|$)/
options = args.last.kind_of?(Hash) ? args.last : {}
if suitable_template && !(options.has_key?(:xray) && (options[:xray] == false))
Xray.augment_template(source, path)
else
source
end
end
alias_method_chain :render, :xray
end
# Augment JS templates
app.assets.register_preprocessor 'application/javascript', :xray do |context, source|
path = context.pathname.to_s
if path =~ /^#{app.root}.+\.(jst)(\.|$)/
Xray.augment_template(source, path)
else
source
end
end
# This event is called near the beginning of a request cycle. We use it to
# collect information about the controller and action that is responding, for
# display in the Xray bar.
ActiveSupport::Notifications.subscribe('start_processing.action_controller') do |*args|
event = ActiveSupport::Notifications::Event.new(*args)
controller_name = event.payload[:controller]
action_name = event.payload[:action]
path = ActiveSupport::Dependencies.search_for_file(controller_name.underscore)
Xray.request_info.clear
Xray.request_info[:controller] = {
:path => path,
:name => controller_name,
:action => action_name
}
end
# This event is called each time during the request cycle that
# ActionView renders a template. The first time it's called will most
# likely be the view the controller is rendering, which is what we're
# interested in.
ActiveSupport::Notifications.subscribe('render_template.action_view') do |*args|
event = ActiveSupport::Notifications::Event.new(*args)
layout = event.payload[:layout]
path = event.payload[:identifier]
# We are only interested in the first notification that has a layout.
if layout
Xray.request_info[:view] ||= {
:path => path,
:layout => layout
}
end
end
end
def ensure_asset_pipeline_enabled!(app)
unless app.assets
raise "xray-rails requires the Rails asset pipeline.
The asset pipeline is currently disabled in this application.
Either convert your application to use the asset pipeline, or remove xray-rails from your Gemfile."
end
end
end
end