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 objToggle.classList.add('open'); 345 var height = objCollapse.offsetHeight; 346 objCollapse.style.overflow = 'hidden'; 347 objCollapse.style.height = 0; 348 objCollapse.style.paddingTop = 0; 349 objCollapse.style.paddingBottom = 0; 350 objCollapse.style.marginTop = 0; 351 objCollapse.style.marginBottom = 0; 352 objCollapse.offsetHeight; 353 objCollapse.style.boxSizing = 'border-box'; 354 objCollapse.style.transitionProperty = "height, margin, padding"; 355 objCollapse.style.transitionDuration = '500ms'; 356 objCollapse.style.height = height + 'px'; 357 objCollapse.style.removeProperty('padding-top'); 358 objCollapse.style.removeProperty('padding-bottom'); 359 objCollapse.style.removeProperty('margin-top'); 360 objCollapse.style.removeProperty('margin-bottom'); 361 window.setTimeout(function() { 362 objCollapse.style.removeProperty('height'); 363 objCollapse.style.removeProperty('overflow'); 364 objCollapse.style.removeProperty('transition-duration'); 365 objCollapse.style.removeProperty('transition-property'); 366 objCollapse.style.removeProperty('box-sizing'); 367 }, 500); 368 } else { 369 objCollapse.style.transitionProperty = 'height, margin, padding'; 370 objCollapse.style.transitionDuration = '500ms'; 371 objCollapse.style.boxSizing = 'border-box'; 372 objCollapse.style.height = objCollapse.offsetHeight + 'px'; 373 objCollapse.offsetHeight; 374 objCollapse.style.overflow = 'hidden'; 375 objCollapse.style.height = 0; 376 objCollapse.style.paddingTop = 0; 377 objCollapse.style.paddingBottom = 0; 378 objCollapse.style.marginTop = 0; 379 objCollapse.style.marginBottom = 0; 380 window.setTimeout(function() { 381 objToggle.classList.add('closed'); 382 objToggle.classList.remove('open'); 383 objCollapse.style.removeProperty('height'); 384 objCollapse.style.removeProperty('padding-top'); 385 objCollapse.style.removeProperty('padding-bottom'); 386 objCollapse.style.removeProperty('margin-top'); 387 objCollapse.style.removeProperty('margin-bottom'); 388 objCollapse.style.removeProperty('overflow'); 389 objCollapse.style.removeProperty('transition-duration'); 390 objCollapse.style.removeProperty('transition-property'); 391 objCollapse.style.removeProperty('box-sizing'); 392 }, 500); 393 } 394 }, 395 396 397 toggleDropdown: function(objToggle) { 398 if(objToggle.classList.contains('closed')) { 399 objToggle.classList.remove('closed'); 400 } else { 401 objToggle.classList.add('closed'); 402 } 403 404 Array.from(document.getElementsByClassName('mikio-dropdown')).forEach(function(elem) { 405 if(!elem.classList.contains('closed') && elem != objToggle) { 406 elem.classList.add('closed'); 407 } 408 }); 409 }, 410 411 setHeroSubTitle: function(str) { 412 Array.from(document.getElementsByClassName('mikio-hero-subtitle')).forEach(function(elem) { 413 elem.innerHTML = str; 414 }); 415 }, 416 417 setHeroImage: function(str) { 418 var heroImages = document.getElementsByClassName('mikio-hero-image'); 419 420 if(heroImages.length > 0) { 421 Array.from(document.getElementsByClassName('mikio-hero-image')).forEach(function(elem) { 422 elem.style.backgroundImage = 'url(\'' + str + '\')'; 423 elem.classList.add('mikio-hero-image-resize'); 424 }); 425 } else { 426 Array.from(document.getElementsByClassName('mikio-hero-text')).forEach(function(elem) { 427 elem.insertAdjacentHTML('afterend', '<div class="mikio-hero-image mikio-hero-image-resize" style="background-image:url(\'' + str + '\');"></div>'); 428 }); 429 } 430 }, 431 432 setHeroColor: function(str) { 433 var colors = str.trim().replace(/ +(?= )/g,'').split(/(?!\(.*)\s(?![^(]*?\))/g); 434 if(colors.length > 0 && colors[0] != '') { 435 Array.from(document.getElementsByClassName('mikio-hero')).forEach(function(elem) { 436 elem.style.backgroundColor = colors[0]; 437 }); 438 439 if(colors.length > 1) { 440 Array.from(document.getElementsByClassName('mikio-hero-title')).forEach(function(elem) { 441 elem.style.color = colors[1]; 442 }); 443 } 444 445 if(colors.length > 2) { 446 Array.from(document.getElementsByClassName('mikio-hero-subtitle')).forEach(function(elem) { 447 elem.style.color = colors[2]; 448 }); 449 } 450 451 if(colors.length > 3) { 452 Array.from(document.getElementsByClassName('mikio-hero')).forEach(function(parentElem) { 453 Array.from(parentElem.querySelectorAll('.mikio-breadcrumbs ul li a')).forEach(function(elem) { 454 elem.style.color = colors[3]; 455 }); 456 457 Array.from(parentElem.querySelectorAll('.mikio-breadcrumbs ul li, .mikio-breadcrumbs ul li a')).forEach(function(elem) { 458 elem.style.color = colors[3]; 459 elem.onmouseover = function() { this.style.color = (colors.length > 4 ? colors[4] : 'initial'); }; 460 elem.onmouseout = function() { this.style.color = colors[3]; }; 461 }); 462 }); 463 } 464 } 465 }, 466 467 setTags: function(str) { 468 Array.from(document.getElementsByClassName('mikio-tags')).forEach(function(elem) { 469 elem.innerHTML = str; 470 }); 471 }, 472 473 hidePart: function (part) { 474 var selectorArray = { 475 topheader: '.mikio-page-topheader', 476 header: '.mikio-page-header', 477 contentheader: '.mikio-page-contentheader', 478 contentfooter: '.mikio-page-contentfooter', 479 sidebarheader: '.mikio-sidebar-left .mikio-sidebar-header', 480 sidebarfooter: '.mikio-sidebar-left .mikio-sidebar-footer', 481 rightsidebarheader: '.mikio-sidebar-right .mikio-sidebar-header', 482 rightsidebarfooter: '.mikio-sidebar-right .mikio-sidebar-footer', 483 footer: '.mikio-footer', 484 bottomfooter: '.mikio-page-bottomfooter', 485 navbar: '.mikio-navbar', 486 hero: '.mikio-hero' 487 }; 488 489 if(selectorArray.hasOwnProperty(part)) { 490 Array.from(document.querySelectorAll(selectorArray[part])).forEach(function (elem) { 491 elem.style.display = 'none'; 492 }); 493 } 494 } 495}; 496 497 498if(document.readyState != 'loading') { 499 mikio.ready(); 500} else { 501 document.addEventListener('DOMContentLoaded', function() { mikio.ready() }); 502} 503