stimulus_reflex 3.2.3 → 3.3.0.pre4
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/CHANGELOG.md +123 -2
- data/Gemfile.lock +72 -72
- data/README.md +26 -20
- data/lib/generators/USAGE +1 -1
- data/lib/generators/stimulus_reflex_generator.rb +10 -21
- data/lib/generators/templates/{custom_controller.js → app/javascript/controllers/%file_name%_controller.js.tt} +20 -0
- data/lib/generators/templates/{application_controller.js → app/javascript/controllers/application_controller.js.tt} +0 -0
- data/lib/generators/templates/{custom_reflex.rb → app/reflexes/%file_name%_reflex.rb.tt} +6 -0
- data/lib/generators/templates/{application_reflex.rb → app/reflexes/application_reflex.rb.tt} +0 -0
- data/lib/stimulus_reflex.rb +4 -0
- data/lib/stimulus_reflex/broadcasters/broadcaster.rb +56 -0
- data/lib/stimulus_reflex/broadcasters/nothing_broadcaster.rb +17 -0
- data/lib/stimulus_reflex/broadcasters/page_broadcaster.rb +36 -0
- data/lib/stimulus_reflex/broadcasters/selector_broadcaster.rb +51 -0
- data/lib/stimulus_reflex/channel.rb +14 -49
- data/lib/stimulus_reflex/reflex.rb +22 -3
- data/lib/stimulus_reflex/version.rb +1 -1
- data/lib/tasks/stimulus_reflex/install.rake +10 -5
- data/test/generators/stimulus_reflex_generator_test.rb +23 -0
- metadata +28 -16
- data/stimulus_reflex.gemspec +0 -39
- data/tags +0 -42
- data/test/tmp/app/reflexes/application_reflex.rb +0 -12
- data/test/tmp/app/reflexes/posts_reflex.rb +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c9b7c733ac621d7a767be4d2674f3fc93ba082fd49b2b97bae28f1af426c3a2
|
4
|
+
data.tar.gz: 2a8c9b669f1b3ae3ca05061fb56fc04ab68c4617d9c90228ce66ea6af929101e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32827f948085f06d9980c806f2392ca59f4c32b39e5512ee8ef69c89c45192abc4de4824a216c2544e49c816ae345bbbf2713d496f6cd07fbefd1f45e94a9ea1
|
7
|
+
data.tar.gz: b1033c190f6794f2480436ab45da9ba78339dda1cfda7fa2ca724b88186158434dfe36710187bcc36b8fb91433a044ff4585f9deef65178318c95a6e969cf091
|
data/CHANGELOG.md
CHANGED
@@ -2,7 +2,128 @@
|
|
2
2
|
|
3
3
|
## [Unreleased](https://github.com/hopsoft/stimulus_reflex/tree/HEAD)
|
4
4
|
|
5
|
-
[Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.
|
5
|
+
[Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.3.0.pre3...HEAD)
|
6
|
+
|
7
|
+
**Fixed bugs:**
|
8
|
+
|
9
|
+
- Lifecycle callbacks do not work [\#281](https://github.com/hopsoft/stimulus_reflex/issues/281)
|
10
|
+
|
11
|
+
**Closed issues:**
|
12
|
+
|
13
|
+
- self-referential data-reflex-root [\#301](https://github.com/hopsoft/stimulus_reflex/issues/301)
|
14
|
+
- data-reflex-permanent not working when using slim templates [\#295](https://github.com/hopsoft/stimulus_reflex/issues/295)
|
15
|
+
- undefined method `rescue\_with\_handler' whit reflex action such as "click-\>…" or "change-\>…" [\#287](https://github.com/hopsoft/stimulus_reflex/issues/287)
|
16
|
+
|
17
|
+
**Merged pull requests:**
|
18
|
+
|
19
|
+
- Fixed typo in sample code. [\#296](https://github.com/hopsoft/stimulus_reflex/pull/296) ([jclarke](https://github.com/jclarke))
|
20
|
+
|
21
|
+
## [v3.3.0.pre3](https://github.com/hopsoft/stimulus_reflex/tree/v3.3.0.pre3) (2020-08-31)
|
22
|
+
|
23
|
+
[Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.3.0.pre2...v3.3.0.pre3)
|
24
|
+
|
25
|
+
**Fixed bugs:**
|
26
|
+
|
27
|
+
- First argument of type "object" in this.stimulate\(\) will always be assigned to options. [\#278](https://github.com/hopsoft/stimulus_reflex/issues/278)
|
28
|
+
- Allow morphs to run before triggering success/after [\#286](https://github.com/hopsoft/stimulus_reflex/pull/286) ([hopsoft](https://github.com/hopsoft))
|
29
|
+
|
30
|
+
**Closed issues:**
|
31
|
+
|
32
|
+
- Reflex ignores turbolinks cached pages [\#288](https://github.com/hopsoft/stimulus_reflex/issues/288)
|
33
|
+
- Issue with Stimulus Reflex and ViewComponent [\#284](https://github.com/hopsoft/stimulus_reflex/issues/284)
|
34
|
+
- controller inheritance does not seem to work [\#283](https://github.com/hopsoft/stimulus_reflex/issues/283)
|
35
|
+
- Cannot read property 'schema' of undefined [\#282](https://github.com/hopsoft/stimulus_reflex/issues/282)
|
36
|
+
- Reflex on form submit does not get parameter from input\[type="file"\] [\#277](https://github.com/hopsoft/stimulus_reflex/issues/277)
|
37
|
+
- jQuery Plugins [\#246](https://github.com/hopsoft/stimulus_reflex/issues/246)
|
38
|
+
- ActiveStorage variants performance [\#242](https://github.com/hopsoft/stimulus_reflex/issues/242)
|
39
|
+
- Unnecessary body update after text\_content [\#186](https://github.com/hopsoft/stimulus_reflex/issues/186)
|
40
|
+
- Warn about enabling Rails after running stimulus reflex' initializer [\#185](https://github.com/hopsoft/stimulus_reflex/issues/185)
|
41
|
+
- Integration tests for stimulus-reflex [\#162](https://github.com/hopsoft/stimulus_reflex/issues/162)
|
42
|
+
- Clearer explanation of quickstart example without javascript. [\#149](https://github.com/hopsoft/stimulus_reflex/issues/149)
|
43
|
+
- Webpack compilation fails with rails/webpacker 3.6 [\#83](https://github.com/hopsoft/stimulus_reflex/issues/83)
|
44
|
+
|
45
|
+
**Merged pull requests:**
|
46
|
+
|
47
|
+
- Check if reflex exists before using it [\#293](https://github.com/hopsoft/stimulus_reflex/pull/293) ([joshleblanc](https://github.com/joshleblanc))
|
48
|
+
- Add instructions for existing projects [\#291](https://github.com/hopsoft/stimulus_reflex/pull/291) ([gerrywastaken](https://github.com/gerrywastaken))
|
49
|
+
- Fix argument of type object always being assigned to options [\#279](https://github.com/hopsoft/stimulus_reflex/pull/279) ([shawnleong](https://github.com/shawnleong))
|
50
|
+
- Simplify devise authentication logic \(in docs\) [\#276](https://github.com/hopsoft/stimulus_reflex/pull/276) ([inner-whisper](https://github.com/inner-whisper))
|
51
|
+
- Bump lodash from 4.17.15 to 4.17.19 in /javascript [\#275](https://github.com/hopsoft/stimulus_reflex/pull/275) ([dependabot[bot]](https://github.com/apps/dependabot))
|
52
|
+
|
53
|
+
## [v3.3.0.pre2](https://github.com/hopsoft/stimulus_reflex/tree/v3.3.0.pre2) (2020-07-17)
|
54
|
+
|
55
|
+
[Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.3.0.pre1...v3.3.0.pre2)
|
56
|
+
|
57
|
+
**Closed issues:**
|
58
|
+
|
59
|
+
- afterReflex not always firing on morph with selectors [\#269](https://github.com/hopsoft/stimulus_reflex/issues/269)
|
60
|
+
- Lifecycle hooks [\#266](https://github.com/hopsoft/stimulus_reflex/issues/266)
|
61
|
+
- Stimulus Reflex with Rspec not working [\#263](https://github.com/hopsoft/stimulus_reflex/issues/263)
|
62
|
+
|
63
|
+
**Merged pull requests:**
|
64
|
+
|
65
|
+
- Smarter warnings when element not found [\#274](https://github.com/hopsoft/stimulus_reflex/pull/274) ([hopsoft](https://github.com/hopsoft))
|
66
|
+
- Add the attributes to the warning message when element not found [\#273](https://github.com/hopsoft/stimulus_reflex/pull/273) ([hopsoft](https://github.com/hopsoft))
|
67
|
+
- Update find element to ignore SR attrs [\#272](https://github.com/hopsoft/stimulus_reflex/pull/272) ([hopsoft](https://github.com/hopsoft))
|
68
|
+
- Refactor of the morph feature [\#270](https://github.com/hopsoft/stimulus_reflex/pull/270) ([hopsoft](https://github.com/hopsoft))
|
69
|
+
- coerce html arguments to string type [\#268](https://github.com/hopsoft/stimulus_reflex/pull/268) ([leastbad](https://github.com/leastbad))
|
70
|
+
- Update deployment docs after the official AnyCable 1.0 release [\#267](https://github.com/hopsoft/stimulus_reflex/pull/267) ([rmacklin](https://github.com/rmacklin))
|
71
|
+
|
72
|
+
## [v3.3.0.pre1](https://github.com/hopsoft/stimulus_reflex/tree/v3.3.0.pre1) (2020-07-08)
|
73
|
+
|
74
|
+
[Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.3.0.pre0...v3.3.0.pre1)
|
75
|
+
|
76
|
+
**Merged pull requests:**
|
77
|
+
|
78
|
+
- Fix selector morphs for updating partials and ViewComponents [\#262](https://github.com/hopsoft/stimulus_reflex/pull/262) ([leastbad](https://github.com/leastbad))
|
79
|
+
|
80
|
+
## [v3.3.0.pre0](https://github.com/hopsoft/stimulus_reflex/tree/v3.3.0.pre0) (2020-07-04)
|
81
|
+
|
82
|
+
[Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.2.3...v3.3.0.pre0)
|
83
|
+
|
84
|
+
**Implemented enhancements:**
|
85
|
+
|
86
|
+
- Returns more helpful error message if Reflex doesn't exist [\#254](https://github.com/hopsoft/stimulus_reflex/pull/254) ([leastbad](https://github.com/leastbad))
|
87
|
+
- Update install.rake to handle Typescript [\#241](https://github.com/hopsoft/stimulus_reflex/pull/241) ([iv-mexx](https://github.com/iv-mexx))
|
88
|
+
- Morph Modes: page, selector and nothing [\#211](https://github.com/hopsoft/stimulus_reflex/pull/211) ([leastbad](https://github.com/leastbad))
|
89
|
+
|
90
|
+
**Fixed bugs:**
|
91
|
+
|
92
|
+
- Limit MutationObserver mutations [\#256](https://github.com/hopsoft/stimulus_reflex/pull/256) ([jasoncharnes](https://github.com/jasoncharnes))
|
93
|
+
|
94
|
+
**Closed issues:**
|
95
|
+
|
96
|
+
- beforeUpdate/updateSuccess/updateError functions deprecated? [\#255](https://github.com/hopsoft/stimulus_reflex/issues/255)
|
97
|
+
- Error handling will fail if reflex is not defined [\#253](https://github.com/hopsoft/stimulus_reflex/issues/253)
|
98
|
+
- Select with data-reflex in Firefox flickers [\#251](https://github.com/hopsoft/stimulus_reflex/issues/251)
|
99
|
+
- data-reflex-attributes vs data-reflex-dataset [\#237](https://github.com/hopsoft/stimulus_reflex/issues/237)
|
100
|
+
- Shorthand action notations corresponding to stimulus [\#233](https://github.com/hopsoft/stimulus_reflex/issues/233)
|
101
|
+
- Lifecycle methods only called for one reflex [\#225](https://github.com/hopsoft/stimulus_reflex/issues/225)
|
102
|
+
- Tweak the generator so we can specify reflex actions [\#219](https://github.com/hopsoft/stimulus_reflex/issues/219)
|
103
|
+
- Docs: Clarify forcing DOM update with authentication [\#123](https://github.com/hopsoft/stimulus_reflex/issues/123)
|
104
|
+
- ActiveJob integration example [\#112](https://github.com/hopsoft/stimulus_reflex/issues/112)
|
105
|
+
|
106
|
+
**Merged pull requests:**
|
107
|
+
|
108
|
+
- Prep for pre release of 3.3.0 [\#259](https://github.com/hopsoft/stimulus_reflex/pull/259) ([hopsoft](https://github.com/hopsoft))
|
109
|
+
- Fallback to first Stimulus controller in array [\#257](https://github.com/hopsoft/stimulus_reflex/pull/257) ([jasoncharnes](https://github.com/jasoncharnes))
|
110
|
+
- Fix cases where plural reflexes were unresolved [\#252](https://github.com/hopsoft/stimulus_reflex/pull/252) ([joshleblanc](https://github.com/joshleblanc))
|
111
|
+
- warn against collections of identical elements that trigger reflexes [\#250](https://github.com/hopsoft/stimulus_reflex/pull/250) ([leastbad](https://github.com/leastbad))
|
112
|
+
- always calls params to persist them into controller action [\#249](https://github.com/hopsoft/stimulus_reflex/pull/249) ([RolandStuder](https://github.com/RolandStuder))
|
113
|
+
- Update deployment.md [\#248](https://github.com/hopsoft/stimulus_reflex/pull/248) ([user073](https://github.com/user073))
|
114
|
+
- Update reflexes.md [\#247](https://github.com/hopsoft/stimulus_reflex/pull/247) ([user073](https://github.com/user073))
|
115
|
+
- Bump actionpack from 6.0.3.1 to 6.0.3.2 [\#245](https://github.com/hopsoft/stimulus_reflex/pull/245) ([dependabot[bot]](https://github.com/apps/dependabot))
|
116
|
+
- Bump rack from 2.2.2 to 2.2.3 [\#244](https://github.com/hopsoft/stimulus_reflex/pull/244) ([dependabot[bot]](https://github.com/apps/dependabot))
|
117
|
+
- Revert "Revert "Add instructions for pulling the user id out of session storage"" [\#240](https://github.com/hopsoft/stimulus_reflex/pull/240) ([leastbad](https://github.com/leastbad))
|
118
|
+
- Revert "Add instructions for pulling the user id out of session storage" [\#239](https://github.com/hopsoft/stimulus_reflex/pull/239) ([leastbad](https://github.com/leastbad))
|
119
|
+
- Add instructions for pulling the user id out of session storage [\#238](https://github.com/hopsoft/stimulus_reflex/pull/238) ([mtomov](https://github.com/mtomov))
|
120
|
+
- adds params documentation [\#230](https://github.com/hopsoft/stimulus_reflex/pull/230) ([RolandStuder](https://github.com/RolandStuder))
|
121
|
+
- Fix calling wrong controller lifecycle methods [\#226](https://github.com/hopsoft/stimulus_reflex/pull/226) ([davidalejandroaguilar](https://github.com/davidalejandroaguilar))
|
122
|
+
- Allow to pass reflex action names to reflex generator [\#224](https://github.com/hopsoft/stimulus_reflex/pull/224) ([marcoroth](https://github.com/marcoroth))
|
123
|
+
|
124
|
+
## [v3.2.3](https://github.com/hopsoft/stimulus_reflex/tree/v3.2.3) (2020-06-15)
|
125
|
+
|
126
|
+
[Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.2.2...v3.2.3)
|
6
127
|
|
7
128
|
**Fixed bugs:**
|
8
129
|
|
@@ -285,7 +406,6 @@
|
|
285
406
|
**Implemented enhancements:**
|
286
407
|
|
287
408
|
- Explicit and implicit registering of the ActionCable consumer [\#116](https://github.com/hopsoft/stimulus_reflex/pull/116) ([hopsoft](https://github.com/hopsoft))
|
288
|
-
- Add schema support [\#94](https://github.com/hopsoft/stimulus_reflex/pull/94) ([hopsoft](https://github.com/hopsoft))
|
289
409
|
|
290
410
|
## [v2.1.9](https://github.com/hopsoft/stimulus_reflex/tree/v2.1.9) (2020-02-20)
|
291
411
|
|
@@ -340,6 +460,7 @@
|
|
340
460
|
**Implemented enhancements:**
|
341
461
|
|
342
462
|
- Custom Stimulus schema breaks Reflex [\#91](https://github.com/hopsoft/stimulus_reflex/issues/91)
|
463
|
+
- Add schema support [\#94](https://github.com/hopsoft/stimulus_reflex/pull/94) ([hopsoft](https://github.com/hopsoft))
|
343
464
|
- inherit stimulus schema [\#92](https://github.com/hopsoft/stimulus_reflex/pull/92) ([nickyvanurk](https://github.com/nickyvanurk))
|
344
465
|
- Single source of truth [\#76](https://github.com/hopsoft/stimulus_reflex/pull/76) ([leastbad](https://github.com/leastbad))
|
345
466
|
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
stimulus_reflex (3.
|
4
|
+
stimulus_reflex (3.3.0.pre3)
|
5
5
|
cable_ready (>= 4.1.2)
|
6
6
|
nokogiri
|
7
7
|
rack
|
@@ -10,56 +10,56 @@ PATH
|
|
10
10
|
GEM
|
11
11
|
remote: https://rubygems.org/
|
12
12
|
specs:
|
13
|
-
actioncable (6.0.3.
|
14
|
-
actionpack (= 6.0.3.
|
13
|
+
actioncable (6.0.3.2)
|
14
|
+
actionpack (= 6.0.3.2)
|
15
15
|
nio4r (~> 2.0)
|
16
16
|
websocket-driver (>= 0.6.1)
|
17
|
-
actionmailbox (6.0.3.
|
18
|
-
actionpack (= 6.0.3.
|
19
|
-
activejob (= 6.0.3.
|
20
|
-
activerecord (= 6.0.3.
|
21
|
-
activestorage (= 6.0.3.
|
22
|
-
activesupport (= 6.0.3.
|
17
|
+
actionmailbox (6.0.3.2)
|
18
|
+
actionpack (= 6.0.3.2)
|
19
|
+
activejob (= 6.0.3.2)
|
20
|
+
activerecord (= 6.0.3.2)
|
21
|
+
activestorage (= 6.0.3.2)
|
22
|
+
activesupport (= 6.0.3.2)
|
23
23
|
mail (>= 2.7.1)
|
24
|
-
actionmailer (6.0.3.
|
25
|
-
actionpack (= 6.0.3.
|
26
|
-
actionview (= 6.0.3.
|
27
|
-
activejob (= 6.0.3.
|
24
|
+
actionmailer (6.0.3.2)
|
25
|
+
actionpack (= 6.0.3.2)
|
26
|
+
actionview (= 6.0.3.2)
|
27
|
+
activejob (= 6.0.3.2)
|
28
28
|
mail (~> 2.5, >= 2.5.4)
|
29
29
|
rails-dom-testing (~> 2.0)
|
30
|
-
actionpack (6.0.3.
|
31
|
-
actionview (= 6.0.3.
|
32
|
-
activesupport (= 6.0.3.
|
30
|
+
actionpack (6.0.3.2)
|
31
|
+
actionview (= 6.0.3.2)
|
32
|
+
activesupport (= 6.0.3.2)
|
33
33
|
rack (~> 2.0, >= 2.0.8)
|
34
34
|
rack-test (>= 0.6.3)
|
35
35
|
rails-dom-testing (~> 2.0)
|
36
36
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
37
|
-
actiontext (6.0.3.
|
38
|
-
actionpack (= 6.0.3.
|
39
|
-
activerecord (= 6.0.3.
|
40
|
-
activestorage (= 6.0.3.
|
41
|
-
activesupport (= 6.0.3.
|
37
|
+
actiontext (6.0.3.2)
|
38
|
+
actionpack (= 6.0.3.2)
|
39
|
+
activerecord (= 6.0.3.2)
|
40
|
+
activestorage (= 6.0.3.2)
|
41
|
+
activesupport (= 6.0.3.2)
|
42
42
|
nokogiri (>= 1.8.5)
|
43
|
-
actionview (6.0.3.
|
44
|
-
activesupport (= 6.0.3.
|
43
|
+
actionview (6.0.3.2)
|
44
|
+
activesupport (= 6.0.3.2)
|
45
45
|
builder (~> 3.1)
|
46
46
|
erubi (~> 1.4)
|
47
47
|
rails-dom-testing (~> 2.0)
|
48
48
|
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
49
|
-
activejob (6.0.3.
|
50
|
-
activesupport (= 6.0.3.
|
49
|
+
activejob (6.0.3.2)
|
50
|
+
activesupport (= 6.0.3.2)
|
51
51
|
globalid (>= 0.3.6)
|
52
|
-
activemodel (6.0.3.
|
53
|
-
activesupport (= 6.0.3.
|
54
|
-
activerecord (6.0.3.
|
55
|
-
activemodel (= 6.0.3.
|
56
|
-
activesupport (= 6.0.3.
|
57
|
-
activestorage (6.0.3.
|
58
|
-
actionpack (= 6.0.3.
|
59
|
-
activejob (= 6.0.3.
|
60
|
-
activerecord (= 6.0.3.
|
52
|
+
activemodel (6.0.3.2)
|
53
|
+
activesupport (= 6.0.3.2)
|
54
|
+
activerecord (6.0.3.2)
|
55
|
+
activemodel (= 6.0.3.2)
|
56
|
+
activesupport (= 6.0.3.2)
|
57
|
+
activestorage (6.0.3.2)
|
58
|
+
actionpack (= 6.0.3.2)
|
59
|
+
activejob (= 6.0.3.2)
|
60
|
+
activerecord (= 6.0.3.2)
|
61
61
|
marcel (~> 0.3.1)
|
62
|
-
activesupport (6.0.3.
|
62
|
+
activesupport (6.0.3.2)
|
63
63
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
64
64
|
i18n (>= 0.7, < 2)
|
65
65
|
minitest (~> 5.1)
|
@@ -67,17 +67,17 @@ GEM
|
|
67
67
|
zeitwerk (~> 2.2, >= 2.2.2)
|
68
68
|
ast (2.4.1)
|
69
69
|
builder (3.2.4)
|
70
|
-
cable_ready (4.
|
70
|
+
cable_ready (4.3.0)
|
71
71
|
rails (>= 5.2)
|
72
72
|
coderay (1.1.3)
|
73
|
-
concurrent-ruby (1.1.
|
73
|
+
concurrent-ruby (1.1.7)
|
74
74
|
crass (1.0.6)
|
75
75
|
erubi (1.9.0)
|
76
76
|
globalid (0.4.2)
|
77
77
|
activesupport (>= 4.2.0)
|
78
|
-
i18n (1.8.
|
78
|
+
i18n (1.8.5)
|
79
79
|
concurrent-ruby (~> 1.0)
|
80
|
-
loofah (2.
|
80
|
+
loofah (2.7.0)
|
81
81
|
crass (~> 1.0.2)
|
82
82
|
nokogiri (>= 1.5.9)
|
83
83
|
mail (2.7.1)
|
@@ -90,42 +90,42 @@ GEM
|
|
90
90
|
mini_portile2 (2.4.0)
|
91
91
|
minitest (5.14.1)
|
92
92
|
nio4r (2.5.2)
|
93
|
-
nokogiri (1.10.
|
93
|
+
nokogiri (1.10.10)
|
94
94
|
mini_portile2 (~> 2.4.0)
|
95
|
-
parallel (1.19.
|
96
|
-
parser (2.7.1.
|
97
|
-
ast (~> 2.4.
|
95
|
+
parallel (1.19.2)
|
96
|
+
parser (2.7.1.4)
|
97
|
+
ast (~> 2.4.1)
|
98
98
|
pry (0.12.2)
|
99
99
|
coderay (~> 1.1.0)
|
100
100
|
method_source (~> 0.9.0)
|
101
101
|
pry-nav (0.3.0)
|
102
102
|
pry (>= 0.9.10, < 0.13.0)
|
103
|
-
rack (2.2.
|
103
|
+
rack (2.2.3)
|
104
104
|
rack-test (1.1.0)
|
105
105
|
rack (>= 1.0, < 3)
|
106
|
-
rails (6.0.3.
|
107
|
-
actioncable (= 6.0.3.
|
108
|
-
actionmailbox (= 6.0.3.
|
109
|
-
actionmailer (= 6.0.3.
|
110
|
-
actionpack (= 6.0.3.
|
111
|
-
actiontext (= 6.0.3.
|
112
|
-
actionview (= 6.0.3.
|
113
|
-
activejob (= 6.0.3.
|
114
|
-
activemodel (= 6.0.3.
|
115
|
-
activerecord (= 6.0.3.
|
116
|
-
activestorage (= 6.0.3.
|
117
|
-
activesupport (= 6.0.3.
|
106
|
+
rails (6.0.3.2)
|
107
|
+
actioncable (= 6.0.3.2)
|
108
|
+
actionmailbox (= 6.0.3.2)
|
109
|
+
actionmailer (= 6.0.3.2)
|
110
|
+
actionpack (= 6.0.3.2)
|
111
|
+
actiontext (= 6.0.3.2)
|
112
|
+
actionview (= 6.0.3.2)
|
113
|
+
activejob (= 6.0.3.2)
|
114
|
+
activemodel (= 6.0.3.2)
|
115
|
+
activerecord (= 6.0.3.2)
|
116
|
+
activestorage (= 6.0.3.2)
|
117
|
+
activesupport (= 6.0.3.2)
|
118
118
|
bundler (>= 1.3.0)
|
119
|
-
railties (= 6.0.3.
|
119
|
+
railties (= 6.0.3.2)
|
120
120
|
sprockets-rails (>= 2.0.0)
|
121
121
|
rails-dom-testing (2.0.3)
|
122
122
|
activesupport (>= 4.2.0)
|
123
123
|
nokogiri (>= 1.6)
|
124
124
|
rails-html-sanitizer (1.3.0)
|
125
125
|
loofah (~> 2.3)
|
126
|
-
railties (6.0.3.
|
127
|
-
actionpack (= 6.0.3.
|
128
|
-
activesupport (= 6.0.3.
|
126
|
+
railties (6.0.3.2)
|
127
|
+
actionpack (= 6.0.3.2)
|
128
|
+
activesupport (= 6.0.3.2)
|
129
129
|
method_source
|
130
130
|
rake (>= 0.8.7)
|
131
131
|
thor (>= 0.20.3, < 2.0)
|
@@ -133,19 +133,19 @@ GEM
|
|
133
133
|
rake (13.0.1)
|
134
134
|
regexp_parser (1.7.1)
|
135
135
|
rexml (3.2.4)
|
136
|
-
rubocop (0.
|
136
|
+
rubocop (0.89.1)
|
137
137
|
parallel (~> 1.10)
|
138
|
-
parser (>= 2.7.
|
138
|
+
parser (>= 2.7.1.1)
|
139
139
|
rainbow (>= 2.2.2, < 4.0)
|
140
140
|
regexp_parser (>= 1.7)
|
141
141
|
rexml
|
142
|
-
rubocop-ast (>= 0.0.
|
142
|
+
rubocop-ast (>= 0.3.0, < 1.0)
|
143
143
|
ruby-progressbar (~> 1.7)
|
144
144
|
unicode-display_width (>= 1.4.0, < 2.0)
|
145
|
-
rubocop-ast (0.0
|
146
|
-
parser (>= 2.7.
|
147
|
-
rubocop-performance (1.
|
148
|
-
rubocop (>= 0.
|
145
|
+
rubocop-ast (0.3.0)
|
146
|
+
parser (>= 2.7.1.4)
|
147
|
+
rubocop-performance (1.7.1)
|
148
|
+
rubocop (>= 0.82.0)
|
149
149
|
ruby-progressbar (1.10.1)
|
150
150
|
sprockets (4.0.2)
|
151
151
|
concurrent-ruby (~> 1.0)
|
@@ -154,9 +154,9 @@ GEM
|
|
154
154
|
actionpack (>= 4.0)
|
155
155
|
activesupport (>= 4.0)
|
156
156
|
sprockets (>= 3.0.0)
|
157
|
-
standard (0.
|
158
|
-
rubocop (~> 0.
|
159
|
-
rubocop-performance (~> 1.
|
157
|
+
standard (0.5.2)
|
158
|
+
rubocop (~> 0.89.1)
|
159
|
+
rubocop-performance (~> 1.7.1)
|
160
160
|
standardrb (1.0.0)
|
161
161
|
standard
|
162
162
|
thor (1.0.1)
|
@@ -164,10 +164,10 @@ GEM
|
|
164
164
|
tzinfo (1.2.7)
|
165
165
|
thread_safe (~> 0.1)
|
166
166
|
unicode-display_width (1.7.0)
|
167
|
-
websocket-driver (0.7.
|
167
|
+
websocket-driver (0.7.3)
|
168
168
|
websocket-extensions (>= 0.1.0)
|
169
169
|
websocket-extensions (0.1.5)
|
170
|
-
zeitwerk (2.
|
170
|
+
zeitwerk (2.4.0)
|
171
171
|
|
172
172
|
PLATFORMS
|
173
173
|
ruby
|
data/README.md
CHANGED
@@ -11,7 +11,7 @@
|
|
11
11
|
<img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-brightgreen.svg" target="_blank" />
|
12
12
|
</a>
|
13
13
|
<a href="http://blog.codinghorror.com/the-best-code-is-no-code-at-all/" target="_blank">
|
14
|
-
<img alt="Lines of Code" src="https://img.shields.io/badge/lines_of_code-
|
14
|
+
<img alt="Lines of Code" src="https://img.shields.io/badge/lines_of_code-1098-brightgreen.svg?style=flat" />
|
15
15
|
</a>
|
16
16
|
<a href="https://docs.stimulusreflex.com/" target="_blank">
|
17
17
|
<img alt="Documentation" src="https://img.shields.io/badge/documentation-yes-brightgreen.svg" />
|
@@ -44,45 +44,51 @@
|
|
44
44
|
<br />
|
45
45
|
|
46
46
|
|
47
|
-
### 🎉 **
|
47
|
+
### 🎉 **An exciting new way to build modern, reactive, real-time apps with Ruby on Rails.**
|
48
48
|
|
49
49
|
StimulusReflex eliminates the complexity imposed by full-stack frontend frameworks.
|
50
50
|
And, it's fast.
|
51
51
|
|
52
52
|
It works seamlessly with the Rails tooling you already know and love.
|
53
53
|
|
54
|
-
-
|
55
|
-
-
|
56
|
-
- [Russian doll caching](https://edgeguides.rubyonrails.org/caching_with_rails.html#russian-doll-caching)
|
57
|
-
- [
|
58
|
-
- [
|
59
|
-
- etc...
|
54
|
+
- Server-rendered HTML, delivered in miliseconds over the wire via Websockets
|
55
|
+
- ERB templates and partials, with first-class [ViewComponent](https://github.com/github/view_component) support
|
56
|
+
- [Russian doll caching](https://edgeguides.rubyonrails.org/caching_with_rails.html#russian-doll-caching) and [ActiveJob](https://guides.rubyonrails.org/active_job_basics.html)
|
57
|
+
- [StimulusJS](https://stimulusjs.org/) and [Turbolinks](https://www.youtube.com/watch?v=SWEts0rlezA)
|
58
|
+
- Built with [CableReady](https://www.youtube.com/watch?v=dPzv2qsj5L8), our secret power-move
|
60
59
|
|
61
|
-
**
|
60
|
+
**Our goal is to help small teams do big things with familiar tools.**
|
62
61
|
|
63
62
|
This project strives to live up to the vision outlined in [The Rails Doctrine](https://rubyonrails.org/doctrine/).
|
64
63
|
|
65
64
|
## 📚 Docs
|
66
65
|
|
67
|
-
- [
|
66
|
+
- [StimulusReflex Documentation](https://docs.stimulusreflex.com)
|
67
|
+
- [CableReady Documentation](https://cableready.stimulusreflex.com)
|
68
68
|
|
69
69
|
## ✨ Demos
|
70
70
|
|
71
|
-
-
|
72
|
-
-
|
71
|
+
- [StimulusReflex Expo](http://expo.stimulusreflex.com) - part showcase, part learning tool
|
72
|
+
- [Build a Twitter Clone in 10 Minutes](https://youtu.be/F5hA79vKE_E) (video)
|
73
|
+
- [BoxDrop](https://dropbox-clone-rails.herokuapp.com/) - a Dropbox-inspired [concept demo](https://github.com/marcoroth/boxdrop/)
|
73
74
|
|
74
|
-
##
|
75
|
+
## 👩👩👧 Discord Community
|
75
76
|
|
76
|
-
|
77
|
-
- [Discord](https://discord.gg/XveN625) - chat root
|
77
|
+
Please join over 350 of us on [Discord](https://discord.gg/XveN625) for support getting started, as well as active discussions around Rails, StimulusJS and CableReady.
|
78
78
|
|
79
|
-
|
79
|
+
![](https://img.shields.io/discord/629472241427415060)
|
80
|
+
|
81
|
+
Stop by #newcomers and introduce yourselves!
|
82
|
+
|
83
|
+
## 💙 Support
|
80
84
|
|
81
|
-
|
82
|
-
|
83
|
-
|
85
|
+
Your best bet is to ask for help on Discord before filing an issue on Github. We are happy to help, and we ask people to come with all relevant code to look at. A git repo is preferred, but Gists or posts on [Discourse](https://stimulus-reflex.discourse.group) are fine, too.
|
86
|
+
|
87
|
+
Please note that we are not actively providing support on Stack Overflow. If you post there, we likely won't see it.
|
88
|
+
|
89
|
+
## 🚀 Install
|
84
90
|
|
85
|
-
|
91
|
+
CLI and manual setup procedures are fully detailed in the [official docs](https://docs.stimulusreflex.com/setup).
|
86
92
|
|
87
93
|
## 🙏 Contributing
|
88
94
|
|
data/lib/generators/USAGE
CHANGED
@@ -2,7 +2,7 @@ Description:
|
|
2
2
|
Generate boilerplate files to help get you up and running with StimulusReflex
|
3
3
|
|
4
4
|
Example:
|
5
|
-
rails generate stimulus_reflex User
|
5
|
+
rails generate stimulus_reflex User update do_stuff [options]
|
6
6
|
|
7
7
|
This will create, but not overwrite the following files:
|
8
8
|
|
@@ -5,33 +5,22 @@ require "rails/generators"
|
|
5
5
|
class StimulusReflexGenerator < Rails::Generators::NamedBase
|
6
6
|
source_root File.expand_path("templates", __dir__)
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
end
|
11
|
-
|
12
|
-
def initialize_reflexes
|
13
|
-
copy_reflex_files
|
14
|
-
end
|
15
|
-
|
16
|
-
def initialize_controllers
|
17
|
-
copy_controller_files
|
18
|
-
end
|
8
|
+
argument :name, type: :string, required: true, banner: "NAME"
|
9
|
+
argument :actions, type: :array, default: [], banner: "action action"
|
19
10
|
|
20
|
-
|
11
|
+
def execute
|
12
|
+
actions.map!(&:underscore)
|
21
13
|
|
22
|
-
|
23
|
-
REFLEX_BASE_PATH = "app/reflexes"
|
14
|
+
copy_application_files if behavior == :invoke
|
24
15
|
|
25
|
-
|
26
|
-
template "
|
16
|
+
template "app/reflexes/%file_name%_reflex.rb"
|
17
|
+
template "app/javascript/controllers/%file_name%_controller.js"
|
27
18
|
end
|
28
19
|
|
29
|
-
|
30
|
-
template "custom_controller.js", File.join(CONTROLLER_BASE_PATH, "#{name.underscore}_controller.js")
|
31
|
-
end
|
20
|
+
private
|
32
21
|
|
33
22
|
def copy_application_files
|
34
|
-
template "application_reflex.rb"
|
35
|
-
template "application_controller.js"
|
23
|
+
template "app/reflexes/application_reflex.rb"
|
24
|
+
template "app/javascript/controllers/application_controller.js"
|
36
25
|
end
|
37
26
|
end
|
@@ -22,6 +22,7 @@ export default class extends ApplicationController {
|
|
22
22
|
* error - error message from the server
|
23
23
|
*/
|
24
24
|
|
25
|
+
<% if actions.empty? -%>
|
25
26
|
// beforeUpdate(element, reflex) {
|
26
27
|
// element.innerText = 'Updating...'
|
27
28
|
// }
|
@@ -34,4 +35,23 @@ export default class extends ApplicationController {
|
|
34
35
|
// console.error('updateError', error);
|
35
36
|
// element.innerText = 'Update Failed!'
|
36
37
|
// }
|
38
|
+
<% end -%>
|
39
|
+
<% actions.each do |action| -%>
|
40
|
+
// <%= "before_#{action}".camelize(:lower) %>(element, reflex) {
|
41
|
+
// console.log("before <%= action %>", element, reflex)
|
42
|
+
// }
|
43
|
+
|
44
|
+
// <%= "#{action}_success".camelize(:lower) %>(element, reflex) {
|
45
|
+
// console.log("<%= action %> success", element, reflex)
|
46
|
+
// }
|
47
|
+
|
48
|
+
// <%= "#{action}_error".camelize(:lower) %>(element, reflex, error) {
|
49
|
+
// console.error("<%= action %> error", element, reflex, error)
|
50
|
+
// }
|
51
|
+
|
52
|
+
// <%= "after_#{action}".camelize(:lower) %>(element, reflex, error) {
|
53
|
+
// console.log("after <%= action %>", element, reflex, error)
|
54
|
+
// }
|
55
|
+
<%= "\n" unless action == actions.last -%>
|
56
|
+
<% end -%>
|
37
57
|
}
|
File without changes
|
data/lib/generators/templates/{application_reflex.rb → app/reflexes/application_reflex.rb.tt}
RENAMED
File without changes
|
data/lib/stimulus_reflex.rb
CHANGED
@@ -12,6 +12,10 @@ require "stimulus_reflex/version"
|
|
12
12
|
require "stimulus_reflex/reflex"
|
13
13
|
require "stimulus_reflex/element"
|
14
14
|
require "stimulus_reflex/channel"
|
15
|
+
require "stimulus_reflex/broadcasters/broadcaster"
|
16
|
+
require "stimulus_reflex/broadcasters/nothing_broadcaster"
|
17
|
+
require "stimulus_reflex/broadcasters/page_broadcaster"
|
18
|
+
require "stimulus_reflex/broadcasters/selector_broadcaster"
|
15
19
|
require "generators/stimulus_reflex_generator"
|
16
20
|
|
17
21
|
module StimulusReflex
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StimulusReflex
|
4
|
+
class Broadcaster
|
5
|
+
include CableReady::Broadcaster
|
6
|
+
|
7
|
+
attr_reader :reflex, :logger
|
8
|
+
delegate :permanent_attribute_name, :stream_name, to: :reflex
|
9
|
+
|
10
|
+
def initialize(reflex)
|
11
|
+
@reflex = reflex
|
12
|
+
@logger = Rails.logger
|
13
|
+
end
|
14
|
+
|
15
|
+
def nothing?
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
19
|
+
def page?
|
20
|
+
false
|
21
|
+
end
|
22
|
+
|
23
|
+
def selector?
|
24
|
+
false
|
25
|
+
end
|
26
|
+
|
27
|
+
def enqueue_message(subject:, body: nil, data: {})
|
28
|
+
logger.error "\e[31m#{body}\e[0m" if subject == "error"
|
29
|
+
cable_ready[stream_name].dispatch_event(
|
30
|
+
name: "stimulus-reflex:server-message",
|
31
|
+
detail: {
|
32
|
+
reflexId: data["reflexId"],
|
33
|
+
stimulus_reflex: data.merge(
|
34
|
+
broadcaster: to_sym,
|
35
|
+
server_message: {subject: subject, body: body}
|
36
|
+
)
|
37
|
+
}
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def broadcast_message(subject:, body: nil, data: {})
|
42
|
+
enqueue_message subject: subject, body: body, data: data
|
43
|
+
cable_ready.broadcast
|
44
|
+
end
|
45
|
+
|
46
|
+
# abstract method to be implemented by subclasses
|
47
|
+
def broadcast(*args)
|
48
|
+
raise NotImplementedError
|
49
|
+
end
|
50
|
+
|
51
|
+
# abstract method to be implemented by subclasses
|
52
|
+
def to_sym
|
53
|
+
raise NotImplementedError
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StimulusReflex
|
4
|
+
class NothingBroadcaster < Broadcaster
|
5
|
+
def broadcast(_, data)
|
6
|
+
broadcast_message subject: "nothing", data: data
|
7
|
+
end
|
8
|
+
|
9
|
+
def nothing?
|
10
|
+
true
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_sym
|
14
|
+
:nothing
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StimulusReflex
|
4
|
+
class PageBroadcaster < Broadcaster
|
5
|
+
def broadcast(selectors, data)
|
6
|
+
reflex.controller.process reflex.url_params[:action]
|
7
|
+
page_html = reflex.controller.response.body
|
8
|
+
|
9
|
+
return unless page_html.present?
|
10
|
+
|
11
|
+
document = Nokogiri::HTML(page_html)
|
12
|
+
selectors = selectors.select { |s| document.css(s).present? }
|
13
|
+
selectors.each do |selector|
|
14
|
+
html = document.css(selector).inner_html
|
15
|
+
cable_ready[stream_name].morph(
|
16
|
+
selector: selector,
|
17
|
+
html: html,
|
18
|
+
children_only: true,
|
19
|
+
permanent_attribute_name: permanent_attribute_name,
|
20
|
+
stimulus_reflex: data.merge({
|
21
|
+
broadast_type: to_sym
|
22
|
+
})
|
23
|
+
)
|
24
|
+
end
|
25
|
+
cable_ready.broadcast
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_sym
|
29
|
+
:page
|
30
|
+
end
|
31
|
+
|
32
|
+
def page?
|
33
|
+
true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module StimulusReflex
|
4
|
+
class SelectorBroadcaster < Broadcaster
|
5
|
+
def broadcast(_, data = {})
|
6
|
+
morphs.each do |morph|
|
7
|
+
selectors, html = morph
|
8
|
+
updates = selectors.is_a?(Hash) ? selectors : Hash[selectors, html]
|
9
|
+
updates.each do |selector, html|
|
10
|
+
html = html.to_s
|
11
|
+
fragment = Nokogiri::HTML.fragment(html)
|
12
|
+
match = fragment.at_css(selector)
|
13
|
+
if match.present?
|
14
|
+
cable_ready[stream_name].morph(
|
15
|
+
selector: selector,
|
16
|
+
html: match.inner_html,
|
17
|
+
children_only: true,
|
18
|
+
permanent_attribute_name: permanent_attribute_name,
|
19
|
+
stimulus_reflex: data.merge({
|
20
|
+
broadast_type: to_sym
|
21
|
+
})
|
22
|
+
)
|
23
|
+
else
|
24
|
+
cable_ready[stream_name].inner_html(
|
25
|
+
selector: selector,
|
26
|
+
html: fragment.to_html,
|
27
|
+
stimulus_reflex: data.merge({
|
28
|
+
broadast_type: to_sym
|
29
|
+
})
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
cable_ready.broadcast
|
36
|
+
morphs.clear
|
37
|
+
end
|
38
|
+
|
39
|
+
def morphs
|
40
|
+
@morphs ||= []
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_sym
|
44
|
+
:selector
|
45
|
+
end
|
46
|
+
|
47
|
+
def selector?
|
48
|
+
true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class StimulusReflex::Channel < ActionCable::Channel::Base
|
4
|
-
include CableReady::Broadcaster
|
5
|
-
|
6
4
|
def stream_name
|
7
5
|
ids = connection.identifiers.map { |identifier| send(identifier).try(:id) || send(identifier) }
|
8
6
|
[
|
@@ -21,32 +19,39 @@ class StimulusReflex::Channel < ActionCable::Channel::Base
|
|
21
19
|
selectors = data["selectors"] = ["body"] if selectors.blank?
|
22
20
|
target = data["target"].to_s
|
23
21
|
reflex_name, method_name = target.split("#")
|
24
|
-
reflex_name = reflex_name.
|
22
|
+
reflex_name = reflex_name.camelize
|
25
23
|
reflex_name = reflex_name.end_with?("Reflex") ? reflex_name : "#{reflex_name}Reflex"
|
26
24
|
arguments = (data["args"] || []).map { |arg| object_with_indifferent_access arg }
|
27
25
|
element = StimulusReflex::Element.new(data)
|
26
|
+
permanent_attribute_name = data["permanent_attribute_name"]
|
28
27
|
params = data["params"] || {}
|
29
28
|
|
30
29
|
begin
|
31
30
|
begin
|
32
31
|
reflex_class = reflex_name.constantize.tap { |klass| raise ArgumentError.new("#{reflex_name} is not a StimulusReflex::Reflex") unless is_reflex?(klass) }
|
33
|
-
reflex = reflex_class.new(self, url: url, element: element, selectors: selectors, method_name: method_name, params: params)
|
32
|
+
reflex = reflex_class.new(self, url: url, element: element, selectors: selectors, method_name: method_name, permanent_attribute_name: permanent_attribute_name, params: params)
|
34
33
|
delegate_call_to_reflex reflex, method_name, arguments
|
35
34
|
rescue => invoke_error
|
36
|
-
reflex.rescue_with_handler(invoke_error)
|
37
35
|
message = exception_message_with_backtrace(invoke_error)
|
38
|
-
|
36
|
+
body = "StimulusReflex::Channel Failed to invoke #{target}! #{url} #{message}"
|
37
|
+
if reflex
|
38
|
+
reflex.rescue_with_handler(invoke_error)
|
39
|
+
reflex.broadcast_message subject: "error", body: body, data: data
|
40
|
+
else
|
41
|
+
logger.error "\e[31m#{body}\e[0m"
|
42
|
+
end
|
43
|
+
return
|
39
44
|
end
|
40
45
|
|
41
46
|
if reflex.halted?
|
42
|
-
broadcast_message subject: "halted", data: data
|
47
|
+
reflex.broadcast_message subject: "halted", data: data
|
43
48
|
else
|
44
49
|
begin
|
45
|
-
|
50
|
+
reflex.broadcast(selectors, data)
|
46
51
|
rescue => render_error
|
47
52
|
reflex.rescue_with_handler(render_error)
|
48
53
|
message = exception_message_with_backtrace(render_error)
|
49
|
-
broadcast_message subject: "error", body: "StimulusReflex::Channel Failed to re-render #{url} #{message}", data: data
|
54
|
+
reflex.broadcast_message subject: "error", body: "StimulusReflex::Channel Failed to re-render #{url} #{message}", data: data
|
50
55
|
end
|
51
56
|
end
|
52
57
|
ensure
|
@@ -80,11 +85,6 @@ class StimulusReflex::Channel < ActionCable::Channel::Base
|
|
80
85
|
end
|
81
86
|
end
|
82
87
|
|
83
|
-
def render_page_and_broadcast_morph(reflex, selectors, data = {})
|
84
|
-
html = render_page(reflex)
|
85
|
-
broadcast_morphs selectors, data, html if html.present?
|
86
|
-
end
|
87
|
-
|
88
88
|
def commit_session(reflex)
|
89
89
|
store = reflex.request.session.instance_variable_get("@by")
|
90
90
|
store.commit_session reflex.request, reflex.controller.response
|
@@ -93,41 +93,6 @@ class StimulusReflex::Channel < ActionCable::Channel::Base
|
|
93
93
|
logger.error "\e[31m#{message}\e[0m"
|
94
94
|
end
|
95
95
|
|
96
|
-
def render_page(reflex)
|
97
|
-
reflex.controller.process reflex.url_params[:action]
|
98
|
-
reflex.controller.response.body
|
99
|
-
end
|
100
|
-
|
101
|
-
def broadcast_morphs(selectors, data, html)
|
102
|
-
document = Nokogiri::HTML(html)
|
103
|
-
selectors = selectors.select { |s| document.css(s).present? }
|
104
|
-
selectors.each do |selector|
|
105
|
-
cable_ready[stream_name].morph(
|
106
|
-
selector: selector,
|
107
|
-
html: document.css(selector).inner_html,
|
108
|
-
children_only: true,
|
109
|
-
permanent_attribute_name: data["permanent_attribute_name"],
|
110
|
-
stimulus_reflex: data.merge(last: selector == selectors.last)
|
111
|
-
)
|
112
|
-
end
|
113
|
-
cable_ready.broadcast
|
114
|
-
end
|
115
|
-
|
116
|
-
def broadcast_message(subject:, body: nil, data: {})
|
117
|
-
message = {
|
118
|
-
subject: subject,
|
119
|
-
body: body
|
120
|
-
}
|
121
|
-
|
122
|
-
logger.error "\e[31m#{body}\e[0m" if subject == "error"
|
123
|
-
|
124
|
-
cable_ready[stream_name].dispatch_event(
|
125
|
-
name: "stimulus-reflex:server-message",
|
126
|
-
detail: {stimulus_reflex: data.merge(server_message: message)}
|
127
|
-
)
|
128
|
-
cable_ready.broadcast
|
129
|
-
end
|
130
|
-
|
131
96
|
def exception_message_with_backtrace(exception)
|
132
97
|
"#{exception} #{exception.backtrace.first}"
|
133
98
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
class StimulusReflex::Reflex
|
4
4
|
include ActiveSupport::Rescuable
|
5
5
|
include ActiveSupport::Callbacks
|
6
|
+
include CableReady::Broadcaster
|
6
7
|
|
7
8
|
define_callbacks :process, skip_after_callbacks_if_terminated: true
|
8
9
|
|
@@ -42,18 +43,22 @@ class StimulusReflex::Reflex
|
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
45
|
-
attr_reader :channel, :url, :element, :selectors, :method_name
|
46
|
+
attr_reader :channel, :url, :element, :selectors, :method_name, :broadcaster, :permanent_attribute_name
|
46
47
|
|
47
|
-
delegate :connection, to: :channel
|
48
|
+
delegate :connection, :stream_name, to: :channel
|
48
49
|
delegate :session, to: :request
|
50
|
+
delegate :broadcast, :broadcast_message, to: :broadcaster
|
49
51
|
|
50
|
-
def initialize(channel, url: nil, element: nil, selectors: [], method_name: nil, params: {})
|
52
|
+
def initialize(channel, url: nil, element: nil, selectors: [], method_name: nil, permanent_attribute_name: nil, params: {})
|
51
53
|
@channel = channel
|
52
54
|
@url = url
|
53
55
|
@element = element
|
54
56
|
@selectors = selectors
|
55
57
|
@method_name = method_name
|
56
58
|
@params = params
|
59
|
+
@permanent_attribute_name = permanent_attribute_name
|
60
|
+
@broadcaster = StimulusReflex::PageBroadcaster.new(self)
|
61
|
+
self.params
|
57
62
|
end
|
58
63
|
|
59
64
|
def request
|
@@ -82,6 +87,20 @@ class StimulusReflex::Reflex
|
|
82
87
|
end
|
83
88
|
end
|
84
89
|
|
90
|
+
def morph(selectors, html = "")
|
91
|
+
case selectors
|
92
|
+
when :page
|
93
|
+
raise StandardError.new("Cannot call :page morph after :#{broadcaster.to_sym} morph") unless broadcaster.page?
|
94
|
+
when :nothing
|
95
|
+
raise StandardError.new("Cannot call :nothing morph after :selector morph") if broadcaster.selector?
|
96
|
+
@broadcaster = StimulusReflex::NothingBroadcaster.new(self) unless broadcaster.nothing?
|
97
|
+
else
|
98
|
+
raise StandardError.new("Cannot call :selector morph after :nothing morph") if broadcaster.nothing?
|
99
|
+
@broadcaster = StimulusReflex::SelectorBroadcaster.new(self) unless broadcaster.selector?
|
100
|
+
broadcaster.morphs << [selectors, html]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
85
104
|
def controller
|
86
105
|
@controller ||= begin
|
87
106
|
request.controller_class.new.tap do |c|
|
@@ -11,11 +11,16 @@ namespace :stimulus_reflex do
|
|
11
11
|
FileUtils.mkdir_p Rails.root.join("app/javascript/controllers"), verbose: true
|
12
12
|
FileUtils.mkdir_p Rails.root.join("app/reflexes"), verbose: true
|
13
13
|
|
14
|
-
filepath =
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
filepath = %w[
|
15
|
+
app/javascript/controllers/index.js
|
16
|
+
app/javascript/controllers/index.ts
|
17
|
+
app/javascript/packs/application.js
|
18
|
+
app/javascript/packs/application.ts
|
19
|
+
]
|
20
|
+
.select { |path| File.exist?(path) }
|
21
|
+
.map { |path| Rails.root.join(path) }
|
22
|
+
.first
|
23
|
+
|
19
24
|
puts "Updating #{filepath}"
|
20
25
|
lines = File.open(filepath, "r") { |f| f.readlines }
|
21
26
|
|
@@ -23,4 +23,27 @@ class StimulusReflexGeneratorTest < Rails::Generators::TestCase
|
|
23
23
|
assert_file "app/reflexes/application_reflex.rb"
|
24
24
|
assert_file "app/reflexes/posts_reflex.rb", /PostsReflex/
|
25
25
|
end
|
26
|
+
|
27
|
+
test "creates reflex with given reflex actions" do
|
28
|
+
run_generator %w[User update do_stuff DoMoreStuff]
|
29
|
+
assert_file "app/reflexes/user_reflex.rb" do |reflex|
|
30
|
+
assert_instance_method :update, reflex
|
31
|
+
assert_instance_method :do_stuff, reflex
|
32
|
+
assert_instance_method :do_more_stuff, reflex
|
33
|
+
end
|
34
|
+
assert_file "app/javascript/controllers/user_controller.js" do |controller|
|
35
|
+
assert_match(/beforeUpdate/, controller)
|
36
|
+
assert_match(/updateSuccess/, controller)
|
37
|
+
assert_match(/updateError/, controller)
|
38
|
+
assert_match(/afterUpdate/, controller)
|
39
|
+
assert_match(/beforeDoStuff/, controller)
|
40
|
+
assert_match(/doStuffSuccess/, controller)
|
41
|
+
assert_match(/doStuffError/, controller)
|
42
|
+
assert_match(/afterDoStuff/, controller)
|
43
|
+
assert_match(/beforeDoMoreStuff/, controller)
|
44
|
+
assert_match(/doMoreStuffSuccess/, controller)
|
45
|
+
assert_match(/doMoreStuffError/, controller)
|
46
|
+
assert_match(/afterDoMoreStuff/, controller)
|
47
|
+
end
|
48
|
+
end
|
26
49
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stimulus_reflex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.3.0.pre4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Hopkins
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 4.1.2
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: redis
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: bundler
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -157,22 +171,22 @@ files:
|
|
157
171
|
- bin/standardize
|
158
172
|
- lib/generators/USAGE
|
159
173
|
- lib/generators/stimulus_reflex_generator.rb
|
160
|
-
- lib/generators/templates/
|
161
|
-
- lib/generators/templates/
|
162
|
-
- lib/generators/templates/
|
163
|
-
- lib/generators/templates/
|
174
|
+
- lib/generators/templates/app/javascript/controllers/%file_name%_controller.js.tt
|
175
|
+
- lib/generators/templates/app/javascript/controllers/application_controller.js.tt
|
176
|
+
- lib/generators/templates/app/reflexes/%file_name%_reflex.rb.tt
|
177
|
+
- lib/generators/templates/app/reflexes/application_reflex.rb.tt
|
164
178
|
- lib/stimulus_reflex.rb
|
179
|
+
- lib/stimulus_reflex/broadcasters/broadcaster.rb
|
180
|
+
- lib/stimulus_reflex/broadcasters/nothing_broadcaster.rb
|
181
|
+
- lib/stimulus_reflex/broadcasters/page_broadcaster.rb
|
182
|
+
- lib/stimulus_reflex/broadcasters/selector_broadcaster.rb
|
165
183
|
- lib/stimulus_reflex/channel.rb
|
166
184
|
- lib/stimulus_reflex/element.rb
|
167
185
|
- lib/stimulus_reflex/reflex.rb
|
168
186
|
- lib/stimulus_reflex/version.rb
|
169
187
|
- lib/tasks/stimulus_reflex/install.rake
|
170
|
-
- stimulus_reflex.gemspec
|
171
|
-
- tags
|
172
188
|
- test/generators/stimulus_reflex_generator_test.rb
|
173
189
|
- test/test_helper.rb
|
174
|
-
- test/tmp/app/reflexes/application_reflex.rb
|
175
|
-
- test/tmp/app/reflexes/posts_reflex.rb
|
176
190
|
homepage: https://github.com/hopsoft/stimulus_reflex
|
177
191
|
licenses:
|
178
192
|
- MIT
|
@@ -197,16 +211,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
197
211
|
version: '0'
|
198
212
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
199
213
|
requirements:
|
200
|
-
- - "
|
214
|
+
- - ">"
|
201
215
|
- !ruby/object:Gem::Version
|
202
|
-
version:
|
216
|
+
version: 1.3.1
|
203
217
|
requirements: []
|
204
|
-
rubygems_version: 3.0.
|
218
|
+
rubygems_version: 3.0.6
|
205
219
|
signing_key:
|
206
220
|
specification_version: 4
|
207
221
|
summary: Build reactive applications with the Rails tooling you already know and love.
|
208
222
|
test_files:
|
209
|
-
- test/test_helper.rb
|
210
223
|
- test/generators/stimulus_reflex_generator_test.rb
|
211
|
-
- test/
|
212
|
-
- test/tmp/app/reflexes/posts_reflex.rb
|
224
|
+
- test/test_helper.rb
|
data/stimulus_reflex.gemspec
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
require File.expand_path("../lib/stimulus_reflex/version", __FILE__)
|
2
|
-
|
3
|
-
Gem::Specification.new do |gem|
|
4
|
-
gem.name = "stimulus_reflex"
|
5
|
-
gem.license = "MIT"
|
6
|
-
gem.version = StimulusReflex::VERSION
|
7
|
-
gem.authors = ["Nathan Hopkins"]
|
8
|
-
gem.email = ["natehop@gmail.com"]
|
9
|
-
gem.homepage = "https://github.com/hopsoft/stimulus_reflex"
|
10
|
-
gem.summary = "Build reactive applications with the Rails tooling you already know and love."
|
11
|
-
gem.post_install_message = <<~MESSAGE
|
12
|
-
Friendly reminder: When updating the stimulus_reflex gem,
|
13
|
-
don't forget to update your npm package as well.
|
14
|
-
|
15
|
-
See https://www.npmjs.com/package/stimulus_reflex
|
16
|
-
MESSAGE
|
17
|
-
|
18
|
-
gem.metadata = {
|
19
|
-
"bug_tracker_uri" => "https://github.com/hopsoft/stimulus_reflex/issues",
|
20
|
-
"changelog_uri" => "https://github.com/hopsoft/stimulus_reflex/CHANGELOG.md",
|
21
|
-
"documentation_uri" => "https://docs.stimulusreflex.com",
|
22
|
-
"homepage_uri" => gem.homepage,
|
23
|
-
"source_code_uri" => gem.homepage
|
24
|
-
}
|
25
|
-
|
26
|
-
gem.files = Dir["lib/**/*", "bin/*", "[A-Z]*"]
|
27
|
-
gem.test_files = Dir["test/**/*.rb"]
|
28
|
-
|
29
|
-
gem.add_dependency "rack"
|
30
|
-
gem.add_dependency "nokogiri"
|
31
|
-
gem.add_dependency "rails", ">= 5.2"
|
32
|
-
gem.add_dependency "cable_ready", ">= 4.1.2"
|
33
|
-
|
34
|
-
gem.add_development_dependency "bundler", "~> 2.0"
|
35
|
-
gem.add_development_dependency "pry-nav"
|
36
|
-
gem.add_development_dependency "pry"
|
37
|
-
gem.add_development_dependency "rake"
|
38
|
-
gem.add_development_dependency "standardrb"
|
39
|
-
end
|
data/tags
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
|
2
|
-
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
|
3
|
-
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
|
4
|
-
!_TAG_PROGRAM_NAME Exuberant Ctags //
|
5
|
-
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
|
6
|
-
!_TAG_PROGRAM_VERSION 5.8 //
|
7
|
-
ApplicationReflex lib/generators/templates/application_reflex.rb /^class ApplicationReflex < StimulusReflex::Reflex$/;" c
|
8
|
-
ApplicationReflex test/tmp/app/reflexes/application_reflex.rb /^class ApplicationReflex < StimulusReflex::Reflex$/;" c
|
9
|
-
DemoReflex test/tmp/app/reflexes/demo_reflex.rb /^class DemoReflex < ApplicationReflex$/;" c
|
10
|
-
Engine lib/stimulus_reflex.rb /^ class Engine < Rails::Engine$/;" c class:StimulusReflex
|
11
|
-
StimulusReflex lib/stimulus_reflex.rb /^module StimulusReflex$/;" m
|
12
|
-
StimulusReflex lib/stimulus_reflex/channel.rb /^class StimulusReflex::Channel < ActionCable::Channel::Base$/;" c
|
13
|
-
StimulusReflex lib/stimulus_reflex/element.rb /^class StimulusReflex::Element$/;" c
|
14
|
-
StimulusReflex lib/stimulus_reflex/reflex.rb /^class StimulusReflex::Reflex$/;" c
|
15
|
-
StimulusReflex lib/stimulus_reflex/version.rb /^module StimulusReflex$/;" m
|
16
|
-
StimulusReflexGenerator lib/generators/stimulus_reflex_generator.rb /^class StimulusReflexGenerator < Rails::Generators::NamedBase$/;" c
|
17
|
-
StimulusReflexGeneratorTest test/generators/stimulus_reflex_generator_test.rb /^class StimulusReflexGeneratorTest < Rails::Generators::TestCase$/;" c
|
18
|
-
broadcast_error lib/stimulus_reflex/channel.rb /^ def broadcast_error(message, data = {})$/;" f class:StimulusReflex
|
19
|
-
broadcast_morphs lib/stimulus_reflex/channel.rb /^ def broadcast_morphs(selectors, data, html)$/;" f class:StimulusReflex
|
20
|
-
build_request lib/stimulus_reflex/channel.rb /^ def build_request$/;" f class:StimulusReflex
|
21
|
-
commit_session lib/stimulus_reflex/channel.rb /^ def commit_session(request, response)$/;" f class:StimulusReflex
|
22
|
-
copy_controller_files lib/generators/stimulus_reflex_generator.rb /^ def copy_controller_files$/;" f class:StimulusReflexGenerator
|
23
|
-
copy_reflex_files lib/generators/stimulus_reflex_generator.rb /^ def copy_reflex_files$/;" f class:StimulusReflexGenerator
|
24
|
-
dataset lib/stimulus_reflex/element.rb /^ def dataset$/;" f class:StimulusReflex
|
25
|
-
delegate_call_to_reflex lib/stimulus_reflex/channel.rb /^ def delegate_call_to_reflex(reflex, method_name, arguments = [])$/;" f class:StimulusReflex
|
26
|
-
exception_message_with_backtrace lib/stimulus_reflex/channel.rb /^ def exception_message_with_backtrace(exception)$/;" f class:StimulusReflex
|
27
|
-
export.reflexAttribute javascript/schema.js /^ reflexAttribute: 'data-reflex',$/;" p
|
28
|
-
export.reflexPermanentAttribute javascript/schema.js /^ reflexPermanentAttribute: 'data-reflex-permanent',$/;" p
|
29
|
-
export.reflexRootAttribute javascript/schema.js /^ reflexRootAttribute: 'data-reflex-root'$/;" p
|
30
|
-
findConsumer javascript/consumer.js /^function findConsumer (object, depth = 0) {$/;" f
|
31
|
-
initialize lib/stimulus_reflex/element.rb /^ def initialize(attrs = {})$/;" f class:StimulusReflex
|
32
|
-
initialize lib/stimulus_reflex/reflex.rb /^ def initialize(channel, url: nil, element: nil, selectors: [])$/;" f class:StimulusReflex
|
33
|
-
initialize_controllers lib/generators/stimulus_reflex_generator.rb /^ def initialize_controllers$/;" f class:StimulusReflexGenerator
|
34
|
-
initialize_reflexes lib/generators/stimulus_reflex_generator.rb /^ def initialize_reflexes$/;" f class:StimulusReflexGenerator
|
35
|
-
is_reflex? lib/stimulus_reflex/channel.rb /^ def is_reflex?(reflex_class)$/;" f class:StimulusReflex
|
36
|
-
receive lib/stimulus_reflex/channel.rb /^ def receive(data)$/;" f class:StimulusReflex
|
37
|
-
render_page lib/stimulus_reflex/channel.rb /^ def render_page(reflex)$/;" f class:StimulusReflex
|
38
|
-
render_page_and_broadcast_morph lib/stimulus_reflex/channel.rb /^ def render_page_and_broadcast_morph(reflex, selectors, data = {})$/;" f class:StimulusReflex
|
39
|
-
request lib/stimulus_reflex/reflex.rb /^ def request$/;" f class:StimulusReflex
|
40
|
-
stream_name lib/stimulus_reflex/channel.rb /^ def stream_name$/;" f class:StimulusReflex
|
41
|
-
subscribed lib/stimulus_reflex/channel.rb /^ def subscribed$/;" f class:StimulusReflex
|
42
|
-
url_params lib/stimulus_reflex/reflex.rb /^ def url_params$/;" f class:StimulusReflex
|
@@ -1,12 +0,0 @@
|
|
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: :connection
|
10
|
-
#
|
11
|
-
# Learn more at: https://docs.stimulusreflex.com
|
12
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class PostsReflex < 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
|
-
# - params - parameters from the element's closest form (if any)
|
15
|
-
#
|
16
|
-
# Example:
|
17
|
-
#
|
18
|
-
# def example(argument=true)
|
19
|
-
# # Your logic here...
|
20
|
-
# # Any declared instance variables will be made available to the Rails controller and view.
|
21
|
-
# end
|
22
|
-
#
|
23
|
-
# Learn more at: https://docs.stimulusreflex.com
|
24
|
-
end
|