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).replaceAll('/', ':'); 137 break; 138 default: // unknown -> skip 139 return; 140 } 141 142 // URL found? 143 if (url !== null) { 144 145 /* load the page info */ 146 jQuery.ajax({ 147 url: url.replace('%id%', encodeURIComponent(wid)), 148 context: a, 149 dataType: 'json', 150 crossDomain: true, 151 error: function(xhr, msg, e) { 152 console.error(msg); 153 }, 154 success: function(data, msg, xhr) { 155 // build the new title for the element: 156 jQuery(this).attr('title', data.title + "\n" + data.extract); 157 jQuery.data(this, 'has-info', '1') 158 }, 159 complete: function() { 160 if (jQuery.data(this, 'has-info') == '0') { 161 jQuery.removeData(this, 'has-info'); 162 } 163 } 164 }); 165 } 166 } 167 } 168 }, 169 170 /* anything related to the search */ 171 search: { 172 173 /* initializer */ 174 init: function() { 175 $p.search.gui.init(); 176 }, 177 178 /* the search gui */ 179 gui: { 180 181 _container: null, 182 _elements: { field: null, clear: null, search: null }, 183 184 /* init the gui */ 185 init: function() { 186 187 try { 188 189 /* find all the search elements: */ 190 var form = document.getElementById('dw__search'); 191 192 193 var div = form.getElementsByClassName('search-field')[0]; 194 $p.search.gui._container = div; 195 196 var field = div.getElementsByTagName('input')[0]; 197 $p.search.gui._elements.field = field; 198 field.addEventListener('focus', $p.search.gui.__elementFocus); 199 field.addEventListener('blur', $p.search.gui.__elementBlur); 200 201 var buttons = div.getElementsByTagName('button'); 202 Array.prototype.forEach.call(buttons, function(b) { 203 var type = b.getAttribute('type'); 204 if (type == 'reset') { 205 $p.search.gui._elements.clear = b; 206 } else if (type == 'submit') { 207 $p.search.gui._elements.search = b; 208 } 209 b.addEventListener('focus', $p.search.gui.__elementFocus); 210 b.addEventListener('blur', $p.search.gui.__elementBlur); 211 }); 212 213 } catch (e) { 214 console.warn("Can’t initialize search form."); 215 console.error(e); 216 } 217 }, 218 219 /* call back for fields */ 220 __elementFocus: function() { 221 $p.search.gui._container.classList.add("focus"); 222 }, 223 __elementBlur: function() { 224 $p.search.gui._container.classList.remove("focus"); 225 226 } 227 } 228 }, 229 230 /* expaning sections, for menus, etc. */ 231 togglers: { 232 233 /* initialize togglers */ 234 init: function() { 235 236 const togglers = document.getElementsByClassName("toggle"); 237 238 Array.prototype.forEach.call(togglers, function(t) { 239 240 /* add default state */ 241 if (!(t.classList.contains('show') || (t.classList.contains('hide')))) { 242 t.classList.add('auto'); 243 } 244 245 /* add a callback to the toggler buttons */ 246 var btn = t.getElementsByClassName('tg_button'); 247 Array.prototype.forEach.call(btn, function(b) { 248 b.addEventListener('click', $p.togglers._buttonCallback); 249 b.classList.add('active'); 250 }); 251 252 }); 253 }, 254 255 /* callback for the toggler button click */ 256 _buttonCallback: function() { 257 258 var t = this.parentNode; 259 260 /* current state of the toggler: */ 261 var state = 'auto'; 262 if (t.classList.contains('show')) state = 'show'; 263 if (t.classList.contains('hide')) state = 'hide'; 264 if (t.classList.contains('alt')) state = 'alt'; 265 266 /* set new state: */ 267 var newState = 'alt'; 268 if (state == 'show') { newState = 'hide' } 269 else if (state == 'hide') { newState = 'show' } 270 else if (state == 'alt') { newState = 'auto' } 271 272 t.classList.remove(state); 273 t.classList.add(newState); 274 275 } 276 }, 277 278 /* Cookies info banner */ 279 cookie_banner: { 280 281 /* initialize Cookies info banner */ 282 init: function() { 283 284 // find the cookiebanner button: 285 var btn = jQuery('#cookiebanner button'); 286 287 if (btn.length >= 1) { // if found only 288 289 // assign callback: 290 jQuery(btn).click($p.cookie_banner._buttonCallback); 291 292 // set focus: 293 jQuery(btn).first().focus(); 294 } 295 }, 296 297 /* callback for the "OK" button */ 298 _buttonCallback: function() { 299 300 const date = new Date(); 301 date.setFullYear(date.getFullYear() + 1); 302 303 var path = ( typeof BASEDIR !== 'undefined' ? BASEDIR : '/'); 304 305 document.cookie = 'cookielaw=1; path=' + path + '; expires=' + date.toUTCString() + '; SameSite=Lax'; 306 jQuery('#cookiebanner').remove(); 307 } 308 } 309}; 310 311/* load the script when the DOM is ready */ 312 313window.addEventListener("DOMContentLoaded", $p.init); 314