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 _restURLs : { 45 'wikilink1' : '%basedir%lib/tpl/ad-hominem/rest/pageinfo.php?id=%id%&v=preview', 46 'iw_wp' : 'https://en.wikipedia.org/api/rest_v1/page/summary/%ln%', 47 'iw_wpfr' : 'https://fr.wikipedia.org/api/rest_v1/page/summary/%ln%', 48 'iw_wpde' : 'https://de.wikipedia.org/api/rest_v1/page/summary/%ln%', 49 'iw_wpes' : 'https://es.wikipedia.org/api/rest_v1/page/summary/%ln%', 50 'iw_wppl' : 'https://pl.wikipedia.org/api/rest_v1/page/summary/%ln%', 51 'iw_wpja' : 'https://it.wikipedia.org/api/rest_v1/page/summary/%ln%', 52 'iw_wpru' : 'https://ru.wikipedia.org/api/rest_v1/page/summary/%ln%', 53 'iw_meta' : 'https://meta.wikipedia.org/api/rest_v1/page/summary/%ln%' 54 }, 55 56 /* callback for the onhover event of links: */ 57 _linkHoverCallback: function() { 58 59 /* TODO: remove jQuery dependency! */ 60 61 var a = jQuery(this); 62 var hi = jQuery.data(this, 'has-info'); 63 var wid = jQuery(this).data('wiki-id'); 64 var url = null; 65 66 /* only if the info hasn't been set yet: */ 67 if ((hi == undefined || hi == '') && wid !== undefined) { 68 69 // remember that we are now working on it: 70 jQuery.data(this, 'has-info', '0'); 71 72 for (var cls in $p.linkinfo._restURLs) { 73 if (a.hasClass(cls)) { 74 url = $p.linkinfo._restURLs[cls]; 75 break; 76 } 77 }; 78 79 if (url !== null) { 80 81 /* modify the URLs: */ 82 var href = jQuery(this).attr('href'); 83 84 var rp = { 85 'basedir': BASEDIR, 86 'id': wid, 87 'ln': href.substring(href.lastIndexOf('/')+1) 88 }; 89 90 for (var p in rp) { 91 url = url.replace('%'+p+'%', rp[p]); 92 } 93 94 /* load the page info */ 95 jQuery.ajax({ 96 url: url, 97 context: a, 98 dataType: 'json', 99 error: function(xhr, msg, e) { 100 console.error(msg); 101 }, 102 success: function(data, msg, xhr) { 103 // build the new title for the element: 104 jQuery(this).attr('title', data.title + "\n" + data.extract); 105 jQuery.data(this, 'has-info', '1') 106 }, 107 complete: function() { 108 if (jQuery.data(this, 'has-info') == '0') { 109 jQuery.removeData(this, 'has-info'); 110 } 111 } 112 }); 113 } 114 } 115 } 116 }, 117 118 /* anything related to the search */ 119 search: { 120 121 /* initializer */ 122 init: function() { 123 $p.search.gui.init(); 124 }, 125 126 /* the search gui */ 127 gui: { 128 129 _container: null, 130 _elements: { field: null, clear: null, search: null }, 131 132 /* init the gui */ 133 init: function() { 134 135 try { 136 137 /* find all the search elements: */ 138 var form = document.getElementById('dw__search'); 139 140 141 var div = form.getElementsByClassName('search-field')[0]; 142 $p.search.gui._container = div; 143 144 var field = div.getElementsByTagName('input')[0]; 145 $p.search.gui._elements.field = field; 146 field.addEventListener('focus', $p.search.gui.__elementFocus); 147 field.addEventListener('blur', $p.search.gui.__elementBlur); 148 149 var buttons = div.getElementsByTagName('button'); 150 Array.prototype.forEach.call(buttons, function(b) { 151 var type = b.getAttribute('type'); 152 if (type == 'reset') { 153 $p.search.gui._elements.clear = b; 154 } else if (type == 'submit') { 155 $p.search.gui._elements.search = b; 156 } 157 b.addEventListener('focus', $p.search.gui.__elementFocus); 158 b.addEventListener('blur', $p.search.gui.__elementBlur); 159 }); 160 161 } catch (e) { 162 console.warn("Can’t initialize search form."); 163 console.error(e); 164 } 165 }, 166 167 /* call back for fields */ 168 __elementFocus: function() { 169 $p.search.gui._container.classList.add("focus"); 170 }, 171 __elementBlur: function() { 172 $p.search.gui._container.classList.remove("focus"); 173 174 } 175 } 176 }, 177 178 /* expaning sections, for menus, etc. */ 179 togglers: { 180 181 /* initialize togglers */ 182 init: function() { 183 184 const togglers = document.getElementsByClassName("toggle"); 185 186 Array.prototype.forEach.call(togglers, function(t) { 187 188 /* add default state */ 189 if (!(t.classList.contains('show') || (t.classList.contains('hide')))) { 190 t.classList.add('auto'); 191 } 192 193 /* add a callback to the toggler buttons */ 194 var btn = t.getElementsByClassName('tg_button'); 195 Array.prototype.forEach.call(btn, function(b) { 196 b.addEventListener('click', $p.togglers._buttonCallback); 197 b.classList.add('active'); 198 }); 199 200 }); 201 }, 202 203 /* callback for the toggler button click */ 204 _buttonCallback: function() { 205 206 var t = this.parentNode; 207 208 /* current state of the toggler: */ 209 var state = 'auto'; 210 if (t.classList.contains('show')) state = 'show'; 211 if (t.classList.contains('hide')) state = 'hide'; 212 if (t.classList.contains('alt')) state = 'alt'; 213 214 /* set new state: */ 215 var newState = 'alt'; 216 if (state == 'show') { newState = 'hide' } 217 else if (state == 'hide') { newState = 'show' } 218 else if (state == 'alt') { newState = 'auto' } 219 220 t.classList.remove(state); 221 t.classList.add(newState); 222 223 } 224 }, 225 226 /* Cookies info banner */ 227 cookie_banner: { 228 229 /* initialize Cookies info banner */ 230 init: function() { 231 232 // find the cookiebanner button: 233 var btn = jQuery('#cookiebanner button'); 234 235 if (btn.length >= 1) { // if found only 236 237 // assign callback: 238 jQuery(btn).click($p.cookie_banner._buttonCallback); 239 240 // set focus: 241 jQuery(btn).first().focus(); 242 } 243 }, 244 245 /* callback for the "OK" button */ 246 _buttonCallback: function() { 247 248 const date = new Date(); 249 date.setFullYear(date.getFullYear() + 1); 250 document.cookie = 'cookielaw=1; path=' + BASEDIR + '; expires=' + date.toUTCString() + '; SameSite=Lax'; 251 jQuery('#cookiebanner').remove(); 252 } 253 } 254}; 255 256/* load the script when the DOM is ready */ 257 258window.addEventListener("DOMContentLoaded", $p.init); 259