xref: /template/ad-hominem/script.js (revision 3d8547bdcd12eaccfabca6d2b62d5cf8440b9432)
1/**
2 *  Page scripts for Ad Hominem Info Template
3 *
4 * @author     Sascha Leib <sascha@leib.be>
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 */
7
8/* everything is contained in the $p namespace: */
9$p = {
10
11	/* called to initialize the entire script */
12	init:	function() {
13
14		$p.linkinfo.init();
15		$p.cookie_banner.init();
16		$p.search.init();
17		$p.togglers.init();
18
19	},
20
21	/* link information */
22	linkinfo: {
23		init: function() {
24
25			/* find all links in the main section */
26			var main = document.getElementsByTagName("main")[0];
27			var al = main.getElementsByTagName("a");
28			Array.prototype.forEach.call(al, function (a) {
29
30				Object.entries($p.linkinfo._restURLs).forEach((c) => {
31					var cls = c[0];
32					if (a.classList.contains(cls)) {
33						a.addEventListener('mouseover', $p.linkinfo._linkHoverCallback);
34					}
35				});
36			});
37		},
38
39		/* list of REST API URLs for different sites. */
40		/* variables are enclosed in %, allowed vars are: */
41		/* - basedir = this site's basedir (e.g. "/"), */
42		/* - id = the data id of the link (internal only) */
43		/* - ln = the link name (e.g. for Wikipedia links) */
44		/* types can be 'internal', 'wikimedia', or 'ahtpl' */
45		/*  for other sites using this template. */
46		_restURLs : {
47			'wikilink1'	: {
48				url: '%basedir%lib/tpl/ad-hominem/rest/pageinfo.php?id=%id%&v=preview',
49				type:'internal'
50			},
51			'iw_wp'		: {
52				url:'https://en.wikipedia.org/api/rest_v1/page/summary/%id%',
53				type:'wikimedia'
54			},
55			'iw_wpfr' 	: {
56				url:'https://fr.wikipedia.org/api/rest_v1/page/summary/%id%',
57				type:'wikimedia'
58			},
59			'iw_wpde' 	: {
60				url:'https://de.wikipedia.org/api/rest_v1/page/summary/%id%',
61				type:'wikimedia'
62			},
63			'iw_wpes' 	: {
64				url:'https://es.wikipedia.org/api/rest_v1/page/summary/%id%',
65				type:'wikimedia'
66			},
67			'iw_wppl' 	: {
68				url:'https://pl.wikipedia.org/api/rest_v1/page/summary/%id%',
69				type:'wikimedia'
70			},
71			'iw_wpja' 	: {
72				url:'https://it.wikipedia.org/api/rest_v1/page/summary/%id%',
73				type:'wikimedia'
74			},
75			'iw_wpru' 	: {
76				url:'https://ru.wikipedia.org/api/rest_v1/page/summary/%id%',
77				type:'wikimedia'
78			},
79			'iw_meta' 	: {
80				url:'https://meta.wikipedia.org/api/rest_v1/page/summary/%id%',
81				type:'wikimedia'
82			},
83			'iw_ah' 	: {
84				url:'https://ad.hominem.info/de/lib/tpl/ad-hominem/rest/pageinfo.php?id=%id%&v=preview',
85				type:'ahtpl',
86				base:'https://ad.hominem.info/de/'
87			},
88			'iw_ahen' 	: {
89				url:'https://ad.hominem.info/en/lib/tpl/ad-hominem/rest/pageinfo.php?id=%id%&v=preview',
90				type:'ahtpl',
91				base:'https://ad.hominem.info/en/'
92			},
93			'iw_dfo' 	: {
94				url:'https://denkfehler.online/lib/tpl/ad-hominem/rest/pageinfo.php?id=%id%&v=preview',
95				type:'ahtpl',
96				base:'https://denkfehler.online/'
97			}
98		},
99
100		/* callback for the onhover event of links: */
101		_linkHoverCallback: function() {
102
103			var a = jQuery(this);
104			var hi = jQuery.data(this, 'has-info');
105			var href = jQuery(this).attr('href');
106			var wid = null;
107			var url = null;
108			var type = '';
109
110			/* only if the info hasn't been set yet: */
111			if (hi == undefined || hi == '') {
112
113				// remember that we are now working on the link:
114				jQuery.data(this, 'has-info', '0');
115
116				// find the URL to query:
117				for (var cls in $p.linkinfo._restURLs) {
118					if (a.hasClass(cls)) {
119						url = $p.linkinfo._restURLs[cls].url;
120						type = $p.linkinfo._restURLs[cls].type;
121						break;
122					}
123				};
124
125				/* get the ID to request: */
126				switch(type) {
127
128					case 'internal': // internal links
129						url = url.replace('%basedir%', (typeof BASEDIR!=='undefined'?BASEDIR:'/'));
130						wid = jQuery(this).data('wiki-id');
131						break;
132					case 'wikimedia': // wikipedia sites
133						wid = href.substring(href.lastIndexOf('/')+1);
134						break;
135					case 'ahtpl': // Other sites with this template
136						wid = href.substring($p.linkinfo._restURLs[cls].base.length).replace('/', ':');
137						break;
138					default: // unknown -> skip
139						return;
140				}
141
142				console.log('href=' + href);
143				console.log('wid=' + wid);
144
145				// URL found?
146				if (url !== null) {
147
148					/* load the page info */
149					jQuery.ajax({
150						url:		url.replace('%id%', encodeURIComponent(wid)),
151						context:	a,
152						dataType:	'json',
153						crossDomain: true,
154						error:		function(xhr, msg, e) {
155										console.error(msg);
156									},
157						success:	function(data, msg, xhr) {
158										// build the new title for the element:
159										jQuery(this).attr('title', data.title + "\n" + data.extract);
160										jQuery.data(this, 'has-info', '1')
161									},
162						complete:	function() {
163										if (jQuery.data(this, 'has-info') == '0') {
164											jQuery.removeData(this, 'has-info');
165										}
166									}
167					});
168				}
169			}
170		}
171	},
172
173	/* anything related to the search */
174	search: {
175
176		/* initializer */
177		init: function() {
178			$p.search.gui.init();
179		},
180
181		/* the search gui */
182		gui: {
183
184			_container: null,
185			_elements: { field: null, clear: null, search: null },
186
187			/* init the gui */
188			init: function() {
189
190				try {
191
192					/* find all the search elements: */
193					var form = document.getElementById('dw__search');
194
195
196					var div = form.getElementsByClassName('search-field')[0];
197					$p.search.gui._container = div;
198
199					var field = div.getElementsByTagName('input')[0];
200					$p.search.gui._elements.field = field;
201					field.addEventListener('focus', $p.search.gui.__elementFocus);
202					field.addEventListener('blur', $p.search.gui.__elementBlur);
203
204					var buttons = div.getElementsByTagName('button');
205					Array.prototype.forEach.call(buttons, function(b) {
206						var type = b.getAttribute('type');
207						if (type == 'reset') {
208							$p.search.gui._elements.clear = b;
209						} else if (type == 'submit') {
210							$p.search.gui._elements.search = b;
211						}
212						b.addEventListener('focus', $p.search.gui.__elementFocus);
213						b.addEventListener('blur', $p.search.gui.__elementBlur);
214					});
215
216				} catch (e) {
217					console.warn("Can’t initialize search form.");
218					console.error(e);
219				}
220			},
221
222			/* call back for fields */
223			__elementFocus: function() {
224				$p.search.gui._container.classList.add("focus");
225			},
226			__elementBlur: function() {
227				$p.search.gui._container.classList.remove("focus");
228
229			}
230		}
231	},
232
233	/* expaning sections, for menus, etc. */
234	togglers: {
235
236		/* initialize togglers */
237		init:	function() {
238
239			const togglers = document.getElementsByClassName("toggle");
240
241			Array.prototype.forEach.call(togglers, function(t) {
242
243				/* add default state  */
244				if (!(t.classList.contains('show') || (t.classList.contains('hide')))) {
245					t.classList.add('auto');
246				}
247
248				/* add a callback to the toggler buttons */
249				var btn = t.getElementsByClassName('tg_button');
250				Array.prototype.forEach.call(btn, function(b) {
251					b.addEventListener('click', $p.togglers._buttonCallback);
252					b.classList.add('active');
253				});
254
255			});
256		},
257
258		/* callback for the toggler button click */
259		_buttonCallback: function() {
260
261			var t = this.parentNode;
262
263			/* current state of the toggler: */
264			var state = 'auto';
265			if (t.classList.contains('show')) state = 'show';
266			if (t.classList.contains('hide')) state = 'hide';
267			if (t.classList.contains('alt')) state = 'alt';
268
269			/* set new state: */
270			var newState = 'alt';
271			if (state == 'show') { newState = 'hide' }
272			else if (state == 'hide') { newState = 'show' }
273			else if (state == 'alt') { newState = 'auto' }
274
275			t.classList.remove(state);
276			t.classList.add(newState);
277
278		}
279	},
280
281	/* Cookies info banner */
282	cookie_banner: {
283
284		/* initialize Cookies info banner */
285		init: function() {
286
287			// find the cookiebanner button:
288			var btn = jQuery('#cookiebanner button');
289
290			if (btn.length >= 1) { // if found only
291
292				// assign callback:
293				jQuery(btn).click($p.cookie_banner._buttonCallback);
294
295				// set focus:
296				jQuery(btn).first().focus();
297			}
298		},
299
300		/* callback for the "OK" button */
301		_buttonCallback: function() {
302
303			const date = new Date();
304			date.setFullYear(date.getFullYear() + 1);
305
306			var path = ( typeof BASEDIR !== 'undefined' ? BASEDIR : '/');
307
308			document.cookie = 'cookielaw=1; path=' + path + '; expires=' + date.toUTCString() + '; SameSite=Lax';
309			jQuery('#cookiebanner').remove();
310		}
311	}
312};
313
314/* load the script when the DOM is ready */
315
316window.addEventListener("DOMContentLoaded", $p.init);
317