browse-everything 1.0.0.rc1 → 1.0.0.rc2

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 (32) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +4 -0
  3. data/.travis.yml +6 -0
  4. data/README.md +19 -3
  5. data/Rakefile +0 -9
  6. data/app/assets/javascripts/browse_everything/behavior.js +413 -0
  7. data/app/assets/stylesheets/_browse_everything_bootstrap3.scss +122 -0
  8. data/app/assets/stylesheets/_browse_everything_bootstrap4.scss +117 -0
  9. data/app/assets/stylesheets/browse_everything/_browse_everything.scss +2 -116
  10. data/app/views/browse_everything/_providers.html.erb +2 -1
  11. data/app/views/browse_everything/index.html.erb +3 -2
  12. data/browse-everything.gemspec +0 -3
  13. data/karma.conf.js +71 -0
  14. data/lib/browse-everything.rb +0 -2
  15. data/lib/browse_everything.rb +10 -5
  16. data/lib/browse_everything/version.rb +1 -1
  17. data/lib/generators/browse_everything/install_generator.rb +1 -7
  18. data/spec/javascripts/behavior_spec.js +1 -3
  19. data/spec/javascripts/helpers/jquery.js +11008 -0
  20. data/spec/javascripts/karma_spec.rb +16 -0
  21. data/spec/lib/browse_everything_spec.rb +7 -0
  22. data/spec/test_app_templates/Gemfile.extra +7 -0
  23. data/spec/test_app_templates/lib/generators/test_app_generator.rb +7 -1
  24. metadata +11 -56
  25. data/app/assets/javascripts/browse_everything/behavior.js.coffee +0 -342
  26. data/app/assets/stylesheets/browse_everything.scss +0 -6
  27. data/app/helpers/font_awesome_version_helper.rb +0 -17
  28. data/lib/generators/browse_everything/assets_generator.rb +0 -13
  29. data/lib/generators/browse_everything/templates/browse_everything.scss +0 -6
  30. data/spec/javascripts/jasmine_spec.rb +0 -21
  31. data/spec/javascripts/support/jasmine.yml +0 -124
  32. data/spec/javascripts/support/jasmine_helper.rb +0 -16
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'open3'
4
+
5
+ # Run karma and parse the output for failures.
6
+ # The spec will fail if any karma test fails.
7
+ describe 'Karma' do
8
+ let(:runner) { Open3.capture3('karma', 'start') }
9
+ let(:output) { runner[0] + runner[1] }
10
+ let(:status) { runner[2].exitstatus }
11
+
12
+ it 'expects all karma tests to pass' do
13
+ $stderr.puts output unless status == 0
14
+ expect(status).to eq(0)
15
+ end
16
+ end
@@ -72,6 +72,13 @@ describe BrowseEverything do
72
72
 
73
73
  it_behaves_like 'a configured BrowseEverything module'
74
74
  end
75
+
76
+ context 'without a YAML file' do
77
+ let(:config) { '' }
78
+ it 'raises a configuration error' do
79
+ expect { described_class.configure(:config).to raise_error(BrowseEverything::ConfigurationError, 'Missing browse_everything_providers.yml configuration file') }
80
+ end
81
+ end
75
82
  end
76
83
 
77
84
  context 'with an unsupported or invalid configuration' do
@@ -1,2 +1,9 @@
1
1
  gem 'jquery-rails'
2
2
  gem 'puma-rails'
3
+
4
+ if ENV['TEST_BOOTSTRAP'] == "3"
5
+ gem "bootstrap-sass"
6
+ else
7
+ # bootstrap 4
8
+ gem "bootstrap"
9
+ end
@@ -17,7 +17,13 @@ class TestAppGenerator < Rails::Generators::Base
17
17
  copy_file File.expand_path('app/assets/stylesheets/application.css', ENV['RAILS_ROOT']), 'app/assets/stylesheets/application.css.scss'
18
18
  remove_file 'app/assets/stylesheets/application.css'
19
19
  insert_into_file 'app/assets/stylesheets/application.css.scss', after: '*/' do
