PageSourceSearch

https://www.euroclix.nl/assets/f93cbd4b2ba5510d/app/pages/resources/js/tapestry-form-params.js

js euroclix.nl collected 2026-10-01 10:33:11 UTC 5,312 bytes, 196 lines download raw bytes

1(function () {
2	if (window.__euroclixTapestryFormParamsInstalled) {
3		return;
4	}
5	window.__euroclixTapestryFormParamsInstalled = true;
6
7	// iOS WKWebView (and some proxies) drop query parameters from POST URLs.
8	// Tapestry encodes form state in t:formdata on the action URL, so mirror those
9	// parameters into hidden fields so they still arrive in the POST body.
10	function formHasField(form, name) {
11		var inputs = form.elements;
12		for (var i = 0; i < inputs.length; i++) {
13			if (inputs[i].name === name) {
14				return true;
15			}
16		}
17		return false;
18	}
19
20	function decodeQueryComponent(value) {
21		return decodeURIComponent(String(value).replace(/\+/g, " "));
22	}
23
24	function moveTapestryFormParams(form) {
25		if (!form || form.tagName !== "FORM") {
26			return;
27		}
28
29		var method = (form.getAttribute("method") || "get").toLowerCase();
30		if (method !== "post") {
31			return;
32		}
33
34		var action = form.getAttribute("action");
35		if (!action) {
36			return;
37		}
38
39		var qIndex = action.indexOf("?");
40		if (qIndex === -1) {
41			return;
42		}
43
44		var queryString = action.substring(qIndex + 1);
45		queryString.split("&").forEach(function (pair) {
46			if (!pair) {
47				return;
48			}
49			var eqIndex = pair.indexOf("=");
50			var name =
51				eqIndex === -1 ?
52					decodeQueryComponent(pair)
53				:	decodeQueryComponent(pair.substring(0, eqIndex));
54			var value =
55				eqIndex === -1 ? "" : (
56					decodeQueryComponent(pair.substring(eqIndex + 1))
57				);
58			if (formHasField(form, name)) {
59				return;
60			}
61			var hidden = document.createElement("input");
62			hidden.type = "hidden";
63			hidden.name = name;
64			hidden.value = value;
65			form.appendChild(hidden);
66		});
67	}
68
69	function installFormSubmitPatch() {
70		if (window.__euroclixFormSubmitPatched || !window.HTMLFormElement) {
71			return;
72		}
73		window.__euroclixFormSubmitPatched = true;
74
75		var nativeSubmit = HTMLFormElement.prototype.submit;
76		HTMLFormElement.prototype.submit = function () {
77			moveTapestryFormParams(this);
78			return nativeSubmit.call(this);
79		};
80
81		if (HTMLFormElement.prototype.requestSubmit) {
82			var nativeRequestSubmit = HTMLFormElement.prototype.requestSubmit;
83			HTMLFormElement.prototype.requestSubmit = function (submitter) {
84				moveTapestryFormParams(this);
85				return nativeRequestSubmit.call(this, submitter);
86			};
87		}
88	}
89
90	document.addEventListener(
91		"submit",
92		function (event) {
93			moveTapestryFormParams(event.target);
94		},
95		true,
96	);
97
98	installFormSubmitPatch();
99
100	window.euroclixMoveTapestryFormParams = moveTapestryFormParams;
101
102	function looksLikeJson(text) {
103		if (!text) {
104			return false;
105		}
106		var trimmed = String(text).replace(/^\s+/, "");
107		return trimmed.charAt(0) === "{" || trimmed.charAt(0) === "[";
108	}
109
110	function installTapestryAjaxGuards() {
111		if (window.__euroclixTapestryAjaxGuardsInstalled) {
112			return true;
113		}
114		if (!window.Tapestry || !Tapestry.loadScriptsInReply) {
115			return false;
116		}
117		window.__euroclixTapestryAjaxGuardsInstalled = true;
118
119		// Prototype only fills responseJSON when Content-Type is application/json.
120		// Tapestry zone posts still call processReply(responseJSON), which throws
121		// "Cannot read properties of null (reading 'redirectURL')" for HTML/empty 200s.
122		if (window.Ajax && Ajax.Response && Ajax.Response.prototype._getResponseJSON) {
123			var originalGetJson = Ajax.Response.prototype._getResponseJSON;
124			Ajax.Response.prototype._getResponseJSON = function () {
125				var json = originalGetJson.call(this);
126				if (json != null) {
127					return json;
128				}
129				if (!looksLikeJson(this.responseText)) {
130					return null;
131				}
132				try {
133					return this.responseText.evalJSON(true);
134				} catch (e) {
135					return null;
136				}
137			};
138		}
139
140		var originalLoadScripts = Tapestry.loadScriptsInReply;
141		Tapestry.loadScriptsInReply = function (reply, callback) {
142			if (!reply) {
143				if (callback) {
144					callback.call(this);
145				}
146				return;
147			}
148			return originalLoadScripts.call(this, reply, callback);
149		};
150
151		if (Tapestry.Initializer && Tapestry.Initializer.formEventManager) {
152			var originalFormEventManager = Tapestry.Initializer.formEventManager;
153			Tapestry.Initializer.formEventManager = function (spec) {
154				if (!spec || !spec.formId || !document.getElementById(spec.formId)) {
155					return;
156				}
157				return originalFormEventManager.call(this, spec);
158			};
159		}
160
161		if (Tapestry.ZoneManager) {
162			Tapestry.ZoneManager.addMethods({
163				processReply: function (reply) {
164					if (!reply) {
165						return;
166					}
167					Tapestry.loadScriptsInReply(reply, function () {
168						var zoneUpdates = reply.zones || {};
169						var primaryId = this.element && this.element.id;
170						// When the same zone is in reply.zones, skip reply.content.
171						// Applying both inserts one form then replaces it; inits
172						// then call $T() for the removed form id (getStorage on null).
173						if (
174							reply.content != undefined &&
175							!(primaryId && zoneUpdates[primaryId] != undefined)
176						) {
177							this.show(reply.content);
178						}
179						Object.keys(zoneUpdates).each(function (zoneId) {
180							var manager = Tapestry.findZoneManagerForZone(zoneId);
181							if (manager) {
182								manager.show(zoneUpdates[zoneId]);
183							}
184						});
185					}.bind(this));
186				}
187			});
188		}
189
190		return true;
191	}
192
193	if (!installTapestryAjaxGuards()) {
194		document.addEventListener("DOMContentLoaded", installTapestryAjaxGuards);
195	}
196})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.