bullet 5.4.3 → 5.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +1 -92
- data/CHANGELOG.md +6 -9
- data/Gemfile.mongoid-5.0 +1 -1
- data/{Gemfile.mongoid-2.4 → Gemfile.mongoid-6.0} +2 -2
- data/README.md +4 -2
- data/lib/bullet/active_record4.rb +2 -2
- data/lib/bullet/active_record41.rb +5 -6
- data/lib/bullet/active_record42.rb +6 -19
- data/lib/bullet/dependency.rb +8 -34
- data/lib/bullet/{mongoid3x.rb → mongoid6x.rb} +3 -3
- data/lib/bullet/notification/n_plus_one_query.rb +3 -3
- data/lib/bullet/notification/unused_eager_loading.rb +12 -7
- data/lib/bullet/rack.rb +6 -1
- data/lib/bullet/version.rb +1 -1
- data/spec/bullet/notification/n_plus_one_query_spec.rb +3 -3
- data/spec/bullet/notification/unused_eager_loading_spec.rb +1 -1
- data/spec/integration/counter_cache_spec.rb +7 -0
- data/test.sh +1 -10
- data/update.sh +1 -10
- metadata +4 -18
- data/Gemfile.mongoid-2.5 +0 -15
- data/Gemfile.mongoid-2.6 +0 -15
- data/Gemfile.mongoid-2.7 +0 -15
- data/Gemfile.mongoid-2.8 +0 -15
- data/Gemfile.mongoid-3.0 +0 -15
- data/Gemfile.mongoid-3.1 +0 -15
- data/Gemfile.rails-3.0 +0 -16
- data/Gemfile.rails-3.1 +0 -16
- data/Gemfile.rails-3.2 +0 -16
- data/lib/bullet/active_record3.rb +0 -238
- data/lib/bullet/active_record3x.rb +0 -210
- data/lib/bullet/mongoid2x.rb +0 -56
- data/spec/integration/active_record3/association_spec.rb +0 -745
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f8cac0418ea4a1bb9f8abc6c12e84022f2f118d
|
4
|
+
data.tar.gz: ebdf99115037dec22a5480a63d3bed5f15956dda
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0904f996964a403a495af310bab8a0612e614eb72a71d08646948508c25d4bf36d2b939da65156a5fc81595477820e0f123aa2a88d618fe97e28e81a6b6f8ada
|
7
|
+
data.tar.gz: d491e12ccce38a26a5e3d27d3f6b84acafe34bb7b6aff56b78a8e22a73a5a3abf88443110587de0080e50b32ef70d8ca387eab5faac0b1bec16efed04bf3acc1
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,107 +1,16 @@
|
|
1
1
|
sudo: false
|
2
2
|
language: ruby
|
3
3
|
rvm:
|
4
|
-
- 1.9.3
|
5
|
-
- 2.0
|
6
|
-
- 2.1
|
7
|
-
- 2.2
|
8
4
|
- 2.3.0
|
9
5
|
gemfile:
|
10
6
|
- Gemfile.rails-5.0
|
11
7
|
- Gemfile.rails-4.2
|
12
8
|
- Gemfile.rails-4.1
|
13
9
|
- Gemfile.rails-4.0
|
14
|
-
- Gemfile.
|
15
|
-
- Gemfile.rails-3.1
|
16
|
-
- Gemfile.rails-3.0
|
10
|
+
- Gemfile.mongoid-6.0
|
17
11
|
- Gemfile.mongoid-5.0
|
18
12
|
- Gemfile.mongoid-4.0
|
19
|
-
- Gemfile.mongoid-3.1
|
20
|
-
- Gemfile.mongoid-3.0
|
21
|
-
- Gemfile.mongoid-2.8
|
22
|
-
- Gemfile.mongoid-2.7
|
23
|
-
- Gemfile.mongoid-2.6
|
24
|
-
- Gemfile.mongoid-2.5
|
25
|
-
- Gemfile.mongoid-2.4
|
26
13
|
env:
|
27
14
|
- DB=sqlite
|
28
15
|
services:
|
29
16
|
- mongodb
|
30
|
-
matrix:
|
31
|
-
exclude:
|
32
|
-
- rvm: 1.9.3
|
33
|
-
gemfile: Gemfile.rails-4.0
|
34
|
-
- rvm: 1.9.3
|
35
|
-
gemfile: Gemfile.rails-4.1
|
36
|
-
- rvm: 1.9.3
|
37
|
-
gemfile: Gemfile.rails-4.2
|
38
|
-
- rvm: 1.9.3
|
39
|
-
gemfile: Gemfile.rails-5.0
|
40
|
-
- rvm: 1.9.3
|
41
|
-
gemfile: Gemfile.mongoid-2.4
|
42
|
-
- rvm: 1.9.3
|
43
|
-
gemfile: Gemfile.mongoid-2.5
|
44
|
-
- rvm: 1.9.3
|
45
|
-
gemfile: Gemfile.mongoid-2.6
|
46
|
-
- rvm: 1.9.3
|
47
|
-
gemfile: Gemfile.mongoid-2.7
|
48
|
-
- rvm: 1.9.3
|
49
|
-
gemfile: Gemfile.mongoid-2.8
|
50
|
-
- rvm: 1.9.3
|
51
|
-
gemfile: Gemfile.mongoid-3.0
|
52
|
-
- rvm: 1.9.3
|
53
|
-
gemfile: Gemfile.mongoid-3.1
|
54
|
-
- rvm: 1.9.3
|
55
|
-
gemfile: Gemfile.mongoid-4.0
|
56
|
-
- rvm: 1.9.3
|
57
|
-
gemfile: Gemfile.mongoid-5.0
|
58
|
-
- rvm: 2.0
|
59
|
-
gemfile: Gemfile.rails-3.0
|
60
|
-
- rvm: 2.0
|
61
|
-
gemfile: Gemfile.rails-5.0
|
62
|
-
- rvm: 2.1
|
63
|
-
gemfile: Gemfile.rails-3.0
|
64
|
-
- rvm: 2.1
|
65
|
-
gemfile: Gemfile.rails-5.0
|
66
|
-
- rvm: 2.2
|
67
|
-
gemfile: Gemfile.rails-3.0
|
68
|
-
- rvm: 2.2
|
69
|
-
gemfile: Gemfile.rails-3.1
|
70
|
-
- rvm: 2.2
|
71
|
-
gemfile: Gemfile.rails-3.2
|
72
|
-
- rvm: 2.2
|
73
|
-
gemfile: Gemfile.rails-5.0
|
74
|
-
- rvm: 2.2
|
75
|
-
gemfile: Gemfile.mongoid-3.1
|
76
|
-
- rvm: 2.2
|
77
|
-
gemfile: Gemfile.mongoid-3.0
|
78
|
-
- rvm: 2.2
|
79
|
-
gemfile: Gemfile.mongoid-2.8
|
80
|
-
- rvm: 2.2
|
81
|
-
gemfile: Gemfile.mongoid-2.7
|
82
|
-
- rvm: 2.2
|
83
|
-
gemfile: Gemfile.mongoid-2.6
|
84
|
-
- rvm: 2.2
|
85
|
-
gemfile: Gemfile.mongoid-2.5
|
86
|
-
- rvm: 2.2
|
87
|
-
gemfile: Gemfile.mongoid-2.4
|
88
|
-
- rvm: 2.3.0
|
89
|
-
gemfile: Gemfile.rails-3.0
|
90
|
-
- rvm: 2.3.0
|
91
|
-
gemfile: Gemfile.rails-3.1
|
92
|
-
- rvm: 2.3.0
|
93
|
-
gemfile: Gemfile.rails-3.2
|
94
|
-
- rvm: 2.3.0
|
95
|
-
gemfile: Gemfile.mongoid-3.1
|
96
|
-
- rvm: 2.3.0
|
97
|
-
gemfile: Gemfile.mongoid-3.0
|
98
|
-
- rvm: 2.3.0
|
99
|
-
gemfile: Gemfile.mongoid-2.8
|
100
|
-
- rvm: 2.3.0
|
101
|
-
gemfile: Gemfile.mongoid-2.7
|
102
|
-
- rvm: 2.3.0
|
103
|
-
gemfile: Gemfile.mongoid-2.6
|
104
|
-
- rvm: 2.3.0
|
105
|
-
gemfile: Gemfile.mongoid-2.5
|
106
|
-
- rvm: 2.3.0
|
107
|
-
gemfile: Gemfile.mongoid-2.4
|
data/CHANGELOG.md
CHANGED
@@ -1,17 +1,14 @@
|
|
1
1
|
# Next Release
|
2
2
|
|
3
|
-
## 5.
|
4
|
-
|
5
|
-
* Fix "false alert" in rails 5 #239
|
6
|
-
|
7
|
-
## 5.4.2
|
8
|
-
|
9
|
-
* Fix "display http request method" #311
|
10
|
-
|
11
|
-
## 5.4.1
|
3
|
+
## 5.5.0 (12/30/2016)
|
12
4
|
|
13
5
|
* Display http request method #311
|
6
|
+
* Add close button to footer
|
14
7
|
* Raise an error if bullet does not support AR or Mongoid
|
8
|
+
* Avoid double backtrace
|
9
|
+
* Fix false alert on counter cache when associations are already loaded #288
|
10
|
+
* Fix "false alert" in rails 5 #239
|
11
|
+
* Do not support ActiveRecord 3.x and Mongoid 3.x / 4.x anymore
|
15
12
|
|
16
13
|
## 5.4.0 (10/09/2016)
|
17
14
|
|
data/Gemfile.mongoid-5.0
CHANGED
@@ -2,10 +2,10 @@ source "https://rubygems.org"
|
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
gem 'rails', '~>
|
5
|
+
gem 'rails', '~> 5.0.0'
|
6
6
|
gem 'sqlite3', platforms: [:ruby]
|
7
7
|
gem 'activerecord-jdbcsqlite3-adapter', platforms: [:jruby]
|
8
|
-
gem 'mongoid', '~>
|
8
|
+
gem 'mongoid', '~> 6.0.0'
|
9
9
|
|
10
10
|
gem "rspec"
|
11
11
|
|
data/README.md
CHANGED
@@ -9,10 +9,12 @@ The Bullet gem is designed to help you increase your application's performance b
|
|
9
9
|
|
10
10
|
Best practice is to use Bullet in development mode or custom mode (staging, profile, etc.). The last thing you want is your clients getting alerts about how lazy you are.
|
11
11
|
|
12
|
-
Bullet gem now supports **activerecord** >=
|
12
|
+
Bullet gem now supports **activerecord** >= 4.0 and **mongoid** >= 4.0.
|
13
13
|
|
14
14
|
If you use activerecord 2.x, please use bullet <= 4.5.0
|
15
15
|
|
16
|
+
If you use activerecord 3.x, plesae use bullet < 5.5.0
|
17
|
+
|
16
18
|
## External Introduction
|
17
19
|
|
18
20
|
* [http://railscasts.com/episodes/372-bullet](http://railscasts.com/episodes/372-bullet)
|
@@ -81,7 +83,7 @@ The code above will enable all seven of the Bullet notification systems:
|
|
81
83
|
* `Bullet.growl`: pop up Growl warnings if your system has Growl installed. Requires a little bit of configuration
|
82
84
|
* `Bullet.xmpp`: send XMPP/Jabber notifications to the receiver indicated. Note that the code will currently not handle the adding of contacts, so you will need to make both accounts indicated know each other manually before you will receive any notifications. If you restart the development server frequently, the 'coming online' sound for the Bullet account may start to annoy - in this case set :show_online_status to false; you will still get notifications, but the Bullet account won't announce it's online status anymore.
|
83
85
|
* `Bullet.raise`: raise errors, useful for making your specs fail unless they have optimized queries
|
84
|
-
* `Bullet.add_footer`: adds the details in the bottom left corner of the page
|
86
|
+
* `Bullet.add_footer`: adds the details in the bottom left corner of the page. Double click the footer or use close button to hide footer.
|
85
87
|
* `Bullet.stacktrace_includes`: include paths with any of these substrings in the stack trace, even if they are not in your main app
|
86
88
|
* `Bullet.stacktrace_excludes`: ignore paths with any of these substrings in the stack trace, even if they are not in your main app.
|
87
89
|
* `Bullet.slack`: add notifications to slack
|
@@ -152,7 +152,7 @@ module Bullet
|
|
152
152
|
::ActiveRecord::Associations::HasManyAssociation.class_eval do
|
153
153
|
alias_method :origin_empty?, :empty?
|
154
154
|
def empty?
|
155
|
-
if Bullet.start? && !has_cached_counter?(@reflection)
|
155
|
+
if Bullet.start? && !loaded? && !has_cached_counter?(@reflection)
|
156
156
|
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
157
157
|
end
|
158
158
|
origin_empty?
|
@@ -162,7 +162,7 @@ module Bullet
|
|
162
162
|
::ActiveRecord::Associations::HasAndBelongsToManyAssociation.class_eval do
|
163
163
|
alias_method :origin_empty?, :empty?
|
164
164
|
def empty?
|
165
|
-
if Bullet.start?
|
165
|
+
if Bullet.start? && !loaded?
|
166
166
|
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
167
167
|
end
|
168
168
|
origin_empty?
|
@@ -176,14 +176,13 @@ module Bullet
|
|
176
176
|
end
|
177
177
|
|
178
178
|
::ActiveRecord::Associations::HasManyAssociation.class_eval do
|
179
|
-
alias_method :
|
180
|
-
|
181
|
-
|
182
|
-
result = origin_has_cached_counter?(reflection)
|
179
|
+
alias_method :origin_count_records, :count_records
|
180
|
+
def count_records
|
181
|
+
result = has_cached_counter?
|
183
182
|
if Bullet.start? && !result
|
184
|
-
Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name)
|
183
|
+
Bullet::Detector::CounterCache.add_counter_cache(@owner, @reflection.name)
|
185
184
|
end
|
186
|
-
|
185
|
+
origin_count_records
|
187
186
|
end
|
188
187
|
end
|
189
188
|
end
|
@@ -230,33 +230,20 @@ module Bullet
|
|
230
230
|
::ActiveRecord::Associations::HasManyAssociation.class_eval do
|
231
231
|
alias_method :origin_many_empty?, :empty?
|
232
232
|
def empty?
|
233
|
-
Thread.current[:bullet_collection_empty] = true
|
234
233
|
result = origin_many_empty?
|
235
|
-
Thread.current[:bullet_collection_empty] = nil
|
236
234
|
if Bullet.start? && !has_cached_counter?(@reflection)
|
237
235
|
Bullet::Detector::NPlusOneQuery.call_association(@owner, @reflection.name)
|
238
236
|
end
|
239
237
|
result
|
240
238
|
end
|
241
239
|
|
242
|
-
alias_method :
|
243
|
-
def
|
244
|
-
result =
|
245
|
-
if Bullet.start? && !result
|
246
|
-
Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name)
|
240
|
+
alias_method :origin_count_records, :count_records
|
241
|
+
def count_records
|
242
|
+
result = has_cached_counter?
|
243
|
+
if Bullet.start? && !result
|
244
|
+
Bullet::Detector::CounterCache.add_counter_cache(@owner, @reflection.name)
|
247
245
|
end
|
248
|
-
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
::ActiveRecord::Associations::HasManyThroughAssociation.class_eval do
|
253
|
-
alias_method :origin_hmt_has_cached_counter?, :has_cached_counter?
|
254
|
-
def has_cached_counter?(reflection = reflection())
|
255
|
-
result = origin_hmt_has_cached_counter?(reflection)
|
256
|
-
if Bullet.start? && !result && !Thread.current[:bullet_collection_empty]
|
257
|
-
Bullet::Detector::CounterCache.add_counter_cache(owner, reflection.name)
|
258
|
-
end
|
259
|
-
result
|
246
|
+
origin_count_records
|
260
247
|
end
|
261
248
|
end
|
262
249
|
end
|
data/lib/bullet/dependency.rb
CHANGED
@@ -14,11 +14,7 @@ module Bullet
|
|
14
14
|
|
15
15
|
def active_record_version
|
16
16
|
@active_record_version ||= begin
|
17
|
-
if
|
18
|
-
'active_record3'
|
19
|
-
elsif active_record31? || active_record32?
|
20
|
-
'active_record3x'
|
21
|
-
elsif active_record40?
|
17
|
+
if active_record40?
|
22
18
|
'active_record4'
|
23
19
|
elsif active_record41?
|
24
20
|
'active_record41'
|
@@ -36,24 +32,18 @@ module Bullet
|
|
36
32
|
|
37
33
|
def mongoid_version
|
38
34
|
@mongoid_version ||= begin
|
39
|
-
if
|
40
|
-
'mongoid2x'
|
41
|
-
elsif mongoid3x?
|
42
|
-
'mongoid3x'
|
43
|
-
elsif mongoid4x?
|
35
|
+
if mongoid4x?
|
44
36
|
'mongoid4x'
|
45
37
|
elsif mongoid5x?
|
46
38
|
'mongoid5x'
|
39
|
+
elsif mongoid6x?
|
40
|
+
'mongoid6x'
|
47
41
|
else
|
48
42
|
raise "Bullet does not support mongoid #{::Mongoid::VERSION} yet"
|
49
43
|
end
|
50
44
|
end
|
51
45
|
end
|
52
46
|
|
53
|
-
def active_record3?
|
54
|
-
active_record? && ::ActiveRecord::VERSION::MAJOR == 3
|
55
|
-
end
|
56
|
-
|
57
47
|
def active_record4?
|
58
48
|
active_record? && ::ActiveRecord::VERSION::MAJOR == 4
|
59
49
|
end
|
@@ -62,18 +52,6 @@ module Bullet
|
|
62
52
|
active_record? && ::ActiveRecord::VERSION::MAJOR == 5
|
63
53
|
end
|
64
54
|
|
65
|
-
def active_record30?
|
66
|
-
active_record3? && ::ActiveRecord::VERSION::MINOR == 0
|
67
|
-
end
|
68
|
-
|
69
|
-
def active_record31?
|
70
|
-
active_record3? && ::ActiveRecord::VERSION::MINOR == 1
|
71
|
-
end
|
72
|
-
|
73
|
-
def active_record32?
|
74
|
-
active_record3? && ::ActiveRecord::VERSION::MINOR == 2
|
75
|
-
end
|
76
|
-
|
77
55
|
def active_record40?
|
78
56
|
active_record4? && ::ActiveRecord::VERSION::MINOR == 0
|
79
57
|
end
|
@@ -94,14 +72,6 @@ module Bullet
|
|
94
72
|
active_record5? && ::ActiveRecord::VERSION::MINOR == 1
|
95
73
|
end
|
96
74
|
|
97
|
-
def mongoid2x?
|
98
|
-
mongoid? && ::Mongoid::VERSION =~ /\A2\.[4-9]/
|
99
|
-
end
|
100
|
-
|
101
|
-
def mongoid3x?
|
102
|
-
mongoid? && ::Mongoid::VERSION =~ /\A3/
|
103
|
-
end
|
104
|
-
|
105
75
|
def mongoid4x?
|
106
76
|
mongoid? && ::Mongoid::VERSION =~ /\A4/
|
107
77
|
end
|
@@ -109,5 +79,9 @@ module Bullet
|
|
109
79
|
def mongoid5x?
|
110
80
|
mongoid? && ::Mongoid::VERSION =~ /\A5/
|
111
81
|
end
|
82
|
+
|
83
|
+
def mongoid6x?
|
84
|
+
mongoid? && ::Mongoid::VERSION =~ /\A6/
|
85
|
+
end
|
112
86
|
end
|
113
87
|
end
|
@@ -21,7 +21,7 @@ module Bullet
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def each(&block)
|
24
|
-
records =
|
24
|
+
records = view.map{ |doc| ::Mongoid::Factory.from_db(klass, doc) }
|
25
25
|
if records.length > 1
|
26
26
|
Bullet::Detector::NPlusOneQuery.add_possible_objects(records)
|
27
27
|
elsif records.size == 1
|
@@ -43,8 +43,8 @@ module Bullet
|
|
43
43
|
::Mongoid::Relations::Accessors.class_eval do
|
44
44
|
alias_method :origin_get_relation, :get_relation
|
45
45
|
|
46
|
-
def get_relation(name, metadata, reload = false)
|
47
|
-
result = origin_get_relation(name, metadata, reload)
|
46
|
+
def get_relation(name, metadata, object, reload = false)
|
47
|
+
result = origin_get_relation(name, metadata, object, reload)
|
48
48
|
if metadata.macro !~ /embed/
|
49
49
|
Bullet::Detector::NPlusOneQuery.call_association(self, name)
|
50
50
|
end
|
@@ -12,18 +12,18 @@ module Bullet
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def title
|
15
|
-
"
|
15
|
+
"USE eager loading #{@path ? "in #{@path}" : 'detected'}"
|
16
16
|
end
|
17
17
|
|
18
18
|
def notification_data
|
19
19
|
super.merge(
|
20
|
-
:backtrace =>
|
20
|
+
:backtrace => []
|
21
21
|
)
|
22
22
|
end
|
23
23
|
|
24
24
|
protected
|
25
25
|
def call_stack_messages
|
26
|
-
(['
|
26
|
+
(['Call stack'] + @callers).join( "\n " )
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
@@ -7,19 +7,24 @@ module Bullet
|
|
7
7
|
@callers = callers
|
8
8
|
end
|
9
9
|
|
10
|
-
def notification_data
|
11
|
-
super.merge(
|
12
|
-
:backtrace => @callers
|
13
|
-
)
|
14
|
-
end
|
15
|
-
|
16
10
|
def body
|
17
11
|
"#{klazz_associations_str}\n Remove from your finder: #{associations_str}"
|
18
12
|
end
|
19
13
|
|
20
14
|
def title
|
21
|
-
"
|
15
|
+
"AVOID eager loading #{@path ? "in #{@path}" : 'detected'}"
|
22
16
|
end
|
17
|
+
|
18
|
+
def notification_data
|
19
|
+
super.merge(
|
20
|
+
:backtrace => []
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
def call_stack_messages
|
26
|
+
(['Call stack'] + @callers).join( "\n " )
|
27
|
+
end
|
23
28
|
end
|
24
29
|
end
|
25
30
|
end
|
data/lib/bullet/rack.rb
CHANGED
@@ -51,7 +51,7 @@ module Bullet
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def footer_note
|
54
|
-
"<div #{footer_div_attributes}>" + Bullet.footer_info.uniq.join("<br>") + "</div>"
|
54
|
+
"<div #{footer_div_attributes}>" + footer_close_button + Bullet.footer_info.uniq.join("<br>") + "</div>"
|
55
55
|
end
|
56
56
|
|
57
57
|
def file?(headers)
|
@@ -75,6 +75,7 @@ module Bullet
|
|
75
75
|
end
|
76
76
|
|
77
77
|
private
|
78
|
+
|
78
79
|
def footer_div_attributes
|
79
80
|
<<EOF
|
80
81
|
data-is-bullet-footer ondblclick="this.parentNode.removeChild(this);" style="position: fixed; bottom: 0pt; left: 0pt; cursor: pointer; border-style: solid; border-color: rgb(153, 153, 153);
|
@@ -84,5 +85,9 @@ data-is-bullet-footer ondblclick="this.parentNode.removeChild(this);" style="pos
|
|
84
85
|
color: rgb(119, 119, 119); font-size: 16px; font-family: 'Arial', sans-serif; z-index:9999;"
|
85
86
|
EOF
|
86
87
|
end
|
88
|
+
|
89
|
+
def footer_close_button
|
90
|
+
"<span onclick='this.parentNode.remove()' style='position:absolute; right: 10px; top: 0px; font-weight: bold; color: #333;'>×</span>"
|
91
|
+
end
|
87
92
|
end
|
88
93
|
end
|