@hotwired/turbo 7.1.0-rc.2 → 7.2.0-beta.1
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.
- package/dist/turbo.es2017-esm.js +730 -391
- package/dist/turbo.es2017-umd.js +735 -392
- package/dist/types/core/bardo.d.ts +7 -2
- package/dist/types/core/cache.d.ts +10 -0
- package/dist/types/core/drive/error_renderer.d.ts +1 -0
- package/dist/types/core/drive/form_submission.d.ts +13 -4
- package/dist/types/core/drive/history.d.ts +1 -1
- package/dist/types/core/drive/navigator.d.ts +1 -0
- package/dist/types/core/drive/page_renderer.d.ts +3 -0
- package/dist/types/core/drive/page_view.d.ts +8 -5
- package/dist/types/core/drive/preloader.d.ts +14 -0
- package/dist/types/core/drive/progress_bar.d.ts +1 -0
- package/dist/types/core/drive/visit.d.ts +3 -3
- package/dist/types/core/frames/frame_controller.d.ts +26 -16
- package/dist/types/core/frames/frame_redirector.d.ts +1 -1
- package/dist/types/core/frames/frame_renderer.d.ts +8 -1
- package/dist/types/core/frames/frame_view.d.ts +2 -1
- package/dist/types/core/frames/link_interceptor.d.ts +1 -1
- package/dist/types/core/index.d.ts +11 -2
- package/dist/types/core/native/adapter.d.ts +2 -1
- package/dist/types/core/native/browser_adapter.d.ts +17 -8
- package/dist/types/core/renderer.d.ts +12 -4
- package/dist/types/core/session.d.ts +68 -16
- package/dist/types/core/snapshot.d.ts +2 -1
- package/dist/types/core/view.d.ts +12 -6
- package/dist/types/elements/frame_element.d.ts +5 -1
- package/dist/types/elements/stream_element.d.ts +1 -0
- package/dist/types/elements/stream_source_element.d.ts +7 -0
- package/dist/types/http/fetch_request.d.ts +8 -0
- package/dist/types/observers/cache_observer.d.ts +1 -1
- package/dist/types/observers/form_link_interceptor.d.ts +14 -0
- package/dist/types/observers/link_click_observer.d.ts +2 -2
- package/dist/types/polyfills/submit-event.d.ts +1 -7
- package/dist/types/tests/functional/async_script_tests.d.ts +1 -6
- package/dist/types/tests/functional/autofocus_tests.d.ts +1 -9
- package/dist/types/tests/functional/cache_observer_tests.d.ts +1 -5
- package/dist/types/tests/functional/drive_disabled_tests.d.ts +1 -9
- package/dist/types/tests/functional/drive_tests.d.ts +1 -8
- package/dist/types/tests/functional/form_submission_tests.d.ts +1 -79
- package/dist/types/tests/functional/frame_navigation_tests.d.ts +1 -7
- package/dist/types/tests/functional/frame_tests.d.ts +1 -51
- package/dist/types/tests/functional/import_tests.d.ts +1 -4
- package/dist/types/tests/functional/loading_tests.d.ts +1 -13
- package/dist/types/tests/functional/navigation_tests.d.ts +1 -37
- package/dist/types/tests/functional/pausable_rendering_tests.d.ts +1 -6
- package/dist/types/tests/functional/pausable_requests_tests.d.ts +1 -6
- package/dist/types/tests/functional/preloader_tests.d.ts +1 -0
- package/dist/types/tests/functional/rendering_tests.d.ts +1 -35
- package/dist/types/tests/functional/scroll_restoration_tests.d.ts +1 -6
- package/dist/types/tests/functional/stream_tests.d.ts +1 -6
- package/dist/types/tests/functional/visit_tests.d.ts +1 -13
- package/dist/types/tests/helpers/page.d.ts +44 -0
- package/dist/types/tests/unit/deprecated_adapter_support_test.d.ts +10 -10
- package/dist/types/util.d.ts +6 -3
- package/package.json +22 -8
- package/CHANGELOG.md +0 -3
- package/dist/types/tests/functional/index.d.ts +0 -17
- package/dist/types/tests/helpers/functional_test_case.d.ts +0 -44
- package/dist/types/tests/helpers/remote_channel.d.ts +0 -10
- package/dist/types/tests/helpers/turbo_drive_test_case.d.ts +0 -21
package/dist/turbo.es2017-umd.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Turbo 7.
|
|
3
|
-
Copyright ©
|
|
2
|
+
Turbo 7.2.0-beta.1
|
|
3
|
+
Copyright © 2022 Basecamp, LLC
|
|
4
4
|
*/
|
|
5
5
|
(function (global, factory) {
|
|
6
6
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
7
7
|
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
8
8
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Turbo = {}));
|
|
9
|
-
}(this, (function (exports) { 'use strict';
|
|
9
|
+
})(this, (function (exports) { 'use strict';
|
|
10
10
|
|
|
11
11
|
(function () {
|
|
12
|
-
if (window.Reflect === undefined ||
|
|
12
|
+
if (window.Reflect === undefined ||
|
|
13
|
+
window.customElements === undefined ||
|
|
13
14
|
window.customElements.polyfillWrapFlushCallback) {
|
|
14
15
|
return;
|
|
15
16
|
}
|
|
16
17
|
const BuiltInHTMLElement = HTMLElement;
|
|
17
18
|
const wrapperForTheName = {
|
|
18
|
-
|
|
19
|
+
HTMLElement: function HTMLElement() {
|
|
19
20
|
return Reflect.construct(BuiltInHTMLElement, [], this.constructor);
|
|
20
|
-
}
|
|
21
|
+
},
|
|
21
22
|
};
|
|
22
|
-
window.HTMLElement =
|
|
23
|
-
wrapperForTheName['HTMLElement'];
|
|
23
|
+
window.HTMLElement = wrapperForTheName["HTMLElement"];
|
|
24
24
|
HTMLElement.prototype = BuiltInHTMLElement.prototype;
|
|
25
25
|
HTMLElement.prototype.constructor = HTMLElement;
|
|
26
26
|
Object.setPrototypeOf(HTMLElement, BuiltInHTMLElement);
|
|
@@ -78,7 +78,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
78
78
|
}
|
|
79
79
|
})(HTMLFormElement.prototype);
|
|
80
80
|
|
|
81
|
-
const submittersByForm = new WeakMap;
|
|
81
|
+
const submittersByForm = new WeakMap();
|
|
82
82
|
function findSubmitterFromClickTarget(target) {
|
|
83
83
|
const element = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;
|
|
84
84
|
const candidate = element ? element.closest("input, button") : null;
|
|
@@ -109,7 +109,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
109
109
|
if (this.type == "submit" && this.target instanceof HTMLFormElement) {
|
|
110
110
|
return submittersByForm.get(this.target);
|
|
111
111
|
}
|
|
112
|
-
}
|
|
112
|
+
},
|
|
113
113
|
});
|
|
114
114
|
})();
|
|
115
115
|
|
|
@@ -125,7 +125,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
125
125
|
this.delegate = new FrameElement.delegateConstructor(this);
|
|
126
126
|
}
|
|
127
127
|
static get observedAttributes() {
|
|
128
|
-
return ["disabled", "loading", "src"];
|
|
128
|
+
return ["disabled", "complete", "loading", "src"];
|
|
129
129
|
}
|
|
130
130
|
connectedCallback() {
|
|
131
131
|
this.delegate.connect();
|
|
@@ -135,6 +135,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
135
135
|
}
|
|
136
136
|
reload() {
|
|
137
137
|
const { src } = this;
|
|
138
|
+
this.removeAttribute("complete");
|
|
138
139
|
this.src = null;
|
|
139
140
|
this.src = src;
|
|
140
141
|
}
|
|
@@ -142,6 +143,9 @@ Copyright © 2021 Basecamp, LLC
|
|
|
142
143
|
if (name == "loading") {
|
|
143
144
|
this.delegate.loadingStyleChanged();
|
|
144
145
|
}
|
|
146
|
+
else if (name == "complete") {
|
|
147
|
+
this.delegate.completeChanged();
|
|
148
|
+
}
|
|
145
149
|
else if (name == "src") {
|
|
146
150
|
this.delegate.sourceURLChanged();
|
|
147
151
|
}
|
|
@@ -206,8 +210,10 @@ Copyright © 2021 Basecamp, LLC
|
|
|
206
210
|
}
|
|
207
211
|
function frameLoadingStyleFromString(style) {
|
|
208
212
|
switch (style.toLowerCase()) {
|
|
209
|
-
case "lazy":
|
|
210
|
-
|
|
213
|
+
case "lazy":
|
|
214
|
+
return FrameLoadingStyle.lazy;
|
|
215
|
+
default:
|
|
216
|
+
return FrameLoadingStyle.eager;
|
|
211
217
|
}
|
|
212
218
|
}
|
|
213
219
|
|
|
@@ -219,7 +225,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
219
225
|
if (url.hash) {
|
|
220
226
|
return url.hash.slice(1);
|
|
221
227
|
}
|
|
222
|
-
else if (anchorMatch = url.href.match(/#(.*)$/)) {
|
|
228
|
+
else if ((anchorMatch = url.href.match(/#(.*)$/))) {
|
|
223
229
|
return anchorMatch[1];
|
|
224
230
|
}
|
|
225
231
|
}
|
|
@@ -231,7 +237,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
231
237
|
return (getLastPathComponent(url).match(/\.[^.]*$/) || [])[0] || "";
|
|
232
238
|
}
|
|
233
239
|
function isHTML(url) {
|
|
234
|
-
return !!getExtension(url).match(/^(?:|\.(?:htm|html|xhtml))$/);
|
|
240
|
+
return !!getExtension(url).match(/^(?:|\.(?:htm|html|xhtml|php))$/);
|
|
235
241
|
}
|
|
236
242
|
function isPrefixedBy(baseURL, url) {
|
|
237
243
|
const prefix = getPrefix(url);
|
|
@@ -242,9 +248,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
242
248
|
}
|
|
243
249
|
function getRequestURL(url) {
|
|
244
250
|
const anchor = getAnchor(url);
|
|
245
|
-
return anchor != null
|
|
246
|
-
? url.href.slice(0, -(anchor.length + 1))
|
|
247
|
-
: url.href;
|
|
251
|
+
return anchor != null ? url.href.slice(0, -(anchor.length + 1)) : url.href;
|
|
248
252
|
}
|
|
249
253
|
function toCacheKey(url) {
|
|
250
254
|
return getRequestURL(url);
|
|
@@ -313,7 +317,11 @@ Copyright © 2021 Basecamp, LLC
|
|
|
313
317
|
}
|
|
314
318
|
|
|
315
319
|
function dispatch(eventName, { target, cancelable, detail } = {}) {
|
|
316
|
-
const event = new CustomEvent(eventName, {
|
|
320
|
+
const event = new CustomEvent(eventName, {
|
|
321
|
+
cancelable,
|
|
322
|
+
bubbles: true,
|
|
323
|
+
detail,
|
|
324
|
+
});
|
|
317
325
|
if (target && target.isConnected) {
|
|
318
326
|
target.dispatchEvent(event);
|
|
319
327
|
}
|
|
@@ -323,10 +331,10 @@ Copyright © 2021 Basecamp, LLC
|
|
|
323
331
|
return event;
|
|
324
332
|
}
|
|
325
333
|
function nextAnimationFrame() {
|
|
326
|
-
return new Promise(resolve => requestAnimationFrame(() => resolve()));
|
|
334
|
+
return new Promise((resolve) => requestAnimationFrame(() => resolve()));
|
|
327
335
|
}
|
|
328
336
|
function nextEventLoopTick() {
|
|
329
|
-
return new Promise(resolve => setTimeout(() => resolve(), 0));
|
|
337
|
+
return new Promise((resolve) => setTimeout(() => resolve(), 0));
|
|
330
338
|
}
|
|
331
339
|
function nextMicrotask() {
|
|
332
340
|
return Promise.resolve();
|
|
@@ -338,7 +346,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
338
346
|
const lines = interpolate(strings, values).replace(/^\n/, "").split("\n");
|
|
339
347
|
const match = lines[0].match(/^\s+/);
|
|
340
348
|
const indent = match ? match[0].length : 0;
|
|
341
|
-
return lines.map(line => line.slice(indent)).join("\n");
|
|
349
|
+
return lines.map((line) => line.slice(indent)).join("\n");
|
|
342
350
|
}
|
|
343
351
|
function interpolate(strings, values) {
|
|
344
352
|
return strings.reduce((result, string, i) => {
|
|
@@ -347,7 +355,8 @@ Copyright © 2021 Basecamp, LLC
|
|
|
347
355
|
}, "");
|
|
348
356
|
}
|
|
349
357
|
function uuid() {
|
|
350
|
-
return Array.
|
|
358
|
+
return Array.from({ length: 36 })
|
|
359
|
+
.map((_, i) => {
|
|
351
360
|
if (i == 8 || i == 13 || i == 18 || i == 23) {
|
|
352
361
|
return "-";
|
|
353
362
|
}
|
|
@@ -360,10 +369,11 @@ Copyright © 2021 Basecamp, LLC
|
|
|
360
369
|
else {
|
|
361
370
|
return Math.floor(Math.random() * 15).toString(16);
|
|
362
371
|
}
|
|
363
|
-
})
|
|
372
|
+
})
|
|
373
|
+
.join("");
|
|
364
374
|
}
|
|
365
375
|
function getAttribute(attributeName, ...elements) {
|
|
366
|
-
for (const value of elements.map(element => element === null || element === void 0 ? void 0 : element.getAttribute(attributeName))) {
|
|
376
|
+
for (const value of elements.map((element) => element === null || element === void 0 ? void 0 : element.getAttribute(attributeName))) {
|
|
367
377
|
if (typeof value == "string")
|
|
368
378
|
return value;
|
|
369
379
|
}
|
|
@@ -385,6 +395,23 @@ Copyright © 2021 Basecamp, LLC
|
|
|
385
395
|
element.removeAttribute("aria-busy");
|
|
386
396
|
}
|
|
387
397
|
}
|
|
398
|
+
function getMetaElement(name) {
|
|
399
|
+
return document.querySelector(`meta[name="${name}"]`);
|
|
400
|
+
}
|
|
401
|
+
function getMetaContent(name) {
|
|
402
|
+
const element = getMetaElement(name);
|
|
403
|
+
return element && element.content;
|
|
404
|
+
}
|
|
405
|
+
function setMetaContent(name, content) {
|
|
406
|
+
let element = getMetaElement(name);
|
|
407
|
+
if (!element) {
|
|
408
|
+
element = document.createElement("meta");
|
|
409
|
+
element.setAttribute("name", name);
|
|
410
|
+
document.head.appendChild(element);
|
|
411
|
+
}
|
|
412
|
+
element.setAttribute("content", content);
|
|
413
|
+
return element;
|
|
414
|
+
}
|
|
388
415
|
|
|
389
416
|
var FetchMethod;
|
|
390
417
|
(function (FetchMethod) {
|
|
@@ -396,27 +423,27 @@ Copyright © 2021 Basecamp, LLC
|
|
|
396
423
|
})(FetchMethod || (FetchMethod = {}));
|
|
397
424
|
function fetchMethodFromString(method) {
|
|
398
425
|
switch (method.toLowerCase()) {
|
|
399
|
-
case "get":
|
|
400
|
-
|
|
401
|
-
case "
|
|
402
|
-
|
|
403
|
-
case "
|
|
426
|
+
case "get":
|
|
427
|
+
return FetchMethod.get;
|
|
428
|
+
case "post":
|
|
429
|
+
return FetchMethod.post;
|
|
430
|
+
case "put":
|
|
431
|
+
return FetchMethod.put;
|
|
432
|
+
case "patch":
|
|
433
|
+
return FetchMethod.patch;
|
|
434
|
+
case "delete":
|
|
435
|
+
return FetchMethod.delete;
|
|
404
436
|
}
|
|
405
437
|
}
|
|
406
438
|
class FetchRequest {
|
|
407
|
-
constructor(delegate, method, location, body = new URLSearchParams, target = null) {
|
|
408
|
-
this.abortController = new AbortController;
|
|
409
|
-
this.resolveRequestPromise = (
|
|
439
|
+
constructor(delegate, method, location, body = new URLSearchParams(), target = null) {
|
|
440
|
+
this.abortController = new AbortController();
|
|
441
|
+
this.resolveRequestPromise = (_value) => { };
|
|
410
442
|
this.delegate = delegate;
|
|
411
443
|
this.method = method;
|
|
412
444
|
this.headers = this.defaultHeaders;
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
}
|
|
416
|
-
else {
|
|
417
|
-
this.body = body;
|
|
418
|
-
this.url = location;
|
|
419
|
-
}
|
|
445
|
+
this.body = body;
|
|
446
|
+
this.url = location;
|
|
420
447
|
this.target = target;
|
|
421
448
|
}
|
|
422
449
|
get location() {
|
|
@@ -442,7 +469,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
442
469
|
return await this.receive(response);
|
|
443
470
|
}
|
|
444
471
|
catch (error) {
|
|
445
|
-
if (error.name !==
|
|
472
|
+
if (error.name !== "AbortError") {
|
|
446
473
|
this.delegate.requestErrored(this, error);
|
|
447
474
|
throw error;
|
|
448
475
|
}
|
|
@@ -453,7 +480,11 @@ Copyright © 2021 Basecamp, LLC
|
|
|
453
480
|
}
|
|
454
481
|
async receive(response) {
|
|
455
482
|
const fetchResponse = new FetchResponse(response);
|
|
456
|
-
const event = dispatch("turbo:before-fetch-response", {
|
|
483
|
+
const event = dispatch("turbo:before-fetch-response", {
|
|
484
|
+
cancelable: true,
|
|
485
|
+
detail: { fetchResponse },
|
|
486
|
+
target: this.target,
|
|
487
|
+
});
|
|
457
488
|
if (event.defaultPrevented) {
|
|
458
489
|
this.delegate.requestPreventedHandlingResponse(this, fetchResponse);
|
|
459
490
|
}
|
|
@@ -472,14 +503,14 @@ Copyright © 2021 Basecamp, LLC
|
|
|
472
503
|
credentials: "same-origin",
|
|
473
504
|
headers: this.headers,
|
|
474
505
|
redirect: "follow",
|
|
475
|
-
body: this.body,
|
|
506
|
+
body: this.isIdempotent ? null : this.body,
|
|
476
507
|
signal: this.abortSignal,
|
|
477
|
-
referrer: (_a = this.delegate.referrer) === null || _a === void 0 ? void 0 : _a.href
|
|
508
|
+
referrer: (_a = this.delegate.referrer) === null || _a === void 0 ? void 0 : _a.href,
|
|
478
509
|
};
|
|
479
510
|
}
|
|
480
511
|
get defaultHeaders() {
|
|
481
512
|
return {
|
|
482
|
-
|
|
513
|
+
Accept: "text/html, application/xhtml+xml",
|
|
483
514
|
};
|
|
484
515
|
}
|
|
485
516
|
get isIdempotent() {
|
|
@@ -489,40 +520,25 @@ Copyright © 2021 Basecamp, LLC
|
|
|
489
520
|
return this.abortController.signal;
|
|
490
521
|
}
|
|
491
522
|
async allowRequestToBeIntercepted(fetchOptions) {
|
|
492
|
-
const requestInterception = new Promise(resolve => this.resolveRequestPromise = resolve);
|
|
523
|
+
const requestInterception = new Promise((resolve) => (this.resolveRequestPromise = resolve));
|
|
493
524
|
const event = dispatch("turbo:before-fetch-request", {
|
|
494
525
|
cancelable: true,
|
|
495
526
|
detail: {
|
|
496
527
|
fetchOptions,
|
|
497
|
-
url: this.url
|
|
498
|
-
resume: this.resolveRequestPromise
|
|
528
|
+
url: this.url,
|
|
529
|
+
resume: this.resolveRequestPromise,
|
|
499
530
|
},
|
|
500
|
-
target: this.target
|
|
531
|
+
target: this.target,
|
|
501
532
|
});
|
|
502
533
|
if (event.defaultPrevented)
|
|
503
534
|
await requestInterception;
|
|
504
535
|
}
|
|
505
536
|
}
|
|
506
|
-
function mergeFormDataEntries(url, entries) {
|
|
507
|
-
const currentSearchParams = new URLSearchParams(url.search);
|
|
508
|
-
for (const [name, value] of entries) {
|
|
509
|
-
if (value instanceof File)
|
|
510
|
-
continue;
|
|
511
|
-
if (currentSearchParams.has(name)) {
|
|
512
|
-
currentSearchParams.delete(name);
|
|
513
|
-
url.searchParams.set(name, value);
|
|
514
|
-
}
|
|
515
|
-
else {
|
|
516
|
-
url.searchParams.append(name, value);
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
return url;
|
|
520
|
-
}
|
|
521
537
|
|
|
522
538
|
class AppearanceObserver {
|
|
523
539
|
constructor(delegate, element) {
|
|
524
540
|
this.started = false;
|
|
525
|
-
this.intersect = entries => {
|
|
541
|
+
this.intersect = (entries) => {
|
|
526
542
|
const lastEntry = entries.slice(-1)[0];
|
|
527
543
|
if (lastEntry === null || lastEntry === void 0 ? void 0 : lastEntry.isIntersecting) {
|
|
528
544
|
this.delegate.elementAppearedInViewport(this.element);
|
|
@@ -599,9 +615,12 @@ Copyright © 2021 Basecamp, LLC
|
|
|
599
615
|
})(FormEnctype || (FormEnctype = {}));
|
|
600
616
|
function formEnctypeFromString(encoding) {
|
|
601
617
|
switch (encoding.toLowerCase()) {
|
|
602
|
-
case FormEnctype.multipart:
|
|
603
|
-
|
|
604
|
-
|
|
618
|
+
case FormEnctype.multipart:
|
|
619
|
+
return FormEnctype.multipart;
|
|
620
|
+
case FormEnctype.plain:
|
|
621
|
+
return FormEnctype.plain;
|
|
622
|
+
default:
|
|
623
|
+
return FormEnctype.urlEncoded;
|
|
605
624
|
}
|
|
606
625
|
}
|
|
607
626
|
class FormSubmission {
|
|
@@ -611,11 +630,15 @@ Copyright © 2021 Basecamp, LLC
|
|
|
611
630
|
this.formElement = formElement;
|
|
612
631
|
this.submitter = submitter;
|
|
613
632
|
this.formData = buildFormData(formElement, submitter);
|
|
633
|
+
this.location = expandURL(this.action);
|
|
634
|
+
if (this.method == FetchMethod.get) {
|
|
635
|
+
mergeFormDataEntries(this.location, [...this.body.entries()]);
|
|
636
|
+
}
|
|
614
637
|
this.fetchRequest = new FetchRequest(this, this.method, this.location, this.body, this.formElement);
|
|
615
638
|
this.mustRedirect = mustRedirect;
|
|
616
639
|
}
|
|
617
|
-
static confirmMethod(message,
|
|
618
|
-
return confirm(message);
|
|
640
|
+
static confirmMethod(message, _element) {
|
|
641
|
+
return Promise.resolve(confirm(message));
|
|
619
642
|
}
|
|
620
643
|
get method() {
|
|
621
644
|
var _a;
|
|
@@ -624,11 +647,13 @@ Copyright © 2021 Basecamp, LLC
|
|
|
624
647
|
}
|
|
625
648
|
get action() {
|
|
626
649
|
var _a;
|
|
627
|
-
const formElementAction = typeof this.formElement.action ===
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
650
|
+
const formElementAction = typeof this.formElement.action === "string" ? this.formElement.action : null;
|
|
651
|
+
if ((_a = this.submitter) === null || _a === void 0 ? void 0 : _a.hasAttribute("formaction")) {
|
|
652
|
+
return this.submitter.getAttribute("formaction") || "";
|
|
653
|
+
}
|
|
654
|
+
else {
|
|
655
|
+
return this.formElement.getAttribute("action") || formElementAction || "";
|
|
656
|
+
}
|
|
632
657
|
}
|
|
633
658
|
get body() {
|
|
634
659
|
if (this.enctype == FormEnctype.urlEncoded || this.method == FetchMethod.get) {
|
|
@@ -651,7 +676,8 @@ Copyright © 2021 Basecamp, LLC
|
|
|
651
676
|
}, []);
|
|
652
677
|
}
|
|
653
678
|
get confirmationMessage() {
|
|
654
|
-
|
|
679
|
+
var _a;
|
|
680
|
+
return ((_a = this.submitter) === null || _a === void 0 ? void 0 : _a.getAttribute("data-turbo-confirm")) || this.formElement.getAttribute("data-turbo-confirm");
|
|
655
681
|
}
|
|
656
682
|
get needsConfirmation() {
|
|
657
683
|
return this.confirmationMessage !== null;
|
|
@@ -659,7 +685,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
659
685
|
async start() {
|
|
660
686
|
const { initialized, requesting } = FormSubmissionState;
|
|
661
687
|
if (this.needsConfirmation) {
|
|
662
|
-
const answer = FormSubmission.confirmMethod(this.confirmationMessage, this.formElement);
|
|
688
|
+
const answer = await FormSubmission.confirmMethod(this.confirmationMessage, this.formElement);
|
|
663
689
|
if (!answer) {
|
|
664
690
|
return;
|
|
665
691
|
}
|
|
@@ -683,14 +709,19 @@ Copyright © 2021 Basecamp, LLC
|
|
|
683
709
|
if (token) {
|
|
684
710
|
headers["X-CSRF-Token"] = token;
|
|
685
711
|
}
|
|
712
|
+
}
|
|
713
|
+
if (this.requestAcceptsTurboStreamResponse(request)) {
|
|
686
714
|
headers["Accept"] = [StreamMessage.contentType, headers["Accept"]].join(", ");
|
|
687
715
|
}
|
|
688
716
|
}
|
|
689
|
-
requestStarted(
|
|
717
|
+
requestStarted(_request) {
|
|
690
718
|
var _a;
|
|
691
719
|
this.state = FormSubmissionState.waiting;
|
|
692
720
|
(_a = this.submitter) === null || _a === void 0 ? void 0 : _a.setAttribute("disabled", "");
|
|
693
|
-
dispatch("turbo:submit-start", {
|
|
721
|
+
dispatch("turbo:submit-start", {
|
|
722
|
+
target: this.formElement,
|
|
723
|
+
detail: { formSubmission: this },
|
|
724
|
+
});
|
|
694
725
|
this.delegate.formSubmissionStarted(this);
|
|
695
726
|
}
|
|
696
727
|
requestPreventedHandlingResponse(request, response) {
|
|
@@ -718,16 +749,22 @@ Copyright © 2021 Basecamp, LLC
|
|
|
718
749
|
this.result = { success: false, error };
|
|
719
750
|
this.delegate.formSubmissionErrored(this, error);
|
|
720
751
|
}
|
|
721
|
-
requestFinished(
|
|
752
|
+
requestFinished(_request) {
|
|
722
753
|
var _a;
|
|
723
754
|
this.state = FormSubmissionState.stopped;
|
|
724
755
|
(_a = this.submitter) === null || _a === void 0 ? void 0 : _a.removeAttribute("disabled");
|
|
725
|
-
dispatch("turbo:submit-end", {
|
|
756
|
+
dispatch("turbo:submit-end", {
|
|
757
|
+
target: this.formElement,
|
|
758
|
+
detail: Object.assign({ formSubmission: this }, this.result),
|
|
759
|
+
});
|
|
726
760
|
this.delegate.formSubmissionFinished(this);
|
|
727
761
|
}
|
|
728
762
|
requestMustRedirect(request) {
|
|
729
763
|
return !request.isIdempotent && this.mustRedirect;
|
|
730
764
|
}
|
|
765
|
+
requestAcceptsTurboStreamResponse(request) {
|
|
766
|
+
return !request.isIdempotent || this.formElement.hasAttribute("data-turbo-stream");
|
|
767
|
+
}
|
|
731
768
|
}
|
|
732
769
|
function buildFormData(formElement, submitter) {
|
|
733
770
|
const formData = new FormData(formElement);
|
|
@@ -748,18 +785,27 @@ Copyright © 2021 Basecamp, LLC
|
|
|
748
785
|
}
|
|
749
786
|
}
|
|
750
787
|
}
|
|
751
|
-
function getMetaContent(name) {
|
|
752
|
-
const element = document.querySelector(`meta[name="${name}"]`);
|
|
753
|
-
return element && element.content;
|
|
754
|
-
}
|
|
755
788
|
function responseSucceededWithoutRedirect(response) {
|
|
756
789
|
return response.statusCode == 200 && !response.redirected;
|
|
757
790
|
}
|
|
791
|
+
function mergeFormDataEntries(url, entries) {
|
|
792
|
+
const searchParams = new URLSearchParams();
|
|
793
|
+
for (const [name, value] of entries) {
|
|
794
|
+
if (value instanceof File)
|
|
795
|
+
continue;
|
|
796
|
+
searchParams.append(name, value);
|
|
797
|
+
}
|
|
798
|
+
url.search = searchParams.toString();
|
|
799
|
+
return url;
|
|
800
|
+
}
|
|
758
801
|
|
|
759
802
|
class Snapshot {
|
|
760
803
|
constructor(element) {
|
|
761
804
|
this.element = element;
|
|
762
805
|
}
|
|
806
|
+
get activeElement() {
|
|
807
|
+
return this.element.ownerDocument.activeElement;
|
|
808
|
+
}
|
|
763
809
|
get children() {
|
|
764
810
|
return [...this.element.children];
|
|
765
811
|
}
|
|
@@ -798,7 +844,9 @@ Copyright © 2021 Basecamp, LLC
|
|
|
798
844
|
constructor(delegate, element) {
|
|
799
845
|
this.submitBubbled = ((event) => {
|
|
800
846
|
const form = event.target;
|
|
801
|
-
if (
|
|
847
|
+
if (!event.defaultPrevented &&
|
|
848
|
+
form instanceof HTMLFormElement &&
|
|
849
|
+
form.closest("turbo-frame, html") == this.element) {
|
|
802
850
|
const submitter = event.submitter || undefined;
|
|
803
851
|
const method = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("formmethod")) || form.method;
|
|
804
852
|
if (method != "dialog" && this.delegate.shouldInterceptFormSubmission(form, submitter)) {
|
|
@@ -821,8 +869,8 @@ Copyright © 2021 Basecamp, LLC
|
|
|
821
869
|
|
|
822
870
|
class View {
|
|
823
871
|
constructor(delegate, element) {
|
|
824
|
-
this.resolveRenderPromise = (
|
|
825
|
-
this.resolveInterceptionPromise = (
|
|
872
|
+
this.resolveRenderPromise = (_value) => { };
|
|
873
|
+
this.resolveInterceptionPromise = (_value) => { };
|
|
826
874
|
this.delegate = delegate;
|
|
827
875
|
this.element = element;
|
|
828
876
|
}
|
|
@@ -867,15 +915,17 @@ Copyright © 2021 Basecamp, LLC
|
|
|
867
915
|
const { isPreview, shouldRender, newSnapshot: snapshot } = renderer;
|
|
868
916
|
if (shouldRender) {
|
|
869
917
|
try {
|
|
870
|
-
this.renderPromise = new Promise(resolve => this.resolveRenderPromise = resolve);
|
|
918
|
+
this.renderPromise = new Promise((resolve) => (this.resolveRenderPromise = resolve));
|
|
871
919
|
this.renderer = renderer;
|
|
872
920
|
this.prepareToRenderSnapshot(renderer);
|
|
873
|
-
const renderInterception = new Promise(resolve => this.resolveInterceptionPromise = resolve);
|
|
874
|
-
const
|
|
921
|
+
const renderInterception = new Promise((resolve) => (this.resolveInterceptionPromise = resolve));
|
|
922
|
+
const options = { resume: this.resolveInterceptionPromise, render: this.renderer.renderElement };
|
|
923
|
+
const immediateRender = this.delegate.allowsImmediateRender(snapshot, options);
|
|
875
924
|
if (!immediateRender)
|
|
876
925
|
await renderInterception;
|
|
877
926
|
await this.renderSnapshot(renderer);
|
|
878
927
|
this.delegate.viewRenderedSnapshot(snapshot, isPreview);
|
|
928
|
+
this.delegate.preloadOnLoadLinksForView(this.element);
|
|
879
929
|
this.finishRenderingSnapshot(renderer);
|
|
880
930
|
}
|
|
881
931
|
finally {
|
|
@@ -885,11 +935,11 @@ Copyright © 2021 Basecamp, LLC
|
|
|
885
935
|
}
|
|
886
936
|
}
|
|
887
937
|
else {
|
|
888
|
-
this.invalidate();
|
|
938
|
+
this.invalidate(renderer.reloadReason);
|
|
889
939
|
}
|
|
890
940
|
}
|
|
891
|
-
invalidate() {
|
|
892
|
-
this.delegate.viewInvalidated();
|
|
941
|
+
invalidate(reason) {
|
|
942
|
+
this.delegate.viewInvalidated(reason);
|
|
893
943
|
}
|
|
894
944
|
prepareToRenderSnapshot(renderer) {
|
|
895
945
|
this.markAsPreview(renderer.isPreview);
|
|
@@ -940,9 +990,9 @@ Copyright © 2021 Basecamp, LLC
|
|
|
940
990
|
}
|
|
941
991
|
delete this.clickEvent;
|
|
942
992
|
});
|
|
943
|
-
this.willVisit = () => {
|
|
993
|
+
this.willVisit = ((_event) => {
|
|
944
994
|
delete this.clickEvent;
|
|
945
|
-
};
|
|
995
|
+
});
|
|
946
996
|
this.delegate = delegate;
|
|
947
997
|
this.element = element;
|
|
948
998
|
}
|
|
@@ -957,28 +1007,65 @@ Copyright © 2021 Basecamp, LLC
|
|
|
957
1007
|
document.removeEventListener("turbo:before-visit", this.willVisit);
|
|
958
1008
|
}
|
|
959
1009
|
respondsToEventTarget(target) {
|
|
960
|
-
const element = target instanceof Element
|
|
961
|
-
? target
|
|
962
|
-
: target instanceof Node
|
|
963
|
-
? target.parentElement
|
|
964
|
-
: null;
|
|
1010
|
+
const element = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;
|
|
965
1011
|
return element && element.closest("turbo-frame, html") == this.element;
|
|
966
1012
|
}
|
|
967
1013
|
}
|
|
968
1014
|
|
|
1015
|
+
class FormLinkInterceptor {
|
|
1016
|
+
constructor(delegate, element) {
|
|
1017
|
+
this.delegate = delegate;
|
|
1018
|
+
this.linkInterceptor = new LinkInterceptor(this, element);
|
|
1019
|
+
}
|
|
1020
|
+
start() {
|
|
1021
|
+
this.linkInterceptor.start();
|
|
1022
|
+
}
|
|
1023
|
+
stop() {
|
|
1024
|
+
this.linkInterceptor.stop();
|
|
1025
|
+
}
|
|
1026
|
+
shouldInterceptLinkClick(link) {
|
|
1027
|
+
return (this.delegate.shouldInterceptFormLinkClick(link) &&
|
|
1028
|
+
(link.hasAttribute("data-turbo-method") || link.hasAttribute("data-turbo-stream")));
|
|
1029
|
+
}
|
|
1030
|
+
linkClickIntercepted(link, action) {
|
|
1031
|
+
const form = document.createElement("form");
|
|
1032
|
+
form.setAttribute("data-turbo", "true");
|
|
1033
|
+
form.setAttribute("action", action);
|
|
1034
|
+
form.setAttribute("hidden", "");
|
|
1035
|
+
const method = link.getAttribute("data-turbo-method");
|
|
1036
|
+
if (method)
|
|
1037
|
+
form.setAttribute("method", method);
|
|
1038
|
+
const turboFrame = link.getAttribute("data-turbo-frame");
|
|
1039
|
+
if (turboFrame)
|
|
1040
|
+
form.setAttribute("data-turbo-frame", turboFrame);
|
|
1041
|
+
const turboConfirm = link.getAttribute("data-turbo-confirm");
|
|
1042
|
+
if (turboConfirm)
|
|
1043
|
+
form.setAttribute("data-turbo-confirm", turboConfirm);
|
|
1044
|
+
const turboStream = link.hasAttribute("data-turbo-stream");
|
|
1045
|
+
if (turboStream)
|
|
1046
|
+
form.setAttribute("data-turbo-stream", "");
|
|
1047
|
+
this.delegate.formLinkClickIntercepted(link, form);
|
|
1048
|
+
document.body.appendChild(form);
|
|
1049
|
+
form.requestSubmit();
|
|
1050
|
+
form.remove();
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
|
|
969
1054
|
class Bardo {
|
|
970
|
-
constructor(permanentElementMap) {
|
|
1055
|
+
constructor(delegate, permanentElementMap) {
|
|
1056
|
+
this.delegate = delegate;
|
|
971
1057
|
this.permanentElementMap = permanentElementMap;
|
|
972
1058
|
}
|
|
973
|
-
static preservingPermanentElements(permanentElementMap, callback) {
|
|
974
|
-
const bardo = new this(permanentElementMap);
|
|
1059
|
+
static preservingPermanentElements(delegate, permanentElementMap, callback) {
|
|
1060
|
+
const bardo = new this(delegate, permanentElementMap);
|
|
975
1061
|
bardo.enter();
|
|
976
1062
|
callback();
|
|
977
1063
|
bardo.leave();
|
|
978
1064
|
}
|
|
979
1065
|
enter() {
|
|
980
1066
|
for (const id in this.permanentElementMap) {
|
|
981
|
-
const [, newPermanentElement] = this.permanentElementMap[id];
|
|
1067
|
+
const [currentPermanentElement, newPermanentElement] = this.permanentElementMap[id];
|
|
1068
|
+
this.delegate.enteringBardo(currentPermanentElement, newPermanentElement);
|
|
982
1069
|
this.replaceNewPermanentElementWithPlaceholder(newPermanentElement);
|
|
983
1070
|
}
|
|
984
1071
|
}
|
|
@@ -987,6 +1074,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
987
1074
|
const [currentPermanentElement] = this.permanentElementMap[id];
|
|
988
1075
|
this.replaceCurrentPermanentElementWithClone(currentPermanentElement);
|
|
989
1076
|
this.replacePlaceholderWithPermanentElement(currentPermanentElement);
|
|
1077
|
+
this.delegate.leavingBardo(currentPermanentElement);
|
|
990
1078
|
}
|
|
991
1079
|
}
|
|
992
1080
|
replaceNewPermanentElementWithPlaceholder(permanentElement) {
|
|
@@ -1002,7 +1090,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1002
1090
|
placeholder === null || placeholder === void 0 ? void 0 : placeholder.replaceWith(permanentElement);
|
|
1003
1091
|
}
|
|
1004
1092
|
getPlaceholderById(id) {
|
|
1005
|
-
return this.placeholders.find(element => element.content == id);
|
|
1093
|
+
return this.placeholders.find((element) => element.content == id);
|
|
1006
1094
|
}
|
|
1007
1095
|
get placeholders() {
|
|
1008
1096
|
return [...document.querySelectorAll("meta[name=turbo-permanent-placeholder][content]")];
|
|
@@ -1016,16 +1104,21 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1016
1104
|
}
|
|
1017
1105
|
|
|
1018
1106
|
class Renderer {
|
|
1019
|
-
constructor(currentSnapshot, newSnapshot, isPreview, willRender = true) {
|
|
1107
|
+
constructor(currentSnapshot, newSnapshot, renderElement, isPreview, willRender = true) {
|
|
1108
|
+
this.activeElement = null;
|
|
1020
1109
|
this.currentSnapshot = currentSnapshot;
|
|
1021
1110
|
this.newSnapshot = newSnapshot;
|
|
1022
1111
|
this.isPreview = isPreview;
|
|
1023
1112
|
this.willRender = willRender;
|
|
1024
|
-
this.
|
|
1113
|
+
this.renderElement = renderElement;
|
|
1114
|
+
this.promise = new Promise((resolve, reject) => (this.resolvingFunctions = { resolve, reject }));
|
|
1025
1115
|
}
|
|
1026
1116
|
get shouldRender() {
|
|
1027
1117
|
return true;
|
|
1028
1118
|
}
|
|
1119
|
+
get reloadReason() {
|
|
1120
|
+
return;
|
|
1121
|
+
}
|
|
1029
1122
|
prepareToRender() {
|
|
1030
1123
|
return;
|
|
1031
1124
|
}
|
|
@@ -1051,7 +1144,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1051
1144
|
}
|
|
1052
1145
|
}
|
|
1053
1146
|
preservingPermanentElements(callback) {
|
|
1054
|
-
Bardo.preservingPermanentElements(this.permanentElementMap, callback);
|
|
1147
|
+
Bardo.preservingPermanentElements(this, this.permanentElementMap, callback);
|
|
1055
1148
|
}
|
|
1056
1149
|
focusFirstAutofocusableElement() {
|
|
1057
1150
|
const element = this.connectedSnapshot.firstAutofocusableElement;
|
|
@@ -1059,6 +1152,19 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1059
1152
|
element.focus();
|
|
1060
1153
|
}
|
|
1061
1154
|
}
|
|
1155
|
+
enteringBardo(currentPermanentElement) {
|
|
1156
|
+
if (this.activeElement)
|
|
1157
|
+
return;
|
|
1158
|
+
if (currentPermanentElement.contains(this.currentSnapshot.activeElement)) {
|
|
1159
|
+
this.activeElement = this.currentSnapshot.activeElement;
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
leavingBardo(currentPermanentElement) {
|
|
1163
|
+
if (currentPermanentElement.contains(this.activeElement) && this.activeElement instanceof HTMLElement) {
|
|
1164
|
+
this.activeElement.focus();
|
|
1165
|
+
this.activeElement = null;
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1062
1168
|
get connectedSnapshot() {
|
|
1063
1169
|
return this.newSnapshot.isConnected ? this.newSnapshot : this.currentSnapshot;
|
|
1064
1170
|
}
|
|
@@ -1072,8 +1178,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1072
1178
|
return this.currentSnapshot.getPermanentElementMapForSnapshot(this.newSnapshot);
|
|
1073
1179
|
}
|
|
1074
1180
|
get cspNonce() {
|
|
1075
|
-
|
|
1076
|
-
return (_a = document.head.querySelector('meta[name="csp-nonce"]')) === null || _a === void 0 ? void 0 : _a.getAttribute("content");
|
|
1181
|
+
return getMetaContent("csp-nonce");
|
|
1077
1182
|
}
|
|
1078
1183
|
}
|
|
1079
1184
|
function copyElementAttributes(destinationElement, sourceElement) {
|
|
@@ -1086,6 +1191,22 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1086
1191
|
}
|
|
1087
1192
|
|
|
1088
1193
|
class FrameRenderer extends Renderer {
|
|
1194
|
+
constructor(delegate, currentSnapshot, newSnapshot, renderElement, isPreview, willRender = true) {
|
|
1195
|
+
super(currentSnapshot, newSnapshot, renderElement, isPreview, willRender);
|
|
1196
|
+
this.delegate = delegate;
|
|
1197
|
+
}
|
|
1198
|
+
static renderElement(currentElement, newElement) {
|
|
1199
|
+
var _a;
|
|
1200
|
+
const destinationRange = document.createRange();
|
|
1201
|
+
destinationRange.selectNodeContents(currentElement);
|
|
1202
|
+
destinationRange.deleteContents();
|
|
1203
|
+
const frameElement = newElement;
|
|
1204
|
+
const sourceRange = (_a = frameElement.ownerDocument) === null || _a === void 0 ? void 0 : _a.createRange();
|
|
1205
|
+
if (sourceRange) {
|
|
1206
|
+
sourceRange.selectNodeContents(frameElement);
|
|
1207
|
+
currentElement.appendChild(sourceRange.extractContents());
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1089
1210
|
get shouldRender() {
|
|
1090
1211
|
return true;
|
|
1091
1212
|
}
|
|
@@ -1101,23 +1222,16 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1101
1222
|
this.activateScriptElements();
|
|
1102
1223
|
}
|
|
1103
1224
|
loadFrameElement() {
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
destinationRange.selectNodeContents(this.currentElement);
|
|
1107
|
-
destinationRange.deleteContents();
|
|
1108
|
-
const frameElement = this.newElement;
|
|
1109
|
-
const sourceRange = (_a = frameElement.ownerDocument) === null || _a === void 0 ? void 0 : _a.createRange();
|
|
1110
|
-
if (sourceRange) {
|
|
1111
|
-
sourceRange.selectNodeContents(frameElement);
|
|
1112
|
-
this.currentElement.appendChild(sourceRange.extractContents());
|
|
1113
|
-
}
|
|
1225
|
+
this.delegate.frameExtracted(this.newElement.cloneNode(true));
|
|
1226
|
+
this.renderElement(this.currentElement, this.newElement);
|
|
1114
1227
|
}
|
|
1115
1228
|
scrollFrameIntoView() {
|
|
1116
1229
|
if (this.currentElement.autoscroll || this.newElement.autoscroll) {
|
|
1117
1230
|
const element = this.currentElement.firstElementChild;
|
|
1118
1231
|
const block = readScrollLogicalPosition(this.currentElement.getAttribute("data-autoscroll-block"), "end");
|
|
1232
|
+
const behavior = readScrollBehavior(this.currentElement.getAttribute("data-autoscroll-behavior"), "auto");
|
|
1119
1233
|
if (element) {
|
|
1120
|
-
element.scrollIntoView({ block });
|
|
1234
|
+
element.scrollIntoView({ block, behavior });
|
|
1121
1235
|
return true;
|
|
1122
1236
|
}
|
|
1123
1237
|
}
|
|
@@ -1141,6 +1255,14 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1141
1255
|
return defaultValue;
|
|
1142
1256
|
}
|
|
1143
1257
|
}
|
|
1258
|
+
function readScrollBehavior(value, defaultValue) {
|
|
1259
|
+
if (value == "auto" || value == "smooth") {
|
|
1260
|
+
return value;
|
|
1261
|
+
}
|
|
1262
|
+
else {
|
|
1263
|
+
return defaultValue;
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1144
1266
|
|
|
1145
1267
|
class ProgressBar {
|
|
1146
1268
|
constructor() {
|
|
@@ -1164,7 +1286,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1164
1286
|
left: 0;
|
|
1165
1287
|
height: 3px;
|
|
1166
1288
|
background: #0076ff;
|
|
1167
|
-
z-index:
|
|
1289
|
+
z-index: 2147483647;
|
|
1168
1290
|
transition:
|
|
1169
1291
|
width ${ProgressBar.animationDuration}ms ease-out,
|
|
1170
1292
|
opacity ${ProgressBar.animationDuration / 2}ms ${ProgressBar.animationDuration / 2}ms ease-in;
|
|
@@ -1223,13 +1345,16 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1223
1345
|
}
|
|
1224
1346
|
refresh() {
|
|
1225
1347
|
requestAnimationFrame(() => {
|
|
1226
|
-
this.progressElement.style.width = `${10 +
|
|
1348
|
+
this.progressElement.style.width = `${10 + this.value * 90}%`;
|
|
1227
1349
|
});
|
|
1228
1350
|
}
|
|
1229
1351
|
createStylesheetElement() {
|
|
1230
1352
|
const element = document.createElement("style");
|
|
1231
1353
|
element.type = "text/css";
|
|
1232
1354
|
element.textContent = ProgressBar.defaultCSS;
|
|
1355
|
+
if (this.cspNonce) {
|
|
1356
|
+
element.nonce = this.cspNonce;
|
|
1357
|
+
}
|
|
1233
1358
|
return element;
|
|
1234
1359
|
}
|
|
1235
1360
|
createProgressElement() {
|
|
@@ -1237,6 +1362,9 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1237
1362
|
element.className = "turbo-progress-bar";
|
|
1238
1363
|
return element;
|
|
1239
1364
|
}
|
|
1365
|
+
get cspNonce() {
|
|
1366
|
+
return getMetaContent("csp-nonce");
|
|
1367
|
+
}
|
|
1240
1368
|
}
|
|
1241
1369
|
ProgressBar.animationDuration = 300;
|
|
1242
1370
|
|
|
@@ -1253,14 +1381,14 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1253
1381
|
: {
|
|
1254
1382
|
type: elementType(element),
|
|
1255
1383
|
tracked: elementIsTracked(element),
|
|
1256
|
-
elements: []
|
|
1384
|
+
elements: [],
|
|
1257
1385
|
};
|
|
1258
1386
|
return Object.assign(Object.assign({}, result), { [outerHTML]: Object.assign(Object.assign({}, details), { elements: [...details.elements, element] }) });
|
|
1259
1387
|
}, {});
|
|
1260
1388
|
}
|
|
1261
1389
|
get trackedElementSignature() {
|
|
1262
1390
|
return Object.keys(this.detailsByOuterHTML)
|
|
1263
|
-
.filter(outerHTML => this.detailsByOuterHTML[outerHTML].tracked)
|
|
1391
|
+
.filter((outerHTML) => this.detailsByOuterHTML[outerHTML].tracked)
|
|
1264
1392
|
.join("");
|
|
1265
1393
|
}
|
|
1266
1394
|
getScriptElementsNotInSnapshot(snapshot) {
|
|
@@ -1271,8 +1399,8 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1271
1399
|
}
|
|
1272
1400
|
getElementsMatchingTypeNotInSnapshot(matchedType, snapshot) {
|
|
1273
1401
|
return Object.keys(this.detailsByOuterHTML)
|
|
1274
|
-
.filter(outerHTML => !(outerHTML in snapshot.detailsByOuterHTML))
|
|
1275
|
-
.map(outerHTML => this.detailsByOuterHTML[outerHTML])
|
|
1402
|
+
.filter((outerHTML) => !(outerHTML in snapshot.detailsByOuterHTML))
|
|
1403
|
+
.map((outerHTML) => this.detailsByOuterHTML[outerHTML])
|
|
1276
1404
|
.filter(({ type }) => type == matchedType)
|
|
1277
1405
|
.map(({ elements: [element] }) => element);
|
|
1278
1406
|
}
|
|
@@ -1292,13 +1420,11 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1292
1420
|
}
|
|
1293
1421
|
getMetaValue(name) {
|
|
1294
1422
|
const element = this.findMetaElementByName(name);
|
|
1295
|
-
return element
|
|
1296
|
-
? element.getAttribute("content")
|
|
1297
|
-
: null;
|
|
1423
|
+
return element ? element.getAttribute("content") : null;
|
|
1298
1424
|
}
|
|
1299
1425
|
findMetaElementByName(name) {
|
|
1300
1426
|
return Object.keys(this.detailsByOuterHTML).reduce((result, outerHTML) => {
|
|
1301
|
-
const { elements: [element] } = this.detailsByOuterHTML[outerHTML];
|
|
1427
|
+
const { elements: [element], } = this.detailsByOuterHTML[outerHTML];
|
|
1302
1428
|
return elementIsMetaElementWithName(element, name) ? element : result;
|
|
1303
1429
|
}, undefined);
|
|
1304
1430
|
}
|
|
@@ -1465,9 +1591,11 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1465
1591
|
if (this.state == VisitState.started) {
|
|
1466
1592
|
this.recordTimingMetric(TimingMetric.visitEnd);
|
|
1467
1593
|
this.state = VisitState.completed;
|
|
1468
|
-
this.adapter.visitCompleted(this);
|
|
1469
|
-
this.delegate.visitCompleted(this);
|
|
1470
1594
|
this.followRedirect();
|
|
1595
|
+
if (!this.followedRedirect) {
|
|
1596
|
+
this.adapter.visitCompleted(this);
|
|
1597
|
+
this.delegate.visitCompleted(this);
|
|
1598
|
+
}
|
|
1471
1599
|
}
|
|
1472
1600
|
}
|
|
1473
1601
|
fail() {
|
|
@@ -1529,12 +1657,12 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1529
1657
|
if (this.view.renderPromise)
|
|
1530
1658
|
await this.view.renderPromise;
|
|
1531
1659
|
if (isSuccessful(statusCode) && responseHTML != null) {
|
|
1532
|
-
await this.view.renderPage(PageSnapshot.fromHTMLString(responseHTML), false, this.willRender);
|
|
1660
|
+
await this.view.renderPage(PageSnapshot.fromHTMLString(responseHTML), false, this.willRender, this);
|
|
1533
1661
|
this.adapter.visitRendered(this);
|
|
1534
1662
|
this.complete();
|
|
1535
1663
|
}
|
|
1536
1664
|
else {
|
|
1537
|
-
await this.view.renderError(PageSnapshot.fromHTMLString(responseHTML));
|
|
1665
|
+
await this.view.renderError(PageSnapshot.fromHTMLString(responseHTML), this);
|
|
1538
1666
|
this.adapter.visitRendered(this);
|
|
1539
1667
|
this.fail();
|
|
1540
1668
|
}
|
|
@@ -1569,7 +1697,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1569
1697
|
else {
|
|
1570
1698
|
if (this.view.renderPromise)
|
|
1571
1699
|
await this.view.renderPromise;
|
|
1572
|
-
await this.view.renderPage(snapshot, isPreview, this.willRender);
|
|
1700
|
+
await this.view.renderPage(snapshot, isPreview, this.willRender, this);
|
|
1573
1701
|
this.adapter.visitRendered(this);
|
|
1574
1702
|
if (!isPreview) {
|
|
1575
1703
|
this.complete();
|
|
@@ -1582,8 +1710,9 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1582
1710
|
var _a;
|
|
1583
1711
|
if (this.redirectedToLocation && !this.followedRedirect && ((_a = this.response) === null || _a === void 0 ? void 0 : _a.redirected)) {
|
|
1584
1712
|
this.adapter.visitProposedToLocation(this.redirectedToLocation, {
|
|
1585
|
-
action:
|
|
1586
|
-
|
|
1713
|
+
action: "replace",
|
|
1714
|
+
willRender: false,
|
|
1715
|
+
response: this.response,
|
|
1587
1716
|
});
|
|
1588
1717
|
this.followedRedirect = true;
|
|
1589
1718
|
}
|
|
@@ -1599,13 +1728,15 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1599
1728
|
requestStarted() {
|
|
1600
1729
|
this.startRequest();
|
|
1601
1730
|
}
|
|
1602
|
-
requestPreventedHandlingResponse(
|
|
1603
|
-
}
|
|
1731
|
+
requestPreventedHandlingResponse(_request, _response) { }
|
|
1604
1732
|
async requestSucceededWithResponse(request, response) {
|
|
1605
1733
|
const responseHTML = await response.responseHTML;
|
|
1606
1734
|
const { redirected, statusCode } = response;
|
|
1607
1735
|
if (responseHTML == undefined) {
|
|
1608
|
-
this.recordResponse({
|
|
1736
|
+
this.recordResponse({
|
|
1737
|
+
statusCode: SystemStatusCode.contentTypeMismatch,
|
|
1738
|
+
redirected,
|
|
1739
|
+
});
|
|
1609
1740
|
}
|
|
1610
1741
|
else {
|
|
1611
1742
|
this.redirectedToLocation = response.redirected ? response.location : undefined;
|
|
@@ -1616,14 +1747,20 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1616
1747
|
const responseHTML = await response.responseHTML;
|
|
1617
1748
|
const { redirected, statusCode } = response;
|
|
1618
1749
|
if (responseHTML == undefined) {
|
|
1619
|
-
this.recordResponse({
|
|
1750
|
+
this.recordResponse({
|
|
1751
|
+
statusCode: SystemStatusCode.contentTypeMismatch,
|
|
1752
|
+
redirected,
|
|
1753
|
+
});
|
|
1620
1754
|
}
|
|
1621
1755
|
else {
|
|
1622
1756
|
this.recordResponse({ statusCode: statusCode, responseHTML, redirected });
|
|
1623
1757
|
}
|
|
1624
1758
|
}
|
|
1625
|
-
requestErrored(
|
|
1626
|
-
this.recordResponse({
|
|
1759
|
+
requestErrored(_request, _error) {
|
|
1760
|
+
this.recordResponse({
|
|
1761
|
+
statusCode: SystemStatusCode.networkFailure,
|
|
1762
|
+
redirected: false,
|
|
1763
|
+
});
|
|
1627
1764
|
}
|
|
1628
1765
|
requestFinished() {
|
|
1629
1766
|
this.finishRequest();
|
|
@@ -1664,9 +1801,11 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1664
1801
|
}
|
|
1665
1802
|
getHistoryMethodForAction(action) {
|
|
1666
1803
|
switch (action) {
|
|
1667
|
-
case "replace":
|
|
1804
|
+
case "replace":
|
|
1805
|
+
return history.replaceState;
|
|
1668
1806
|
case "advance":
|
|
1669
|
-
case "restore":
|
|
1807
|
+
case "restore":
|
|
1808
|
+
return history.pushState;
|
|
1670
1809
|
}
|
|
1671
1810
|
}
|
|
1672
1811
|
hasPreloadedResponse() {
|
|
@@ -1685,18 +1824,20 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1685
1824
|
}
|
|
1686
1825
|
cacheSnapshot() {
|
|
1687
1826
|
if (!this.snapshotCached) {
|
|
1688
|
-
this.view.cacheSnapshot().then(snapshot => snapshot && this.visitCachedSnapshot(snapshot));
|
|
1827
|
+
this.view.cacheSnapshot().then((snapshot) => snapshot && this.visitCachedSnapshot(snapshot));
|
|
1689
1828
|
this.snapshotCached = true;
|
|
1690
1829
|
}
|
|
1691
1830
|
}
|
|
1692
1831
|
async render(callback) {
|
|
1693
1832
|
this.cancelRender();
|
|
1694
|
-
await new Promise(resolve => {
|
|
1833
|
+
await new Promise((resolve) => {
|
|
1695
1834
|
this.frame = requestAnimationFrame(() => resolve());
|
|
1696
1835
|
});
|
|
1697
1836
|
await callback();
|
|
1698
1837
|
delete this.frame;
|
|
1699
|
-
this.
|
|
1838
|
+
if (!this.view.forceReloaded) {
|
|
1839
|
+
this.performScroll();
|
|
1840
|
+
}
|
|
1700
1841
|
}
|
|
1701
1842
|
cancelRender() {
|
|
1702
1843
|
if (this.frame) {
|
|
@@ -1711,7 +1852,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1711
1852
|
|
|
1712
1853
|
class BrowserAdapter {
|
|
1713
1854
|
constructor(session) {
|
|
1714
|
-
this.progressBar = new ProgressBar;
|
|
1855
|
+
this.progressBar = new ProgressBar();
|
|
1715
1856
|
this.showProgressBar = () => {
|
|
1716
1857
|
this.progressBar.show();
|
|
1717
1858
|
};
|
|
@@ -1721,10 +1862,10 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1721
1862
|
this.navigator.startVisit(location, uuid(), options);
|
|
1722
1863
|
}
|
|
1723
1864
|
visitStarted(visit) {
|
|
1865
|
+
this.location = visit.location;
|
|
1866
|
+
visit.loadCachedSnapshot();
|
|
1724
1867
|
visit.issueRequest();
|
|
1725
|
-
visit.changeHistory();
|
|
1726
1868
|
visit.goToSamePageAnchor();
|
|
1727
|
-
visit.loadCachedSnapshot();
|
|
1728
1869
|
}
|
|
1729
1870
|
visitRequestStarted(visit) {
|
|
1730
1871
|
this.progressBar.setValue(0);
|
|
@@ -1743,29 +1884,31 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1743
1884
|
case SystemStatusCode.networkFailure:
|
|
1744
1885
|
case SystemStatusCode.timeoutFailure:
|
|
1745
1886
|
case SystemStatusCode.contentTypeMismatch:
|
|
1746
|
-
return this.reload(
|
|
1887
|
+
return this.reload({
|
|
1888
|
+
reason: "request_failed",
|
|
1889
|
+
context: {
|
|
1890
|
+
statusCode,
|
|
1891
|
+
},
|
|
1892
|
+
});
|
|
1747
1893
|
default:
|
|
1748
1894
|
return visit.loadResponse();
|
|
1749
1895
|
}
|
|
1750
1896
|
}
|
|
1751
|
-
visitRequestFinished(
|
|
1897
|
+
visitRequestFinished(_visit) {
|
|
1752
1898
|
this.progressBar.setValue(1);
|
|
1753
1899
|
this.hideVisitProgressBar();
|
|
1754
1900
|
}
|
|
1755
|
-
visitCompleted(
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
this.reload();
|
|
1901
|
+
visitCompleted(_visit) { }
|
|
1902
|
+
pageInvalidated(reason) {
|
|
1903
|
+
this.reload(reason);
|
|
1759
1904
|
}
|
|
1760
|
-
visitFailed(
|
|
1761
|
-
}
|
|
1762
|
-
|
|
1763
|
-
}
|
|
1764
|
-
formSubmissionStarted(formSubmission) {
|
|
1905
|
+
visitFailed(_visit) { }
|
|
1906
|
+
visitRendered(_visit) { }
|
|
1907
|
+
formSubmissionStarted(_formSubmission) {
|
|
1765
1908
|
this.progressBar.setValue(0);
|
|
1766
1909
|
this.showFormProgressBarAfterDelay();
|
|
1767
1910
|
}
|
|
1768
|
-
formSubmissionFinished(
|
|
1911
|
+
formSubmissionFinished(_formSubmission) {
|
|
1769
1912
|
this.progressBar.setValue(1);
|
|
1770
1913
|
this.hideFormProgressBar();
|
|
1771
1914
|
}
|
|
@@ -1791,8 +1934,11 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1791
1934
|
delete this.formProgressBarTimeout;
|
|
1792
1935
|
}
|
|
1793
1936
|
}
|
|
1794
|
-
reload() {
|
|
1795
|
-
|
|
1937
|
+
reload(reason) {
|
|
1938
|
+
dispatch("turbo:reload", { detail: reason });
|
|
1939
|
+
if (!this.location)
|
|
1940
|
+
return;
|
|
1941
|
+
window.location.href = this.location.toString();
|
|
1796
1942
|
}
|
|
1797
1943
|
get navigator() {
|
|
1798
1944
|
return this.session.navigator;
|
|
@@ -1802,6 +1948,12 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1802
1948
|
class CacheObserver {
|
|
1803
1949
|
constructor() {
|
|
1804
1950
|
this.started = false;
|
|
1951
|
+
this.removeStaleElements = ((_event) => {
|
|
1952
|
+
const staleElements = [...document.querySelectorAll('[data-turbo-cache="false"]')];
|
|
1953
|
+
for (const element of staleElements) {
|
|
1954
|
+
element.remove();
|
|
1955
|
+
}
|
|
1956
|
+
});
|
|
1805
1957
|
}
|
|
1806
1958
|
start() {
|
|
1807
1959
|
if (!this.started) {
|
|
@@ -1815,12 +1967,6 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1815
1967
|
removeEventListener("turbo:before-cache", this.removeStaleElements, false);
|
|
1816
1968
|
}
|
|
1817
1969
|
}
|
|
1818
|
-
removeStaleElements() {
|
|
1819
|
-
const staleElements = [...document.querySelectorAll('[data-turbo-cache="false"]')];
|
|
1820
|
-
for (const element of staleElements) {
|
|
1821
|
-
element.remove();
|
|
1822
|
-
}
|
|
1823
|
-
}
|
|
1824
1970
|
}
|
|
1825
1971
|
|
|
1826
1972
|
class FormSubmitObserver {
|
|
@@ -1834,12 +1980,12 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1834
1980
|
if (!event.defaultPrevented) {
|
|
1835
1981
|
const form = event.target instanceof HTMLFormElement ? event.target : undefined;
|
|
1836
1982
|
const submitter = event.submitter || undefined;
|
|
1837
|
-
if (form
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1983
|
+
if (form &&
|
|
1984
|
+
submissionDoesNotDismissDialog(form, submitter) &&
|
|
1985
|
+
submissionDoesNotTargetIFrame(form, submitter) &&
|
|
1986
|
+
this.delegate.willSubmitForm(form, submitter)) {
|
|
1987
|
+
event.preventDefault();
|
|
1988
|
+
this.delegate.formSubmitted(form, submitter);
|
|
1843
1989
|
}
|
|
1844
1990
|
}
|
|
1845
1991
|
});
|
|
@@ -1858,6 +2004,18 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1858
2004
|
}
|
|
1859
2005
|
}
|
|
1860
2006
|
}
|
|
2007
|
+
function submissionDoesNotDismissDialog(form, submitter) {
|
|
2008
|
+
const method = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("formmethod")) || form.getAttribute("method");
|
|
2009
|
+
return method != "dialog";
|
|
2010
|
+
}
|
|
2011
|
+
function submissionDoesNotTargetIFrame(form, submitter) {
|
|
2012
|
+
const target = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("formtarget")) || form.target;
|
|
2013
|
+
for (const element of document.getElementsByName(target)) {
|
|
2014
|
+
if (element instanceof HTMLIFrameElement)
|
|
2015
|
+
return false;
|
|
2016
|
+
}
|
|
2017
|
+
return true;
|
|
2018
|
+
}
|
|
1861
2019
|
|
|
1862
2020
|
class FrameRedirector {
|
|
1863
2021
|
constructor(element) {
|
|
@@ -1873,7 +2031,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1873
2031
|
this.linkInterceptor.stop();
|
|
1874
2032
|
this.formInterceptor.stop();
|
|
1875
2033
|
}
|
|
1876
|
-
shouldInterceptLinkClick(element,
|
|
2034
|
+
shouldInterceptLinkClick(element, _url) {
|
|
1877
2035
|
return this.shouldRedirect(element);
|
|
1878
2036
|
}
|
|
1879
2037
|
linkClickIntercepted(element, url) {
|
|
@@ -1888,7 +2046,6 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1888
2046
|
formSubmissionIntercepted(element, submitter) {
|
|
1889
2047
|
const frame = this.findFrameElement(element, submitter);
|
|
1890
2048
|
if (frame) {
|
|
1891
|
-
frame.removeAttribute("reloadable");
|
|
1892
2049
|
frame.delegate.formSubmissionIntercepted(element, submitter);
|
|
1893
2050
|
}
|
|
1894
2051
|
}
|
|
@@ -1931,7 +2088,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
1931
2088
|
}
|
|
1932
2089
|
}
|
|
1933
2090
|
};
|
|
1934
|
-
this.onPageLoad = async (
|
|
2091
|
+
this.onPageLoad = async (_event) => {
|
|
1935
2092
|
await nextMicrotask();
|
|
1936
2093
|
this.pageLoaded = true;
|
|
1937
2094
|
};
|
|
@@ -2004,9 +2161,9 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2004
2161
|
if (this.clickEventIsSignificant(event)) {
|
|
2005
2162
|
const target = (event.composedPath && event.composedPath()[0]) || event.target;
|
|
2006
2163
|
const link = this.findLinkFromClickTarget(target);
|
|
2007
|
-
if (link) {
|
|
2164
|
+
if (link && doesNotTargetIFrame(link)) {
|
|
2008
2165
|
const location = this.getLocationForLink(link);
|
|
2009
|
-
if (this.delegate.willFollowLinkToLocation(link, location)) {
|
|
2166
|
+
if (this.delegate.willFollowLinkToLocation(link, location, event)) {
|
|
2010
2167
|
event.preventDefault();
|
|
2011
2168
|
this.delegate.followedLinkToLocation(link, location);
|
|
2012
2169
|
}
|
|
@@ -2028,13 +2185,13 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2028
2185
|
}
|
|
2029
2186
|
}
|
|
2030
2187
|
clickEventIsSignificant(event) {
|
|
2031
|
-
return !((event.target && event.target.isContentEditable)
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2188
|
+
return !((event.target && event.target.isContentEditable) ||
|
|
2189
|
+
event.defaultPrevented ||
|
|
2190
|
+
event.which > 1 ||
|
|
2191
|
+
event.altKey ||
|
|
2192
|
+
event.ctrlKey ||
|
|
2193
|
+
event.metaKey ||
|
|
2194
|
+
event.shiftKey);
|
|
2038
2195
|
}
|
|
2039
2196
|
findLinkFromClickTarget(target) {
|
|
2040
2197
|
if (target instanceof Element) {
|
|
@@ -2045,6 +2202,13 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2045
2202
|
return expandURL(link.getAttribute("href") || "");
|
|
2046
2203
|
}
|
|
2047
2204
|
}
|
|
2205
|
+
function doesNotTargetIFrame(anchor) {
|
|
2206
|
+
for (const element of document.getElementsByName(anchor.target)) {
|
|
2207
|
+
if (element instanceof HTMLIFrameElement)
|
|
2208
|
+
return false;
|
|
2209
|
+
}
|
|
2210
|
+
return true;
|
|
2211
|
+
}
|
|
2048
2212
|
|
|
2049
2213
|
function isAction(action) {
|
|
2050
2214
|
return action == "advance" || action == "replace" || action == "restore";
|
|
@@ -2065,6 +2229,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2065
2229
|
}
|
|
2066
2230
|
}
|
|
2067
2231
|
startVisit(locatable, restorationIdentifier, options = {}) {
|
|
2232
|
+
this.lastVisit = this.currentVisit;
|
|
2068
2233
|
this.stop();
|
|
2069
2234
|
this.currentVisit = new Visit(this, expandURL(locatable), restorationIdentifier, Object.assign({ referrer: this.location }, options));
|
|
2070
2235
|
this.currentVisit.start();
|
|
@@ -2094,7 +2259,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2094
2259
|
return this.delegate.history;
|
|
2095
2260
|
}
|
|
2096
2261
|
formSubmissionStarted(formSubmission) {
|
|
2097
|
-
if (typeof this.adapter.formSubmissionStarted ===
|
|
2262
|
+
if (typeof this.adapter.formSubmissionStarted === "function") {
|
|
2098
2263
|
this.adapter.formSubmissionStarted(formSubmission);
|
|
2099
2264
|
}
|
|
2100
2265
|
}
|
|
@@ -2107,7 +2272,10 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2107
2272
|
}
|
|
2108
2273
|
const { statusCode, redirected } = fetchResponse;
|
|
2109
2274
|
const action = this.getActionForFormSubmission(formSubmission);
|
|
2110
|
-
const visitOptions = {
|
|
2275
|
+
const visitOptions = {
|
|
2276
|
+
action,
|
|
2277
|
+
response: { statusCode, responseHTML, redirected },
|
|
2278
|
+
};
|
|
2111
2279
|
this.proposeVisit(fetchResponse.location, visitOptions);
|
|
2112
2280
|
}
|
|
2113
2281
|
}
|
|
@@ -2117,10 +2285,10 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2117
2285
|
if (responseHTML) {
|
|
2118
2286
|
const snapshot = PageSnapshot.fromHTMLString(responseHTML);
|
|
2119
2287
|
if (fetchResponse.serverError) {
|
|
2120
|
-
await this.view.renderError(snapshot);
|
|
2288
|
+
await this.view.renderError(snapshot, this.currentVisit);
|
|
2121
2289
|
}
|
|
2122
2290
|
else {
|
|
2123
|
-
await this.view.renderPage(snapshot);
|
|
2291
|
+
await this.view.renderPage(snapshot, false, true, this.currentVisit);
|
|
2124
2292
|
}
|
|
2125
2293
|
this.view.scrollToTop();
|
|
2126
2294
|
this.view.clearSnapshotCache();
|
|
@@ -2130,7 +2298,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2130
2298
|
console.error(error);
|
|
2131
2299
|
}
|
|
2132
2300
|
formSubmissionFinished(formSubmission) {
|
|
2133
|
-
if (typeof this.adapter.formSubmissionFinished ===
|
|
2301
|
+
if (typeof this.adapter.formSubmissionFinished === "function") {
|
|
2134
2302
|
this.adapter.formSubmissionFinished(formSubmission);
|
|
2135
2303
|
}
|
|
2136
2304
|
}
|
|
@@ -2141,12 +2309,14 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2141
2309
|
this.delegate.visitCompleted(visit);
|
|
2142
2310
|
}
|
|
2143
2311
|
locationWithActionIsSamePage(location, action) {
|
|
2312
|
+
var _a;
|
|
2144
2313
|
const anchor = getAnchor(location);
|
|
2145
|
-
const
|
|
2146
|
-
const
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
(
|
|
2314
|
+
const lastLocation = ((_a = this.lastVisit) === null || _a === void 0 ? void 0 : _a.location) || this.view.lastRenderedLocation;
|
|
2315
|
+
const currentAnchor = getAnchor(lastLocation);
|
|
2316
|
+
const isRestorationToTop = action === "restore" && typeof anchor === "undefined";
|
|
2317
|
+
return (action !== "replace" &&
|
|
2318
|
+
getRequestURL(location) === getRequestURL(lastLocation) &&
|
|
2319
|
+
(isRestorationToTop || (anchor != null && anchor !== currentAnchor)));
|
|
2150
2320
|
}
|
|
2151
2321
|
visitScrolledToSamePageLocation(oldURL, newURL) {
|
|
2152
2322
|
this.delegate.visitScrolledToSamePageLocation(oldURL, newURL);
|
|
@@ -2252,7 +2422,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2252
2422
|
|
|
2253
2423
|
class StreamObserver {
|
|
2254
2424
|
constructor(delegate) {
|
|
2255
|
-
this.sources = new Set;
|
|
2425
|
+
this.sources = new Set();
|
|
2256
2426
|
this.started = false;
|
|
2257
2427
|
this.inspectFetchResponse = ((event) => {
|
|
2258
2428
|
const response = fetchResponseFromEvent(event);
|
|
@@ -2319,14 +2489,18 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2319
2489
|
}
|
|
2320
2490
|
|
|
2321
2491
|
class ErrorRenderer extends Renderer {
|
|
2492
|
+
static renderElement(currentElement, newElement) {
|
|
2493
|
+
const { documentElement, body } = document;
|
|
2494
|
+
documentElement.replaceChild(newElement, body);
|
|
2495
|
+
}
|
|
2322
2496
|
async render() {
|
|
2323
2497
|
this.replaceHeadAndBody();
|
|
2324
2498
|
this.activateScriptElements();
|
|
2325
2499
|
}
|
|
2326
2500
|
replaceHeadAndBody() {
|
|
2327
|
-
const { documentElement, head
|
|
2501
|
+
const { documentElement, head } = document;
|
|
2328
2502
|
documentElement.replaceChild(this.newHead, head);
|
|
2329
|
-
|
|
2503
|
+
this.renderElement(this.currentElement, this.newElement);
|
|
2330
2504
|
}
|
|
2331
2505
|
activateScriptElements() {
|
|
2332
2506
|
for (const replaceableElement of this.scriptElements) {
|
|
@@ -2346,9 +2520,29 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2346
2520
|
}
|
|
2347
2521
|
|
|
2348
2522
|
class PageRenderer extends Renderer {
|
|
2523
|
+
static renderElement(currentElement, newElement) {
|
|
2524
|
+
if (document.body && newElement instanceof HTMLBodyElement) {
|
|
2525
|
+
document.body.replaceWith(newElement);
|
|
2526
|
+
}
|
|
2527
|
+
else {
|
|
2528
|
+
document.documentElement.appendChild(newElement);
|
|
2529
|
+
}
|
|
2530
|
+
}
|
|
2349
2531
|
get shouldRender() {
|
|
2350
2532
|
return this.newSnapshot.isVisitable && this.trackedElementsAreIdentical;
|
|
2351
2533
|
}
|
|
2534
|
+
get reloadReason() {
|
|
2535
|
+
if (!this.newSnapshot.isVisitable) {
|
|
2536
|
+
return {
|
|
2537
|
+
reason: "turbo_visit_control_is_reload",
|
|
2538
|
+
};
|
|
2539
|
+
}
|
|
2540
|
+
if (!this.trackedElementsAreIdentical) {
|
|
2541
|
+
return {
|
|
2542
|
+
reason: "tracked_element_mismatch",
|
|
2543
|
+
};
|
|
2544
|
+
}
|
|
2545
|
+
}
|
|
2352
2546
|
prepareToRender() {
|
|
2353
2547
|
this.mergeHead();
|
|
2354
2548
|
}
|
|
@@ -2418,12 +2612,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2418
2612
|
}
|
|
2419
2613
|
}
|
|
2420
2614
|
assignNewBody() {
|
|
2421
|
-
|
|
2422
|
-
document.body.replaceWith(this.newElement);
|
|
2423
|
-
}
|
|
2424
|
-
else {
|
|
2425
|
-
document.documentElement.appendChild(this.newElement);
|
|
2426
|
-
}
|
|
2615
|
+
this.renderElement(this.currentElement, this.newElement);
|
|
2427
2616
|
}
|
|
2428
2617
|
get newHeadStylesheetElements() {
|
|
2429
2618
|
return this.newHeadSnapshot.getStylesheetElementsNotInSnapshot(this.currentHeadSnapshot);
|
|
@@ -2492,13 +2681,21 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2492
2681
|
super(...arguments);
|
|
2493
2682
|
this.snapshotCache = new SnapshotCache(10);
|
|
2494
2683
|
this.lastRenderedLocation = new URL(location.href);
|
|
2684
|
+
this.forceReloaded = false;
|
|
2495
2685
|
}
|
|
2496
|
-
renderPage(snapshot, isPreview = false, willRender = true) {
|
|
2497
|
-
const renderer = new PageRenderer(this.snapshot, snapshot, isPreview, willRender);
|
|
2686
|
+
renderPage(snapshot, isPreview = false, willRender = true, visit) {
|
|
2687
|
+
const renderer = new PageRenderer(this.snapshot, snapshot, PageRenderer.renderElement, isPreview, willRender);
|
|
2688
|
+
if (!renderer.shouldRender) {
|
|
2689
|
+
this.forceReloaded = true;
|
|
2690
|
+
}
|
|
2691
|
+
else {
|
|
2692
|
+
visit === null || visit === void 0 ? void 0 : visit.changeHistory();
|
|
2693
|
+
}
|
|
2498
2694
|
return this.render(renderer);
|
|
2499
2695
|
}
|
|
2500
|
-
renderError(snapshot) {
|
|
2501
|
-
|
|
2696
|
+
renderError(snapshot, visit) {
|
|
2697
|
+
visit === null || visit === void 0 ? void 0 : visit.changeHistory();
|
|
2698
|
+
const renderer = new ErrorRenderer(this.snapshot, snapshot, ErrorRenderer.renderElement, false);
|
|
2502
2699
|
return this.render(renderer);
|
|
2503
2700
|
}
|
|
2504
2701
|
clearSnapshotCache() {
|
|
@@ -2525,10 +2722,50 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2525
2722
|
}
|
|
2526
2723
|
}
|
|
2527
2724
|
|
|
2725
|
+
class Preloader {
|
|
2726
|
+
constructor(delegate) {
|
|
2727
|
+
this.selector = "a[data-turbo-preload]";
|
|
2728
|
+
this.delegate = delegate;
|
|
2729
|
+
}
|
|
2730
|
+
get snapshotCache() {
|
|
2731
|
+
return this.delegate.navigator.view.snapshotCache;
|
|
2732
|
+
}
|
|
2733
|
+
start() {
|
|
2734
|
+
if (document.readyState === "loading") {
|
|
2735
|
+
return document.addEventListener("DOMContentLoaded", () => {
|
|
2736
|
+
this.preloadOnLoadLinksForView(document.body);
|
|
2737
|
+
});
|
|
2738
|
+
}
|
|
2739
|
+
else {
|
|
2740
|
+
this.preloadOnLoadLinksForView(document.body);
|
|
2741
|
+
}
|
|
2742
|
+
}
|
|
2743
|
+
preloadOnLoadLinksForView(element) {
|
|
2744
|
+
for (const link of element.querySelectorAll(this.selector)) {
|
|
2745
|
+
this.preloadURL(link);
|
|
2746
|
+
}
|
|
2747
|
+
}
|
|
2748
|
+
async preloadURL(link) {
|
|
2749
|
+
const location = new URL(link.href);
|
|
2750
|
+
if (this.snapshotCache.has(location)) {
|
|
2751
|
+
return;
|
|
2752
|
+
}
|
|
2753
|
+
try {
|
|
2754
|
+
const response = await fetch(location.toString(), { headers: { "VND.PREFETCH": "true", Accept: "text/html" } });
|
|
2755
|
+
const responseText = await response.text();
|
|
2756
|
+
const snapshot = PageSnapshot.fromHTMLString(responseText);
|
|
2757
|
+
this.snapshotCache.put(location, snapshot);
|
|
2758
|
+
}
|
|
2759
|
+
catch (_) {
|
|
2760
|
+
}
|
|
2761
|
+
}
|
|
2762
|
+
}
|
|
2763
|
+
|
|
2528
2764
|
class Session {
|
|
2529
2765
|
constructor() {
|
|
2530
2766
|
this.navigator = new Navigator(this);
|
|
2531
2767
|
this.history = new History(this);
|
|
2768
|
+
this.preloader = new Preloader(this);
|
|
2532
2769
|
this.view = new PageView(this, document.documentElement);
|
|
2533
2770
|
this.adapter = new BrowserAdapter(this);
|
|
2534
2771
|
this.pageObserver = new PageObserver(this);
|
|
@@ -2537,22 +2774,26 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2537
2774
|
this.formSubmitObserver = new FormSubmitObserver(this);
|
|
2538
2775
|
this.scrollObserver = new ScrollObserver(this);
|
|
2539
2776
|
this.streamObserver = new StreamObserver(this);
|
|
2777
|
+
this.formLinkInterceptor = new FormLinkInterceptor(this, document.documentElement);
|
|
2540
2778
|
this.frameRedirector = new FrameRedirector(document.documentElement);
|
|
2541
2779
|
this.drive = true;
|
|
2542
2780
|
this.enabled = true;
|
|
2543
2781
|
this.progressBarDelay = 500;
|
|
2544
2782
|
this.started = false;
|
|
2783
|
+
this.formMode = "on";
|
|
2545
2784
|
}
|
|
2546
2785
|
start() {
|
|
2547
2786
|
if (!this.started) {
|
|
2548
2787
|
this.pageObserver.start();
|
|
2549
2788
|
this.cacheObserver.start();
|
|
2789
|
+
this.formLinkInterceptor.start();
|
|
2550
2790
|
this.linkClickObserver.start();
|
|
2551
2791
|
this.formSubmitObserver.start();
|
|
2552
2792
|
this.scrollObserver.start();
|
|
2553
2793
|
this.streamObserver.start();
|
|
2554
2794
|
this.frameRedirector.start();
|
|
2555
2795
|
this.history.start();
|
|
2796
|
+
this.preloader.start();
|
|
2556
2797
|
this.started = true;
|
|
2557
2798
|
this.enabled = true;
|
|
2558
2799
|
}
|
|
@@ -2564,6 +2805,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2564
2805
|
if (this.started) {
|
|
2565
2806
|
this.pageObserver.stop();
|
|
2566
2807
|
this.cacheObserver.stop();
|
|
2808
|
+
this.formLinkInterceptor.stop();
|
|
2567
2809
|
this.linkClickObserver.stop();
|
|
2568
2810
|
this.formSubmitObserver.stop();
|
|
2569
2811
|
this.scrollObserver.stop();
|
|
@@ -2594,6 +2836,9 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2594
2836
|
setProgressBarDelay(delay) {
|
|
2595
2837
|
this.progressBarDelay = delay;
|
|
2596
2838
|
}
|
|
2839
|
+
setFormMode(mode) {
|
|
2840
|
+
this.formMode = mode;
|
|
2841
|
+
}
|
|
2597
2842
|
get location() {
|
|
2598
2843
|
return this.history.location;
|
|
2599
2844
|
}
|
|
@@ -2602,48 +2847,32 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2602
2847
|
}
|
|
2603
2848
|
historyPoppedToLocationWithRestorationIdentifier(location, restorationIdentifier) {
|
|
2604
2849
|
if (this.enabled) {
|
|
2605
|
-
this.navigator.startVisit(location, restorationIdentifier, {
|
|
2850
|
+
this.navigator.startVisit(location, restorationIdentifier, {
|
|
2851
|
+
action: "restore",
|
|
2852
|
+
historyChanged: true,
|
|
2853
|
+
});
|
|
2606
2854
|
}
|
|
2607
2855
|
else {
|
|
2608
|
-
this.adapter.pageInvalidated(
|
|
2856
|
+
this.adapter.pageInvalidated({
|
|
2857
|
+
reason: "turbo_disabled",
|
|
2858
|
+
});
|
|
2609
2859
|
}
|
|
2610
2860
|
}
|
|
2611
2861
|
scrollPositionChanged(position) {
|
|
2612
2862
|
this.history.updateRestorationData({ scrollPosition: position });
|
|
2613
2863
|
}
|
|
2614
|
-
|
|
2615
|
-
return
|
|
2616
|
-
|
|
2617
|
-
|
|
2864
|
+
shouldInterceptFormLinkClick(_link) {
|
|
2865
|
+
return true;
|
|
2866
|
+
}
|
|
2867
|
+
formLinkClickIntercepted(_link, _form) { }
|
|
2868
|
+
willFollowLinkToLocation(link, location, event) {
|
|
2869
|
+
return (this.elementDriveEnabled(link) &&
|
|
2870
|
+
locationIsVisitable(location, this.snapshot.rootLocation) &&
|
|
2871
|
+
this.applicationAllowsFollowingLinkToLocation(link, location, event));
|
|
2618
2872
|
}
|
|
2619
2873
|
followedLinkToLocation(link, location) {
|
|
2620
2874
|
const action = this.getActionForLink(link);
|
|
2621
|
-
this.
|
|
2622
|
-
}
|
|
2623
|
-
convertLinkWithMethodClickToFormSubmission(link) {
|
|
2624
|
-
const linkMethod = link.getAttribute("data-turbo-method");
|
|
2625
|
-
if (linkMethod) {
|
|
2626
|
-
const form = document.createElement("form");
|
|
2627
|
-
form.method = linkMethod;
|
|
2628
|
-
form.action = link.getAttribute("href") || "undefined";
|
|
2629
|
-
form.hidden = true;
|
|
2630
|
-
if (link.hasAttribute("data-turbo-confirm")) {
|
|
2631
|
-
form.setAttribute("data-turbo-confirm", link.getAttribute("data-turbo-confirm"));
|
|
2632
|
-
}
|
|
2633
|
-
const frame = this.getTargetFrameForLink(link);
|
|
2634
|
-
if (frame) {
|
|
2635
|
-
form.setAttribute("data-turbo-frame", frame);
|
|
2636
|
-
form.addEventListener("turbo:submit-start", () => form.remove());
|
|
2637
|
-
}
|
|
2638
|
-
else {
|
|
2639
|
-
form.addEventListener("submit", () => form.remove());
|
|
2640
|
-
}
|
|
2641
|
-
document.body.appendChild(form);
|
|
2642
|
-
return dispatch("submit", { cancelable: true, target: form });
|
|
2643
|
-
}
|
|
2644
|
-
else {
|
|
2645
|
-
return false;
|
|
2646
|
-
}
|
|
2875
|
+
this.visit(location.href, { action });
|
|
2647
2876
|
}
|
|
2648
2877
|
allowsVisitingLocationWithAction(location, action) {
|
|
2649
2878
|
return this.locationWithActionIsSamePage(location, action) || this.applicationAllowsVisitingLocation(location);
|
|
@@ -2669,9 +2898,9 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2669
2898
|
}
|
|
2670
2899
|
willSubmitForm(form, submitter) {
|
|
2671
2900
|
const action = getAction(form, submitter);
|
|
2672
|
-
return this.elementDriveEnabled(form)
|
|
2673
|
-
|
|
2674
|
-
|
|
2901
|
+
return (this.elementDriveEnabled(form) &&
|
|
2902
|
+
(!submitter || this.formElementDriveEnabled(submitter)) &&
|
|
2903
|
+
locationIsVisitable(expandURL(action), this.snapshot.rootLocation));
|
|
2675
2904
|
}
|
|
2676
2905
|
formSubmitted(form, submitter) {
|
|
2677
2906
|
this.navigator.submitForm(form, submitter);
|
|
@@ -2695,16 +2924,23 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2695
2924
|
this.notifyApplicationBeforeCachingSnapshot();
|
|
2696
2925
|
}
|
|
2697
2926
|
}
|
|
2698
|
-
allowsImmediateRender({ element },
|
|
2699
|
-
const event = this.notifyApplicationBeforeRender(element,
|
|
2700
|
-
|
|
2927
|
+
allowsImmediateRender({ element }, options) {
|
|
2928
|
+
const event = this.notifyApplicationBeforeRender(element, options);
|
|
2929
|
+
const { defaultPrevented, detail: { render }, } = event;
|
|
2930
|
+
if (this.view.renderer && render) {
|
|
2931
|
+
this.view.renderer.renderElement = render;
|
|
2932
|
+
}
|
|
2933
|
+
return !defaultPrevented;
|
|
2701
2934
|
}
|
|
2702
|
-
viewRenderedSnapshot(
|
|
2935
|
+
viewRenderedSnapshot(_snapshot, _isPreview) {
|
|
2703
2936
|
this.view.lastRenderedLocation = this.history.location;
|
|
2704
2937
|
this.notifyApplicationAfterRender();
|
|
2705
2938
|
}
|
|
2706
|
-
|
|
2707
|
-
this.
|
|
2939
|
+
preloadOnLoadLinksForView(element) {
|
|
2940
|
+
this.preloader.preloadOnLoadLinksForView(element);
|
|
2941
|
+
}
|
|
2942
|
+
viewInvalidated(reason) {
|
|
2943
|
+
this.adapter.pageInvalidated(reason);
|
|
2708
2944
|
}
|
|
2709
2945
|
frameLoaded(frame) {
|
|
2710
2946
|
this.notifyApplicationAfterFrameLoad(frame);
|
|
@@ -2712,19 +2948,26 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2712
2948
|
frameRendered(fetchResponse, frame) {
|
|
2713
2949
|
this.notifyApplicationAfterFrameRender(fetchResponse, frame);
|
|
2714
2950
|
}
|
|
2715
|
-
applicationAllowsFollowingLinkToLocation(link, location) {
|
|
2716
|
-
const event = this.notifyApplicationAfterClickingLinkToLocation(link, location);
|
|
2951
|
+
applicationAllowsFollowingLinkToLocation(link, location, ev) {
|
|
2952
|
+
const event = this.notifyApplicationAfterClickingLinkToLocation(link, location, ev);
|
|
2717
2953
|
return !event.defaultPrevented;
|
|
2718
2954
|
}
|
|
2719
2955
|
applicationAllowsVisitingLocation(location) {
|
|
2720
2956
|
const event = this.notifyApplicationBeforeVisitingLocation(location);
|
|
2721
2957
|
return !event.defaultPrevented;
|
|
2722
2958
|
}
|
|
2723
|
-
notifyApplicationAfterClickingLinkToLocation(link, location) {
|
|
2724
|
-
return dispatch("turbo:click", {
|
|
2959
|
+
notifyApplicationAfterClickingLinkToLocation(link, location, event) {
|
|
2960
|
+
return dispatch("turbo:click", {
|
|
2961
|
+
target: link,
|
|
2962
|
+
detail: { url: location.href, originalEvent: event },
|
|
2963
|
+
cancelable: true,
|
|
2964
|
+
});
|
|
2725
2965
|
}
|
|
2726
2966
|
notifyApplicationBeforeVisitingLocation(location) {
|
|
2727
|
-
return dispatch("turbo:before-visit", {
|
|
2967
|
+
return dispatch("turbo:before-visit", {
|
|
2968
|
+
detail: { url: location.href },
|
|
2969
|
+
cancelable: true,
|
|
2970
|
+
});
|
|
2728
2971
|
}
|
|
2729
2972
|
notifyApplicationAfterVisitingLocation(location, action) {
|
|
2730
2973
|
markAsBusy(document.documentElement);
|
|
@@ -2733,24 +2976,46 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2733
2976
|
notifyApplicationBeforeCachingSnapshot() {
|
|
2734
2977
|
return dispatch("turbo:before-cache");
|
|
2735
2978
|
}
|
|
2736
|
-
notifyApplicationBeforeRender(newBody,
|
|
2737
|
-
return dispatch("turbo:before-render", {
|
|
2979
|
+
notifyApplicationBeforeRender(newBody, options) {
|
|
2980
|
+
return dispatch("turbo:before-render", {
|
|
2981
|
+
detail: Object.assign({ newBody }, options),
|
|
2982
|
+
cancelable: true,
|
|
2983
|
+
});
|
|
2738
2984
|
}
|
|
2739
2985
|
notifyApplicationAfterRender() {
|
|
2740
2986
|
return dispatch("turbo:render");
|
|
2741
2987
|
}
|
|
2742
2988
|
notifyApplicationAfterPageLoad(timing = {}) {
|
|
2743
2989
|
clearBusyState(document.documentElement);
|
|
2744
|
-
return dispatch("turbo:load", {
|
|
2990
|
+
return dispatch("turbo:load", {
|
|
2991
|
+
detail: { url: this.location.href, timing },
|
|
2992
|
+
});
|
|
2745
2993
|
}
|
|
2746
2994
|
notifyApplicationAfterVisitingSamePageLocation(oldURL, newURL) {
|
|
2747
|
-
dispatchEvent(new HashChangeEvent("hashchange", {
|
|
2995
|
+
dispatchEvent(new HashChangeEvent("hashchange", {
|
|
2996
|
+
oldURL: oldURL.toString(),
|
|
2997
|
+
newURL: newURL.toString(),
|
|
2998
|
+
}));
|
|
2748
2999
|
}
|
|
2749
3000
|
notifyApplicationAfterFrameLoad(frame) {
|
|
2750
3001
|
return dispatch("turbo:frame-load", { target: frame });
|
|
2751
3002
|
}
|
|
2752
3003
|
notifyApplicationAfterFrameRender(fetchResponse, frame) {
|
|
2753
|
-
return dispatch("turbo:frame-render", {
|
|
3004
|
+
return dispatch("turbo:frame-render", {
|
|
3005
|
+
detail: { fetchResponse },
|
|
3006
|
+
target: frame,
|
|
3007
|
+
cancelable: true,
|
|
3008
|
+
});
|
|
3009
|
+
}
|
|
3010
|
+
formElementDriveEnabled(element) {
|
|
3011
|
+
if (this.formMode == "off") {
|
|
3012
|
+
return false;
|
|
3013
|
+
}
|
|
3014
|
+
if (this.formMode == "optin") {
|
|
3015
|
+
const form = element === null || element === void 0 ? void 0 : element.closest("form[data-turbo]");
|
|
3016
|
+
return (form === null || form === void 0 ? void 0 : form.getAttribute("data-turbo")) == "true";
|
|
3017
|
+
}
|
|
3018
|
+
return this.elementDriveEnabled(element);
|
|
2754
3019
|
}
|
|
2755
3020
|
elementDriveEnabled(element) {
|
|
2756
3021
|
const container = element === null || element === void 0 ? void 0 : element.closest("[data-turbo]");
|
|
@@ -2775,18 +3040,6 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2775
3040
|
const action = link.getAttribute("data-turbo-action");
|
|
2776
3041
|
return isAction(action) ? action : "advance";
|
|
2777
3042
|
}
|
|
2778
|
-
getTargetFrameForLink(link) {
|
|
2779
|
-
const frame = link.getAttribute("data-turbo-frame");
|
|
2780
|
-
if (frame) {
|
|
2781
|
-
return frame;
|
|
2782
|
-
}
|
|
2783
|
-
else {
|
|
2784
|
-
const container = link.closest("turbo-frame");
|
|
2785
|
-
if (container) {
|
|
2786
|
-
return container.id;
|
|
2787
|
-
}
|
|
2788
|
-
}
|
|
2789
|
-
}
|
|
2790
3043
|
get snapshot() {
|
|
2791
3044
|
return this.view.snapshot;
|
|
2792
3045
|
}
|
|
@@ -2798,11 +3051,59 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2798
3051
|
absoluteURL: {
|
|
2799
3052
|
get() {
|
|
2800
3053
|
return this.toString();
|
|
2801
|
-
}
|
|
3054
|
+
},
|
|
3055
|
+
},
|
|
3056
|
+
};
|
|
3057
|
+
|
|
3058
|
+
class Cache {
|
|
3059
|
+
constructor(session) {
|
|
3060
|
+
this.session = session;
|
|
3061
|
+
}
|
|
3062
|
+
clear() {
|
|
3063
|
+
this.session.clearCache();
|
|
3064
|
+
}
|
|
3065
|
+
resetCacheControl() {
|
|
3066
|
+
this.setCacheControl("");
|
|
3067
|
+
}
|
|
3068
|
+
exemptPageFromCache() {
|
|
3069
|
+
this.setCacheControl("no-cache");
|
|
3070
|
+
}
|
|
3071
|
+
exemptPageFromPreview() {
|
|
3072
|
+
this.setCacheControl("no-preview");
|
|
3073
|
+
}
|
|
3074
|
+
setCacheControl(value) {
|
|
3075
|
+
setMetaContent("turbo-cache-control", value);
|
|
2802
3076
|
}
|
|
3077
|
+
}
|
|
3078
|
+
|
|
3079
|
+
const StreamActions = {
|
|
3080
|
+
after() {
|
|
3081
|
+
this.targetElements.forEach((e) => { var _a; return (_a = e.parentElement) === null || _a === void 0 ? void 0 : _a.insertBefore(this.templateContent, e.nextSibling); });
|
|
3082
|
+
},
|
|
3083
|
+
append() {
|
|
3084
|
+
this.removeDuplicateTargetChildren();
|
|
3085
|
+
this.targetElements.forEach((e) => e.append(this.templateContent));
|
|
3086
|
+
},
|
|
3087
|
+
before() {
|
|
3088
|
+
this.targetElements.forEach((e) => { var _a; return (_a = e.parentElement) === null || _a === void 0 ? void 0 : _a.insertBefore(this.templateContent, e); });
|
|
3089
|
+
},
|
|
3090
|
+
prepend() {
|
|
3091
|
+
this.removeDuplicateTargetChildren();
|
|
3092
|
+
this.targetElements.forEach((e) => e.prepend(this.templateContent));
|
|
3093
|
+
},
|
|
3094
|
+
remove() {
|
|
3095
|
+
this.targetElements.forEach((e) => e.remove());
|
|
3096
|
+
},
|
|
3097
|
+
replace() {
|
|
3098
|
+
this.targetElements.forEach((e) => e.replaceWith(this.templateContent));
|
|
3099
|
+
},
|
|
3100
|
+
update() {
|
|
3101
|
+
this.targetElements.forEach((e) => e.replaceChildren(this.templateContent));
|
|
3102
|
+
},
|
|
2803
3103
|
};
|
|
2804
3104
|
|
|
2805
|
-
const session = new Session;
|
|
3105
|
+
const session = new Session();
|
|
3106
|
+
const cache = new Cache(session);
|
|
2806
3107
|
const { navigator: navigator$1 } = session;
|
|
2807
3108
|
function start() {
|
|
2808
3109
|
session.start();
|
|
@@ -2823,6 +3124,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2823
3124
|
session.renderStreamMessage(message);
|
|
2824
3125
|
}
|
|
2825
3126
|
function clearCache() {
|
|
3127
|
+
console.warn("Please replace `Turbo.clearCache()` with `Turbo.cache.clear()`. The top-level function is deprecated and will be removed in a future version of Turbo.`");
|
|
2826
3128
|
session.clearCache();
|
|
2827
3129
|
}
|
|
2828
3130
|
function setProgressBarDelay(delay) {
|
|
@@ -2831,13 +3133,18 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2831
3133
|
function setConfirmMethod(confirmMethod) {
|
|
2832
3134
|
FormSubmission.confirmMethod = confirmMethod;
|
|
2833
3135
|
}
|
|
3136
|
+
function setFormMode(mode) {
|
|
3137
|
+
session.setFormMode(mode);
|
|
3138
|
+
}
|
|
2834
3139
|
|
|
2835
3140
|
var Turbo = /*#__PURE__*/Object.freeze({
|
|
2836
3141
|
__proto__: null,
|
|
2837
3142
|
navigator: navigator$1,
|
|
2838
3143
|
session: session,
|
|
3144
|
+
cache: cache,
|
|
2839
3145
|
PageRenderer: PageRenderer,
|
|
2840
3146
|
PageSnapshot: PageSnapshot,
|
|
3147
|
+
FrameRenderer: FrameRenderer,
|
|
2841
3148
|
start: start,
|
|
2842
3149
|
registerAdapter: registerAdapter,
|
|
2843
3150
|
visit: visit,
|
|
@@ -2846,39 +3153,52 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2846
3153
|
renderStreamMessage: renderStreamMessage,
|
|
2847
3154
|
clearCache: clearCache,
|
|
2848
3155
|
setProgressBarDelay: setProgressBarDelay,
|
|
2849
|
-
setConfirmMethod: setConfirmMethod
|
|
3156
|
+
setConfirmMethod: setConfirmMethod,
|
|
3157
|
+
setFormMode: setFormMode,
|
|
3158
|
+
StreamActions: StreamActions
|
|
2850
3159
|
});
|
|
2851
3160
|
|
|
2852
3161
|
class FrameController {
|
|
2853
3162
|
constructor(element) {
|
|
2854
|
-
this.fetchResponseLoaded = (
|
|
3163
|
+
this.fetchResponseLoaded = (_fetchResponse) => { };
|
|
2855
3164
|
this.currentFetchRequest = null;
|
|
2856
3165
|
this.resolveVisitPromise = () => { };
|
|
2857
3166
|
this.connected = false;
|
|
2858
3167
|
this.hasBeenLoaded = false;
|
|
2859
|
-
this.
|
|
3168
|
+
this.ignoredAttributes = new Set();
|
|
3169
|
+
this.visitCachedSnapshot = ({ element }) => {
|
|
3170
|
+
const frame = element.querySelector("#" + this.element.id);
|
|
3171
|
+
if (frame && this.previousFrameElement) {
|
|
3172
|
+
frame.replaceChildren(...this.previousFrameElement.children);
|
|
3173
|
+
}
|
|
3174
|
+
delete this.previousFrameElement;
|
|
3175
|
+
};
|
|
2860
3176
|
this.element = element;
|
|
2861
3177
|
this.view = new FrameView(this, this.element);
|
|
2862
3178
|
this.appearanceObserver = new AppearanceObserver(this, this.element);
|
|
3179
|
+
this.formLinkInterceptor = new FormLinkInterceptor(this, this.element);
|
|
2863
3180
|
this.linkInterceptor = new LinkInterceptor(this, this.element);
|
|
2864
3181
|
this.formInterceptor = new FormInterceptor(this, this.element);
|
|
2865
3182
|
}
|
|
2866
3183
|
connect() {
|
|
2867
3184
|
if (!this.connected) {
|
|
2868
3185
|
this.connected = true;
|
|
2869
|
-
this.reloadable = false;
|
|
2870
3186
|
if (this.loadingStyle == FrameLoadingStyle.lazy) {
|
|
2871
3187
|
this.appearanceObserver.start();
|
|
2872
3188
|
}
|
|
3189
|
+
else {
|
|
3190
|
+
this.loadSourceURL();
|
|
3191
|
+
}
|
|
3192
|
+
this.formLinkInterceptor.start();
|
|
2873
3193
|
this.linkInterceptor.start();
|
|
2874
3194
|
this.formInterceptor.start();
|
|
2875
|
-
this.sourceURLChanged();
|
|
2876
3195
|
}
|
|
2877
3196
|
}
|
|
2878
3197
|
disconnect() {
|
|
2879
3198
|
if (this.connected) {
|
|
2880
3199
|
this.connected = false;
|
|
2881
3200
|
this.appearanceObserver.stop();
|
|
3201
|
+
this.formLinkInterceptor.stop();
|
|
2882
3202
|
this.linkInterceptor.stop();
|
|
2883
3203
|
this.formInterceptor.stop();
|
|
2884
3204
|
}
|
|
@@ -2889,10 +3209,20 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2889
3209
|
}
|
|
2890
3210
|
}
|
|
2891
3211
|
sourceURLChanged() {
|
|
3212
|
+
if (this.isIgnoringChangesTo("src"))
|
|
3213
|
+
return;
|
|
3214
|
+
if (this.element.isConnected) {
|
|
3215
|
+
this.complete = false;
|
|
3216
|
+
}
|
|
2892
3217
|
if (this.loadingStyle == FrameLoadingStyle.eager || this.hasBeenLoaded) {
|
|
2893
3218
|
this.loadSourceURL();
|
|
2894
3219
|
}
|
|
2895
3220
|
}
|
|
3221
|
+
completeChanged() {
|
|
3222
|
+
if (this.isIgnoringChangesTo("complete"))
|
|
3223
|
+
return;
|
|
3224
|
+
this.loadSourceURL();
|
|
3225
|
+
}
|
|
2896
3226
|
loadingStyleChanged() {
|
|
2897
3227
|
if (this.loadingStyle == FrameLoadingStyle.lazy) {
|
|
2898
3228
|
this.appearanceObserver.start();
|
|
@@ -2903,21 +3233,11 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2903
3233
|
}
|
|
2904
3234
|
}
|
|
2905
3235
|
async loadSourceURL() {
|
|
2906
|
-
if (
|
|
2907
|
-
|
|
2908
|
-
this.
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
this.element.loaded = this.visit(this.sourceURL);
|
|
2912
|
-
this.appearanceObserver.stop();
|
|
2913
|
-
await this.element.loaded;
|
|
2914
|
-
this.hasBeenLoaded = true;
|
|
2915
|
-
}
|
|
2916
|
-
catch (error) {
|
|
2917
|
-
this.currentURL = previousURL;
|
|
2918
|
-
throw error;
|
|
2919
|
-
}
|
|
2920
|
-
}
|
|
3236
|
+
if (this.enabled && this.isActive && !this.complete && this.sourceURL) {
|
|
3237
|
+
this.element.loaded = this.visit(expandURL(this.sourceURL));
|
|
3238
|
+
this.appearanceObserver.stop();
|
|
3239
|
+
await this.element.loaded;
|
|
3240
|
+
this.hasBeenLoaded = true;
|
|
2921
3241
|
}
|
|
2922
3242
|
}
|
|
2923
3243
|
async loadResponse(fetchResponse) {
|
|
@@ -2929,10 +3249,11 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2929
3249
|
if (html) {
|
|
2930
3250
|
const { body } = parseHTMLDocument(html);
|
|
2931
3251
|
const snapshot = new Snapshot(await this.extractForeignFrameElement(body));
|
|
2932
|
-
const renderer = new FrameRenderer(this.view.snapshot, snapshot, false, false);
|
|
3252
|
+
const renderer = new FrameRenderer(this, this.view.snapshot, snapshot, FrameRenderer.renderElement, false, false);
|
|
2933
3253
|
if (this.view.renderPromise)
|
|
2934
3254
|
await this.view.renderPromise;
|
|
2935
3255
|
await this.view.render(renderer);
|
|
3256
|
+
this.complete = true;
|
|
2936
3257
|
session.frameRendered(fetchResponse, this.element);
|
|
2937
3258
|
session.frameLoaded(this.element);
|
|
2938
3259
|
this.fetchResponseLoaded(fetchResponse);
|
|
@@ -2946,19 +3267,21 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2946
3267
|
this.fetchResponseLoaded = () => { };
|
|
2947
3268
|
}
|
|
2948
3269
|
}
|
|
2949
|
-
elementAppearedInViewport(
|
|
3270
|
+
elementAppearedInViewport(_element) {
|
|
2950
3271
|
this.loadSourceURL();
|
|
2951
3272
|
}
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
3273
|
+
shouldInterceptFormLinkClick(link) {
|
|
3274
|
+
return this.shouldInterceptNavigation(link);
|
|
3275
|
+
}
|
|
3276
|
+
formLinkClickIntercepted(link, form) {
|
|
3277
|
+
const frame = this.findFrameElement(link);
|
|
3278
|
+
if (frame)
|
|
3279
|
+
form.setAttribute("data-turbo-frame", frame.id);
|
|
3280
|
+
}
|
|
3281
|
+
shouldInterceptLinkClick(element, _url) {
|
|
3282
|
+
return this.shouldInterceptNavigation(element);
|
|
2959
3283
|
}
|
|
2960
3284
|
linkClickIntercepted(element, url) {
|
|
2961
|
-
this.reloadable = true;
|
|
2962
3285
|
this.navigateFrame(element, url);
|
|
2963
3286
|
}
|
|
2964
3287
|
shouldInterceptFormSubmission(element, submitter) {
|
|
@@ -2968,19 +3291,18 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2968
3291
|
if (this.formSubmission) {
|
|
2969
3292
|
this.formSubmission.stop();
|
|
2970
3293
|
}
|
|
2971
|
-
this.reloadable = false;
|
|
2972
3294
|
this.formSubmission = new FormSubmission(this, element, submitter);
|
|
2973
3295
|
const { fetchRequest } = this.formSubmission;
|
|
2974
3296
|
this.prepareHeadersForRequest(fetchRequest.headers, fetchRequest);
|
|
2975
3297
|
this.formSubmission.start();
|
|
2976
3298
|
}
|
|
2977
|
-
prepareHeadersForRequest(headers,
|
|
3299
|
+
prepareHeadersForRequest(headers, _request) {
|
|
2978
3300
|
headers["Turbo-Frame"] = this.id;
|
|
2979
3301
|
}
|
|
2980
|
-
requestStarted(
|
|
3302
|
+
requestStarted(_request) {
|
|
2981
3303
|
markAsBusy(this.element);
|
|
2982
3304
|
}
|
|
2983
|
-
requestPreventedHandlingResponse(
|
|
3305
|
+
requestPreventedHandlingResponse(_request, _response) {
|
|
2984
3306
|
this.resolveVisitPromise();
|
|
2985
3307
|
}
|
|
2986
3308
|
async requestSucceededWithResponse(request, response) {
|
|
@@ -2995,7 +3317,7 @@ Copyright © 2021 Basecamp, LLC
|
|
|
2995
3317
|
console.error(error);
|
|
2996
3318
|
this.resolveVisitPromise();
|
|
2997
3319
|
}
|
|
2998
|
-
requestFinished(
|
|
3320
|
+
requestFinished(_request) {
|
|
2999
3321
|
clearBusyState(this.element);
|
|
3000
3322
|
}
|
|
3001
3323
|
formSubmissionStarted({ formElement }) {
|
|
@@ -3015,19 +3337,32 @@ Copyright © 2021 Basecamp, LLC
|
|
|
3015
3337
|
formSubmissionFinished({ formElement }) {
|
|
3016
3338
|
clearBusyState(formElement, this.findFrameElement(formElement));
|
|
3017
3339
|
}
|
|
3018
|
-
allowsImmediateRender(
|
|
3019
|
-
|
|
3340
|
+
allowsImmediateRender({ element: newFrame }, options) {
|
|
3341
|
+
const event = dispatch("turbo:before-frame-render", {
|
|
3342
|
+
target: this.element,
|
|
3343
|
+
detail: Object.assign({ newFrame }, options),
|
|
3344
|
+
cancelable: true,
|
|
3345
|
+
});
|
|
3346
|
+
const { defaultPrevented, detail: { render }, } = event;
|
|
3347
|
+
if (this.view.renderer && render) {
|
|
3348
|
+
this.view.renderer.renderElement = render;
|
|
3349
|
+
}
|
|
3350
|
+
return !defaultPrevented;
|
|
3020
3351
|
}
|
|
3021
|
-
viewRenderedSnapshot(
|
|
3352
|
+
viewRenderedSnapshot(_snapshot, _isPreview) { }
|
|
3353
|
+
preloadOnLoadLinksForView(element) {
|
|
3354
|
+
session.preloadOnLoadLinksForView(element);
|
|
3022
3355
|
}
|
|
3023
|
-
viewInvalidated() {
|
|
3356
|
+
viewInvalidated() { }
|
|
3357
|
+
frameExtracted(element) {
|
|
3358
|
+
this.previousFrameElement = element;
|
|
3024
3359
|
}
|
|
3025
3360
|
async visit(url) {
|
|
3026
3361
|
var _a;
|
|
3027
|
-
const request = new FetchRequest(this, FetchMethod.get,
|
|
3362
|
+
const request = new FetchRequest(this, FetchMethod.get, url, new URLSearchParams(), this.element);
|
|
3028
3363
|
(_a = this.currentFetchRequest) === null || _a === void 0 ? void 0 : _a.cancel();
|
|
3029
3364
|
this.currentFetchRequest = request;
|
|
3030
|
-
return new Promise(resolve => {
|
|
3365
|
+
return new Promise((resolve) => {
|
|
3031
3366
|
this.resolveVisitPromise = () => {
|
|
3032
3367
|
this.resolveVisitPromise = () => { };
|
|
3033
3368
|
this.currentFetchRequest = null;
|
|
@@ -3039,19 +3374,23 @@ Copyright © 2021 Basecamp, LLC
|
|
|
3039
3374
|
navigateFrame(element, url, submitter) {
|
|
3040
3375
|
const frame = this.findFrameElement(element, submitter);
|
|
3041
3376
|
this.proposeVisitIfNavigatedWithAction(frame, element, submitter);
|
|
3042
|
-
frame.setAttribute("reloadable", "");
|
|
3043
3377
|
frame.src = url;
|
|
3044
3378
|
}
|
|
3045
3379
|
proposeVisitIfNavigatedWithAction(frame, element, submitter) {
|
|
3046
3380
|
const action = getAttribute("data-turbo-action", submitter, element, frame);
|
|
3047
3381
|
if (isAction(action)) {
|
|
3048
|
-
const { visitCachedSnapshot } =
|
|
3382
|
+
const { visitCachedSnapshot } = frame.delegate;
|
|
3049
3383
|
frame.delegate.fetchResponseLoaded = (fetchResponse) => {
|
|
3050
3384
|
if (frame.src) {
|
|
3051
3385
|
const { statusCode, redirected } = fetchResponse;
|
|
3052
3386
|
const responseHTML = frame.ownerDocument.documentElement.outerHTML;
|
|
3053
3387
|
const response = { statusCode, redirected, responseHTML };
|
|
3054
|
-
session.visit(frame.src, {
|
|
3388
|
+
session.visit(frame.src, {
|
|
3389
|
+
action,
|
|
3390
|
+
response,
|
|
3391
|
+
visitCachedSnapshot,
|
|
3392
|
+
willRender: false,
|
|
3393
|
+
});
|
|
3055
3394
|
}
|
|
3056
3395
|
};
|
|
3057
3396
|
}
|
|
@@ -3065,10 +3404,12 @@ Copyright © 2021 Basecamp, LLC
|
|
|
3065
3404
|
let element;
|
|
3066
3405
|
const id = CSS.escape(this.id);
|
|
3067
3406
|
try {
|
|
3068
|
-
|
|
3407
|
+
element = activateElement(container.querySelector(`turbo-frame#${id}`), this.sourceURL);
|
|
3408
|
+
if (element) {
|
|
3069
3409
|
return element;
|
|
3070
3410
|
}
|
|
3071
|
-
|
|
3411
|
+
element = activateElement(container.querySelector(`turbo-frame[src][recurse~=${id}]`), this.sourceURL);
|
|
3412
|
+
if (element) {
|
|
3072
3413
|
await element.loaded;
|
|
3073
3414
|
return await this.extractForeignFrameElement(element);
|
|
3074
3415
|
}
|
|
@@ -3116,24 +3457,10 @@ Copyright © 2021 Basecamp, LLC
|
|
|
3116
3457
|
return this.element.src;
|
|
3117
3458
|
}
|
|
3118
3459
|
}
|
|
3119
|
-
get reloadable() {
|
|
3120
|
-
const frame = this.findFrameElement(this.element);
|
|
3121
|
-
return frame.hasAttribute("reloadable");
|
|
3122
|
-
}
|
|
3123
|
-
set reloadable(value) {
|
|
3124
|
-
const frame = this.findFrameElement(this.element);
|
|
3125
|
-
if (value) {
|
|
3126
|
-
frame.setAttribute("reloadable", "");
|
|
3127
|
-
}
|
|
3128
|
-
else {
|
|
3129
|
-
frame.removeAttribute("reloadable");
|
|
3130
|
-
}
|
|
3131
|
-
}
|
|
3132
3460
|
set sourceURL(sourceURL) {
|
|
3133
|
-
this.
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
this.settingSourceURL = false;
|
|
3461
|
+
this.ignoringChangesToAttribute("src", () => {
|
|
3462
|
+
this.element.src = sourceURL !== null && sourceURL !== void 0 ? sourceURL : null;
|
|
3463
|
+
});
|
|
3137
3464
|
}
|
|
3138
3465
|
get loadingStyle() {
|
|
3139
3466
|
return this.element.loading;
|
|
@@ -3141,6 +3468,19 @@ Copyright © 2021 Basecamp, LLC
|
|
|
3141
3468
|
get isLoading() {
|
|
3142
3469
|
return this.formSubmission !== undefined || this.resolveVisitPromise() !== undefined;
|
|
3143
3470
|
}
|
|
3471
|
+
get complete() {
|
|
3472
|
+
return this.element.hasAttribute("complete");
|
|
3473
|
+
}
|
|
3474
|
+
set complete(value) {
|
|
3475
|
+
this.ignoringChangesToAttribute("complete", () => {
|
|
3476
|
+
if (value) {
|
|
3477
|
+
this.element.setAttribute("complete", "");
|
|
3478
|
+
}
|
|
3479
|
+
else {
|
|
3480
|
+
this.element.removeAttribute("complete");
|
|
3481
|
+
}
|
|
3482
|
+
});
|
|
3483
|
+
}
|
|
3144
3484
|
get isActive() {
|
|
3145
3485
|
return this.element.isActive && this.connected;
|
|
3146
3486
|
}
|
|
@@ -3150,16 +3490,13 @@ Copyright © 2021 Basecamp, LLC
|
|
|
3150
3490
|
const root = (_a = meta === null || meta === void 0 ? void 0 : meta.content) !== null && _a !== void 0 ? _a : "/";
|
|
3151
3491
|
return expandURL(root);
|
|
3152
3492
|
}
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
};
|
|
3161
|
-
this.clone = element.cloneNode(true);
|
|
3162
|
-
this.id = element.id;
|
|
3493
|
+
isIgnoringChangesTo(attributeName) {
|
|
3494
|
+
return this.ignoredAttributes.has(attributeName);
|
|
3495
|
+
}
|
|
3496
|
+
ignoringChangesToAttribute(attributeName, callback) {
|
|
3497
|
+
this.ignoredAttributes.add(attributeName);
|
|
3498
|
+
callback();
|
|
3499
|
+
this.ignoredAttributes.delete(attributeName);
|
|
3163
3500
|
}
|
|
3164
3501
|
}
|
|
3165
3502
|
function getFrameElementById(id) {
|
|
@@ -3187,35 +3524,6 @@ Copyright © 2021 Basecamp, LLC
|
|
|
3187
3524
|
}
|
|
3188
3525
|
}
|
|
3189
3526
|
|
|
3190
|
-
const StreamActions = {
|
|
3191
|
-
after() {
|
|
3192
|
-
this.targetElements.forEach(e => { var _a; return (_a = e.parentElement) === null || _a === void 0 ? void 0 : _a.insertBefore(this.templateContent, e.nextSibling); });
|
|
3193
|
-
},
|
|
3194
|
-
append() {
|
|
3195
|
-
this.removeDuplicateTargetChildren();
|
|
3196
|
-
this.targetElements.forEach(e => e.append(this.templateContent));
|
|
3197
|
-
},
|
|
3198
|
-
before() {
|
|
3199
|
-
this.targetElements.forEach(e => { var _a; return (_a = e.parentElement) === null || _a === void 0 ? void 0 : _a.insertBefore(this.templateContent, e); });
|
|
3200
|
-
},
|
|
3201
|
-
prepend() {
|
|
3202
|
-
this.removeDuplicateTargetChildren();
|
|
3203
|
-
this.targetElements.forEach(e => e.prepend(this.templateContent));
|
|
3204
|
-
},
|
|
3205
|
-
remove() {
|
|
3206
|
-
this.targetElements.forEach(e => e.remove());
|
|
3207
|
-
},
|
|
3208
|
-
replace() {
|
|
3209
|
-
this.targetElements.forEach(e => e.replaceWith(this.templateContent));
|
|
3210
|
-
},
|
|
3211
|
-
update() {
|
|
3212
|
-
this.targetElements.forEach(e => {
|
|
3213
|
-
e.innerHTML = "";
|
|
3214
|
-
e.append(this.templateContent);
|
|
3215
|
-
});
|
|
3216
|
-
}
|
|
3217
|
-
};
|
|
3218
|
-
|
|
3219
3527
|
class StreamElement extends HTMLElement {
|
|
3220
3528
|
async connectedCallback() {
|
|
3221
3529
|
try {
|
|
@@ -3230,12 +3538,12 @@ Copyright © 2021 Basecamp, LLC
|
|
|
3230
3538
|
}
|
|
3231
3539
|
async render() {
|
|
3232
3540
|
var _a;
|
|
3233
|
-
return (_a = this.renderPromise) !== null && _a !== void 0 ? _a : (this.renderPromise = (async () => {
|
|
3541
|
+
return ((_a = this.renderPromise) !== null && _a !== void 0 ? _a : (this.renderPromise = (async () => {
|
|
3234
3542
|
if (this.dispatchEvent(this.beforeRenderEvent)) {
|
|
3235
3543
|
await nextAnimationFrame();
|
|
3236
3544
|
this.performAction();
|
|
3237
3545
|
}
|
|
3238
|
-
})());
|
|
3546
|
+
})()));
|
|
3239
3547
|
}
|
|
3240
3548
|
disconnect() {
|
|
3241
3549
|
try {
|
|
@@ -3244,13 +3552,13 @@ Copyright © 2021 Basecamp, LLC
|
|
|
3244
3552
|
catch (_a) { }
|
|
3245
3553
|
}
|
|
3246
3554
|
removeDuplicateTargetChildren() {
|
|
3247
|
-
this.duplicateChildren.forEach(c => c.remove());
|
|
3555
|
+
this.duplicateChildren.forEach((c) => c.remove());
|
|
3248
3556
|
}
|
|
3249
3557
|
get duplicateChildren() {
|
|
3250
3558
|
var _a;
|
|
3251
|
-
const existingChildren = this.targetElements.flatMap(e => [...e.children]).filter(c => !!c.id);
|
|
3252
|
-
const newChildrenIds = [...(_a = this.templateContent) === null || _a === void 0 ? void 0 : _a.children].filter(c => !!c.id).map(c => c.id);
|
|
3253
|
-
return existingChildren.filter(c => newChildrenIds.includes(c.id));
|
|
3559
|
+
const existingChildren = this.targetElements.flatMap((e) => [...e.children]).filter((c) => !!c.id);
|
|
3560
|
+
const newChildrenIds = [...(((_a = this.templateContent) === null || _a === void 0 ? void 0 : _a.children) || [])].filter((c) => !!c.id).map((c) => c.id);
|
|
3561
|
+
return existingChildren.filter((c) => newChildrenIds.includes(c.id));
|
|
3254
3562
|
}
|
|
3255
3563
|
get performAction() {
|
|
3256
3564
|
if (this.action) {
|
|
@@ -3299,7 +3607,10 @@ Copyright © 2021 Basecamp, LLC
|
|
|
3299
3607
|
return (_b = ((_a = this.outerHTML.match(/<[^>]+>/)) !== null && _a !== void 0 ? _a : [])[0]) !== null && _b !== void 0 ? _b : "<turbo-stream>";
|
|
3300
3608
|
}
|
|
3301
3609
|
get beforeRenderEvent() {
|
|
3302
|
-
return new CustomEvent("turbo:before-stream-render", {
|
|
3610
|
+
return new CustomEvent("turbo:before-stream-render", {
|
|
3611
|
+
bubbles: true,
|
|
3612
|
+
cancelable: true,
|
|
3613
|
+
});
|
|
3303
3614
|
}
|
|
3304
3615
|
get targetElementsById() {
|
|
3305
3616
|
var _a;
|
|
@@ -3323,9 +3634,35 @@ Copyright © 2021 Basecamp, LLC
|
|
|
3323
3634
|
}
|
|
3324
3635
|
}
|
|
3325
3636
|
|
|
3637
|
+
class StreamSourceElement extends HTMLElement {
|
|
3638
|
+
constructor() {
|
|
3639
|
+
super(...arguments);
|
|
3640
|
+
this.streamSource = null;
|
|
3641
|
+
}
|
|
3642
|
+
connectedCallback() {
|
|
3643
|
+
this.streamSource = this.src.match(/^ws{1,2}:/) ? new WebSocket(this.src) : new EventSource(this.src);
|
|
3644
|
+
connectStreamSource(this.streamSource);
|
|
3645
|
+
}
|
|
3646
|
+
disconnectedCallback() {
|
|
3647
|
+
if (this.streamSource) {
|
|
3648
|
+
disconnectStreamSource(this.streamSource);
|
|
3649
|
+
}
|
|
3650
|
+
}
|
|
3651
|
+
get src() {
|
|
3652
|
+
return this.getAttribute("src") || "";
|
|
3653
|
+
}
|
|
3654
|
+
}
|
|
3655
|
+
|
|
3326
3656
|
FrameElement.delegateConstructor = FrameController;
|
|
3327
|
-
customElements.
|
|
3328
|
-
|
|
3657
|
+
if (customElements.get("turbo-frame") === undefined) {
|
|
3658
|
+
customElements.define("turbo-frame", FrameElement);
|
|
3659
|
+
}
|
|
3660
|
+
if (customElements.get("turbo-stream") === undefined) {
|
|
3661
|
+
customElements.define("turbo-stream", StreamElement);
|
|
3662
|
+
}
|
|
3663
|
+
if (customElements.get("turbo-stream-source") === undefined) {
|
|
3664
|
+
customElements.define("turbo-stream-source", StreamSourceElement);
|
|
3665
|
+
}
|
|
3329
3666
|
|
|
3330
3667
|
(() => {
|
|
3331
3668
|
let element = document.currentScript;
|
|
@@ -3333,7 +3670,8 @@ Copyright © 2021 Basecamp, LLC
|
|
|
3333
3670
|
return;
|
|
3334
3671
|
if (element.hasAttribute("data-turbo-suppress-warning"))
|
|
3335
3672
|
return;
|
|
3336
|
-
|
|
3673
|
+
element = element.parentElement;
|
|
3674
|
+
while (element) {
|
|
3337
3675
|
if (element == document.body) {
|
|
3338
3676
|
return console.warn(unindent `
|
|
3339
3677
|
You are loading Turbo from a <script> element inside the <body> element. This is probably not what you meant to do!
|
|
@@ -3346,14 +3684,18 @@ Copyright © 2021 Basecamp, LLC
|
|
|
3346
3684
|
Suppress this warning by adding a "data-turbo-suppress-warning" attribute to: %s
|
|
3347
3685
|
`, element.outerHTML);
|
|
3348
3686
|
}
|
|
3687
|
+
element = element.parentElement;
|
|
3349
3688
|
}
|
|
3350
3689
|
})();
|
|
3351
3690
|
|
|
3352
3691
|
window.Turbo = Turbo;
|
|
3353
3692
|
start();
|
|
3354
3693
|
|
|
3694
|
+
exports.FrameRenderer = FrameRenderer;
|
|
3355
3695
|
exports.PageRenderer = PageRenderer;
|
|
3356
3696
|
exports.PageSnapshot = PageSnapshot;
|
|
3697
|
+
exports.StreamActions = StreamActions;
|
|
3698
|
+
exports.cache = cache;
|
|
3357
3699
|
exports.clearCache = clearCache;
|
|
3358
3700
|
exports.connectStreamSource = connectStreamSource;
|
|
3359
3701
|
exports.disconnectStreamSource = disconnectStreamSource;
|
|
@@ -3362,10 +3704,11 @@ Copyright © 2021 Basecamp, LLC
|
|
|
3362
3704
|
exports.renderStreamMessage = renderStreamMessage;
|
|
3363
3705
|
exports.session = session;
|
|
3364
3706
|
exports.setConfirmMethod = setConfirmMethod;
|
|
3707
|
+
exports.setFormMode = setFormMode;
|
|
3365
3708
|
exports.setProgressBarDelay = setProgressBarDelay;
|
|
3366
3709
|
exports.start = start;
|
|
3367
3710
|
exports.visit = visit;
|
|
3368
3711
|
|
|
3369
3712
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
3370
3713
|
|
|
3371
|
-
}))
|
|
3714
|
+
}));
|