futurism 1.4.1 → 1.4.2

Sign up to get free protection for your applications and to get access to all the features.
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":"2BAIA,MAcaA,EAAqBC,IAChCA,EAASC,cAAcC,OAAO,oBAAqB,CACjD,SAAAC,GACEC,OAAOC,SAAWC,KAClBC,SAASC,iBACP,kBAnBe,EAACC,EAAUC,EAAQ,MACxC,IAAIC,EACAC,EAAS,GACb,MAAO,IAAIC,KACTC,aAAaH,GACbC,EAAS,IAAIA,KAAWC,GACxBF,EAAYI,YAAW,KACrBJ,EAAY,KACZF,EAASG,GACTA,EAAS,EAAE,GACVF,EAAM,CACV,EASKM,EAAeJ,IACbN,KAAKW,KAAK,CACRC,cAAeN,EAAOO,KAAIC,GAAKA,EAAEC,OAAOC,QAAQC,eAChDC,MAAOZ,EAAOO,KAAIC,GAAKA,EAAEC,OAAOC,QAAQG,OACxCC,mBAAoBd,EAAOO,KACzBC,GAAKA,EAAEC,OAAOC,QAAQK,mBAExBC,KAAMhB,EAAOO,KAAIU,GAAKzB,OAAO0B,SAASC,OACtCC,eAAgBpB,EAAOO,KAAIC,GAAKA,EAAEC,OAAOC,QAAQW,iBACjD,IAGP,EAED,QAAAC,CAAUC,GACJA,EAAKC,aACPC,EAAWC,QAAQH,EAAKI,WAAY,CAClCC,4BAA4B,IAG9BjC,SAASkC,cACP,IAAIC,YAAY,oBAAqB,CACnCC,SAAS,EACTC,YAAY,KAInB,GACD,EClDEC,EAAsB,CAACC,EAAOC,EAAW,QAC7C,IAAK3C,OAAOC,SACV,MAAO,KACLU,YAAW,IAAM8B,EAAoBC,EAAOC,EAA3BF,IAAwC,EAAE,EAI/D,MAAMxB,EAASyB,EAAMzB,OAASyB,EAAMzB,OAASyB,EAEvCE,EAAM,IAAIN,YAAY,kBAAmB,CAC7CC,SAAS,EACTM,OAAQ,CACN5B,SACA0B,cAIJ,MAAO,KACL1B,EAAOoB,cAAcO,EAAI,CAC1B,EAMGE,EAAgBC,MAAOC,EAAIC,EAAQ,KACvC,IACE,aAAaD,GACd,CAAC,MAAOhC,GACP,GAAIiC,EAAQ,GACV,MAAMjC,EAIR,aAXSkC,EASE,MAAQD,EAAQ,IATZ,IAAIE,SAAQC,GAAWzC,WAAWyC,EAASF,MAWnDJ,EAAcE,EAAIC,EAAQ,EAClC,CAZUC,KAYV,EAGGG,EAAmB,CAACC,EAASX,KACjCW,EAAQC,SAAQR,UACTL,EAAMc,sBAELV,EAAcL,EAAoBC,EAAOC,GAAU,GACzD,EAGSc,EAAwCC,IACnDC,OAAOC,OAAOF,EAAS,CACrBf,SAAU,IAAIkB,qBAAqBR,EAAiBS,KAAKJ,GAAU,MAGhEA,EAAQK,aAAa,SACxBL,EAAQf,SAASqB,QAAQN,EAC1B,EAGUO,EAAgCP,IACb,SAA1BA,EAAQxC,QAAQgD,QACdR,EAAQf,UAAUe,EAAQf,SAASwB,aACvCrB,EAAcL,EAAoBiB,IACnC,ECvDY,MAAMU,UAAwBC,YAC3C,iBAAAC,GACEb,EAAsCvD,MACtC+D,EAA8B/D,KAC/B,ECJY,MAAMqE,UAAyBC,oBAC5C,iBAAAF,GACEb,EAAsCvD,MACtC+D,EAA8B/D,KAC/B,ECJY,MAAMuE,UAAmBC,cACtC,iBAAAJ,GACEb,EAAsCvD,MACtC+D,EAA8B/D,KAC/B,ECHH,MA4BMyE,EAAiB3D,IAChB4D,eAAeC,IAAI,sBACtBD,eAAeE,OAAO,mBAAoBV,GAC1CQ,eAAeE,OAAO,qBAAsBP,EAAkB,CAC5DQ,QAAS,OAEXH,eAAeE,OAAO,cAAeL,EAAY,CAAEM,QAAS,OAC7D,EAGGC,EAAoBhE,KC5CnB+B,eAAuBkC,GAE5B,MAAMC,EAAY,IAAIC,YAAY,SAASC,OAAOH,GAG5CI,QAAmBC,OAAOC,OAAOC,OAAO,UAAWN,GAQzD,OALkBO,MAAMC,KAAK,IAAIC,WAAWN,IAGlBtE,KAAI6E,IAAM,KAAOA,EAAEC,SAAS,KAAKC,OAAO,KAAIC,KAAK,GAG7E,ED+BEC,CAAOhF,EAAE6B,OAAOa,QAAQuC,WAAWC,MAAKC,IACtCnF,EAAE6B,OAAOa,QAAQ0C,aAAa,OAAQ,IACtCC,eAAeC,QACb,YAAYH,IACZnF,EAAE6B,OAAOa,QAAQuC,WAEnBjF,EAAEC,OAAOC,QAAQqF,aAAeJ,CAAa,GAC7C,EAGEK,EAAsBxF,IAE1B2C,OAAOL,QAAQ+C,gBACZI,QAFiB,EAAEC,EAAKC,KAAcD,EAAIE,WAAW,eAGrDrD,SAAQ,EAAEmD,EAAKG,MACd,MAAMC,EAAQ,iBAAiBC,KAAKL,GAC9BM,EAAgB7G,SAAS8G,cAC7B,wBAAwBH,EAAM,QAG5BE,IACFA,EAAcf,UAAYY,EAC1BR,eAAea,WAAWR,GAC3B,GACD,EAGOS,EAAqB,KAlEH,MAC7B,MAAMC,EAAW,iCAAiCC,KAAKC,UAAUC,WAEjE,GAAI3C,eACF,GAAIwC,EACFjH,SAASqH,MACP,4EAGF,IACE5C,eAAeE,OACb,WACA3E,SAASsH,cAAc,MAAMC,YAC7B,CAAE3C,QAAS,MAEd,CAAC,MAAOtD,GACPtB,SAASqH,MACP,sEAEH,MAGHrH,SAASqH,MACP,iEAEH,EA0CDG,GACAxH,SAASC,iBAAiB,mBAAoBuE,GAC9CxE,SAASC,iBAAiB,aAAcuE,GACxCxE,SAASC,iBAAiB,qBAAsBoG,GAChDrG,SAASC,iBAAiB,kBAAmBuE,GAC7CxE,SAASC,iBAAiB,0BAA2BoG,GACrDrG,SAASC,iBAAiB,+BAAgC4E,EAAkB"}
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":"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"}
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