dev_panel 0.2.1
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/lib/dev_panel.rb +10 -0
- data/lib/devpanel/extension.rb +47 -0
- data/lib/devpanel/middleware.rb +98 -0
- data/lib/devpanel/rails.rb +25 -0
- data/lib/devpanel/stats.rb +48 -0
- metadata +51 -0
data/lib/dev_panel.rb
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module DevPanel
|
|
2
|
+
module Panel
|
|
3
|
+
|
|
4
|
+
def self.included(base)
|
|
5
|
+
base.after_filter :dev_panel_output
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def dev_panel_output
|
|
9
|
+
self.response.body += dev_panel_ajax
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def dev_panel_ajax
|
|
13
|
+
jquery_cdn + jquery_ui_cdn + ajax_call
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def ajax_call
|
|
17
|
+
'<div id="DevPanel"></div><script type="text/javascript">
|
|
18
|
+
$.ajax({
|
|
19
|
+
url: "/__DevPanel/main",
|
|
20
|
+
success: function(response) {
|
|
21
|
+
$("#DevPanel").html(response);' + hide_container +
|
|
22
|
+
'
|
|
23
|
+
$("#devPanelHider").on("click", function(s) {
|
|
24
|
+
$("#devPanelContainer").toggle();
|
|
25
|
+
$.get("/__DevPanel/set_options?visible=" + $("#devPanelContainer").is(":visible"));
|
|
26
|
+
});
|
|
27
|
+
$("#devPanelWindow").draggable({stop: function() {
|
|
28
|
+
$.get("/__DevPanel/set_options?top=" + $("#devPanelWindow").position().top + "&left=" + $("#devPanelWindow").position().left);
|
|
29
|
+
}});
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
</script>'
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def hide_container
|
|
36
|
+
(Stats.show?) ? '' : '$("#devPanelContainer").toggle()'
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def jquery_cdn
|
|
40
|
+
'<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>'
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def jquery_ui_cdn
|
|
44
|
+
'<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>'
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
module DevPanel
|
|
2
|
+
class Middleware
|
|
3
|
+
def initialize(app)
|
|
4
|
+
@app = app
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def call(env)
|
|
8
|
+
if env["REQUEST_URI"] =~ /__DevPanel\/main/
|
|
9
|
+
[200, { "Content-Type" => "text/plain; charset=utf-8" }, [dev_panel_output]]
|
|
10
|
+
elsif env["REQUEST_URI"] =~ /__DevPanel\/set_options/
|
|
11
|
+
params = Rack::Utils.parse_query(env['QUERY_STRING'], "&")
|
|
12
|
+
Stats.set_by_params(params)
|
|
13
|
+
[200, { "Content-Type" => "text/plain; charset=utf-8" }, ["#{Stats.show?} #{Stats.left} #{Stats.top}"]]
|
|
14
|
+
else
|
|
15
|
+
@app.call(env)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def dev_panel_output
|
|
20
|
+
css + html_containers + html_table
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def css
|
|
24
|
+
"<style>
|
|
25
|
+
#devPanelWindow {
|
|
26
|
+
border-radius: 3px;
|
|
27
|
+
margin-bottom: 2px;
|
|
28
|
+
box-shadow: 0 0 10px rgba(0, 0, 0, 0.03), 1px 1px 0 rgba(0, 0, 0, 0.05), -1px 1px 0 rgba(0, 0, 0, 0.05), 0 0 0 4px rgba(0, 0, 0, 0.04);
|
|
29
|
+
font-family: menlo, lucida console, monospace;
|
|
30
|
+
border: 2px solid #000;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
#devPanelHider {
|
|
34
|
+
background: #F1F1F1;
|
|
35
|
+
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3);
|
|
36
|
+
font-family: arial;
|
|
37
|
+
font-size: 12.8px;
|
|
38
|
+
overflow: hidden;
|
|
39
|
+
padding: 6px 10px;
|
|
40
|
+
border: solid 1px #CCC;
|
|
41
|
+
border-bottom: 0;
|
|
42
|
+
border-top-left-radius: 2px;
|
|
43
|
+
border-top-right-radius: 2px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
#devPanelContainer {
|
|
47
|
+
font-family: menlo, lucida console, monospace;
|
|
48
|
+
background-color: #fff;
|
|
49
|
+
box-shadow: inset 3px 3px 3px rgba(0, 0, 0, 0.1), inset 0 0 0 1px rgba(0, 0, 0, 0.1);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
#devPanelContainer td {
|
|
53
|
+
font-family: arial;
|
|
54
|
+
color: #000;
|
|
55
|
+
font-size: 10px;
|
|
56
|
+
font-weight: normal;
|
|
57
|
+
padding: 8px;
|
|
58
|
+
overflow: auto;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
#devPanelContainer tr {
|
|
62
|
+
background-color: #FACC9B;;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
#devPanelContainer td.firstColumn {
|
|
66
|
+
width: 60px;
|
|
67
|
+
font-weight: bold;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
#devPanelContainer .alt {
|
|
71
|
+
background-color: #FFF;;
|
|
72
|
+
}
|
|
73
|
+
</style>"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def html_containers
|
|
77
|
+
str = '<div id="devPanelWindow" style="padding: 3px; color: #000; background-color: #F0F0F5; position: absolute; float: left; top: ' + Stats.top.to_s + 'px; left: ' + Stats.left.to_s + 'px;" >'
|
|
78
|
+
str += '<div id="devPanelHider" style="width: 150px; text-align:center; border: solid 1px #fff"><a href="#">Show/Hide Stats</a> / <span style="font-size: 10px">' + Stats.data[:action_controller].duration.round(0).to_s + 'ms</span></div>'
|
|
79
|
+
str += '<div id="devPanelContainer" style="width: 300px; padding-top: 20px">'
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def html_table
|
|
83
|
+
str = '<table style="width: 300px; table-layout: fixed">'
|
|
84
|
+
str += "<tr class='alt'><td class='firstColumn'>Total Time:</td> <td>#{Stats.data[:action_controller].duration.round(2).to_s}ms</td></tr>"
|
|
85
|
+
controller_time = (Stats.data[:action_controller].duration - Stats.data[:action_controller].payload[:view_runtime])
|
|
86
|
+
str += "<tr><td class='firstColumn'>Controller Time:</td> <td> #{controller_time.round(2).to_s}ms</td></tr>"
|
|
87
|
+
str += "<tr class='alt'><td class='firstColumn'>View Time:</td> <td>#{Stats.data[:action_controller].payload[:view_runtime].round(2).to_s}ms</td></tr>"
|
|
88
|
+
str += "<tr><td class='firstColumn'>Partials Rendered:</td> <td> #{Stats.data[:partial_count] || 0}</td></tr>"
|
|
89
|
+
str += "<tr class='alt'><td class='firstColumn'>Response Code:</td> <td> #{Stats.data[:action_controller].payload[:status].to_s}</td></tr>"
|
|
90
|
+
str += "<tr><td class='firstColumn'>Controller:</td> <td> #{Stats.data[:action_controller].payload[:controller].to_s}</td></tr>"
|
|
91
|
+
str += "<tr class='alt'><td class='firstColumn'>Action:</td> <td> #{Stats.data[:action_controller].payload[:action].to_s}</td></tr>"
|
|
92
|
+
str += "<tr><td class='firstColumn'>Method:</td> <td> #{Stats.data[:action_controller].payload[:method].to_s}</td></tr>"
|
|
93
|
+
str += "<tr class='alt'><td class='firstColumn'>Params:</td> <td> #{Stats.data[:action_controller].payload[:params]}</td></tr>"
|
|
94
|
+
str += "<tr><td class='firstColumn'>Log:</td> <td> #{Stats.data[:log]}</td></tr>"
|
|
95
|
+
str += "</table></div></div>"
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module DevPanel
|
|
2
|
+
class Railtie < Rails::Railtie
|
|
3
|
+
initializer "dev_panel.configure_rails_initialization" do
|
|
4
|
+
unless Rails.env.production?
|
|
5
|
+
Rails.application.middleware.use DevPanel::Middleware
|
|
6
|
+
|
|
7
|
+
ActiveSupport::Notifications.subscribe('start_processing.action_controller') do |*args|
|
|
8
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
|
9
|
+
Stats.delete_data if event.payload[:format] == :html
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
ActiveSupport::Notifications.subscribe('process_action.action_controller') do |*args|
|
|
13
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
|
14
|
+
Stats.data[:action_controller] = event if event.payload[:format] == :html
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
ActiveSupport::Notifications.subscribe('render_partial.action_view') do |*args|
|
|
18
|
+
Stats.data[:partial_count] ||= 0
|
|
19
|
+
Stats.data[:partial_count] += 1
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module DevPanel
|
|
2
|
+
class Stats
|
|
3
|
+
|
|
4
|
+
@@data ||= { log: "" }
|
|
5
|
+
@@visible = "false"
|
|
6
|
+
@@left = 0
|
|
7
|
+
@@top = 0
|
|
8
|
+
|
|
9
|
+
def self.set_by_params(params)
|
|
10
|
+
['visible', 'left', 'top'].each do |str|
|
|
11
|
+
Stats.send(str, params[str]) if params[str].present?
|
|
12
|
+
end
|
|
13
|
+
Stats.log(" ")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.data
|
|
17
|
+
@@data ||= { log: "" }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.delete_data
|
|
21
|
+
@@data = {}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.left(val = @@left)
|
|
25
|
+
return @@left if val.class != Fixnum && val.empty?
|
|
26
|
+
@@left = val || 0
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.top(val = @@top)
|
|
30
|
+
return @@top if val.class != Fixnum && val.empty?
|
|
31
|
+
@@top = val
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.visible(val = @@visible)
|
|
35
|
+
@@visible = val
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.show?
|
|
39
|
+
@@visible == "true"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.log(log)
|
|
43
|
+
@@data[:log] ||= ""
|
|
44
|
+
@@data[:log] += CGI::escapeHTML("#{log}")
|
|
45
|
+
@@data[:log] += "<br>--------------<br>"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: dev_panel
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.2.1
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- Matthew Stopa
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2012-12-29 00:00:00.000000000 Z
|
|
13
|
+
dependencies: []
|
|
14
|
+
description: A panel that appears in the browser to provide stats on page load times
|
|
15
|
+
and other debugging information for Rails 3
|
|
16
|
+
email: matthew.p.stopa@gmail.com
|
|
17
|
+
executables: []
|
|
18
|
+
extensions: []
|
|
19
|
+
extra_rdoc_files: []
|
|
20
|
+
files:
|
|
21
|
+
- lib/dev_panel.rb
|
|
22
|
+
- lib/devpanel/extension.rb
|
|
23
|
+
- lib/devpanel/middleware.rb
|
|
24
|
+
- lib/devpanel/rails.rb
|
|
25
|
+
- lib/devpanel/stats.rb
|
|
26
|
+
homepage: http://github.com/MattStopa/DevPanel
|
|
27
|
+
licenses: []
|
|
28
|
+
post_install_message:
|
|
29
|
+
rdoc_options: []
|
|
30
|
+
require_paths:
|
|
31
|
+
- lib
|
|
32
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
33
|
+
none: false
|
|
34
|
+
requirements:
|
|
35
|
+
- - ! '>='
|
|
36
|
+
- !ruby/object:Gem::Version
|
|
37
|
+
version: '0'
|
|
38
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
39
|
+
none: false
|
|
40
|
+
requirements:
|
|
41
|
+
- - ! '>='
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '0'
|
|
44
|
+
requirements: []
|
|
45
|
+
rubyforge_project:
|
|
46
|
+
rubygems_version: 1.8.24
|
|
47
|
+
signing_key:
|
|
48
|
+
specification_version: 3
|
|
49
|
+
summary: DevPanel, a gem for performance stats and debugging information
|
|
50
|
+
test_files: []
|
|
51
|
+
has_rdoc:
|