stimulus_reflex 3.2.1 → 3.3.0.pre0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +122 -1
- data/Gemfile.lock +76 -73
- data/README.md +1 -1
- 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} +7 -0
- data/lib/generators/templates/{application_reflex.rb → app/reflexes/application_reflex.rb.tt} +0 -0
- data/lib/stimulus_reflex.rb +5 -0
- data/lib/stimulus_reflex/broadcaster.rb +53 -0
- data/lib/stimulus_reflex/channel.rb +40 -66
- data/lib/stimulus_reflex/element.rb +9 -10
- data/lib/stimulus_reflex/morph_mode.rb +19 -0
- data/lib/stimulus_reflex/morph_mode/nothing_morph_mode.rb +15 -0
- data/lib/stimulus_reflex/morph_mode/page_morph_mode.rb +15 -0
- data/lib/stimulus_reflex/morph_mode/selector_morph_mode.rb +15 -0
- data/lib/stimulus_reflex/reflex.rb +53 -2
- data/lib/stimulus_reflex/version.rb +1 -1
- data/lib/tasks/stimulus_reflex/install.rake +10 -5
- data/stimulus_reflex.gemspec +1 -1
- data/test/generators/stimulus_reflex_generator_test.rb +23 -0
- data/test/tmp/app/reflexes/demo_reflex.rb +2 -0
- metadata +18 -13
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 541ecc905c542c182d7abd3989aee4e0b7e2cbcc0708a741d292af0447f657b7
|
|
4
|
+
data.tar.gz: 47b2665deb288d4f63e99ab3a72256f7f39c095f57cc3c71444038f91ebdc170
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e63680e0a55bfff333385be622ab7bca8850846896befc9269b5d806a8baea6906cd0b29df90f65d586b6ad50f057575d8bce1b8fc3cf09c4a877c7692324209
|
|
7
|
+
data.tar.gz: 0e748c92fef73ad6038c334348eaf38e40e11dcad3edfab69c4e5f6bef6286d594d100357af95a69cbcaf69a04ee31ad579e562d7389f651a2e56af26eb114c2
|
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.2.
|
|
5
|
+
[Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.2.3...HEAD)
|
|
6
|
+
|
|
7
|
+
**Implemented enhancements:**
|
|
8
|
+
|
|
9
|
+
- Returns more helpful error message if Reflex doesn't exist [\#254](https://github.com/hopsoft/stimulus_reflex/pull/254) ([leastbad](https://github.com/leastbad))
|
|
10
|
+
- Update install.rake to handle Typescript [\#241](https://github.com/hopsoft/stimulus_reflex/pull/241) ([iv-mexx](https://github.com/iv-mexx))
|
|
11
|
+
- Morph Modes: page, selector and nothing [\#211](https://github.com/hopsoft/stimulus_reflex/pull/211) ([leastbad](https://github.com/leastbad))
|
|
12
|
+
|
|
13
|
+
**Fixed bugs:**
|
|
14
|
+
|
|
15
|
+
- Limit MutationObserver mutations [\#256](https://github.com/hopsoft/stimulus_reflex/pull/256) ([jasoncharnes](https://github.com/jasoncharnes))
|
|
16
|
+
|
|
17
|
+
**Closed issues:**
|
|
18
|
+
|
|
19
|
+
- beforeUpdate/updateSuccess/updateError functions deprecated? [\#255](https://github.com/hopsoft/stimulus_reflex/issues/255)
|
|
20
|
+
- Error handling will fail if reflex is not defined [\#253](https://github.com/hopsoft/stimulus_reflex/issues/253)
|
|
21
|
+
- Select with data-reflex in Firefox flickers [\#251](https://github.com/hopsoft/stimulus_reflex/issues/251)
|
|
22
|
+
- data-reflex-attributes vs data-reflex-dataset [\#237](https://github.com/hopsoft/stimulus_reflex/issues/237)
|
|
23
|
+
- Shorthand action notations corresponding to stimulus [\#233](https://github.com/hopsoft/stimulus_reflex/issues/233)
|
|
24
|
+
- Lifecycle methods only called for one reflex [\#225](https://github.com/hopsoft/stimulus_reflex/issues/225)
|
|
25
|
+
- Tweak the generator so we can specify reflex actions [\#219](https://github.com/hopsoft/stimulus_reflex/issues/219)
|
|
26
|
+
- Docs: Clarify forcing DOM update with authentication [\#123](https://github.com/hopsoft/stimulus_reflex/issues/123)
|
|
27
|
+
- ActiveJob integration example [\#112](https://github.com/hopsoft/stimulus_reflex/issues/112)
|
|
28
|
+
|
|
29
|
+
**Merged pull requests:**
|
|
30
|
+
|
|
31
|
+
- Prep for pre release of 3.3.0 [\#259](https://github.com/hopsoft/stimulus_reflex/pull/259) ([hopsoft](https://github.com/hopsoft))
|
|
32
|
+
- Fallback to first Stimulus controller in array [\#257](https://github.com/hopsoft/stimulus_reflex/pull/257) ([jasoncharnes](https://github.com/jasoncharnes))
|
|
33
|
+
- Fix cases where plural reflexes were unresolved [\#252](https://github.com/hopsoft/stimulus_reflex/pull/252) ([joshleblanc](https://github.com/joshleblanc))
|
|
34
|
+
- warn against collections of identical elements that trigger reflexes [\#250](https://github.com/hopsoft/stimulus_reflex/pull/250) ([leastbad](https://github.com/leastbad))
|
|
35
|
+
- always calls params to persist them into controller action [\#249](https://github.com/hopsoft/stimulus_reflex/pull/249) ([RolandStuder](https://github.com/RolandStuder))
|
|
36
|
+
- Update deployment.md [\#248](https://github.com/hopsoft/stimulus_reflex/pull/248) ([user073](https://github.com/user073))
|
|
37
|
+
- Update reflexes.md [\#247](https://github.com/hopsoft/stimulus_reflex/pull/247) ([user073](https://github.com/user073))
|
|
38
|
+
- 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))
|
|
39
|
+
- 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))
|
|
40
|
+
- 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))
|
|
41
|
+
- 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))
|
|
42
|
+
- 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))
|
|
43
|
+
- adds params documentation [\#230](https://github.com/hopsoft/stimulus_reflex/pull/230) ([RolandStuder](https://github.com/RolandStuder))
|
|
44
|
+
- Fix calling wrong controller lifecycle methods [\#226](https://github.com/hopsoft/stimulus_reflex/pull/226) ([davidalejandroaguilar](https://github.com/davidalejandroaguilar))
|
|
45
|
+
- Allow to pass reflex action names to reflex generator [\#224](https://github.com/hopsoft/stimulus_reflex/pull/224) ([marcoroth](https://github.com/marcoroth))
|
|
46
|
+
|
|
47
|
+
## [v3.2.3](https://github.com/hopsoft/stimulus_reflex/tree/v3.2.3) (2020-06-15)
|
|
48
|
+
|
|
49
|
+
[Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.2.2...v3.2.3)
|
|
50
|
+
|
|
51
|
+
**Fixed bugs:**
|
|
52
|
+
|
|
53
|
+
- Add more smarts to \_\_perform [\#235](https://github.com/hopsoft/stimulus_reflex/pull/235) ([hopsoft](https://github.com/hopsoft))
|
|
54
|
+
- \_\_perform had a bug where it was only ever calling the first event [\#234](https://github.com/hopsoft/stimulus_reflex/pull/234) ([leastbad](https://github.com/leastbad))
|
|
55
|
+
- merges insteads of overwrites params for reflex actions with form data [\#231](https://github.com/hopsoft/stimulus_reflex/pull/231) ([RolandStuder](https://github.com/RolandStuder))
|
|
56
|
+
|
|
57
|
+
**Closed issues:**
|
|
58
|
+
|
|
59
|
+
- "Uncaught \(in promise\)" error after failed declarative reflex [\#170](https://github.com/hopsoft/stimulus_reflex/issues/170)
|
|
60
|
+
|
|
61
|
+
**Merged pull requests:**
|
|
62
|
+
|
|
63
|
+
- Fix typos in the documentation [\#228](https://github.com/hopsoft/stimulus_reflex/pull/228) ([dlt](https://github.com/dlt))
|
|
64
|
+
|
|
65
|
+
## [v3.2.2](https://github.com/hopsoft/stimulus_reflex/tree/v3.2.2) (2020-06-06)
|
|
66
|
+
|
|
67
|
+
[Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.2.2.pre1...v3.2.2)
|
|
68
|
+
|
|
69
|
+
**Closed issues:**
|
|
70
|
+
|
|
71
|
+
- Issue with doing a partial dom update [\#223](https://github.com/hopsoft/stimulus_reflex/issues/223)
|
|
72
|
+
|
|
73
|
+
## [v3.2.2.pre1](https://github.com/hopsoft/stimulus_reflex/tree/v3.2.2.pre1) (2020-05-30)
|
|
74
|
+
|
|
75
|
+
[Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.2.2.pre0...v3.2.2.pre1)
|
|
76
|
+
|
|
77
|
+
**Fixed bugs:**
|
|
78
|
+
|
|
79
|
+
- Session lost after throw :abort [\#221](https://github.com/hopsoft/stimulus_reflex/issues/221)
|
|
80
|
+
- Fix multipleInstances convenience method [\#220](https://github.com/hopsoft/stimulus_reflex/pull/220) ([julianrubisch](https://github.com/julianrubisch))
|
|
81
|
+
|
|
82
|
+
**Merged pull requests:**
|
|
83
|
+
|
|
84
|
+
- Always commit session [\#222](https://github.com/hopsoft/stimulus_reflex/pull/222) ([hopsoft](https://github.com/hopsoft))
|
|
85
|
+
|
|
86
|
+
## [v3.2.2.pre0](https://github.com/hopsoft/stimulus_reflex/tree/v3.2.2.pre0) (2020-05-27)
|
|
87
|
+
|
|
88
|
+
[Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.2.1...v3.2.2.pre0)
|
|
89
|
+
|
|
90
|
+
**Implemented enhancements:**
|
|
91
|
+
|
|
92
|
+
- Add a halted lifecycle event [\#190](https://github.com/hopsoft/stimulus_reflex/issues/190)
|
|
93
|
+
- Allow extractElementAttributes to use a checkbox list [\#147](https://github.com/hopsoft/stimulus_reflex/issues/147)
|
|
94
|
+
- reflex\_name restriction loosening [\#212](https://github.com/hopsoft/stimulus_reflex/pull/212) ([leastbad](https://github.com/leastbad))
|
|
95
|
+
- Make element even more user friendly [\#210](https://github.com/hopsoft/stimulus_reflex/pull/210) ([hopsoft](https://github.com/hopsoft))
|
|
96
|
+
- Form parameters [\#204](https://github.com/hopsoft/stimulus_reflex/pull/204) ([jasoncharnes](https://github.com/jasoncharnes))
|
|
97
|
+
- Map hashes in incoming arguments using with\_indifferent\_access [\#203](https://github.com/hopsoft/stimulus_reflex/pull/203) ([jaredcwhite](https://github.com/jaredcwhite))
|
|
98
|
+
- Combine dataset with data-attributes from parent elements on reflex call [\#200](https://github.com/hopsoft/stimulus_reflex/pull/200) ([marcoroth](https://github.com/marcoroth))
|
|
99
|
+
- Setup mutation aware declarative reflexes [\#197](https://github.com/hopsoft/stimulus_reflex/pull/197) ([hopsoft](https://github.com/hopsoft))
|
|
100
|
+
|
|
101
|
+
**Fixed bugs:**
|
|
102
|
+
|
|
103
|
+
- Text area values are lost if re-sized [\#195](https://github.com/hopsoft/stimulus_reflex/issues/195)
|
|
104
|
+
|
|
105
|
+
**Closed issues:**
|
|
106
|
+
|
|
107
|
+
- Accessing dataset as before is returning nil [\#218](https://github.com/hopsoft/stimulus_reflex/issues/218)
|
|
108
|
+
- Spurious console error using data-reflex-root and CSS attribute selector [\#207](https://github.com/hopsoft/stimulus_reflex/issues/207)
|
|
109
|
+
- ActionController Parameters [\#199](https://github.com/hopsoft/stimulus_reflex/issues/199)
|
|
110
|
+
|
|
111
|
+
**Merged pull requests:**
|
|
112
|
+
|
|
113
|
+
- Bump activesupport from 6.0.3 to 6.0.3.1 [\#217](https://github.com/hopsoft/stimulus_reflex/pull/217) ([dependabot[bot]](https://github.com/apps/dependabot))
|
|
114
|
+
- Bump activestorage from 6.0.3 to 6.0.3.1 [\#216](https://github.com/hopsoft/stimulus_reflex/pull/216) ([dependabot[bot]](https://github.com/apps/dependabot))
|
|
115
|
+
- Bump actionpack from 6.0.3 to 6.0.3.1 [\#215](https://github.com/hopsoft/stimulus_reflex/pull/215) ([dependabot[bot]](https://github.com/apps/dependabot))
|
|
116
|
+
- Update dataset handling and some minor refactoring to better naming [\#214](https://github.com/hopsoft/stimulus_reflex/pull/214) ([hopsoft](https://github.com/hopsoft))
|
|
117
|
+
- Stimulus reflexData assignment after callback [\#208](https://github.com/hopsoft/stimulus_reflex/pull/208) ([jasoncharnes](https://github.com/jasoncharnes))
|
|
118
|
+
- Loosen Rails requirement to 5.2 with instructions [\#205](https://github.com/hopsoft/stimulus_reflex/pull/205) ([jasoncharnes](https://github.com/jasoncharnes))
|
|
119
|
+
- Fix undefined is not an object for Object.keys in log.js [\#201](https://github.com/hopsoft/stimulus_reflex/pull/201) ([marcoroth](https://github.com/marcoroth))
|
|
120
|
+
- Small typo/grammar fix in quickstart doc. [\#198](https://github.com/hopsoft/stimulus_reflex/pull/198) ([acoffman](https://github.com/acoffman))
|
|
121
|
+
- Add halted lifecycle event [\#193](https://github.com/hopsoft/stimulus_reflex/pull/193) ([seb1441](https://github.com/seb1441))
|
|
122
|
+
- 147 extract multiple checkbox values [\#175](https://github.com/hopsoft/stimulus_reflex/pull/175) ([julianrubisch](https://github.com/julianrubisch))
|
|
123
|
+
|
|
124
|
+
## [v3.2.1](https://github.com/hopsoft/stimulus_reflex/tree/v3.2.1) (2020-05-09)
|
|
125
|
+
|
|
126
|
+
[Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.2.0...v3.2.1)
|
|
6
127
|
|
|
7
128
|
**Merged pull requests:**
|
|
8
129
|
|
data/Gemfile.lock
CHANGED
|
@@ -1,84 +1,83 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
stimulus_reflex (3.
|
|
4
|
+
stimulus_reflex (3.3.0.pre0)
|
|
5
5
|
cable_ready (>= 4.1.2)
|
|
6
6
|
nokogiri
|
|
7
7
|
rack
|
|
8
|
-
rails (>=
|
|
8
|
+
rails (>= 5.2)
|
|
9
9
|
|
|
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)
|
|
66
66
|
tzinfo (~> 1.1)
|
|
67
67
|
zeitwerk (~> 2.2, >= 2.2.2)
|
|
68
|
-
ast (2.4.
|
|
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
|
-
coderay (1.1.
|
|
72
|
+
coderay (1.1.3)
|
|
73
73
|
concurrent-ruby (1.1.6)
|
|
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.3)
|
|
79
79
|
concurrent-ruby (~> 1.0)
|
|
80
|
-
|
|
81
|
-
loofah (2.5.0)
|
|
80
|
+
loofah (2.6.0)
|
|
82
81
|
crass (~> 1.0.2)
|
|
83
82
|
nokogiri (>= 1.5.9)
|
|
84
83
|
mail (2.7.1)
|
|
@@ -89,71 +88,75 @@ GEM
|
|
|
89
88
|
mimemagic (0.3.5)
|
|
90
89
|
mini_mime (1.0.2)
|
|
91
90
|
mini_portile2 (2.4.0)
|
|
92
|
-
minitest (5.14.
|
|
91
|
+
minitest (5.14.1)
|
|
93
92
|
nio4r (2.5.2)
|
|
94
93
|
nokogiri (1.10.9)
|
|
95
94
|
mini_portile2 (~> 2.4.0)
|
|
96
|
-
parallel (1.19.
|
|
97
|
-
parser (2.7.1.
|
|
98
|
-
ast (~> 2.4.
|
|
95
|
+
parallel (1.19.2)
|
|
96
|
+
parser (2.7.1.4)
|
|
97
|
+
ast (~> 2.4.1)
|
|
99
98
|
pry (0.12.2)
|
|
100
99
|
coderay (~> 1.1.0)
|
|
101
100
|
method_source (~> 0.9.0)
|
|
102
101
|
pry-nav (0.3.0)
|
|
103
102
|
pry (>= 0.9.10, < 0.13.0)
|
|
104
|
-
rack (2.2.
|
|
103
|
+
rack (2.2.3)
|
|
105
104
|
rack-test (1.1.0)
|
|
106
105
|
rack (>= 1.0, < 3)
|
|
107
|
-
rails (6.0.3)
|
|
108
|
-
actioncable (= 6.0.3)
|
|
109
|
-
actionmailbox (= 6.0.3)
|
|
110
|
-
actionmailer (= 6.0.3)
|
|
111
|
-
actionpack (= 6.0.3)
|
|
112
|
-
actiontext (= 6.0.3)
|
|
113
|
-
actionview (= 6.0.3)
|
|
114
|
-
activejob (= 6.0.3)
|
|
115
|
-
activemodel (= 6.0.3)
|
|
116
|
-
activerecord (= 6.0.3)
|
|
117
|
-
activestorage (= 6.0.3)
|
|
118
|
-
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)
|
|
119
118
|
bundler (>= 1.3.0)
|
|
120
|
-
railties (= 6.0.3)
|
|
119
|
+
railties (= 6.0.3.2)
|
|
121
120
|
sprockets-rails (>= 2.0.0)
|
|
122
121
|
rails-dom-testing (2.0.3)
|
|
123
122
|
activesupport (>= 4.2.0)
|
|
124
123
|
nokogiri (>= 1.6)
|
|
125
124
|
rails-html-sanitizer (1.3.0)
|
|
126
125
|
loofah (~> 2.3)
|
|
127
|
-
railties (6.0.3)
|
|
128
|
-
actionpack (= 6.0.3)
|
|
129
|
-
activesupport (= 6.0.3)
|
|
126
|
+
railties (6.0.3.2)
|
|
127
|
+
actionpack (= 6.0.3.2)
|
|
128
|
+
activesupport (= 6.0.3.2)
|
|
130
129
|
method_source
|
|
131
130
|
rake (>= 0.8.7)
|
|
132
131
|
thor (>= 0.20.3, < 2.0)
|
|
133
132
|
rainbow (3.0.0)
|
|
134
133
|
rake (13.0.1)
|
|
134
|
+
regexp_parser (1.7.1)
|
|
135
135
|
rexml (3.2.4)
|
|
136
|
-
rubocop (0.
|
|
137
|
-
jaro_winkler (~> 1.5.1)
|
|
136
|
+
rubocop (0.85.1)
|
|
138
137
|
parallel (~> 1.10)
|
|
139
138
|
parser (>= 2.7.0.1)
|
|
140
139
|
rainbow (>= 2.2.2, < 4.0)
|
|
140
|
+
regexp_parser (>= 1.7)
|
|
141
141
|
rexml
|
|
142
|
+
rubocop-ast (>= 0.0.3)
|
|
142
143
|
ruby-progressbar (~> 1.7)
|
|
143
144
|
unicode-display_width (>= 1.4.0, < 2.0)
|
|
144
|
-
rubocop-
|
|
145
|
+
rubocop-ast (0.1.0)
|
|
146
|
+
parser (>= 2.7.0.1)
|
|
147
|
+
rubocop-performance (1.6.1)
|
|
145
148
|
rubocop (>= 0.71.0)
|
|
146
149
|
ruby-progressbar (1.10.1)
|
|
147
|
-
sprockets (4.0.
|
|
150
|
+
sprockets (4.0.2)
|
|
148
151
|
concurrent-ruby (~> 1.0)
|
|
149
152
|
rack (> 1, < 3)
|
|
150
153
|
sprockets-rails (3.2.1)
|
|
151
154
|
actionpack (>= 4.0)
|
|
152
155
|
activesupport (>= 4.0)
|
|
153
156
|
sprockets (>= 3.0.0)
|
|
154
|
-
standard (0.4.
|
|
155
|
-
rubocop (~> 0.
|
|
156
|
-
rubocop-performance (~> 1.
|
|
157
|
+
standard (0.4.7)
|
|
158
|
+
rubocop (~> 0.85.0)
|
|
159
|
+
rubocop-performance (~> 1.6.0)
|
|
157
160
|
standardrb (1.0.0)
|
|
158
161
|
standard
|
|
159
162
|
thor (1.0.1)
|
|
@@ -161,10 +164,10 @@ GEM
|
|
|
161
164
|
tzinfo (1.2.7)
|
|
162
165
|
thread_safe (~> 0.1)
|
|
163
166
|
unicode-display_width (1.7.0)
|
|
164
|
-
websocket-driver (0.7.
|
|
167
|
+
websocket-driver (0.7.2)
|
|
165
168
|
websocket-extensions (>= 0.1.0)
|
|
166
|
-
websocket-extensions (0.1.
|
|
167
|
-
zeitwerk (2.3.
|
|
169
|
+
websocket-extensions (0.1.5)
|
|
170
|
+
zeitwerk (2.3.1)
|
|
168
171
|
|
|
169
172
|
PLATFORMS
|
|
170
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-932-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" />
|
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
|
|
@@ -11,6 +11,7 @@ class <%= class_name %>Reflex < ApplicationReflex
|
|
|
11
11
|
# - session - the ActionDispatch::Session store for the current visitor
|
|
12
12
|
# - url - the URL of the page that triggered the reflex
|
|
13
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)
|
|
14
15
|
#
|
|
15
16
|
# Example:
|
|
16
17
|
#
|
|
@@ -20,4 +21,10 @@ class <%= class_name %>Reflex < ApplicationReflex
|
|
|
20
21
|
# end
|
|
21
22
|
#
|
|
22
23
|
# Learn more at: https://docs.stimulusreflex.com
|
|
24
|
+
|
|
25
|
+
<% actions.each do |action| -%>
|
|
26
|
+
def <%= action %>
|
|
27
|
+
end
|
|
28
|
+
<%= "\n" unless action == actions.last -%>
|
|
29
|
+
<% end -%>
|
|
23
30
|
end
|
data/lib/generators/templates/{application_reflex.rb → app/reflexes/application_reflex.rb.tt}
RENAMED
|
File without changes
|
data/lib/stimulus_reflex.rb
CHANGED
|
@@ -11,7 +11,12 @@ require "cable_ready"
|
|
|
11
11
|
require "stimulus_reflex/version"
|
|
12
12
|
require "stimulus_reflex/reflex"
|
|
13
13
|
require "stimulus_reflex/element"
|
|
14
|
+
require "stimulus_reflex/broadcaster"
|
|
15
|
+
require "stimulus_reflex/morph_mode"
|
|
14
16
|
require "stimulus_reflex/channel"
|
|
17
|
+
require "stimulus_reflex/morph_mode/nothing_morph_mode"
|
|
18
|
+
require "stimulus_reflex/morph_mode/page_morph_mode"
|
|
19
|
+
require "stimulus_reflex/morph_mode/selector_morph_mode"
|
|
15
20
|
require "generators/stimulus_reflex_generator"
|
|
16
21
|
|
|
17
22
|
module StimulusReflex
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module StimulusReflex
|
|
2
|
+
module Broadcaster
|
|
3
|
+
include CableReady::Broadcaster
|
|
4
|
+
|
|
5
|
+
def render_page_and_broadcast_morph(reflex, selectors, data = {})
|
|
6
|
+
html = render_page(reflex)
|
|
7
|
+
broadcast_morphs selectors, data, html if html.present?
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def render_page(reflex)
|
|
11
|
+
reflex.controller.process reflex.url_params[:action]
|
|
12
|
+
reflex.controller.response.body
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def broadcast_morphs(selectors, data, html)
|
|
16
|
+
document = Nokogiri::HTML(html)
|
|
17
|
+
selectors = selectors.select { |s| document.css(s).present? }
|
|
18
|
+
selectors.each do |selector|
|
|
19
|
+
cable_ready[stream_name].morph(
|
|
20
|
+
selector: selector,
|
|
21
|
+
html: document.css(selector).inner_html,
|
|
22
|
+
children_only: true,
|
|
23
|
+
permanent_attribute_name: data["permanent_attribute_name"],
|
|
24
|
+
stimulus_reflex: data.merge({
|
|
25
|
+
last: selector == selectors.last,
|
|
26
|
+
morph_mode: "page"
|
|
27
|
+
})
|
|
28
|
+
)
|
|
29
|
+
end
|
|
30
|
+
cable_ready.broadcast
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def broadcast_message(subject:, body: nil, data: {})
|
|
34
|
+
message = {
|
|
35
|
+
subject: subject,
|
|
36
|
+
body: body
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
logger.error "\e[31m#{body}\e[0m" if subject == "error"
|
|
40
|
+
|
|
41
|
+
data[:morph_mode] = "page"
|
|
42
|
+
data[:server_message] = message
|
|
43
|
+
data[:morph_mode] = "selector" if subject == "selector"
|
|
44
|
+
data[:morph_mode] = "nothing" if subject == "nothing"
|
|
45
|
+
|
|
46
|
+
cable_ready[stream_name].dispatch_event(
|
|
47
|
+
name: "stimulus-reflex:server-message",
|
|
48
|
+
detail: {stimulus_reflex: data}
|
|
49
|
+
)
|
|
50
|
+
cable_ready.broadcast
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class StimulusReflex::Channel < ActionCable::Channel::Base
|
|
4
|
-
include
|
|
4
|
+
include StimulusReflex::Broadcaster
|
|
5
5
|
|
|
6
6
|
def stream_name
|
|
7
7
|
ids = connection.identifiers.map { |identifier| send(identifier).try(:id) || send(identifier) }
|
|
@@ -21,32 +21,49 @@ class StimulusReflex::Channel < ActionCable::Channel::Base
|
|
|
21
21
|
selectors = data["selectors"] = ["body"] if selectors.blank?
|
|
22
22
|
target = data["target"].to_s
|
|
23
23
|
reflex_name, method_name = target.split("#")
|
|
24
|
-
reflex_name = reflex_name.
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
reflex_name = reflex_name.camelize
|
|
25
|
+
reflex_name = reflex_name.end_with?("Reflex") ? reflex_name : "#{reflex_name}Reflex"
|
|
26
|
+
arguments = (data["args"] || []).map { |arg| object_with_indifferent_access arg }
|
|
27
|
+
element = StimulusReflex::Element.new(data)
|
|
28
|
+
permanent_attribute_name = data["permanent_attribute_name"]
|
|
29
|
+
params = data["params"] || {}
|
|
27
30
|
|
|
28
31
|
begin
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
32
|
+
begin
|
|
33
|
+
reflex_class = reflex_name.constantize.tap { |klass| raise ArgumentError.new("#{reflex_name} is not a StimulusReflex::Reflex") unless is_reflex?(klass) }
|
|
34
|
+
reflex = reflex_class.new(self, url: url, element: element, selectors: selectors, method_name: method_name, permanent_attribute_name: permanent_attribute_name, params: params)
|
|
35
|
+
delegate_call_to_reflex reflex, method_name, arguments
|
|
36
|
+
rescue => invoke_error
|
|
37
|
+
reflex&.rescue_with_handler(invoke_error)
|
|
38
|
+
message = exception_message_with_backtrace(invoke_error)
|
|
39
|
+
return broadcast_message subject: "error", body: "StimulusReflex::Channel Failed to invoke #{target}! #{url} #{message}", data: data
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
if reflex.halted?
|
|
43
|
+
broadcast_message subject: "halted", data: data
|
|
44
|
+
else
|
|
45
|
+
begin
|
|
46
|
+
reflex.morph_mode.stream_name = stream_name
|
|
47
|
+
reflex.morph_mode.broadcast(reflex, selectors, data)
|
|
48
|
+
rescue => render_error
|
|
49
|
+
reflex.rescue_with_handler(render_error)
|
|
50
|
+
message = exception_message_with_backtrace(render_error)
|
|
51
|
+
broadcast_message subject: "error", body: "StimulusReflex::Channel Failed to re-render #{url} #{message}", data: data
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
ensure
|
|
55
|
+
commit_session reflex if reflex
|
|
45
56
|
end
|
|
46
57
|
end
|
|
47
58
|
|
|
48
59
|
private
|
|
49
60
|
|
|
61
|
+
def object_with_indifferent_access(object)
|
|
62
|
+
return object.with_indifferent_access if object.respond_to?(:with_indifferent_access)
|
|
63
|
+
object.map! { |obj| object_with_indifferent_access obj } if object.is_a?(Array)
|
|
64
|
+
object
|
|
65
|
+
end
|
|
66
|
+
|
|
50
67
|
def is_reflex?(reflex_class)
|
|
51
68
|
reflex_class.ancestors.include? StimulusReflex::Reflex
|
|
52
69
|
end
|
|
@@ -65,57 +82,14 @@ class StimulusReflex::Channel < ActionCable::Channel::Base
|
|
|
65
82
|
end
|
|
66
83
|
end
|
|
67
84
|
|
|
68
|
-
def
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def commit_session(request, response)
|
|
74
|
-
store = request.session.instance_variable_get("@by")
|
|
75
|
-
store.commit_session request, response
|
|
85
|
+
def commit_session(reflex)
|
|
86
|
+
store = reflex.request.session.instance_variable_get("@by")
|
|
87
|
+
store.commit_session reflex.request, reflex.controller.response
|
|
76
88
|
rescue => e
|
|
77
89
|
message = "Failed to commit session! #{exception_message_with_backtrace(e)}"
|
|
78
90
|
logger.error "\e[31m#{message}\e[0m"
|
|
79
91
|
end
|
|
80
92
|
|
|
81
|
-
def render_page(reflex)
|
|
82
|
-
controller = reflex.request.controller_class.new
|
|
83
|
-
controller.instance_variable_set :"@stimulus_reflex", true
|
|
84
|
-
reflex.instance_variables.each do |name|
|
|
85
|
-
controller.instance_variable_set name, reflex.instance_variable_get(name)
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
controller.request = reflex.request
|
|
89
|
-
controller.response = ActionDispatch::Response.new
|
|
90
|
-
controller.process reflex.url_params[:action]
|
|
91
|
-
commit_session reflex.request, controller.response
|
|
92
|
-
controller.response.body
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def broadcast_morphs(selectors, data, html)
|
|
96
|
-
document = Nokogiri::HTML(html)
|
|
97
|
-
selectors = selectors.select { |s| document.css(s).present? }
|
|
98
|
-
selectors.each do |selector|
|
|
99
|
-
cable_ready[stream_name].morph(
|
|
100
|
-
selector: selector,
|
|
101
|
-
html: document.css(selector).inner_html,
|
|
102
|
-
children_only: true,
|
|
103
|
-
permanent_attribute_name: data["permanent_attribute_name"],
|
|
104
|
-
stimulus_reflex: data.merge(last: selector == selectors.last)
|
|
105
|
-
)
|
|
106
|
-
end
|
|
107
|
-
cable_ready.broadcast
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
def broadcast_error(message, data = {})
|
|
111
|
-
logger.error "\e[31m#{message}\e[0m"
|
|
112
|
-
cable_ready[stream_name].dispatch_event(
|
|
113
|
-
name: "stimulus-reflex:500",
|
|
114
|
-
detail: {stimulus_reflex: data.merge(error: message)}
|
|
115
|
-
)
|
|
116
|
-
cable_ready.broadcast
|
|
117
|
-
end
|
|
118
|
-
|
|
119
93
|
def exception_message_with_backtrace(exception)
|
|
120
94
|
"#{exception} #{exception.backtrace.first}"
|
|
121
95
|
end
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
class StimulusReflex::Element
|
|
4
|
-
attr_reader :attributes
|
|
3
|
+
class StimulusReflex::Element < OpenStruct
|
|
4
|
+
attr_reader :attributes, :data_attributes
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
def initialize(data = {})
|
|
7
|
+
@attributes = HashWithIndifferentAccess.new(data["attrs"] || {})
|
|
8
|
+
@data_attributes = HashWithIndifferentAccess.new(data["dataset"] || {})
|
|
9
|
+
all_attributes = @attributes.merge(@data_attributes)
|
|
10
|
+
super all_attributes.merge(all_attributes.transform_keys(&:underscore))
|
|
11
|
+
@data_attributes.transform_keys! { |key| key.delete_prefix "data-" }
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
def dataset
|
|
13
|
-
@dataset ||=
|
|
14
|
-
next unless key.start_with?("data-")
|
|
15
|
-
memo[key.delete_prefix("data-")] = value
|
|
16
|
-
}.freeze
|
|
15
|
+
@dataset ||= OpenStruct.new(data_attributes.merge(data_attributes.transform_keys(&:underscore)))
|
|
17
16
|
end
|
|
18
17
|
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,17 +43,21 @@ 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, :morph_mode, :permanent_attribute_name
|
|
46
47
|
|
|
47
48
|
delegate :connection, to: :channel
|
|
48
49
|
delegate :session, to: :request
|
|
49
50
|
|
|
50
|
-
def initialize(channel, url: nil, element: nil, selectors: [], method_name: nil)
|
|
51
|
+
def initialize(channel, url: nil, element: nil, selectors: [], method_name: nil, stream_name: nil, permanent_attribute_name: nil, params: {})
|
|
51
52
|
@channel = channel
|
|
52
53
|
@url = url
|
|
53
54
|
@element = element
|
|
54
55
|
@selectors = selectors
|
|
55
56
|
@method_name = method_name
|
|
57
|
+
@params = params
|
|
58
|
+
@permanent_attribute_name = permanent_attribute_name
|
|
59
|
+
@morph_mode = StimulusReflex::PageMorphMode.new
|
|
60
|
+
self.params
|
|
56
61
|
end
|
|
57
62
|
|
|
58
63
|
def request
|
|
@@ -76,10 +81,52 @@ class StimulusReflex::Reflex
|
|
|
76
81
|
)
|
|
77
82
|
path_params = Rails.application.routes.recognize_path_with_request(req, url, req.env[:extras] || {})
|
|
78
83
|
req.env.merge(ActionDispatch::Http::Parameters::PARAMETERS_KEY => path_params)
|
|
84
|
+
req.env["action_dispatch.request.parameters"] = req.parameters.merge(@params)
|
|
79
85
|
req.tap { |r| r.session.send :load! }
|
|
80
86
|
end
|
|
81
87
|
end
|
|
82
88
|
|
|
89
|
+
def morph(selectors, html = "")
|
|
90
|
+
case selectors
|
|
91
|
+
when :page
|
|
92
|
+
raise StandardError.new("Cannot call :page morph after :#{@morph_mode.to_sym} morph") unless @morph_mode.page?
|
|
93
|
+
when :nothing
|
|
94
|
+
raise StandardError.new("Cannot call :nothing morph after :selector morph") if @morph_mode.selector?
|
|
95
|
+
@morph_mode = StimulusReflex::NothingMorphMode.new
|
|
96
|
+
else
|
|
97
|
+
raise StandardError.new("Cannot call :selector morph after :nothing morph") if @morph_mode.nothing?
|
|
98
|
+
@morph_mode = StimulusReflex::SelectorMorphMode.new
|
|
99
|
+
if selectors.is_a?(Hash)
|
|
100
|
+
selectors.each do |selector, html|
|
|
101
|
+
enqueue_selector_broadcast selector, html
|
|
102
|
+
end
|
|
103
|
+
else
|
|
104
|
+
enqueue_selector_broadcast selectors, html
|
|
105
|
+
end
|
|
106
|
+
cable_ready.broadcast
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def enqueue_selector_broadcast(selector, html)
|
|
111
|
+
cable_ready[channel.stream_name].morph(
|
|
112
|
+
selector: selector,
|
|
113
|
+
html: html,
|
|
114
|
+
children_only: true,
|
|
115
|
+
permanent_attribute_name: permanent_attribute_name
|
|
116
|
+
)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def controller
|
|
120
|
+
@controller ||= begin
|
|
121
|
+
request.controller_class.new.tap do |c|
|
|
122
|
+
c.instance_variable_set :"@stimulus_reflex", true
|
|
123
|
+
instance_variables.each { |name| c.instance_variable_set name, instance_variable_get(name) }
|
|
124
|
+
c.request = request
|
|
125
|
+
c.response = ActionDispatch::Response.new
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
83
130
|
def url_params
|
|
84
131
|
@url_params ||= Rails.application.routes.recognize_path_with_request(request, request.path, request.env[:extras] || {})
|
|
85
132
|
end
|
|
@@ -103,4 +150,8 @@ class StimulusReflex::Reflex
|
|
|
103
150
|
def default_reflex
|
|
104
151
|
# noop default reflex to force page reloads
|
|
105
152
|
end
|
|
153
|
+
|
|
154
|
+
def params
|
|
155
|
+
@_params ||= ActionController::Parameters.new(request.parameters)
|
|
156
|
+
end
|
|
106
157
|
end
|
|
@@ -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
|
|
data/stimulus_reflex.gemspec
CHANGED
|
@@ -28,7 +28,7 @@ Gem::Specification.new do |gem|
|
|
|
28
28
|
|
|
29
29
|
gem.add_dependency "rack"
|
|
30
30
|
gem.add_dependency "nokogiri"
|
|
31
|
-
gem.add_dependency "rails", ">=
|
|
31
|
+
gem.add_dependency "rails", ">= 5.2"
|
|
32
32
|
gem.add_dependency "cable_ready", ">= 4.1.2"
|
|
33
33
|
|
|
34
34
|
gem.add_development_dependency "bundler", "~> 2.0"
|
|
@@ -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
|
|
@@ -11,6 +11,7 @@ class DemoReflex < ApplicationReflex
|
|
|
11
11
|
# - session - the ActionDispatch::Session store for the current visitor
|
|
12
12
|
# - url - the URL of the page that triggered the reflex
|
|
13
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)
|
|
14
15
|
#
|
|
15
16
|
# Example:
|
|
16
17
|
#
|
|
@@ -20,4 +21,5 @@ class DemoReflex < ApplicationReflex
|
|
|
20
21
|
# end
|
|
21
22
|
#
|
|
22
23
|
# Learn more at: https://docs.stimulusreflex.com
|
|
24
|
+
|
|
23
25
|
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.pre0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nathan Hopkins
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-
|
|
11
|
+
date: 2020-07-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rack
|
|
@@ -44,14 +44,14 @@ dependencies:
|
|
|
44
44
|
requirements:
|
|
45
45
|
- - ">="
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: '
|
|
47
|
+
version: '5.2'
|
|
48
48
|
type: :runtime
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - ">="
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: '
|
|
54
|
+
version: '5.2'
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: cable_ready
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -136,7 +136,7 @@ dependencies:
|
|
|
136
136
|
- - ">="
|
|
137
137
|
- !ruby/object:Gem::Version
|
|
138
138
|
version: '0'
|
|
139
|
-
description:
|
|
139
|
+
description:
|
|
140
140
|
email:
|
|
141
141
|
- natehop@gmail.com
|
|
142
142
|
executables: []
|
|
@@ -157,13 +157,18 @@ files:
|
|
|
157
157
|
- bin/standardize
|
|
158
158
|
- lib/generators/USAGE
|
|
159
159
|
- lib/generators/stimulus_reflex_generator.rb
|
|
160
|
-
- lib/generators/templates/
|
|
161
|
-
- lib/generators/templates/
|
|
162
|
-
- lib/generators/templates/
|
|
163
|
-
- lib/generators/templates/
|
|
160
|
+
- lib/generators/templates/app/javascript/controllers/%file_name%_controller.js.tt
|
|
161
|
+
- lib/generators/templates/app/javascript/controllers/application_controller.js.tt
|
|
162
|
+
- lib/generators/templates/app/reflexes/%file_name%_reflex.rb.tt
|
|
163
|
+
- lib/generators/templates/app/reflexes/application_reflex.rb.tt
|
|
164
164
|
- lib/stimulus_reflex.rb
|
|
165
|
+
- lib/stimulus_reflex/broadcaster.rb
|
|
165
166
|
- lib/stimulus_reflex/channel.rb
|
|
166
167
|
- lib/stimulus_reflex/element.rb
|
|
168
|
+
- lib/stimulus_reflex/morph_mode.rb
|
|
169
|
+
- lib/stimulus_reflex/morph_mode/nothing_morph_mode.rb
|
|
170
|
+
- lib/stimulus_reflex/morph_mode/page_morph_mode.rb
|
|
171
|
+
- lib/stimulus_reflex/morph_mode/selector_morph_mode.rb
|
|
167
172
|
- lib/stimulus_reflex/reflex.rb
|
|
168
173
|
- lib/stimulus_reflex/version.rb
|
|
169
174
|
- lib/tasks/stimulus_reflex/install.rake
|
|
@@ -197,12 +202,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
197
202
|
version: '0'
|
|
198
203
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
199
204
|
requirements:
|
|
200
|
-
- - "
|
|
205
|
+
- - ">"
|
|
201
206
|
- !ruby/object:Gem::Version
|
|
202
|
-
version:
|
|
207
|
+
version: 1.3.1
|
|
203
208
|
requirements: []
|
|
204
209
|
rubygems_version: 3.0.3
|
|
205
|
-
signing_key:
|
|
210
|
+
signing_key:
|
|
206
211
|
specification_version: 4
|
|
207
212
|
summary: Build reactive applications with the Rails tooling you already know and love.
|
|
208
213
|
test_files:
|