futurism 0.5.4 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +70 -17
- data/lib/futurism.rb +10 -1
- data/lib/futurism.rb~ +10 -0
- data/lib/futurism/channel.rb +4 -20
- data/lib/futurism/channel.rb~ +19 -9
- data/lib/futurism/helpers.rb +17 -8
- data/lib/futurism/helpers.rb~ +14 -6
- data/lib/futurism/message_verifier.rb +11 -0
- data/lib/futurism/resolver/controller.rb +17 -0
- data/lib/futurism/resolver/controller.rb~ +17 -0
- data/lib/futurism/resolver/controller/renderer.rb +57 -0
- data/lib/futurism/resolver/controller/renderer.rb~ +57 -0
- data/lib/futurism/resolver/resources.rb +68 -0
- data/lib/futurism/resolver/resources.rb~ +73 -0
- data/lib/futurism/version.rb +1 -1
- data/lib/futurism/version.rb~ +3 -0
- metadata +10 -31
- data/app/assets/config/futurism_manifest.js +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75dd023300659792f3dd9e114727b0003204ed6b2e9e990413fcc1ca82971fba
|
4
|
+
data.tar.gz: b73280cb140625612fc5e7188e301f98e5be0eb19e7359c7786fae8b4a8f4b8c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9285da73bb00137f7aea08b2171d370b032681abd79b8d37e652b1aef546159a2d568ecc695ecaeb0a7f3a8f4a74abb0a6a310dca9969021923d4590c0fd03b
|
7
|
+
data.tar.gz: ae425d91dcae19d847105b5633a0f0b434166d5cb45f9aed14bfccb2a07cc9661594c2a814d072b541b30d7b401c6273919e6c199ffcdb38c146d6fc8f8a6a74
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Futurism
|
2
2
|
[![Twitter follow](https://img.shields.io/twitter/follow/julian_rubisch?style=social)](https://twitter.com/julian_rubisch)
|
3
3
|
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
4
|
-
[![All Contributors](https://img.shields.io/badge/all_contributors-
|
4
|
+
[![All Contributors](https://img.shields.io/badge/all_contributors-15-orange.svg?style=flat-square)](#contributors-)
|
5
5
|
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
6
6
|
Lazy-load Rails partials via CableReady
|
7
7
|
|
@@ -33,7 +33,7 @@ Lazy-load Rails partials via CableReady
|
|
33
33
|
|
34
34
|
## Facts
|
35
35
|
- only one dependency: CableReady
|
36
|
-
- bundle size (without CableReady) is around [~
|
36
|
+
- bundle size (without CableReady) is around [~2.46kB](https://bundlephobia.com/result?p=@minthesize/futurism@0.7.2)
|
37
37
|
|
38
38
|
### Browser Support
|
39
39
|
|
@@ -124,6 +124,22 @@ Collection rendering is also possible:
|
|
124
124
|
<% end %>
|
125
125
|
```
|
126
126
|
|
127
|
+
#### Specifying Controller to Render
|
128
|
+
|
129
|
+
You can also pass in the controller that will be used to render the partial.
|
130
|
+
|
131
|
+
```erb
|
132
|
+
<%= futurize partial: "items/card", collection: @cards, controller: MyController, extends: :div do %>
|
133
|
+
<div class="spinner"></div>
|
134
|
+
<% end %>
|
135
|
+
```
|
136
|
+
|
137
|
+
By default (i.e. not passing in a value), futurize will use `ApplicationController`, but you may override by setting the Futurism default controller in an initializer, for example `config/initializers/futurism.rb`.
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
Futurism.default_controller = "MyController" # to avoid the controller from trying to autoload at boot, provide as a string
|
141
|
+
```
|
142
|
+
|
127
143
|
### HTML Options
|
128
144
|
|
129
145
|
You can pass a hash of attribute/value pairs which will be mixed into the HTML markup for the placeholder element. This is important for layouts that require elements to have dimensionality. For example, many scripts calculate size based on element height and width. This option ensures that your elements have integrity, even if they are gone before you see them.
|
@@ -241,6 +257,39 @@ to your environments.
|
|
241
257
|
|
242
258
|
## Contributing
|
243
259
|
|
260
|
+
### Get local environment setup
|
261
|
+
|
262
|
+
Below are a set of instructions that may help you get a local development environment working
|
263
|
+
|
264
|
+
```shell
|
265
|
+
# Get the gem/npm package source locally
|
266
|
+
git clone futurism
|
267
|
+
cd futurism/javascript
|
268
|
+
yarn install # install all of the npm package's dependencies
|
269
|
+
yarn link # set the local machine's futurism npm package's lookup to this local path
|
270
|
+
|
271
|
+
# Setup a sample project, use the information below directly or use your own project
|
272
|
+
git clone https://github.com/leastbad/stimulus_reflex_harness.git
|
273
|
+
cd stimulus_reflex_harness
|
274
|
+
git checkout futurism
|
275
|
+
# Edit Gemfile to point point to local gem (e.g. `gem "futurism", path: "../futurism"`)
|
276
|
+
# yarn link @minthesize/futurism
|
277
|
+
|
278
|
+
|
279
|
+
# Do your work, Submit PR, Profit!
|
280
|
+
|
281
|
+
|
282
|
+
# To stop using your local version of futurism
|
283
|
+
# change your Gemfile back to the published (e.g. `gem "futurism"`)
|
284
|
+
cd path/to/futurism/javascript
|
285
|
+
# Stop using the local npm package
|
286
|
+
yarn unlink
|
287
|
+
|
288
|
+
# Instruct your project to reinstall the published version of the npm package
|
289
|
+
cd path/to/project
|
290
|
+
yarn install --force
|
291
|
+
```
|
292
|
+
|
244
293
|
## License
|
245
294
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
246
295
|
|
@@ -253,27 +302,31 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|
253
302
|
<!-- markdownlint-disable -->
|
254
303
|
<table>
|
255
304
|
<tr>
|
256
|
-
<td align="center"><a href="http://www.julianrubisch.at"><img src="https://avatars0.githubusercontent.com/u/4352208?v=4" width="100px;" alt=""/><br /><sub><b>Julian Rubisch</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=julianrubisch" title="Code">💻</a></td>
|
257
|
-
<td align="center"><a href="https://github.com/darkrubyist"><img src="https://avatars2.githubusercontent.com/u/11207292?v=4" width="100px;" alt=""/><br /><sub><b>darkrubyist</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=darkrubyist" title="Code">💻</a> <a href="https://github.com/julianrubisch/futurism/commits?author=darkrubyist" title="Documentation">📖</a></td>
|
258
|
-
<td align="center"><a href="https://ParamagicDev.github.io/portfolio"><img src="https://avatars2.githubusercontent.com/u/26425882?v=4" width="100px;" alt=""/><br /><sub><b>Konnor Rogers</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=ParamagicDev" title="Code">💻</a></td>
|
259
|
-
<td align="center"><a href="https://www.andrewm.codes"><img src="https://avatars1.githubusercontent.com/u/18423853?v=4" width="100px;" alt=""/><br /><sub><b>Andrew Mason</b></sub></a><br /><a href="#maintenance-andrewmcodes" title="Maintenance">🚧</a></td>
|
260
|
-
<td align="center"><a href="http://gorails.com"><img src="https://avatars1.githubusercontent.com/u/67093?v=4" width="100px;" alt=""/><br /><sub><b>Chris Oliver</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=excid3" title="Code">💻</a> <a href="https://github.com/julianrubisch/futurism/pulls?q=is%3Apr+reviewed-by%3Aexcid3" title="Reviewed Pull Requests">👀</a></td>
|
261
|
-
<td align="center"><a href="https://github.com/leastbad"><img src="https://avatars2.githubusercontent.com/u/38150464?v=4" width="100px;" alt=""/><br /><sub><b>leastbad</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=leastbad" title="Code">💻</a> <a href="https://github.com/julianrubisch/futurism/pulls?q=is%3Apr+reviewed-by%3Aleastbad" title="Reviewed Pull Requests">👀</a></td>
|
262
|
-
<td align="center"><a href="http://code.digimonkey.com"><img src="https://avatars0.githubusercontent.com/u/74207?v=4" width="100px;" alt=""/><br /><sub><b>M. E. Patterson</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/issues?q=author%3Amepatterson" title="Bug reports">🐛</a></td>
|
305
|
+
<td align="center"><a href="http://www.julianrubisch.at"><img src="https://avatars0.githubusercontent.com/u/4352208?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Julian Rubisch</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=julianrubisch" title="Code">💻</a></td>
|
306
|
+
<td align="center"><a href="https://github.com/darkrubyist"><img src="https://avatars2.githubusercontent.com/u/11207292?v=4?s=100" width="100px;" alt=""/><br /><sub><b>darkrubyist</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=darkrubyist" title="Code">💻</a> <a href="https://github.com/julianrubisch/futurism/commits?author=darkrubyist" title="Documentation">📖</a></td>
|
307
|
+
<td align="center"><a href="https://ParamagicDev.github.io/portfolio"><img src="https://avatars2.githubusercontent.com/u/26425882?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Konnor Rogers</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=ParamagicDev" title="Code">💻</a></td>
|
308
|
+
<td align="center"><a href="https://www.andrewm.codes"><img src="https://avatars1.githubusercontent.com/u/18423853?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Andrew Mason</b></sub></a><br /><a href="#maintenance-andrewmcodes" title="Maintenance">🚧</a></td>
|
309
|
+
<td align="center"><a href="http://gorails.com"><img src="https://avatars1.githubusercontent.com/u/67093?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Chris Oliver</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=excid3" title="Code">💻</a> <a href="https://github.com/julianrubisch/futurism/pulls?q=is%3Apr+reviewed-by%3Aexcid3" title="Reviewed Pull Requests">👀</a></td>
|
310
|
+
<td align="center"><a href="https://github.com/leastbad"><img src="https://avatars2.githubusercontent.com/u/38150464?v=4?s=100" width="100px;" alt=""/><br /><sub><b>leastbad</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=leastbad" title="Code">💻</a> <a href="https://github.com/julianrubisch/futurism/pulls?q=is%3Apr+reviewed-by%3Aleastbad" title="Reviewed Pull Requests">👀</a></td>
|
311
|
+
<td align="center"><a href="http://code.digimonkey.com"><img src="https://avatars0.githubusercontent.com/u/74207?v=4?s=100" width="100px;" alt=""/><br /><sub><b>M. E. Patterson</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/issues?q=author%3Amepatterson" title="Bug reports">🐛</a></td>
|
263
312
|
</tr>
|
264
313
|
<tr>
|
265
|
-
<td align="center"><a href="http://fractaledmind.com"><img src="https://avatars3.githubusercontent.com/u/5077225?v=4" width="100px;" alt=""/><br /><sub><b>Stephen Margheim</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=fractaledmind" title="Code">💻</a></td>
|
266
|
-
<td align="center"><a href="http://hass.codes"><img src="https://avatars2.githubusercontent.com/u/1064205?v=4" width="100px;" alt=""/><br /><sub><b>Hassanin Ahmed</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=sas1ni69" title="Code">💻</a></td>
|
267
|
-
<td align="center"><a href="https://marcoroth.dev"><img src="https://avatars2.githubusercontent.com/u/6411752?v=4" width="100px;" alt=""/><br /><sub><b>Marco Roth</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=marcoroth" title="Code">💻</a></td>
|
268
|
-
<td align="center"><a href="https://viedit.com"><img src="https://avatars1.githubusercontent.com/u/49990587?v=4" width="100px;" alt=""/><br /><sub><b>Viedit com</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=vieditcom" title="Documentation">📖</a></td>
|
269
|
-
<td align="center"><a href="http://scottbarrow.ca"><img src="https://avatars2.githubusercontent.com/u/5571736?v=4" width="100px;" alt=""/><br /><sub><b>Scott Barrow</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=scottbarrow" title="Code">💻</a></td>
|
270
|
-
<td align="center"><a href="http://domchristie.co.uk"><img src="https://avatars0.githubusercontent.com/u/111734?v=4" width="100px;" alt=""/><br /><sub><b>Dom Christie</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/pulls?q=is%3Apr+reviewed-by%3Adomchristie" title="Reviewed Pull Requests">👀</a></td>
|
271
|
-
<td align="center"><a href="http://www.rickychilcott.com"><img src="https://avatars1.githubusercontent.com/u/445759?v=4" width="100px;" alt=""/><br /><sub><b>Ricky Chilcott</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/pulls?q=is%3Apr+reviewed-by%3Arickychilcott" title="Reviewed Pull Requests">👀</a></td>
|
314
|
+
<td align="center"><a href="http://fractaledmind.com"><img src="https://avatars3.githubusercontent.com/u/5077225?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Stephen Margheim</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=fractaledmind" title="Code">💻</a></td>
|
315
|
+
<td align="center"><a href="http://hass.codes"><img src="https://avatars2.githubusercontent.com/u/1064205?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Hassanin Ahmed</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=sas1ni69" title="Code">💻</a></td>
|
316
|
+
<td align="center"><a href="https://marcoroth.dev"><img src="https://avatars2.githubusercontent.com/u/6411752?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Marco Roth</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=marcoroth" title="Code">💻</a></td>
|
317
|
+
<td align="center"><a href="https://viedit.com"><img src="https://avatars1.githubusercontent.com/u/49990587?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Viedit com</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=vieditcom" title="Documentation">📖</a></td>
|
318
|
+
<td align="center"><a href="http://scottbarrow.ca"><img src="https://avatars2.githubusercontent.com/u/5571736?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Scott Barrow</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=scottbarrow" title="Code">💻</a></td>
|
319
|
+
<td align="center"><a href="http://domchristie.co.uk"><img src="https://avatars0.githubusercontent.com/u/111734?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dom Christie</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/pulls?q=is%3Apr+reviewed-by%3Adomchristie" title="Reviewed Pull Requests">👀</a></td>
|
320
|
+
<td align="center"><a href="http://www.rickychilcott.com"><img src="https://avatars1.githubusercontent.com/u/445759?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ricky Chilcott</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/pulls?q=is%3Apr+reviewed-by%3Arickychilcott" title="Reviewed Pull Requests">👀</a></td>
|
321
|
+
</tr>
|
322
|
+
<tr>
|
323
|
+
<td align="center"><a href="https://github.com/mansakondo"><img src="https://avatars.githubusercontent.com/u/47113995?v=4?s=100" width="100px;" alt=""/><br /><sub><b>mansakondo</b></sub></a><br /><a href="https://github.com/julianrubisch/futurism/commits?author=mansakondo" title="Code">💻</a></td>
|
272
324
|
</tr>
|
273
325
|
</table>
|
274
326
|
|
275
|
-
<!-- markdownlint-
|
327
|
+
<!-- markdownlint-restore -->
|
276
328
|
<!-- prettier-ignore-end -->
|
329
|
+
|
277
330
|
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
278
331
|
|
279
332
|
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
data/lib/futurism.rb
CHANGED
@@ -2,6 +2,10 @@ require "rails"
|
|
2
2
|
require "action_cable"
|
3
3
|
require "cable_ready"
|
4
4
|
require "futurism/engine"
|
5
|
+
require "futurism/message_verifier"
|
6
|
+
require "futurism/resolver/resources"
|
7
|
+
require "futurism/resolver/controller"
|
8
|
+
require "futurism/resolver/controller/renderer"
|
5
9
|
require "futurism/channel"
|
6
10
|
require "futurism/helpers"
|
7
11
|
|
@@ -10,7 +14,12 @@ module Futurism
|
|
10
14
|
|
11
15
|
autoload :Helpers, "futurism/helpers"
|
12
16
|
|
13
|
-
mattr_accessor :skip_in_test
|
17
|
+
mattr_accessor :skip_in_test, default: false
|
18
|
+
|
19
|
+
mattr_writer :default_controller
|
20
|
+
def self.default_controller
|
21
|
+
(@@default_controller || "::ApplicationController").to_s.constantize
|
22
|
+
end
|
14
23
|
|
15
24
|
ActiveSupport.on_load(:action_view) {
|
16
25
|
include Futurism::Helpers
|
data/lib/futurism.rb~
CHANGED
@@ -2,6 +2,9 @@ require "rails"
|
|
2
2
|
require "action_cable"
|
3
3
|
require "cable_ready"
|
4
4
|
require "futurism/engine"
|
5
|
+
require "futurism/message_verifier"
|
6
|
+
require "futurism/resolver/controller"
|
7
|
+
require "futurism/resolver/controller/renderer"
|
5
8
|
require "futurism/channel"
|
6
9
|
require "futurism/helpers"
|
7
10
|
|
@@ -10,6 +13,13 @@ module Futurism
|
|
10
13
|
|
11
14
|
autoload :Helpers, "futurism/helpers"
|
12
15
|
|
16
|
+
mattr_accessor :skip_in_test, default: false
|
17
|
+
|
18
|
+
mattr_writer :default_controller
|
19
|
+
def self.default_controller
|
20
|
+
(@@default_controller || "::ApplicationController").to_s.constantize
|
21
|
+
end
|
22
|
+
|
13
23
|
ActiveSupport.on_load(:action_view) {
|
14
24
|
include Futurism::Helpers
|
15
25
|
}
|
data/lib/futurism/channel.rb
CHANGED
@@ -15,33 +15,17 @@ module Futurism
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def receive(data)
|
18
|
-
resources = data.fetch_values("signed_params", "sgids") { |
|
18
|
+
resources = data.fetch_values("signed_params", "sgids", "signed_controllers", "urls") { |_key| Array.new(data["signed_params"].length, nil) }.transpose
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
resources.each do |signed_params, sgid|
|
24
|
-
selector = "[data-signed-params='#{signed_params}']"
|
25
|
-
selector << "[data-sgid='#{sgid}']" if sgid.present?
|
20
|
+
resolver = Resolver::Resources.new(resource_definitions: resources, connection: connection, params: @params)
|
21
|
+
resolver.resolve do |selector, html|
|
26
22
|
cable_ready[stream_name].outer_html(
|
27
23
|
selector: selector,
|
28
|
-
html:
|
24
|
+
html: html
|
29
25
|
)
|
30
26
|
end
|
31
27
|
|
32
28
|
cable_ready.broadcast
|
33
29
|
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def resource(signed_params:, sgid:)
|
38
|
-
return GlobalID::Locator.locate_signed(sgid) if sgid.present?
|
39
|
-
|
40
|
-
Rails
|
41
|
-
.application
|
42
|
-
.message_verifier("futurism")
|
43
|
-
.verify(signed_params)
|
44
|
-
.deep_transform_values { |value| value.is_a?(String) && value.start_with?("gid://") ? GlobalID::Locator.locate(value) : value }
|
45
|
-
end
|
46
30
|
end
|
47
31
|
end
|
data/lib/futurism/channel.rb~
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Futurism
|
2
2
|
class Channel < ActionCable::Channel::Base
|
3
3
|
include CableReady::Broadcaster
|
4
|
+
include Futurism::MessageVerifier
|
4
5
|
|
5
6
|
def stream_name
|
6
7
|
ids = connection.identifiers.map { |identifier| send(identifier).try(:id) || send(identifier) }
|
@@ -15,17 +16,28 @@ module Futurism
|
|
15
16
|
end
|
16
17
|
|
17
18
|
def receive(data)
|
18
|
-
resources = data.fetch_values("signed_params", "sgids") { |
|
19
|
+
resources = data.fetch_values("signed_params", "sgids", "signed_controllers", "urls") { |_key| Array.new(data["signed_params"].length, nil) }.transpose
|
19
20
|
|
20
|
-
|
21
|
-
ApplicationController.renderer.instance_variable_set(:@env, new_env)
|
21
|
+
resources_with_sgids, resources_without_sgids = resources.partition { |signed_params, sgid, *| sgid.present? }
|
22
22
|
|
23
|
-
|
23
|
+
GlobalID::Locator.locate_many_signed resources_with_sgids.map(&:second)
|
24
|
+
|
25
|
+
resources_without_sgids.each do |signed_params, sgid, signed_controller, url|
|
24
26
|
selector = "[data-signed-params='#{signed_params}']"
|
25
27
|
selector << "[data-sgid='#{sgid}']" if sgid.present?
|
28
|
+
|
29
|
+
controller = Resolver::Controller.from(signed_string: signed_controller)
|
30
|
+
renderer = Resolver::Controller::Renderer.for(controller: controller,
|
31
|
+
connection: connection,
|
32
|
+
url: url,
|
33
|
+
params: @params)
|
34
|
+
|
35
|
+
resource = lookup_resource(signed_params: signed_params, sgid: sgid)
|
36
|
+
html = renderer.render(resource)
|
37
|
+
|
26
38
|
cable_ready[stream_name].outer_html(
|
27
39
|
selector: selector,
|
28
|
-
html:
|
40
|
+
html: html
|
29
41
|
)
|
30
42
|
end
|
31
43
|
|
@@ -34,12 +46,10 @@ module Futurism
|
|
34
46
|
|
35
47
|
private
|
36
48
|
|
37
|
-
def
|
49
|
+
def lookup_resource(signed_params:, sgid:)
|
38
50
|
return GlobalID::Locator.locate_signed(sgid) if sgid.present?
|
39
51
|
|
40
|
-
|
41
|
-
.application
|
42
|
-
.message_verifier("futurism")
|
52
|
+
message_verifier
|
43
53
|
.verify(signed_params)
|
44
54
|
.deep_transform_values { |value| value.is_a?(String) && value.start_with?("gid://") ? GlobalID::Locator.locate(value) : value }
|
45
55
|
end
|
data/lib/futurism/helpers.rb
CHANGED
@@ -3,9 +3,9 @@ module Futurism
|
|
3
3
|
def futurize(records_or_string = nil, extends:, **options, &block)
|
4
4
|
if Rails.env.test? && Futurism.skip_in_test
|
5
5
|
if records_or_string.nil?
|
6
|
-
return render
|
6
|
+
return render(**options)
|
7
7
|
else
|
8
|
-
return render
|
8
|
+
return render(records_or_string, **options)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
@@ -26,10 +26,10 @@ module Futurism
|
|
26
26
|
if collection.nil?
|
27
27
|
Element.new(extends: extends, placeholder: placeholder, options: options).render
|
28
28
|
else
|
29
|
-
collection_class_name = collection.klass.name
|
29
|
+
collection_class_name = collection.try(:klass).try(:name) || collection.first.class.to_s
|
30
30
|
as = options.delete(:as) || collection_class_name.downcase
|
31
|
-
collection.map { |record|
|
32
|
-
Element.new(extends: extends, placeholder: placeholder, options: options.deep_merge(locals: {as.to_sym => record})).render
|
31
|
+
collection.each_with_index.map { |record, index|
|
32
|
+
Element.new(extends: extends, placeholder: placeholder, options: options.deep_merge(locals: {as.to_sym => record, "#{as}_counter".to_sym => index})).render
|
33
33
|
}.join.html_safe
|
34
34
|
end
|
35
35
|
end
|
@@ -43,13 +43,15 @@ module Futurism
|
|
43
43
|
# wraps functionality for rendering a futurism element
|
44
44
|
class Element
|
45
45
|
include ActionView::Helpers
|
46
|
+
include Futurism::MessageVerifier
|
46
47
|
|
47
|
-
attr_reader :extends, :placeholder, :html_options, :data_attributes, :model, :options, :eager
|
48
|
+
attr_reader :extends, :placeholder, :html_options, :data_attributes, :model, :options, :eager, :controller
|
48
49
|
|
49
50
|
def initialize(extends:, placeholder:, options:)
|
50
51
|
@extends = extends
|
51
52
|
@placeholder = placeholder
|
52
53
|
@eager = options.delete(:eager)
|
54
|
+
@controller = options.delete(:controller)
|
53
55
|
@html_options = options.delete(:html_options) || {}
|
54
56
|
@data_attributes = html_options.fetch(:data, {}).except(:sgid, :signed_params)
|
55
57
|
@model = options.delete(:model)
|
@@ -60,7 +62,8 @@ module Futurism
|
|
60
62
|
data_attributes.merge({
|
61
63
|
signed_params: signed_params,
|
62
64
|
sgid: model && model.to_sgid.to_s,
|
63
|
-
eager: eager.presence
|
65
|
+
eager: eager.presence,
|
66
|
+
signed_controller: signed_controller
|
64
67
|
})
|
65
68
|
end
|
66
69
|
|
@@ -86,7 +89,13 @@ module Futurism
|
|
86
89
|
private
|
87
90
|
|
88
91
|
def signed_params
|
89
|
-
|
92
|
+
message_verifier.generate(transformed_options)
|
93
|
+
end
|
94
|
+
|
95
|
+
def signed_controller
|
96
|
+
return unless controller.present?
|
97
|
+
|
98
|
+
message_verifier.generate(controller.to_s)
|
90
99
|
end
|
91
100
|
end
|
92
101
|
end
|
data/lib/futurism/helpers.rb~
CHANGED
@@ -3,11 +3,10 @@ module Futurism
|
|
3
3
|
def futurize(records_or_string = nil, extends:, **options, &block)
|
4
4
|
if Rails.env.test? && Futurism.skip_in_test
|
5
5
|
if records_or_string.nil?
|
6
|
-
render
|
6
|
+
return render(**options)
|
7
7
|
else
|
8
|
-
render
|
8
|
+
return render(records_or_string, **options)
|
9
9
|
end
|
10
|
-
return
|
11
10
|
end
|
12
11
|
|
13
12
|
placeholder = capture(&block)
|
@@ -44,13 +43,15 @@ module Futurism
|
|
44
43
|
# wraps functionality for rendering a futurism element
|
45
44
|
class Element
|
46
45
|
include ActionView::Helpers
|
46
|
+
include Futurism::MessageVerifier
|
47
47
|
|
48
|
-
attr_reader :extends, :placeholder, :html_options, :data_attributes, :model, :options, :eager
|
48
|
+
attr_reader :extends, :placeholder, :html_options, :data_attributes, :model, :options, :eager, :controller
|
49
49
|
|
50
50
|
def initialize(extends:, placeholder:, options:)
|
51
51
|
@extends = extends
|
52
52
|
@placeholder = placeholder
|
53
53
|
@eager = options.delete(:eager)
|
54
|
+
@controller = options.delete(:controller)
|
54
55
|
@html_options = options.delete(:html_options) || {}
|
55
56
|
@data_attributes = html_options.fetch(:data, {}).except(:sgid, :signed_params)
|
56
57
|
@model = options.delete(:model)
|
@@ -61,7 +62,8 @@ module Futurism
|
|
61
62
|
data_attributes.merge({
|
62
63
|
signed_params: signed_params,
|
63
64
|
sgid: model && model.to_sgid.to_s,
|
64
|
-
eager: eager.presence
|
65
|
+
eager: eager.presence,
|
66
|
+
signed_controller: signed_controller
|
65
67
|
})
|
66
68
|
end
|
67
69
|
|
@@ -87,7 +89,13 @@ module Futurism
|
|
87
89
|
private
|
88
90
|
|
89
91
|
def signed_params
|
90
|
-
|
92
|
+
message_verifier.generate(transformed_options)
|
93
|
+
end
|
94
|
+
|
95
|
+
def signed_controller
|
96
|
+
return unless controller.present?
|
97
|
+
|
98
|
+
message_verifier.generate(controller.to_s)
|
91
99
|
end
|
92
100
|
end
|
93
101
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Futurism
|
2
|
+
module MessageVerifier
|
3
|
+
def self.message_verifier
|
4
|
+
@message_verifier ||= Rails.application.message_verifier("futurism")
|
5
|
+
end
|
6
|
+
|
7
|
+
def message_verifier
|
8
|
+
@message_verifier ||= Rails.application.message_verifier("futurism")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Futurism
|
2
|
+
module Resolver
|
3
|
+
class Controller
|
4
|
+
def self.from(signed_string:)
|
5
|
+
if signed_string.present?
|
6
|
+
Futurism::MessageVerifier
|
7
|
+
.message_verifier
|
8
|
+
.verify(signed_string)
|
9
|
+
.to_s
|
10
|
+
.safe_constantize
|
11
|
+
else
|
12
|
+
Futurism.default_controller
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Futurism
|
2
|
+
module Resolver
|
3
|
+
class Controller
|
4
|
+
def self.from(signed_string:)
|
5
|
+
if signed_string.present?
|
6
|
+
Futurism::MessageVerifier
|
7
|
+
.message_verifier
|
8
|
+
.verify(signed_string)
|
9
|
+
.to_s
|
10
|
+
.safe_constantize
|
11
|
+
else
|
12
|
+
Futurism.default_controller
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Futurism
|
2
|
+
module Resolver
|
3
|
+
class Controller
|
4
|
+
class Renderer
|
5
|
+
def self.for(controller:, connection:, url:, params:)
|
6
|
+
new(controller: controller, connection: connection, url: url, params: params).renderer
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(controller:, connection:, url:, params:)
|
10
|
+
@controller = controller
|
11
|
+
@connection = connection
|
12
|
+
@url = url || ""
|
13
|
+
@params = params || {}
|
14
|
+
|
15
|
+
setup_env!
|
16
|
+
end
|
17
|
+
|
18
|
+
def renderer
|
19
|
+
@renderer ||= controller.renderer
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :controller, :connection, :url, :params
|
25
|
+
attr_writer :renderer
|
26
|
+
|
27
|
+
def setup_env!
|
28
|
+
if url.present?
|
29
|
+
uri = URI.parse(url)
|
30
|
+
path = ActionDispatch::Journey::Router::Utils.normalize_path(uri.path)
|
31
|
+
query_hash = Rack::Utils.parse_nested_query(uri.query)
|
32
|
+
|
33
|
+
path_params = Rails.application.routes.recognize_path(path)
|
34
|
+
|
35
|
+
self.renderer =
|
36
|
+
renderer.new(
|
37
|
+
"rack.request.query_hash" => query_hash,
|
38
|
+
"rack.request.query_string" => uri.query,
|
39
|
+
"ORIGINAL_SCRIPT_NAME" => "",
|
40
|
+
"ORIGINAL_FULLPATH" => path,
|
41
|
+
Rack::SCRIPT_NAME => "",
|
42
|
+
Rack::PATH_INFO => path,
|
43
|
+
Rack::REQUEST_PATH => path,
|
44
|
+
Rack::QUERY_STRING => uri.query,
|
45
|
+
ActionDispatch::Http::Parameters::PARAMETERS_KEY => params.symbolize_keys.merge(path_params).merge(query_hash)
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Copy connection env to renderer to fix some RACK related issues from gems like
|
50
|
+
# Warden or Devise
|
51
|
+
new_env = connection.env.merge(renderer.instance_variable_get(:@env))
|
52
|
+
renderer.instance_variable_set(:@env, new_env)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Futurism
|
2
|
+
module Resolver
|
3
|
+
class Controller
|
4
|
+
class Renderer
|
5
|
+
def self.for(controller:, connection:, url:, params:)
|
6
|
+
new(controller: controller, connection: connection, url: url, params: params).renderer
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(controller:, connection:, url:, params:)
|
10
|
+
@controller = controller
|
11
|
+
@connection = connection
|
12
|
+
@url = url || ""
|
13
|
+
@params = params || {}
|
14
|
+
|
15
|
+
setup_env!
|
16
|
+
end
|
17
|
+
|
18
|
+
def renderer
|
19
|
+
@renderer ||= controller.renderer
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :controller, :connection, :url, :params
|
25
|
+
attr_writer :renderer
|
26
|
+
|
27
|
+
def setup_env!
|
28
|
+
if url.present?
|
29
|
+
uri = URI.parse(url)
|
30
|
+
path = ActionDispatch::Journey::Router::Utils.normalize_path(uri.path)
|
31
|
+
query_hash = Rack::Utils.parse_nested_query(uri.query)
|
32
|
+
|
33
|
+
path_params = Rails.application.routes.recognize_path(path)
|
34
|
+
|
35
|
+
self.renderer =
|
36
|
+
renderer.new(
|
37
|
+
"rack.request.query_hash" => query_hash,
|
38
|
+
"rack.request.query_string" => uri.query,
|
39
|
+
"ORIGINAL_SCRIPT_NAME" => "",
|
40
|
+
"ORIGINAL_FULLPATH" => path,
|
41
|
+
Rack::SCRIPT_NAME => "",
|
42
|
+
Rack::PATH_INFO => path,
|
43
|
+
Rack::REQUEST_PATH => path,
|
44
|
+
Rack::QUERY_STRING => uri.query,
|
45
|
+
ActionDispatch::Http::Parameters::PARAMETERS_KEY => path_params.reverse_merge(path_params)
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Copy connection env to renderer to fix some RACK related issues from gems like
|
50
|
+
# Warden or Devise
|
51
|
+
new_env = connection.env.merge(renderer.instance_variable_get(:@env))
|
52
|
+
renderer.instance_variable_set(:@env, new_env)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Futurism
|
2
|
+
module Resolver
|
3
|
+
class Resources
|
4
|
+
include Futurism::MessageVerifier
|
5
|
+
|
6
|
+
# resource definitions are an array of [signed_params, sgid, signed_controller, url]
|
7
|
+
def initialize(resource_definitions:, connection:, params:)
|
8
|
+
@connection = connection
|
9
|
+
@params = params
|
10
|
+
@resources_with_sgids, @resources_without_sgids = resource_definitions
|
11
|
+
.partition { |signed_params, sgid, *| sgid.present? }
|
12
|
+
.map { |partition| partition.map { |definition| ResourceDefinition.new(definition) } }
|
13
|
+
end
|
14
|
+
|
15
|
+
def resolve
|
16
|
+
resolved_models.zip(@resources_with_sgids).each do |model, resource_definition|
|
17
|
+
html = renderer_for(resource_definition: resource_definition).render(model)
|
18
|
+
|
19
|
+
yield(resource_definition.selector, html)
|
20
|
+
end
|
21
|
+
|
22
|
+
@resources_without_sgids.each do |resource_definition|
|
23
|
+
resource = lookup_resource(resource_definition)
|
24
|
+
html = renderer_for(resource_definition: resource_definition).render(resource)
|
25
|
+
|
26
|
+
yield(resource_definition.selector, html)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
class ResourceDefinition
|
33
|
+
attr_reader :signed_params, :sgid, :signed_controller, :url
|
34
|
+
|
35
|
+
def initialize(resource_definition)
|
36
|
+
@signed_params, @sgid, @signed_controller, @url = resource_definition
|
37
|
+
end
|
38
|
+
|
39
|
+
def selector
|
40
|
+
selector = "[data-signed-params='#{@signed_params}']"
|
41
|
+
selector << "[data-sgid='#{@sgid}']" if @sgid.present?
|
42
|
+
selector
|
43
|
+
end
|
44
|
+
|
45
|
+
def controller
|
46
|
+
Resolver::Controller.from(signed_string: @signed_controller)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def renderer_for(resource_definition:)
|
51
|
+
Resolver::Controller::Renderer.for(controller: resource_definition.controller,
|
52
|
+
connection: @connection,
|
53
|
+
url: resource_definition.url,
|
54
|
+
params: @params)
|
55
|
+
end
|
56
|
+
|
57
|
+
def resolved_models
|
58
|
+
GlobalID::Locator.locate_many_signed @resources_with_sgids.map(&:sgid)
|
59
|
+
end
|
60
|
+
|
61
|
+
def lookup_resource(resource_definition)
|
62
|
+
message_verifier
|
63
|
+
.verify(resource_definition.signed_params)
|
64
|
+
.deep_transform_values { |value| value.is_a?(String) && value.start_with?("gid://") ? GlobalID::Locator.locate(value) : value }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Futurism
|
2
|
+
module Resolver
|
3
|
+
class Resources
|
4
|
+
include Futurism::MessageVerifier
|
5
|
+
|
6
|
+
# resource definitions are an array of [signed_params, sgid, signed_controller, url]
|
7
|
+
def initialize(resource_definitions:, connection:, params:)
|
8
|
+
@connection = connection
|
9
|
+
@params = params
|
10
|
+
@resources_with_sgids, @resources_without_sgids = resource_definitions
|
11
|
+
.partition { |signed_params, sgid, *| sgid.present? }
|
12
|
+
.map { |definition| ResourceDefinition.new(definition) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def resolve
|
16
|
+
resolved_models.zip(@resources_with_sgids).each do |model, resource_definition|
|
17
|
+
signed_params, sgid, signed_controller, url = resource_definition
|
18
|
+
|
19
|
+
selector = selector_for(signed_params: signed_params, sgid: sgid)
|
20
|
+
|
21
|
+
controller = Resolver::Controller.from(signed_string: signed_controller)
|
22
|
+
renderer = Resolver::Controller::Renderer.for(controller: controller,
|
23
|
+
connection: @connection,
|
24
|
+
url: url,
|
25
|
+
params: @params)
|
26
|
+
|
27
|
+
html = renderer.render(model)
|
28
|
+
|
29
|
+
yield(selector, html)
|
30
|
+
end
|
31
|
+
|
32
|
+
@resources_without_sgids.each do |signed_params, sgid, signed_controller, url|
|
33
|
+
selector = selector_for(signed_params: signed_params, sgid: sgid)
|
34
|
+
|
35
|
+
controller = Resolver::Controller.from(signed_string: signed_controller)
|
36
|
+
renderer = Resolver::Controller::Renderer.for(controller: controller,
|
37
|
+
connection: @connection,
|
38
|
+
url: url,
|
39
|
+
params: @params)
|
40
|
+
|
41
|
+
resource = lookup_resource(signed_params: signed_params)
|
42
|
+
html = renderer.render(resource)
|
43
|
+
|
44
|
+
yield(selector, html)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
class ResourceDefinition
|
51
|
+
def initialize(resource_definition)
|
52
|
+
@signed_params, @sgid, @signed_controller, @url = resource_definition
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def resolved_models
|
57
|
+
GlobalID::Locator.locate_many_signed @resources_with_sgids.map(&:second)
|
58
|
+
end
|
59
|
+
|
60
|
+
def lookup_resource(signed_params:)
|
61
|
+
message_verifier
|
62
|
+
.verify(signed_params)
|
63
|
+
.deep_transform_values { |value| value.is_a?(String) && value.start_with?("gid://") ? GlobalID::Locator.locate(value) : value }
|
64
|
+
end
|
65
|
+
|
66
|
+
def selector_for(signed_params:, sgid:)
|
67
|
+
selector = "[data-signed-params='#{signed_params}']"
|
68
|
+
selector << "[data-sgid='#{sgid}']" if sgid.present?
|
69
|
+
selector
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/futurism/version.rb
CHANGED
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: futurism
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julian Rubisch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-04-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: appraisal
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ">="
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: bundler
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,20 +94,6 @@ dependencies:
|
|
108
94
|
- - ">="
|
109
95
|
- !ruby/object:Gem::Version
|
110
96
|
version: '0'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: spy
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - ">="
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - ">="
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '0'
|
125
97
|
- !ruby/object:Gem::Dependency
|
126
98
|
name: rack
|
127
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -175,7 +147,6 @@ files:
|
|
175
147
|
- MIT-LICENSE
|
176
148
|
- README.md
|
177
149
|
- Rakefile
|
178
|
-
- app/assets/config/futurism_manifest.js
|
179
150
|
- config/routes.rb
|
180
151
|
- lib/futurism.rb
|
181
152
|
- lib/futurism.rb~
|
@@ -184,8 +155,16 @@ files:
|
|
184
155
|
- lib/futurism/engine.rb
|
185
156
|
- lib/futurism/helpers.rb
|
186
157
|
- lib/futurism/helpers.rb~
|
158
|
+
- lib/futurism/message_verifier.rb
|
159
|
+
- lib/futurism/resolver/controller.rb
|
160
|
+
- lib/futurism/resolver/controller.rb~
|
161
|
+
- lib/futurism/resolver/controller/renderer.rb
|
162
|
+
- lib/futurism/resolver/controller/renderer.rb~
|
163
|
+
- lib/futurism/resolver/resources.rb
|
164
|
+
- lib/futurism/resolver/resources.rb~
|
187
165
|
- lib/futurism/shims/deep_transform_values.rb
|
188
166
|
- lib/futurism/version.rb
|
167
|
+
- lib/futurism/version.rb~
|
189
168
|
- lib/tasks/futurism_tasks.rake
|
190
169
|
- lib/tasks/futurism_tasks.rake~
|
191
170
|
homepage: https://github.com/julianrubisch/futurism
|
File without changes
|