@hotwired/turbo
Version:
The speed of a single-page web application without having to write any JavaScript
1,210 lines (1,183 loc) • 168 kB
JavaScript
/*
Turbo 7.0.0-beta.7
Copyright © 2021 Basecamp, LLC
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Turbo = {}));
}(this, (function (exports) { 'use strict';
(function () {
if (window.Reflect === undefined || window.customElements === undefined ||
window.customElements.polyfillWrapFlushCallback) {
return;
}
var BuiltInHTMLElement = HTMLElement;
var wrapperForTheName = {
'HTMLElement': function HTMLElement() {
return Reflect.construct(BuiltInHTMLElement, [], this.constructor);
}
};
window.HTMLElement =
wrapperForTheName['HTMLElement'];
HTMLElement.prototype = BuiltInHTMLElement.prototype;
HTMLElement.prototype.constructor = HTMLElement;
Object.setPrototypeOf(HTMLElement, BuiltInHTMLElement);
})();
var submittersByForm = new WeakMap;
function findSubmitterFromClickTarget(target) {
var element = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;
var candidate = element ? element.closest("input, button") : null;
return (candidate === null || candidate === void 0 ? void 0 : candidate.type) == "submit" ? candidate : null;
}
function clickCaptured(event) {
var submitter = findSubmitterFromClickTarget(event.target);
if (submitter && submitter.form) {
submittersByForm.set(submitter.form, submitter);
}
}
(function () {
if ("SubmitEvent" in window)
return;
addEventListener("click", clickCaptured, true);
Object.defineProperty(Event.prototype, "submitter", {
get: function () {
if (this.type == "submit" && this.target instanceof HTMLFormElement) {
return submittersByForm.get(this.target);
}
}
});
})();
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator(thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
}
function __values(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
}
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
}
function __spread() {
for (var ar = [], i = 0; i < arguments.length; i++)
ar = ar.concat(__read(arguments[i]));
return ar;
}
function __makeTemplateObject(cooked, raw) {
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
return cooked;
}
var FrameLoadingStyle;
(function (FrameLoadingStyle) {
FrameLoadingStyle["eager"] = "eager";
FrameLoadingStyle["lazy"] = "lazy";
})(FrameLoadingStyle || (FrameLoadingStyle = {}));
var FrameElement = (function (_super) {
__extends(FrameElement, _super);
function FrameElement() {
var _this = _super.call(this) || this;
_this.loaded = Promise.resolve();
_this.delegate = new FrameElement.delegateConstructor(_this);
return _this;
}
Object.defineProperty(FrameElement, "observedAttributes", {
get: function () {
return ["disabled", "loading", "src"];
},
enumerable: false,
configurable: true
});
FrameElement.prototype.connectedCallback = function () {
this.delegate.connect();
};
FrameElement.prototype.disconnectedCallback = function () {
this.delegate.disconnect();
};
FrameElement.prototype.attributeChangedCallback = function (name) {
if (name == "loading") {
this.delegate.loadingStyleChanged();
}
else if (name == "src") {
this.delegate.sourceURLChanged();
}
else {
this.delegate.disabledChanged();
}
};
Object.defineProperty(FrameElement.prototype, "src", {
get: function () {
return this.getAttribute("src");
},
set: function (value) {
if (value) {
this.setAttribute("src", value);
}
else {
this.removeAttribute("src");
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(FrameElement.prototype, "loading", {
get: function () {
return frameLoadingStyleFromString(this.getAttribute("loading") || "");
},
set: function (value) {
if (value) {
this.setAttribute("loading", value);
}
else {
this.removeAttribute("loading");
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(FrameElement.prototype, "disabled", {
get: function () {
return this.hasAttribute("disabled");
},
set: function (value) {
if (value) {
this.setAttribute("disabled", "");
}
else {
this.removeAttribute("disabled");
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(FrameElement.prototype, "autoscroll", {
get: function () {
return this.hasAttribute("autoscroll");
},
set: function (value) {
if (value) {
this.setAttribute("autoscroll", "");
}
else {
this.removeAttribute("autoscroll");
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(FrameElement.prototype, "complete", {
get: function () {
return !this.delegate.isLoading;
},
enumerable: false,
configurable: true
});
Object.defineProperty(FrameElement.prototype, "isActive", {
get: function () {
return this.ownerDocument === document && !this.isPreview;
},
enumerable: false,
configurable: true
});
Object.defineProperty(FrameElement.prototype, "isPreview", {
get: function () {
var _a, _b;
return (_b = (_a = this.ownerDocument) === null || _a === void 0 ? void 0 : _a.documentElement) === null || _b === void 0 ? void 0 : _b.hasAttribute("data-turbo-preview");
},
enumerable: false,
configurable: true
});
return FrameElement;
}(HTMLElement));
function frameLoadingStyleFromString(style) {
switch (style.toLowerCase()) {
case "lazy": return FrameLoadingStyle.lazy;
default: return FrameLoadingStyle.eager;
}
}
function expandURL(locatable) {
return new URL(locatable.toString(), document.baseURI);
}
function getAnchor(url) {
var anchorMatch;
if (url.hash) {
return url.hash.slice(1);
}
else if (anchorMatch = url.href.match(/#(.*)$/)) {
return anchorMatch[1];
}
else {
return "";
}
}
function getExtension(url) {
return (getLastPathComponent(url).match(/\.[^.]*$/) || [])[0] || "";
}
function isHTML(url) {
return !!getExtension(url).match(/^(?:|\.(?:htm|html|xhtml))$/);
}
function isPrefixedBy(baseURL, url) {
var prefix = getPrefix(url);
return baseURL.href === expandURL(prefix).href || baseURL.href.startsWith(prefix);
}
function toCacheKey(url) {
var anchorLength = url.hash.length;
if (anchorLength < 2) {
return url.href;
}
else {
return url.href.slice(0, -anchorLength);
}
}
function urlsAreEqual(left, right) {
return expandURL(left).href == expandURL(right).href;
}
function getPathComponents(url) {
return url.pathname.split("/").slice(1);
}
function getLastPathComponent(url) {
return getPathComponents(url).slice(-1)[0];
}
function getPrefix(url) {
return addTrailingSlash(url.origin + url.pathname);
}
function addTrailingSlash(value) {
return value.endsWith("/") ? value : value + "/";
}
var FetchResponse = (function () {
function FetchResponse(response) {
this.response = response;
}
Object.defineProperty(FetchResponse.prototype, "succeeded", {
get: function () {
return this.response.ok;
},
enumerable: false,
configurable: true
});
Object.defineProperty(FetchResponse.prototype, "failed", {
get: function () {
return !this.succeeded;
},
enumerable: false,
configurable: true
});
Object.defineProperty(FetchResponse.prototype, "clientError", {
get: function () {
return this.statusCode >= 400 && this.statusCode <= 499;
},
enumerable: false,
configurable: true
});
Object.defineProperty(FetchResponse.prototype, "serverError", {
get: function () {
return this.statusCode >= 500 && this.statusCode <= 599;
},
enumerable: false,
configurable: true
});
Object.defineProperty(FetchResponse.prototype, "redirected", {
get: function () {
return this.response.redirected;
},
enumerable: false,
configurable: true
});
Object.defineProperty(FetchResponse.prototype, "location", {
get: function () {
return expandURL(this.response.url);
},
enumerable: false,
configurable: true
});
Object.defineProperty(FetchResponse.prototype, "isHTML", {
get: function () {
return this.contentType && this.contentType.match(/^(?:text\/([^\s;,]+\b)?html|application\/xhtml\+xml)\b/);
},
enumerable: false,
configurable: true
});
Object.defineProperty(FetchResponse.prototype, "statusCode", {
get: function () {
return this.response.status;
},
enumerable: false,
configurable: true
});
Object.defineProperty(FetchResponse.prototype, "contentType", {
get: function () {
return this.header("Content-Type");
},
enumerable: false,
configurable: true
});
Object.defineProperty(FetchResponse.prototype, "responseText", {
get: function () {
return this.response.text();
},
enumerable: false,
configurable: true
});
Object.defineProperty(FetchResponse.prototype, "responseHTML", {
get: function () {
if (this.isHTML) {
return this.response.text();
}
else {
return Promise.resolve(undefined);
}
},
enumerable: false,
configurable: true
});
FetchResponse.prototype.header = function (name) {
return this.response.headers.get(name);
};
return FetchResponse;
}());
function dispatch(eventName, _a) {
var _b = _a === void 0 ? {} : _a, target = _b.target, cancelable = _b.cancelable, detail = _b.detail;
var event = new CustomEvent(eventName, { cancelable: cancelable, bubbles: true, detail: detail });
void (target || document.documentElement).dispatchEvent(event);
return event;
}
function nextAnimationFrame() {
return new Promise(function (resolve) { return requestAnimationFrame(function () { return resolve(); }); });
}
function nextEventLoopTick() {
return new Promise(function (resolve) { return setTimeout(function () { return resolve(); }, 0); });
}
function nextMicrotask() {
return Promise.resolve();
}
function parseHTMLDocument(html) {
if (html === void 0) { html = ""; }
return new DOMParser().parseFromString(html, "text/html");
}
function unindent(strings) {
var values = [];
for (var _i = 1; _i < arguments.length; _i++) {
values[_i - 1] = arguments[_i];
}
var lines = interpolate(strings, values).replace(/^\n/, "").split("\n");
var match = lines[0].match(/^\s+/);
var indent = match ? match[0].length : 0;
return lines.map(function (line) { return line.slice(indent); }).join("\n");
}
function interpolate(strings, values) {
return strings.reduce(function (result, string, i) {
var value = values[i] == undefined ? "" : values[i];
return result + string + value;
}, "");
}
function uuid() {
return Array.apply(null, { length: 36 }).map(function (_, i) {
if (i == 8 || i == 13 || i == 18 || i == 23) {
return "-";
}
else if (i == 14) {
return "4";
}
else if (i == 19) {
return (Math.floor(Math.random() * 4) + 8).toString(16);
}
else {
return Math.floor(Math.random() * 15).toString(16);
}
}).join("");
}
var FetchMethod;
(function (FetchMethod) {
FetchMethod[FetchMethod["get"] = 0] = "get";
FetchMethod[FetchMethod["post"] = 1] = "post";
FetchMethod[FetchMethod["put"] = 2] = "put";
FetchMethod[FetchMethod["patch"] = 3] = "patch";
FetchMethod[FetchMethod["delete"] = 4] = "delete";
})(FetchMethod || (FetchMethod = {}));
function fetchMethodFromString(method) {
switch (method.toLowerCase()) {
case "get": return FetchMethod.get;
case "post": return FetchMethod.post;
case "put": return FetchMethod.put;
case "patch": return FetchMethod.patch;
case "delete": return FetchMethod.delete;
}
}
var FetchRequest = (function () {
function FetchRequest(delegate, method, location, body) {
if (body === void 0) { body = new URLSearchParams; }
this.abortController = new AbortController;
this.delegate = delegate;
this.method = method;
this.headers = this.defaultHeaders;
if (this.isIdempotent) {
this.url = mergeFormDataEntries(location, __spread(body.entries()));
}
else {
this.body = body;
this.url = location;
}
}
Object.defineProperty(FetchRequest.prototype, "location", {
get: function () {
return this.url;
},
enumerable: false,
configurable: true
});
Object.defineProperty(FetchRequest.prototype, "params", {
get: function () {
return this.url.searchParams;
},
enumerable: false,
configurable: true
});
Object.defineProperty(FetchRequest.prototype, "entries", {
get: function () {
return this.body ? Array.from(this.body.entries()) : [];
},
enumerable: false,
configurable: true
});
FetchRequest.prototype.cancel = function () {
this.abortController.abort();
};
FetchRequest.prototype.perform = function () {
var _a, _b;
return __awaiter(this, void 0, void 0, function () {
var fetchOptions, response, error_1;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
fetchOptions = this.fetchOptions;
(_b = (_a = this.delegate).prepareHeadersForRequest) === null || _b === void 0 ? void 0 : _b.call(_a, this.headers, this);
dispatch("turbo:before-fetch-request", { detail: { fetchOptions: fetchOptions } });
_c.label = 1;
case 1:
_c.trys.push([1, 4, 5, 6]);
this.delegate.requestStarted(this);
return [4, fetch(this.url.href, fetchOptions)];
case 2:
response = _c.sent();
return [4, this.receive(response)];
case 3: return [2, _c.sent()];
case 4:
error_1 = _c.sent();
this.delegate.requestErrored(this, error_1);
throw error_1;
case 5:
this.delegate.requestFinished(this);
return [7];
case 6: return [2];
}
});
});
};
FetchRequest.prototype.receive = function (response) {
return __awaiter(this, void 0, void 0, function () {
var fetchResponse, event;
return __generator(this, function (_a) {
fetchResponse = new FetchResponse(response);
event = dispatch("turbo:before-fetch-response", { cancelable: true, detail: { fetchResponse: fetchResponse } });
if (event.defaultPrevented) {
this.delegate.requestPreventedHandlingResponse(this, fetchResponse);
}
else if (fetchResponse.succeeded) {
this.delegate.requestSucceededWithResponse(this, fetchResponse);
}
else {
this.delegate.requestFailedWithResponse(this, fetchResponse);
}
return [2, fetchResponse];
});
});
};
Object.defineProperty(FetchRequest.prototype, "fetchOptions", {
get: function () {
return {
method: FetchMethod[this.method].toUpperCase(),
credentials: "same-origin",
headers: this.headers,
redirect: "follow",
body: this.body,
signal: this.abortSignal
};
},
enumerable: false,
configurable: true
});
Object.defineProperty(FetchRequest.prototype, "defaultHeaders", {
get: function () {
return {
"Accept": "text/html, application/xhtml+xml"
};
},
enumerable: false,
configurable: true
});
Object.defineProperty(FetchRequest.prototype, "isIdempotent", {
get: function () {
return this.method == FetchMethod.get;
},
enumerable: false,
configurable: true
});
Object.defineProperty(FetchRequest.prototype, "abortSignal", {
get: function () {
return this.abortController.signal;
},
enumerable: false,
configurable: true
});
return FetchRequest;
}());
function mergeFormDataEntries(url, entries) {
var e_1, _a;
var currentSearchParams = new URLSearchParams(url.search);
try {
for (var entries_1 = __values(entries), entries_1_1 = entries_1.next(); !entries_1_1.done; entries_1_1 = entries_1.next()) {
var _b = __read(entries_1_1.value, 2), name_1 = _b[0], value = _b[1];
if (value instanceof File)
continue;
if (currentSearchParams.has(name_1)) {
currentSearchParams.delete(name_1);
url.searchParams.set(name_1, value);
}
else {
url.searchParams.append(name_1, value);
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (entries_1_1 && !entries_1_1.done && (_a = entries_1.return)) _a.call(entries_1);
}
finally { if (e_1) throw e_1.error; }
}
return url;
}
var AppearanceObserver = (function () {
function AppearanceObserver(delegate, element) {
var _this = this;
this.started = false;
this.intersect = function (entries) {
var lastEntry = entries.slice(-1)[0];
if (lastEntry === null || lastEntry === void 0 ? void 0 : lastEntry.isIntersecting) {
_this.delegate.elementAppearedInViewport(_this.element);
}
};
this.delegate = delegate;
this.element = element;
this.intersectionObserver = new IntersectionObserver(this.intersect);
}
AppearanceObserver.prototype.start = function () {
if (!this.started) {
this.started = true;
this.intersectionObserver.observe(this.element);
}
};
AppearanceObserver.prototype.stop = function () {
if (this.started) {
this.started = false;
this.intersectionObserver.unobserve(this.element);
}
};
return AppearanceObserver;
}());
var StreamMessage = (function () {
function StreamMessage(html) {
this.templateElement = document.createElement("template");
this.templateElement.innerHTML = html;
}
StreamMessage.wrap = function (message) {
if (typeof message == "string") {
return new this(message);
}
else {
return message;
}
};
Object.defineProperty(StreamMessage.prototype, "fragment", {
get: function () {
var e_1, _a;
var fragment = document.createDocumentFragment();
try {
for (var _b = __values(this.foreignElements), _c = _b.next(); !_c.done; _c = _b.next()) {
var element = _c.value;
fragment.appendChild(document.importNode(element, true));
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
return fragment;
},
enumerable: false,
configurable: true
});
Object.defineProperty(StreamMessage.prototype, "foreignElements", {
get: function () {
return this.templateChildren.reduce(function (streamElements, child) {
if (child.tagName.toLowerCase() == "turbo-stream") {
return __spread(streamElements, [child]);
}
else {
return streamElements;
}
}, []);
},
enumerable: false,
configurable: true
});
Object.defineProperty(StreamMessage.prototype, "templateChildren", {
get: function () {
return Array.from(this.templateElement.content.children);
},
enumerable: false,
configurable: true
});
StreamMessage.contentType = "text/vnd.turbo-stream.html";
return StreamMessage;
}());
var FormSubmissionState;
(function (FormSubmissionState) {
FormSubmissionState[FormSubmissionState["initialized"] = 0] = "initialized";
FormSubmissionState[FormSubmissionState["requesting"] = 1] = "requesting";
FormSubmissionState[FormSubmissionState["waiting"] = 2] = "waiting";
FormSubmissionState[FormSubmissionState["receiving"] = 3] = "receiving";
FormSubmissionState[FormSubmissionState["stopping"] = 4] = "stopping";
FormSubmissionState[FormSubmissionState["stopped"] = 5] = "stopped";
})(FormSubmissionState || (FormSubmissionState = {}));
var FormEnctype;
(function (FormEnctype) {
FormEnctype["urlEncoded"] = "application/x-www-form-urlencoded";
FormEnctype["multipart"] = "multipart/form-data";
FormEnctype["plain"] = "text/plain";
})(FormEnctype || (FormEnctype = {}));
function formEnctypeFromString(encoding) {
switch (encoding.toLowerCase()) {
case FormEnctype.multipart: return FormEnctype.multipart;
case FormEnctype.plain: return FormEnctype.plain;
default: return FormEnctype.urlEncoded;
}
}
var FormSubmission = (function () {
function FormSubmission(delegate, formElement, submitter, mustRedirect) {
if (mustRedirect === void 0) { mustRedirect = false; }
this.state = FormSubmissionState.initialized;
this.delegate = delegate;
this.formElement = formElement;
this.submitter = submitter;
this.formData = buildFormData(formElement, submitter);
this.fetchRequest = new FetchRequest(this, this.method, this.location, this.body);
this.mustRedirect = mustRedirect;
}
Object.defineProperty(FormSubmission.prototype, "method", {
get: function () {
var _a;
var method = ((_a = this.submitter) === null || _a === void 0 ? void 0 : _a.getAttribute("formmethod")) || this.formElement.getAttribute("method") || "";
return fetchMethodFromString(method.toLowerCase()) || FetchMethod.get;
},
enumerable: false,
configurable: true
});
Object.defineProperty(FormSubmission.prototype, "action", {
get: function () {
var _a;
return ((_a = this.submitter) === null || _a === void 0 ? void 0 : _a.getAttribute("formaction")) || this.formElement.action;
},
enumerable: false,
configurable: true
});
Object.defineProperty(FormSubmission.prototype, "location", {
get: function () {
return expandURL(this.action);
},
enumerable: false,
configurable: true
});
Object.defineProperty(FormSubmission.prototype, "body", {
get: function () {
if (this.enctype == FormEnctype.urlEncoded || this.method == FetchMethod.get) {
return new URLSearchParams(this.stringFormData);
}
else {
return this.formData;
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(FormSubmission.prototype, "enctype", {
get: function () {
var _a;
return formEnctypeFromString(((_a = this.submitter) === null || _a === void 0 ? void 0 : _a.getAttribute("formenctype")) || this.formElement.enctype);
},
enumerable: false,
configurable: true
});
Object.defineProperty(FormSubmission.prototype, "isIdempotent", {
get: function () {
return this.fetchRequest.isIdempotent;
},
enumerable: false,
configurable: true
});
Object.defineProperty(FormSubmission.prototype, "stringFormData", {
get: function () {
return __spread(this.formData).reduce(function (entries, _a) {
var _b = __read(_a, 2), name = _b[0], value = _b[1];
return entries.concat(typeof value == "string" ? [[name, value]] : []);
}, []);
},
enumerable: false,
configurable: true
});
FormSubmission.prototype.start = function () {
return __awaiter(this, void 0, void 0, function () {
var initialized, requesting;
return __generator(this, function (_a) {
initialized = FormSubmissionState.initialized, requesting = FormSubmissionState.requesting;
if (this.state == initialized) {
this.state = requesting;
return [2, this.fetchRequest.perform()];
}
return [2];
});
});
};
FormSubmission.prototype.stop = function () {
var stopping = FormSubmissionState.stopping, stopped = FormSubmissionState.stopped;
if (this.state != stopping && this.state != stopped) {
this.state = stopping;
this.fetchRequest.cancel();
return true;
}
};
FormSubmission.prototype.prepareHeadersForRequest = function (headers, request) {
if (!request.isIdempotent) {
var token = getCookieValue(getMetaContent("csrf-param")) || getMetaContent("csrf-token");
if (token) {
headers["X-CSRF-Token"] = token;
}
headers["Accept"] = [StreamMessage.contentType, headers["Accept"]].join(", ");
}
};
FormSubmission.prototype.requestStarted = function (request) {
this.state = FormSubmissionState.waiting;
dispatch("turbo:submit-start", { target: this.formElement, detail: { formSubmission: this } });
this.delegate.formSubmissionStarted(this);
};
FormSubmission.prototype.requestPreventedHandlingResponse = function (request, response) {
this.result = { success: response.succeeded, fetchResponse: response };
};
FormSubmission.prototype.requestSucceededWithResponse = function (request, response) {
if (response.clientError || response.serverError) {
this.delegate.formSubmissionFailedWithResponse(this, response);
}
else if (this.requestMustRedirect(request) && responseSucceededWithoutRedirect(response)) {
var error = new Error("Form responses must redirect to another location");
this.delegate.formSubmissionErrored(this, error);
}
else {
this.state = FormSubmissionState.receiving;
this.result = { success: true, fetchResponse: response };
this.delegate.formSubmissionSucceededWithResponse(this, response);
}
};
FormSubmission.prototype.requestFailedWithResponse = function (request, response) {
this.result = { success: false, fetchResponse: response };
this.delegate.formSubmissionFailedWithResponse(this, response);
};
FormSubmission.prototype.requestErrored = function (request, error) {
this.result = { success: false, error: error };
this.delegate.formSubmissionErrored(this, error);
};
FormSubmission.prototype.requestFinished = function (request) {
this.state = FormSubmissionState.stopped;
dispatch("turbo:submit-end", { target: this.formElement, detail: __assign({ formSubmission: this }, this.result) });
this.delegate.formSubmissionFinished(this);
};
FormSubmission.prototype.requestMustRedirect = function (request) {
return !request.isIdempotent && this.mustRedirect;
};
return FormSubmission;
}());
function buildFormData(formElement, submitter) {
var formData = new FormData(formElement);
var name = submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("name");
var value = submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("value");
if (name && value != null && formData.get(name) != value) {
formData.append(name, value);
}
return formData;
}
function getCookieValue(cookieName) {
if (cookieName != null) {
var cookies = document.cookie ? document.cookie.split("; ") : [];
var cookie = cookies.find(function (cookie) { return cookie.startsWith(cookieName); });
if (cookie) {
var value = cookie.split("=").slice(1).join("=");
return value ? decodeURIComponent(value) : undefined;
}
}
}
function getMetaContent(name) {
var element = document.querySelector("meta[name=\"" + name + "\"]");
return element && element.content;
}
function responseSucceededWithoutRedirect(response) {
return response.statusCode == 200 && !response.redirected;
}
var Snapshot = (function () {
function Snapshot(element) {
this.element = element;
}
Object.defineProperty(Snapshot.prototype, "children", {
get: function () {
return __spread(this.element.children);
},
enumerable: false,
configurable: true
});
Snapshot.prototype.hasAnchor = function (anchor) {
return this.getElementForAnchor(anchor) != null;
};
Snapshot.prototype.getElementForAnchor = function (anchor) {
try {
return this.element.querySelector("[id='" + anchor + "'], a[name='" + anchor + "']");
}
catch (_a) {
return null;
}
};
Object.defineProperty(Snapshot.prototype, "isConnected", {
get: function () {
return this.element.isConnected;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Snapshot.prototype, "firstAutofocusableElement", {
get: function () {
return this.element.querySelector("[autofocus]");
},
enumerable: false,
configurable: true
});
Object.defineProperty(Snapshot.prototype, "permanentElements", {
get: function () {
return __spread(this.element.querySelectorAll("[id][data-turbo-permanent]"));
},
enumerable: false,
configurable: true
});
Snapshot.prototype.getPermanentElementById = function (id) {
return this.element.querySelector("#" + id + "[data-turbo-permanent]");
};
Snapshot.prototype.getPermanentElementMapForSnapshot = function (snapshot) {
var e_1, _a;
var permanentElementMap = {};
try {
for (var _b = __values(this.permanentElements), _c = _b.next(); !_c.done; _c = _b.next()) {
var currentPermanentElement = _c.value;
var id = currentPermanentElement.id;
var newPermanentElement = snapshot.getPermanentElementById(id);
if (newPermanentElement) {
permanentElementMap[id] = [currentPermanentElement, newPermanentElement];
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
return permanentElementMap;
};
return Snapshot;
}());
var FormInterceptor = (function () {
function FormInterceptor(delegate, element) {
var _this = this;
this.submitBubbled = (function (event) {
if (event.target instanceof HTMLFormElement) {
var form = event.target;
var submitter = event.submitter || undefined;
if (_this.delegate.shouldInterceptFormSubmission(form, submitter)) {
event.preventDefault();
event.stopImmediatePropagation();
_this.delegate.formSubmissionIntercepted(form, submitter);
}
}
});
this.delegate = delegate;
this.element = element;
}
FormInterceptor.prototype.start = function () {
this.element.addEventListener("submit", this.submitBubbled);
};
FormInterceptor.prototype.stop = function () {
this.element.removeEventListener("submit", this.submitBubbled);
};
return FormInterceptor;
}());
var View = (function () {
function View(delegate, element) {
this.delegate = delegate;
this.element = element;
}
View.prototype.scrollToAnchor = function (anchor) {
var element = this.snapshot.getElementForAnchor(anchor);
if (element) {
this.scrollToElement(element);
}
else {
this.scrollToPosition({ x: 0, y: 0 });
}
};
View.prototype.scrollToElement = function (element) {
element.scrollIntoView();
};
View.prototype.scrollToPosition = function (_a) {
var x = _a.x, y = _a.y;
this.scrollRoot.scrollTo(x, y);
};
Object.defineProperty(View.prototype, "scrollRoot", {
get: function () {
return window;
},
enumerable: false,
configurable: true
});
View.prototype.render = function (renderer) {
return __awaiter(this, void 0, void 0, function () {
var isPreview, shouldRender, snapshot;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (this.renderer) {
throw new Error("rendering is already in progress");
}
isPreview = renderer.isPreview, shouldRender = renderer.shouldRender, snapshot = renderer.newSnapshot;
if (!shouldRender) return [3, 5];
_a.label = 1;
case 1:
_a.trys.push([1, , 3, 4]);
this.renderer = renderer;
this.prepareToRenderSnapshot(renderer);
this.delegate.viewWillRenderSnapshot(snapshot, isPreview);
return [4, this.renderSnapshot(renderer)];
case 2:
_a.sent();
this.delegate.viewRenderedSnapshot(snapshot, isPreview);
this.finishRenderingSnapshot(renderer);
return [3, 4];
case 3:
delete this.renderer;
return [7];
case 4: return [3, 6];
case 5:
this.invalidate();
_a.label = 6;
case 6: return [2];
}
});
});
};
View.prototype.invalidate = function () {
this.delegate.viewInvalidated();
};
View.prototype.prepareToRenderSnapshot = function (renderer) {
this.markAsPreview(renderer.isPreview);
renderer.prepareToRender();
};
View.prototype.markAsPreview = function (isPreview) {
if (isPreview) {
this.element.setAttribute("data-turbo-preview", "");
}
else {
this.element.removeAttribute("data-turbo-preview");
}
};
View.prototype.renderSnapshot = function (renderer) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4, renderer.render()];
case 1:
_a.sent();
return [2];
}
});
});
};
View.prototype.finishRenderingSnapshot = function (renderer) {
renderer.finishRendering();
};
return View;
}());
var FrameView = (function (_super) {
__extends(FrameView, _super);
function FrameView() {
return _super !== null && _super.apply(this, arguments) || this;
}
FrameView.prototype.invalidate = function () {
this.element.innerHTML = "";
};
Object.defineProperty(FrameView.prototype, "snapshot", {
get: function () {
return new Snapshot(this.element);
},
enumerable: false,
configurable: true
});
return FrameView;
}(View));
var LinkInterceptor = (function () {
function LinkInterceptor(delegate, element) {
var _this = this;
this.clickBubbled = function (event) {
if (_this.respondsToEventTarget(event.target)) {
_this.clickEvent = event;
}
else {
delete _this.clickEvent;
}
};
this.linkClicked = (function (event) {
if (_this.clickEvent && _this.respondsToEventTarget(event.target) && event.target instanceof Element) {
if (_this.delegate.shouldInterceptLinkClick(event.target, event.detail.url)) {
_this.clickEvent.preventDefault();
event.preventDefault();
_this.convertLinkWithMethodClickToFormSubmission(event.target) ||
_this.delegate.linkClickIntercepted(event.target, event.detail.url);
}
}
delete _this.clickEvent;
});
this.willVisit = function () {
delete _this.clickEvent;
};
this.delegate = delegate;
this.element = element;
}
LinkInterceptor.prototype.start = function () {
this.element.addEventListener("click", this.clickBubbled);
document.addEventListener("turbo:click", this.linkClicked);
document.addEventListener("turbo:before-visit", this.willVisit);
};
LinkInterceptor.prototype.stop = function () {
this.element.removeEventListener("click", this.clickBubbled);
document.removeEventListener("turbo:click", this.linkClicked);
document.removeEventListener("turbo:before-visit", this.willVisit);
};
LinkInterceptor.prototype.convertLinkWithMethodClickToFormSubmission = function (link) {
var _a;
var linkMethod = link.getAttribute("data-turbo-method") || link.getAttribute("data-method");
if (linkMethod) {
var form = document.createElement("form");
form.method = linkMethod;
form.action = link.getAttribute("href") || "undefined";
(_a = link.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(form, link);
return dispatch("submit", { target: form });
}
else {
return false;
}
};
LinkInterceptor.prototype.respondsToEventTarget = function (target) {
var element = target instanceof Ele