futurism 1.4.1 → 1.4.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c4296e173d85171de4f86327adf9849dab72d491fc23f2f0b05c66c858ed5f48
4
- data.tar.gz: 0f71eebdc174b7a6b4154a67cd0962944ee41bc1777060578abbd919a164e2c3
3
+ metadata.gz: 6a8ee3fe6d96bf57ee2ade40827a96b016a470c29dca6e47e810eb8e0c3445de
4
+ data.tar.gz: 25a1d96d3a49adea326740d551bd0d56f4e258134d83bf5982bdfb99eda3ccc5
5
5
  SHA512:
6
- metadata.gz: e531ac9c47f070d26e91e3124b45ddcf287fd402fcc3f640b35149475c52ee14232cd5e5d6422cdd04e63deee32b5ec1f9204de9f0be46ae71dd05d9a305d188
7
- data.tar.gz: 27c42c8c389a63f0dd839db592138dd22f5f7a4b2d1634b52ed43432ed825cda9a63f9a157aba25b436af760b7eae03d3e45ad7ddd1e05f82f9d8725a65fd9c9
6
+ metadata.gz: 9d5396fde2a53b5e91ef31062176757fc0c89eeb2835dca3068d3b3e965a8fd9d47d3f8f8762f38fce83c7c7c418cf176113b015739ea2a2bec846b2cec0e6c8
7
+ data.tar.gz: 527881e8fa5c643ac2bb210fe0b8175abfd78638b256b14717f26100c417afbadd9c6e0e2ea5c25cf02047ba87e374aaf7e702c2528619481806614258f04a7a
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- futurism (1.4.1)
4
+ futurism (1.4.2)
5
5
  cable_ready (>= 5.0)
6
6
  rack (>= 2, < 4)
7
7
  rails (>= 5.2)
@@ -9,35 +9,35 @@ PATH
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- actioncable (7.1.3.2)
13
- actionpack (= 7.1.3.2)
14
- activesupport (= 7.1.3.2)
12
+ actioncable (7.1.3.4)
13
+ actionpack (= 7.1.3.4)
14
+ activesupport (= 7.1.3.4)
15
15
  nio4r (~> 2.0)
16
16
  websocket-driver (>= 0.6.1)
17
17
  zeitwerk (~> 2.6)
18
- actionmailbox (7.1.3.2)
19
- actionpack (= 7.1.3.2)
20
- activejob (= 7.1.3.2)
21
- activerecord (= 7.1.3.2)
22
- activestorage (= 7.1.3.2)
23
- activesupport (= 7.1.3.2)
18
+ actionmailbox (7.1.3.4)
19
+ actionpack (= 7.1.3.4)
20
+ activejob (= 7.1.3.4)
21
+ activerecord (= 7.1.3.4)
22
+ activestorage (= 7.1.3.4)
23
+ activesupport (= 7.1.3.4)
24
24
  mail (>= 2.7.1)
25
25
  net-imap
26
26
  net-pop
27
27
  net-smtp
28
- actionmailer (7.1.3.2)
29
- actionpack (= 7.1.3.2)
30
- actionview (= 7.1.3.2)
31
- activejob (= 7.1.3.2)
32
- activesupport (= 7.1.3.2)
28
+ actionmailer (7.1.3.4)
29
+ actionpack (= 7.1.3.4)
30
+ actionview (= 7.1.3.4)
31
+ activejob (= 7.1.3.4)
32
+ activesupport (= 7.1.3.4)
33
33
  mail (~> 2.5, >= 2.5.4)
34
34
  net-imap
35
35
  net-pop
36
36
  net-smtp
37
37
  rails-dom-testing (~> 2.2)
38
- actionpack (7.1.3.2)
39
- actionview (= 7.1.3.2)
40
- activesupport (= 7.1.3.2)
38
+ actionpack (7.1.3.4)
39
+ actionview (= 7.1.3.4)
40
+ activesupport (= 7.1.3.4)
41
41
  nokogiri (>= 1.8.5)
42
42
  racc
43
43
  rack (>= 2.2.4)
@@ -45,35 +45,35 @@ GEM
45
45
  rack-test (>= 0.6.3)
46
46
  rails-dom-testing (~> 2.2)
47
47
  rails-html-sanitizer (~> 1.6)
48
- actiontext (7.1.3.2)
49
- actionpack (= 7.1.3.2)
50
- activerecord (= 7.1.3.2)
51
- activestorage (= 7.1.3.2)
52
- activesupport (= 7.1.3.2)
48
+ actiontext (7.1.3.4)
49
+ actionpack (= 7.1.3.4)
50
+ activerecord (= 7.1.3.4)
51
+ activestorage (= 7.1.3.4)
52
+ activesupport (= 7.1.3.4)
53
53
  globalid (>= 0.6.0)
54
54
  nokogiri (>= 1.8.5)
55
- actionview (7.1.3.2)
56
- activesupport (= 7.1.3.2)
55
+ actionview (7.1.3.4)
56
+ activesupport (= 7.1.3.4)
57
57
  builder (~> 3.1)
58
58
  erubi (~> 1.11)
59
59
  rails-dom-testing (~> 2.2)
60
60
  rails-html-sanitizer (~> 1.6)
61
- activejob (7.1.3.2)
62
- activesupport (= 7.1.3.2)
61
+ activejob (7.1.3.4)
62
+ activesupport (= 7.1.3.4)
63
63
  globalid (>= 0.3.6)
64
- activemodel (7.1.3.2)
65
- activesupport (= 7.1.3.2)
66
- activerecord (7.1.3.2)
67
- activemodel (= 7.1.3.2)
68
- activesupport (= 7.1.3.2)
64
+ activemodel (7.1.3.4)
65
+ activesupport (= 7.1.3.4)
66
+ activerecord (7.1.3.4)
67
+ activemodel (= 7.1.3.4)
68
+ activesupport (= 7.1.3.4)
69
69
  timeout (>= 0.4.0)
70
- activestorage (7.1.3.2)
71
- actionpack (= 7.1.3.2)
72
- activejob (= 7.1.3.2)
73
- activerecord (= 7.1.3.2)
74
- activesupport (= 7.1.3.2)
70
+ activestorage (7.1.3.4)
71
+ actionpack (= 7.1.3.4)
72
+ activejob (= 7.1.3.4)
73
+ activerecord (= 7.1.3.4)
74
+ activesupport (= 7.1.3.4)
75
75
  marcel (~> 1.0)
76
- activesupport (7.1.3.2)
76
+ activesupport (7.1.3.4)
77
77
  base64
78
78
  bigdecimal
79
79
  concurrent-ruby (~> 1.0, >= 1.0.2)
@@ -89,27 +89,28 @@ GEM
89
89
  thor (>= 0.14.0)
90
90
  ast (2.4.2)
91
91
  base64 (0.2.0)
92
- bigdecimal (3.1.7)
93
- builder (3.2.4)
94
- cable_ready (5.0.3)
92
+ bigdecimal (3.1.8)
93
+ builder (3.3.0)
94
+ cable_ready (5.0.5)
95
95
  actionpack (>= 5.2)
96
96
  actionview (>= 5.2)
97
97
  activesupport (>= 5.2)
98
+ observer (~> 0.1)
98
99
  railties (>= 5.2)
99
100
  thread-local (>= 1.1.0)
100
- concurrent-ruby (1.2.3)
101
+ concurrent-ruby (1.3.3)
101
102
  connection_pool (2.4.1)
102
103
  crass (1.0.6)
103
104
  date (3.3.4)
104
105
  drb (2.2.1)
105
- erubi (1.12.0)
106
+ erubi (1.13.0)
106
107
  globalid (1.2.1)
107
108
  activesupport (>= 6.1)
108
- i18n (1.14.4)
109
+ i18n (1.14.5)
109
110
  concurrent-ruby (~> 1.0)
110
111
  io-console (0.7.2)
111
- irb (1.12.0)
112
- rdoc
112
+ irb (1.14.0)
113
+ rdoc (>= 4.0.0)
113
114
  reline (>= 0.4.2)
114
115
  json (2.7.1)
115
116
  language_server-protocol (3.17.0.3)
@@ -124,9 +125,9 @@ GEM
124
125
  net-smtp
125
126
  marcel (1.0.4)
126
127
  mini_mime (1.1.5)
127
- minitest (5.22.3)
128
+ minitest (5.24.1)
128
129
  mutex_m (0.2.0)
129
- net-imap (0.4.10)
130
+ net-imap (0.4.14)
130
131
  date
131
132
  net-protocol
132
133
  net-pop (0.1.2)
@@ -135,11 +136,12 @@ GEM
135
136
  timeout
136
137
  net-smtp (0.5.0)
137
138
  net-protocol
138
- nio4r (2.7.1)
139
- nokogiri (1.16.2-arm64-darwin)
139
+ nio4r (2.7.3)
140
+ nokogiri (1.16.5-arm64-darwin)
140
141
  racc (~> 1.4)
141
- nokogiri (1.16.2-x86_64-linux)
142
+ nokogiri (1.16.5-x86_64-linux)
142
143
  racc (~> 1.4)
144
+ observer (0.1.2)
143
145
  parallel (1.24.0)
144
146
  parser (3.3.0.5)
145
147
  ast (~> 2.4.1)
@@ -147,7 +149,7 @@ GEM
147
149
  psych (5.1.2)
148
150
  stringio
149
151
  racc (1.7.3)
150
- rack (3.0.10)
152
+ rack (3.1.6)
151
153
  rack-session (2.0.0)
152
154
  rack (>= 3.0.0)
153
155
  rack-test (2.1.0)
@@ -155,20 +157,20 @@ GEM
155
157
  rackup (2.1.0)
156
158
  rack (>= 3)
157
159
  webrick (~> 1.8)
158
- rails (7.1.3.2)
159
- actioncable (= 7.1.3.2)
160
- actionmailbox (= 7.1.3.2)
161
- actionmailer (= 7.1.3.2)
162
- actionpack (= 7.1.3.2)
163
- actiontext (= 7.1.3.2)
164
- actionview (= 7.1.3.2)
165
- activejob (= 7.1.3.2)
166
- activemodel (= 7.1.3.2)
167
- activerecord (= 7.1.3.2)
168
- activestorage (= 7.1.3.2)
169
- activesupport (= 7.1.3.2)
160
+ rails (7.1.3.4)
161
+ actioncable (= 7.1.3.4)
162
+ actionmailbox (= 7.1.3.4)
163
+ actionmailer (= 7.1.3.4)
164
+ actionpack (= 7.1.3.4)
165
+ actiontext (= 7.1.3.4)
166
+ actionview (= 7.1.3.4)
167
+ activejob (= 7.1.3.4)
168
+ activemodel (= 7.1.3.4)
169
+ activerecord (= 7.1.3.4)
170
+ activestorage (= 7.1.3.4)
171
+ activesupport (= 7.1.3.4)
170
172
  bundler (>= 1.15.0)
