stimulus_reflex 3.2.2.pre1 → 3.3.0.pre2
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 +101 -4
- data/Gemfile.lock +74 -69
- 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} +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 +55 -0
- data/lib/stimulus_reflex/broadcasters/nothing_broadcaster.rb +17 -0
- data/lib/stimulus_reflex/broadcasters/page_broadcaster.rb +37 -0
- data/lib/stimulus_reflex/broadcasters/selector_broadcaster.rb +54 -0
- data/lib/stimulus_reflex/channel.rb +8 -49
- data/lib/stimulus_reflex/reflex.rb +23 -4
- data/lib/stimulus_reflex/version.rb +1 -1
- data/lib/tasks/stimulus_reflex/install.rake +10 -5
- data/tags +51 -17
- data/test/generators/stimulus_reflex_generator_test.rb +23 -0
- data/test/tmp/app/reflexes/demo_reflex.rb +1 -0
- metadata +13 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 16b54837068db127425aef4bb7d055fb461ed06cfd1693a1303f4b2e7c8e94d2
|
|
4
|
+
data.tar.gz: 23cb0849034978ecae65551b069f0173d9a63fd78db7233b11e4453be752cb48
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 88f1f347aad5757ee0f2420f4d781626f759f2bd00ed8392f101d52fd813e1e6e1ae9cbfde1fa3954332ad55766569cb1bcf33a56d1dc26b952057e60f97ad7b
|
|
7
|
+
data.tar.gz: eadb6be440d20ab3183e373e07579fbd7462d2b2fab06c60a80a0d9991c7003f10674e6696eb34e30e320e359b544bc8d25b9c0252bb251cb0d8a32f5946d766
|
data/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,104 @@
|
|
|
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.pre1...HEAD)
|
|
6
|
+
|
|
7
|
+
**Closed issues:**
|
|
8
|
+
|
|
9
|
+
- afterReflex not always firing on morph with selectors [\#269](https://github.com/hopsoft/stimulus_reflex/issues/269)
|
|
10
|
+
- Lifecycle hooks [\#266](https://github.com/hopsoft/stimulus_reflex/issues/266)
|
|
11
|
+
- Stimulus Reflex with Rspec not working [\#263](https://github.com/hopsoft/stimulus_reflex/issues/263)
|
|
12
|
+
|
|
13
|
+
**Merged pull requests:**
|
|
14
|
+
|
|
15
|
+
- Smarter warnings when element not found [\#274](https://github.com/hopsoft/stimulus_reflex/pull/274) ([hopsoft](https://github.com/hopsoft))
|
|
16
|
+
- 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))
|
|
17
|
+
- Update find element to ignore SR attrs [\#272](https://github.com/hopsoft/stimulus_reflex/pull/272) ([hopsoft](https://github.com/hopsoft))
|
|
18
|
+
- Refactor of the morph feature [\#270](https://github.com/hopsoft/stimulus_reflex/pull/270) ([hopsoft](https://github.com/hopsoft))
|
|
19
|
+
- coerce html arguments to string type [\#268](https://github.com/hopsoft/stimulus_reflex/pull/268) ([leastbad](https://github.com/leastbad))
|
|
20
|
+
- Update deployment docs after the official AnyCable 1.0 release [\#267](https://github.com/hopsoft/stimulus_reflex/pull/267) ([rmacklin](https://github.com/rmacklin))
|
|
21
|
+
|
|
22
|
+
## [v3.3.0.pre1](https://github.com/hopsoft/stimulus_reflex/tree/v3.3.0.pre1) (2020-07-08)
|
|
23
|
+
|
|
24
|
+
[Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.3.0.pre0...v3.3.0.pre1)
|
|
25
|
+
|
|
26
|
+
**Merged pull requests:**
|
|
27
|
+
|
|
28
|
+
- Fix selector morphs for updating partials and ViewComponents [\#262](https://github.com/hopsoft/stimulus_reflex/pull/262) ([leastbad](https://github.com/leastbad))
|
|
29
|
+
|
|
30
|
+
## [v3.3.0.pre0](https://github.com/hopsoft/stimulus_reflex/tree/v3.3.0.pre0) (2020-07-04)
|
|
31
|
+
|
|
32
|
+
[Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.2.3...v3.3.0.pre0)
|
|
33
|
+
|
|
34
|
+
**Implemented enhancements:**
|
|
35
|
+
|
|
36
|
+
- Returns more helpful error message if Reflex doesn't exist [\#254](https://github.com/hopsoft/stimulus_reflex/pull/254) ([leastbad](https://github.com/leastbad))
|
|
37
|
+
- Update install.rake to handle Typescript [\#241](https://github.com/hopsoft/stimulus_reflex/pull/241) ([iv-mexx](https://github.com/iv-mexx))
|
|
38
|
+
- Morph Modes: page, selector and nothing [\#211](https://github.com/hopsoft/stimulus_reflex/pull/211) ([leastbad](https://github.com/leastbad))
|
|
39
|
+
|
|
40
|
+
**Fixed bugs:**
|
|
41
|
+
|
|
42
|
+
- Limit MutationObserver mutations [\#256](https://github.com/hopsoft/stimulus_reflex/pull/256) ([jasoncharnes](https://github.com/jasoncharnes))
|
|
43
|
+
|
|
44
|
+
**Closed issues:**
|
|
45
|
+
|
|
46
|
+
- beforeUpdate/updateSuccess/updateError functions deprecated? [\#255](https://github.com/hopsoft/stimulus_reflex/issues/255)
|
|
47
|
+
- Error handling will fail if reflex is not defined [\#253](https://github.com/hopsoft/stimulus_reflex/issues/253)
|
|
48
|
+
- Select with data-reflex in Firefox flickers [\#251](https://github.com/hopsoft/stimulus_reflex/issues/251)
|
|
49
|
+
- data-reflex-attributes vs data-reflex-dataset [\#237](https://github.com/hopsoft/stimulus_reflex/issues/237)
|
|
50
|
+
- Shorthand action notations corresponding to stimulus [\#233](https://github.com/hopsoft/stimulus_reflex/issues/233)
|
|
51
|
+
- Lifecycle methods only called for one reflex [\#225](https://github.com/hopsoft/stimulus_reflex/issues/225)
|
|
52
|
+
- Tweak the generator so we can specify reflex actions [\#219](https://github.com/hopsoft/stimulus_reflex/issues/219)
|
|
53
|
+
- Docs: Clarify forcing DOM update with authentication [\#123](https://github.com/hopsoft/stimulus_reflex/issues/123)
|
|
54
|
+
- ActiveJob integration example [\#112](https://github.com/hopsoft/stimulus_reflex/issues/112)
|
|
55
|
+
|
|
56
|
+
**Merged pull requests:**
|
|
57
|
+
|
|
58
|
+
- Prep for pre release of 3.3.0 [\#259](https://github.com/hopsoft/stimulus_reflex/pull/259) ([hopsoft](https://github.com/hopsoft))
|
|
59
|
+
- Fallback to first Stimulus controller in array [\#257](https://github.com/hopsoft/stimulus_reflex/pull/257) ([jasoncharnes](https://github.com/jasoncharnes))
|
|
60
|
+
- Fix cases where plural reflexes were unresolved [\#252](https://github.com/hopsoft/stimulus_reflex/pull/252) ([joshleblanc](https://github.com/joshleblanc))
|
|
61
|
+
- warn against collections of identical elements that trigger reflexes [\#250](https://github.com/hopsoft/stimulus_reflex/pull/250) ([leastbad](https://github.com/leastbad))
|
|
62
|
+
- always calls params to persist them into controller action [\#249](https://github.com/hopsoft/stimulus_reflex/pull/249) ([RolandStuder](https://github.com/RolandStuder))
|
|
63
|
+
- Update deployment.md [\#248](https://github.com/hopsoft/stimulus_reflex/pull/248) ([user073](https://github.com/user073))
|
|
64
|
+
- Update reflexes.md [\#247](https://github.com/hopsoft/stimulus_reflex/pull/247) ([user073](https://github.com/user073))
|
|
65
|
+
- 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))
|
|
66
|
+
- 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))
|
|
67
|
+
- 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))
|
|
68
|
+
- 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))
|
|
69
|
+
- 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))
|
|
70
|
+
- adds params documentation [\#230](https://github.com/hopsoft/stimulus_reflex/pull/230) ([RolandStuder](https://github.com/RolandStuder))
|
|
71
|
+
- Fix calling wrong controller lifecycle methods [\#226](https://github.com/hopsoft/stimulus_reflex/pull/226) ([davidalejandroaguilar](https://github.com/davidalejandroaguilar))
|
|
72
|
+
- Allow to pass reflex action names to reflex generator [\#224](https://github.com/hopsoft/stimulus_reflex/pull/224) ([marcoroth](https://github.com/marcoroth))
|
|
73
|
+
|
|
74
|
+
## [v3.2.3](https://github.com/hopsoft/stimulus_reflex/tree/v3.2.3) (2020-06-15)
|
|
75
|
+
|
|
76
|
+
[Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.2.2...v3.2.3)
|
|
77
|
+
|
|
78
|
+
**Fixed bugs:**
|
|
79
|
+
|
|
80
|
+
- Add more smarts to \_\_perform [\#235](https://github.com/hopsoft/stimulus_reflex/pull/235) ([hopsoft](https://github.com/hopsoft))
|
|
81
|
+
- \_\_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))
|
|
82
|
+
- 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))
|
|
83
|
+
|
|
84
|
+
**Closed issues:**
|
|
85
|
+
|
|
86
|
+
- "Uncaught \(in promise\)" error after failed declarative reflex [\#170](https://github.com/hopsoft/stimulus_reflex/issues/170)
|
|
87
|
+
|
|
88
|
+
**Merged pull requests:**
|
|
89
|
+
|
|
90
|
+
- Fix typos in the documentation [\#228](https://github.com/hopsoft/stimulus_reflex/pull/228) ([dlt](https://github.com/dlt))
|
|
91
|
+
|
|
92
|
+
## [v3.2.2](https://github.com/hopsoft/stimulus_reflex/tree/v3.2.2) (2020-06-06)
|
|
93
|
+
|
|
94
|
+
[Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.2.2.pre1...v3.2.2)
|
|
95
|
+
|
|
96
|
+
**Closed issues:**
|
|
97
|
+
|
|
98
|
+
- Issue with doing a partial dom update [\#223](https://github.com/hopsoft/stimulus_reflex/issues/223)
|
|
99
|
+
|
|
100
|
+
## [v3.2.2.pre1](https://github.com/hopsoft/stimulus_reflex/tree/v3.2.2.pre1) (2020-05-30)
|
|
101
|
+
|
|
102
|
+
[Full Changelog](https://github.com/hopsoft/stimulus_reflex/compare/v3.2.2.pre0...v3.2.2.pre1)
|
|
6
103
|
|
|
7
104
|
**Fixed bugs:**
|
|
8
105
|
|
|
@@ -103,6 +200,7 @@
|
|
|
103
200
|
- Some housekeeping [\#189](https://github.com/hopsoft/stimulus_reflex/pull/189) ([hopsoft](https://github.com/hopsoft))
|
|
104
201
|
- Allow to call stimulate without a reflex target [\#188](https://github.com/hopsoft/stimulus_reflex/pull/188) ([marcoroth](https://github.com/marcoroth))
|
|
105
202
|
- Fix bug in super documentation [\#174](https://github.com/hopsoft/stimulus_reflex/pull/174) ([silva96](https://github.com/silva96))
|
|
203
|
+
- Support devise authenticated routes [\#172](https://github.com/hopsoft/stimulus_reflex/pull/172) ([db0sch](https://github.com/db0sch))
|
|
106
204
|
|
|
107
205
|
## [v3.1.4](https://github.com/hopsoft/stimulus_reflex/tree/v3.1.4) (2020-04-27)
|
|
108
206
|
|
|
@@ -130,7 +228,6 @@
|
|
|
130
228
|
|
|
131
229
|
- prettier-standard: include all js files in the project [\#177](https://github.com/hopsoft/stimulus_reflex/pull/177) ([marcoroth](https://github.com/marcoroth))
|
|
132
230
|
- Remove implicit permanent for text inputs [\#176](https://github.com/hopsoft/stimulus_reflex/pull/176) ([hopsoft](https://github.com/hopsoft))
|
|
133
|
-
- Support devise authenticated routes [\#172](https://github.com/hopsoft/stimulus_reflex/pull/172) ([db0sch](https://github.com/db0sch))
|
|
134
231
|
- setupDeclarativeReflexes export with UJS support [\#169](https://github.com/hopsoft/stimulus_reflex/pull/169) ([leastbad](https://github.com/leastbad))
|
|
135
232
|
- Fix compilation issue [\#168](https://github.com/hopsoft/stimulus_reflex/pull/168) ([jonathan-s](https://github.com/jonathan-s))
|
|
136
233
|
|
|
@@ -400,7 +497,6 @@
|
|
|
400
497
|
|
|
401
498
|
- Add support to configure room via register option [\#52](https://github.com/hopsoft/stimulus_reflex/pull/52) ([hopsoft](https://github.com/hopsoft))
|
|
402
499
|
- Move gitbook files to docs [\#49](https://github.com/hopsoft/stimulus_reflex/pull/49) ([hopsoft](https://github.com/hopsoft))
|
|
403
|
-
- Allow override of default controller [\#37](https://github.com/hopsoft/stimulus_reflex/pull/37) ([hopsoft](https://github.com/hopsoft))
|
|
404
500
|
|
|
405
501
|
**Closed issues:**
|
|
406
502
|
|
|
@@ -416,10 +512,10 @@
|
|
|
416
512
|
- Updated Minimal Javascript Example in README.md [\#47](https://github.com/hopsoft/stimulus_reflex/pull/47) ([kobaltz](https://github.com/kobaltz))
|
|
417
513
|
- Setup StimulusReflex controller callbacks [\#45](https://github.com/hopsoft/stimulus_reflex/pull/45) ([hopsoft](https://github.com/hopsoft))
|
|
418
514
|
- add .vscode directory to .gitignore [\#42](https://github.com/hopsoft/stimulus_reflex/pull/42) ([andrewmcodes](https://github.com/andrewmcodes))
|
|
515
|
+
- Allow override of default controller [\#37](https://github.com/hopsoft/stimulus_reflex/pull/37) ([hopsoft](https://github.com/hopsoft))
|
|
419
516
|
- update the name of the actions per feedback [\#36](https://github.com/hopsoft/stimulus_reflex/pull/36) ([andrewmcodes](https://github.com/andrewmcodes))
|
|
420
517
|
- update github templates [\#35](https://github.com/hopsoft/stimulus_reflex/pull/35) ([andrewmcodes](https://github.com/andrewmcodes))
|
|
421
518
|
- Tighten up security of remote invocation [\#32](https://github.com/hopsoft/stimulus_reflex/pull/32) ([hopsoft](https://github.com/hopsoft))
|
|
422
|
-
- Add Ruby magic comment [\#18](https://github.com/hopsoft/stimulus_reflex/pull/18) ([dixpac](https://github.com/dixpac))
|
|
423
519
|
|
|
424
520
|
**Fixed bugs:**
|
|
425
521
|
|
|
@@ -453,6 +549,7 @@
|
|
|
453
549
|
**Implemented enhancements:**
|
|
454
550
|
|
|
455
551
|
- Implicitly send DOM attributes to reflex methods [\#21](https://github.com/hopsoft/stimulus_reflex/pull/21) ([hopsoft](https://github.com/hopsoft))
|
|
552
|
+
- Add Ruby magic comment [\#18](https://github.com/hopsoft/stimulus_reflex/pull/18) ([dixpac](https://github.com/dixpac))
|
|
456
553
|
- Add GitHub Actions for Linters [\#17](https://github.com/hopsoft/stimulus_reflex/pull/17) ([andrewmcodes](https://github.com/andrewmcodes))
|
|
457
554
|
|
|
458
555
|
**Fixed bugs:**
|
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.pre2)
|
|
5
5
|
cable_ready (>= 4.1.2)
|
|
6
6
|
nokogiri
|
|
7
7
|
rack
|
|
@@ -10,64 +10,64 @@ 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)
|
|
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
72
|
coderay (1.1.3)
|
|
73
73
|
concurrent-ruby (1.1.6)
|
|
@@ -75,9 +75,9 @@ GEM
|
|
|
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
|
-
loofah (2.
|
|
80
|
+
loofah (2.6.0)
|
|
81
81
|
crass (~> 1.0.2)
|
|
82
82
|
nokogiri (>= 1.5.9)
|
|
83
83
|
mail (2.7.1)
|
|
@@ -90,68 +90,73 @@ 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)
|
|
132
132
|
rainbow (3.0.0)
|
|
133
133
|
rake (13.0.1)
|
|
134
|
+
regexp_parser (1.7.1)
|
|
134
135
|
rexml (3.2.4)
|
|
135
|
-
rubocop (0.
|
|
136
|
+
rubocop (0.85.1)
|
|
136
137
|
parallel (~> 1.10)
|
|
137
138
|
parser (>= 2.7.0.1)
|
|
138
139
|
rainbow (>= 2.2.2, < 4.0)
|
|
140
|
+
regexp_parser (>= 1.7)
|
|
139
141
|
rexml
|
|
142
|
+
rubocop-ast (>= 0.0.3)
|
|
140
143
|
ruby-progressbar (~> 1.7)
|
|
141
144
|
unicode-display_width (>= 1.4.0, < 2.0)
|
|
142
|
-
rubocop-
|
|
145
|
+
rubocop-ast (0.1.0)
|
|
146
|
+
parser (>= 2.7.0.1)
|
|
147
|
+
rubocop-performance (1.6.1)
|
|
143
148
|
rubocop (>= 0.71.0)
|
|
144
149
|
ruby-progressbar (1.10.1)
|
|
145
|
-
sprockets (4.0.
|
|
150
|
+
sprockets (4.0.2)
|
|
146
151
|
concurrent-ruby (~> 1.0)
|
|
147
152
|
rack (> 1, < 3)
|
|
148
153
|
sprockets-rails (3.2.1)
|
|
149
154
|
actionpack (>= 4.0)
|
|
150
155
|
activesupport (>= 4.0)
|
|
151
156
|
sprockets (>= 3.0.0)
|
|
152
|
-
standard (0.4.
|
|
153
|
-
rubocop (~> 0.
|
|
154
|
-
rubocop-performance (~> 1.
|
|
157
|
+
standard (0.4.7)
|
|
158
|
+
rubocop (~> 0.85.0)
|
|
159
|
+
rubocop-performance (~> 1.6.0)
|
|
155
160
|
standardrb (1.0.0)
|
|
156
161
|
standard
|
|
157
162
|
thor (1.0.1)
|
|
@@ -159,10 +164,10 @@ GEM
|
|
|
159
164
|
tzinfo (1.2.7)
|
|
160
165
|
thread_safe (~> 0.1)
|
|
161
166
|
unicode-display_width (1.7.0)
|
|
162
|
-
websocket-driver (0.7.
|
|
167
|
+
websocket-driver (0.7.3)
|
|
163
168
|
websocket-extensions (>= 0.1.0)
|
|
164
|
-
websocket-extensions (0.1.
|
|
165
|
-
zeitwerk (2.
|
|
169
|
+
websocket-extensions (0.1.5)
|
|
170
|
+
zeitwerk (2.4.0)
|
|
166
171
|
|
|
167
172
|
PLATFORMS
|
|
168
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" />
|
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,55 @@
|
|
|
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
|
+
stimulus_reflex: data.merge(
|
|
33
|
+
broadcaster: to_sym,
|
|
34
|
+
server_message: {subject: subject, body: body}
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def broadcast_message(subject:, body: nil, data: {})
|
|
41
|
+
enqueue_message subject: subject, body: body, data: data
|
|
42
|
+
cable_ready.broadcast
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# abstract method to be implemented by subclasses
|
|
46
|
+
def broadcast(*args)
|
|
47
|
+
raise NotImplementedError
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# abstract method to be implemented by subclasses
|
|
51
|
+
def to_sym
|
|
52
|
+
raise NotImplementedError
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
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,37 @@
|
|
|
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
|
+
last: selector == selectors.last,
|
|
22
|
+
broadast_type: to_sym
|
|
23
|
+
})
|
|
24
|
+
)
|
|
25
|
+
end
|
|
26
|
+
cable_ready.broadcast
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def to_sym
|
|
30
|
+
:page
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def page?
|
|
34
|
+
true
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
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
|
+
last = morph == morphs.last && selector == updates.keys.last
|
|
11
|
+
html = html.to_s
|
|
12
|
+
fragment = Nokogiri::HTML.fragment(html)
|
|
13
|
+
match = fragment.at_css(selector)
|
|
14
|
+
if match.present?
|
|
15
|
+
cable_ready[stream_name].morph(
|
|
16
|
+
selector: selector,
|
|
17
|
+
html: match.inner_html,
|
|
18
|
+
children_only: true,
|
|
19
|
+
permanent_attribute_name: permanent_attribute_name,
|
|
20
|
+
stimulus_reflex: data.merge({
|
|
21
|
+
last: last,
|
|
22
|
+
broadast_type: to_sym
|
|
23
|
+
})
|
|
24
|
+
)
|
|
25
|
+
else
|
|
26
|
+
cable_ready[stream_name].inner_html(
|
|
27
|
+
selector: selector,
|
|
28
|
+
html: fragment.to_html,
|
|
29
|
+
stimulus_reflex: data.merge({
|
|
30
|
+
last: last,
|
|
31
|
+
broadast_type: to_sym
|
|
32
|
+
})
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
cable_ready.broadcast
|
|
39
|
+
morphs.clear
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def morphs
|
|
43
|
+
@morphs ||= []
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def to_sym
|
|
47
|
+
:selector
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def selector?
|
|
51
|
+
true
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
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,33 @@ 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
|
|
35
|
+
reflex&.rescue_with_handler(invoke_error)
|
|
37
36
|
message = exception_message_with_backtrace(invoke_error)
|
|
38
|
-
return broadcast_message subject: "error", body: "StimulusReflex::Channel Failed to invoke #{target}! #{url} #{message}", data: data
|
|
37
|
+
return reflex.broadcast_message subject: "error", body: "StimulusReflex::Channel Failed to invoke #{target}! #{url} #{message}", data: data
|
|
39
38
|
end
|
|
40
39
|
|
|
41
40
|
if reflex.halted?
|
|
42
|
-
broadcast_message subject: "halted", data: data
|
|
41
|
+
reflex.broadcast_message subject: "halted", data: data
|
|
43
42
|
else
|
|
44
43
|
begin
|
|
45
|
-
|
|
44
|
+
reflex.broadcast(selectors, data)
|
|
46
45
|
rescue => render_error
|
|
47
46
|
reflex.rescue_with_handler(render_error)
|
|
48
47
|
message = exception_message_with_backtrace(render_error)
|
|
49
|
-
broadcast_message subject: "error", body: "StimulusReflex::Channel Failed to re-render #{url} #{message}", data: data
|
|
48
|
+
reflex.broadcast_message subject: "error", body: "StimulusReflex::Channel Failed to re-render #{url} #{message}", data: data
|
|
50
49
|
end
|
|
51
50
|
end
|
|
52
51
|
ensure
|
|
@@ -80,11 +79,6 @@ class StimulusReflex::Channel < ActionCable::Channel::Base
|
|
|
80
79
|
end
|
|
81
80
|
end
|
|
82
81
|
|
|
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
82
|
def commit_session(reflex)
|
|
89
83
|
store = reflex.request.session.instance_variable_get("@by")
|
|
90
84
|
store.commit_session reflex.request, reflex.controller.response
|
|
@@ -93,41 +87,6 @@ class StimulusReflex::Channel < ActionCable::Channel::Base
|
|
|
93
87
|
logger.error "\e[31m#{message}\e[0m"
|
|
94
88
|
end
|
|
95
89
|
|
|
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
90
|
def exception_message_with_backtrace(exception)
|
|
132
91
|
"#{exception} #{exception.backtrace.first}"
|
|
133
92
|
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
|
|
@@ -77,11 +82,25 @@ class StimulusReflex::Reflex
|
|
|
77
82
|
)
|
|
78
83
|
path_params = Rails.application.routes.recognize_path_with_request(req, url, req.env[:extras] || {})
|
|
79
84
|
req.env.merge(ActionDispatch::Http::Parameters::PARAMETERS_KEY => path_params)
|
|
80
|
-
req.env["action_dispatch.request.parameters"] = @params
|
|
85
|
+
req.env["action_dispatch.request.parameters"] = req.parameters.merge(@params)
|
|
81
86
|
req.tap { |r| r.session.send :load! }
|
|
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
|
|
data/tags
CHANGED
|
@@ -4,39 +4,73 @@
|
|
|
4
4
|
!_TAG_PROGRAM_NAME Exuberant Ctags //
|
|
5
5
|
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
|
|
6
6
|
!_TAG_PROGRAM_VERSION 5.8 //
|
|
7
|
-
ApplicationReflex lib/generators/templates/application_reflex.rb /^class ApplicationReflex < StimulusReflex::Reflex$/;" c
|
|
8
7
|
ApplicationReflex test/tmp/app/reflexes/application_reflex.rb /^class ApplicationReflex < StimulusReflex::Reflex$/;" c
|
|
8
|
+
Broadcaster lib/stimulus_reflex/broadcasters/broadcaster.rb /^ class Broadcaster$/;" c class:StimulusReflex
|
|
9
9
|
DemoReflex test/tmp/app/reflexes/demo_reflex.rb /^class DemoReflex < ApplicationReflex$/;" c
|
|
10
10
|
Engine lib/stimulus_reflex.rb /^ class Engine < Rails::Engine$/;" c class:StimulusReflex
|
|
11
|
+
NothingBroadcaster lib/stimulus_reflex/broadcasters/nothing_broadcaster.rb /^ class NothingBroadcaster < Broadcaster$/;" c class:StimulusReflex
|
|
12
|
+
PageBroadcaster lib/stimulus_reflex/broadcasters/page_broadcaster.rb /^ class PageBroadcaster < Broadcaster$/;" c class:StimulusReflex
|
|
13
|
+
SelectorBroadcaster lib/stimulus_reflex/broadcasters/selector_broadcaster.rb /^ class SelectorBroadcaster < Broadcaster$/;" c class:StimulusReflex
|
|
11
14
|
StimulusReflex lib/stimulus_reflex.rb /^module StimulusReflex$/;" m
|
|
15
|
+
StimulusReflex lib/stimulus_reflex/broadcasters/broadcaster.rb /^module StimulusReflex$/;" m
|
|
16
|
+
StimulusReflex lib/stimulus_reflex/broadcasters/nothing_broadcaster.rb /^module StimulusReflex$/;" m
|
|
17
|
+
StimulusReflex lib/stimulus_reflex/broadcasters/page_broadcaster.rb /^module StimulusReflex$/;" m
|
|
18
|
+
StimulusReflex lib/stimulus_reflex/broadcasters/selector_broadcaster.rb /^module StimulusReflex$/;" m
|
|
12
19
|
StimulusReflex lib/stimulus_reflex/channel.rb /^class StimulusReflex::Channel < ActionCable::Channel::Base$/;" c
|
|
13
|
-
StimulusReflex lib/stimulus_reflex/element.rb /^class StimulusReflex::Element$/;" c
|
|
20
|
+
StimulusReflex lib/stimulus_reflex/element.rb /^class StimulusReflex::Element < OpenStruct$/;" c
|
|
14
21
|
StimulusReflex lib/stimulus_reflex/reflex.rb /^class StimulusReflex::Reflex$/;" c
|
|
15
22
|
StimulusReflex lib/stimulus_reflex/version.rb /^module StimulusReflex$/;" m
|
|
16
23
|
StimulusReflexGenerator lib/generators/stimulus_reflex_generator.rb /^class StimulusReflexGenerator < Rails::Generators::NamedBase$/;" c
|
|
17
24
|
StimulusReflexGeneratorTest test/generators/stimulus_reflex_generator_test.rb /^class StimulusReflexGeneratorTest < Rails::Generators::TestCase$/;" c
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
add_callback lib/stimulus_reflex/reflex.rb /^ def add_callback(kind, *args, &block)$/;" f class:StimulusReflex
|
|
26
|
+
after_reflex lib/stimulus_reflex/reflex.rb /^ def after_reflex(*args, &block)$/;" f class:StimulusReflex
|
|
27
|
+
around_reflex lib/stimulus_reflex/reflex.rb /^ def around_reflex(*args, &block)$/;" f class:StimulusReflex
|
|
28
|
+
before_reflex lib/stimulus_reflex/reflex.rb /^ def before_reflex(*args, &block)$/;" f class:StimulusReflex
|
|
29
|
+
broadcast lib/stimulus_reflex/broadcasters/broadcaster.rb /^ def broadcast(*args)$/;" f class:StimulusReflex.Broadcaster
|
|
30
|
+
broadcast lib/stimulus_reflex/broadcasters/nothing_broadcaster.rb /^ def broadcast(_, data)$/;" f class:StimulusReflex.NothingBroadcaster
|
|
31
|
+
broadcast lib/stimulus_reflex/broadcasters/page_broadcaster.rb /^ def broadcast(selectors, data)$/;" f class:StimulusReflex.PageBroadcaster
|
|
32
|
+
broadcast lib/stimulus_reflex/broadcasters/selector_broadcaster.rb /^ def broadcast(_, data = {})$/;" f class:StimulusReflex.SelectorBroadcaster
|
|
33
|
+
broadcast_message lib/stimulus_reflex/broadcasters/broadcaster.rb /^ def broadcast_message(subject:, body: nil, data: {})$/;" f class:StimulusReflex.Broadcaster
|
|
34
|
+
commit_session lib/stimulus_reflex/channel.rb /^ def commit_session(reflex)$/;" f class:StimulusReflex
|
|
35
|
+
controller lib/stimulus_reflex/reflex.rb /^ def controller$/;" f
|
|
36
|
+
copy_application_files lib/generators/stimulus_reflex_generator.rb /^ def copy_application_files$/;" f class:StimulusReflexGenerator
|
|
24
37
|
dataset lib/stimulus_reflex/element.rb /^ def dataset$/;" f class:StimulusReflex
|
|
38
|
+
default_reflex lib/stimulus_reflex/reflex.rb /^ def default_reflex$/;" f
|
|
25
39
|
delegate_call_to_reflex lib/stimulus_reflex/channel.rb /^ def delegate_call_to_reflex(reflex, method_name, arguments = [])$/;" f class:StimulusReflex
|
|
40
|
+
enqueue_message lib/stimulus_reflex/broadcasters/broadcaster.rb /^ def enqueue_message(subject:, body: nil, data: {})$/;" f class:StimulusReflex.Broadcaster
|
|
41
|
+
error javascript/log.js /^function error (response) {$/;" f
|
|
26
42
|
exception_message_with_backtrace lib/stimulus_reflex/channel.rb /^ def exception_message_with_backtrace(exception)$/;" f class:StimulusReflex
|
|
43
|
+
execute lib/generators/stimulus_reflex_generator.rb /^ def execute$/;" f class:StimulusReflexGenerator
|
|
27
44
|
export.reflexAttribute javascript/schema.js /^ reflexAttribute: 'data-reflex',$/;" p
|
|
45
|
+
export.reflexDatasetAttribute javascript/schema.js /^ reflexDatasetAttribute: 'data-reflex-dataset'$/;" p
|
|
28
46
|
export.reflexPermanentAttribute javascript/schema.js /^ reflexPermanentAttribute: 'data-reflex-permanent',$/;" p
|
|
29
|
-
export.reflexRootAttribute javascript/schema.js /^ reflexRootAttribute: 'data-reflex-root'
|
|
47
|
+
export.reflexRootAttribute javascript/schema.js /^ reflexRootAttribute: 'data-reflex-root',$/;" p
|
|
30
48
|
findConsumer javascript/consumer.js /^function findConsumer (object, depth = 0) {$/;" f
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
49
|
+
function.success javascript/log.js /^function success (response, options = { halted: false }) {$/;" f
|
|
50
|
+
halted? lib/stimulus_reflex/reflex.rb /^ def halted?$/;" f
|
|
51
|
+
initialize lib/stimulus_reflex/broadcasters/broadcaster.rb /^ def initialize(reflex)$/;" f class:StimulusReflex.Broadcaster
|
|
52
|
+
initialize lib/stimulus_reflex/element.rb /^ def initialize(data = {})$/;" f class:StimulusReflex
|
|
53
|
+
initialize lib/stimulus_reflex/reflex.rb /^ def initialize(channel, url: nil, element: nil, selectors: [], method_name: nil, permanent_attribute_name: nil, params: {})$/;" f
|
|
35
54
|
is_reflex? lib/stimulus_reflex/channel.rb /^ def is_reflex?(reflex_class)$/;" f class:StimulusReflex
|
|
55
|
+
morph lib/stimulus_reflex/reflex.rb /^ def morph(selectors, html = "")$/;" f
|
|
56
|
+
morphs lib/stimulus_reflex/broadcasters/selector_broadcaster.rb /^ def morphs$/;" f class:StimulusReflex.SelectorBroadcaster
|
|
57
|
+
normalize_callback_option! lib/stimulus_reflex/reflex.rb /^ def normalize_callback_option!(options, from, to)$/;" f class:StimulusReflex
|
|
58
|
+
normalize_callback_options! lib/stimulus_reflex/reflex.rb /^ def normalize_callback_options!(options)$/;" f class:StimulusReflex
|
|
59
|
+
nothing? lib/stimulus_reflex/broadcasters/broadcaster.rb /^ def nothing?$/;" f class:StimulusReflex.Broadcaster
|
|
60
|
+
nothing? lib/stimulus_reflex/broadcasters/nothing_broadcaster.rb /^ def nothing?$/;" f class:StimulusReflex.NothingBroadcaster
|
|
61
|
+
object_with_indifferent_access lib/stimulus_reflex/channel.rb /^ def object_with_indifferent_access(object)$/;" f class:StimulusReflex
|
|
62
|
+
page? lib/stimulus_reflex/broadcasters/broadcaster.rb /^ def page?$/;" f class:StimulusReflex.Broadcaster
|
|
63
|
+
page? lib/stimulus_reflex/broadcasters/page_broadcaster.rb /^ def page?$/;" f class:StimulusReflex.PageBroadcaster
|
|
64
|
+
params lib/stimulus_reflex/reflex.rb /^ def params$/;" f
|
|
65
|
+
process lib/stimulus_reflex/reflex.rb /^ def process(name, *args)$/;" f
|
|
36
66
|
receive lib/stimulus_reflex/channel.rb /^ def receive(data)$/;" f class:StimulusReflex
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
67
|
+
request lib/stimulus_reflex/reflex.rb /^ def request$/;" f
|
|
68
|
+
selector? lib/stimulus_reflex/broadcasters/broadcaster.rb /^ def selector?$/;" f class:StimulusReflex.Broadcaster
|
|
69
|
+
selector? lib/stimulus_reflex/broadcasters/selector_broadcaster.rb /^ def selector?$/;" f class:StimulusReflex.SelectorBroadcaster
|
|
40
70
|
stream_name lib/stimulus_reflex/channel.rb /^ def stream_name$/;" f class:StimulusReflex
|
|
41
71
|
subscribed lib/stimulus_reflex/channel.rb /^ def subscribed$/;" f class:StimulusReflex
|
|
42
|
-
|
|
72
|
+
to_sym lib/stimulus_reflex/broadcasters/broadcaster.rb /^ def to_sym$/;" f class:StimulusReflex.Broadcaster
|
|
73
|
+
to_sym lib/stimulus_reflex/broadcasters/nothing_broadcaster.rb /^ def to_sym$/;" f class:StimulusReflex.NothingBroadcaster
|
|
74
|
+
to_sym lib/stimulus_reflex/broadcasters/page_broadcaster.rb /^ def to_sym$/;" f class:StimulusReflex.PageBroadcaster
|
|
75
|
+
to_sym lib/stimulus_reflex/broadcasters/selector_broadcaster.rb /^ def to_sym$/;" f class:StimulusReflex.SelectorBroadcaster
|
|
76
|
+
url_params lib/stimulus_reflex/reflex.rb /^ def url_params$/;" f
|
|
@@ -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.pre2
|
|
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-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rack
|
|
@@ -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,11 +157,15 @@ 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/broadcasters/broadcaster.rb
|
|
166
|
+
- lib/stimulus_reflex/broadcasters/nothing_broadcaster.rb
|
|
167
|
+
- lib/stimulus_reflex/broadcasters/page_broadcaster.rb
|
|
168
|
+
- lib/stimulus_reflex/broadcasters/selector_broadcaster.rb
|
|
165
169
|
- lib/stimulus_reflex/channel.rb
|
|
166
170
|
- lib/stimulus_reflex/element.rb
|
|
167
171
|
- lib/stimulus_reflex/reflex.rb
|
|
@@ -202,7 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
202
206
|
version: 1.3.1
|
|
203
207
|
requirements: []
|
|
204
208
|
rubygems_version: 3.0.3
|
|
205
|
-
signing_key:
|
|
209
|
+
signing_key:
|
|
206
210
|
specification_version: 4
|
|
207
211
|
summary: Build reactive applications with the Rails tooling you already know and love.
|
|
208
212
|
test_files:
|