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 var sibling = mikio.getPrevSibling(event.target, 'span'); 105 106 setTimeout(function () { 107 if (sibling) { 108 if (event.target.value != '') { 109 sibling.style.display = 'none'; 110 } else { 111 sibling.style.display = 'block'; 112 } 113 } 114 }, 50); 115 }); 116 }); 117 118 // Admin - Exit button 119 Array.from(document.querySelectorAll('a[rel="exit-admin"]')).forEach(function (elem) { 120 elem.addEventListener('click', function (event) { 121 event.preventDefault(); 122 123 var href = window.location.protocol + "//" + window.location.host + "/" + window.location.pathname; 124 125 var params = window.location.search; 126 if (params !== '') { 127 params = params.substr(1).split('&'); 128 if (params.length > 1) { 129 href += '?'; 130 params.forEach(function (p) { 131 if (p.substring(0, 3) == 'id=') { 132 href += p; 133 } 134 }); 135 } 136 } 137 138 window.location = href; 139 }); 140 }); 141 142 // Admin - Back button 143 Array.from(document.querySelectorAll('a[rel="exit-page"]')).forEach(function (elem) { 144 elem.addEventListener('click', function (event) { 145 event.preventDefault(); 146 147 var href = window.location.protocol + "//" + window.location.host + "/" + window.location.pathname; 148 149 var params = window.location.search; 150 if (params != '') { 151 params = params.substr(1).split('&'); 152 if (params.length > 1) { 153 href += '?'; 154 params.forEach(function (p) { 155 if (p.substring(0, 5) != 'page=') { 156 href += p + '&'; 157 } 158 }); 159 } 160 } 161 162 window.location = href; 163 }); 164 }); 165 166 // Admin - Resize large text blocks in tasks 167 Array.from(document.querySelectorAll('.admin_tasks span.prompt')).forEach(function (elem) { 168 if (elem.offsetHeight > 48) { 169 elem.style.fontSize = '80%'; 170 } 171 }); 172 173 // Media Manager - ui-resizable is always auto 174 var mediaChangedObserver = new MutationObserver(function (mutationsList) { 175 for (let mutation of mutationsList) { 176 if (mutation.type === 'childList') { 177 if (mutation.addedNodes) { 178 mutation.addedNodes.forEach(function (node) { 179 if (node.nodeName == 'LI') { 180 181 } 182 }); 183 } 184 } 185 186 if (mutation.type === 'attributes' && mutation.attributeName == 'style' && mutation.target && mutation.target.style.height) { 187 mutation.target.style.height = ''; 188 } 189 } 190 }); 191 192 var target = document.getElementById('mediamanager__page'); 193 if (target) { 194 mediaChangedObserver.observe(target, { attributes: true, childList: true, subtree: true }); 195 } 196 197 // Media Manager - file click 198 Array.from(document.querySelectorAll('#mediamanager__page .filelist')).forEach(function (elem) { 199 elem.addEventListener('click', function (event) { 200 var liElem = event.target.closest('li'); 201 if (liElem && event.target.closest('ul.thumbs')) { 202 var aElem = liElem.querySelector('dd.name a'); 203 if (aElem) aElem.click(); 204 } 205 }); 206 }); 207 208 // Popup Media Manager - clean file info 209 var mediaPopupFileInfoClean = function (elem) { 210 var file = { resolution: '', date: '', time: '', size: '' }; 211 212 var infoElem = elem.querySelector('span.info'); 213 if (infoElem) { 214 var infoText = infoElem.innerText.replace(/(<[^>]*>|[\(\)])/g, ''); 215 var detail = infoText.split(' '); 216 while (detail.length < 4) { 217 detail.unshift(''); 218 } 219 220 infoElem.innerHTML = detail[0] + '<br>' + detail[1] + ' ' + detail[2] + '<br>' + detail[3]; 221 } 222 223 Array.from(elem.querySelectorAll('img')).forEach(function (elem) { 224 elem.removeAttribute('width'); 225 elem.removeAttribute('height'); 226 }); 227 } 228 229 var mediaPopupObserver = new MutationObserver(function (mutationsList) { 230 for (let mutation of mutationsList) { 231 if (mutation.type === 'childList') { 232 if (mutation.addedNodes) { 233 mutation.addedNodes.forEach(function (node) { 234 if (node.nodeName == 'DIV') { 235 mediaPopupFileInfoClean(node); 236 } 237 }); 238 } 239 } 240 } 241 }); 242 243 var target = document.getElementById('media__content'); 244 if (target) { 245 Array.from(target.querySelectorAll('div.odd, div.even')).forEach(function (elem) { 246 mediaPopupFileInfoClean(elem); 247 }); 248 249 mediaPopupObserver.observe(target, { attributes: false, childList: true }); 250 } 251 252 if (typeof mikioFooterRun === "function") mikioFooterRun(); 253 254 // TESTING 255 256 var mediaChangedObserver = new MutationObserver(function (mutationsList) { 257 for (let mutation of mutationsList) { 258 if (mutation.type === 'attributes' && mutation.attributeName == 'href') { 259 if (self.mikioCSS != false) { 260 var elem = self.mikioCSS; 261 var prev = elem.href; 262 263 setTimeout(function () { 264 var url = new URL(prev); 265 var params = url.searchParams; 266 params.set('seed', new Date().getTime()); 267 url.search = params.toString(); 268 elem.href = url.toString(); 269 }, 500); 270 } 271 } 272 } 273 }); 274 275 var linkElements = document.getElementsByTagName('link'); 276 for (let element of linkElements) { 277 if (element.rel == 'stylesheet' && element.href) { 278 if (element.href.includes('/lib/exe/css.php')) { 279 mediaChangedObserver.observe(element, { attributes: true, childList: true, subtree: true }); 280 } else if (element.href.includes('/lib/tpl/mikio/css.php')) { 281 this.mikioCSS = element; 282 } 283 } 284 } 285 }, 286 287 insertAfter: function (newNode, existingNode) { 288 existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling); 289 }, 290 291 addToggleClick: function (elemToggle, elemCollapse) { 292 this.addEventListenerByClassName(elemToggle, 'click', function (event) { 293 event.preventDefault(); 294 event.stopPropagation(); 295 let nextSibling = mikio.getNextSibling(this, '.' + elemCollapse); 296 297 if (typeof nextSibling !== 'undefined') { 298 mikio.toggleCollapse(this, nextSibling); 299 } 300 }); 301 }, 302 303 addDropdownClick: function (elemToggle, elemCollapse) { 304 this.addEventListenerByClassName(elemToggle, 'click', function (event) { 305 event.preventDefault(); 306 event.stopPropagation(); 307 308 var dropdown = this.querySelector('.' + elemCollapse); 309 if (dropdown) { 310 mikio.toggleDropdown(dropdown); 311 } 312 }); 313 }, 314 315 addEventListenerByClassName: function (className, eventType, callback) { 316 Array.from(document.getElementsByClassName(className)).forEach(function (elem) { 317 elem.addEventListener(eventType, callback); 318 }); 319 }, 320 321 getNextSibling: function (elem, selector) { 322 var sibling = elem.nextElementSibling; 323 324 while (sibling) { 325 if (sibling.matches(selector)) return sibling; 326 sibling = sibling.nextElementSibling; 327 } 328 }, 329 330 getPrevSibling: function (elem, selector) { 331 var sibling = elem.previousElementSibling; 332 333 while (sibling) { 334 if (sibling.matches(selector)) return sibling; 335 sibling = sibling.previousElementSibling; 336 } 337 }, 338 339 toggleCollapse: function (objToggle, objCollapse) { 340 if (objToggle.classList.contains('closed')) { 341 objToggle.classList.remove('closed'); 342 objToggle.classList.add('open'); 343 var height = objCollapse.offsetHeight; 344 objCollapse.style.overflow = 'hidden'; 345 objCollapse.style.height = 0; 346 objCollapse.style.paddingTop = 0; 347 objCollapse.style.paddingBottom = 0; 348 objCollapse.style.marginTop = 0; 349 objCollapse.style.marginBottom = 0; 350 objCollapse.offsetHeight; 351 objCollapse.style.boxSizing = 'border-box'; 352 objCollapse.style.transitionProperty = "height, margin, padding"; 353 objCollapse.style.transitionDuration = '500ms'; 354 objCollapse.style.height = height + 'px'; 355 objCollapse.style.removeProperty('padding-top'); 356 objCollapse.style.removeProperty('padding-bottom'); 357 objCollapse.style.removeProperty('margin-top'); 358 objCollapse.style.removeProperty('margin-bottom'); 359 window.setTimeout(function () { 360 objCollapse.style.removeProperty('height'); 361 objCollapse.style.removeProperty('overflow'); 362 objCollapse.style.removeProperty('transition-duration'); 363 objCollapse.style.removeProperty('transition-property'); 364 objCollapse.style.removeProperty('box-sizing'); 365 }, 500); 366 } else { 367 objCollapse.style.transitionProperty = 'height, margin, padding'; 368 objCollapse.style.transitionDuration = '500ms'; 369 objCollapse.style.boxSizing = 'border-box'; 370 objCollapse.style.height = objCollapse.offsetHeight + 'px'; 371 objCollapse.offsetHeight; 372 objCollapse.style.overflow = 'hidden'; 373 objCollapse.style.height = 0; 374 objCollapse.style.paddingTop = 0; 375 objCollapse.style.paddingBottom = 0; 376 objCollapse.style.marginTop = 0; 377 objCollapse.style.marginBottom = 0; 378 window.setTimeout(function () { 379 objToggle.classList.add('closed'); 380 objToggle.classList.remove('open'); 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 hidePart: function (part) { 472 var selectorArray = { 473 topheader: '.mikio-page-topheader', 474 header: '.mikio-page-header', 475 contentheader: '.mikio-page-contentheader', 476 contentfooter: '.mikio-page-contentfooter', 477 sidebarheader: '.mikio-sidebar-left .mikio-sidebar-header', 478 sidebarfooter: '.mikio-sidebar-left .mikio-sidebar-footer', 479 rightsidebarheader: '.mikio-sidebar-right .mikio-sidebar-header', 480 rightsidebarfooter: '.mikio-sidebar-right .mikio-sidebar-footer', 481 footer: '.mikio-footer', 482 bottomfooter: '.mikio-page-bottomfooter', 483 navbar: '.mikio-navbar', 484 hero: '.mikio-hero' 485 }; 486 487 if (selectorArray.hasOwnProperty(part)) { 488 Array.from(document.querySelectorAll(selectorArray[part])).forEach(function (elem) { 489 elem.style.display = 'none'; 490 }); 491 } 492 } 493}; 494 495 496if (document.readyState != 'loading') { 497 mikio.ready(); 498} else { 499 document.addEventListener('DOMContentLoaded', function () { mikio.ready() }); 500} 501