merb_footnotes 0.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.
@@ -0,0 +1,16 @@
1
+ require "#{File.dirname(__FILE__)}/files_note"
2
+
3
+ module MerbFootnotes
4
+ module Notes
5
+ class JavascriptsNote < FilesNote
6
+ def title
7
+ "Javascripts (#{@files.length})"
8
+ end
9
+
10
+ protected
11
+ def scan_text(text)
12
+ text.scan(/<script[^>]+src\s*=\s*['"]([^>?'"]+\.js)/im).flatten
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,33 @@
1
+ # LAYOUT NOTE
2
+ # Todo: make this note display the currently displayed layout
3
+
4
+ require "#{File.dirname(__FILE__)}/view_note"
5
+
6
+ module MerbFootnotes
7
+ module Notes
8
+ class LayoutNote < AbstractNote
9
+ def initialize(controller)
10
+ @controller = controller
11
+ @layout_path = find_layout
12
+ end
13
+
14
+ def row
15
+ :edit
16
+ end
17
+
18
+ def link
19
+ escape(Merb::Plugins.config[:merb_footnotes][:prefix] + @layout_path)
20
+ end
21
+
22
+ def valid?
23
+ prefix? and !@layout_path.blank?
24
+ end
25
+
26
+ protected
27
+ def find_layout
28
+ # TODO: find the real rendered layout
29
+ "#{Merb.root}/app/views/layout/application.html.#{Merb.template_engine}"
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,38 @@
1
+ require "#{File.dirname(__FILE__)}/abstract_note"
2
+
3
+ module MerbFootnotes
4
+ module Notes
5
+ class LogNote < AbstractNote
6
+ def initialize(controller)
7
+ @controller = controller
8
+ end
9
+
10
+ def content
11
+ ""
12
+ # TODO
13
+ # escape(log_tail).gsub("\n","<br />")
14
+ end
15
+
16
+ protected
17
+ def log_tail
18
+ filename = if Merb.logger.instance_variable_get('@log')
19
+ Merb.logger.instance_variable_get('@log').path
20
+ else
21
+ Merb.logger.instance_variable_get('@logdev').filename
22
+ end
23
+ file_string = File.open(filename).read.to_s
24
+
25
+ # We try to select the specified action from the log
26
+ # If we can't find it, we get the last 100 lines
27
+ #
28
+ if rindex = file_string.rindex('Processing '+@controller.controller_class_name+'#'+@controller.action_name)
29
+ file_string[rindex..-1].gsub(/\e\[.+?m/, '')
30
+ else
31
+ lines = file_string.split("\n")
32
+ index = [lines.size-100,0].max
33
+ lines[index..-1].join("\n")
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,19 @@
1
+ require "#{File.dirname(__FILE__)}/abstract_note"
2
+
3
+ module MerbFootnotes
4
+ module Notes
5
+ class ParamsNote < AbstractNote
6
+ def initialize(controller)
7
+ @params = controller.params
8
+ end
9
+
10
+ def title
11
+ "Params (#{@params.length})"
12
+ end
13
+
14
+ def content
15
+ escape(@params.inspect)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,59 @@
1
+ require "#{File.dirname(__FILE__)}/abstract_note"
2
+
3
+ # View Note
4
+ # this note should give you an easy linkback to the currently render view
5
+ # TODO: include all rendered partials by wrapping the partial call
6
+ module MerbFootnotes
7
+ module Notes
8
+ class PartialsNote < AbstractNote
9
+ def initialize(controller)
10
+ @controller = controller
11
+ @partials = format_partials(@controller.footnotes[:partials])
12
+ end
13
+
14
+ def row
15
+ :edit
16
+ end
17
+
18
+ def title
19
+ "Partials (#{@partials.size})"
20
+ end
21
+
22
+ # def link
23
+ # escape(Merb::Plugins.config[:merb_footnotes][:prefix] + filename)
24
+ # end
25
+
26
+ def content
27
+ mount_table(@partials.unshift([:partial, :arguments]))
28
+ end
29
+
30
+ def valid?
31
+ prefix?
32
+ end
33
+
34
+ protected
35
+ def format_partials(partials)
36
+ display_list = []
37
+ partials.each do |r|
38
+ action = r.first
39
+ opts = r.last
40
+
41
+ action = "<a href='#{get_path_for_partial(action)}'>#{action}</a>"
42
+ display_list << [action.to_s, opts.inspect]
43
+ end
44
+ display_list
45
+ end
46
+
47
+ def get_path_for_partial(template)
48
+ template = template.to_s
49
+ if template =~ %r{^/}
50
+ template_path = File.dirname(template) / "_#{File.basename(template)}"
51
+ else
52
+ kontroller = (m = template.match(/.*(?=\/)/)) ? m[0] : @controller.controller_name
53
+ template_path = "#{kontroller}/_#{File.basename(template)}"
54
+ end
55
+ "#{Merb::Plugins.config[:merb_footnotes][:prefix]}/#{Merb.root}/app/views/#{template_path}.html.#{Merb.template_engine}"
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,139 @@
1
+ # TODO: fix instrumentation in order to populate the MerbFootNotes::Notes::QueriesNote.sql accessor
2
+
3
+ require "#{File.dirname(__FILE__)}/abstract_note"
4
+
5
+ module MerbFootnotes
6
+ module Notes
7
+ class QueriesNote < AbstractNote
8
+ @@sql = []
9
+
10
+ def self.sql
11
+ @@sql
12
+ end
13
+
14
+ def self.start!(controller)
15
+ @@sql = []
16
+ end
17
+
18
+ def self.to_sym
19
+ :queries
20
+ end
21
+
22
+ def title
23
+ "Queries (#{@@sql.length})"
24
+ end
25
+
26
+ def stylesheet
27
+ %{
28
+ #queries_debug_info table td, #queries_debug_info table th{border:1px solid #A00; padding:0 3px; text-align:center;}
29
+ #queries_debug_info table thead, #queries_debug_info table tbody {color:#A00;}
30
+ #queries_debug_info p {background-color:#F3F3FF; border:1px solid #CCC; margin:12px; padding:4px 6px;}
31
+ #queries_debug_info a:hover {text-decoration:underline;}
32
+ }
33
+ end
34
+
35
+ def javascript
36
+ %{
37
+ function queries_toogle(type, id){
38
+ s = document.getElementById('q'+type+'_'+id).style
39
+ s.display = (s.display != 'block') ? 'block' : 'none'
40
+ location.href = '#qtitle_'+id
41
+ }
42
+ }
43
+ end
44
+
45
+ def content
46
+ html = ''
47
+
48
+ @@sql.each_with_index do |item, i|
49
+ sql_links = []
50
+ sql_links << "<a href=\"#\" style=\"color:#A00;\" onclick=\"queries_toogle('table',#{i});return false\">explain</a>" if item.explain
51
+ sql_links << "<a href=\"#\" style=\"color:#00A;\" onclick=\"queries_toogle('trace',#{i});return false\">trace</a>" if item.trace
52
+
53
+ html << %{
54
+ <b id="qtitle_#{i}">#{escape(item.type.to_s.upcase)}</b> (#{sql_links.join(' | ')})<br />
55
+ #{print_name_and_time(item.name, item.time)}<br />
56
+ #{print_query(item.query)}<br />
57
+ #{print_explain(i, item.explain) if item.explain}
58
+ <p id="qtrace_#{i}" style="display:none;">#{parse_trace(item.trace) if item.trace}</p><br />
59
+ }
60
+ end
61
+
62
+ # return html
63
+
64
+ # TODO: remove this
65
+ return "NOT WORKING"
66
+
67
+ end
68
+
69
+ protected
70
+ def parse_explain(results)
71
+ table = []
72
+ table << results.fetch_fields.map{|f| f.name}
73
+ results.each{|row| table << row}
74
+ table
75
+ end
76
+
77
+ def parse_trace(trace)
78
+ trace.map do |t|
79
+ s = t.split(':')
80
+ "<a href=\"#{escape("#{Merb::Plugins.config[:merb_footnotes][:prefix]}#{Merb.root}/#{s[0]}&line=#{s[1].to_i}")}\">#{escape(t)}</a><br />"
81
+ end.join
82
+ end
83
+
84
+ def print_name_and_time(name, time)
85
+ "#{escape(name || 'SQL')} (#{sprintf('%f', time)}s)"
86
+ end
87
+
88
+ def print_query(query)
89
+ escape(query.to_s.gsub(/(\s)+/, ' ').gsub('`', ''))
90
+ end
91
+
92
+ def print_explain(i, explain)
93
+ mount_table(parse_explain(explain), :id => "qtable_#{i}", :style => 'margin:10px;display:none;')
94
+ end
95
+ end
96
+ end
97
+
98
+ module Extensions
99
+ class Sql
100
+ attr_accessor :type, :name, :time, :query, :explain, :trace
101
+
102
+ def initialize(type, name, time, query, explain)
103
+ @type = type
104
+ @name = name
105
+ @time = time
106
+ @query = query
107
+ @explain = explain
108
+
109
+ # Strip, select those ones from app and reject first two, because they are from the plugin
110
+ @trace = Kernel.caller.collect{|c| c.strip}.select{|i| i.gsub!(/^#{Merb.root}\//im, '') }[2..-1]
111
+ end
112
+ end
113
+
114
+ module AbstractAdapter
115
+ def log_silence
116
+ result = nil
117
+ if @logger
118
+ @logger.silence do
119
+ result = yield
120
+ end
121
+ else
122
+ result = yield
123
+ end
124
+ result
125
+ end
126
+ end
127
+ end
128
+ end
129
+
130
+ # NOT WORKING
131
+
132
+ # if MerbFootnotes::Notes::QueriesNote.included?
133
+ # ActiveRecord::ConnectionAdapters::AbstractAdapter.__send__ :include, MerbFootnotes::Extensions::AbstractAdapter
134
+ # ActiveRecord::ConnectionAdapters.local_constants.each do |adapter|
135
+ # next unless adapter =~ /.*[^Abstract]Adapter$/
136
+ # next if adapter =~ /SQLite.Adapter$/
137
+ # eval("ActiveRecord::ConnectionAdapters::#{adapter}").__send__ :include, MerbFootnotes::Extensions::QueryAnalyzer
138
+ # end
139
+ # end
@@ -0,0 +1,35 @@
1
+ require "#{File.dirname(__FILE__)}/abstract_note"
2
+
3
+ module MerbFootnotes
4
+ module Notes
5
+ class RoutesNote < AbstractNote
6
+ def initialize(controller)
7
+ @controller = controller
8
+ @parsed_routes = parse_routes || []
9
+ end
10
+
11
+ def legend
12
+ "Routes for #{@controller.class.to_s}"
13
+ end
14
+
15
+ def content
16
+ mount_table(@parsed_routes.to_a.unshift([:name, :path, :params]))
17
+ end
18
+
19
+ protected
20
+ def parse_routes
21
+ routes_with_name = Merb::Router.named_routes.to_a
22
+
23
+ return Merb::Router.routes.collect do |route|
24
+ if route.params[:controller].to_s.include?(@controller.class.to_s.downcase)
25
+ [
26
+ escape(route.name.to_s),
27
+ route.segments.to_a.join,
28
+ route.params.reject{|key, value| key == :controller}.inspect.gsub('\"', '')
29
+ ]
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,19 @@
1
+ require "#{File.dirname(__FILE__)}/abstract_note"
2
+
3
+ module MerbFootnotes
4
+ module Notes
5
+ class SessionNote < AbstractNote
6
+ def initialize(controller)
7
+ @session = controller.session
8
+ end
9
+
10
+ def title
11
+ "Session (#{@session.size})"
12
+ end
13
+
14
+ def content
15
+ escape(@session.inspect)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ require "#{File.dirname(__FILE__)}/files_note"
2
+
3
+ module MerbFootnotes
4
+ module Notes
5
+ class StylesheetsNote < FilesNote
6
+ def title
7
+ "Stylesheets (#{@files.length})"
8
+ end
9
+
10
+ protected
11
+ def scan_text(text)
12
+ text.scan(/<link[^>]+href\s*=\s*['"]([^>?'"]+\.css)/im).flatten
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,37 @@
1
+ require "#{File.dirname(__FILE__)}/abstract_note"
2
+
3
+ # View Note
4
+ # this note should give you an easy linkback to the currently render view
5
+ # TODO: include all rendered partials by wrapping the partial call
6
+ module MerbFootnotes
7
+ module Notes
8
+ class ViewNote < AbstractNote
9
+ def initialize(controller)
10
+ @controller = controller
11
+ @filename = get_filename
12
+ end
13
+
14
+ def row
15
+ :edit
16
+ end
17
+
18
+ def title
19
+ "View"
20
+ end
21
+
22
+ def link
23
+ escape(Merb::Plugins.config[:merb_footnotes][:prefix] + @filename)
24
+ end
25
+
26
+
27
+ def valid?
28
+ prefix?
29
+ end
30
+
31
+ protected
32
+ def get_filename
33
+ "#{Merb.root}/app/views/#{@controller.controller_name}/#{@controller.params[:action]}.html.#{Merb.template_engine}"
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "merb_footnotes" do
4
+ it "should do nothing" do
5
+ true.should == true
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ $:.push File.join(File.dirname(__FILE__), '..', 'lib')
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: merb_footnotes
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - Jacques Crocker
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-11-22 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: merb
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "1.0"
24
+ version:
25
+ description: Provides an extensible footnotes debugging bar to Merb development mode
26
+ email: merbjedi@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README
33
+ - LICENSE
34
+ files:
35
+ - LICENSE
36
+ - README
37
+ - Rakefile
38
+ - lib/merb-plugins-footnotes.rb
39
+ - lib/merb_footnotes
40
+ - lib/merb_footnotes/filter.rb
41
+ - lib/merb_footnotes/formatter.rb
42
+ - lib/merb_footnotes/instrumentation.rb
43
+ - lib/merb_footnotes/notes
44
+ - lib/merb_footnotes/notes/abstract_note.rb
45
+ - lib/merb_footnotes/notes/controller_note.rb
46
+ - lib/merb_footnotes/notes/cookies_note.rb
47
+ - lib/merb_footnotes/notes/env_note.rb
48
+ - lib/merb_footnotes/notes/files_note.rb
49
+ - lib/merb_footnotes/notes/filters_note.rb
50
+ - lib/merb_footnotes/notes/javascripts_note.rb
51
+ - lib/merb_footnotes/notes/layout_note.rb
52
+ - lib/merb_footnotes/notes/log_note.rb
53
+ - lib/merb_footnotes/notes/params_note.rb
54
+ - lib/merb_footnotes/notes/partials_note.rb
55
+ - lib/merb_footnotes/notes/queries_note.rb
56
+ - lib/merb_footnotes/notes/routes_note.rb
57
+ - lib/merb_footnotes/notes/session_note.rb
58
+ - lib/merb_footnotes/notes/stylesheets_note.rb
59
+ - lib/merb_footnotes/notes/view_note.rb
60
+ - spec/merb_footnotes_spec.rb
61
+ - spec/spec_helper.rb
62
+ has_rdoc: true
63
+ homepage: http://merbjedi.com/
64
+ post_install_message:
65
+ rdoc_options: []
66
+
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "0"
74
+ version:
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: "0"
80
+ version:
81
+ requirements: []
82
+
83
+ rubyforge_project: merb
84
+ rubygems_version: 1.3.1
85
+ signing_key:
86
+ specification_version: 2
87
+ summary: Provides an extensible footnotes debugging bar to Merb development mode
88
+ test_files: []
89
+