20
- %(\n\n@import "browse_everything")
20
+ if ENV['TEST_BOOTSTRAP'] == "3"
21
+ # bootstrap 3 from bootstrap-sass gem
22
+ %(\n\n@import "bootstrap-sprockets";\n@import "bootstrap";\n@import "browse_everything_bootstrap3";)
23
+ else
24
+ # bootstrap4 from bootstrap gem
25
+ %(\n\n@import "bootstrap";\n@import "browse_everything_bootstrap4";)
26
+ end
21
27
  end
22
28
  end
23
29
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: browse-everything
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc1
4
+ version: 1.0.0.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carolyn Cole
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2018-11-06 00:00:00.000000000 Z
16
+ date: 2018-11-28 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: addressable
@@ -43,20 +43,6 @@ dependencies:
43
43
  - - ">="
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
- - !ruby/object:Gem::Dependency
47
- name: bootstrap-sass
48
- requirement: !ruby/object:Gem::Requirement
49
- requirements:
50
- - - "~>"
51
- - !ruby/object:Gem::Version
52
- version: '3.2'
53
- type: :runtime
54
- prerelease: false
55
- version_requirements: !ruby/object:Gem::Requirement
56
- requirements:
57
- - - "~>"
58
- - !ruby/object:Gem::Version
59
- version: '3.2'
60
46
  - !ruby/object:Gem::Dependency
61
47
  name: dropbox_api
62
48
  requirement: !ruby/object:Gem::Requirement
@@ -71,20 +57,6 @@ dependencies:
71
57
  - - ">="
72
58
  - !ruby/object:Gem::Version
73
59
  version: 0.1.10
74
- - !ruby/object:Gem::Dependency
75
- name: font-awesome-rails
76
- requirement: !ruby/object:Gem::Requirement
77
- requirements:
78
- - - ">="
79
- - !ruby/object:Gem::Version
80
- version: '0'
81
- type: :runtime
82
- prerelease: false
83
- version_requirements: !ruby/object:Gem::Requirement
84
- requirements:
85
- - - ">="
86
- - !ruby/object:Gem::Version
87
- version: '0'
88
60
  - !ruby/object:Gem::Dependency
89
61
  name: google-api-client
90
62
  requirement: !ruby/object:Gem::Requirement
@@ -155,20 +127,6 @@ dependencies:
155
127
  - - ">="
156
128
  - !ruby/object:Gem::Version
157
129
  version: '0'
158
- - !ruby/object:Gem::Dependency
159
- name: sass-rails
160
- requirement: !ruby/object:Gem::Requirement
161
- requirements:
162
- - - ">="
163
- - !ruby/object:Gem::Version
164
- version: '0'
165
- type: :runtime
166
- prerelease: false
167
- version_requirements: !ruby/object:Gem::Requirement
168
- requirements:
169
- - - ">="
170
- - !ruby/object:Gem::Version
171
- version: '0'
172
130
  - !ruby/object:Gem::Dependency
173
131
  name: signet
174
132
  requirement: !ruby/object:Gem::Requirement
@@ -504,13 +462,13 @@ files:
504
462
  - Rakefile
505
463
  - SUPPORT.md
506
464
  - app/assets/javascripts/browse_everything.js
507
- - app/assets/javascripts/browse_everything/behavior.js.coffee
508
- - app/assets/stylesheets/browse_everything.scss
465
+ - app/assets/javascripts/browse_everything/behavior.js
466
+ - app/assets/stylesheets/_browse_everything_bootstrap3.scss
467
+ - app/assets/stylesheets/_browse_everything_bootstrap4.scss
509
468
  - app/assets/stylesheets/browse_everything/_browse_everything.scss
510
469
  - app/assets/stylesheets/jquery.treetable.theme.browse.css
511
470
  - app/controllers/browse_everything_controller.rb
512
471
  - app/helpers/browse_everything_helper.rb
513
- - app/helpers/font_awesome_version_helper.rb
514
472
  - app/services/browse_everything_session.rb
515
473
  - app/services/browse_everything_session/provider_session.rb
516
474
  - app/services/browser_factory.rb
@@ -524,6 +482,7 @@ files:
524
482
  - browse-everything.gemspec
