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