rails-footnotes 4.1.5 → 5.0.0

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.
Files changed (47) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci.yml +25 -0
  3. data/.gitignore +4 -3
  4. data/CHANGELOG +8 -0
  5. data/Gemfile +8 -1
  6. data/Gemfile.lock +187 -0
  7. data/README.rdoc +8 -54
  8. data/Rakefile +1 -6
  9. data/bin/rake +29 -0
  10. data/bin/rspec +29 -0
  11. data/gemfiles/{Gemfile.rails-3.2.x → Gemfile.rails-3.2.22} +1 -1
  12. data/lib/generators/templates/rails_footnotes.rb +4 -5
  13. data/lib/rails-footnotes.rb +9 -9
  14. data/lib/rails-footnotes/extension.rb +8 -11
  15. data/lib/rails-footnotes/filter.rb +13 -4
  16. data/lib/rails-footnotes/notes/assigns_note.rb +2 -2
  17. data/lib/rails-footnotes/notes/files_note.rb +12 -23
  18. data/lib/rails-footnotes/notes/log_note.rb +1 -1
  19. data/lib/rails-footnotes/notes/params_note.rb +5 -1
  20. data/lib/rails-footnotes/notes/queries_note.rb +9 -10
  21. data/lib/rails-footnotes/notes/view_note.rb +16 -7
  22. data/lib/rails-footnotes/version.rb +1 -1
  23. data/lib/rails6-footnotes.rb +1 -0
  24. data/rails-footnotes.gemspec +5 -10
  25. data/spec/abstract_note_spec.rb +17 -13
  26. data/spec/app/assets/config/manifest.js +2 -0
  27. data/spec/app/assets/javascripts/foobar.js +1 -0
  28. data/spec/app/assets/stylesheets/foobar.css +0 -0
  29. data/spec/app/views/files/index.html.erb +1 -0
  30. data/spec/app/views/layouts/application.html.erb +12 -0
  31. data/spec/{views → app/views}/partials/_foo.html.erb +0 -0
  32. data/spec/{views → app/views}/partials/index.html.erb +0 -0
  33. data/spec/controllers/files_note_controller_spec.rb +38 -0
  34. data/spec/controllers/footnotes_controller_spec.rb +49 -34
  35. data/spec/controllers/log_note_controller_spec.rb +4 -8
  36. data/spec/controllers/partials_note_controller_spec.rb +2 -3
  37. data/spec/env_note_spec.rb +4 -4
  38. data/spec/footnotes_spec.rb +38 -54
  39. data/spec/notes/assigns_note_spec.rb +13 -9
  40. data/spec/notes/controller_note_spec.rb +2 -2
  41. data/spec/notes/files_note_spec.rb +12 -3
  42. data/spec/notes/javascripts_note_spec.rb +1 -1
  43. data/spec/notes/stylesheets_note_spec.rb +1 -1
  44. data/spec/notes/view_note_spec.rb +18 -0
  45. data/spec/spec_helper.rb +35 -3
  46. metadata +38 -48
  47. data/.travis.yml +0 -14
@@ -2,4 +2,4 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec :path => '..'
4
4
 
5
- gem 'rails', '~> 3.2.0'
5
+ gem 'rails', '~> 3.2.22'
@@ -1,11 +1,10 @@
1
- defined?(Footnotes) && Footnotes.setup do |f|
1
+ Footnotes.setup do |f|
2
2
  # Whether or not to enable footnotes
3
3
  f.enabled = Rails.env.development?
4
- # You can also use a lambda / proc to conditionally toggle footnotes
5
- # Example :
4
+ # You can also use a lambda / proc to conditionally toggle footnotes, like
6
5
  # f.enabled = -> { User.current.admin? }
7
6
  # Beware of thread-safety though, Footnotes.enabled is NOT thread safe
8
- # and should not be modified anywhere else.
7
+ # and should not be modified outside this initializer.
9
8
 
10
9
  # Only toggle some notes :
11
10
  # f.notes = [:session, :cookies, :params, :filters, :routes, :env, :queries, :log]
@@ -24,4 +23,4 @@ defined?(Footnotes) && Footnotes.setup do |f|
24
23
 
25
24
  # Allow to open multiple notes :
26
25
  # f.multiple_notes = true
27
- end
26
+ end if defined?(Footnotes) && Footnotes.respond_to?(:setup)
@@ -5,7 +5,6 @@ require 'rails-footnotes/each_with_rescue'
5
5
  require 'rails-footnotes/filter'
6
6
  require 'rails-footnotes/notes/all'