171
- railties (= 7.1.3.2)
173
+ railties (= 7.1.3.4)
172
174
  rails-dom-testing (2.2.0)
173
175
  activesupport (>= 5.0.0)
174
176
  minitest
@@ -176,9 +178,9 @@ GEM
176
178
  rails-html-sanitizer (1.6.0)
177
179
  loofah (~> 2.21)
178
180
  nokogiri (~> 1.14)
179
- railties (7.1.3.2)
180
- actionpack (= 7.1.3.2)
181
- activesupport (= 7.1.3.2)
181
+ railties (7.1.3.4)
182
+ actionpack (= 7.1.3.4)
183
+ activesupport (= 7.1.3.4)
182
184
  irb
183
185
  rackup (>= 1.0.0)
184
186
  rake (>= 12.2)
@@ -186,12 +188,13 @@ GEM
186
188
  zeitwerk (~> 2.6)
187
189
  rainbow (3.1.1)
188
190
  rake (13.1.0)
189
- rdoc (6.6.3.1)
191
+ rdoc (6.7.0)
190
192
  psych (>= 4.0.0)
191
193
  regexp_parser (2.9.0)
192
- reline (0.5.2)
194
+ reline (0.5.9)
193
195
  io-console (~> 0.5)
194
- rexml (3.2.6)
196
+ rexml (3.2.8)
197
+ strscan (>= 3.0.9)
195
198
  rubocop (1.60.2)
196
199
  json (~> 2.3)
197
200
  language_server-protocol (>= 3.17.0)
@@ -225,7 +228,8 @@ GEM
225
228
  rubocop-performance (~> 1.20.2)
226
229
  standardrb (1.0.1)
227
230
  standard
228
- stringio (3.1.0)
231
+ stringio (3.1.1)
232
+ strscan (3.1.0)
229
233
  thor (1.3.1)
230
234
  thread-local (1.1.0)
231
235
  timeout (0.4.1)
@@ -236,7 +240,7 @@ GEM
236
240
  websocket-driver (0.7.6)
237
241
  websocket-extensions (>= 0.1.0)
238
242
  websocket-extensions (0.1.5)
239
- zeitwerk (2.6.13)
243
+ zeitwerk (2.6.16)
240
244
 
241
245
  PLATFORMS
242
246
  arm64-darwin-21
