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.