7
7
  require 'rails-footnotes/extension'
8
- require 'active_support/deprecation'
9
8
 
10
9
  module Footnotes
11
10
  mattr_accessor :before_hooks
@@ -37,11 +36,6 @@ module Footnotes
37
36
  delegate :font_size=, :to => Filter
38
37
  end
39
38
 
40
- def self.run!
41
- ActiveSupport::Deprecation.warn "run! is deprecated and will be removed from future releases, use Footnotes.setup or Footnotes.enabled instead.", caller
42
- Footnotes.enabled = true
43
- end
44
-
45
39
  def self.before(&block)
46
40
  @@before_hooks << block
47
41
  end
@@ -50,9 +44,13 @@ module Footnotes
50
44
  @@after_hooks << block
51
45
  end
52
46
 
53
- def self.enabled?
47
+ def self.enabled?(controller)
54
48
  if @@enabled.is_a? Proc
55
- @@enabled.call
49
+ if @@enabled.arity == 1
50
+ @@enabled.call(controller)
51
+ else
52
+ @@enabled.call
53
+ end
56
54
  else
57
55
  !!@@enabled
58
56
  end
@@ -63,6 +61,8 @@ module Footnotes
63
61
  end
64
62
  end
65
63
 
66
- ActionController::Base.send(:include, Footnotes::RailsFootnotesExtension)
64
+ ActiveSupport.on_load(:action_controller) do
65
+ ActionController::Base.send(:include, Footnotes::RailsFootnotesExtension)
66
+ end
67
67
 
68
68
  load Rails.root.join('.rails_footnotes') if Rails.root && Rails.root.join('.rails_footnotes').exist?
@@ -2,26 +2,23 @@ require 'active_support/concern'
2
2
 
3
3
  module Footnotes
4
4
  module RailsFootnotesExtension
5
-
6
5
  extend ActiveSupport::Concern
7
6
 
8
7
  included do
9
- prepend_before_filter :rails_footnotes_before_filter
10
- after_filter :rails_footnotes_after_filter
8
+ prepend_before_action :rails_footnotes_before_filter
9
+ after_action :rails_footnotes_after_filter
11
10
  end
12
11
 
13
12
  def rails_footnotes_before_filter
14
- if Footnotes.enabled?
15
- Footnotes::Filter.start!(self)
16
- end
13
+ Footnotes::Filter.start!(self) if Footnotes.enabled?(self)
17
14
  end
18
15
 
19
16
  def rails_footnotes_after_filter
20
- if Footnotes.enabled?
21
- filter = Footnotes::Filter.new(self)
22
- filter.add_footnotes!
23
- filter.close!(self)
24
- end
17
+ return unless Footnotes.enabled?(self)
18
+
19
+ filter = Footnotes::Filter.new(self)
20
+ filter.add_footnotes!
21
+ filter.close!(self)
25
22
  end
26
23
  end
27
24
  end
@@ -47,7 +47,7 @@ module Footnotes
47
47
  if args.empty?
48
48
  @@prefix
49
49
  else
50
- args.map! { |arg| URI.escape(arg.to_s) }
50
+ args.map! { |arg| arg.to_s.split("/").map{|s| ERB::Util.url_encode(s) }.join("/") }
51
51
 
52
52
  if @@prefix.respond_to? :call
53
53
  @@prefix.call *args
@@ -116,7 +116,8 @@ module Footnotes
116
116
  end
117
117
 
118
118
  def valid_format?
119
- ['text/html', nil].include? @controller.response.content_type
119
+ format = @controller.response.content_type
120
+ format.nil? || format.include?("text/html")
120
121
  end
121
122
 
122
123
  def valid_content_type?
@@ -169,7 +170,7 @@ module Footnotes
169
170
  #footnotes_debug table td {padding: 5px; border-bottom: 1px solid #ccc;}
170
171
  #footnotes_debug table td strong {color: #9b1b1b;}
171
172
  #footnotes_debug table th {padding: 5px; border-bottom: 1px solid #ccc;}
172
- #footnotes_debug table tr:nth-child(2n) td {background: #eee;}
173
+ #footnotes_debug table tr:nth-child(2n) td {background: #f5f5f5;}
173
174
  #footnotes_debug table tr:nth-child(2n + 1) td {background: #fff;}
174
175
  #footnotes_debug tbody {text-align: left;}
175
176
  #footnotes_debug .name_values td {vertical-align: top;}
@@ -207,14 +208,22 @@ module Footnotes
207
208
  }
208
209
 
