turbo_reflex 0.0.2 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Dockerfile +43 -0
- data/Dockerfile.orig +49 -0
- data/Gemfile.lock +25 -5
- data/README.md +30 -28
- data/app/assets/builds/turbo_reflex.js +2 -0
- data/app/assets/builds/turbo_reflex.js.map +7 -0
- data/app/assets/images/turbo-reflex-mark.webp +0 -0
- data/app/controllers/concerns/turbo_reflex/controller.rb +1 -0
- data/app/controllers/turbo_reflex/application_controller.rb +5 -0
- data/app/controllers/turbo_reflex/turbo_reflexes_controller.rb +10 -0
- data/app/helpers/turbo_reflex/turbo_reflex_helper.rb +9 -0
- data/app/javascript/elements.js +2 -2
- data/bin/standardize +2 -0
- data/config/routes.rb +5 -0
- data/docker-compose.yml +46 -0
- data/fly.toml +38 -0
- data/lib/turbo_reflex/base.rb +6 -0
- data/lib/turbo_reflex/engine.rb +15 -0
- data/lib/turbo_reflex/errors.rb +6 -0
- data/lib/turbo_reflex/version.rb +1 -1
- data/package.json +6 -4
- data/turbo_reflex.gemspec +5 -1
- data/yarn-error.log +3033 -0
- data/yarn.lock +193 -134
- metadata +71 -5
- data/app/assets/builds/turbo_reflex.min.js +0 -2
- data/app/assets/builds/turbo_reflex.min.js.map +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c9fe08630cc0c938fc6b2eb4ed55b841bd968d3b1a9e47c4d7831eba6877994f
|
4
|
+
data.tar.gz: 41e2891f690ec5d77c0c3ec537145f4126e750351bcd9b9040fa701374a35afa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f2069894ceef06beac578f28a4c4729ab272e089fbe4556f71743ef2d7dfdd328512102ac24d0cf4d8d1f5379fc67e2c356e1ec05b74a207ddf656ac470d7bdf
|
7
|
+
data.tar.gz: f316ed002e6560cd93d4d30c600c51d5181c82a500e75b93baad27195d0934fd5ebf4fb0ea1cdecd72fd7b5d6654f4671c104d9d46c30e446c77df876a7f9911
|
data/Dockerfile
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
FROM ruby:3.1.2
|
2
|
+
|
3
|
+
RUN apt-get -y update && \
|
4
|
+
apt-get -y upgrade && \
|
5
|
+
apt-get -y --allow-downgrades --allow-remove-essential --allow-change-held-packages install \
|
6
|
+
build-essential \
|
7
|
+
git \
|
8
|
+
nodejs \
|
9
|
+
npm \
|
10
|
+
sqlite3 \
|
11
|
+
tzdata && \
|
12
|
+
apt-get clean
|
13
|
+
|
14
|
+
# setup ruby gems
|
15
|
+
RUN gem update --system && \
|
16
|
+
gem install bundler && \
|
17
|
+
bundle config set --global --without test
|
18
|
+
|
19
|
+
# setup yarn
|
20
|
+
RUN npm install -g yarn
|
21
|
+
|
22
|
+
# get application code
|
23
|
+
RUN rm -rf /opt/turbo_reflex
|
24
|
+
RUN git clone --origin github --branch main --depth 1 https://github.com/hopsoft/turbo_reflex.git /opt/turbo_reflex
|
25
|
+
|
26
|
+
# install application dependencies 1st time
|
27
|
+
WORKDIR /opt/turbo_reflex
|
28
|
+
RUN yarn
|
29
|
+
RUN bundle
|
30
|
+
|
31
|
+
# prepare the environment
|
32
|
+
ENV RAILS_ENV=production RAILS_LOG_TO_STDOUT=true RAILS_SERVE_STATIC_FILES=true
|
33
|
+
|
34
|
+
# prepare and run the application
|
35
|
+
CMD git pull --no-rebase github main && \
|
36
|
+
yarn && \
|
37
|
+
cd test/dummy && \
|
38
|
+
bundle && \
|
39
|
+
rm -f tmp/pids/server.pid && \
|
40
|
+
bin/rails db:create db:migrate && \
|
41
|
+
bin/rails assets:clobber && \
|
42
|
+
bin/rails assets:precompile && \
|
43
|
+
bin/rails s --binding=0.0.0.0 --port=3000
|
data/Dockerfile.orig
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
FROM ruby:3.1.2
|
2
|
+
|
3
|
+
RUN apt-get -y update && \
|
4
|
+
apt-get -y upgrade && \
|
5
|
+
apt-get -y --allow-downgrades --allow-remove-essential --allow-change-held-packages install \
|
6
|
+
build-essential \
|
7
|
+
git \
|
8
|
+
nodejs \
|
9
|
+
npm \
|
10
|
+
sqlite3 \
|
11
|
+
tzdata && \
|
12
|
+
apt-get clean
|
13
|
+
|
14
|
+
<<<<<<< HEAD
|
15
|
+
# prepare the environment
|
16
|
+
ENV RAILS_ENV=production RAILS_LOG_TO_STDOUT=true RAILS_SERVE_STATIC_FILES=true
|
17
|
+
|
18
|
+
=======
|
19
|
+
>>>>>>> main
|
20
|
+
# setup ruby gems
|
21
|
+
RUN gem update --system && \
|
22
|
+
gem install bundler && \
|
23
|
+
bundle config set --global --without test
|
24
|
+
|
25
|
+
# setup yarn
|
26
|
+
RUN npm install -g yarn
|
27
|
+
|
28
|
+
# get application code
|
29
|
+
RUN git clone --origin github --branch main --depth 1 https://github.com/hopsoft/turbo_reflex.git /opt/turbo_reflex
|
30
|
+
|
31
|
+
# install application dependencies 1st time
|
32
|
+
WORKDIR /opt/turbo_reflex
|
33
|
+
RUN yarn
|
34
|
+
WORKDIR /opt/turbo_reflex/test/dummy
|
35
|
+
RUN bundle
|
36
|
+
|
37
|
+
# prepare the environment
|
38
|
+
ENV RAILS_ENV=production RAILS_LOG_TO_STDOUT=true RAILS_SERVE_STATIC_FILES=true
|
39
|
+
|
40
|
+
# prepare and run the application
|
41
|
+
CMD git pull --no-rebase github && \
|
42
|
+
git checkout hopsoft/hijack && \
|
43
|
+
cd /opt/turbo_reflex && yarn && \
|
44
|
+
cd /opt/turbo_reflex/test/dummy && bundle && \
|
45
|
+
rm -f tmp/pids/server.pid && \
|
46
|
+
bin/rails db:create db:migrate && \
|
47
|
+
bin/rails assets:clobber && \
|
48
|
+
bin/rails assets:precompile && \
|
49
|
+
bin/rails s --binding=0.0.0.0 --port=3000
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
turbo_reflex (0.0.
|
4
|
+
turbo_reflex (0.0.4)
|
5
5
|
rails (>= 6.1)
|
6
6
|
turbo-rails (>= 1.1)
|
7
7
|
|
@@ -77,6 +77,7 @@ GEM
|
|
77
77
|
public_suffix (>= 2.0.2, < 6.0)
|
78
78
|
ansi (1.5.0)
|
79
79
|
ast (2.4.2)
|
80
|
+
bindex (0.8.1)
|
80
81
|
builder (3.2.4)
|
81
82
|
byebug (11.1.3)
|
82
83
|
capybara (3.37.1)
|
@@ -103,6 +104,7 @@ GEM
|
|
103
104
|
cliver (~> 0.3)
|
104
105
|
concurrent-ruby (~> 1.1)
|
105
106
|
websocket-driver (>= 0.6, < 0.8)
|
107
|
+
foreman (0.87.2)
|
106
108
|
globalid (1.0.0)
|
107
109
|
activesupport (>= 5.0)
|
108
110
|
i18n (1.12.0)
|
@@ -111,7 +113,7 @@ GEM
|
|
111
113
|
actionpack (>= 6.0.0)
|
112
114
|
railties (>= 6.0.0)
|
113
115
|
json (2.6.2)
|
114
|
-
loofah (2.
|
116
|
+
loofah (2.19.0)
|
115
117
|
crass (~> 1.0.2)
|
116
118
|
nokogiri (>= 1.5.9)
|
117
119
|
magic_frozen_string_literal (1.2.0)
|
@@ -142,6 +144,8 @@ GEM
|
|
142
144
|
net-protocol
|
143
145
|
timeout
|
144
146
|
nio4r (2.5.8)
|
147
|
+
nokogiri (1.13.8-aarch64-linux)
|
148
|
+
racc (~> 1.4)
|
145
149
|
nokogiri (1.13.8-arm64-darwin)
|
146
150
|
racc (~> 1.4)
|
147
151
|
parallel (1.22.1)
|
@@ -190,6 +194,7 @@ GEM
|
|
190
194
|
rake (13.0.6)
|
191
195
|
regexp_parser (2.5.0)
|
192
196
|
rexml (3.2.5)
|
197
|
+
rouge (4.0.0)
|
193
198
|
rubocop (1.35.1)
|
194
199
|
json (~> 2.3)
|
195
200
|
parallel (~> 1.10)
|
@@ -219,6 +224,7 @@ GEM
|
|
219
224
|
actionpack (>= 5.2)
|
220
225
|
activesupport (>= 5.2)
|
221
226
|
sprockets (>= 3.0.0)
|
227
|
+
sqlite3 (1.5.0-aarch64-linux)
|
222
228
|
sqlite3 (1.5.0-arm64-darwin)
|
223
229
|
standard (1.16.1)
|
224
230
|
rubocop (= 1.35.1)
|
@@ -226,19 +232,28 @@ GEM
|
|
226
232
|
standardrb (1.0.1)
|
227
233
|
standard
|
228
234
|
strscan (3.0.4)
|
235
|
+
tailwindcss-rails (2.0.14-aarch64-linux)
|
236
|
+
railties (>= 6.0.0)
|
237
|
+
tailwindcss-rails (2.0.14-arm64-darwin)
|
238
|
+
railties (>= 6.0.0)
|
229
239
|
thor (1.2.1)
|
230
240
|
timeout (0.3.0)
|
231
241
|
turbo-rails (1.1.1)
|
232
242
|
actionpack (>= 6.0.0)
|
233
243
|
activejob (>= 6.0.0)
|
234
244
|
railties (>= 6.0.0)
|
235
|
-
turbo_ready (0.0
|
245
|
+
turbo_ready (0.1.0)
|
236
246
|
rails (>= 6.1)
|
237
247
|
turbo-rails (>= 1.1)
|
238
248
|
tzinfo (2.0.5)
|
239
249
|
concurrent-ruby (~> 1.0)
|
240
|
-
unicode-display_width (2.
|
241
|
-
|
250
|
+
unicode-display_width (2.3.0)
|
251
|
+
web-console (4.2.0)
|
252
|
+
actionview (>= 6.0.0)
|
253
|
+
activemodel (>= 6.0.0)
|
254
|
+
bindex (>= 0.4.0)
|
255
|
+
railties (>= 6.0.0)
|
256
|
+
webdrivers (5.1.0)
|
242
257
|
nokogiri (~> 1.6)
|
243
258
|
rubyzip (>= 1.3.0)
|
244
259
|
selenium-webdriver (~> 4.0)
|
@@ -251,11 +266,13 @@ GEM
|
|
251
266
|
zeitwerk (2.6.0)
|
252
267
|
|
253
268
|
PLATFORMS
|
269
|
+
aarch64-linux
|
254
270
|
arm64-darwin-21
|
255
271
|
|
256
272
|
DEPENDENCIES
|
257
273
|
capybara
|
258
274
|
cuprite
|
275
|
+
foreman
|
259
276
|
importmap-rails
|
260
277
|
magic_frozen_string_literal
|
261
278
|
minitest-reporters
|
@@ -264,11 +281,14 @@ DEPENDENCIES
|
|
264
281
|
puma
|
265
282
|
rake
|
266
283
|
rexml
|
284
|
+
rouge
|
267
285
|
sprockets-rails
|
268
286
|
sqlite3
|
269
287
|
standardrb
|
288
|
+
tailwindcss-rails
|
270
289
|
turbo_ready
|
271
290
|
turbo_reflex!
|
291
|
+
web-console
|
272
292
|
webdrivers
|
273
293
|
|
274
294
|
BUNDLED WITH
|
data/README.md
CHANGED
@@ -117,14 +117,14 @@ TurboReflex is a lightweight Turbo Frame extension... which means that reactivit
|
|
117
117
|
|
118
118
|
```diff
|
119
119
|
# Gemfile
|
120
|
-
+gem "turbo_reflex", "~> 0.0.
|
120
|
+
+gem "turbo_reflex", "~> 0.0.3"
|
121
121
|
```
|
122
122
|
|
123
123
|
```diff
|
124
124
|
# package.json
|
125
125
|
"dependencies": {
|
126
126
|
"@hotwired/turbo-rails": ">=7.1",
|
127
|
-
+ "turbo_reflex": "^0.0.
|
127
|
+
+ "turbo_reflex": "^0.0.3"
|
128
128
|
```
|
129
129
|
|
130
130
|
*Be sure to install the __same version__ of the Ruby and JavaScript libraries.*
|
@@ -142,16 +142,12 @@ TurboReflex is a lightweight Turbo Frame extension... which means that reactivit
|
|
142
142
|
# app/views/layouts/application.html.erb
|
143
143
|
<html>
|
144
144
|
<head>
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
# /app/controllers/application_controller.rb
|
152
|
-
class ApplicationController < ActionController::Base
|
153
|
-
+ include TurboReflex::Controller
|
154
|
-
end
|
145
|
+
+ <%= turbo_reflex_meta_tag %>
|
146
|
+
</head>
|
147
|
+
<body>
|
148
|
+
+ <%= turbo_reflex_frame_tag %>
|
149
|
+
</body>
|
150
|
+
</html>
|
155
151
|
```
|
156
152
|
|
157
153
|
## Usage
|
@@ -163,7 +159,7 @@ This example illustrates how to use TurboReflex to manage upvotes on a Post.
|
|
163
159
|
```erb
|
164
160
|
<!-- app/views/posts/show.html.erb -->
|
165
161
|
<%= turbo_frame_tag dom_id(@post) do %>
|
166
|
-
<a href="#" data-turbo-reflex="
|
162
|
+
<a href="#" data-turbo-reflex="PostReflex#upvote">Upvote</a>
|
167
163
|
Upvote Count: <%= @post.votes >
|
168
164
|
<% end %>
|
169
165
|
```
|
@@ -172,7 +168,7 @@ This example illustrates how to use TurboReflex to manage upvotes on a Post.
|
|
172
168
|
|
173
169
|
```ruby
|
174
170
|
# app/reflexes/posts_reflex.rb
|
175
|
-
class
|
171
|
+
class PostReflex < TurboReflex::Base
|
176
172
|
def upvote
|
177
173
|
Post.find(controller.params[:id]).increment! :votes
|
178
174
|
end
|
@@ -221,18 +217,10 @@ TurboReflex supports the following lifecycle events.
|
|
221
217
|
|
222
218
|
### Targeting Frames
|
223
219
|
|
224
|
-
|
225
|
-
but you can also explicitly target other frames.
|
226
|
-
|
227
|
-
1. Look for `data-turbo-reflex-frame` on the reflex elemnt
|
228
|
-
|
229
|
-
```erb
|
230
|
-
<input type="checkbox"
|
231
|
-
data-turbo-reflex="ExampleReflex#work"
|
232
|
-
data-turbo-reflex-frame="some-frame-id">
|
233
|
-
```
|
220
|
+
TurboReflex targets the [`closest`](https://developer.mozilla.org/en-US/docs/Web/API/Element/closest) `<turbo-frame>` element by default,
|
221
|
+
but you can also explicitly target other frames just like you normally would with Turbo Frames.
|
234
222
|
|
235
|
-
|
223
|
+
1. Look for `data-turbo-frame` on the reflex element
|
236
224
|
|
237
225
|
```erb
|
238
226
|
<input type="checkbox"
|
@@ -240,7 +228,7 @@ but you can also explicitly target other frames.
|
|
240
228
|
data-turbo-frame="some-frame-id">
|
241
229
|
```
|
242
230
|
|
243
|
-
|
231
|
+
1. Find the closest `<turbo-frame>` to the reflex element
|
244
232
|
|
245
233
|
```erb
|
246
234
|
<turbo-frame id="example-frame">
|
@@ -442,6 +430,8 @@ The best way to learn this stuff is from working examples.
|
|
442
430
|
Be sure to clone the library and run the test application.
|
443
431
|
Then dig into the internals.
|
444
432
|
|
433
|
+
#### Running Locally
|
434
|
+
|
445
435
|
```sh
|
446
436
|
git clone https://github.com/hopsoft/turbo_reflex.git
|
447
437
|
cd turbo_reflex
|
@@ -451,6 +441,17 @@ bin/rails s
|
|
451
441
|
# View the app in a browser at http://localhost:3000
|
452
442
|
```
|
453
443
|
|
444
|
+
#### Running in Docker
|
445
|
+
|
446
|
+
Docker users can get up and running even faster.
|
447
|
+
|
448
|
+
```sh
|
449
|
+
git clone https://github.com/hopsoft/turbo_reflex.git
|
450
|
+
cd turbo_reflex
|
451
|
+
docker compose up -d
|
452
|
+
# View the app in a browser at http://localhost:3000
|
453
|
+
```
|
454
|
+
|
454
455
|
You can review the implementation in [`test/dummy/app`](https://github.com/hopsoft/turbo_reflex/tree/main/test/dummy).
|
455
456
|
*Feel free to add some demos and submit a pull request while you're in there.*
|
456
457
|
|
@@ -462,13 +463,14 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
462
463
|
|
463
464
|
## Todos
|
464
465
|
|
466
|
+
- [ ] Consider falling back to the turbo-reflex-frame when a frame can't be identified
|
467
|
+
- [ ] Consider how to best support `link_to` with methods other than GET
|
468
|
+
- [ ] Update system tests for new demos
|
465
469
|
- [ ] Add tests for lifecycle events
|
466
470
|
- [ ] Add tests for select elements
|
467
471
|
- [ ] Add tests for checkbox elements
|
468
|
-
- [ ] Add controller tests
|
469
472
|
- [ ] Add tests for all variants of frame targeting
|
470
473
|
|
471
|
-
|
472
474
|
## Releasing
|
473
475
|
|
474
476
|
1. Run `yarn upgrade` and `bundle update` to pick up the latest
|
@@ -0,0 +1,2 @@
|
|
1
|
+
var l={beforeStart:"turbo-reflex:before-start",start:"turbo-reflex:start",finish:"turbo-reflex:finish",error:"turbo-reflex:error",missingFrameId:"turbo-reflex:missing-frame-id",missingFrame:"turbo-reflex:missing-frame",missingFrameSrc:"turbo-reflex:missing-frame-src"};function y(t,e=document,r={}){let n=new CustomEvent(t,{detail:r,cancelable:!0,bubbles:!0});e.dispatchEvent(n)}function L(){Object.values(l).forEach(t=>console.log(t))}var o={...l,dispatch:y,logEventNames:L};var c={};addEventListener("turbo:before-fetch-response",t=>{let e=t.target;c[e.id]=e.src;let{turboReflexActive:r,turboReflexElementId:n}=e.dataset;if(!r)return;let s=document.getElementById(n);delete e.dataset.turboReflexActive,delete e.dataset.turboReflexElementId,o.dispatch(o.finish,s||document,{frame:e,element:s||"Unknown! Missing id attribute."})});addEventListener("turbo:frame-load",t=>{let e=t.target;e.dataset.turboReflexSrc=c[e.id]||e.src||e.dataset.turboReflexSrc,delete c[e.id]});var S={get token(){return document.getElementById("turbo-reflex-token").getAttribute("content")}},f=S;function m(t){return t.closest("[data-turbo-reflex]")}function F(t){return t.closest("turbo-frame")}function b(t){let e=t.dataset.turboFrame;if(!e){let r=F(t);r&&(e=r.id)}return e||(console.error("The reflex element does not specify a frame!","Please move the reflex element inside a <turbo-frame> or set the 'data-turbo-frame' attribute.",t),o.dispatch(o.missingFrameId,t,{element:t})),e}function g(t){let e=document.getElementById(t);return e||(console.error(`The frame '${t}' does not exist!`),o.dispatch(o.missingFrame,document,{id:t})),e}function x(t){let e=t.dataset.turboReflexSrc||t.src;return e||(console.error(`The the 'src' for <turbo-frame id='${t.id}'> is unknown!`,"TurboReflex uses 'src' to (re)render frame content after the reflex is invoked.","Please set the 'src' or 'data-turbo-reflex-src' attribute on the <turbo-frame> element.",t),o.dispatch(o.missingFrameSrc,t,{frame:t})),e}function k(t,e={}){if(t.tagName.toLowerCase()!=="select")return e.value=t.value;if(!t.multiple)return e.value=t.options[t.selectedIndex].value;e.values=Array.from(t.options).reduce((r,n)=>(n.selected&&r.push(n.value),r),[])}function v(t){let e=Array.from(t.attributes).reduce((r,n)=>(r[n.name]=n.value,r),{});return e.tag=t.tagName,e.checked=t.checked,e.disabled=t.disabled,k(t,e),e}var a={},h;function p(t){h=t}function u(t,e){a[t]=e,document.addEventListener(t,h,!0)}function E(t,e){return e=e.toLowerCase(),a[t].includes(e)||!Object.values(a).flat().includes(e)&&a[t].includes("*")}function R(){console.log(a)}addEventListener("turbo:before-fetch-request",t=>{let e=t.target,{turboReflexActive:r}=e.dataset;if(!r)return;let{fetchOptions:n}=t.detail;n.headers["Turbo-Reflex"]=f.token});function I(t){let e=document.createElement("a");return e.href=t,new URL(e)}function A(t,e={}){e.token=f.token;let r=document.createElement("input");r.type="hidden",r.name="turbo_reflex",r.value=JSON.stringify(e),t.appendChild(r)}function C(t){let e,r,n,s;try{if(e=m(t.target),!e||!E(t.type,e.tagName)||(o.dispatch(o.beforeStart,e,{element:e}),r=b(e),!r)||(n=g(r),!n)||(s=x(n),!s))return;let i={frameId:r,element:v(e)};if(o.dispatch(o.start,e,{element:e,frameId:r,frame:n,frameSrc:s,payload:i}),n.dataset.turboReflexActive=!0,n.dataset.turboReflexElementId=e.id,e.tagName.toLowerCase()==="form")return A(e,i);t.preventDefault();let d=I(s);d.searchParams.set("turbo_reflex",JSON.stringify(i)),n.src=d.toString()}catch(i){console.error("TurboReflex encountered an unexpected error!",{element:e,frameId:r,frame:n,frameSrc:s,target:t.target},i),o.dispatch(o.error,e||document,{element:e,frameId:r,frame:n,frameSrc:s,error:i})}}p(C);u("change",["input","select","textarea"]);u("submit",["form"]);u("click",["*"]);var M={registerEvent:u,logRegisteredEvents:R,logLifecycleEventNames:o.logEventNames};export{M as default};
|
2
|
+
//# sourceMappingURL=turbo_reflex.js.map
|
@@ -0,0 +1,7 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"sources": ["../../javascript/lifecycle_events.js", "../../javascript/frame_sources.js", "../../javascript/security.js", "../../javascript/elements.js", "../../javascript/event_registry.js", "../../javascript/turbo_reflex.js"],
|
4
|
+
"sourcesContent": ["const events = {\n beforeStart: 'turbo-reflex:before-start',\n start: 'turbo-reflex:start',\n finish: 'turbo-reflex:finish',\n error: 'turbo-reflex:error',\n missingFrameId: 'turbo-reflex:missing-frame-id',\n missingFrame: 'turbo-reflex:missing-frame',\n missingFrameSrc: 'turbo-reflex:missing-frame-src'\n}\n\nfunction dispatch (name, target = document, detail = {}) {\n const event = new CustomEvent(name, {\n detail,\n cancelable: true,\n bubbles: true\n })\n target.dispatchEvent(event)\n}\n\nfunction logEventNames () {\n Object.values(events).forEach(name => console.log(name))\n}\n\nexport default { ...events, dispatch, logEventNames }\n", "import LifecycleEvents from './lifecycle_events'\nconst frameSources = {}\n\n// fires after receiving a turbo HTTP response\naddEventListener('turbo:before-fetch-response', event => {\n const frame = event.target\n frameSources[frame.id] = frame.src\n\n const { turboReflexActive, turboReflexElementId } = frame.dataset\n if (!turboReflexActive) return\n\n const element = document.getElementById(turboReflexElementId)\n delete frame.dataset.turboReflexActive\n delete frame.dataset.turboReflexElementId\n\n LifecycleEvents.dispatch(LifecycleEvents.finish, element || document, {\n frame,\n element: element || 'Unknown! Missing id attribute.'\n })\n})\n\n// fires when a frame element is navigated and finishes loading\naddEventListener('turbo:frame-load', event => {\n const frame = event.target\n frame.dataset.turboReflexSrc =\n frameSources[frame.id] || frame.src || frame.dataset.turboReflexSrc\n delete frameSources[frame.id]\n})\n", "const Security = {\n get token () {\n return document.getElementById('turbo-reflex-token').getAttribute('content')\n }\n}\n\nexport default Security\n", "import LifecycleEvents from './lifecycle_events'\n\nfunction findClosestReflex (element) {\n return element.closest('[data-turbo-reflex]')\n}\n\nfunction findClosestFrame (element) {\n return element.closest('turbo-frame')\n}\n\nfunction findFrameId (element) {\n let id = element.dataset.turboFrame\n if (!id) {\n const frame = findClosestFrame(element)\n if (frame) id = frame.id\n }\n if (!id) {\n console.error(\n `The reflex element does not specify a frame!`,\n `Please move the reflex element inside a <turbo-frame> or set the 'data-turbo-frame' attribute.`,\n element\n )\n LifecycleEvents.dispatch(LifecycleEvents.missingFrameId, element, {\n element\n })\n }\n return id\n}\n\nfunction findFrame (id) {\n const frame = document.getElementById(id)\n if (!frame) {\n console.error(`The frame '${id}' does not exist!`)\n LifecycleEvents.dispatch(LifecycleEvents.missingFrame, document, { id })\n }\n return frame\n}\n\nfunction findFrameSrc (frame) {\n const frameSrc = frame.dataset.turboReflexSrc || frame.src\n if (!frameSrc) {\n console.error(\n `The the 'src' for <turbo-frame id='${frame.id}'> is unknown!`,\n `TurboReflex uses 'src' to (re)render frame content after the reflex is invoked.`,\n `Please set the 'src' or 'data-turbo-reflex-src' attribute on the <turbo-frame> element.`,\n frame\n )\n LifecycleEvents.dispatch(LifecycleEvents.missingFrameSrc, frame, { frame })\n }\n return frameSrc\n}\n\nfunction assignElementValueToPayload (element, payload = {}) {\n if (element.tagName.toLowerCase() !== 'select')\n return (payload.value = element.value)\n\n if (!element.multiple)\n return (payload.value = element.options[element.selectedIndex].value)\n\n payload.values = Array.from(element.options).reduce((memo, option) => {\n if (option.selected) memo.push(option.value)\n return memo\n }, [])\n}\n\nfunction buildAttributePayload (element) {\n const payload = Array.from(element.attributes).reduce((memo, attr) => {\n memo[attr.name] = attr.value\n return memo\n }, {})\n\n payload.tag = element.tagName\n payload.checked = element.checked\n payload.disabled = element.disabled\n assignElementValueToPayload(element, payload)\n\n return payload\n}\n\nexport {\n findClosestReflex,\n findClosestFrame,\n findFrameId,\n findFrame,\n findFrameSrc,\n buildAttributePayload\n}\n", "const registeredEvents = {}\nlet eventListener\n\nfunction registerEventListener (fn) {\n eventListener = fn\n}\n\nfunction registerEvent (eventName, tagNames) {\n registeredEvents[eventName] = tagNames\n document.addEventListener(eventName, eventListener, true)\n}\n\nfunction isRegisteredEvent (eventName, tagName) {\n tagName = tagName.toLowerCase()\n return (\n registeredEvents[eventName].includes(tagName) ||\n (!Object.values(registeredEvents)\n .flat()\n .includes(tagName) &&\n registeredEvents[eventName].includes('*'))\n )\n}\n\nfunction logRegisteredEvents () {\n console.log(registeredEvents)\n}\n\nexport {\n registerEventListener,\n registerEvent,\n registeredEvents,\n isRegisteredEvent,\n logRegisteredEvents\n}\n", "import './frame_sources'\nimport Security from './security'\nimport LifecycleEvents from './lifecycle_events'\nimport {\n findClosestReflex,\n findClosestFrame,\n findFrameId,\n findFrame,\n findFrameSrc,\n buildAttributePayload\n} from './elements'\nimport {\n registerEventListener,\n registerEvent,\n registeredEvents,\n isRegisteredEvent,\n logRegisteredEvents\n} from './event_registry'\n\n// fires before making a turbo HTTP request\naddEventListener('turbo:before-fetch-request', event => {\n const frame = event.target\n const { turboReflexActive } = frame.dataset\n if (!turboReflexActive) return\n const { fetchOptions } = event.detail\n fetchOptions.headers['Turbo-Reflex'] = Security.token\n})\n\nfunction buildURL (urlString) {\n const a = document.createElement('a')\n a.href = urlString\n return new URL(a)\n}\n\nfunction invokeFormReflex (form, payload = {}) {\n payload.token = Security.token\n const input = document.createElement('input')\n input.type = 'hidden'\n input.name = 'turbo_reflex'\n input.value = JSON.stringify(payload)\n form.appendChild(input)\n}\n\nfunction invokeReflex (event) {\n let element, frameId, frame, frameSrc\n try {\n element = findClosestReflex(event.target)\n if (!element) return\n\n if (!isRegisteredEvent(event.type, element.tagName)) return\n\n LifecycleEvents.dispatch(LifecycleEvents.beforeStart, element, { element })\n\n frameId = findFrameId(element)\n if (!frameId) return\n\n frame = findFrame(frameId)\n if (!frame) return\n\n frameSrc = findFrameSrc(frame)\n if (!frameSrc) return\n\n const payload = {\n frameId: frameId,\n element: buildAttributePayload(element)\n }\n\n LifecycleEvents.dispatch(LifecycleEvents.start, element, {\n element,\n frameId,\n frame,\n frameSrc,\n payload\n })\n frame.dataset.turboReflexActive = true\n frame.dataset.turboReflexElementId = element.id\n\n if (element.tagName.toLowerCase() === 'form')\n return invokeFormReflex(element, payload)\n\n event.preventDefault()\n const frameURL = buildURL(frameSrc)\n frameURL.searchParams.set('turbo_reflex', JSON.stringify(payload))\n frame.src = frameURL.toString()\n } catch (error) {\n console.error(\n `TurboReflex encountered an unexpected error!`,\n { element, frameId, frame, frameSrc, target: event.target },\n error\n )\n LifecycleEvents.dispatch(LifecycleEvents.error, element || document, {\n element,\n frameId,\n frame,\n frameSrc,\n error\n })\n }\n}\n\n// wire things up and setup default events\nregisterEventListener(invokeReflex)\nregisterEvent('change', ['input', 'select', 'textarea'])\nregisterEvent('submit', ['form'])\nregisterEvent('click', ['*'])\n\nexport default {\n registerEvent,\n logRegisteredEvents,\n logLifecycleEventNames: LifecycleEvents.logEventNames\n}\n"],
|
5
|
+
"mappings": "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",
|
6
|
+
"names": ["events", "dispatch", "name", "target", "detail", "event", "logEventNames", "lifecycle_events_default", "frameSources", "event", "frame", "turboReflexActive", "turboReflexElementId", "element", "lifecycle_events_default", "Security", "security_default", "findClosestReflex", "element", "findClosestFrame", "findFrameId", "id", "frame", "lifecycle_events_default", "findFrame", "findFrameSrc", "frameSrc", "assignElementValueToPayload", "payload", "memo", "option", "buildAttributePayload", "attr", "registeredEvents", "eventListener", "registerEventListener", "fn", "registerEvent", "eventName", "tagNames", "isRegisteredEvent", "tagName", "logRegisteredEvents", "event", "frame", "turboReflexActive", "fetchOptions", "security_default", "buildURL", "urlString", "a", "invokeFormReflex", "form", "payload", "input", "invokeReflex", "element", "frameId", "frameSrc", "findClosestReflex", "isRegisteredEvent", "lifecycle_events_default", "findFrameId", "findFrame", "findFrameSrc", "buildAttributePayload", "frameURL", "error", "registerEventListener", "registerEvent", "turbo_reflex_default", "logRegisteredEvents"]
|
7
|
+
}
|
Binary file
|
@@ -8,6 +8,7 @@ module TurboReflex::Controller
|
|
8
8
|
after_action :append_turbo_reflex_turbo_streams, if: :turbo_reflex_performed?
|
9
9
|
after_action :assign_turbo_reflex_token
|
10
10
|
helper_method :turbo_reflex_meta_tag, :turbo_reflex_performed?, :turbo_reflex_requested?
|
11
|
+
# helper TurboReflex::TurboReflexHelper # only required if we isolate_namespace
|
11
12
|
end
|
12
13
|
|
13
14
|
def turbo_reflex_meta_tag
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class TurboReflex::TurboReflexesController < TurboReflex::ApplicationController
|
4
|
+
def show
|
5
|
+
return head(:ok) unless turbo_reflex_instance&.turbo_streams.present?
|
6
|
+
render html: view_context.turbo_reflex_frame_tag do
|
7
|
+
turbo_reflex_instance.turbo_streams.map(&:to_s).join
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
data/app/javascript/elements.js
CHANGED
@@ -9,7 +9,7 @@ function findClosestFrame (element) {
|
|
9
9
|
}
|
10
10
|
|
11
11
|
function findFrameId (element) {
|
12
|
-
let id = element.dataset.
|
12
|
+
let id = element.dataset.turboFrame
|
13
13
|
if (!id) {
|
14
14
|
const frame = findClosestFrame(element)
|
15
15
|
if (frame) id = frame.id
|
@@ -17,7 +17,7 @@ function findFrameId (element) {
|
|
17
17
|
if (!id) {
|
18
18
|
console.error(
|
19
19
|
`The reflex element does not specify a frame!`,
|
20
|
-
`Please move the reflex element inside a <turbo-frame> or set the 'data-turbo-
|
20
|
+
`Please move the reflex element inside a <turbo-frame> or set the 'data-turbo-frame' attribute.`,
|
21
21
|
element
|
22
22
|
)
|
23
23
|
LifecycleEvents.dispatch(LifecycleEvents.missingFrameId, element, {
|
data/bin/standardize
CHANGED
@@ -3,3 +3,5 @@
|
|
3
3
|
bundle exec magic_frozen_string_literal
|
4
4
|
bundle exec standardrb --fix
|
5
5
|
yarn run prettier-standard "app/javascript/**/*.js"
|
6
|
+
yarn run rustywind --write test/dummy/app
|
7
|
+
yarn run rustywind --write --custom-regex "(:\s[\"'])(.+)[\"']" test/dummy/app/views/_tailwind.yml.erb
|
data/config/routes.rb
ADDED
data/docker-compose.yml
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
version: "3.9"
|
2
|
+
|
3
|
+
x-default-app: &default_app
|
4
|
+
build: .
|
5
|
+
image: turbo_reflex
|
6
|
+
tty: true
|
7
|
+
stdin_open: true
|
8
|
+
working_dir: /opt/turbo_reflex/test/dummy
|
9
|
+
environment:
|
10
|
+
RAILS_ENV: development
|
11
|
+
volumes:
|
12
|
+
- bundle:/usr/local/bundle:delegated
|
13
|
+
- node_modules:/opt/turbo_reflex/node_modules
|
14
|
+
|
15
|
+
volumes:
|
16
|
+
bundle:
|
17
|
+
node_modules:
|
18
|
+
|
19
|
+
services:
|
20
|
+
# ----------------------------------------------------------------------------
|
21
|
+
# Shell - Intended for tinkering and running misc commands
|
22
|
+
# ----------------------------------------------------------------------------
|
23
|
+
shell:
|
24
|
+
<<: *default_app
|
25
|
+
container_name: turbo_reflex-shell
|
26
|
+
command: /bin/bash -c "tail -f /dev/null"
|
27
|
+
|
28
|
+
# ----------------------------------------------------------------------------
|
29
|
+
# Web - Runs the test/dummy Rails app
|
30
|
+
# ----------------------------------------------------------------------------
|
31
|
+
web:
|
32
|
+
<<: *default_app
|
33
|
+
container_name: turbo_reflex-web
|
34
|
+
ports:
|
35
|
+
- 3000:3000
|
36
|
+
command: >
|
37
|
+
/bin/bash -c "git pull --no-rebase github main &&
|
38
|
+
cd /opt/turbo_reflex &&
|
39
|
+
bundle &&
|
40
|
+
yarn &&
|
41
|
+
cd /opt/turbo_reflex/test/dummy &&
|
42
|
+
rm -f tmp/pids/server.pid &&
|
43
|
+
bin/rails db:create db:migrate &&
|
44
|
+
bin/rails assets:clobber &&
|
45
|
+
bin/rails assets:precompile &&
|
46
|
+
bin/rails s --binding=0.0.0.0 --port=3000"
|
data/fly.toml
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# fly.toml file generated for turbo-reflex on 2022-09-19T05:16:01-06:00
|
2
|
+
|
3
|
+
app = "turbo-reflex"
|
4
|
+
kill_signal = "SIGINT"
|
5
|
+
kill_timeout = 5
|
6
|
+
processes = []
|
7
|
+
|
8
|
+
[env]
|
9
|
+
|
10
|
+
[experimental]
|
11
|
+
allowed_public_ports = []
|
12
|
+
auto_rollback = true
|
13
|
+
|
14
|
+
[[services]]
|
15
|
+
http_checks = []
|
16
|
+
internal_port = 3000
|
17
|
+
processes = ["app"]
|
18
|
+
protocol = "tcp"
|
19
|
+
script_checks = []
|
20
|
+
[services.concurrency]
|
21
|
+
hard_limit = 25
|
22
|
+
soft_limit = 20
|
23
|
+
type = "connections"
|
24
|
+
|
25
|
+
[[services.ports]]
|
26
|
+
force_https = true
|
27
|
+
handlers = ["http"]
|
28
|
+
port = 80
|
29
|
+
|
30
|
+
[[services.ports]]
|
31
|
+
handlers = ["tls", "http"]
|
32
|
+
port = 443
|
33
|
+
|
34
|
+
[[services.tcp_checks]]
|
35
|
+
grace_period = "1s"
|
36
|
+
interval = "15s"
|
37
|
+
restart_limit = 0
|
38
|
+
timeout = "2s"
|
data/lib/turbo_reflex/base.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
class TurboReflex::Base
|
4
4
|
attr_reader :controller, :turbo_streams
|
5
5
|
|
6
|
+
delegate :render, to: :renderer
|
7
|
+
|
6
8
|
def initialize(controller)
|
7
9
|
@controller = controller
|
8
10
|
@turbo_streams = Set.new
|
@@ -29,4 +31,8 @@ class TurboReflex::Base
|
|
29
31
|
def turbo_stream
|
30
32
|
@turbo_stream ||= Turbo::Streams::TagBuilder.new(controller.view_context)
|
31
33
|
end
|
34
|
+
|
35
|
+
def renderer
|
36
|
+
ActionController::Renderer.for controller.class, controller.request.env
|
37
|
+
end
|
32
38
|
end
|
data/lib/turbo_reflex/engine.rb
CHANGED
@@ -2,8 +2,23 @@
|
|
2
2
|
|
3
3
|
require "turbo-rails"
|
4
4
|
require_relative "version"
|
5
|
+
require_relative "errors"
|
5
6
|
require_relative "sanitizer"
|
6
7
|
require_relative "base"
|
7
8
|
|
8
9
|
class TurboReflex::Engine < ::Rails::Engine
|
10
|
+
# isolate_namespace TurboReflex
|
11
|
+
|
12
|
+
config.turbo_reflex = ActiveSupport::OrderedOptions.new
|
13
|
+
initializer "turbo_reflex.configuration" do
|
14
|
+
config.to_prepare do |app|
|
15
|
+
::ApplicationController.send :include, TurboReflex::Controller
|
16
|
+
end
|
17
|
+
|
18
|
+
config.after_initialize do |app|
|
19
|
+
app.routes.draw do
|
20
|
+
mount TurboReflex::Engine => "/turbo_reflex"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
9
24
|
end
|
data/lib/turbo_reflex/version.rb
CHANGED
data/package.json
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
{
|
2
2
|
"name": "turbo_reflex",
|
3
|
-
"version": "0.0.
|
3
|
+
"version": "0.0.3",
|
4
4
|
"description": "Reflexes for Turbo Frames that help you build robust reactive applications",
|
5
|
-
"main": "app/
|
5
|
+
"main": "app/javascript/turbo_reflex.js",
|
6
6
|
"repository": "https://github.com/hopsoft/turbo_reflex",
|
7
7
|
"author": "Nate Hopkins (hopsoft) <natehop@gmail.com>",
|
8
8
|
"license": "MIT",
|
@@ -12,9 +12,11 @@
|
|
12
12
|
"devDependencies": {
|
13
13
|
"esbuild": "^0.15.7",
|
14
14
|
"eslint": "^8.19.0",
|
15
|
-
"
|
15
|
+
"flowbite": "^1.5.3",
|
16
|
+
"prettier-standard": "^16.4.1",
|
17
|
+
"rustywind": "^0.15.1"
|
16
18
|
},
|
17
19
|
"scripts": {
|
18
|
-
"build": "esbuild app/javascript/turbo_reflex.js --bundle --minify --sourcemap --format=esm --outfile=app/assets/builds/turbo_reflex.
|
20
|
+
"build": "esbuild app/javascript/turbo_reflex.js --bundle --minify --sourcemap --format=esm --outfile=app/assets/builds/turbo_reflex.js"
|
19
21
|
}
|
20
22
|
}
|