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