@@ -17,7 +17,9 @@ const debounceEvents = (callback, delay = 20) => {
17
17
  const createSubscription = consumer => {
18
18
  consumer.subscriptions.create("Futurism::Channel", {
19
19
  connected() {
20
- window.Futurism = this;
20
+ window.Futurism = {
21
+ subscription: this
22
+ };
21
23
  document.addEventListener("futurism:appear", debounceEvents((events => {
22
24
  this.send({
23
25
  signed_params: events.map((e => e.target.dataset.signedParams)),
@@ -43,7 +45,7 @@ const createSubscription = consumer => {
43
45
  };
44
46
 
45
47
  const dispatchAppearEvent = (entry, observer = null) => {
46
- if (!window.Futurism) {
48
+ if (!window.Futurism?.subscription) {
47
49
  return () => {
48
50
  setTimeout((() => dispatchAppearEvent(entry, observer)()), 1);
49
51
  };
@@ -167,6 +169,10 @@ const cachePlaceholders = e => {
167
169
  };
168
170
 
169
171
  const restorePlaceholders = e => {
172
+ if (sessionStorage.getItem("requested-turbo-frame")) {
173
+ delete sessionStorage.removeItem("requested-turbo-frame");
174
+ return;
175
+ }
170
176
  const inNamespace = ([key, _payload]) => key.startsWith("futurism-");
171
177
  Object.entries(sessionStorage).filter(inNamespace).forEach((([key, payload]) => {
172
178
  const match = /^futurism-(.*)/.exec(key);
@@ -178,6 +184,12 @@ const restorePlaceholders = e => {
178
184
  }));
179
185
  };
180
186
 
187
+ const storeRequestedTurboFrame = e => {
188
+ const {headers: headers} = e.detail.fetchOptions;
189
+ if (!headers["Turbo-Frame"] || headers["X-Sec-Purpose"] === "prefetch") return;
190
+ sessionStorage.setItem("requested-turbo-frame", headers["Turbo-Frame"]);
191
+ };
192
+
181
193
  const initializeElements = () => {
182
194
  polyfillCustomElements();
183
195
  document.addEventListener("DOMContentLoaded", defineElements);
@@ -186,6 +198,7 @@ const initializeElements = () => {
186
198
  document.addEventListener("turbolinks:load", defineElements);
187
199
  document.addEventListener("turbolinks:before-cache", restorePlaceholders);
188
200
  document.addEventListener("cable-ready:after-outer-html", cachePlaceholders);
201
+ document.addEventListener("turbo:before-fetch-request", storeRequestedTurboFrame);
189
202
  };
190
203
 
191
204
  export { createSubscription, initializeElements };
@@ -1,2 +1,2 @@
1
- import e from"cable_ready";const t=t=>{t.subscriptions.create("Futurism::Channel",{connected(){window.Futurism=this,document.addEventListener("futurism:appear",((e,t=20)=>{let s,r=[];return(...n)=>{clearTimeout(s),r=[...r,...n],s=setTimeout((()=>{s=null,e(r),r=[]}),t)}})((e=>{this.send({signed_params:e.map((e=>e.target.dataset.signedParams)),sgids:e.map((e=>e.target.dataset.sgid)),signed_controllers:e.map((e=>e.target.dataset.signedController)),urls:e.map((e=>window.location.href)),broadcast_each:e.map((e=>e.target.dataset.broadcastEach))})})))},received(t){t.cableReady&&(e.perform(t.operations,{emitMissingElementWarnings:!1}),document.dispatchEvent(new CustomEvent("futurism:appeared",{bubbles:!0,cancelable:!0})))}})},s=(e,t=null)=>{if(!window.Futurism)return()=>{setTimeout((()=>s(e,t)()),1)};const r=e.target?e.target:e,n=new CustomEvent("futurism:appear",{bubbles:!0,detail:{target:r,observer:t}});return()=>{r.dispatchEvent(n)}},r=async(e,t=0)=>{try{return await e()}catch(n){if(t>10)throw n;return await(s=1.15**t*2e3,new Promise((e=>setTimeout(e,s)))),r(e,t+1)}var s},n=(e,t)=>{e.forEach((async e=>{e.isIntersecting&&await r(s(e,t))}))},a=e=>{Object.assign(e,{observer:new IntersectionObserver(n.bind(e),{})}),e.hasAttribute("keep")||e.observer.observe(e)},i=e=>{"true"===e.dataset.eager&&(e.observer&&e.observer.disconnect(),r(s(e)))};class o extends HTMLElement{connectedCallback(){a(this),i(this)}}class c extends HTMLTableRowElement{connectedCallback(){a(this),i(this)}}class u extends HTMLLIElement{connectedCallback(){a(this),i(this)}}const m=e=>{customElements.get("futurism-element")||(customElements.define("futurism-element",o),customElements.define("futurism-table-row",c,{extends:"tr"}),customElements.define("futurism-li",u,{extends:"li"}))},d=e=>{(async function(e){const t=new TextEncoder("utf-8").encode(e),s=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(s)).map((e=>("00"+e.toString(16)).slice(-2))).join("")})(e.detail.element.outerHTML).then((t=>{e.detail.element.setAttribute("keep",""),sessionStorage.setItem(`futurism-${t}`,e.detail.element.outerHTML),e.target.dataset.futurismHash=t}))},l=e=>{Object.entries(sessionStorage).filter((([e,t])=>e.startsWith("futurism-"))).forEach((([e,t])=>{const s=/^futurism-(.*)/.exec(e),r=document.querySelector(`[data-futurism-hash="${s[1]}"]`);r&&(r.outerHTML=t,sessionStorage.removeItem(e))}))},b=()=>{(()=>{const e=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);if(customElements)if(e)document.write('<script src="//unpkg.com/@ungap/custom-elements-builtin"><\/script>');else try{customElements.define("built-in",document.createElement("tr").constructor,{extends:"tr"})}catch(e){document.write('<script src="//unpkg.com/@ungap/custom-elements-builtin"><\/script>')}else document.write('<script src="//unpkg.com/document-register-element"><\/script>')})(),document.addEventListener("DOMContentLoaded",m),document.addEventListener("turbo:load",m),document.addEventListener("turbo:before-cache",l),document.addEventListener("turbolinks:load",m),document.addEventListener("turbolinks:before-cache",l),document.addEventListener("cable-ready:after-outer-html",d)};export{t as createSubscription,b as initializeElements};
1
+ import e from"cable_ready";const t=t=>{t.subscriptions.create("Futurism::Channel",{connected(){window.Futurism={subscription:this},document.addEventListener("futurism:appear",((e,t=20)=>{let s,r=[];return(...n)=>{clearTimeout(s),r=[...r,...n],s=setTimeout((()=>{s=null,e(r),r=[]}),t)}})((e=>{this.send({signed_params:e.map((e=>e.target.dataset.signedParams)),sgids:e.map((e=>e.target.dataset.sgid)),signed_controllers:e.map((e=>e.target.dataset.signedController)),urls:e.map((e=>window.location.href)),broadcast_each:e.map((e=>e.target.dataset.broadcastEach))})})))},received(t){t.cableReady&&(e.perform(t.operations,{emitMissingElementWarnings:!1}),document.dispatchEvent(new CustomEvent("futurism:appeared",{bubbles:!0,cancelable:!0})))}})},s=(e,t=null)=>{if(!window.Futurism?.subscription)return()=>{setTimeout((()=>s(e,t)()),1)};const r=e.target?e.target:e,n=new CustomEvent("futurism:appear",{bubbles:!0,detail:{target:r,observer:t}});return()=>{r.dispatchEvent(n)}},r=async(e,t=0)=>{try{return await e()}catch(n){if(t>10)throw n;return await(s=1.15**t*2e3,new Promise((e=>setTimeout(e,s)))),r(e,t+1)}var s},n=(e,t)=>{e.forEach((async e=>{e.isIntersecting&&await r(s(e,t))}))},a=e=>{Object.assign(e,{observer:new IntersectionObserver(n.bind(e),{})}),e.hasAttribute("keep")||e.observer.observe(e)},i=e=>{"true"===e.dataset.eager&&(e.observer&&e.observer.disconnect(),r(s(e)))};class o extends HTMLElement{connectedCallback(){a(this),i(this)}}class u extends HTMLTableRowElement{connectedCallback(){a(this),i(this)}}class c extends HTMLLIElement{connectedCallback(){a(this),i(this)}}const m=e=>{customElements.get("futurism-element")||(customElements.define("futurism-element",o),customElements.define("futurism-table-row",u,{extends:"tr"}),customElements.define("futurism-li",c,{extends:"li"}))},d=e=>{(async function(e){const t=new TextEncoder("utf-8").encode(e),s=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(s)).map((e=>("00"+e.toString(16)).slice(-2))).join("")})(e.detail.element.outerHTML).then((t=>{e.detail.element.setAttribute("keep",""),sessionStorage.setItem(`futurism-${t}`,e.detail.element.outerHTML),e.target.dataset.futurismHash=t}))},l=e=>{if(sessionStorage.getItem("requested-turbo-frame"))return void sessionStorage.removeItem("requested-turbo-frame");Object.entries(sessionStorage).filter((([e,t])=>e.startsWith("futurism-"))).forEach((([e,t])=>{const s=/^futurism-(.*)/.exec(e),r=document.querySelector(`[data-futurism-hash="${s[1]}"]`);r&&(r.outerHTML=t,sessionStorage.removeItem(e))}))},b=e=>{const{headers:t}=e.detail.fetchOptions;t["Turbo-Frame"]&&"prefetch"!==t["X-Sec-Purpose"]&&sessionStorage.setItem("requested-turbo-frame",t["Turbo-Frame"])},f=()=>{(()=>{const e=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);if(customElements)if(e)document.write('<script src="//unpkg.com/@ungap/custom-elements-builtin"><\/script>');else try{customElements.define("built-in",document.createElement("tr").constructor,{extends:"tr"})}catch(e){document.write('<script src="//unpkg.com/@ungap/custom-elements-builtin"><\/script>')}else document.write('<script src="//unpkg.com/document-register-element"><\/script>')})(),document.addEventListener("DOMContentLoaded",m),document.addEventListener("turbo:load",m),document.addEventListener("turbo:before-cache",l),document.addEventListener("turbolinks:load",m),document.addEventListener("turbolinks:before-cache",l),document.addEventListener("cable-ready:after-outer-html",d),document.addEventListener("turbo:before-fetch-request",b)};export{t as createSubscription,f as initializeElements};
2
2
  //# sourceMappingURL=futurism.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"futurism.min.js","sources":["../../../javascript/futurism_channel.js","../../../javascript/elements/futurism_utils.js","../../../javascript/elements/futurism_element.js","../../../javascript/elements/futurism_table_row.js","../../../javascript/elements/futurism_li.js","../../../javascript/elements/index.js","../../../javascript/utils/crypto.js"],"sourcesContent":["/* global CustomEvent, setTimeout */\n\nimport CableReady from 'cable_ready'\n\nconst debounceEvents = (callback, delay = 20) => {\n let timeoutId\n let events = []\n return (...args) => {\n clearTimeout(timeoutId)\n events = [...events, ...args]\n timeoutId = setTimeout(() => {\n timeoutId = null\n callback(events)\n events = []\n }, delay)\n }\n}\n\nexport const createSubscription = consumer => {\n consumer.subscriptions.create('Futurism::Channel', {\n connected () {\n window.Futurism = this\n document.addEventListener(\n 'futurism:appear',\n debounceEvents(events => {\n this.send({\n signed_params: events.map(e => e.target.dataset.signedParams),\n sgids: events.map(e => e.target.dataset.sgid),\n signed_controllers: events.map(\n e => e.target.dataset.signedController\n ),\n urls: events.map(_ => window.location.href),\n broadcast_each: events.map(e => e.target.dataset.broadcastEach)\n })\n })\n )\n },\n\n received (data) {\n if (data.cableReady) {\n CableReady.perform(data.operations, {\n emitMissingElementWarnings: false\n })\n\n document.dispatchEvent(\n new CustomEvent('futurism:appeared', {\n bubbles: true,\n cancelable: true\n })\n )\n }\n }\n })\n}\n","/* global IntersectionObserver, CustomEvent, setTimeout */\n\nconst dispatchAppearEvent = (entry, observer = null) => {\n if (!window.Futurism) {\n return () => {\n setTimeout(() => dispatchAppearEvent(entry, observer)(), 1)\n }\n }\n\n const target = entry.target ? entry.target : entry\n\n const evt = new CustomEvent('futurism:appear', {\n bubbles: true,\n detail: {\n target,\n observer\n }\n })\n\n return () => {\n target.dispatchEvent(evt)\n }\n}\n\n// from https://advancedweb.hu/how-to-implement-an-exponential-backoff-retry-strategy-in-javascript/#rejection-based-retrying\nconst wait = ms => new Promise(resolve => setTimeout(resolve, ms))\n\nconst callWithRetry = async (fn, depth = 0) => {\n try {\n return await fn()\n } catch (e) {\n if (depth > 10) {\n throw e\n }\n await wait(1.15 ** depth * 2000)\n\n return callWithRetry(fn, depth + 1)\n }\n}\n\nconst observerCallback = (entries, observer) => {\n entries.forEach(async entry => {\n if (!entry.isIntersecting) return\n\n await callWithRetry(dispatchAppearEvent(entry, observer))\n })\n}\n\nexport const extendElementWithIntersectionObserver = element => {\n Object.assign(element, {\n observer: new IntersectionObserver(observerCallback.bind(element), {})\n })\n\n if (!element.hasAttribute('keep')) {\n element.observer.observe(element)\n }\n}\n\nexport const extendElementWithEagerLoading = element => {\n if (element.dataset.eager === 'true') {\n if (element.observer) element.observer.disconnect()\n callWithRetry(dispatchAppearEvent(element))\n }\n}\n","/* global HTMLElement */\n\nimport {\n extendElementWithIntersectionObserver,\n extendElementWithEagerLoading\n} from './futurism_utils'\n\nexport default class FuturismElement extends HTMLElement {\n connectedCallback () {\n extendElementWithIntersectionObserver(this)\n extendElementWithEagerLoading(this)\n }\n}\n","/* global HTMLTableRowElement */\n\nimport {\n extendElementWithIntersectionObserver,\n extendElementWithEagerLoading\n} from './futurism_utils'\n\nexport default class FuturismTableRow extends HTMLTableRowElement {\n connectedCallback () {\n extendElementWithIntersectionObserver(this)\n extendElementWithEagerLoading(this)\n }\n}\n","/* global HTMLLIElement */\r\n\r\nimport {\r\n extendElementWithIntersectionObserver,\r\n extendElementWithEagerLoading\r\n} from './futurism_utils'\r\n\r\nexport default class FuturismLI extends HTMLLIElement {\r\n connectedCallback () {\r\n extendElementWithIntersectionObserver(this)\r\n extendElementWithEagerLoading(this)\r\n }\r\n}\r\n","/* global customElements, sessionStorage */\n\nimport FuturismElement from './futurism_element'\nimport FuturismTableRow from './futurism_table_row'\nimport FuturismLI from './futurism_li'\n\nimport { sha256 } from '../utils/crypto'\n\nconst polyfillCustomElements = () => {\n const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)\n\n if (customElements) {\n if (isSafari) {\n document.write(\n '<script src=\"//unpkg.com/@ungap/custom-elements-builtin\"><\\x2fscript>'\n )\n } else {\n try {\n customElements.define(\n 'built-in',\n document.createElement('tr').constructor,\n { extends: 'tr' }\n )\n } catch (_) {\n document.write(\n '<script src=\"//unpkg.com/@ungap/custom-elements-builtin\"><\\x2fscript>'\n )\n }\n }\n } else {\n document.write(\n '<script src=\"//unpkg.com/document-register-element\"><\\x2fscript>'\n )\n }\n}\n\nconst defineElements = e => {\n if (!customElements.get('futurism-element')) {\n customElements.define('futurism-element', FuturismElement)\n customElements.define('futurism-table-row', FuturismTableRow, {\n extends: 'tr'\n })\n customElements.define('futurism-li', FuturismLI, { extends: 'li' })\n }\n}\n\nconst cachePlaceholders = e => {\n sha256(e.detail.element.outerHTML).then(hashedContent => {\n e.detail.element.setAttribute('keep', '')\n sessionStorage.setItem(\n `futurism-${hashedContent}`,\n e.detail.element.outerHTML\n )\n e.target.dataset.futurismHash = hashedContent\n })\n}\n\nconst restorePlaceholders = e => {\n const inNamespace = ([key, _payload]) => key.startsWith('futurism-')\n Object.entries(sessionStorage)\n .filter(inNamespace)\n .forEach(([key, payload]) => {\n const match = /^futurism-(.*)/.exec(key)\n const targetElement = document.querySelector(\n `[data-futurism-hash=\"${match[1]}\"]`\n )\n\n if (targetElement) {\n targetElement.outerHTML = payload\n sessionStorage.removeItem(key)\n }\n })\n}\n\nexport const initializeElements = () => {\n polyfillCustomElements()\n document.addEventListener('DOMContentLoaded', defineElements)\n document.addEventListener('turbo:load', defineElements)\n document.addEventListener('turbo:before-cache', restorePlaceholders)\n document.addEventListener('turbolinks:load', defineElements)\n document.addEventListener('turbolinks:before-cache', restorePlaceholders)\n document.addEventListener('cable-ready:after-outer-html', cachePlaceholders)\n}\n","/* global crypto */\n\nexport async function sha256 (message) {\n // encode as UTF-8\n const msgBuffer = new TextEncoder('utf-8').encode(message)\n\n // hash the message\n const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer)\n\n // convert ArrayBuffer to Array\n const hashArray = Array.from(new Uint8Array(hashBuffer))\n\n // convert bytes to hex string\n const hashHex = hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join('')\n\n return hashHex\n}\n"],"names":["createSubscription","consumer","subscriptions","create","connected","window","Futurism","this","document","addEventListener","callback","delay","timeoutId","events","args","clearTimeout","setTimeout","debounceEvents","send","signed_params","map","e","target","dataset","signedParams","sgids","sgid","signed_controllers","signedController","urls","_","location","href","broadcast_each","broadcastEach","received","data","cableReady","CableReady","perform","operations","emitMissingElementWarnings","dispatchEvent","CustomEvent","bubbles","cancelable","dispatchAppearEvent","entry","observer","evt","detail","callWithRetry","async","fn","depth","ms","Promise","resolve","observerCallback","entries","forEach","isIntersecting","extendElementWithIntersectionObserver","element","Object","assign","IntersectionObserver","bind","hasAttribute","observe","extendElementWithEagerLoading","eager","disconnect","FuturismElement","HTMLElement","connectedCallback","FuturismTableRow","HTMLTableRowElement","FuturismLI","HTMLLIElement","defineElements","customElements","get","define","extends","cachePlaceholders","message","msgBuffer","TextEncoder","encode","hashBuffer","crypto","subtle","digest","Array","from","Uint8Array","b","toString","slice","join","sha256","outerHTML","then","hashedContent","setAttribute","sessionStorage","setItem","futurismHash","restorePlaceholders","filter","key","_payload","startsWith","payload","match","exec","targetElement","querySelector","removeItem","initializeElements","isSafari","test","navigator","userAgent","write","createElement","constructor","polyfillCustomElements"],"mappings":"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"}
1
+ {"version":3,"file":"futurism.min.js","sources":["../../../javascript/futurism_channel.js","../../../javascript/elements/futurism_utils.js","../../../javascript/elements/futurism_element.js","../../../javascript/elements/futurism_table_row.js","../../../javascript/elements/futurism_li.js","../../../javascript/elements/index.js","../../../javascript/utils/crypto.js"],"sourcesContent":["/* global CustomEvent, setTimeout */\n\nimport CableReady from 'cable_ready'\n\nconst debounceEvents = (callback, delay = 20) => {\n let timeoutId\n let events = []\n return (...args) => {\n clearTimeout(timeoutId)\n events = [...events, ...args]\n timeoutId = setTimeout(() => {\n timeoutId = null\n callback(events)\n events = []\n }, delay)\n }\n}\n\nexport const createSubscription = consumer => {\n consumer.subscriptions.create('Futurism::Channel', {\n connected () {\n window.Futurism = {\n subscription: this\n }\n document.addEventListener(\n 'futurism:appear',\n debounceEvents(events => {\n this.send({\n signed_params: events.map(e => e.target.dataset.signedParams),\n sgids: events.map(e => e.target.dataset.sgid),\n signed_controllers: events.map(\n e => e.target.dataset.signedController\n ),\n urls: events.map(_ => window.location.href),\n broadcast_each: events.map(e => e.target.dataset.broadcastEach)\n })\n })\n )\n },\n\n received (data) {\n if (data.cableReady) {\n CableReady.perform(data.operations, {\n emitMissingElementWarnings: false\n })\n\n document.dispatchEvent(\n new CustomEvent('futurism:appeared', {\n bubbles: true,\n cancelable: true\n })\n )\n }\n }\n })\n}\n","/* global IntersectionObserver, CustomEvent, setTimeout */\n\nconst dispatchAppearEvent = (entry, observer = null) => {\n if (!window.Futurism?.subscription) {\n return () => {\n setTimeout(() => dispatchAppearEvent(entry, observer)(), 1)\n }\n }\n\n const target = entry.target ? entry.target : entry\n\n const evt = new CustomEvent('futurism:appear', {\n bubbles: true,\n detail: {\n target,\n observer\n }\n })\n\n return () => {\n target.dispatchEvent(evt)\n }\n}\n\n// from https://advancedweb.hu/how-to-implement-an-exponential-backoff-retry-strategy-in-javascript/#rejection-based-retrying\nconst wait = ms => new Promise(resolve => setTimeout(resolve, ms))\n\nconst callWithRetry = async (fn, depth = 0) => {\n try {\n return await fn()\n } catch (e) {\n if (depth > 10) {\n throw e\n }\n await wait(1.15 ** depth * 2000)\n\n return callWithRetry(fn, depth + 1)\n }\n}\n\nconst observerCallback = (entries, observer) => {\n entries.forEach(async entry => {\n if (!entry.isIntersecting) return\n\n await callWithRetry(dispatchAppearEvent(entry, observer))\n })\n}\n\nexport const extendElementWithIntersectionObserver = element => {\n Object.assign(element, {\n observer: new IntersectionObserver(observerCallback.bind(element), {})\n })\n\n if (!element.hasAttribute('keep')) {\n element.observer.observe(element)\n }\n}\n\nexport const extendElementWithEagerLoading = element => {\n if (element.dataset.eager === 'true') {\n if (element.observer) element.observer.disconnect()\n callWithRetry(dispatchAppearEvent(element))\n }\n}\n","/* global HTMLElement */\n\nimport {\n extendElementWithIntersectionObserver,\n extendElementWithEagerLoading\n} from './futurism_utils'\n\nexport default class FuturismElement extends HTMLElement {\n connectedCallback () {\n extendElementWithIntersectionObserver(this)\n extendElementWithEagerLoading(this)\n }\n}\n","/* global HTMLTableRowElement */\n\nimport {\n extendElementWithIntersectionObserver,\n extendElementWithEagerLoading\n} from './futurism_utils'\n\nexport default class FuturismTableRow extends HTMLTableRowElement {\n connectedCallback () {\n extendElementWithIntersectionObserver(this)\n extendElementWithEagerLoading(this)\n }\n}\n","/* global HTMLLIElement */\r\n\r\nimport {\r\n extendElementWithIntersectionObserver,\r\n extendElementWithEagerLoading\r\n} from './futurism_utils'\r\n\r\nexport default class FuturismLI extends HTMLLIElement {\r\n connectedCallback () {\r\n extendElementWithIntersectionObserver(this)\r\n extendElementWithEagerLoading(this)\r\n }\r\n}\r\n","/* global customElements, sessionStorage */\n\nimport FuturismElement from './futurism_element'\nimport FuturismTableRow from './futurism_table_row'\nimport FuturismLI from './futurism_li'\n\nimport { sha256 } from '../utils/crypto'\n\nconst polyfillCustomElements = () => {\n const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)\n\n if (customElements) {\n if (isSafari) {\n document.write(\n '<script src=\"//unpkg.com/@ungap/custom-elements-builtin\"><\\x2fscript>'\n )\n } else {\n try {\n customElements.define(\n 'built-in',\n document.createElement('tr').constructor,\n { extends: 'tr' }\n )\n } catch (_) {\n document.write(\n '<script src=\"//unpkg.com/@ungap/custom-elements-builtin\"><\\x2fscript>'\n )\n }\n }\n } else {\n document.write(\n '<script src=\"//unpkg.com/document-register-element\"><\\x2fscript>'\n )\n }\n}\n\nconst defineElements = e => {\n if (!customElements.get('futurism-element')) {\n customElements.define('futurism-element', FuturismElement)\n customElements.define('futurism-table-row', FuturismTableRow, {\n extends: 'tr'\n })\n customElements.define('futurism-li', FuturismLI, { extends: 'li' })\n }\n}\n\nconst cachePlaceholders = e => {\n sha256(e.detail.element.outerHTML).then(hashedContent => {\n e.detail.element.setAttribute('keep', '')\n sessionStorage.setItem(\n `futurism-${hashedContent}`,\n e.detail.element.outerHTML\n )\n e.target.dataset.futurismHash = hashedContent\n })\n}\n\nconst restorePlaceholders = e => {\n // we have to opt out of this if the request leading to this is a TF request\n // if the TF request has been promoted to an advance action\n // (data-turbo-action=\"advance\"), this callback will fire inadvertently\n // but the whole page will not be exchanged as in a regular TD visit\n if (sessionStorage.getItem('requested-turbo-frame')) {\n delete sessionStorage.removeItem('requested-turbo-frame')\n return\n }\n\n const inNamespace = ([key, _payload]) => key.startsWith('futurism-')\n Object.entries(sessionStorage)\n .filter(inNamespace)\n .forEach(([key, payload]) => {\n const match = /^futurism-(.*)/.exec(key)\n const targetElement = document.querySelector(\n `[data-futurism-hash=\"${match[1]}\"]`\n )\n\n if (targetElement) {\n targetElement.outerHTML = payload\n sessionStorage.removeItem(key)\n }\n })\n}\n\nconst storeRequestedTurboFrame = e => {\n const { headers } = e.detail.fetchOptions\n\n if (!headers['Turbo-Frame'] || headers['X-Sec-Purpose'] === 'prefetch') return\n\n // we store the frame ID in case the incoming request was referencing one\n sessionStorage.setItem('requested-turbo-frame', headers['Turbo-Frame'])\n}\n\nexport const initializeElements = () => {\n polyfillCustomElements()\n document.addEventListener('DOMContentLoaded', defineElements)\n document.addEventListener('turbo:load', defineElements)\n document.addEventListener('turbo:before-cache', restorePlaceholders)\n document.addEventListener('turbolinks:load', defineElements)\n document.addEventListener('turbolinks:before-cache', restorePlaceholders)\n document.addEventListener('cable-ready:after-outer-html', cachePlaceholders)\n\n document.addEventListener(\n 'turbo:before-fetch-request',\n storeRequestedTurboFrame\n )\n}\n","/* global crypto */\n\nexport async function sha256 (message) {\n // encode as UTF-8\n const msgBuffer = new TextEncoder('utf-8').encode(message)\n\n // hash the message\n const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer)\n\n // convert ArrayBuffer to Array\n const hashArray = Array.from(new Uint8Array(hashBuffer))\n\n // convert bytes to hex string\n const hashHex = hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join('')\n\n return hashHex\n}\n"],"names":["createSubscription","consumer","subscriptions","create","connected","window","Futurism","subscription","this","document","addEventListener","callback","delay","timeoutId","events","args","clearTimeout","setTimeout","debounceEvents","send","signed_params","map","e","target","dataset","signedParams","sgids","sgid","signed_controllers","signedController","urls","_","location","href","broadcast_each","broadcastEach","received","data","cableReady","CableReady","perform","operations","emitMissingElementWarnings","dispatchEvent","CustomEvent","bubbles","cancelable","dispatchAppearEvent","entry","observer","evt","detail","callWithRetry","async","fn","depth","ms","Promise","resolve","observerCallback","entries","forEach","isIntersecting","extendElementWithIntersectionObserver","element","Object","assign","IntersectionObserver","bind","hasAttribute","observe","extendElementWithEagerLoading","eager","disconnect","FuturismElement","HTMLElement","connectedCallback","FuturismTableRow","HTMLTableRowElement","FuturismLI","HTMLLIElement","defineElements","customElements","get","define","extends","cachePlaceholders","message","msgBuffer","TextEncoder","encode","hashBuffer","crypto","subtle","digest","Array","from","Uint8Array","b","toString","slice","join","sha256","outerHTML","then","hashedContent","setAttribute","sessionStorage","setItem","futurismHash","restorePlaceholders","getItem","removeItem","filter","key","_payload","startsWith","payload","match","exec","targetElement","querySelector","storeRequestedTurboFrame","headers","fetchOptions","initializeElements","isSafari","test","navigator","userAgent","write","createElement","constructor","polyfillCustomElements"],"mappings":"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"}
@@ -25,7 +25,9 @@
25
25
  const createSubscription = consumer => {
26
26
  consumer.subscriptions.create("Futurism::Channel", {
27
27
  connected() {
28
- window.Futurism = this;
28
+ window.Futurism = {
29
+ subscription: this
30
+ };
29
31
  document.addEventListener("futurism:appear", debounceEvents((events => {
30
32
  this.send({
31
33
  signed_params: events.map((e => e.target.dataset.signedParams)),
@@ -50,7 +52,7 @@
50
52
  });
51
53
  };
52
54
  const dispatchAppearEvent = (entry, observer = null) => {
53
- if (!window.Futurism) {
55
+ if (!window.Futurism?.subscription) {
54
56
  return () => {
55
57
  setTimeout((() => dispatchAppearEvent(entry, observer)()), 1);
56
58
  };
@@ -161,6 +163,10 @@
161
163
  }));
162
164
  };
163
165
  const restorePlaceholders = e => {
166
+ if (sessionStorage.getItem("requested-turbo-frame")) {
167
+ delete sessionStorage.removeItem("requested-turbo-frame");
168
+ return;
169
+ }
164
170
  const inNamespace = ([key, _payload]) => key.startsWith("futurism-");
165
171
  Object.entries(sessionStorage).filter(inNamespace).forEach((([key, payload]) => {
166
172
  const match = /^futurism-(.*)/.exec(key);
@@ -171,6 +177,11 @@
171
177
  }
172
178
  }));
173
179
  };
180
+ const storeRequestedTurboFrame = e => {
181
+ const {headers: headers} = e.detail.fetchOptions;
182
+ if (!headers["Turbo-Frame"] || headers["X-Sec-Purpose"] === "prefetch") return;
183
+ sessionStorage.setItem("requested-turbo-frame", headers["Turbo-Frame"]);
184
+ };
174
185
  const initializeElements = () => {
175
186
  polyfillCustomElements();
176
187
  document.addEventListener("DOMContentLoaded", defineElements);
@@ -179,6 +190,7 @@
179
190
  document.addEventListener("turbolinks:load", defineElements);
180
191
  document.addEventListener("turbolinks:before-cache", restorePlaceholders);
181
192
  document.addEventListener("cable-ready:after-outer-html", cachePlaceholders);
193
+ document.addEventListener("turbo:before-fetch-request", storeRequestedTurboFrame);
182
194
  };
183
195
  exports.createSubscription = createSubscription;
184
196
  exports.initializeElements = initializeElements;
@@ -1,2 +1,2 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("cable_ready")):"function"==typeof define&&define.amd?define(["exports","cable_ready"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Futurism={},e.CableReady)}(this,(function(e,t){"use strict";function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var s=n(t);const r=(e,t=null)=>{if(!window.Futurism)return()=>{setTimeout((()=>r(e,t)()),1)};const n=e.target?e.target:e,s=new CustomEvent("futurism:appear",{bubbles:!0,detail:{target:n,observer:t}});return()=>{n.dispatchEvent(s)}},i=async(e,t=0)=>{try{return await e()}catch(s){if(t>10)throw s;return await(n=1.15**t*2e3,new Promise((e=>setTimeout(e,n)))),i(e,t+1)}var n},a=(e,t)=>{e.forEach((async e=>{e.isIntersecting&&await i(r(e,t))}))},o=e=>{Object.assign(e,{observer:new IntersectionObserver(a.bind(e),{})}),e.hasAttribute("keep")||e.observer.observe(e)},u=e=>{"true"===e.dataset.eager&&(e.observer&&e.observer.disconnect(),i(r(e)))};class c extends HTMLElement{connectedCallback(){o(this),u(this)}}class d extends HTMLTableRowElement{connectedCallback(){o(this),u(this)}}class m extends HTMLLIElement{connectedCallback(){o(this),u(this)}}const l=e=>{customElements.get("futurism-element")||(customElements.define("futurism-element",c),customElements.define("futurism-table-row",d,{extends:"tr"}),customElements.define("futurism-li",m,{extends:"li"}))},f=e=>{(async function(e){const t=new TextEncoder("utf-8").encode(e),n=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(n)).map((e=>("00"+e.toString(16)).slice(-2))).join("")})(e.detail.element.outerHTML).then((t=>{e.detail.element.setAttribute("keep",""),sessionStorage.setItem(`futurism-${t}`,e.detail.element.outerHTML),e.target.dataset.futurismHash=t}))},b=e=>{Object.entries(sessionStorage).filter((([e,t])=>e.startsWith("futurism-"))).forEach((([e,t])=>{const n=/^futurism-(.*)/.exec(e),s=document.querySelector(`[data-futurism-hash="${n[1]}"]`);s&&(s.outerHTML=t,sessionStorage.removeItem(e))}))};e.createSubscription=e=>{e.subscriptions.create("Futurism::Channel",{connected(){window.Futurism=this,document.addEventListener("futurism:appear",((e,t=20)=>{let n,s=[];return(...r)=>{clearTimeout(n),s=[...s,...r],n=setTimeout((()=>{n=null,e(s),s=[]}),t)}})((e=>{this.send({signed_params:e.map((e=>e.target.dataset.signedParams)),sgids:e.map((e=>e.target.dataset.sgid)),signed_controllers:e.map((e=>e.target.dataset.signedController)),urls:e.map((e=>window.location.href)),broadcast_each:e.map((e=>e.target.dataset.broadcastEach))})})))},received(e){e.cableReady&&(s.default.perform(e.operations,{emitMissingElementWarnings:!1}),document.dispatchEvent(new CustomEvent("futurism:appeared",{bubbles:!0,cancelable:!0})))}})},e.initializeElements=()=>{(()=>{const e=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);if(customElements)if(e)document.write('<script src="//unpkg.com/@ungap/custom-elements-builtin"><\/script>');else try{customElements.define("built-in",document.createElement("tr").constructor,{extends:"tr"})}catch(e){document.write('<script src="//unpkg.com/@ungap/custom-elements-builtin"><\/script>')}else document.write('<script src="//unpkg.com/document-register-element"><\/script>')})(),document.addEventListener("DOMContentLoaded",l),document.addEventListener("turbo:load",l),document.addEventListener("turbo:before-cache",b),document.addEventListener("turbolinks:load",l),document.addEventListener("turbolinks:before-cache",b),document.addEventListener("cable-ready:after-outer-html",f)},Object.defineProperty(e,"__esModule",{value:!0})}));
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("cable_ready")):"function"==typeof define&&define.amd?define(["exports","cable_ready"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Futurism={},e.CableReady)}(this,(function(e,t){"use strict";function s(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var r=s(t);const n=(e,t=null)=>{if(!window.Futurism?.subscription)return()=>{setTimeout((()=>n(e,t)()),1)};const s=e.target?e.target:e,r=new CustomEvent("futurism:appear",{bubbles:!0,detail:{target:s,observer:t}});return()=>{s.dispatchEvent(r)}},i=async(e,t=0)=>{try{return await e()}catch(r){if(t>10)throw r;return await(s=1.15**t*2e3,new Promise((e=>setTimeout(e,s)))),i(e,t+1)}var s},a=(e,t)=>{e.forEach((async e=>{e.isIntersecting&&await i(n(e,t))}))},o=e=>{Object.assign(e,{observer:new IntersectionObserver(a.bind(e),{})}),e.hasAttribute("keep")||e.observer.observe(e)},u=e=>{"true"===e.dataset.eager&&(e.observer&&e.observer.disconnect(),i(n(e)))};class c extends HTMLElement{connectedCallback(){o(this),u(this)}}class d extends HTMLTableRowElement{connectedCallback(){o(this),u(this)}}class m extends HTMLLIElement{connectedCallback(){o(this),u(this)}}const l=e=>{customElements.get("futurism-element")||(customElements.define("futurism-element",c),customElements.define("futurism-table-row",d,{extends:"tr"}),customElements.define("futurism-li",m,{extends:"li"}))},f=e=>{(async function(e){const t=new TextEncoder("utf-8").encode(e),s=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(s)).map((e=>("00"+e.toString(16)).slice(-2))).join("")})(e.detail.element.outerHTML).then((t=>{e.detail.element.setAttribute("keep",""),sessionStorage.setItem(`futurism-${t}`,e.detail.element.outerHTML),e.target.dataset.futurismHash=t}))},b=e=>{if(sessionStorage.getItem("requested-turbo-frame"))return void sessionStorage.removeItem("requested-turbo-frame");Object.entries(sessionStorage).filter((([e,t])=>e.startsWith("futurism-"))).forEach((([e,t])=>{const s=/^futurism-(.*)/.exec(e),r=document.querySelector(`[data-futurism-hash="${s[1]}"]`);r&&(r.outerHTML=t,sessionStorage.removeItem(e))}))},p=e=>{const{headers:t}=e.detail.fetchOptions;t["Turbo-Frame"]&&"prefetch"!==t["X-Sec-Purpose"]&&sessionStorage.setItem("requested-turbo-frame",t["Turbo-Frame"])};e.createSubscription=e=>{e.subscriptions.create("Futurism::Channel",{connected(){window.Futurism={subscription:this},document.addEventListener("futurism:appear",((e,t=20)=>{let s,r=[];return(...n)=>{clearTimeout(s),r=[...r,...n],s=setTimeout((()=>{s=null,e(r),r=[]}),t)}})((e=>{this.send({signed_params:e.map((e=>e.target.dataset.signedParams)),sgids:e.map((e=>e.target.dataset.sgid)),signed_controllers:e.map((e=>e.target.dataset.signedController)),urls:e.map((e=>window.location.href)),broadcast_each:e.map((e=>e.target.dataset.broadcastEach))})})))},received(e){e.cableReady&&(r.default.perform(e.operations,{emitMissingElementWarnings:!1}),document.dispatchEvent(new CustomEvent("futurism:appeared",{bubbles:!0,cancelable:!0})))}})},e.initializeElements=()=>{(()=>{const e=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);if(customElements)if(e)document.write('<script src="//unpkg.com/@ungap/custom-elements-builtin"><\/script>');else try{customElements.define("built-in",document.createElement("tr").constructor,{extends:"tr"})}catch(e){document.write('<script src="//unpkg.com/@ungap/custom-elements-builtin"><\/script>')}else document.write('<script src="//unpkg.com/document-register-element"><\/script>')})(),document.addEventListener("DOMContentLoaded",l),document.addEventListener("turbo:load",l),document.addEventListener("turbo:before-cache",b),document.addEventListener("turbolinks:load",l),document.addEventListener("turbolinks:before-cache",b),document.addEventListener("cable-ready:after-outer-html",f),document.addEventListener("turbo:before-fetch-request",p)},Object.defineProperty(e,"__esModule",{value:!0})}));
2
2
  //# sourceMappingURL=futurism.umd.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"futurism.umd.min.js","sources":["../../../javascript/futurism_channel.js","../../../javascript/elements/futurism_utils.js","../../../javascript/elements/futurism_element.js","../../../javascript/elements/futurism_table_row.js","../../../javascript/elements/futurism_li.js","../../../javascript/elements/index.js","../../../javascript/utils/crypto.js"],"sourcesContent":["/* global CustomEvent, setTimeout */\n\nimport CableReady from 'cable_ready'\n\nconst debounceEvents = (callback, delay = 20) => {\n let timeoutId\n let events = []\n return (...args) => {\n clearTimeout(timeoutId)\n events = [...events, ...args]\n timeoutId = setTimeout(() => {\n timeoutId = null\n callback(events)\n events = []\n }, delay)\n }\n}\n\nexport const createSubscription = consumer => {\n consumer.subscriptions.create('Futurism::Channel', {\n connected () {\n window.Futurism = this\n document.addEventListener(\n 'futurism:appear',\n debounceEvents(events => {\n this.send({\n signed_params: events.map(e => e.target.dataset.signedParams),\n sgids: events.map(e => e.target.dataset.sgid),\n signed_controllers: events.map(\n e => e.target.dataset.signedController\n ),\n urls: events.map(_ => window.location.href),\n broadcast_each: events.map(e => e.target.dataset.broadcastEach)\n })\n })\n )\n },\n\n received (data) {\n if (data.cableReady) {\n CableReady.perform(data.operations, {\n emitMissingElementWarnings: false\n })\n\n document.dispatchEvent(\n new CustomEvent('futurism:appeared', {\n bubbles: true,\n cancelable: true\n })\n )\n }\n }\n })\n}\n","/* global IntersectionObserver, CustomEvent, setTimeout */\n\nconst dispatchAppearEvent = (entry, observer = null) => {\n if (!window.Futurism) {\n return () => {\n setTimeout(() => dispatchAppearEvent(entry, observer)(), 1)\n }\n }\n\n const target = entry.target ? entry.target : entry\n\n const evt = new CustomEvent('futurism:appear', {\n bubbles: true,\n detail: {\n target,\n observer\n }\n })\n\n return () => {\n target.dispatchEvent(evt)\n }\n}\n\n// from https://advancedweb.hu/how-to-implement-an-exponential-backoff-retry-strategy-in-javascript/#rejection-based-retrying\nconst wait = ms => new Promise(resolve => setTimeout(resolve, ms))\n\nconst callWithRetry = async (fn, depth = 0) => {\n try {\n return await fn()\n } catch (e) {\n if (depth > 10) {\n throw e\n }\n await wait(1.15 ** depth * 2000)\n\n return callWithRetry(fn, depth + 1)\n }\n}\n\nconst observerCallback = (entries, observer) => {\n entries.forEach(async entry => {\n if (!entry.isIntersecting) return\n\n await callWithRetry(dispatchAppearEvent(entry, observer))\n })\n}\n\nexport const extendElementWithIntersectionObserver = element => {\n Object.assign(element, {\n observer: new IntersectionObserver(observerCallback.bind(element), {})\n })\n\n if (!element.hasAttribute('keep')) {\n element.observer.observe(element)\n }\n}\n\nexport const extendElementWithEagerLoading = element => {\n if (element.dataset.eager === 'true') {\n if (element.observer) element.observer.disconnect()\n callWithRetry(dispatchAppearEvent(element))\n }\n}\n","/* global HTMLElement */\n\nimport {\n extendElementWithIntersectionObserver,\n extendElementWithEagerLoading\n} from './futurism_utils'\n\nexport default class FuturismElement extends HTMLElement {\n connectedCallback () {\n extendElementWithIntersectionObserver(this)\n extendElementWithEagerLoading(this)\n }\n}\n","/* global HTMLTableRowElement */\n\nimport {\n extendElementWithIntersectionObserver,\n extendElementWithEagerLoading\n} from './futurism_utils'\n\nexport default class FuturismTableRow extends HTMLTableRowElement {\n connectedCallback () {\n extendElementWithIntersectionObserver(this)\n extendElementWithEagerLoading(this)\n }\n}\n","/* global HTMLLIElement */\r\n\r\nimport {\r\n extendElementWithIntersectionObserver,\r\n extendElementWithEagerLoading\r\n} from './futurism_utils'\r\n\r\nexport default class FuturismLI extends HTMLLIElement {\r\n connectedCallback () {\r\n extendElementWithIntersectionObserver(this)\r\n extendElementWithEagerLoading(this)\r\n }\r\n}\r\n","/* global customElements, sessionStorage */\n\nimport FuturismElement from './futurism_element'\nimport FuturismTableRow from './futurism_table_row'\nimport FuturismLI from './futurism_li'\n\nimport { sha256 } from '../utils/crypto'\n\nconst polyfillCustomElements = () => {\n const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)\n\n if (customElements) {\n if (isSafari) {\n document.write(\n '<script src=\"//unpkg.com/@ungap/custom-elements-builtin\"><\\x2fscript>'\n )\n } else {\n try {\n customElements.define(\n 'built-in',\n document.createElement('tr').constructor,\n { extends: 'tr' }\n )\n } catch (_) {\n document.write(\n '<script src=\"//unpkg.com/@ungap/custom-elements-builtin\"><\\x2fscript>'\n )\n }\n }\n } else {\n document.write(\n '<script src=\"//unpkg.com/document-register-element\"><\\x2fscript>'\n )\n }\n}\n\nconst defineElements = e => {\n if (!customElements.get('futurism-element')) {\n customElements.define('futurism-element', FuturismElement)\n customElements.define('futurism-table-row', FuturismTableRow, {\n extends: 'tr'\n })\n customElements.define('futurism-li', FuturismLI, { extends: 'li' })\n }\n}\n\nconst cachePlaceholders = e => {\n sha256(e.detail.element.outerHTML).then(hashedContent => {\n e.detail.element.setAttribute('keep', '')\n sessionStorage.setItem(\n `futurism-${hashedContent}`,\n e.detail.element.outerHTML\n )\n e.target.dataset.futurismHash = hashedContent\n })\n}\n\nconst restorePlaceholders = e => {\n const inNamespace = ([key, _payload]) => key.startsWith('futurism-')\n Object.entries(sessionStorage)\n .filter(inNamespace)\n .forEach(([key, payload]) => {\n const match = /^futurism-(.*)/.exec(key)\n const targetElement = document.querySelector(\n `[data-futurism-hash=\"${match[1]}\"]`\n )\n\n if (targetElement) {\n targetElement.outerHTML = payload\n sessionStorage.removeItem(key)\n }\n })\n}\n\nexport const initializeElements = () => {\n polyfillCustomElements()\n document.addEventListener('DOMContentLoaded', defineElements)\n document.addEventListener('turbo:load', defineElements)\n document.addEventListener('turbo:before-cache', restorePlaceholders)\n document.addEventListener('turbolinks:load', defineElements)\n document.addEventListener('turbolinks:before-cache', restorePlaceholders)\n document.addEventListener('cable-ready:after-outer-html', cachePlaceholders)\n}\n","/* global crypto */\n\nexport async function sha256 (message) {\n // encode as UTF-8\n const msgBuffer = new TextEncoder('utf-8').encode(message)\n\n // hash the message\n const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer)\n\n // convert ArrayBuffer to Array\n const hashArray = Array.from(new Uint8Array(hashBuffer))\n\n // convert bytes to hex string\n const hashHex = hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join('')\n\n return hashHex\n}\n"],"names":["dispatchAppearEvent","entry","observer","window","Futurism","setTimeout","target","evt","CustomEvent","bubbles","detail","dispatchEvent","callWithRetry","async","fn","depth","e","ms","Promise","resolve","observerCallback","entries","forEach","isIntersecting","extendElementWithIntersectionObserver","element","Object","assign","IntersectionObserver","bind","hasAttribute","observe","extendElementWithEagerLoading","dataset","eager","disconnect","FuturismElement","HTMLElement","connectedCallback","this","FuturismTableRow","HTMLTableRowElement","FuturismLI","HTMLLIElement","defineElements","customElements","get","define","extends","cachePlaceholders","message","msgBuffer","TextEncoder","encode","hashBuffer","crypto","subtle","digest","Array","from","Uint8Array","map","b","toString","slice","join","sha256","outerHTML","then","hashedContent","setAttribute","sessionStorage","setItem","futurismHash","restorePlaceholders","filter","key","_payload","startsWith","payload","match","exec","targetElement","document","querySelector","removeItem","consumer","subscriptions","create","connected","addEventListener","callback","delay","timeoutId","events","args","clearTimeout","debounceEvents","send","signed_params","signedParams","sgids","sgid","signed_controllers","signedController","urls","_","location","href","broadcast_each","broadcastEach","received","data","cableReady","CableReady","perform","operations","emitMissingElementWarnings","cancelable","isSafari","test","navigator","userAgent","write","createElement","constructor","polyfillCustomElements"],"mappings":"uXAIA,MCFMA,EAAsB,CAACC,EAAOC,EAAW,QAC7C,IAAKC,OAAOC,SACV,MAAO,KACLC,YAAW,IAAML,EAAoBC,EAAOC,EAA3BF,IAAwC,EAAE,EAI/D,MAAMM,EAASL,EAAMK,OAASL,EAAMK,OAASL,EAEvCM,EAAM,IAAIC,YAAY,kBAAmB,CAC7CC,SAAS,EACTC,OAAQ,CACNJ,SACAJ,cAIJ,MAAO,KACLI,EAAOK,cAAcJ,EAAI,CAC1B,EAMGK,EAAgBC,MAAOC,EAAIC,EAAQ,KACvC,IACE,aAAaD,GACd,CAAC,MAAOE,GACP,GAAID,EAAQ,GACV,MAAMC,EAIR,aAXSC,EASE,MAAQF,EAAQ,IATZ,IAAIG,SAAQC,GAAWd,WAAWc,EAASF,MAWnDL,EAAcE,EAAIC,EAAQ,EAClC,CAZUE,KAYV,EAGGG,EAAmB,CAACC,EAASnB,KACjCmB,EAAQC,SAAQT,UACTZ,EAAMsB,sBAELX,EAAcZ,EAAoBC,EAAOC,GAAU,GACzD,EAGSsB,EAAwCC,IACnDC,OAAOC,OAAOF,EAAS,CACrBvB,SAAU,IAAI0B,qBAAqBR,EAAiBS,KAAKJ,GAAU,MAGhEA,EAAQK,aAAa,SACxBL,EAAQvB,SAAS6B,QAAQN,EAC1B,EAGUO,EAAgCP,IACb,SAA1BA,EAAQQ,QAAQC,QACdT,EAAQvB,UAAUuB,EAAQvB,SAASiC,aACvCvB,EAAcZ,EAAoByB,IACnC,ECvDY,MAAMW,UAAwBC,YAC3C,iBAAAC,GACEd,EAAsCe,MACtCP,EAA8BO,KAC/B,ECJY,MAAMC,UAAyBC,oBAC5C,iBAAAH,GACEd,EAAsCe,MACtCP,EAA8BO,KAC/B,ECJY,MAAMG,UAAmBC,cACtC,iBAAAL,GACEd,EAAsCe,MACtCP,EAA8BO,KAC/B,ECHH,MA4BMK,EAAiB5B,IAChB6B,eAAeC,IAAI,sBACtBD,eAAeE,OAAO,mBAAoBX,GAC1CS,eAAeE,OAAO,qBAAsBP,EAAkB,CAC5DQ,QAAS,OAEXH,eAAeE,OAAO,cAAeL,EAAY,CAAEM,QAAS,OAC7D,EAGGC,EAAoBjC,KC5CnBH,eAAuBqC,GAE5B,MAAMC,EAAY,IAAIC,YAAY,SAASC,OAAOH,GAG5CI,QAAmBC,OAAOC,OAAOC,OAAO,UAAWN,GAQzD,OALkBO,MAAMC,KAAK,IAAIC,WAAWN,IAGlBO,KAAIC,IAAM,KAAOA,EAAEC,SAAS,KAAKC,OAAO,KAAIC,KAAK,GAG7E,ED+BEC,CAAOlD,EAAEN,OAAOe,QAAQ0C,WAAWC,MAAKC,IACtCrD,EAAEN,OAAOe,QAAQ6C,aAAa,OAAQ,IACtCC,eAAeC,QACb,YAAYH,IACZrD,EAAEN,OAAOe,QAAQ0C,WAEnBnD,EAAEV,OAAO2B,QAAQwC,aAAeJ,CAAa,GAC7C,EAGEK,EAAsB1D,IAE1BU,OAAOL,QAAQkD,gBACZI,QAFiB,EAAEC,EAAKC,KAAcD,EAAIE,WAAW,eAGrDxD,SAAQ,EAAEsD,EAAKG,MACd,MAAMC,EAAQ,iBAAiBC,KAAKL,GAC9BM,EAAgBC,SAASC,cAC7B,wBAAwBJ,EAAM,QAG5BE,IACFA,EAAcf,UAAYY,EAC1BR,eAAec,WAAWT,GAC3B,GACD,uBLrD4BU,IAChCA,EAASC,cAAcC,OAAO,oBAAqB,CACjD,SAAAC,GACEtF,OAAOC,SAAWmC,KAClB4C,SAASO,iBACP,kBAnBe,EAACC,EAAUC,EAAQ,MACxC,IAAIC,EACAC,EAAS,GACb,MAAO,IAAIC,KACTC,aAAaH,GACbC,EAAS,IAAIA,KAAWC,GACxBF,EAAYxF,YAAW,KACrBwF,EAAY,KACZF,EAASG,GACTA,EAAS,EAAE,GACVF,EAAM,CACV,EASKK,EAAeH,IACbvD,KAAK2D,KAAK,CACRC,cAAeL,EAAOjC,KAAI7C,GAAKA,EAAEV,OAAO2B,QAAQmE,eAChDC,MAAOP,EAAOjC,KAAI7C,GAAKA,EAAEV,OAAO2B,QAAQqE,OACxCC,mBAAoBT,EAAOjC,KACzB7C,GAAKA,EAAEV,OAAO2B,QAAQuE,mBAExBC,KAAMX,EAAOjC,KAAI6C,GAAKvG,OAAOwG,SAASC,OACtCC,eAAgBf,EAAOjC,KAAI7C,GAAKA,EAAEV,OAAO2B,QAAQ6E,iBACjD,IAGP,EAED,QAAAC,CAAUC,GACJA,EAAKC,aACPC,UAAWC,QAAQH,EAAKI,WAAY,CAClCC,4BAA4B,IAG9BlC,SAASxE,cACP,IAAIH,YAAY,oBAAqB,CACnCC,SAAS,EACT6G,YAAY,KAInB,GACD,uBKsB8B,KAlEH,MAC7B,MAAMC,EAAW,iCAAiCC,KAAKC,UAAUC,WAEjE,GAAI7E,eACF,GAAI0E,EACFpC,SAASwC,MACP,4EAGF,IACE9E,eAAeE,OACb,WACAoC,SAASyC,cAAc,MAAMC,YAC7B,CAAE7E,QAAS,MAEd,CAAC,MAAO0D,GACPvB,SAASwC,MACP,sEAEH,MAGHxC,SAASwC,MACP,iEAEH,EA0CDG,GACA3C,SAASO,iBAAiB,mBAAoB9C,GAC9CuC,SAASO,iBAAiB,aAAc9C,GACxCuC,SAASO,iBAAiB,qBAAsBhB,GAChDS,SAASO,iBAAiB,kBAAmB9C,GAC7CuC,SAASO,iBAAiB,0BAA2BhB,GACrDS,SAASO,iBAAiB,+BAAgCzC,EAAkB"}
1
+ {"version":3,"file":"futurism.umd.min.js","sources":["../../../javascript/futurism_channel.js","../../../javascript/elements/futurism_utils.js","../../../javascript/elements/futurism_element.js","../../../javascript/elements/futurism_table_row.js","../../../javascript/elements/futurism_li.js","../../../javascript/elements/index.js","../../../javascript/utils/crypto.js"],"sourcesContent":["/* global CustomEvent, setTimeout */\n\nimport CableReady from 'cable_ready'\n\nconst debounceEvents = (callback, delay = 20) => {\n let timeoutId\n let events = []\n return (...args) => {\n clearTimeout(timeoutId)\n events = [...events, ...args]\n timeoutId = setTimeout(() => {\n timeoutId = null\n callback(events)\n events = []\n }, delay)\n }\n}\n\nexport const createSubscription = consumer => {\n consumer.subscriptions.create('Futurism::Channel', {\n connected () {\n window.Futurism = {\n subscription: this\n }\n document.addEventListener(\n 'futurism:appear',\n debounceEvents(events => {\n this.send({\n signed_params: events.map(e => e.target.dataset.signedParams),\n sgids: events.map(e => e.target.dataset.sgid),\n signed_controllers: events.map(\n e => e.target.dataset.signedController\n ),\n urls: events.map(_ => window.location.href),\n broadcast_each: events.map(e => e.target.dataset.broadcastEach)\n })\n })\n )\n },\n\n received (data) {\n if (data.cableReady) {\n CableReady.perform(data.operations, {\n emitMissingElementWarnings: false\n })\n\n document.dispatchEvent(\n new CustomEvent('futurism:appeared', {\n bubbles: true,\n cancelable: true\n })\n )\n }\n }\n })\n}\n","/* global IntersectionObserver, CustomEvent, setTimeout */\n\nconst dispatchAppearEvent = (entry, observer = null) => {\n if (!window.Futurism?.subscription) {\n return () => {\n setTimeout(() => dispatchAppearEvent(entry, observer)(), 1)\n }\n }\n\n const target = entry.target ? entry.target : entry\n\n const evt = new CustomEvent('futurism:appear', {\n bubbles: true,\n detail: {\n target,\n observer\n }\n })\n\n return () => {\n target.dispatchEvent(evt)\n }\n}\n\n// from https://advancedweb.hu/how-to-implement-an-exponential-backoff-retry-strategy-in-javascript/#rejection-based-retrying\nconst wait = ms => new Promise(resolve => setTimeout(resolve, ms))\n\nconst callWithRetry = async (fn, depth = 0) => {\n try {\n return await fn()\n } catch (e) {\n if (depth > 10) {\n throw e\n }\n await wait(1.15 ** depth * 2000)\n\n return callWithRetry(fn, depth + 1)\n }\n}\n\nconst observerCallback = (entries, observer) => {\n entries.forEach(async entry => {\n if (!entry.isIntersecting) return\n\n await callWithRetry(dispatchAppearEvent(entry, observer))\n })\n}\n\nexport const extendElementWithIntersectionObserver = element => {\n Object.assign(element, {\n observer: new IntersectionObserver(observerCallback.bind(element), {})\n })\n\n if (!element.hasAttribute('keep')) {\n element.observer.observe(element)\n }\n}\n\nexport const extendElementWithEagerLoading = element => {\n if (element.dataset.eager === 'true') {\n if (element.observer) element.observer.disconnect()\n callWithRetry(dispatchAppearEvent(element))\n }\n}\n","/* global HTMLElement */\n\nimport {\n extendElementWithIntersectionObserver,\n extendElementWithEagerLoading\n} from './futurism_utils'\n\nexport default class FuturismElement extends HTMLElement {\n connectedCallback () {\n extendElementWithIntersectionObserver(this)\n extendElementWithEagerLoading(this)\n }\n}\n","/* global HTMLTableRowElement */\n\nimport {\n extendElementWithIntersectionObserver,\n extendElementWithEagerLoading\n} from './futurism_utils'\n\nexport default class FuturismTableRow extends HTMLTableRowElement {\n connectedCallback () {\n extendElementWithIntersectionObserver(this)\n extendElementWithEagerLoading(this)\n }\n}\n","/* global HTMLLIElement */\r\n\r\nimport {\r\n extendElementWithIntersectionObserver,\r\n extendElementWithEagerLoading\r\n} from './futurism_utils'\r\n\r\nexport default class FuturismLI extends HTMLLIElement {\r\n connectedCallback () {\r\n extendElementWithIntersectionObserver(this)\r\n extendElementWithEagerLoading(this)\r\n }\r\n}\r\n","/* global customElements, sessionStorage */\n\nimport FuturismElement from './futurism_element'\nimport FuturismTableRow from './futurism_table_row'\nimport FuturismLI from './futurism_li'\n\nimport { sha256 } from '../utils/crypto'\n\nconst polyfillCustomElements = () => {\n const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)\n\n if (customElements) {\n if (isSafari) {\n document.write(\n '<script src=\"//unpkg.com/@ungap/custom-elements-builtin\"><\\x2fscript>'\n )\n } else {\n try {\n customElements.define(\n 'built-in',\n document.createElement('tr').constructor,\n { extends: 'tr' }\n )\n } catch (_) {\n document.write(\n '<script src=\"//unpkg.com/@ungap/custom-elements-builtin\"><\\x2fscript>'\n )\n }\n }\n } else {\n document.write(\n '<script src=\"//unpkg.com/document-register-element\"><\\x2fscript>'\n )\n }\n}\n\nconst defineElements = e => {\n if (!customElements.get('futurism-element')) {\n customElements.define('futurism-element', FuturismElement)\n customElements.define('futurism-table-row', FuturismTableRow, {\n extends: 'tr'\n })\n customElements.define('futurism-li', FuturismLI, { extends: 'li' })\n }\n}\n\nconst cachePlaceholders = e => {\n sha256(e.detail.element.outerHTML).then(hashedContent => {\n e.detail.element.setAttribute('keep', '')\n sessionStorage.setItem(\n `futurism-${hashedContent}`,\n e.detail.element.outerHTML\n )\n e.target.dataset.futurismHash = hashedContent\n })\n}\n\nconst restorePlaceholders = e => {\n // we have to opt out of this if the request leading to this is a TF request\n // if the TF request has been promoted to an advance action\n // (data-turbo-action=\"advance\"), this callback will fire inadvertently\n // but the whole page will not be exchanged as in a regular TD visit\n if (sessionStorage.getItem('requested-turbo-frame')) {\n delete sessionStorage.removeItem('requested-turbo-frame')\n return\n }\n\n const inNamespace = ([key, _payload]) => key.startsWith('futurism-')\n Object.entries(sessionStorage)\n .filter(inNamespace)\n .forEach(([key, payload]) => {\n const match = /^futurism-(.*)/.exec(key)\n const targetElement = document.querySelector(\n `[data-futurism-hash=\"${match[1]}\"]`\n )\n\n if (targetElement) {\n targetElement.outerHTML = payload\n sessionStorage.removeItem(key)\n }\n })\n}\n\nconst storeRequestedTurboFrame = e => {\n const { headers } = e.detail.fetchOptions\n\n if (!headers['Turbo-Frame'] || headers['X-Sec-Purpose'] === 'prefetch') return\n\n // we store the frame ID in case the incoming request was referencing one\n sessionStorage.setItem('requested-turbo-frame', headers['Turbo-Frame'])\n}\n\nexport const initializeElements = () => {\n polyfillCustomElements()\n document.addEventListener('DOMContentLoaded', defineElements)\n document.addEventListener('turbo:load', defineElements)\n document.addEventListener('turbo:before-cache', restorePlaceholders)\n document.addEventListener('turbolinks:load', defineElements)\n document.addEventListener('turbolinks:before-cache', restorePlaceholders)\n document.addEventListener('cable-ready:after-outer-html', cachePlaceholders)\n\n document.addEventListener(\n 'turbo:before-fetch-request',\n storeRequestedTurboFrame\n )\n}\n","/* global crypto */\n\nexport async function sha256 (message) {\n // encode as UTF-8\n const msgBuffer = new TextEncoder('utf-8').encode(message)\n\n // hash the message\n const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer)\n\n // convert ArrayBuffer to Array\n const hashArray = Array.from(new Uint8Array(hashBuffer))\n\n // convert bytes to hex string\n const hashHex = hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join('')\n\n return hashHex\n}\n"],"names":["dispatchAppearEvent","entry","observer","window","Futurism","subscription","setTimeout","target","evt","CustomEvent","bubbles","detail","dispatchEvent","callWithRetry","async","fn","depth","e","ms","Promise","resolve","observerCallback","entries","forEach","isIntersecting","extendElementWithIntersectionObserver","element","Object","assign","IntersectionObserver","bind","hasAttribute","observe","extendElementWithEagerLoading","dataset","eager","disconnect","FuturismElement","HTMLElement","connectedCallback","this","FuturismTableRow","HTMLTableRowElement","FuturismLI","HTMLLIElement","defineElements","customElements","get","define","extends","cachePlaceholders","message","msgBuffer","TextEncoder","encode","hashBuffer","crypto","subtle","digest","Array","from","Uint8Array","map","b","toString","slice","join","sha256","outerHTML","then","hashedContent","setAttribute","sessionStorage","setItem","futurismHash","restorePlaceholders","getItem","removeItem","filter","key","_payload","startsWith","payload","match","exec","targetElement","document","querySelector","storeRequestedTurboFrame","headers","fetchOptions","consumer","subscriptions","create","connected","addEventListener","callback","delay","timeoutId","events","args","clearTimeout","debounceEvents","send","signed_params","signedParams","sgids","sgid","signed_controllers","signedController","urls","_","location","href","broadcast_each","broadcastEach","received","data","cableReady","CableReady","perform","operations","emitMissingElementWarnings","cancelable","isSafari","test","navigator","userAgent","write","createElement","constructor","polyfillCustomElements"],"mappings":"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"}
data/futurism.gemspec CHANGED
@@ -16,6 +16,7 @@ Gem::Specification.new do |spec|
16
16
 
17
17
  spec.files = Dir[
18
18
  "lib/**/*.rb",
19
+ "lib/**/*.rake",
19
20
  "app/**/*.rb",
20
21
  "app/assets/javascripts/*",
21
22
  "bin/*",
data/futurism.gemspec~ CHANGED
@@ -29,7 +29,8 @@ Gem::Specification.new do |spec|
29
29
  spec.add_development_dependency "standardrb"
30
30
  spec.add_development_dependency "sqlite3"
31
31
 
32
- spec.add_dependency "rack", "~> 2.0"
32
+ spec.add_dependency "rack", ">= 2", "< 4"
33
+
33
34
  spec.add_dependency "rails", ">= 5.2"
34
35
  spec.add_dependency "cable_ready", ">= 5.0"
35
36
  end
@@ -1,3 +1,3 @@
1
1
  module Futurism
2
- VERSION = "1.4.1"
2
+ VERSION = "1.4.2"
3
3
  end
@@ -0,0 +1,41 @@
1
+ require "fileutils"
2
+
3
+ namespace :futurism do
4
+ desc "Let's look into a brighter future with futurism and CableReady"
5
+ task install: :environment do
6
+ system "yarn add @stimulus_reflex/futurism"
7
+
8
+ filepath = %w[
9
+ app/javascript/channels/index.js
10
+ app/javascript/channels/index.ts
11
+ app/javascript/application.js
12
+ app/javascript/application.ts
13
+ app/javascript/packs/application.js
14
+ app/javascript/packs/application.ts
15
+ ]
16
+ .select { |path| File.exist?(path) }
17
+ .map { |path| Rails.root.join(path) }
18
+ .first
19
+
20
+ puts "Updating #{filepath}"
21
+ lines = File.open(filepath, "r") { |f| f.readlines }
22
+
23
+ unless lines.find { |line| line.start_with?("import * as Futurism") }
24
+ matches = lines.select { |line| line =~ /\A(require|import)/ }
25
+ lines.insert lines.index(matches.last).to_i + 1, "import * as Futurism from '@stimulus_reflex/futurism'\n"
26
+ end
27
+
28
+ unless lines.find { |line| line.start_with?("import consumer") }
29
+ matches = lines.select { |line| line =~ /\A(require|import)/ }
30
+ lines.insert lines.index(matches.last).to_i + 1, "import consumer from '../channels/consumer'\n"
31
+ end
32
+
33
+ initialize_line = lines.find { |line| line.start_with?("Futurism.initializeElements") }
34
+ lines << "Futurism.initializeElements()\n" unless initialize_line
35
+
36
+ subscribe_line = lines.find { |line| line.start_with?("Futurism.createSubscription") }
37
+ lines << "Futurism.createSubscription(consumer)\n" unless subscribe_line
38
+
39
+ File.write(filepath, lines.join)
40
+ end
41
+ end
data/yarn.lock CHANGED
@@ -452,11 +452,11 @@ brace-expansion@^1.1.7:
452
452
  concat-map "0.0.1"
453
453
 
454
454
  braces@^3.0.1, braces@~3.0.2:
455
- version "3.0.2"
456
- resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
457
- integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
455
+ version "3.0.3"
456
+ resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
457
+ integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
458
458
  dependencies:
459
- fill-range "^7.0.1"
459
+ fill-range "^7.1.1"
460
460
 
461
461
  browser-stdout@1.3.1:
462
462
  version "1.3.1"
@@ -1108,10 +1108,10 @@ file-entry-cache@^5.0.1:
1108
1108
  dependencies:
1109
1109
  flat-cache "^2.0.1"
1110
1110
 
1111
- fill-range@^7.0.1:
1112
- version "7.0.1"
1113
- resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
1114
- integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
1111
+ fill-range@^7.1.1:
1112
+ version "7.1.1"
1113
+ resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
1114
+ integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
1115
1115
  dependencies:
1116
1116
  to-regex-range "^5.0.1"
1117
1117
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: futurism
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 1.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julian Rubisch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-22 00:00:00.000000000 Z
11
+ date: 2024-07-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: appraisal
@@ -186,6 +186,7 @@ files:
186
186
  - lib/futurism/resolver/resources.rb
187
187
  - lib/futurism/shims/deep_transform_values.rb
188
188
  - lib/futurism/version.rb
189
+ - lib/tasks/futurism_tasks.rake
189
190
  - package.json
190
191
  - package.json~
191
192
  - rollup.config.js