1/** 2 * DokuWiki Mikio Template Javascript 3 * 4 * @link http://dokuwiki.org/template:mikio 5 * @author James Collins <james.collins@outlook.com.au> 6 * @license GPLv2 (http://www.gnu.org/licenses/gpl-2.0.html) 7 */ 8"use strict"; 9 10var mikio = { 11 queueResize: false, 12 mikioCSS: false, 13 14 ready: function() { 15 var self = this; 16 17 this.addToggleClick('mikio-sidebar-toggle', 'mikio-sidebar-collapse'); 18 this.addToggleClick('mikio-navbar-toggle', 'mikio-navbar-collapse'); 19 this.addDropdownClick('mikio-nav-dropdown', 'mikio-dropdown'); 20 21 window.onresize = function() { 22 if(!this.queueResize) { 23 this.queueResize = true; 24 window.setTimeout(function() { 25 this.queueResize = false; 26 Array.from(document.getElementsByClassName('mikio-dropdown')).forEach(function(elem) { 27 if(!elem.classList.contains('closed')) { 28 elem.classList.add('closed'); 29 } 30 }); 31 }, 100); 32 } 33 }; 34 35 // Mikio-Dropdown - Click 36 Array.from(document.getElementsByClassName('mikio-dropdown')).forEach(function(elem) { 37 elem.addEventListener('click', function(event) { 38 event.stopPropagation(); 39 }); 40 }); 41 42 // Mikio-Dropdown - Close when clicked outside dropdown 43 Array.from(document.getElementsByTagName('body')).forEach(function(elem) { 44 elem.addEventListener('click', function(event) { 45 Array.from(document.getElementsByClassName('mikio-dropdown')).forEach(function(elem) { 46 if(!elem.classList.contains('closed')) { 47 elem.classList.add('closed'); 48 } 49 }); 50 }); 51 }); 52 53 // Mikio-Navbar-Toggle - Fix 54 Array.from(document.getElementsByClassName('mikio-navbar-toggle')).forEach(function(elem) { 55 elem.classList.add('closed'); 56 }); 57 58 // Mikio-Dropdown - Fix 59 Array.from(document.getElementsByClassName('mikio-dropdown')).forEach(function(elem) { 60 elem.classList.add('closed'); 61 }); 62 63 // Input File - Cleanup 64 Array.from(document.querySelectorAll('input[type=file]')).forEach(function(elem) { 65 var style = window.getComputedStyle(elem); 66 67 if(style.display != 'none') { 68 var parentElem = elem.parentElement; 69 var fileRect = elem.getBoundingClientRect(); 70 var parentRect = parentElem.getBoundingClientRect(); 71 var spanElem = document.createElement('span'); 72 73 elem.style.opacity = 0; 74 parentElem.style.position = 'relative'; 75 spanElem.innerHTML = 'Choose file...'; 76 spanElem.classList.add('mikio-input-file'); 77 spanElem.style.left = Math.floor(fileRect.left - parentRect.left) + 'px'; 78 spanElem.style.width = Math.floor(fileRect.right - fileRect.left) + 'px'; 79 mikio.insertAfter(spanElem, elem); 80 81 spanElem.addEventListener('click', function(event) { 82 if(event.target.parentElement.tagName.toLowerCase() != 'label') { 83 let sibling = mikio.getPrevSibling(event.target, 'input'); 84 if(typeof sibling !== 'undefined') { 85 sibling.click(); 86 } 87 } 88 }); 89 90 elem.addEventListener('change', function() { 91 if(this.files.length > 0) { 92 let mikioInput = mikio.getNextSibling(this, '.mikio-input-file'); 93 if(typeof mikioInput !== 'undefined') { 94 mikioInput.innerHTML = this.files[0].name; 95 } 96 } 97 }); 98 } 99 }); 100 101 // Input - Span (Placeholder) clear when typing 102 Array.from(document.querySelectorAll('.mikio.dokuwiki .mode_login fieldset label.block input.edit, .mikio.dokuwiki .mode_denied fieldset label.block input.edit')).forEach(function(elem) { 103 elem.addEventListener('keydown', function(event) { 104 console.log(event.key); 105 var sibling = mikio.getPrevSibling(event.target, 'span'); 106 107 setTimeout(function() { 108 if(sibling) { 109 if(event.target.value != '') { 110 sibling.style.display = 'none'; 111 } else { 112 sibling.style.display = 'block'; 113 } 114 } 115 }, 50); 116 }); 117 }); 118 119 // Admin - Exit button 120 Array.from(document.querySelectorAll('a[rel="exit-admin"]')).forEach(function(elem) { 121 elem.addEventListener('click', function(event) { 122 event.preventDefault(); 123 124 var href = window.location.protocol + "//" + window.location.host + "/" + window.location.pathname; 125 126 var params = window.location.search; 127 if(params !== '') { 128 params = params.substr(1).split('&'); 129 if(params.length > 1) { 130 href += '?'; 131 params.forEach(function(p) { 132 if(p.substring(0, 3) == 'id=') { 133 href += p; 134 } 135 }); 136 } 137 } 138 139 window.location = href; 140 }); 141 }); 142 143 // Admin - Back button 144 Array.from(document.querySelectorAll('a[rel="exit-page"]')).forEach(function(elem) { 145 elem.addEventListener('click', function(event) { 146 event.preventDefault(); 147 148 var href = window.location.protocol + "//" + window.location.host + "/" + window.location.pathname; 149 150 var params = window.location.search; 151 if(params != '') { 152 params = params.substr(1).split('&'); 153 if(params.length > 1) { 154 href += '?'; 155 params.forEach(function(p) { 156 if(p.substring(0, 5) != 'page=') { 157 href += p + '&'; 158 } 159 }); 160 } 161 } 162 163 window.location = href; 164 }); 165 }); 166 167 // Admin - Resize large text blocks in tasks 168 Array.from(document.querySelectorAll('.admin_tasks span.prompt')).forEach(function(elem) { 169 if(elem.offsetHeight > 48) { 170 elem.style.fontSize = '80%'; 171 } 172 }); 173 174 // Media Manager - ui-resizable is always auto 175 var mediaChangedObserver = new MutationObserver(function(mutationsList) { 176 for(let mutation of mutationsList) { 177 if (mutation.type === 'childList') { 178 if(mutation.addedNodes) { 179 mutation.addedNodes.forEach(function(node) { 180 if(node.nodeName == 'LI') { 181 182 } 183 }); 184 } 185 } 186 187 if (mutation.type === 'attributes' && mutation.attributeName == 'style' && mutation.target && mutation.target.style.height) { 188 mutation.target.style.height = ''; 189 } 190 } 191 }); 192 193 var target = document.getElementById('mediamanager__page'); 194 if(target) { 195 mediaChangedObserver.observe(target, {attributes: true, childList: true, subtree: true}); 196 } 197 198 // Media Manager - file click 199 Array.from(document.querySelectorAll('#mediamanager__page .filelist')).forEach(function(elem) { 200 elem.addEventListener('click', function(event) { 201 var liElem = event.target.closest('li'); 202 if(liElem && event.target.closest('ul.thumbs')) { 203 var aElem = liElem.querySelector('dd.name a'); 204 if(aElem) aElem.click(); 205 } 206 }); 207 }); 208 209 // Popup Media Manager - clean file info 210 var mediaPopupFileInfoClean = function(elem) { 211 var file = {resolution: '', date: '', time: '', size: ''}; 212 213 var infoElem = elem.querySelector('span.info'); 214 if(infoElem) { 215 var infoText = infoElem.innerText.replace(/(<[^>]*>|[\(\)])/g, ''); 216 var detail = infoText.split(' '); 217 while(detail.length < 4) { 218 detail.unshift(''); 219 } 220 221 infoElem.innerHTML = detail[0] + '<br>' + detail[1] + ' ' + detail[2] + '<br>' + detail[3]; 222 } 223 224 console.log('there'); 225 Array.from(elem.querySelectorAll('img')).forEach(function(elem) { 226 elem.removeAttribute('width'); 227 elem.removeAttribute('height'); 228 }); 229 } 230 231 var mediaPopupObserver = new MutationObserver(function(mutationsList) { 232 for(let mutation of mutationsList) { 233 if (mutation.type === 'childList') { 234 if(mutation.addedNodes) { 235 mutation.addedNodes.forEach(function(node) { 236 if(node.nodeName == 'DIV') { 237 mediaPopupFileInfoClean(node); 238 } 239 }); 240 } 241 } 242 } 243 }); 244 245 var target = document.getElementById('media__content'); 246 if(target) { 247 Array.from(target.querySelectorAll('div.odd, div.even')).forEach(function(elem) { 248 mediaPopupFileInfoClean(elem); 249 }); 250 251 mediaPopupObserver.observe(target, {attributes: false, childList: true}); 252 } 253 254 if(typeof mikioFooterRun === "function") mikioFooterRun(); 255 256 // TESTING 257 258 var mediaChangedObserver = new MutationObserver(function(mutationsList) { 259 for(let mutation of mutationsList) { 260 if (mutation.type === 'attributes' && mutation.attributeName == 'href') { 261 if(self.mikioCSS != false) { 262 var elem = self.mikioCSS; 263 var prev = elem.href; 264 265 setTimeout(function() { 266 var url = new URL(prev); 267 var params = url.searchParams; 268 params.set('seed', new Date().getTime()); 269 url.search = params.toString(); 270 elem.href = url.toString(); 271 }, 500); 272 } 273 } 274 } 275 }); 276 277 var linkElements = document.getElementsByTagName('link'); 278 for(let element of linkElements) { 279 if(element.rel == 'stylesheet' && element.href) { 280 if(element.href.includes('/lib/exe/css.php')) { 281 mediaChangedObserver.observe(element, {attributes: true, childList: true, subtree: true}); 282 } else if(element.href.includes('/lib/tpl/mikio/css.php')) { 283 this.mikioCSS = element; 284 } 285 } 286 } 287 }, 288 289 insertAfter: function(newNode, existingNode) { 290 existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling); 291 }, 292 293 addToggleClick: function(elemToggle, elemCollapse) { 294 this.addEventListenerByClassName(elemToggle, 'click', function(event) { 295 event.preventDefault(); 296 event.stopPropagation(); 297 let nextSibling = mikio.getNextSibling(this, '.' + elemCollapse); 298 299 if(typeof nextSibling !== 'undefined') { 300 mikio.toggleCollapse(this, nextSibling); 301 } 302 }); 303 }, 304 305 addDropdownClick: function(elemToggle, elemCollapse) { 306 this.addEventListenerByClassName(elemToggle, 'click', function(event) { 307 event.preventDefault(); 308 event.stopPropagation(); 309 310 var dropdown = this.querySelector('.' + elemCollapse); 311 if(dropdown) { 312 mikio.toggleDropdown(dropdown); 313 } 314 }); 315 }, 316 317 addEventListenerByClassName: function(className, eventType, callback) { 318 Array.from(document.getElementsByClassName(className)).forEach(function(elem) { 319 elem.addEventListener(eventType, callback); 320 }); 321 }, 322 323 getNextSibling: function(elem, selector) { 324 var sibling = elem.nextElementSibling; 325 326 while (sibling) { 327 if (sibling.matches(selector)) return sibling; 328 sibling = sibling.nextElementSibling; 329 } 330 }, 331 332 getPrevSibling: function(elem, selector) { 333 var sibling = elem.previousElementSibling; 334 335 while (sibling) { 336 if (sibling.matches(selector)) return sibling; 337 sibling = sibling.previousElementSibling; 338 } 339 }, 340 341 toggleCollapse: function(objToggle, objCollapse) { 342 if(objToggle.classList.contains('closed')) { 343 objToggle.classList.remove('closed'); 344 var height = objCollapse.offsetHeight; 345 objCollapse.style.overflow = 'hidden'; 346 objCollapse.style.height = 0; 347 objCollapse.style.paddingTop = 0; 348 objCollapse.style.paddingBottom = 0; 349 objCollapse.style.marginTop = 0; 350 objCollapse.style.marginBottom = 0; 351 objCollapse.offsetHeight; 352 objCollapse.style.boxSizing = 'border-box'; 353 objCollapse.style.transitionProperty = "height, margin, padding"; 354 objCollapse.style.transitionDuration = '500ms'; 355 objCollapse.style.height = height + 'px'; 356 objCollapse.style.removeProperty('padding-top'); 357 objCollapse.style.removeProperty('padding-bottom'); 358 objCollapse.style.removeProperty('margin-top'); 359 objCollapse.style.removeProperty('margin-bottom'); 360 window.setTimeout(function() { 361 objCollapse.style.removeProperty('height'); 362 objCollapse.style.removeProperty('overflow'); 363 objCollapse.style.removeProperty('transition-duration'); 364 objCollapse.style.removeProperty('transition-property'); 365 objCollapse.style.removeProperty('box-sizing'); 366 }, 500); 367 } else { 368 objCollapse.style.transitionProperty = 'height, margin, padding'; 369 objCollapse.style.transitionDuration = '500ms'; 370 objCollapse.style.boxSizing = 'border-box'; 371 objCollapse.style.height = objCollapse.offsetHeight + 'px'; 372 objCollapse.offsetHeight; 373 objCollapse.style.overflow = 'hidden'; 374 objCollapse.style.height = 0; 375 objCollapse.style.paddingTop = 0; 376 objCollapse.style.paddingBottom = 0; 377 objCollapse.style.marginTop = 0; 378 objCollapse.style.marginBottom = 0; 379 window.setTimeout(function() { 380 objToggle.classList.add('closed'); 381 objCollapse.style.removeProperty('height'); 382 objCollapse.style.removeProperty('padding-top'); 383 objCollapse.style.removeProperty('padding-bottom'); 384 objCollapse.style.removeProperty('margin-top'); 385 objCollapse.style.removeProperty('margin-bottom'); 386 objCollapse.style.removeProperty('overflow'); 387 objCollapse.style.removeProperty('transition-duration'); 388 objCollapse.style.removeProperty('transition-property'); 389 objCollapse.style.removeProperty('box-sizing'); 390 }, 500); 391 } 392 }, 393 394 395 toggleDropdown: function(objToggle) { 396 if(objToggle.classList.contains('closed')) { 397 objToggle.classList.remove('closed'); 398 } else { 399 objToggle.classList.add('closed'); 400 } 401 402 Array.from(document.getElementsByClassName('mikio-dropdown')).forEach(function(elem) { 403 if(!elem.classList.contains('closed') && elem != objToggle) { 404 elem.classList.add('closed'); 405 } 406 }); 407 }, 408 409 setHeroSubTitle: function(str) { 410 Array.from(document.getElementsByClassName('mikio-hero-subtitle')).forEach(function(elem) { 411 elem.innerHTML = str; 412 }); 413 }, 414 415 setHeroImage: function(str) { 416 var heroImages = document.getElementsByClassName('mikio-hero-image'); 417 418 if(heroImages.length > 0) { 419 Array.from(document.getElementsByClassName('mikio-hero-image')).forEach(function(elem) { 420 elem.style.backgroundImage = 'url(\'' + str + '\')'; 421 elem.classList.add('mikio-hero-image-resize'); 422 }); 423 } else { 424 Array.from(document.getElementsByClassName('mikio-hero-text')).forEach(function(elem) { 425 elem.insertAdjacentHTML('afterend', '<div class="mikio-hero-image mikio-hero-image-resize" style="background-image:url(\'' + str + '\');"></div>'); 426 }); 427 } 428 }, 429 430 setHeroColor: function(str) { 431 var colors = str.trim().replace(/ +(?= )/g,'').split(/(?!\(.*)\s(?![^(]*?\))/g); 432 if(colors.length > 0 && colors[0] != '') { 433 Array.from(document.getElementsByClassName('mikio-hero')).forEach(function(elem) { 434 elem.style.backgroundColor = colors[0]; 435 }); 436 437 if(colors.length > 1) { 438 Array.from(document.getElementsByClassName('mikio-hero-title')).forEach(function(elem) { 439 elem.style.color = colors[1]; 440 }); 441 } 442 443 if(colors.length > 2) { 444 Array.from(document.getElementsByClassName('mikio-hero-subtitle')).forEach(function(elem) { 445 elem.style.color = colors[2]; 446 }); 447 } 448 449 if(colors.length > 3) { 450 Array.from(document.getElementsByClassName('mikio-hero')).forEach(function(parentElem) { 451 Array.from(parentElem.querySelectorAll('.mikio-breadcrumbs ul li a')).forEach(function(elem) { 452 elem.style.color = colors[3]; 453 }); 454 455 Array.from(parentElem.querySelectorAll('.mikio-breadcrumbs ul li, .mikio-breadcrumbs ul li a')).forEach(function(elem) { 456 elem.style.color = colors[3]; 457 elem.onmouseover = function() { this.style.color = (colors.length > 4 ? colors[4] : 'initial'); }; 458 elem.onmouseout = function() { this.style.color = colors[3]; }; 459 }); 460 }); 461 } 462 } 463 }, 464 465 setTags: function(str) { 466 Array.from(document.getElementsByClassName('mikio-tags')).forEach(function(elem) { 467 elem.innerHTML = str; 468 }); 469 } 470}; 471 472 473if(document.readyState != 'loading') { 474 mikio.ready(); 475} else { 476 document.addEventListener('DOMContentLoaded', function() { mikio.ready() }); 477} 478