xref: /template/ad-hominem/script.js (revision 7b97b4d7884aacd5ea380f2d46afc437d25d4eb4)
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.search.init();
16		$p.togglers.init();
17
18	},
19
20	/* link information */
21	linkinfo: {
22		init:	function() {
23
24			/* find all links in the main section */
25			var main = document.getElementsByTagName("main")[0];
26			var al = main.getElementsByTagName("a");
27			Array.prototype.forEach.call(al, function (a) {
28
29				Object.entries($p.linkinfo._restURLs).forEach((c) => {
30					var cls = c[0];
31					if (a.classList.contains(cls)) {
32						a.addEventListener('mouseover', $p.linkinfo._linkHoverCallback);
33					}
34				});
35			});
36		},
37
38		/* list of REST API URLs for different sites. */
39		/* variables are enclosed in %, allowed vars are: */
40		/* - basedir = this site's basedir (e.g. "/"), */
41		/* - id = the data id of the link (internal only) */
42		/* - ln = the link name (e.g. for Wikipedia links) */
43		_restURLs : {
44				'wikilink1'	: '%basedir%lib/tpl/ad-hominem/rest/pageinfo.php?id=%id%&v=preview',
45				'iw_wp'		: 'https://en.wikipedia.org/api/rest_v1/page/summary/%ln%',
46				'iw_wpfr' 	: 'https://fr.wikipedia.org/api/rest_v1/page/summary/%ln%',
47				'iw_wpde' 	: 'https://de.wikipedia.org/api/rest_v1/page/summary/%ln%',
48				'iw_wpes' 	: 'https://es.wikipedia.org/api/rest_v1/page/summary/%ln%',
49				'iw_wppl' 	: 'https://pl.wikipedia.org/api/rest_v1/page/summary/%ln%',
50				'iw_wpja' 	: 'https://it.wikipedia.org/api/rest_v1/page/summary/%ln%',
51				'iw_wpru' 	: 'https://ru.wikipedia.org/api/rest_v1/page/summary/%ln%',
52				'iw_meta' 	: 'https://meta.wikipedia.org/api/rest_v1/page/summary/%ln%'
53		},
54
55		/* callback for the onhover event of links: */
56		_linkHoverCallback: function() {
57
58			/* TODO: remove jQuery dependency! */
59
60			var a = jQuery(this);
61			var hi = jQuery.data(this, 'has-info');
62			var wid = jQuery(this).data('wiki-id');
63			var url = null;
64
65			/* only if the info hasn't been set yet: */
66			if ((hi == undefined || hi == '') && wid !== undefined) {
67
68				// remember that we are now working on it:
69				jQuery.data(this, 'has-info', '0');
70
71				for (var cls in $p.linkinfo._restURLs) {
72					if (a.hasClass(cls)) {
73						url = $p.linkinfo._restURLs[cls];
74						break;
75					}
76				};
77
78				if (url !== null) {
79
80					/* modify the URLs: */
81					var href = jQuery(this).attr('href');
82
83					var rp = {
84						'basedir': BASEDIR,
85						'id': wid,
86						'ln': href.substring(href.lastIndexOf('/')+1)
87					};
88
89					for (var p in rp) {
90						url = url.replace('%'+p+'%', rp[p]);
91					}
92
93					/* load the page info */
94					jQuery.ajax({
95						url:		url,
96						context:	a,
97						dataType:	'json',
98						error:		function(xhr, msg, e) {
99										console.error(msg);
100									},
101						success:	function(data, msg, xhr) {
102										// build the new title for the element:
103										jQuery(this).attr('title', data.title + "\n" + data.extract);
104										jQuery.data(this, 'has-info', '1')
105									},
106						complete:	function() {
107										if (jQuery.data(this, 'has-info') == '0') {
108											jQuery.removeData(this, 'has-info');
109										}
110									}
111					});
112				}
113			}
114		}
115	},
116
117	/* anything related to the search */
118	search: {
119
120		/* initializer */
121		init: function() {
122			$p.search.gui.init();
123		},
124
125		/* the search gui */
126		gui: {
127
128			_container: null,
129			_elements: { field: null, clear: null, search: null },
130
131			/* init the gui */
132			init: function() {
133
134				try {
135
136					/* find all the search elements: */
137					var form = document.getElementById('dw__search');
138
139
140					var div = form.getElementsByClassName('search-field')[0];
141					$p.search.gui._container = div;
142
143					var field = div.getElementsByTagName('input')[0];
144					$p.search.gui._elements.field = field;
145					field.addEventListener('focus', $p.search.gui.__elementFocus);
146					field.addEventListener('blur', $p.search.gui.__elementBlur);
147
148					var buttons = div.getElementsByTagName('button');
149					Array.prototype.forEach.call(buttons, function(b) {
150						var type = b.getAttribute('type');
151						if (type == 'reset') {
152							$p.search.gui._elements.clear = b;
153						} else if (type == 'submit') {
154							$p.search.gui._elements.search = b;
155						}
156						b.addEventListener('focus', $p.search.gui.__elementFocus);
157						b.addEventListener('blur', $p.search.gui.__elementBlur);
158					});
159
160				} catch (e) {
161					console.warn("Can’t initialize search form.");
162					console.error(e);
163				}
164			},
165
166			/* call back for fields */
167			__elementFocus: function() {
168				$p.search.gui._container.classList.add("focus");
169			},
170			__elementBlur: function() {
171				$p.search.gui._container.classList.remove("focus");
172
173			}
174		}
175	},
176
177	/* expaning sections, for menus, etc. */
178	togglers: {
179
180		/* initialize togglers */
181		init:	function() {
182
183			const togglers = document.getElementsByClassName("toggle");
184
185			Array.prototype.forEach.call(togglers, function(t) {
186
187				/* add default state  */
188				if (!(t.classList.contains('show') || (t.classList.contains('hide')))) {
189					t.classList.add('auto');
190				}
191
192				/* add a callback to the toggler buttons */
193				var btn = t.getElementsByClassName('tg_button');
194				Array.prototype.forEach.call(btn, function(b) {
195					b.addEventListener('click', $p.togglers._buttonCallback);
196					b.classList.add('active');
197				});
198
199			});
200		},
201
202		/* callback for the toggler button click */
203		_buttonCallback: function() {
204
205			var t = this.parentNode;
206
207			/* current state of the toggler: */
208			var state = 'auto';
209			if (t.classList.contains('show')) state = 'show';
210			if (t.classList.contains('hide')) state = 'hide';
211			if (t.classList.contains('alt')) state = 'alt';
212
213			/* set new state: */
214			var newState = 'alt';
215			if (state == 'show') { newState = 'hide' }
216			else if (state == 'hide') { newState = 'show' }
217			else if (state == 'alt') { newState = 'auto' }
218
219			t.classList.remove(state);
220			t.classList.add(newState);
221
222		}
223	}
224};
225
226/* load the script when the DOM is ready */
227
228window.addEventListener("DOMContentLoaded", $p.init);
229