ajaxify 8.3.0 → 8.3.1

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