ajaxify 8.2.7 → 8.3.0

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.
Files changed (3) hide show
  1. package/ajaxify.js +786 -598
  2. package/ajaxify.min.js +1 -1
  3. package/package.json +35 -35
package/ajaxify.js CHANGED
@@ -5,9 +5,9 @@
5
5
  *
6
6
  * Copyright Arvind Gupta; MIT Licensed
7
7
  *
8
- * Version 8.2.7
8
+ * Version 8.3.0
9
9
  */
10
-
10
+
11
11
  /* INTERFACE: See also https://4nf.org/interface/
12
12
 
13
13
  Simplest plugin call:
@@ -19,30 +19,38 @@ Ajaxifies the whole site, dynamically replacing the elements specified in "eleme
19
19
 
20
20
  let Ay; //to become the global handle for the main Ajaxify parent class - if used by you already, please rename and rebuild
21
21
 
22
- function _won(a, b, c = false) { if(c === false) c = {once: true}; setTimeout( () => window.addEventListener(a, b, c) ); };
22
+ function _won(a, b, c = false) {
23
+ if (c === false) c = { once: true };
24
+ setTimeout(() => window.addEventListener(a, b, c));
25
+ }
23
26
 
24
27
  //Module global helpers
25
- let rootUrl = location.origin, inlineclass = "ajy-inline",
28
+ let rootUrl = location.origin,
29
+ inlineclass = "ajy-inline",
26
30
  bdy,
27
- qa=(s,o=document)=>o.querySelectorAll(s),
28
- qs=(s,o=document)=>o.querySelector(s),
29
- qha=(e)=>qs("head").appendChild(e),
30
- prC=(e)=>e.parentNode.removeChild(e),
31
- dcE=(e)=>document.createElement(e),
32
-
33
- _copyAttributes=(el, S, flush)=>{ //copy all attributes of element generically
34
- if(flush) [...el.attributes].forEach(e => el.removeAttribute(e.name)); //delete all old attributes
35
- [...S.attributes].forEach(e => e.nodeValue == "ajy-body" || el.setAttribute(e.nodeName, e.nodeValue)); //low-level insertion
36
- };
31
+ qa = (s, o = document) => o.querySelectorAll(s),
32
+ qs = (s, o = document) => o.querySelector(s),
33
+ qha = (e) => qs("head").appendChild(e),
34
+ qba = (e) => qs("body").appendChild(e),
35
+ prC = (e) => e.parentNode.removeChild(e),
36
+ dcE = (e) => document.createElement(e),
37
+ _copyAttributes = (el, S, flush) => {
38
+ //copy all attributes of element generically
39
+ if (flush) [...el.attributes].forEach((e) => el.removeAttribute(e.name)); //delete all old attributes
40
+ [...S.attributes].forEach((e) => e.nodeValue == "ajy-body" || el.setAttribute(e.nodeName, e.nodeValue)); //low-level insertion
41
+ };
37
42
 
38
43
  // The main plugin - Ajaxify
39
- // Is passed the global options
44
+ // Is passed the global options
40
45
  // Checks for necessary pre-conditions - otherwise gracefully degrades
41
46
  // Initialises sub-plugins
42
47
  // Calls Pronto
43
- class Ajaxify { constructor(options) {
44
- String.prototype.iO = function(s) { return this.toString().indexOf(s) + 1; }; //Intuitively better understandable shorthand for String.indexOf() - String.iO()
45
- Ay = this;
48
+ class Ajaxify {
49
+ constructor(options) {
50
+ String.prototype.iO = function (s) {
51
+ return this.toString().indexOf(s) + 1;
52
+ }; //Intuitively better understandable shorthand for String.indexOf() - String.iO()
53
+ Ay = this;
46
54
 
47
55
  //Options default values
48
56
  Ay.s = {
@@ -76,572 +84,614 @@ Ay.s = {
76
84
  memoryoff : false, // strings - separated by ", " - if matched in any URLs - only these are NOT executed - set to "true" to disable memory completely
77
85
  cb : 0, // callback handler on completion of each Ajax request - default 0
78
86
  pluginon : true, // Plugin set "on" or "off" (==false) manually
79
- passCount: false // Show number of pass for debugging
87
+ passCount: false, // Show number of pass for debugging
88
+ DCLDelay: 0
80
89
  };
81
90
 
82
91
 
83
- Ay.pass = 0; Ay.currentURL = ""; Ay.h = {};
84
- Ay.parse = (s, pl) => (pl = dcE('div'), pl.insertAdjacentHTML('afterbegin', s), pl.firstElementChild); // HTML parser
85
- Ay.trigger = (t, e) => { let ev = document.createEvent('HTMLEvents'); ev.initEvent("pronto." + t, true, false); ev.data = e ? e : Ay.Rq("e"); window.dispatchEvent(ev); };
86
- Ay.internal = (url) => { if (!url) return false; if (typeof(url) === "object") url = url.href; if (url==="") return true; return url.substring(0,rootUrl.length) === rootUrl || !url.iO(":"); };
87
- Ay.intevents = () => {
88
- let iFn = function (a, b, c = false) { if ((this === document || this === window) && a=="DOMContentLoaded") setTimeout(b); else this.ael(a,b,c);}; // if "DOMContentLoaded" - execute function, else - add event listener
89
- EventTarget.prototype.ael = EventTarget.prototype.addEventListener; // store original method
90
- EventTarget.prototype.addEventListener = iFn; // start intercepting event listener addition
91
- };
92
-
93
- function _on(eventName, elementSelector, handler, el = document) { //e.currentTarget is document when the handler is called
94
- el.addEventListener(eventName, function(e) {
95
- // loop parent nodes from the target to the delegation node
96
- for (var target = e.target; target && target != this; target = target.parentNode) {
97
- if (target.matches(elementSelector)) {
98
- handler(target, e);
99
- break;
92
+ Ay.pass = 0;
93
+ Ay.currentURL = "";
94
+ Ay.h = {};
95
+ Ay.parse = (s, pl) => ((pl = dcE("div")), pl.insertAdjacentHTML("afterbegin", s), pl.firstElementChild); // HTML parser
96
+
97
+ // Trigger event
98
+ Ay.triggerEvent = (v) => {
99
+ if (Ay.s.DCLDelay !== false) {
100
+ const evnt = new Event(v, { bubbles: true, cancelable: true });
101
+ const dw = v === "DOMContentLoaded" ? document : window;
102
+ Ay.s.DCLDelay === 0
103
+ ? dw.dispatchEvent(evnt)
104
+ : setTimeout(() => {
105
+ dw.dispatchEvent(evnt);
106
+ }, Ay.s.DCLDelay);
100
107
  }
108
+ };
109
+
110
+ Ay.trigger = (t, e) => {
111
+ const ev = new Event("pronto." + t, { bubbles: true, cancelable: false });
112
+ ev.data = e ? e : Ay.Rq("e");
113
+ window.dispatchEvent(ev);
114
+ };
115
+
116
+ Ay.internal = (url) => {
117
+ if (!url) return false;
118
+ if (typeof url === "object") url = url.href;
119
+ if (url === "") return true;
120
+ return url.substring(0, rootUrl.length) === rootUrl || !url.iO(":");
121
+ };
122
+
123
+ Ay.intevents = () => {
124
+ let iFn = function (a, b, c = false) {
125
+ // if "DOMContentLoaded" - execute function, else - add event listener
126
+ if ((this === document || this === window) && (a == "DOMContentLoaded" || a == "load")) {
127
+ c = c ? Object.assign(c, { once: true }) : { once: true };
128
+ }
129
+ return this && this.ael(a, b, c);
130
+ };
131
+ EventTarget.prototype.ael = EventTarget.prototype.addEventListener; // store original method
132
+ EventTarget.prototype.addEventListener = iFn; // start intercepting event listener addition
133
+ };
134
+
135
+ function _on(eventName, elementSelector, handler, el = document) {
136
+ //e.currentTarget is document when the handler is called
137
+ el.addEventListener(
138
+ eventName,
139
+ function (e) {
140
+ // loop parent nodes from the target to the delegation node
141
+ for (var target = e.target; target && target != this; target = target.parentNode) {
142
+ if (target.matches(elementSelector)) {
143
+ handler(target, e);
144
+ break;
145
+ }
146
+ }
147
+ },
148
+ !!eventName.iO("mo")
149
+ );
101
150
  }
102
- }, !!eventName.iO('mo'));
103
- }
104
-
105
- class Hints { constructor(h) { let _ = this;
106
- _.list = (typeof h === 'string' && h.length > 0) ? h.split(", ") : false; //hints are passed as a comma separated string
107
- _.find = (t) => (!t || !_.list) ? false : _.list.some(h => t.iO(h)); //iterate through hints within passed text (t)
108
- }}
109
-
110
- function lg(m){ Ay.s.verbosity && console && console.log(m); }
111
-
112
- // The GetPage class
113
- // First parameter (o) is a switch:
114
- // empty - returns cache
115
- // <URL> - loads HTML via Ajax, second parameter "p" must be callback
116
- // + - pre-fetches page, second parameter "p" must be URL, third parameter "p2" must be callback
117
- // - - loads page into DOM and handle scripts, second parameter "p" must hold selection to load
118
- // x - returns response
119
- // otherwise - returns selection of current page to client
120
-
121
- class GetPage { constructor() {
122
- let rsp = 0, cb = 0, plus = 0, rt = "", ct = 0, rc = 0, ac = 0,
123
-
124
- //Regexes for escaping fetched HTML of a whole page - best of Baluptons Ajaxify
125
- //Makes it possible to pre-fetch an entire page
126
- docType = /<\!DOCTYPE[^>]*>/i,
127
- tagso = /<(html|head|link)([\s\>])/gi,
128
- tagsod = /<(body)([\s\>])/gi,
129
- tagsc = /<\/(html|head|body|link)\>/gi,
130
-
131
- //Helper strings
132
- div12 = '<div class="ajy-$1"$2',
133
- divid12 = '<div id="ajy-$1"$2';
134
-
135
- this.a = function (o, p, p2) {
136
- if (!o) return Ay.cache.g();
137
-
138
- if (o.iO("/")) {
139
- cb = p;
140
- if(plus == o) return;
141
- return _lPage(o);
142
- }
143
-
144
- if (o === "+") {
145
- plus = p;
146
- cb = p2;
147
- return _lPage(p, true);
148
- }
149
-
150
- if (o === "a") { if (rc > 0) {_cl(); ac.abort();} return; }
151
- if (o === "s") return ((rc) ? 1 : 0) + rt;
152
- if (o === "-") return _lSel(p);
153
- if (o === "x") return rsp;
154
-
155
- if (!Ay.cache.g()) return;
156
- if (o === "body") return qs("#ajy-" + o, Ay.cache.g());
157
- if (o === "script") return qa(o, Ay.cache.g());
158
151
 
159
- return qs((o === "title") ? o : ".ajy-" + o, Ay.cache.g());
160
- };
161
- let _lSel = t => (
162
- Ay.pass++,
163
- _lEls(t),
164
- qa("body > script").forEach(e => (e.classList.contains(inlineclass)) ? prC(e) : false),
165
- Ay.scripts(true),
166
- Ay.scripts("s"),
167
- Ay.scripts("c")
168
- ),
169
- _lPage = (h, pre) => {
170
- if (h.iO("#")) h = h.split("#")[0];
171
- if (Ay.Rq("is") || !Ay.cache.l(h)) return _lAjax(h, pre);
172
-
173
- plus = 0;
174
- if (cb) return cb();
175
- },
176
- _ld = (t, h) => {
177
- if(!h) return; //no input
178
-
179
- var c = h.cloneNode(true); // clone element node (true = deep clone)
180
- qa("script", c).forEach(e => prC(e));
181
- _copyAttributes(t, c, true);
182
- t.innerHTML = c.innerHTML;
183
- },
184
- _lEls = t =>
185
- Ay.cache.g() && !_isBody(t) && t.forEach(function(e) {
186
- _ld(e, qs("#" + e.getAttribute("id"), Ay.cache.g()));
187
- }),
188
- _isBody = t => t[0].tagName.toLowerCase() == "body" && (_ld(bdy, qs("#ajy-body", Ay.cache.g())), 1),
189
- _lAjax = (hin, pre) => {
190
- var ispost = Ay.Rq("is");
191
- if (pre) rt="p"; else rt="c";
192
-
193
- ac = new AbortController(); // set abort controller
194
- rc++; // set active request counter
195
- fetch(hin, {
196
- method: ((ispost) ? "POST" : "GET"),
197
- cache: "default",
198
- mode: "same-origin",
199
- headers: {"X-Requested-With": "XMLHttpRequest"},
200
- body: (ispost) ? Ay.Rq("d") : null,
201
- signal: ac.signal
202
- }).then(r => {
203
- if (!r.ok || !_isHtml(r)) {
204
- if (!pre) {location.href = hin;}
205
- return;
152
+ class Hints {
153
+ constructor(h) {
154
+ let _ = this;
155
+ _.list = typeof h === "string" && h.length > 0 ? h.split(", ") : false; //hints are passed as a comma separated string
156
+ _.find = (t) => (!t || !_.list ? false : _.list.some((h) => t.iO(h))); //iterate through hints within passed text (t)
206
157
  }
207
- rsp = r; // store response
208
- return r.text();
209
- }).then(r => {
210
- _cl(1); // clear only plus variable
211
- if (!r) return; // ensure data
212
- rsp.responseText = r; // store response text
213
-
214
- return _cache(hin, r);
215
- }).catch(err => {
216
- if(err.name === "AbortError") return;
217
- try {
218
- Ay.trigger("error", err);
219
- lg("Response text : " + err.message);
220
- return _cache(hin, err.message, err);
221
- } catch (e) {}
222
- }).finally(() => rc--); // reset active request counter
223
- },
224
- _cl = c => (plus = 0, (!c) ? cb = 0 : 0), // clear plus AND/OR callback
225
- _cache = (href, h, err) => Ay.cache.s(Ay.parse(_parseHTML(h))) && (Ay.pages.p([href, Ay.cache.g()]), 1) && cb && cb(err),
226
- _isHtml = x => (ct = x.headers.get("content-type")) && (ct.iO("html") || ct.iO("form-")),
227
- _parseHTML = h => dcE("html").innerHTML = _replD(h).trim(),
228
- _replD = h => String(h).replace(docType, "").replace(tagso, div12).replace(tagsod, divid12).replace(tagsc, "</div>")
229
- }}
230
-
231
- // The stateful Scripts plugin
232
- // First parameter "o" is switch:
233
- // i - initailise options
234
- // c - fetch canonical URL
235
- // <object> - handle one inline script
236
- // otherwise - delta loading
237
- class Scripts { constructor() {
238
- let S = false, txt = 0;
239
- Ay.h.inlinehints = new Hints(Ay.s.inlinehints);
240
- Ay.h.inlineskip = new Hints(Ay.s.inlineskip);
241
-
242
- this.a = function (o) {
243
- if (o === "i") {
244
- if(!S) S = {};
245
- return true;
246
158
  }
247
159
 
248
- if (o === "s") return _allstyle(S.y);
249
-
250
- if (o === "1") {
251
- Ay.detScripts.d(S);
252
- return _addScripts(S);
160
+ function lg(m) {
161
+ Ay.s.verbosity && console && console.log(m);
253
162
  }
254
163
 
255
- if (o === "c") return Ay.s.canonical && S.can ? S.can.getAttribute("href") : false;
256
- if (o === "d") return Ay.detScripts.d(S);
257
- if (o && typeof o == "object") return _onetxt(o);
258
-
259
- if (Ay.scripts("d")) return;
260
- _addScripts(S);
261
- };
262
- let _allstyle = S =>
263
- !Ay.s.style || !S || (
264
- qa("style", qs("head")).forEach(e => prC(e)), //delete old style tags
265
- S.forEach(el => {
266
- let st = Ay.parse('<style>' + el.textContent + '</style>');
267
- _copyAttributes(st, el);
268
- qha(st); //append to the head
269
- })
270
- ),
271
- _onetxt = S =>
272
- (!(txt = S.textContent).iO(").ajaxify(") && (!txt.iO("new Ajaxify(")) &&
273
- ((Ay.s.inline && !Ay.h.inlineskip.find(txt)) || S.classList.contains("ajaxy") ||
274
- Ay.h.inlinehints.find(txt))
275
- ) && _addtxt(S),
276
- _addtxt = S => {
277
- if(!txt || !txt.length) return;
278
- if(Ay.s.inlineappend || (S.getAttribute("type") && !S.getAttribute("type").iO("text/javascript"))) try { return _apptxt(S); } catch (e) { }
279
-
280
- try { eval(txt); } catch (e1) {
281
- lg("Error in inline script : " + txt + "\nError code : " + e1);
282
- }
283
- },
284
- _apptxt = S => { let sc = dcE("script"); _copyAttributes(sc, S); sc.classList.add(inlineclass);
285
- try {sc.appendChild(document.createTextNode(S.textContent))} catch(e) {sc.text = S.textContent};
286
- return qs("body").appendChild(sc);
287
- },
288
- _addScripts = S => (Ay.addAll.a(S.c, "href"), Ay.addAll.a(S.j, "src"))
289
- }}
290
-
291
- // The Rq plugin - stands for request
292
- // Stores all kinds of and manages data concerning the pending request
293
- // Simplifies the Pronto plugin by managing request data separately, instead of passing it around...
294
- // Second parameter (p) : data
295
- // First parameter (o) values:
296
- // = - check whether internally stored "href" ("h") variable is the same as the global currentURL
297
- // ! - update last request ("l") variable with passed href
298
- // ? - Edin's intelligent plausibility check - can spawn an external fetch abort
299
- // v - validate value passed in "p", which is expected to be a click event value - also performs "i" afterwards
300
- // i - initialise request defaults and return "c" (currentTarget)
301
- // h - access internal href hard
302
- // e - set / get internal "e" (event)
303
- // p - set / get internal "p" (push flag)
304
- // is - set / get internal "ispost" (flag whether request is a POST)
305
- // d - set / get internal "d" (data for central fetch())
306
- // C - set / get internal "can" ("href" of canonical URL)
307
- // c - check whether simple canonical URL is given and return, otherwise return value passed in "p"
308
- class RQ { constructor() {
309
- let ispost = 0, data = 0, push = 0, can = 0, e = 0, c = 0, h = 0, l = false;
310
-
311
- this.a = function (o, p, t) {
312
- if(o === "=") {
313
- if(p) return h === Ay.currentURL //check whether internally stored "href" ("h") variable is the same as the global currentURL
314
- || h === l; //or href of last request ("l")
315
- return h === Ay.currentURL; //for click requests
316
- }
317
-
318
- if(o === "!") return l = h; //store href in "l" (last request)
319
-
320
- if(o === "?") { //Edin previously called this "isOK" - powerful intelligent plausibility check
321
- let xs=Ay.fn("s");
322
- if (!xs.iO("0") && !p) Ay.fn("a"); //if fetch is not idle and new request is standard one, do ac.abort() to set it free
323
- if (xs==="1c" && p) return false; //if fetch is processing standard request and new request is prefetch, cancel prefetch until fetch is finished
324
- if (xs==="1p" && p) Ay.s.memoryoff ? Ay.fn("a") : 1; //if fetch is processing prefetch request and new request is prefetch do nothing (see [options] comment below)
325
- //([semaphore options for requests] Ay.fn("a") -> abort previous, proceed with new | return false -> leave previous, stop new | return true -> proceed)
326
- return true;
327
- }
328
-
329
- if(o === "v") { //validate value passed in "p", which is expected to be a click event value - also performs "i" afterwards
330
- if(!p) return false; //ensure data
331
- _setE(p, t); //Set event and href in one go
332
- if(!Ay.internal(h)) return false; //if not internal -> report failure
333
- o = "i"; //continue with "i"
334
- }
335
-
336
- if(o === "i") { //initialise request defaults and return "c" (currentTarget)
337
- ispost = false; //GET assumed
338
- data = null; //reset data
339
- push = true; //assume we want to push URL to the History API
340
- can = false; //reset can (canonical URL)
341
- return h; //return "h" (href)
342
- }
343
-
344
- if(o === "h") { // Access href hard
345
- if(p) {
346
- if (typeof p === "string") e = 0; // Reset e -> default handler
347
- h = (p.href) ? p.href : p; // Poke in href hard
164
+ // The GetPage class
165
+ // First parameter (o) is a switch:
166
+ // empty - returns cache
167
+ // <URL> - loads HTML via Ajax, second parameter "p" must be callback
168
+ // + - pre-fetches page, second parameter "p" must be URL, third parameter "p2" must be callback
169
+ // - - loads page into DOM and handle scripts, second parameter "p" must hold selection to load
170
+ // x - returns response
171
+ // otherwise - returns selection of current page to client
172
+
173
+ class GetPage {
174
+ constructor() {
175
+ let rsp = 0,
176
+ cb = 0,
177
+ plus = 0,
178
+ rt = "",
179
+ ct = 0,
180
+ rc = 0,
181
+ ac = 0,
182
+ //Regexes for escaping fetched HTML of a whole page - best of Baluptons Ajaxify
183
+ //for html, head and body tag
184
+ //Makes it possible to pre-fetch an entire page
185
+ docType = /<\!DOCTYPE[^>]*>/i,
186
+ tagso = /<(html|head)([\s\>])/gi,
187
+ tagsod = /<(body)([\s\>])/gi,
188
+ tagsc = /<\/(html|head|body)\>/gi,
189
+ //Helper strings
190
+ div12 = '<div class="ajy-$1"$2',
191
+ divid12 = '<div id="ajy-$1"$2';
192
+
193
+ this.a = function (o, p, p2) {
194
+ if (!o) return Ay.cache.g();
195
+
196
+ if (o.iO("/")) {
197
+ cb = p;
198
+ if (plus == o) return;
199
+ return _lPage(o);
200
+ }
201
+
202
+ if (o === "+") {
203
+ plus = p;
204
+ cb = p2;
205
+ return _lPage(p, true);
206
+ }
207
+
208
+ if (o === "a") {
209
+ if (rc > 0) {
210
+ _cl();
211
+ ac.abort();
212
+ }
213
+ return;
214
+ }
215
+ if (o === "s") return (rc ? 1 : 0) + rt;
216
+ if (o === "-") return _lSel(p);
217
+ if (o === "x") return rsp;
218
+
219
+ if (!Ay.cache.g()) return;
220
+ if (o === "body") return qs("#ajy-" + o, Ay.cache.g());
221
+ if (o === "script") return qa(o, Ay.cache.g());
222
+
223
+ return qs(o === "title" ? o : ".ajy-" + o, Ay.cache.g());
224
+ };
225
+ let _lSel = (t) => (Ay.pass++, _lEls(t), qa("body > script").forEach((e) => (e.classList.contains(inlineclass) ? prC(e) : false)), Ay.scripts.t(), Ay.scripts.s(), Ay.scripts.c()),
226
+ _lPage = (h, pre) => {
227
+ if (h.iO("#")) h = h.split("#")[0];
228
+ if (Ay.Rq("is") || !Ay.cache.l(h)) return _lAjax(h, pre);
229
+
230
+ plus = 0;
231
+ if (cb) return cb();
232
+ },
233
+ _ld = (t, h) => {
234
+ if (!h) return; //no input
235
+
236
+ var c = h.cloneNode(true); // clone element node (true = deep clone)
237
+ qa("script", c).forEach((e) => prC(e));
238
+ _copyAttributes(t, c, true);
239
+ t.innerHTML = c.innerHTML;
240
+ },
241
+ _lEls = (t) =>
242
+ Ay.cache.g() &&
243
+ !_isBody(t) &&
244
+ t.forEach(function (e) {
245
+ _ld(e, qs("#" + e.getAttribute("id"), Ay.cache.g()));
246
+ }),
247
+ _isBody = (t) => t[0].tagName.toLowerCase() == "body" && (_ld(bdy, qs("#ajy-body", Ay.cache.g())), 1),
248
+ _lAjax = (hin, pre) => {
249
+ var ispost = Ay.Rq("is");
250
+ if (pre) rt = "p";
251
+ else rt = "c";
252
+
253
+ ac = new AbortController(); // set abort controller
254
+ rc++; // set active request counter
255
+ fetch(hin, {
256
+ method: ispost ? "POST" : "GET",
257
+ cache: "default",
258
+ mode: "same-origin",
259
+ headers: { "X-Requested-With": "XMLHttpRequest" },
260
+ body: ispost ? Ay.Rq("d") : null,
261
+ signal: ac.signal,
262
+ })
263
+ .then((r) => {
264
+ if (!r.ok || !_isHtml(r)) {
265
+ if (!pre) {
266
+ location.href = hin;
267
+ }
268
+ return;
269
+ }
270
+ rsp = r; // store response
271
+ return r.text();
272
+ })
273
+ .then((r) => {
274
+ _cl(1); // clear only plus variable
275
+ if (!r) return; // ensure data
276
+ rsp.responseText = r; // store response text
277
+
278
+ return _cache(hin, r);
279
+ })
280
+ .catch((err) => {
281
+ if (err.name === "AbortError") return;
282
+ try {
283
+ Ay.trigger("error", err);
284
+ lg("Response text : " + err.message);
285
+ return _cache(hin, err.message, err);
286
+ } catch (e) { }
287
+ })
288
+ .finally(() => rc--); // reset active request counter
289
+ },
290
+ _cl = (c) => ((plus = 0), !c ? (cb = 0) : 0), // clear plus AND/OR callback
291
+ _cache = (href, h, err) => Ay.cache.s(Ay.parse(_parseHTML(h))) && (Ay.pages.p([href, Ay.cache.g()]), 1) && cb && cb(err),
292
+ _isHtml = (x) => (ct = x.headers.get("content-type")) && (ct.iO("html") || ct.iO("form-")),
293
+ _parseHTML = (h) => (dcE("html").innerHTML = _replD(h).trim()),
294
+ _replD = (h) => String(h).replace(docType, "").replace(tagso, div12).replace(tagsod, divid12).replace(tagsc, "</div>");
348
295
  }
349
-
350
- return h; //href
351
- }
352
-
353
- if(o === "e") { //set / get internal "e" (event)
354
- if(p) _setE(p, t); //Set event and href in one go
355
- return e ? e : h; // Return "e" or if not given "h"
356
- }
357
-
358
- if(o === "p") { //set / get internal "p" (push flag)
359
- if(p !== undefined) push = p;
360
- return push;
361
296
  }
362
297
 
363
- if(o === "is") { //set / get internal "ispost" (flag whether request is a POST)
364
- if(p !== undefined) ispost = p;
365
- return ispost;
366
- }
367
-
368
- if(o === "d") { //set / get internal "d" (data for central fetch())
369
- if(p) data = p;
370
- return data;
371
- }
372
-
373
- if(o === "C") { //set internal "can" ("href" of canonical URL)
374
- if(p !== undefined) can = p;
375
- return can;
376
- }
377
-
378
- if(o === "c") return can && can !== p && !p.iO("#") && !p.iO("?") ? can : p; //get internal "can" ("href" of canonical URL)
379
- };
380
- let _setE = (p, t) => h = typeof (e = p) !== "string" ? (e.currentTarget && e.currentTarget.href) || (t && t.href) || e.currentTarget.action || e.originalEvent.state.url : e
381
- }}
382
-
383
- // The Frms plugin - stands for forms
384
- // Ajaxify all forms in the specified divs
385
- // Switch (o) values:
386
- // d - set divs variable
387
- // a - Ajaxify all forms in divs
388
- class Frms { constructor() {
389
- let fm = 0, divs = 0;
390
-
391
- this.a = function (o, p) {
392
- if (!Ay.s.forms || !o) return; //ensure data
393
-
394
- if(o === "d") divs = p; //set divs variable
395
- if(o === "a") divs.forEach(div => { //iterate through divs
396
- Array.prototype.filter.call(qa(Ay.s.forms, div), function(e) { //filter forms
397
- let c = e.getAttribute("action");
398
- return(Ay.internal(c && c.length > 0 ? c : Ay.currentURL)); //ensure "action"
399
- }).forEach(frm => { //iterate through forms
400
- frm.addEventListener("submit", q => { //create event listener
401
- fm = q.target; // fetch target
402
-
403
- p = _k(); //Serialise data
404
- var g = "get", //assume GET
405
- m = fm.getAttribute("method"); //fetch method attribute
406
- if (m.length > 0 && m.toLowerCase() == "post") g = "post"; //Override with "post"
407
-
408
- var h, a = fm.getAttribute("action"); //fetch action attribute
409
- if (a && a.length > 0) h = a; //found -> store
410
- else h = Ay.currentURL; //not found -> select current URL
411
-
412
- Ay.Rq("v", q); //validate request
413
-
414
- if (g == "get") h = _b(h, p); //GET -> copy URL parameters
415
- else {
416
- Ay.Rq("is", true); //set is POST in request data
417
- Ay.Rq("d", p); //save data in request data
298
+ // The Rq plugin - stands for request
299
+ // Stores all kinds of and manages data concerning the pending request
300
+ // Simplifies the Pronto plugin by managing request data separately, instead of passing it around...
301
+ // Second parameter (p) : data
302
+ // First parameter (o) values:
303
+ // = - check whether internally stored "href" ("h") variable is the same as the global currentURL
304
+ // ! - update last request ("l") variable with passed href
305
+ // ? - Edin's intelligent plausibility check - can spawn an external fetch abort
306
+ // v - validate value passed in "p", which is expected to be a click event value - also performs "i" afterwards
307
+ // i - initialise request defaults and return "c" (currentTarget)
308
+ // h - access internal href hard
309
+ // e - set / get internal "e" (event)
310
+ // p - set / get internal "p" (push flag)
311
+ // is - set / get internal "ispost" (flag whether request is a POST)
312
+ // d - set / get internal "d" (data for central fetch())
313
+ // C - set / get internal "can" ("href" of canonical URL)
314
+ // c - check whether simple canonical URL is given and return, otherwise return value passed in "p"
315
+ class RQ {
316
+ constructor() {
317
+ let ispost = 0,
318
+ data = 0,
319
+ push = 0,
320
+ can = 0,
321
+ e = 0,
322
+ c = 0,
323
+ h = 0,
324
+ l = false;
325
+
326
+ this.a = function (o, p, t) {
327
+ if (o === "=") {
328
+ if (p)
329
+ return (
330
+ h === Ay.currentURL || //check whether internally stored "href" ("h") variable is the same as the global currentURL
331
+ h === l
332
+ ); //or href of last request ("l")
333
+ return h === Ay.currentURL; //for click requests
334
+ }
335
+
336
+ if (o === "!") return (l = h); //store href in "l" (last request)
337
+
338
+ if (o === "?") {
339
+ //Edin previously called this "isOK" - powerful intelligent plausibility check
340
+ let xs = Ay.fn("s");
341
+ if (!xs.iO("0") && !p) Ay.fn("a"); //if fetch is not idle and new request is standard one, do ac.abort() to set it free
342
+ if (xs === "1c" && p) return false; //if fetch is processing standard request and new request is prefetch, cancel prefetch until fetch is finished
343
+ if (xs === "1p" && p) Ay.s.memoryoff ? Ay.fn("a") : 1; //if fetch is processing prefetch request and new request is prefetch do nothing (see [options] comment below)
344
+ //([semaphore options for requests] Ay.fn("a") -> abort previous, proceed with new | return false -> leave previous, stop new | return true -> proceed)
345
+ return true;
346
+ }
347
+
348
+ if (o === "v") {
349
+ //validate value passed in "p", which is expected to be a click event value - also performs "i" afterwards
350
+ if (!p) return false; //ensure data
351
+ _setE(p, t); //Set event and href in one go
352
+ if (!Ay.internal(h)) return false; //if not internal -> report failure
353
+ o = "i"; //continue with "i"
354
+ }
355
+
356
+ if (o === "i") {
357
+ //initialise request defaults and return "c" (currentTarget)
358
+ ispost = false; //GET assumed
359
+ data = null; //reset data
360
+ push = true; //assume we want to push URL to the History API
361
+ can = false; //reset can (canonical URL)
362
+ return h; //return "h" (href)
363
+ }
364
+
365
+ if (o === "h") {
366
+ // Access href hard
367
+ if (p) {
368
+ if (typeof p === "string") e = 0; // Reset e -> default handler
369
+ h = p.href ? p.href : p; // Poke in href hard
370
+ }
371
+
372
+ return h; //href
373
+ }
374
+
375
+ if (o === "e") {
376
+ //set / get internal "e" (event)
377
+ if (p) _setE(p, t); //Set event and href in one go
378
+ return e ? e : h; // Return "e" or if not given "h"
379
+ }
380
+
381
+ if (o === "p") {
382
+ //set / get internal "p" (push flag)
383
+ if (p !== undefined) push = p;
384
+ return push;
385
+ }
386
+
387
+ if (o === "is") {
388
+ //set / get internal "ispost" (flag whether request is a POST)
389
+ if (p !== undefined) ispost = p;
390
+ return ispost;
391
+ }
392
+
393
+ if (o === "d") {
394
+ //set / get internal "d" (data for central fetch())
395
+ if (p) data = p;
396
+ return data;
397
+ }
398
+
399
+ if (o === "C") {
400
+ //set internal "can" ("href" of canonical URL)
401
+ if (p !== undefined) can = p;
402
+ return can;
403
+ }
404
+
405
+ if (o === "c") return can && can !== p && !p.iO("#") && !p.iO("?") ? can : p; //get internal "can" ("href" of canonical URL)
406
+ };
407
+ let _setE = (p, t) => (h = typeof (e = p) !== "string" ? (e.currentTarget && e.currentTarget.href) || (t && t.href) || e.currentTarget.action || e.originalEvent.state.url : e);
418
408
  }
419
-
420
- Ay.trigger("submit", h); //raise pronto.submit event
421
- Ay.pronto(0, { href: h }); //programmatically change page
422
-
423
- q.preventDefault(); //prevent default form action
424
- return(false); //success -> disable default behaviour
425
- });
426
- });
427
- });
428
- };
429
- let _k = () => {
430
- let o = new FormData(fm), n = qs("input[name][type=submit]", fm);
431
-
432
- if (n) o.append(n.getAttribute("name"), n.value);
433
- return o;
434
- },
435
- _b = (m, n) => {
436
- let s = "";
437
- if (m.iO("?")) m = m.substring(0, m.iO("?"));
438
-
439
- for (var [k, v] of n.entries()) s += `${k}=${encodeURIComponent(v)}&`;
440
- return `${m}?${s.slice(0,-1)}`;
441
- }
442
- }}
443
-
444
- // The Pronto plugin - Pronto variant of Ben Plum's Pronto plugin - low level event handling in general
445
- // Works on a selection, passed to Pronto by the selection, which specifies, which elements to Ajaxify
446
- // Switch (h) values:
447
- // i - initialise Pronto
448
- // <object> - fetch href part and continue with _request()
449
- // <URL> - set "h" variable of Rq hard and continue with _request()
450
- class Pronto { constructor() {
451
- let gsl = 0, requestTimer = 0, pd = 150, ptim = 0;
452
- Ay.h.prefetchoff = new Hints(Ay.s.prefetchoff);
453
-
454
- this.a = function (sl, h) {
455
- if(!h) return; //ensure data
456
-
457
- if(h === "i") { //request to initialise
458
- bdy = document.body;
459
- if(!sl.length) sl = "body";
460
- gsl = qa(sl); //copy selection to global selector
461
- Ay.frms = new Frms().a; //initialise forms sub-plugin
462
- if(Ay.s.idleTime) Ay.slides = new classSlides(Ay).a; //initialise optional slideshow sub-plugin
463
- Ay.scrolly = new Scrolly(); //initialise scroll effects sub-plugin
464
- (Ay.offsets = new Offsets()).f();
465
- Ay.hApi = new HApi();
466
- _init_p(); //initialise Pronto sub-plugin
467
- return sl; //return query selector for chaining
468
409
  }
469
410
 
470
- if(typeof(h) === "object") { //jump to internal page programmatically -> handler for forms sub-plugin
471
- Ay.Rq("h", h);
472
- _request();
473
- return;
411
+ // The Frms plugin - stands for forms
412
+ // Ajaxify all forms in the specified divs
413
+ // Switch (o) values:
414
+ // d - set divs variable
415
+ // a - Ajaxify all forms in divs
416
+ class Frms {
417
+ constructor() {
418
+ let fm = 0,
419
+ divs = 0;
420
+
421
+ this.a = function (o, p) {
422
+ if (!Ay.s.forms || !o) return; //ensure data
423
+
424
+ if (o === "d") divs = p; //set divs variable
425
+ if (o === "a")
426
+ divs.forEach((div) => {
427
+ //iterate through divs
428
+ Array.prototype.filter
429
+ .call(qa(Ay.s.forms, div), function (e) {
430
+ //filter forms
431
+ let c = e.getAttribute("action");
432
+ return Ay.internal(c && c.length > 0 ? c : Ay.currentURL); //ensure "action"
433
+ })
434
+ .forEach((frm) => {
435
+ //iterate through forms
436
+ frm.addEventListener("submit", (q) => {
437
+ //create event listener
438
+ fm = q.target; // fetch target
439
+
440
+ p = _k(); //Serialise data
441
+ var g = "get", //assume GET
442
+ m = fm.getAttribute("method"); //fetch method attribute
443
+ if (m.length > 0 && m.toLowerCase() == "post") g = "post"; //Override with "post"
444
+
445
+ var h,
446
+ a = fm.getAttribute("action"); //fetch action attribute
447
+ if (a && a.length > 0) h = a; //found -> store
448
+ else h = Ay.currentURL; //not found -> select current URL
449
+
450
+ Ay.Rq("v", q); //validate request
451
+
452
+ if (g == "get") h = _b(h, p); //GET -> copy URL parameters
453
+ else {
454
+ Ay.Rq("is", true); //set is POST in request data
455
+ Ay.Rq("d", p); //save data in request data
456
+ }
457
+
458
+ Ay.trigger("submit", h); //raise pronto.submit event
459
+ Ay.pronto(0, { href: h }); //programmatically change page
460
+
461
+ q.preventDefault(); //prevent default form action
462
+ return false; //success -> disable default behaviour
463
+ });
464
+ });
465
+ });
466
+ };
467
+ let _k = () => {
468
+ let o = new FormData(fm),
469
+ n = qs("input[name][type=submit]", fm);
470
+
471
+ if (n) o.append(n.getAttribute("name"), n.value);
472
+ return o;
473
+ },
474
+ _b = (m, n) => {
475
+ let s = "";
476
+ if (m.iO("?")) m = m.substring(0, m.iO("?"));
477
+
478
+ for (var [k, v] of n.entries()) s += `${k}=${encodeURIComponent(v)}&`;
479
+ return `${m}?${s.slice(0, -1)}`;
480
+ };
481
+ }
474
482
  }
475
483
 
476
- if(h.iO("/")) { //jump to internal page programmatically -> default handler
477
- Ay.Rq("h", h);
478
- _request(true);
479
- }
480
- };
481
- let _init_p = () => {
482
- Ay.hApi.r(window.location.href);
483
- window.addEventListener("popstate", _onPop);
484
- if (Ay.s.prefetchoff !== true) {
485
- _on("mouseenter", Ay.s.selector, _preftime); // start prefetch timeout
486
- _on("mouseleave", Ay.s.selector, _prefstop); // stop prefetch timeout
487
- _on("touchstart", Ay.s.selector, _prefetch);
488
- }
489
- _on("click", Ay.s.selector, _click, bdy);
490
- Ay.frms("d", qa("body"));
491
- Ay.frms("a");
492
- Ay.frms("d", gsl);
493
- if(Ay.s.idleTime) Ay.slides("i");
494
- },
495
- _preftime = (t, e) => (_prefstop(), ptim = setTimeout(()=> _prefetch(t, e), pd)), // call prefetch if timeout expires without being cleared by _prefstop
496
- _prefstop = () => clearTimeout(ptim),
497
- _prefetch = (t, e) => {
498
- if(Ay.s.prefetchoff === true) return;
499
- if (!Ay.Rq("?", true)) return;
500
- var href = Ay.Rq("v", e, t);
501
- if (Ay.Rq("=", true) || !href || Ay.h.prefetchoff.find(href)) return;
502
- Ay.fn("+", href, () => false);
503
- },
504
- _stopBubbling = e => (
505
- e.preventDefault(),
506
- e.stopPropagation(),
507
- e.stopImmediatePropagation()
508
- ),
509
- _click = (t, e, notPush) => {
510
- if(!Ay.Rq("?")) return;
511
- var href = Ay.Rq("v", e, t);
512
- if(!href || _exoticKey(t)) return;
513
- if(href.substr(-1) ==="#") return true;
514
- if(_hashChange()) {
515
- Ay.hApi.r(href);
516
- return true;
484
+ // The Pronto plugin - Pronto variant of Ben Plum's Pronto plugin - low level event handling in general
485
+ // Works on a selection, passed to Pronto by the selection, which specifies, which elements to Ajaxify
486
+ // Switch (h) values:
487
+ // i - initialise Pronto
488
+ // <object> - fetch href part and continue with _request()
489
+ // <URL> - set "h" variable of Rq hard and continue with _request()
490
+ class Pronto {
491
+ constructor() {
492
+ let gsl = 0,
493
+ requestTimer = 0,
494
+ pd = 150,
495
+ ptim = 0;
496
+ Ay.h.prefetchoff = new Hints(Ay.s.prefetchoff);
497
+
498
+ this.a = function (sl, h) {
499
+ if (!h) return; //ensure data
500
+
501
+ if (h === "i") {
502
+ //request to initialise
503
+ bdy = document.body;
504
+ if (!sl.length) sl = "body";
505
+ gsl = qa(sl); //copy selection to global selector
506
+ Ay.frms = new Frms().a; //initialise forms sub-plugin
507
+ if (Ay.s.idleTime) Ay.slides = new classSlides(Ay).a; //initialise optional slideshow sub-plugin
508
+ Ay.scrolly = new Scrolly(); //initialise scroll effects sub-plugin
509
+ (Ay.offsets = new Offsets()).f();
510
+ Ay.hApi = new HApi();
511
+ _init_p(); //initialise Pronto sub-plugin
512
+ return sl; //return query selector for chaining
513
+ }
514
+
515
+ if (typeof h === "object") {
516
+ //jump to internal page programmatically -> handler for forms sub-plugin
517
+ Ay.Rq("h", h);
518
+ _request();
519
+ return;
520
+ }
521
+
522
+ if (h.iO("/")) {
523
+ //jump to internal page programmatically -> default handler
524
+ Ay.Rq("h", h);
525
+ _request(true);
526
+ }
527
+ };
528
+ let _init_p = () => {
529
+ Ay.hApi.r(window.location.href);
530
+ window.addEventListener("popstate", _onPop);
531
+ if (Ay.s.prefetchoff !== true) {
532
+ _on("mouseenter", Ay.s.selector, _preftime); // start prefetch timeout
533
+ _on("mouseleave", Ay.s.selector, _prefstop); // stop prefetch timeout
534
+ _on("touchstart", Ay.s.selector, _prefetch);
535
+ }
536
+ _on("click", Ay.s.selector, _click, bdy);
537
+ Ay.frms("d", qa("body"));
538
+ Ay.frms("a");
539
+ Ay.frms("d", gsl);
540
+ if (Ay.s.idleTime) Ay.slides("i");
541
+ },
542
+ _preftime = (t, e) => (_prefstop(), (ptim = setTimeout(() => _prefetch(t, e), pd))), // call prefetch if timeout expires without being cleared by _prefstop
543
+ _prefstop = () => clearTimeout(ptim),
544
+ _prefetch = (t, e) => {
545
+ if (Ay.s.prefetchoff === true) return;
546
+ if (!Ay.Rq("?", true)) return;
547
+ var href = Ay.Rq("v", e, t);
548
+ if (Ay.Rq("=", true) || !href || Ay.h.prefetchoff.find(href)) return;
549
+ Ay.fn("+", href, () => false);
550
+ },
551
+ _stopBubbling = (e) => (e.preventDefault(), e.stopPropagation(), e.stopImmediatePropagation()),
552
+ _click = (t, e, notPush) => {
553
+ if (!Ay.Rq("?")) return;
554
+ var href = Ay.Rq("v", e, t);
555
+ if (!href || _exoticKey(t)) return;
556
+ if (href.substr(-1) === "#") return true;
557
+ if (_hashChange()) {
558
+ Ay.hApi.r(href);
559
+ return true;
560
+ }
561
+
562
+ Ay.scrolly.p();
563
+ _stopBubbling(e);
564
+ if (Ay.Rq("=")) Ay.hApi.r();
565
+ if (Ay.s.refresh || !Ay.Rq("=")) _request(notPush);
566
+ },
567
+ _request = (notPush) => {
568
+ Ay.Rq("!");
569
+ if (notPush) Ay.Rq("p", false);
570
+ Ay.fn(Ay.Rq("h"), (err) => {
571
+ if (err) {
572
+ lg("Error in _request : " + err);
573
+ Ay.trigger("error", err);
574
+ }
575
+ _render();
576
+ });
577
+ },
578
+ _render = () => {
579
+ if (Ay.s.requestDelay) {
580
+ if (requestTimer) clearTimeout(requestTimer);
581
+ requestTimer = setTimeout(_doRender, Ay.s.requestDelay);
582
+ } else _doRender();
583
+ },
584
+ _onPop = (e) => {
585
+ var url = window.location.href;
586
+
587
+ Ay.Rq("i");
588
+ Ay.Rq("h", url);
589
+ Ay.Rq("p", false);
590
+ Ay.scrolly.p();
591
+
592
+ if (!url || url === Ay.currentURL) return;
593
+ Ay.fn(url, _render);
594
+ },
595
+ _doRender = () => {
596
+ if (Ay.s.bodyClasses) _copyAttributes(bdy, Ay.fn("body"), true);
597
+
598
+ var href = Ay.Rq("h"),
599
+ title;
600
+ href = Ay.Rq("c", href);
601
+
602
+ if (Ay.Rq("p")) Ay.hApi.p(href);
603
+ else Ay.hApi.r(href);
604
+ if ((title = Ay.fn("title"))) qs("title").innerHTML = title.innerHTML;
605
+ Ay.Rq("C", Ay.fn("-", gsl));
606
+ Ay.frms("a");
607
+
608
+ Ay.scrolly.l();
609
+ _gaCaptureView(href);
610
+ Ay.triggerEvent("DOMContentLoaded");
611
+ if (Ay.s.passCount) qs("#" + Ay.s.passCount).innerHTML = "Pass: " + Ay.pass;
612
+ if (Ay.s.cb) Ay.s.cb();
613
+ },
614
+ _gaCaptureView = (href) => {
615
+ href = "/" + href.replace(rootUrl, "");
616
+ if (typeof window.ga !== "undefined") window.ga("send", "pageview", href);
617
+ else if (typeof window._gaq !== "undefined") window._gaq.push(["_trackPageview", href]);
618
+ },
619
+ _exoticKey = (t) => {
620
+ var href = Ay.Rq("h"),
621
+ e = Ay.Rq("e"),
622
+ tgt = e.currentTarget.target || t.target;
623
+ return e.which > 1 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || tgt === "_blank" || href.iO("wp-login") || href.iO("wp-admin");
624
+ },
625
+ _hashChange = () => {
626
+ var e = Ay.Rq("e");
627
+ return (e.hash && e.href.replace(e.hash, "") === window.location.href.replace(location.hash, "")) || e.href === window.location.href + "#";
628
+ };
629
+ }
517
630
  }
518
631
 
519
- Ay.scrolly.p();
520
- _stopBubbling(e);
521
- if(Ay.Rq("=")) Ay.hApi.r();
522
- if(Ay.s.refresh || !Ay.Rq("=")) _request(notPush);
523
- },
524
- _request = notPush => {
525
- Ay.Rq("!");
526
- if(notPush) Ay.Rq("p", false);
527
- Ay.trigger("request");
528
- Ay.fn(Ay.Rq("h"), err => {
529
- if (err) {
530
- lg("Error in _request : " + err);
531
- Ay.trigger("error", err);
632
+ Ay.init = () => {
633
+ let o = options;
634
+ if (!o || typeof o !== "string") {
635
+ if (document.readyState === "complete" || (document.readyState !== "loading" && !document.documentElement.doScroll)) run();
636
+ else document.addEventListener("DOMContentLoaded", run);
637
+ return Ay;
638
+ } else return Ay.pronto(0, o);
639
+ };
640
+
641
+ let run = () => {
642
+ Ay.s = Object.assign(Ay.s, options);
643
+ (Ay.pages = new Pages()).f();
644
+ Ay.pronto = new Pronto().a;
645
+ if (load()) {
646
+ Ay.pronto(Ay.s.elements, "i");
647
+ if (Ay.s.deltas) Ay.scripts.o();
532
648
  }
649
+ },
650
+ load = () => {
651
+ if (!(window.history && window.history.pushState && window.history.replaceState) || !Ay.s.pluginon) {
652
+ lg("Gracefully exiting...");
653
+ return false;
654
+ }
533
655
 
534
- _render();
535
- });
536
- },
537
- _render = () => {
538
- Ay.trigger("beforeload");
539
- if(Ay.s.requestDelay) {
540
- if(requestTimer) clearTimeout(requestTimer);
541
- requestTimer = setTimeout(_doRender, Ay.s.requestDelay);
542
- } else _doRender();
543
- },
544
- _onPop = e => {
545
- var url = window.location.href;
546
-
547
- Ay.Rq("i");
548
- Ay.Rq("h", url);
549
- Ay.Rq("p", false);
550
- Ay.scrolly.p();
551
-
552
- if (!url || url === Ay.currentURL) return;
553
- Ay.trigger("request");
554
- Ay.fn(url, _render);
555
- },
556
- _doRender = () => {
557
- Ay.trigger("load");
558
- if(Ay.s.bodyClasses) _copyAttributes(bdy, Ay.fn("body"), true);
559
-
560
- var href = Ay.Rq("h"), title;
561
- href = Ay.Rq("c", href);
562
-
563
- if(Ay.Rq("p")) Ay.hApi.p(href); else Ay.hApi.r(href);
564
- if(title = Ay.fn("title")) qs("title").innerHTML = title.innerHTML;
565
- Ay.Rq("C", Ay.fn("-", gsl));
566
- Ay.frms("a");
567
-
568
- Ay.scrolly.l();
569
- _gaCaptureView(href);
570
- Ay.trigger("render");
571
- if(Ay.s.passCount) qs("#" + Ay.s.passCount).innerHTML = "Pass: " + Ay.pass;
572
- if(Ay.s.cb) Ay.s.cb();
573
- },
574
- _gaCaptureView = href => {
575
- href = "/" + href.replace(rootUrl,"");
576
- if (typeof window.ga !== "undefined") window.ga("send", "pageview", href);
577
- else if (typeof window._gaq !== "undefined") window._gaq.push(["_trackPageview", href]);
578
- },
579
- _exoticKey = (t) => {
580
- var href = Ay.Rq("h"), e = Ay.Rq("e"), tgt = e.currentTarget.target || t.target;
581
- return (e.which > 1 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || tgt === "_blank"
582
- || href.iO("wp-login") || href.iO("wp-admin"));
583
- },
584
- _hashChange = () => {
585
- var e = Ay.Rq("e");
586
- return (e.hash && e.href.replace(e.hash, "") === window.location.href.replace(location.hash, "") || e.href === window.location.href + "#");
587
- }
588
- }}
589
-
590
-
591
- Ay.init = () => {
592
- let o = options;
593
- if (!o || typeof(o) !== "string") {
594
- if (document.readyState === "complete" ||
595
- (document.readyState !== "loading" && !document.documentElement.doScroll)) run();
596
- else document.addEventListener('DOMContentLoaded', run);
597
- return Ay;
598
- }
599
- else return Ay.pronto(0, o);
600
- };
601
-
602
- let run = () => {
603
- Ay.s = Object.assign(Ay.s, options);
604
- (Ay.pages = new Pages()).f();
605
- Ay.pronto = new Pronto().a;
606
- if (load()) {
607
- Ay.pronto(Ay.s.elements, "i");
608
- if (Ay.s.deltas) Ay.scripts("1");
609
- }
610
- },
611
- load = () => {
612
- if (!(window.history && window.history.pushState && window.history.replaceState) || !Ay.s.pluginon) {
613
- lg("Gracefully exiting...");
614
- return false;
615
- }
616
-
617
- lg("Ajaxify loaded..."); //verbosity option steers, whether this initialisation message is output
618
-
656
+ lg("Ajaxify loaded..."); //verbosity option steers, whether this initialisation message is output
657
+
658
+ Ay.scripts = new Scrpts();
659
+ Ay.h.inlinehints = new Hints(Ay.s.inlinehints);
660
+ Ay.h.inlineskip = new Hints(Ay.s.inlineskip);
661
+ Ay.cache = new Cache();
662
+ Ay.memory = new Memory();
663
+ Ay.h.memoryoff = new Hints(Ay.s.memoryoff);
664
+ Ay.fn = Ay.getPage = new GetPage().a;
665
+ Ay.detScripts = new DetScripts();
666
+ Ay.addAll = new AddAll();
667
+ Ay.h.alwayshints = new Hints(Ay.s.alwayshints);
668
+ Ay.Rq = new RQ().a;
669
+ return true;
670
+ };
619
671
  if (Ay.s.intevents) Ay.intevents(); // intercept events
620
- Ay.scripts = new Scripts().a;
621
- Ay.scripts("i");
622
- Ay.cache = new Cache();
623
- Ay.memory = new Memory(); Ay.h.memoryoff = new Hints(Ay.s.memoryoff);
624
- Ay.fn = Ay.getPage = new GetPage().a;
625
- Ay.detScripts = new DetScripts();
626
- Ay.addAll = new AddAll(); Ay.h.alwayshints = new Hints(Ay.s.alwayshints);
627
- Ay.Rq = new RQ().a;
628
- return true;
629
- };
630
- Ay.init(); // initialize Ajaxify on definition
631
- }}
672
+ Ay.init(); // initialize Ajaxify on definition
673
+ }
674
+ }
632
675
 
633
676
  // The stateful Cache class
634
677
  // this.d = entire current page (as an object)
635
678
  class Cache {
636
- g(){ return this.d } //getter
637
- s(v){ return this.d = v } //setter
638
- l(u){ let v = Ay.memory.l(u); return this.s(v === false ? v : Ay.pages.l(v)) } //lookup URL and load
679
+ g() {
680
+ return this.d;
681
+ } //getter
682
+ s(v) {
683
+ return (this.d = v);
684
+ } //setter
685
+ l(u) {
686
+ let v = Ay.memory.l(u);
687
+ return this.s(v === false ? v : Ay.pages.l(v));
688
+ } //lookup URL and load
639
689
  }
640
690
 
641
691
  // The stateful Memory class
642
692
  // Usage: Ay.memory.l(<URL>) - returns the same URL if not turned off internally
643
693
  class Memory {
644
- l(h){
694
+ l(h) {
645
695
  if (!h || Ay.s.memoryoff === true) return false;
646
696
  if (Ay.s.memoryoff === false) return h;
647
697
  return Ay.h.memoryoff.find(h) ? false : h;
@@ -651,56 +701,82 @@ class Memory {
651
701
  // The stateful Pages class
652
702
  // this.d = Array of pages - [0] = URL // [1] = reference to whole page
653
703
  class Pages {
654
- f(){ this.d = [] } //flush
655
- l(u){ if (this.P(u)) return this.d[this.i][1] } //lookup URL and return page
656
- p(o){ if(this.P(o[0])) this.d[this.i]=o; else this.d.push(o) } //update or push page passed as an object
657
- P(u){ return (this.i = this.d.findIndex(e => e[0] == u)) + 1 } //lookup page index and store in "i"
704
+ f() {
705
+ this.d = [];
706
+ } //flush
707
+ l(u) {
708
+ if (this.P(u)) return this.d[this.i][1];
709
+ } //lookup URL and return page
710
+ p(o) {
711
+ if (this.P(o[0])) this.d[this.i] = o;
712
+ else this.d.push(o);
713
+ } //update or push page passed as an object
714
+ P(u) {
715
+ return (this.i = this.d.findIndex((e) => e[0] == u)) + 1;
716
+ } //lookup page index and store in "i"
658
717
  }
659
718
 
660
719
  // The DetScripts class - stands for "detach scripts"
661
720
  // Works on "s" <object> that is passed in and fills it
662
- class DetScripts {
721
+ class DetScripts {
663
722
  d(s) {
664
- if(!(this.h = Ay.pass ? Ay.fn("head") : qs("head"))) return true; //If pass is 0 -> fetch head from DOM, otherwise from target page
665
- this.lk = qa(Ay.pass ? ".ajy-link" : "link", this.h); //If pass is 0 -> fetch links from DOM, otherwise from target page
723
+ if (!(this.h = Ay.pass ? Ay.fn("head") : qs("head"))) return true; //If pass is 0 -> fetch head from DOM, otherwise from target page
724
+ this.lk = qa("link", this.h); // Fetch links from DOM
666
725
  s.j = Ay.pass ? Ay.fn("script") : qa("script"); //If pass is 0 -> fetch JSs from DOM, otherwise from target page
667
726
  s.c = this.x("stylesheet"); //Extract stylesheets
668
727
  s.y = qa("style", this.h); //Extract style tags
669
728
  s.can = this.x("canonical"); //Extract canonical tag
670
729
  }
671
- x(v){ return Array.prototype.filter.call(this.lk, e => e.getAttribute("rel").iO(v)) } //Extract link tags with given "rel"
730
+ x(v) {
731
+ return Array.prototype.filter.call(this.lk, (e) => e.getAttribute("rel").iO(v));
732
+ } //Extract link tags with given "rel"
672
733
  }
673
734
 
674
735
  // The Offsets class
675
736
  // this.d = Array of pages - [0] = URL // [1] = offset
676
737
  class Offsets {
677
- f(){ this.d = [] } //flush internal offsets array - must be performed by parent
678
- l(h){ if(h.iO("?")) h = h.split("?")[0]; //lookup page offset
738
+ f() {
739
+ this.d = [];
740
+ } //flush internal offsets array - must be performed by parent
741
+ l(h) {
742
+ if (h.iO("?")) h = h.split("?")[0]; //lookup page offset
679
743
  return this.O(h) ? this.d[this.i][1] : 0; //return if found otherwise 0
680
744
  }
681
- p(h){ let us1 = h.iO("?") ? h.split("?")[0] : h, //initialise all helper variables in one go
682
- us = us1.iO("#") ? us1.split("#")[0] : us1,
683
- os = [us, (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop];
684
- if(this.O(us)) this.d[this.i]=os; else this.d.push(os); // update if found, otherwise push
745
+ p(h) {
746
+ let us1 = h.iO("?") ? h.split("?")[0] : h, //initialise all helper variables in one go
747
+ us = us1.iO("#") ? us1.split("#")[0] : us1,
748
+ os = [us, (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop];
749
+ if (this.O(us)) this.d[this.i] = os;
750
+ else this.d.push(os); // update if found, otherwise push
685
751
  }
686
- O(h){ return (this.i = this.d.findIndex(e => e[0] == h)) + 1 } //find URL in internal array - add 1 for convenience
752
+ O(h) {
753
+ return (this.i = this.d.findIndex((e) => e[0] == h)) + 1;
754
+ } //find URL in internal array - add 1 for convenience
687
755
  }
688
756
 
689
757
  // The Scrolly class
690
758
  // operates on Ay.currentURL
691
- class Scrolly { constructor() { if ('scrollRestoration' in history) history.scrollRestoration = 'manual' }
692
- p(){ Ay.s.scrolltop == "s" && Ay.offsets.p(Ay.currentURL) }
693
- l(){ let o = Ay.currentURL;
694
- if(o.iO("#") && (o.iO("#") < o.length - 1)) { //if hash in URL and not standalone hash
759
+ class Scrolly {
760
+ constructor() {
761
+ if ("scrollRestoration" in history) history.scrollRestoration = "manual";
762
+ }
763
+ p() {
764
+ Ay.s.scrolltop == "s" && Ay.offsets.p(Ay.currentURL);
765
+ }
766
+ l() {
767
+ let o = Ay.currentURL;
768
+ if (o.iO("#") && o.iO("#") < o.length - 1) {
769
+ //if hash in URL and not standalone hash
695
770
  let el = qs("#" + o.split("#")[1]); //fetch the element
696
- if(!el) return; //nothing found -> return quickly
771
+ if (!el) return; //nothing found -> return quickly
697
772
  let box = el.getBoundingClientRect();
698
773
  return this.s(box.top + window.pageYOffset - document.documentElement.clientTop); // ...animate to ID
699
774
  }
700
- if(Ay.s.scrolltop == "s") this.s(Ay.offsets.l(o)); //smart scroll -> lookup and restore offset
775
+ if (Ay.s.scrolltop == "s") this.s(Ay.offsets.l(o)); //smart scroll -> lookup and restore offset
701
776
  else Ay.s.scrolltop && this.s(0); //scrolltop true -> scroll to top of page
702
777
  }
703
- s(o){ if(Ay.s.scrollDelay === false) window.scrollTo(0, o); //scroll to offset
778
+ s(o) {
779
+ if (Ay.s.scrollDelay === false) window.scrollTo(0, o); //scroll to offset
704
780
  else setTimeout(() => window.scrollTo(0, o), Ay.s.scrollDelay);
705
781
  }
706
782
  }
@@ -708,34 +784,54 @@ class Scrolly { constructor() { if ('scrollRestoration' in history) history.scro
708
784
  // The HAPi class
709
785
  // operates on Ay.currentURL - manages operations on the History API centrally(replaceState / pushState)
710
786
  class HApi {
711
- r(h){ let c = this.u(h); history.replaceState({ url: c }, "state-" + c, c); } //perform replaceState
712
- p(h){ let c = this.u(h); if (c !== window.location.href) history.pushState({ url: c }, "state-" + c, c); } //perform pushState
713
- u(h){ if(h) Ay.currentURL = h; return Ay.currentURL; } //update currentURL if given and return always
787
+ r(h) {
788
+ let c = this.u(h);
789
+ history.replaceState({ url: c }, "state-" + c, c);
790
+ } //perform replaceState
791
+ p(h) {
792
+ let c = this.u(h);
793
+ if (c !== window.location.href) history.pushState({ url: c }, "state-" + c, c);
794
+ } //perform pushState
795
+ u(h) {
796
+ if (h) Ay.currentURL = h;
797
+ return Ay.currentURL;
798
+ } //update currentURL if given and return always
714
799
  }
715
800
 
716
801
  // The AddAll class
717
- // Works on a new selection of scripts to apply delta-loading to it
718
- class AddAll { constructor() { this.CSS = []; this.JS = []; }
719
- a(sl, pk) { //only public function
720
- if(!sl.length || Ay.s.deltas === "n") return; //ensure input and that delta-loading is enabled
802
+ // Works on a new selection of scripts to apply delta-loading to it
803
+ class AddAll {
804
+ constructor() {
805
+ this.CSS = [];
806
+ this.JS = [];
807
+ this.TCS = [];
808
+ }
809
+ a(sl, pk) {
810
+ //only public function
811
+ this.TCS = [];
812
+ if (!sl.length || Ay.s.deltas === "n") return; //ensure input and that delta-loading is enabled
721
813
 
722
814
  this.PK = pk; //Copy "primary key" into internal variable
723
815
 
724
- if(!Ay.s.deltas) return sl.forEach(e => this.iScript(e)); //process all scripts and return quickly
816
+ if (!Ay.s.deltas) return sl.forEach((e) => this.iScript(e)); //process all scripts and return quickly
725
817
  //deltas presumed to be "true" -> proceed with normal delta-loading
726
818
 
727
819
  this.O = pk == "href" ? this.CSS : this.JS; //Load old stylesheets or JS
728
820
 
729
- sl.forEach(t => { //Iterate through selection
821
+ sl.forEach((t) => {
822
+ //Iterate through selection
730
823
  let url = this.gA(t); //fetch URL
731
- if(!Ay.pass) return url && this.O.push(url); //Fill new array on initial load, nothing more
732
- if(t.getAttribute("data-class") == "always" || Ay.h.alwayshints.find(url)) { //Class always handling
824
+ if (!Ay.pass) return url && this.O.push(url); //Fill new array on initial load, nothing more
825
+ if (t.getAttribute("data-class") == "always" || Ay.h.alwayshints.find(url)) {
826
+ //Class always handling
733
827
  this.removeScript(); //remove from DOM
734
828
  this.iScript(t); //insert back single external script in the head
735
829
  return;
736
830
  }
737
- if(url) { //URL?
738
- if(!this.O.some(e => e == url)) { // Test, whether new
831
+ if (url) {
832
+ //URL?
833
+ if (!this.O.some((e) => e == url)) {
834
+ // Test, whether new
739
835
  this.O.push(url); //If yes: Push to old array
740
836
  this.iScript(t);
741
837
  }
@@ -743,19 +839,111 @@ class AddAll { constructor() { this.CSS = []; this.JS = []; }
743
839
  return;
744
840
  }
745
841
 
746
- if(pk != "href" && !t.classList.contains("no-ajaxy")) Ay.scripts(t); //Inline JS script? -> inject into DOM
842
+ if (pk != "href" && !t.classList.contains("no-ajaxy")) Ay.scripts.i(t); //Inline JS script? -> inject into DOM
747
843
  });
748
- }
749
- gA(e){ return this.u = e.getAttribute(this.PK) }
750
- iScript(S){
844
+ // Wait for all the scripts to be loaded and then trigger loaded
845
+ "src" === pk &&
846
+ Promise.all(this.TCS)
847
+ .then(() => { })
848
+ .catch((l) => { })
849
+ .finally(() => Ay.triggerEvent("load"));
850
+ }
851
+ // Fetch full url of link or script tag
852
+ gA(e) {
853
+ return (this.u = e[this.PK]);
854
+ }
855
+ //Append script to the DOM
856
+ appendScript(S) {
857
+ return new Promise((resolve, reject) => {
858
+ var sc = dcE("script");
859
+ //wait for the load event
860
+ sc.onload = () => resolve();
861
+ sc.onreadystatechange = () => resolve();
862
+ sc.onerror = (event) => reject(event);
863
+ // If the script has defer then it will set it defer otherwise async
864
+ sc.async = S.hasAttribute("defer") ? false : Ay.s.asyncdef;
865
+ _copyAttributes(sc, S);
866
+ qba(sc);
867
+ });
868
+ }
869
+ iScript(S) {
751
870
  this.gA(S);
752
- if(this.PK == "href") return qha(Ay.parse('<link rel="stylesheet" type="text/css" href="*" />'.replace("*", this.u)));
753
- if(!this.u) return Ay.scripts(S);
754
-
755
- var sc = dcE("script");
756
- sc.async = Ay.s.asyncdef;
757
- _copyAttributes(sc, S);
758
- qha(sc);
871
+ if (this.PK == "href") return qha(Ay.parse('<link rel="stylesheet" type="text/css" href="*" />'.replace("*", this.u)));
872
+ if (!this.u) return Ay.scripts.i(S);
873
+ //Push the promises to be resolved
874
+ this.TCS.push(this.appendScript(S));
875
+ }
876
+ removeScript() {
877
+ qa((this.PK == "href" ? 'link[href*="!"]' : 'script[src*="!"]').replace("!", this.u.substring(this.u.lastIndexOf("/") + 1))).forEach((e) => prC(e));
759
878
  }
760
- removeScript(){ qa((this.PK == "href" ? 'link[href*="!"]' : 'script[src*="!"]').replace("!", this.u)).forEach(e => prC(e)) }
761
879
  }
880
+
881
+ // The stateful Scrpts plugin
882
+ class Scrpts {
883
+ constructor() {
884
+ this.S = {};
885
+ }
886
+ s() {
887
+ this.allstyle(this.S.y);
888
+ } //all style tags
889
+ o() {
890
+ this.d();
891
+ this.a();
892
+ } //on initial load
893
+ c() {
894
+ return Ay.s.canonical && this.S.can ? this.S.can.getAttribute("href") : false;
895
+ } //canonical href
896
+ d() {
897
+ return Ay.detScripts.d(this.S);
898
+ } //detach scripts - returning true indicates an error
899
+ i(o) {
900
+ this.one(o);
901
+ } //inline script -> o is scripts object
902
+ t() {
903
+ this.d() || this.a();
904
+ } //former "true" / default method - detach and delta load
905
+ a() {
906
+ this.delta(this.S);
907
+ } //delta loading core
908
+
909
+ allstyle(S) {
910
+ !Ay.s.style ||
911
+ !S ||
912
+ (qa("style", qs("head")).forEach((e) => prC(e)),
913
+ S.forEach((el) => {
914
+ let st = Ay.parse("<style>" + el.textContent + "</style>");
915
+ _copyAttributes(st, el);
916
+ qha(st); //append to the head
917
+ }));
918
+ }
919
+ one(S) {
920
+ !(this.x = S.textContent).iO("new Ajaxify(") && ((Ay.s.inline && !Ay.h.inlineskip.find(this.x)) || S.classList.contains("ajaxy") || Ay.h.inlinehints.find(this.x)) && this.add(S);
921
+ }
922
+ add(S) {
923
+ if (!this.x || !this.x.length) return;
924
+ if (Ay.s.inlineappend || (S.getAttribute("type") && !S.getAttribute("type").iO("text/javascript")))
925
+ try {
926
+ return this.app(S);
927
+ } catch (e) { }
928
+
929
+ try {
930
+ eval(this.x);
931
+ } catch (e1) {
932
+ lg("Error in inline script : " + this.x + "\nError code : " + e1);
933
+ }
934
+ }
935
+ app(S) {
936
+ let sc = dcE("script");
937
+ _copyAttributes(sc, S);
938
+ sc.classList.add(inlineclass);
939
+ try {
940
+ sc.appendChild(document.createTextNode(this.x));
941
+ } catch (e) {
942
+ sc.text = this.x;
943
+ }
944
+ return qs("body").appendChild(sc);
945
+ }
946
+ delta(S) {
947
+ Ay.addAll.a(S.c, "href"), Ay.addAll.a(S.j, "src");
948
+ }
949
+ }