209
210
  function hideAllAndToggle(id) {
211
+ var n = note(id);
212
+ var display = n.style.display;
210
213
  hideAll();
214
+ // Restore original display to allow toggling
215
+ n.style.display = display;
211
216
  toggle(id)
212
217
 
213
218
  location.href = '#footnotes_debug';
214
219
  }
215
220
 
221
+ function note(id) {
222
+ return (document.getElementById(id));
223
+ }
224
+
216
225
  function toggle(id){
217
- var el = document.getElementById(id);
226
+ var el = note(id);
218
227
  if (el.style.display == 'none') {
219
228
  Footnotes.show(el);
220
229
  } else {
@@ -16,9 +16,9 @@ module Footnotes
16
16
  :@view_runtime,
17
17
  :@marked_for_same_origin_verification
18
18
  ]
19
- cattr_accessor :ignored_assigns, :instance_writter => false
19
+ cattr_accessor :ignored_assigns, :instance_writer => false
20
20
  @@ignored_assigns_pattern = /^@_/
21
- cattr_accessor :ignored_assigns_pattern, :instance_writter => false
21
+ cattr_accessor :ignored_assigns_pattern, :instance_writer => false
22
22
 
23
23
  def initialize(controller)
24
24
  @controller = controller
@@ -24,36 +24,25 @@ module Footnotes
24
24
 
25
25
  protected
26
26
  def scan_text(text)
27
- []
27
+ raise NotImplementedError, "implement this in your subclass"
28
28
  end
29
29
 
30
30
  def parse_files!
31
- if Rails.version >= '3.1' && Rails.application.config.assets[:enabled]
32
- asset_paths = Rails.application.config.assets.paths
33
- linked_files = []
31
+ asset_paths = Rails.application.config.try(:assets).try(:paths) || []
32
+ linked_files = []
34
33
 
35
- @files.collect do |file|
36
- base_name = File.basename(file)
37
- asset_paths.each do |asset_path|
38
- results = Dir[File.expand_path(base_name, asset_path) + '*']
39
- results.each do |r|
40
- linked_files << %[<a href="#{Footnotes::Filter.prefix(r, 1, 1)}">#{File.basename(r)}</a>]
41
- end
42
- break if results.present?
43
- end
44
- end
45
- @files = linked_files
46
- else
47
- #Original Implementation
48
- @files.collect! do |filename|
49
- if filename =~ %r{^/}
50
- full_filename = File.join(File.expand_path(Rails.root), 'public', filename)
51
- %[<a href="#{Footnotes::Filter.prefix(full_filename, 1, 1)}">#{filename}</a>]
52
- else
53
- %[<a href="#{filename}">#{filename}</a>]
34
+ @files.collect do |file|
35
+ file.gsub!(/-[a-f0-9]{64}\./, '.')
36
+ base_name = File.basename(file)
37
+ asset_paths.each do |asset_path|
38
+ results = Dir[File.expand_path(base_name, asset_path) + '*']
39
+ results.each do |r|
40
+ linked_files << %[<a href="#{Footnotes::Filter.prefix(r, 1, 1)}">#{File.basename(r)}</a>]
54
41
  end
42
+ break if results.present?
55
43
  end
56
44
  end
45
+ @files = linked_files
57
46
  end
58
47
  end
59
48
  end
@@ -20,7 +20,7 @@ module Footnotes
20
20
  end
21
21
  # Rails 3 don't have ActiveSupport::Logger#broadcast so we backported it
22
22
  extend_module = defined?(ActiveSupport::Logger) ? ActiveSupport::Logger.broadcast(note_logger) : NoteLogger.broadcast(note_logger)
23
- Rails.logger = self.original_logger.dup.extend(extend_module)
23
+ Rails.logger = self.original_logger.clone.extend(extend_module)
24
24
  end
25
25
 
26
26
  def title
@@ -2,7 +2,11 @@ module Footnotes
2
2
  module Notes
3
3
  class ParamsNote < AbstractNote
4
4
  def initialize(controller)
5
- @params = controller.params.symbolize_keys
5
+ @params = if Rails::VERSION::MAJOR >= 5
6
+ controller.params.to_unsafe_h
7
+ else
8
+ controller.params
9
+ end
6
10
  end
7
11
 
8
12
  def title
@@ -1,7 +1,7 @@
1
1
  module Footnotes
2
2
  module Notes
3
3
  class QueriesNote < AbstractNote
4
- cattr_accessor :alert_db_time, :alert_sql_number, :orm, :ignored_regexps, :instance_writter => false
4
+ cattr_accessor :alert_db_time, :alert_sql_number, :orm, :ignored_regexps, :instance_writer => false
5
5
  @@alert_db_time = 16.0
6
6
  @@alert_sql_number = 8
7
7
  @@query_subscriber = nil
@@ -23,8 +23,8 @@ module Footnotes
23
23
  def title
24
24
  queries = self.events.count
25
25
  total_time = self.events.map(&:duration).sum
26
- query_color = generate_red_color(self.events.count, alert_sql_number)
27
- db_color = generate_red_color(total_time, alert_db_time)
26
+ query_color = alert_color(self.events.count, alert_sql_number)
27
+ db_color = alert_color(total_time, alert_db_time)
28
28
 
29
29
  <<-TITLE
30
30
  <span style="background-color:#{query_color}">Queries (#{queries})</span>
@@ -47,7 +47,7 @@ module Footnotes
47
47
  <td>
48
48
  <span id="sql_#{index}">#{print_query(event.payload[:sql])}</span>
49
49
  </td>
50
- <td>#{print_name_and_time(event.payload[:name], event.duration / 1000.0)}</td>
50
+ <td>#{print_name_and_time(event.payload[:name], event.duration)}</td>
51
51
  </tr>
52
52
  HTML
53
53
  end
@@ -57,17 +57,16 @@ module Footnotes
57
57
 
58
58
  protected
59
59
  def print_name_and_time(name, time)
60
- "<span style='background-color:#{generate_red_color(time, alert_ratio)}'>#{escape(name || 'SQL')} (#{'%.3fms' % time})</span>"
60
+ "<span style='background-color:#{alert_color(time, alert_ratio)}'>#{escape(name || 'SQL')} (#{'%.3fms' % time})</span>"
61
61
  end
62
62
 
63
63
  def print_query(query)
64
64
  escape(query.to_s.gsub(/(\s)+/, ' ').gsub('`', ''))
65
65
  end
66
66
 
67
- def generate_red_color(value, alert)
68
- c = ((value.to_f/alert).to_i - 1) * 16
69
- c = 0 if c < 0; c = 15 if c > 15; c = (15-c).to_s(16)
70
- "#ff#{c*4}"
67
+ def alert_color(value, threshold)
68
+ return 'transparent' if value < threshold
69
+ '#ffff00'
71
70
  end
72
71
 
73
72
  def alert_ratio
@@ -103,7 +102,7 @@ module Footnotes
103
102
  attr_accessor :events, :ignore_regexps
104
103
 
105
104
  def initialize(orm)
106
- super()
105
+ super()
107
106
  @events = []
108
107
  orm.each {|adapter| ActiveSupport::LogSubscriber.attach_to adapter, self}
109
108
  end
@@ -1,31 +1,40 @@
1
1
  module Footnotes
2
2
  module Notes
3
3
  class ViewNote < AbstractNote
4
+ cattr_accessor :template
5
+
6
+ def self.start!(controller)
7
+ @subscriber ||= ActiveSupport::Notifications.subscribe('render_template.action_view') do |*args|
8
+ event = ActiveSupport::Notifications::Event.new *args
9
+ self.template = {:file => event.payload[:identifier], :duration => event.duration}
10
+ end
11
+ end
12
+
4
13
  def initialize(controller)
5
14
  @controller = controller
6
- @template = controller.instance_variable_get(:@template)
7
15
  end
8
16
 
9
17
  def row
10
18
  :edit
11
19
  end
12
20
 
21
+ def title
22
+ "View (#{"%.3f" % self.template[:duration]}ms)"
23
+ end
24
+
13
25
  def link
14
26
  escape(Footnotes::Filter.prefix(filename, 1, 1))
15
27
  end
16
28
 
17
29
  def valid?
18
- prefix? && first_render?
30
+ prefix? && filename && File.exists?(filename)
19
31
  end
20
32
 
21
33
  protected
22
34
 
23
- def first_render?
24
- @template.instance_variable_get(:@_first_render)
25
- end
26
-
27
35
  def filename
28
- @filename ||= @template.instance_variable_get(:@_first_render).filename
36
+ return @filename if defined?(@filename)
37
+ @filename = self.class.template.try(:[], :file)
29
38
  end
30
39
 
31
40
  end
@@ -1,3 +1,3 @@
1
1
  module Footnotes
2
- VERSION = "4.1.5"
2
+ VERSION = "5.0.0"
3
3
  end
@@ -0,0 +1 @@
1
+ require_relative "./rails-footnotes"
@@ -6,21 +6,16 @@ Gem::Specification.new do |s|
6
6
  s.name = "rails-footnotes"
7
7
  s.version = Footnotes::VERSION
8
8
  s.platform = Gem::Platform::RUBY
9
- s.authors = ["Roman V. Babenko", "José Valim", "Keenan Brock", "Duane Johnson", "Adrien Siami"]
10
- s.email = ["romanvbabenko@gmail.com"]
11
- s.homepage = "http://github.com/josevalim/rails-footnotes"
9
+ s.authors = ["Roman V. Babenko", "José Valim", "Keenan Brock", "Duane Johnson", "Adrien Siami", "André Arko"]
10
+ s.email = ["andre@arko.net"]
11
+ s.homepage = "http://github.com/indirect/rails-footnotes"
12
12
  s.summary = %q{Every Rails page has footnotes that gives information about your application and links back to your editor.}
13
13
  s.description = %q{Every Rails page has footnotes that gives information about your application and links back to your editor.}
14
14
 
15
- s.rubyforge_project = "rails-footnotes"
16
-
17
- s.add_dependency "rails", ">= 3.2"
18
-
19
- s.add_development_dependency "rspec-rails", '~> 2.14.0'
20
- s.add_development_dependency "capybara"
15
+ s.add_dependency "rails", "~> 6.0"
16
+ s.required_ruby_version = "~> 3.0"
21
17
 
22
18
  s.files = `git ls-files`.split("\n")
23
19
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
- s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
25
20
  s.require_paths = ["lib"]
26
21
  end
@@ -11,17 +11,21 @@ describe Footnotes::Notes::AbstractNote do
11
11
  Footnotes::Filter.notes = @notes
12
12
  end
13
13
 
14
- it {described_class.should respond_to :start!}
15
- it {described_class.should respond_to :close!}
16
- it {described_class.should respond_to :title}
14
+ it {expect(described_class).to respond_to :start!}
15
+ it {expect(described_class).to respond_to :close!}
16
+ it {expect(described_class).to respond_to :title}
17
17
 
18
18
  it {should respond_to :to_sym}
19
- its(:to_sym) {should eql :abstract}
20
19
 
21
- it { described_class.should be_included }
20
+ describe '#to_sym' do
21
+ subject { super().to_sym }
22
+ it {should eql :abstract}
23
+ end
24
+
25
+ it { expect(described_class).to be_included }
22
26
  specify do
23
27
  Footnotes::Filter.notes = []
24
- described_class.should_not be_included
28
+ expect(described_class).not_to be_included
25
29
  end
26
30
 
27
31
  it { should respond_to :row }
@@ -45,12 +49,12 @@ describe Footnotes::Notes::AbstractNote do
45
49
 
46
50
  #TODO should be moved to builder
47
51
  #helpers
48
- specify { subject.escape('<').should eql '&lt;' }
49
- specify { subject.escape('&').should eql '&amp;' }
50
- specify { subject.escape('>').should eql '&gt;' }
52
+ specify { expect(subject.escape('<')).to eql '&lt;' }
53
+ specify { expect(subject.escape('&')).to eql '&amp;' }
54
+ specify { expect(subject.escape('>')).to eql '&gt;' }
51
55
 
52
- specify { subject.mount_table([]).should be_blank }
53
- specify { subject.mount_table([['h1', 'h2', 'h3']], :class => 'table').should be_blank }
56
+ specify { expect(subject.mount_table([])).to be_blank }
57
+ specify { expect(subject.mount_table([['h1', 'h2', 'h3']], :class => 'table')).to be_blank }
54
58
 
55
59
  specify {
56
60
  tab = <<-TABLE
@@ -60,7 +64,7 @@ describe Footnotes::Notes::AbstractNote do
60
64
  </table>
61
65
  TABLE
62
66
 
63
- subject.mount_table([['h1'],['r1c1']], :class => 'table').should eql tab
67
+ expect(subject.mount_table([['h1'],['r1c1']], :class => 'table')).to eql tab
64
68
  }
65
69
 
66
70
  specify {
@@ -70,7 +74,7 @@ describe Footnotes::Notes::AbstractNote do
70
74
  <tbody><tr><td>r1c1</td><td>r1c2</td><td>r1c3</td></tr></tbody>
71
75
  </table>
72
76
  TABLE
73
- subject.mount_table([['h1', 'h2', 'h3'],['r1c1', 'r1c2', 'r1c3']]).should eql tab
77
+ expect(subject.mount_table([['h1', 'h2', 'h3'],['r1c1', 'r1c2', 'r1c3']])).to eql tab
74
78
  }
75
79
 
76
80
  specify {