525
483
  - config/locales/en_browse_everything.yml
526
484
  - config/routes.rb
485
+ - karma.conf.js
527
486
  - lib/browse-everything.rb
528
487
  - lib/browse_everything.rb
529
488
  - lib/browse_everything/auth/google/credentials.rb
@@ -540,10 +499,8 @@ files:
540
499
  - lib/browse_everything/file_entry.rb
541
500
  - lib/browse_everything/retriever.rb
542
501
  - lib/browse_everything/version.rb
543
- - lib/generators/browse_everything/assets_generator.rb
544
502
  - lib/generators/browse_everything/config_generator.rb
545
503
  - lib/generators/browse_everything/install_generator.rb
546
- - lib/generators/browse_everything/templates/browse_everything.scss
547
504
  - lib/generators/browse_everything/templates/browse_everything_providers.yml.example
548
505
  - spec/controllers/browse_everything_controller_spec.rb
549
506
  - spec/features/select_files_spec.rb
@@ -557,9 +514,8 @@ files:
557
514
  - spec/helper/browse_everything_controller_helper_spec.rb
558
515
  - spec/javascripts/behavior_spec.js
559
516
  - spec/javascripts/helpers/jasmine-jquery.js
560
- - spec/javascripts/jasmine_spec.rb
561
- - spec/javascripts/support/jasmine.yml
562
- - spec/javascripts/support/jasmine_helper.rb
517
+ - spec/javascripts/helpers/jquery.js
518
+ - spec/javascripts/karma_spec.rb
563
519
  - spec/lib/browse_everything/auth/google/credentials_spec.rb
564
520
  - spec/lib/browse_everything/browse_everything_helper_spec.rb
565
521
  - spec/lib/browse_everything/browser_spec.rb
@@ -609,7 +565,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
609
565
  version: 1.3.1
610
566
  requirements: []
611
567
  rubyforge_project:
612
- rubygems_version: 2.6.14.1
568
+ rubygems_version: 2.7.3
613
569
  signing_key:
614
570
  specification_version: 4
615
571
  summary: AJAX/Rails engine file browser for cloud storage services
@@ -626,9 +582,8 @@ test_files:
626
582
  - spec/helper/browse_everything_controller_helper_spec.rb
627
583
  - spec/javascripts/behavior_spec.js
628
584
  - spec/javascripts/helpers/jasmine-jquery.js
629
- - spec/javascripts/jasmine_spec.rb
630
- - spec/javascripts/support/jasmine.yml
631
- - spec/javascripts/support/jasmine_helper.rb
585
+ - spec/javascripts/helpers/jquery.js
586
+ - spec/javascripts/karma_spec.rb
632
587
  - spec/lib/browse_everything/auth/google/credentials_spec.rb
633
588
  - spec/lib/browse_everything/browse_everything_helper_spec.rb
634
589
  - spec/lib/browse_everything/browser_spec.rb
