stimulus_reflex 2.1.2 → 2.1.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of stimulus_reflex might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/Rakefile +8 -2
- data/bin/rake +29 -0
- data/bin/standardize +1 -1
- data/lib/generators/USAGE +14 -0
- data/lib/generators/stimulus_reflex_generator.rb +30 -0
- data/lib/generators/templates/application_controller.js +59 -0
- data/lib/generators/templates/application_reflex.rb +12 -0
- data/lib/generators/templates/custom_controller.js +37 -0
- data/lib/generators/templates/custom_reflex.rb +23 -0
- data/lib/stimulus_reflex.rb +1 -0
- data/lib/stimulus_reflex/channel.rb +4 -5
- data/lib/stimulus_reflex/version.rb +1 -1
- data/lib/tasks/stimulus_reflex/install.rake +28 -0
- data/test/generators/stimulus_reflex_generator_test.rb +18 -0
- data/test/test_helper.rb +4 -0
- data/test/tmp/app/reflexes/application_reflex.rb +12 -0
- data/test/tmp/app/reflexes/demo_reflex.rb +23 -0
- metadata +20 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 225d5ebaf25744294ea11566c1b1ea792b19141ec56d10a2017eb39407a1b346
|
4
|
+
data.tar.gz: 2d4afe1de7f8fd3e4f4d12fb29f4c51088713b69303b4c905c8a6cb1ad0385a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c5bd0958b9eaabe325c8c65d81bead836dfb182f43059ea786a941eb9268920efbad8be79498e53bd97529bdea13fc2f24a382ceebf97a81c8ebcf70523d753d
|
7
|
+
data.tar.gz: 49c2bea2d9f35a3722c7e3cd4824441623a4660e46d0754a12906dcfe552c0474222af076f4bc096b89da45f1a3f3b4a0521270ab9f9856e069ad96325e1a9b5
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
[![Lines of Code](http://img.shields.io/badge/lines_of_code-
|
1
|
+
[![Lines of Code](http://img.shields.io/badge/lines_of_code-516-brightgreen.svg?style=flat)](http://blog.codinghorror.com/the-best-code-is-no-code-at-all/)
|
2
2
|
[![Maintainability](https://api.codeclimate.com/v1/badges/2b24fdbd1ae37a24bedb/maintainability)](https://codeclimate.com/github/hopsoft/stimulus_reflex/maintainability)
|
3
3
|
![Prettier-Standard](https://github.com/hopsoft/stimulus_reflex/workflows/Prettier-Standard/badge.svg)
|
4
4
|
![StandardRB](https://github.com/hopsoft/stimulus_reflex/workflows/StandardRB/badge.svg)
|
data/Rakefile
CHANGED
@@ -1,9 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "bundler/gem_tasks"
|
4
|
+
require "rails/test_unit/runner"
|
4
5
|
|
5
6
|
task default: [:test]
|
6
7
|
|
7
|
-
task :test do
|
8
|
-
|
8
|
+
task :test do |task|
|
9
|
+
return 1 unless system("cd javascript && yarn run test")
|
10
|
+
Rails::TestUnit::Runner.run
|
11
|
+
end
|
12
|
+
|
13
|
+
task :test_ruby do |task|
|
14
|
+
Rails::TestUnit::Runner.run
|
9
15
|
end
|
data/bin/rake
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rake' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if /This file was generated by Bundler/.match?(File.read(bundle_binstub, 300))
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load Gem.bin_path("rake", "rake")
|
data/bin/standardize
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
Description:
|
2
|
+
Generate boilerplate files to help get you up and running with StimulusReflex
|
3
|
+
|
4
|
+
Example:
|
5
|
+
rails generate stimulus_reflex User
|
6
|
+
|
7
|
+
This will create, but not overwrite the following files:
|
8
|
+
|
9
|
+
app/javascript/controllers/application_controller.js
|
10
|
+
app/javascript/controllers/user_controller.js
|
11
|
+
app/reflexes/application_reflex.rb
|
12
|
+
app/reflexes/user_reflex.rb
|
13
|
+
|
14
|
+
Don't forget to setup the application: https://docs.stimulusreflex.com/setup
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators"
|
4
|
+
|
5
|
+
class StimulusReflexGenerator < Rails::Generators::NamedBase
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
7
|
+
|
8
|
+
def initialize_reflexes
|
9
|
+
copy_reflex_files
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize_controllers
|
13
|
+
copy_controller_files
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
CONTROLLER_BASE_PATH = "app/javascript/controllers"
|
19
|
+
REFLEX_BASE_PATH = "app/reflexes"
|
20
|
+
|
21
|
+
def copy_reflex_files
|
22
|
+
template "application_reflex.rb", File.join(REFLEX_BASE_PATH, "application_reflex.rb")
|
23
|
+
template "custom_reflex.rb", File.join(REFLEX_BASE_PATH, "#{name.underscore}_reflex.rb")
|
24
|
+
end
|
25
|
+
|
26
|
+
def copy_controller_files
|
27
|
+
template "application_controller.js", File.join(CONTROLLER_BASE_PATH, "application_controller.js")
|
28
|
+
template "custom_controller.js", File.join(CONTROLLER_BASE_PATH, "#{name.underscore}_controller.js")
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import { Controller } from 'stimulus'
|
2
|
+
import StimulusReflex from 'stimulus_reflex'
|
3
|
+
|
4
|
+
/* This is your application's ApplicationController.
|
5
|
+
* All StimulusReflex controllers should inherit from this class.
|
6
|
+
*
|
7
|
+
* Example:
|
8
|
+
*
|
9
|
+
* import ApplicationController from './application_controller'
|
10
|
+
*
|
11
|
+
* export default class extends ApplicationController { ... }
|
12
|
+
*
|
13
|
+
* Learn more at: https://docs.stimulusreflex.com
|
14
|
+
*/
|
15
|
+
export default class extends Controller {
|
16
|
+
connect () {
|
17
|
+
StimulusReflex.register(this)
|
18
|
+
}
|
19
|
+
|
20
|
+
/* Application wide lifecycle methods.
|
21
|
+
* Use these methods to handle lifecycle concerns for the entire application.
|
22
|
+
* Using the lifecycle is optional, so feel free to delete these stubs if you don't need them.
|
23
|
+
*
|
24
|
+
* Arguments:
|
25
|
+
*
|
26
|
+
* element - the element that triggered the reflex
|
27
|
+
* may be different than the Stimulus controller's this.element
|
28
|
+
*
|
29
|
+
* reflex - the name of the reflex e.g. "ExampleReflex#demo"
|
30
|
+
*
|
31
|
+
* error - error message from the server
|
32
|
+
*/
|
33
|
+
|
34
|
+
beforeReflex (element, reflex) {
|
35
|
+
// document.body.classList.add('wait')
|
36
|
+
}
|
37
|
+
|
38
|
+
reflexSuccess (element, reflex, error) {
|
39
|
+
// show success message etc...
|
40
|
+
}
|
41
|
+
|
42
|
+
reflexError (element, reflex, error) {
|
43
|
+
// show error message etc...
|
44
|
+
}
|
45
|
+
|
46
|
+
afterReflex (element, reflex) {
|
47
|
+
// document.body.classList.remove('wait')
|
48
|
+
|
49
|
+
const focusElement = this.element.querySelector('[autofocus]')
|
50
|
+
if (focusElement) {
|
51
|
+
focusElement.focus()
|
52
|
+
|
53
|
+
// shenanigans to ensure that the cursor is placed at the end of the existing value
|
54
|
+
const value = focusElement.value
|
55
|
+
focusElement.value = ''
|
56
|
+
focusElement.value = value
|
57
|
+
}
|
58
|
+
}
|
59
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class ApplicationReflex < StimulusReflex::Reflex
|
4
|
+
# Put application wide Reflex behavior in this file.
|
5
|
+
#
|
6
|
+
# Example:
|
7
|
+
#
|
8
|
+
# # If your ActionCable connection is: `identified_by :current_user`
|
9
|
+
# delegate :current_user, to: :channel
|
10
|
+
#
|
11
|
+
# Learn more at: https://docs.stimulusreflex.com
|
12
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import ApplicationController from './application_controller'
|
2
|
+
|
3
|
+
/* This is the custom StimulusReflex controller for <%= @name.classify %>Reflex.
|
4
|
+
* Learn more at: https://docs.stimulusreflex.com
|
5
|
+
*/
|
6
|
+
export default class extends ApplicationController {
|
7
|
+
/* Reflex specific lifecycle methods.
|
8
|
+
* Use methods similar to this example to handle lifecycle concerns for a specific Reflex method.
|
9
|
+
* Using the lifecycle is optional, so feel free to delete these stubs if you don't need them.
|
10
|
+
*
|
11
|
+
* Example:
|
12
|
+
*
|
13
|
+
* <a href="#" data-reflex="<%= @name.classify %>Reflex#example">Example</a>
|
14
|
+
*
|
15
|
+
* Arguments:
|
16
|
+
*
|
17
|
+
* element - the element that triggered the reflex
|
18
|
+
* may be different than the Stimulus controller's this.element
|
19
|
+
*
|
20
|
+
* reflex - the name of the reflex e.g. "<%= @name.classify %>Reflex#example"
|
21
|
+
*
|
22
|
+
* error - error message from the server
|
23
|
+
*/
|
24
|
+
|
25
|
+
// beforeUpdate(element, reflex) {
|
26
|
+
// element.innerText = 'Updating...'
|
27
|
+
// }
|
28
|
+
|
29
|
+
// updateSuccess(element, reflex) {
|
30
|
+
// element.innerText = 'Updated Successfully.'
|
31
|
+
// }
|
32
|
+
|
33
|
+
// updateError(element, reflex, error) {
|
34
|
+
// console.error('updateError', error);
|
35
|
+
// element.innerText = 'Updated Failed!'
|
36
|
+
// }
|
37
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class <%= @name.classify %>Reflex < ApplicationReflex
|
4
|
+
# Add Reflex methods in this file.
|
5
|
+
#
|
6
|
+
# All Reflex instances expose the following properties:
|
7
|
+
#
|
8
|
+
# - connection - the ActionCable connection
|
9
|
+
# - channel - the ActionCable channel
|
10
|
+
# - request - an ActionDispatch::Request proxy for the socket connection
|
11
|
+
# - session - the ActionDispatch::Session store for the current visitor
|
12
|
+
# - url - the URL of the page that triggered the reflex
|
13
|
+
# - element - a Hash like object that represents the HTML element that triggered the reflex
|
14
|
+
#
|
15
|
+
# Example:
|
16
|
+
#
|
17
|
+
# def example(argument=true)
|
18
|
+
# # Your logic here...
|
19
|
+
# # Any declared instance variables will be made available to the Rails controller and view.
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# Learn more at: https://docs.stimulusreflex.com
|
23
|
+
end
|
data/lib/stimulus_reflex.rb
CHANGED
@@ -19,7 +19,7 @@ class StimulusReflex::Channel < ActionCable::Channel::Base
|
|
19
19
|
def receive(data)
|
20
20
|
url = data["url"].to_s
|
21
21
|
selectors = (data["selectors"] || []).select(&:present?)
|
22
|
-
selectors = ["body"] if selectors.blank?
|
22
|
+
selectors = data["selectors"] = ["body"] if selectors.blank?
|
23
23
|
target = data["target"].to_s
|
24
24
|
reflex_name, method_name = target.split("#")
|
25
25
|
reflex_name = reflex_name.classify
|
@@ -100,15 +100,14 @@ class StimulusReflex::Channel < ActionCable::Channel::Base
|
|
100
100
|
|
101
101
|
def broadcast_morphs(selectors, data, html)
|
102
102
|
document = Nokogiri::HTML(html)
|
103
|
+
selectors = selectors.select { |s| document.css(s).present? }
|
103
104
|
selectors.each do |selector|
|
104
|
-
match = document.css(selector)
|
105
|
-
next if match.blank?
|
106
105
|
cable_ready[stream_name].morph(
|
107
106
|
selector: selector,
|
108
|
-
html:
|
107
|
+
html: document.css(selector).inner_html,
|
109
108
|
children_only: true,
|
110
109
|
permanent_attribute_name: "data-reflex-permanent",
|
111
|
-
stimulus_reflex: data
|
110
|
+
stimulus_reflex: data.merge(last: selector == selectors.last)
|
112
111
|
)
|
113
112
|
end
|
114
113
|
cable_ready.broadcast
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fileutils"
|
4
|
+
|
5
|
+
namespace :stimulus_reflex do
|
6
|
+
desc "Install StimulusReflex in this application"
|
7
|
+
task install: :environment do
|
8
|
+
system "bundle exec rails webpacker:install:stimulus"
|
9
|
+
system "yarn add stimulus_reflex"
|
10
|
+
|
11
|
+
FileUtils.mkdir_p Rails.root.join("app/javascript/controllers"), verbose: true
|
12
|
+
FileUtils.mkdir_p Rails.root.join("app/reflexes"), verbose: true
|
13
|
+
|
14
|
+
filepath = Rails.root.join("app/javascript/controllers/index.js")
|
15
|
+
puts "Updating #{filepath}"
|
16
|
+
lines = File.open(filepath, "r") { |f| f.readlines }
|
17
|
+
import_line = lines.find { |line| line.start_with?("import StimulusReflex") }
|
18
|
+
initialize_line = lines.find { |line| line.start_with?("StimulusReflex.initialize") }
|
19
|
+
unless import_line
|
20
|
+
matches = lines.select { |line| line =~ /\A(require|import)/ }
|
21
|
+
lines.insert lines.index(matches.last).to_i + 1, "import StimulusReflex from 'stimulus_reflex'\n"
|
22
|
+
end
|
23
|
+
lines << "StimulusReflex.initialize(application)\n" unless initialize_line
|
24
|
+
File.open(filepath, "w") { |f| f.write lines.join }
|
25
|
+
|
26
|
+
system "bundle exec rails generate stimulus_reflex example"
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators/test_case"
|
4
|
+
require_relative "../test_helper"
|
5
|
+
|
6
|
+
class StimulusReflexGeneratorTest < Rails::Generators::TestCase
|
7
|
+
tests StimulusReflexGenerator
|
8
|
+
destination File.expand_path("../../tmp", __FILE__)
|
9
|
+
setup :prepare_destination
|
10
|
+
|
11
|
+
test "creates named controller and reflex files" do
|
12
|
+
run_generator %w[demo]
|
13
|
+
assert_file "app/javascript/controllers/application_controller.js"
|
14
|
+
assert_file "app/javascript/controllers/demo_controller.js", /DemoReflex/
|
15
|
+
assert_file "app/reflexes/application_reflex.rb"
|
16
|
+
assert_file "app/reflexes/demo_reflex.rb", /DemoReflex/
|
17
|
+
end
|
18
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class ApplicationReflex < StimulusReflex::Reflex
|
4
|
+
# Put application wide Reflex behavior in this file.
|
5
|
+
#
|
6
|
+
# Example:
|
7
|
+
#
|
8
|
+
# # If your ActionCable connection is: `identified_by :current_user`
|
9
|
+
# delegate :current_user, to: :channel
|
10
|
+
#
|
11
|
+
# Learn more at: https://docs.stimulusreflex.com
|
12
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class DemoReflex < ApplicationReflex
|
4
|
+
# Add Reflex methods in this file.
|
5
|
+
#
|
6
|
+
# All Reflex instances expose the following properties:
|
7
|
+
#
|
8
|
+
# - connection - the ActionCable connection
|
9
|
+
# - channel - the ActionCable channel
|
10
|
+
# - request - an ActionDispatch::Request proxy for the socket connection
|
11
|
+
# - session - the ActionDispatch::Session store for the current visitor
|
12
|
+
# - url - the URL of the page that triggered the reflex
|
13
|
+
# - element - a Hash like object that represents the HTML element that triggered the reflex
|
14
|
+
#
|
15
|
+
# Example:
|
16
|
+
#
|
17
|
+
# def example(argument=true)
|
18
|
+
# # Your logic here...
|
19
|
+
# # Any declared instance variables will be made available to the Rails controller and view.
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# Learn more at: https://docs.stimulusreflex.com
|
23
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stimulus_reflex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Hopkins
|
8
|
-
- Ron Cooke
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2019-10-
|
11
|
+
date: 2019-10-16 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rack
|
@@ -140,7 +139,6 @@ dependencies:
|
|
140
139
|
description:
|
141
140
|
email:
|
142
141
|
- natehop@gmail.com
|
143
|
-
- brasco@thebrascode.com
|
144
142
|
executables: []
|
145
143
|
extensions: []
|
146
144
|
extra_rdoc_files: []
|
@@ -153,13 +151,25 @@ files:
|
|
153
151
|
- Rakefile
|
154
152
|
- bin/console
|
155
153
|
- bin/loc
|
154
|
+
- bin/rake
|
156
155
|
- bin/setup
|
157
156
|
- bin/standardize
|
157
|
+
- lib/generators/USAGE
|
158
|
+
- lib/generators/stimulus_reflex_generator.rb
|
159
|
+
- lib/generators/templates/application_controller.js
|
160
|
+
- lib/generators/templates/application_reflex.rb
|
161
|
+
- lib/generators/templates/custom_controller.js
|
162
|
+
- lib/generators/templates/custom_reflex.rb
|
158
163
|
- lib/stimulus_reflex.rb
|
159
164
|
- lib/stimulus_reflex/channel.rb
|
160
165
|
- lib/stimulus_reflex/element.rb
|
161
166
|
- lib/stimulus_reflex/reflex.rb
|
162
167
|
- lib/stimulus_reflex/version.rb
|
168
|
+
- lib/tasks/stimulus_reflex/install.rake
|
169
|
+
- test/generators/stimulus_reflex_generator_test.rb
|
170
|
+
- test/test_helper.rb
|
171
|
+
- test/tmp/app/reflexes/application_reflex.rb
|
172
|
+
- test/tmp/app/reflexes/demo_reflex.rb
|
163
173
|
homepage: https://github.com/hopsoft/stimulus_reflex
|
164
174
|
licenses:
|
165
175
|
- MIT
|
@@ -182,5 +192,9 @@ requirements: []
|
|
182
192
|
rubygems_version: 3.0.3
|
183
193
|
signing_key:
|
184
194
|
specification_version: 4
|
185
|
-
summary: Build reactive
|
186
|
-
test_files:
|
195
|
+
summary: Build reactive applications with the Rails tooling you already know and love.
|
196
|
+
test_files:
|
197
|
+
- test/test_helper.rb
|
198
|
+
- test/generators/stimulus_reflex_generator_test.rb
|
199
|
+
- test/tmp/app/reflexes/demo_reflex.rb
|
200
|
+
- test/tmp/app/reflexes/application_reflex.rb
|