@@ -1,342 +0,0 @@
1
- $ ->
2
- dialog = $('div#browse-everything')
3
-
4
- initialize = (obj,options) ->
5
- if $('div#browse-everything').length == 0
6
- dialog = $('<div tabindex="-1" id="browse-everything" class="ev-browser modal fade" aria-live="polite" role="dialog" aria-labelledby="beModalLabel"></div>').hide().appendTo('body')
7
-
8
- dialog.modal
9
- backdrop: 'static'
10
- show: false
11
- ctx =
12
- opts: $.extend(true, {}, options)
13
- callbacks:
14
- show: $.Callbacks()
15
- done: $.Callbacks()
16
- cancel: $.Callbacks()
17
- fail: $.Callbacks()
18
- ctx.callback_proxy =
19
- show: (func) -> ctx.callbacks.show.add(func) ; return this
20
- done: (func) -> ctx.callbacks.done.add(func) ; return this
21
- cancel: (func) -> ctx.callbacks.cancel.add(func) ; return this
22
- fail: (func) -> ctx.callbacks.fail.add(func) ; return this
23
- $(obj).data('ev-state',ctx)
24
- ctx
25
-
26
- toHiddenFields = (data) ->
27
- fields = $.param(data)
28
- .split('&')
29
- .map (t) -> t.replace(/\+/g,' ').split('=',2)
30
- elements = $(fields).map () ->
31
- $("<input type='hidden'/>")
32
- .attr('name',decodeURIComponent(this[0]))
33
- .val(decodeURIComponent(this[1]))[0].outerHTML
34
- $(elements.toArray().join("\n"))
35
-
36
- indicateSelected = () ->
37
- $('input.ev-url').each () ->
38
- $("*[data-ev-location='#{$(this).val()}']").addClass('ev-selected')
39
-
40
- fileIsSelected = (row) ->
41
- result = false
42
- $('input.ev-url').each () ->
43
- if this.value == $(row).data('ev-location')
44
- result = true
45
- return result
46
-
47
- toggleFileSelect = (row) ->
48
- row.toggleClass('ev-selected')
49
- if row.hasClass('ev-selected')
50
- selectFile(row)
51
- else
52
- unselectFile(row)
53
- updateFileCount()
54
-
55
- selectFile = (row) ->
56
- target_form = $('form.ev-submit-form')
57
- file_location = row.data('ev-location')
58
- hidden_input = $("<input type='hidden' class='ev-url' name='selected_files[]'/>").val(file_location)
59
- target_form.append(hidden_input)
60
- unless $(row).find('.ev-select-file').prop('checked')
61
- $(row).find('.ev-select-file').prop('checked', true)
62
-
63
- unselectFile = (row) ->
64
- target_form = $('form.ev-submit-form')
65
- file_location = row.data('ev-location')
66
- $("form.ev-submit-form input[value='#{file_location}']").remove()
67
- if $(row).find('.ev-select-file').prop('checked')
68
- $(row).find('.ev-select-file').prop('checked', false)
69
-
70
- updateFileCount = () ->
71
- count = $('input.ev-url').length
72
- files = if count == 1 then "file" else "files"
73
- $('.ev-status').html("#{count} #{files} selected")
74
-
75
- toggleBranchSelect = (row) ->
76
- if row.hasClass('collapsed')
77
- node_id = row.find('td.ev-file-name a.ev-link').attr('href')
78
- $('table#file-list').treetable('expandNode',node_id)
79
-
80
- selectAll = (rows) ->
81
- rows.each () ->
82
- if $(this).data('tt-branch')
83
- box = $(this).find('#select_all')[0]
84
- $(box).prop('checked', true)
85
- $(box).prop('value', "1")
86
- toggleBranchSelect($(this))
87
- else
88
- toggleFileSelect($(this)) unless fileIsSelected($(this))
89
-
90
- selectChildRows = (row, action) ->
91
- $('table#file-list tr').each () ->
92
- if $(this).data('tt-parent-id')
93
- re = RegExp($(row).data('tt-id'), 'i')
94
- if $(this).data('tt-parent-id').match(re)
95
- if $(this).data('tt-branch')
96
- box = $(this).find('#select_all')[0]
97
- $(box).prop('value', action)
98
- if action == "1"
99
- $(box).prop("checked", true)
100
- node_id = $(this).find('td.ev-file-name a.ev-link').attr('href')
101
- $('table#file-list').treetable('expandNode',node_id)
102
- else
103
- $(box).prop("checked", false)
104
- else
105
- if action == "1"
106
- $(this).addClass('ev-selected')
107
- selectFile($(this)) unless fileIsSelected($(this))
108
- else
109
- $(this).removeClass('ev-selected')
110
- unselectFile($(this))
111
- updateFileCount()
112
-
113
- tableSetup = (table) ->
114
- table.treetable
115
- expandable: true
116
- onNodeCollapse: ->
117
- node = this;
118
- table.treetable("unloadBranch", node)
119
- onNodeExpand: ->
120
- node = this
121
- startWait()
122
- size = $(node.row).find('td.ev-file-size').text().trim()
123
- start = 1
124
- increment = 1
125
- if (size.indexOf("MB") >-1)
126
- start = 10
127
- increment = 5
128
- if (size.indexOf("KB") >-1)
129
- start = 50
130
- increment = 10
131
- setProgress(start)
132
- progressIntervalID = setInterval (->
133
- start = start + increment
134
- if start > 99
135
- start = 99
136
- setProgress(start)
137
- ), 2000
138
- setTimeout (->
139
- loadFiles(node, table, progressIntervalID)
140
- ), 10
141
- $("#file-list tr:first").focus()
142
- sizeColumns(table)
143
-
144
- sizeColumns = (table) ->
145
- full_width = $('.ev-files').width()
146
- table.width(full_width)
147
- set_size = (selector, pct) ->
148
- $(selector, table).width(full_width * pct).css('width',full_width * pct).css('max-width',full_width * pct)
149
- set_size '.ev-file', 0.4
150
- set_size '.ev-container', 0.4
151
- set_size '.ev-size', 0.1
152
- set_size '.ev-kind', 0.3
153
- set_size '.ev-date', 0.2
154
-
155
- loadFiles = (node, table, progressIntervalID)->
156
- $.ajax
157
- async: true # Must be false, otherwise loadBranch happens after showChildren?
158
- url: $('a.ev-link',node.row).attr('href')
159
- data:
160
- parent: node.row.data('tt-id')
161
- accept: dialog.data('ev-state').opts.accept
162
- context: dialog.data('ev-state').opts.context
163
- .done (html) ->
164
- setProgress('100')
165
- clearInterval progressIntervalID
166
- rows = $('tbody tr',$(html))
167
- table.treetable("loadBranch", node, rows)
168
- $(node).show()
169
- sizeColumns(table)
170
- indicateSelected()
171
- if $(node.row).find('#select_all')[0].checked
172
- selectAll(rows)
173
- .always ->
174
- clearInterval progressIntervalID
175
- stopWait()
176
-
177
- setProgress = (done)->
178
- $('.loading-text').text(done+'% complete')
179
-
180
- refreshFiles = ->
181
- $('.ev-providers select').change()
182
-
183
- startWait = ->
184
- $('.loading-progress').removeClass("hidden")
185
- $('body').css('cursor','wait')
186
- $("html").addClass("wait")
187
- $(".ev-browser").addClass("loading")
188
- $('.ev-submit').attr('disabled', true)
189
-
190
- stopWait = ->
191
- $('.loading-progress').addClass("hidden")
192
- $('body').css('cursor','default')
193
- $("html").removeClass("wait")
194
- $(".ev-browser").removeClass("loading")
195
- $('.ev-submit').attr('disabled', false)
196
-
197
- $(window).on('resize', -> sizeColumns($('table#file-list')))
198
-
199
- $.fn.browseEverything = (options) ->
200
- ctx = $(this).data('ev-state')
201
- options = $(this).data() unless (ctx? or options?)
202
- if options?
203
- ctx = initialize(this[0], options)
204
- $(this).click () ->
205
- dialog.data('ev-state',ctx)
206
- dialog.load ctx.opts.route, () ->
207
- setTimeout refreshFiles, 500
208
- ctx.callbacks.show.fire()
209
- dialog.modal('show')
210
-
211
- if ctx
212
- ctx.callback_proxy
213
- else
214
- {
215
- show: -> this
216
- done: -> this
217
- cancel: -> this
218
- fail: -> this
219
- }
220
-
221
- $.fn.browseEverything.toggleCheckbox = (box) ->
222
- if box.value == "0"
223
- $(box).prop('value', "1")
224
- else
225
- $(box).prop('value', "0")
226
-
227
- $(document).on 'ev.refresh', (event) -> refreshFiles()
228
-
229
- $(document).on 'click', 'button.ev-cancel', (event) ->
230
- event.preventDefault()
231
- dialog.data('ev-state').callbacks.cancel.fire()
232
- $('.ev-browser').modal('hide')
233
-
234
- $(document).on 'click', 'button.ev-submit', (event) ->
235
- event.preventDefault()
236
- $(this).button('loading')
237
- startWait()
238
- main_form = $(this).closest('form')
239
- resolver_url = main_form.data('resolver')
240
- ctx = dialog.data('ev-state')
241
- $(main_form).find('input[name=context]').val(ctx.opts.context)
242
- $.ajax resolver_url,
243
- type: 'POST'
244
- dataType: 'json'
245
- data: main_form.serialize()
246
- .done (data) ->
247
- if ctx.opts.target?
248
- fields = toHiddenFields({selected_files: data})
249
- $(ctx.opts.target).append($(fields))
250
- ctx.callbacks.done.fire(data)
251
- .fail (xhr,status,error) ->
252
- ctx.callbacks.fail.fire(status, error, xhr.responseText)
253
- .always ->
254
- $('body').css('cursor','default')
255
- $('.ev-browser').modal('hide')
256
- $('#browse-btn').focus()
257
-
258
- $(document).on 'click', '.ev-files .ev-container a.ev-link', (event) ->
259
- event.stopPropagation()
260
- event.preventDefault()
261
- row = $(this).closest('tr')
262
- action = if row.hasClass('expanded') then 'collapseNode' else 'expandNode'
263
- node_id = $(this).attr('href')
264
- $('table#file-list').treetable(action,node_id)
265
-
266
- $(document).on 'change', '.ev-providers select', (event) ->
267
- event.preventDefault()
268
- startWait()
269
- $.ajax
270
- url: $(this).val(),
271
- data:
272
- accept: dialog.data('ev-state').opts.accept
273
- context: dialog.data('ev-state').opts.context
274
- .done (data) ->
275
- $('.ev-files').html(data)
276
- indicateSelected();
277
- $('#provider_auth').focus();
278
- tableSetup($('table#file-list'))
279
- .fail (xhr,status,error) ->
280
- if (xhr.responseText.indexOf("Refresh token has expired")>-1)
281
- $('.ev-files').html("Your sessison has expired please clear your cookies.")
282
- else
283
- $('.ev-files').html(xhr.responseText)
284
- .always ->
285
- stopWait()
286
-
287
- $(document).on 'click', '.ev-providers a', (event) ->
288
- $('.ev-providers li').removeClass('ev-selected')
289
- $(this).closest('li').addClass('ev-selected')
290
-
291
- $(document).on 'click', '.ev-file a', (event) ->
292
- event.preventDefault()
293
- target = $(this).closest('*[data-ev-location]')
294
- toggleFileSelect(target)
295
-
296
- $(document).on 'click', '.ev-auth', (event) ->
297
- event.preventDefault()
298
- auth_win = window.open($(this).attr('href'))
299
- check_func = ->
300
- if auth_win.closed
301
- $('.ev-providers .ev-selected a').click()
302
- else
303
- window.setTimeout check_func, 1000
304
- check_func()
305
-
306
- $(document).on 'change', 'input.ev-select-all', (event) ->
307
- event.stopPropagation()
308
- event.preventDefault()
309
- $.fn.browseEverything.toggleCheckbox(this)
310
- action = this.value
311
- row = $(this).closest('tr')
312
- node_id = row.find('td.ev-file-name a.ev-link').attr('href')
313
- if row.hasClass('collapsed')
314
- $('table#file-list').treetable('expandNode',node_id)
315
- else
316
- selectChildRows(row, action)
317
-
318
- $(document).on 'change', 'input.ev-select-file', (event) ->
319
- event.stopPropagation()
320
- event.preventDefault()
321
- toggleFileSelect($(this).closest('tr'))
322
-
323
-
324
- auto_toggle = ->
325
- triggers = $('*[data-toggle=browse-everything]')
326
- if Rails?
327
- $.ajaxSetup({
328
- headers: { 'X-CSRF-TOKEN': (Rails || $.rails).csrfToken() || '' }
329
- });
330
-
331
- triggers.each () ->
332
- ctx = $(this).data('ev-state')
333
- $(this).browseEverything($(this).data()) unless ctx?
334
-
335
- if Turbolinks? && Turbolinks.supported
336
- # Use turbolinks:load for Turbolinks 5, otherwise use the old way
337
- if (Turbolinks.BrowserAdapter)
338
- $(document).on 'turbolinks:load', auto_toggle
339
- else
340
- $(document).on 'page:change', auto_toggle
341
- else
342
- $(document).ready auto_toggle