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 10const mikio = { 11 queueResize: false, 12 mikioCSS: false, 13 stickyItems: [], 14 stickyOffset: 0, 15 stickyIndex: 2010, 16 darkMode: '', 17 18 ready: function () { 19 const updateStickyScroll = function () { 20 self.stickyItems.forEach((item) => { 21 // noinspection JSDeprecatedSymbols 22 if ((window.scrollY || window.pageYOffset) > item.offsetYTop) { 23 if (item.element.style.position !== 'fixed') { 24 let site = document.getElementById('dokuwiki__site'); 25 site.style.paddingTop = ((parseInt(site.style.paddingTop) || 0) + item.element.offsetHeight) + 'px'; 26 27 item.element.style.position = 'fixed'; 28 item.element.style.top = self.stickyOffset + 'px'; 29 item.element.style.zIndex = self.stickyIndex; 30 31 self.stickyOffset += item.element.offsetHeight; 32 self.stickyIndex--; 33 } 34 } else { 35 if (item.element.style.position === 'fixed') { 36 let site = document.getElementById('dokuwiki__site'); 37 site.style.paddingTop = ((parseInt(site.style.paddingTop) || 0) - item.element.offsetHeight) + 'px'; 38 self.stickyOffset -= item.element.offsetHeight; 39 self.stickyIndex++; 40 41 item.element.style.position = 'relative'; 42 item.element.style.top = null; 43 item.element.style.zIndex = null; 44 } 45 } 46 }); 47 }; 48 const self = this; 49 50 this.initDarkMode(); 51 this.addToggleClick('mikio-sidebar-toggle', 'mikio-sidebar-collapse'); 52 this.addToggleClick('mikio-navbar-toggle', 'mikio-navbar-collapse'); 53 this.addDropdownClick('mikio-nav-dropdown', 'mikio-dropdown'); 54 this.indexmenuPatch(); 55 this.typeahead(); 56 57 this.doPluginPatch(); 58 59 const updateStickyItems = function () { 60 window.removeEventListener('scroll', updateStickyScroll); 61 62 const stickyElements = document.getElementsByClassName('mikio-sticky'); 63 self.stickyItems = []; 64 if (stickyElements && stickyElements.length > 0) { 65 const stickyOffset = stickyElements[0].offsetTop; 66 let stickyHeightCount = stickyOffset; 67 68 [].forEach.call(stickyElements, (item) => { 69 let top = stickyOffset; 70 if (item.offsetTop - stickyHeightCount > stickyHeightCount) { 71 top = stickyHeightCount; 72 } 73 74 self.stickyItems.push({ 75 element: item, 76 offsetYTop: top, 77 debugItemTop: item.offsetTop, 78 debugOffset: stickyOffset, 79 debugHeight: stickyHeightCount 80 }); 81 stickyHeightCount += item.offsetHeight; 82 }); 83 84 window.addEventListener('scroll', updateStickyScroll); 85 updateStickyScroll(); 86 } 87 }; 88 89 90 updateStickyItems(); 91 92 window.onresize = function () { 93 if (!this.queueResize) { 94 this.queueResize = true; 95 const self = this; 96 window.setTimeout(function () { 97 self.queueResize = false; 98 Array.from(document.getElementsByClassName('mikio-dropdown')).forEach(function (elem) { 99 if (!elem.classList.contains('closed')) { 100 elem.classList.add('closed'); 101 } 102 }); 103 104 updateStickyItems(); 105 }, 100); 106 } 107 }; 108 109 // Mikio-Dropdown - Click 110 Array.from(document.getElementsByClassName('mikio-dropdown')).forEach(function (elem) { 111 elem.addEventListener('click', function (event) { 112 event.stopPropagation(); 113 }); 114 }); 115 116 // Mikio-Dropdown - Close when clicked outside dropdown 117 Array.from(document.getElementsByTagName('body')).forEach(function (elem) { 118 elem.addEventListener('click', function () { 119 Array.from(document.getElementsByClassName('mikio-dropdown')).forEach(function (elem) { 120 if (!elem.classList.contains('closed')) { 121 elem.classList.add('closed'); 122 } 123 }); 124 }); 125 }); 126 127 // Mikio-Navbar-Toggle - Fix 128 Array.from(document.getElementsByClassName('mikio-navbar-toggle')).forEach(function (elem) { 129 elem.classList.add('closed'); 130 }); 131 132 // Mikio-Dropdown - Fix 133 Array.from(document.getElementsByClassName('mikio-dropdown')).forEach(function (elem) { 134 elem.classList.add('closed'); 135 }); 136 137 // Input File - Cleanup 138 Array.from(document.querySelectorAll('input[type=file]')).forEach(function (elem) { 139 const style = window.getComputedStyle(elem); 140 141 if (style.display !== 'none') { 142 const parentElem = elem.parentElement; 143 const fileRect = elem.getBoundingClientRect(); 144 const parentRect = parentElem.getBoundingClientRect(); 145 const spanElem = document.createElement('span'); 146 147 elem.style.opacity = '0'; 148 parentElem.style.position = 'relative'; 149 spanElem.innerHTML = 'Choose file...'; 150 spanElem.classList.add('mikio-input-file'); 151 spanElem.style.left = Math.floor(fileRect.left - parentRect.left) + 'px'; 152 spanElem.style.width = Math.floor(fileRect.right - fileRect.left) + 'px'; 153 mikio.insertAfter(spanElem, elem); 154 155 spanElem.addEventListener('click', function (event) { 156 if (event.target.parentElement.tagName.toLowerCase() !== 'label') { 157 let sibling = mikio.getPrevSibling(event.target, 'input'); 158 if (typeof sibling !== 'undefined') { 159 sibling.click(); 160 } 161 } 162 }); 163 164 elem.addEventListener('change', function () { 165 if (this.files.length > 0) { 166 let mikioInput = mikio.getNextSibling(this, '.mikio-input-file'); 167 if (typeof mikioInput !== 'undefined') { 168 mikioInput.innerHTML = this.files[0].name; 169 } 170 } 171 }); 172 } 173 }); 174 175 // Input - Span (Placeholder) clear when typing 176 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) { 177 if (elem.value.length !== 0) { 178 const sibling = mikio.getPrevSibling(elem, 'span'); 179 if (sibling) { 180 sibling.style.display = 'none'; 181 } 182 } 183 184 elem.addEventListener('keydown', function (event) { 185 const sibling = mikio.getPrevSibling(event.target, 'span'); 186 187 setTimeout(function () { 188 if (sibling) { 189 if (event.target.value !== '') { 190 sibling.style.display = 'none'; 191 } else { 192 sibling.style.display = 'block'; 193 } 194 } 195 }, 50); 196 }); 197 }); 198 199 // Admin - Exit button 200 Array.from(document.querySelectorAll('a[rel="exit-admin"]')).forEach(function (elem) { 201 elem.addEventListener('click', function (event) { 202 event.preventDefault(); 203 204 let href = window.location.protocol + "//" + window.location.host + "/" + window.location.pathname; 205 206 let params = window.location.search; 207 if (params !== '') { 208 params = params.substring(1).split('&'); 209 if (params.length > 1) { 210 href += '?'; 211 params.forEach(function (p) { 212 if (p.substring(0, 3) === 'id=') { 213 href += p; 214 } 215 }); 216 } 217 } 218 219 window.location = href; 220 }); 221 }); 222 223 // Admin - Back button 224 Array.from(document.querySelectorAll('a[rel="exit-page"]')).forEach(function (elem) { 225 elem.addEventListener('click', function (event) { 226 event.preventDefault(); 227 228 let href = window.location.protocol + "//" + window.location.host + "/" + window.location.pathname; 229 230 let params = window.location.search; 231 if (params !== '') { 232 params = params.substring(1).split('&'); 233 if (params.length > 1) { 234 href += '?'; 235 params.forEach(function (p) { 236 if (p.substring(0, 5) !== 'page=') { 237 href += p + '&'; 238 } 239 }); 240 } 241 } 242 243 window.location = href; 244 }); 245 }); 246 247 // Admin - Resize large text blocks in tasks 248 Array.from(document.querySelectorAll('.admin_tasks span.prompt')).forEach(function (elem) { 249 if (elem.offsetHeight > 48) { 250 elem.style.fontSize = '80%'; 251 } 252 }); 253 254 let target = document.getElementById('mediamanager__page'); 255 if (target) { 256 // Media Manager - ui-resizable is always auto 257 const mediaChangedObserver = new MutationObserver(function (mutationsList) { 258 for (let mutation of mutationsList) { 259 if (mutation.type === 'childList') { 260 if (mutation.addedNodes) { 261 mutation.addedNodes.forEach(function (node) { 262 if (node.nodeName === 'LI') { 263 264 } 265 }); 266 } 267 } 268 269 if (mutation.type === 'attributes' && mutation.attributeName === 'style' && mutation.target && mutation.target.style.height) { 270 mutation.target.style.height = ''; 271 } 272 } 273 }); 274 275 mediaChangedObserver.observe(target, {attributes: true, childList: true, subtree: true}); 276 } 277 278 // Media Manager - file click 279 Array.from(document.querySelectorAll('#mediamanager__page .filelist')).forEach(function (elem) { 280 elem.addEventListener('click', function (event) { 281 const liElem = event.target.closest('li'); 282 if (liElem && event.target.closest('ul.thumbs')) { 283 const aElem = liElem.querySelector('dd.name a'); 284 if (aElem) aElem.click(); 285 } 286 }); 287 }); 288 289 // Popup Media Manager - clean file info 290 const mediaPopupFileInfoClean = function (elem) { 291 // var file = { resolution: '', date: '', time: '', size: '' }; 292 293 const infoElem = elem.querySelector('span.info'); 294 if (infoElem) { 295 const infoText = infoElem.innerText.replace(/(<[^>]*>|[()])/g, ''); 296 const detail = infoText.split(' '); 297 while (detail.length < 4) { 298 detail.unshift(''); 299 } 300 301 infoElem.innerHTML = detail[0] + '<br>' + detail[1] + ' ' + detail[2] + '<br>' + detail[3]; 302 } 303 304 Array.from(elem.querySelectorAll('img')).forEach(function (elem) { 305 elem.removeAttribute('width'); 306 elem.removeAttribute('height'); 307 }); 308 } 309 310 target = document.getElementById('media__content'); 311 if (target) { 312 Array.from(target.querySelectorAll('div.odd, div.even')).forEach(function (elem) { 313 mediaPopupFileInfoClean(elem); 314 }); 315 316 const mediaPopupObserver = new MutationObserver(function (mutationsList) { 317 for (let mutation of mutationsList) { 318 if (mutation.type === 'childList') { 319 if (mutation.addedNodes) { 320 mutation.addedNodes.forEach(function (node) { 321 if (node.nodeName === 'DIV') { 322 mediaPopupFileInfoClean(node); 323 } 324 }); 325 } 326 } 327 } 328 }); 329 330 mediaPopupObserver.observe(target, {attributes: false, childList: true}); 331 } 332 333 // noinspection JSUnresolvedReference 334 if (window.mikioFooterRun && typeof window.mikioFooterRun === "function") window.mikioFooterRun(); 335 336 const linkElements = document.getElementsByTagName('link'); 337 for (let element of linkElements) { 338 if (element.rel === 'stylesheet' && element.href) { 339 if (element.href.includes('/lib/exe/css.php')) { 340 const mediaChangedObserver = new MutationObserver(function (mutationsList) { 341 for (let mutation of mutationsList) { 342 if (mutation.type === 'attributes' && mutation.attributeName === 'href') { 343 if (self.mikioCSS !== false) { 344 let elem = self.mikioCSS; 345 let prev = elem.href; 346 347 setTimeout(function () { 348 const url = new URL(prev); 349 const params = url.searchParams; 350 params.set('seed', new Date().getTime().toString()); 351 url.search = params.toString(); 352 elem.href = url.toString(); 353 }, 500); 354 } 355 } 356 } 357 }); 358 359 mediaChangedObserver.observe(element, {attributes: true, childList: true, subtree: true}); 360 } else if (element.href.includes('/lib/tpl/mikio/css.php')) { 361 this.mikioCSS = element; 362 } 363 } 364 } 365 366 // Update color text field when selector changes 367 let colorSelectorInputs = document.querySelectorAll('div.mikio-color-picker input[type="color"]'); 368 colorSelectorInputs.forEach(input => { 369 input.addEventListener('input', () => { 370 let colorTextInput = document.querySelector(`div.mikio-color-picker input[for="${input.id}"]`); 371 if (colorTextInput) { 372 colorTextInput.value = input.value; 373 } 374 }); 375 }); 376 377 let colorTextInputs = document.querySelectorAll('div.mikio-color-picker input[type="text"]'); 378 colorTextInputs.forEach(input => { 379 input.addEventListener('blur', () => { 380 const id = input.getAttribute('for'); 381 let colorSelectorInput = document.querySelector(`div.mikio-color-picker input[id="${id}"]`); 382 if (colorSelectorInput) { 383 colorSelectorInput.value = this.colorToHex(input.value); 384 } 385 }); 386 }); 387 }, 388 389 initDarkMode: function () { 390 const showLightDark = document.querySelector('.mikio-darklight-button') != null; 391 if (showLightDark === true) { 392 let setting = this.getCookie('lightDarkToggle'); 393 if (setting === 'dark' || setting === 'light' || setting === 'auto') { 394 this.darkMode = setting; 395 } 396 397 if (document.querySelector('.mikio-auto-darklight') == null && setting === 'auto') { 398 this.darkMode = 'light'; 399 } 400 } else { 401 if (document.querySelector('.mikio-auto-darklight') != null) { 402 this.darkMode = 'auto'; 403 } 404 } 405 406 const self = this; 407 408 if (window.matchMedia) { 409 window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { 410 self.updateDarkMode(); 411 }); 412 } 413 414 this.addEventListenerByClassName('mikio-darklight-button', 'click', function (event) { 415 event.preventDefault(); 416 event.stopPropagation(); 417 418 const autoAllowed = (document.querySelector('.mikio-iicon.mikio-darklight-auto') != null); 419 420 if (self.darkMode === 'light') { 421 self.darkMode = 'dark'; 422 } else if (self.darkMode === 'dark') { 423 if (autoAllowed === true) { 424 self.darkMode = 'auto'; 425 } else { 426 self.darkMode = 'light'; 427 } 428 } else if (self.darkMode === 'auto') { 429 self.darkMode = 'light'; 430 } else { 431 self.darkMode = 'dark'; 432 } 433 434 self.updateDarkMode(); 435 }); 436 437 this.updateDarkMode(); 438 }, 439 440 updateDarkMode: function () { 441 const html = document.querySelector('html'); 442 let themeMode = this.darkMode; 443 444 if (this.darkMode === 'auto') { 445 html.dataset.themeAuto = 'true'; 446 447 themeMode = 'light'; 448 if (window.matchMedia) { 449 let prefersColorSchemeQuery = window.matchMedia('(prefers-color-scheme: dark)'); 450 themeMode = prefersColorSchemeQuery.matches ? 'dark' : 'light'; 451 } 452 } else { 453 delete html.dataset.themeAuto; 454 } 455 456 console.log(this.darkMode); 457 458 if(themeMode === '') { 459 if(document.querySelector('body').classList.contains('mikio-default-dark')) { 460 themeMode = 'dark'; 461 } else { 462 themeMode = 'light'; 463 } 464 } 465 466 html.dataset.theme = `theme-${themeMode}`; 467 this.setCookie('lightDarkToggle', this.darkMode); 468 }, 469 470 insertAfter: function (newNode, existingNode) { 471 existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling); 472 }, 473 474 addToggleClick: function (elemToggle, elemCollapse) { 475 this.addEventListenerByClassName(elemToggle, 'click', function (event) { 476 event.preventDefault(); 477 event.stopPropagation(); 478 let nextSibling = mikio.getNextSibling(this, '.' + elemCollapse); 479 480 if (typeof nextSibling !== 'undefined') { 481 mikio.toggleCollapse(this, nextSibling); 482 } 483 }); 484 }, 485 486 addDropdownClick: function (elemToggle, elemCollapse) { 487 this.addEventListenerByClassName(elemToggle, 'click', function (event) { 488 event.preventDefault(); 489 event.stopPropagation(); 490 491 const dropdown = this.querySelector('.' + elemCollapse); 492 if (dropdown) { 493 mikio.toggleDropdown(dropdown); 494 } 495 }); 496 }, 497 498 addEventListenerByClassName: function (className, eventType, callback) { 499 Array.from(document.getElementsByClassName(className)).forEach(function (elem) { 500 elem.addEventListener(eventType, callback); 501 }); 502 }, 503 504 getNextSibling: function (elem, selector) { 505 let sibling = elem.nextElementSibling; 506 507 while (sibling) { 508 if (sibling.matches(selector)) return sibling; 509 sibling = sibling.nextElementSibling; 510 } 511 }, 512 513 getPrevSibling: function (elem, selector) { 514 let sibling = elem.previousElementSibling; 515 516 while (sibling) { 517 if (sibling.matches(selector)) return sibling; 518 sibling = sibling.previousElementSibling; 519 } 520 }, 521 522 toggleCollapse: function (objToggle, objCollapse) { 523 if (objToggle.classList.contains('closed')) { 524 objToggle.classList.remove('closed'); 525 objToggle.classList.add('open'); 526 const height = objCollapse.offsetHeight; 527 objCollapse.style.overflow = 'hidden'; 528 objCollapse.style.height = '0'; 529 objCollapse.style.paddingTop = '0'; 530 objCollapse.style.paddingBottom = '0'; 531 objCollapse.style.marginTop = '0'; 532 objCollapse.style.marginBottom = '0'; 533 objCollapse.offsetHeight; 534 objCollapse.style.boxSizing = 'border-box'; 535 objCollapse.style.transitionProperty = "height, margin, padding"; 536 objCollapse.style.transitionDuration = '500ms'; 537 objCollapse.style.height = height + 'px'; 538 objCollapse.style.removeProperty('padding-top'); 539 objCollapse.style.removeProperty('padding-bottom'); 540 objCollapse.style.removeProperty('margin-top'); 541 objCollapse.style.removeProperty('margin-bottom'); 542 window.setTimeout(function () { 543 objCollapse.style.removeProperty('height'); 544 objCollapse.style.removeProperty('overflow'); 545 objCollapse.style.removeProperty('transition-duration'); 546 objCollapse.style.removeProperty('transition-property'); 547 objCollapse.style.removeProperty('box-sizing'); 548 }, 500); 549 } else { 550 objCollapse.style.transitionProperty = 'height, margin, padding'; 551 objCollapse.style.transitionDuration = '500ms'; 552 objCollapse.style.boxSizing = 'border-box'; 553 objCollapse.style.height = objCollapse.offsetHeight + 'px'; 554 objCollapse.offsetHeight; 555 objCollapse.style.overflow = 'hidden'; 556 objCollapse.style.height = '0'; 557 objCollapse.style.paddingTop = '0'; 558 objCollapse.style.paddingBottom = '0'; 559 objCollapse.style.marginTop = '0'; 560 objCollapse.style.marginBottom = '0'; 561 window.setTimeout(function () { 562 objToggle.classList.add('closed'); 563 objToggle.classList.remove('open'); 564 objCollapse.style.removeProperty('height'); 565 objCollapse.style.removeProperty('padding-top'); 566 objCollapse.style.removeProperty('padding-bottom'); 567 objCollapse.style.removeProperty('margin-top'); 568 objCollapse.style.removeProperty('margin-bottom'); 569 objCollapse.style.removeProperty('overflow'); 570 objCollapse.style.removeProperty('transition-duration'); 571 objCollapse.style.removeProperty('transition-property'); 572 objCollapse.style.removeProperty('box-sizing'); 573 }, 500); 574 } 575 }, 576 577 578 toggleDropdown: function (objToggle) { 579 if (objToggle.classList.contains('closed')) { 580 objToggle.classList.remove('closed'); 581 } else { 582 objToggle.classList.add('closed'); 583 } 584 585 Array.from(document.getElementsByClassName('mikio-dropdown')).forEach(function (elem) { 586 if (!elem.classList.contains('closed') && elem !== objToggle) { 587 elem.classList.add('closed'); 588 } 589 }); 590 }, 591 592 setHeroSubTitle: function (str) { 593 Array.from(document.getElementsByClassName('mikio-hero-subtitle')).forEach(function (elem) { 594 elem.innerHTML = str; 595 }); 596 }, 597 598 setHeroImage: function (str) { 599 const heroImages = document.getElementsByClassName('mikio-hero-image'); 600 601 if (heroImages.length > 0) { 602 Array.from(document.getElementsByClassName('mikio-hero-image')).forEach(function (elem) { 603 elem.style.backgroundImage = 'url(\'' + str + '\')'; 604 elem.classList.add('mikio-hero-image-resize'); 605 }); 606 } else { 607 Array.from(document.getElementsByClassName('mikio-hero-text')).forEach(function (elem) { 608 elem.insertAdjacentHTML('afterend', '<div class="mikio-hero-image mikio-hero-image-resize" style="background-image:url(\'' + str + '\');"></div>'); 609 }); 610 } 611 }, 612 613 setHeroColor: function (str) { 614 const colors = str.trim().replace(/ +(?= )/g, '').split(/(?!\(.*)\s(?![^(]*?\))/g); 615 if (colors.length > 0 && colors[0] !== '') { 616 Array.from(document.getElementsByClassName('mikio-hero')).forEach(function (elem) { 617 elem.style.backgroundColor = colors[0]; 618 }); 619 620 if (colors.length > 1) { 621 Array.from(document.getElementsByClassName('mikio-hero-title')).forEach(function (elem) { 622 elem.style.color = colors[1]; 623 }); 624 } 625 626 if (colors.length > 2) { 627 Array.from(document.getElementsByClassName('mikio-hero-subtitle')).forEach(function (elem) { 628 elem.style.color = colors[2]; 629 }); 630 } 631 632 if (colors.length > 3) { 633 Array.from(document.getElementsByClassName('mikio-hero')).forEach(function (parentElem) { 634 Array.from(parentElem.querySelectorAll('.mikio-breadcrumbs ul li a')).forEach(function (elem) { 635 elem.style.color = colors[3]; 636 }); 637 638 Array.from(parentElem.querySelectorAll('.mikio-breadcrumbs ul li, .mikio-breadcrumbs ul li a')).forEach(function (elem) { 639 elem.style.color = colors[3]; 640 elem.onmouseover = function () { this.style.color = (colors.length > 4 ? colors[4] : 'initial'); }; 641 elem.onmouseout = function () { this.style.color = colors[3]; }; 642 }); 643 }); 644 } 645 } 646 }, 647 648 setTags: function (str) { 649 Array.from(document.getElementsByClassName('mikio-tags')).forEach(function (elem) { 650 elem.innerHTML = str; 651 }); 652 }, 653 654 hidePart: function (part) { 655 const selectorArray = { 656 topheader: '.mikio-page-topheader', 657 header: '.mikio-page-header', 658 contentheader: '.mikio-page-contentheader', 659 contentfooter: '.mikio-page-contentfooter', 660 sidebarheader: '.mikio-sidebar-left .mikio-sidebar-header', 661 sidebarfooter: '.mikio-sidebar-left .mikio-sidebar-footer', 662 rightsidebarheader: '.mikio-sidebar-right .mikio-sidebar-header', 663 rightsidebarfooter: '.mikio-sidebar-right .mikio-sidebar-footer', 664 footer: '.mikio-footer', 665 bottomfooter: '.mikio-page-bottomfooter', 666 navbar: '.mikio-navbar', 667 hero: '.mikio-hero' 668 }; 669 670 if (selectorArray.hasOwnProperty(part)) { 671 Array.from(document.querySelectorAll(selectorArray[part])).forEach(function (elem) { 672 elem.style.display = 'none'; 673 }); 674 } 675 }, 676 677 indexmenuPatch: function () { 678 window.setTimeout(function () { 679 Array.from(document.querySelectorAll('a.navSel')).forEach(function (elem) { 680 let prev = mikio.getPrevSibling(elem, 'img'); 681 if (prev) { 682 prev.style.opacity = '1'; 683 } 684 }); 685 }, 50); 686 687 688 document.addEventListener('mouseover', function (event) { 689 const indexmenuClasses = ['nodeUrl', 'nodeSel', 'node']; 690 if ([...event.target.classList].some(className => indexmenuClasses.indexOf(className) !== -1)) { 691 let prev = mikio.getPrevSibling(event.target, 'img'); 692 if (prev) { 693 prev.style.opacity = '1'; 694 } 695 } 696 }); 697 698 document.addEventListener('mouseout', function (event) { 699 const indexmenuClasses = ['nodeUrl', 'nodeSel', 'node']; 700 if ([...event.target.classList].some(className => indexmenuClasses.indexOf(className) !== -1)) { 701 let prev = mikio.getPrevSibling(event.target, 'img'); 702 if (prev) { 703 prev.style.opacity = ''; 704 } 705 } 706 }); 707 }, 708 709 // Add typeahead support for quick seach. Taken from bootstrap3 theme. 710 typeahead: function () { 711 jQuery(".search_typeahead").typeahead({ 712 713 source: function (query, process) { 714 715 return jQuery.post(DOKU_BASE + 'lib/exe/ajax.php', 716 { 717 call: 'qsearch', 718 q: encodeURI(query) 719 }, 720 function (data) { 721 722 const results = []; 723 724 jQuery(data).find('a').each(function () { 725 726 const page = jQuery(this); 727 728 results.push({ 729 name: page.text(), 730 href: page.attr('href'), 731 title: page.attr('title'), 732 category: page.attr('title').replace(/:/g, ' : '), 733 }); 734 735 }); 736 737 return process(results); 738 739 }); 740 }, 741 742 itemLink: function (item) { 743 return item.href; 744 }, 745 746 itemTitle: function (item) { 747 return item.title; 748 }, 749 750 followLinkOnSelect: true, 751 autoSelect: false, 752 items: 10, 753 fitToElement: true, 754 delay: 500, 755 theme: 'bootstrap4', 756 757 }); 758 }, 759 760 getCookie: function (cname) { 761 let name = cname + "="; 762 let decodedCookie = decodeURIComponent(document.cookie); 763 let ca = decodedCookie.split(';'); 764 for (let i = 0; i < ca.length; i++) { 765 let c = ca[i]; 766 while (c.charAt(0) === ' ') { 767 c = c.substring(1); 768 } 769 if (c.indexOf(name) === 0) { 770 return c.substring(name.length, c.length); 771 } 772 } 773 return ""; 774 }, 775 776 setCookie: function (cname, cvalue, exdays) { 777 const d = new Date(); 778 d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000)); 779 let expires = "expires=" + d.toUTCString(); 780 document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/;SameSite=Lax"; 781 }, 782 783 clearCookie: function (cname) { 784 document.cookie = cname + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/;SameSite=Lax"; 785 }, 786 787 colorToHex: function (color) { 788 // Create a canvas element 789 let canvas = document.createElement('canvas'); 790 canvas.height = 1; 791 canvas.width = 1; 792 let ctx = canvas.getContext('2d'); 793 794 // Set the fillStyle to the color input 795 ctx.fillStyle = color; 796 ctx.fillRect(0, 0, 1, 1); 797 798 // Get the pixel data from the canvas 799 let data = ctx.getImageData(0, 0, 1, 1).data; 800 801 // Convert the RGB values to HEX 802 return '#' + ((1 << 24) + (data[0] << 16) + (data[1] << 8) + data[2]).toString(16).slice(1).toUpperCase(); 803 }, 804 805 doPluginPatch: function() { 806 if(document.getElementsByClassName('plugin__do_usertasks').length === 0) return; 807 808 this.addEventListenerByClassName('mikio-nav-dropdown', 'click', function(event) { 809 if (jQuery('.plugin__do_usertasks_list').length) { 810 jQuery('.plugin__do_usertasks_list').hide(); 811 } 812 }); 813 814 this.addEventListenerByClassName('plugin__do_usertasks', 'click', function(event) { 815 Array.from(document.getElementsByClassName('mikio-dropdown')).forEach(function (elem) { 816 if (!elem.classList.contains('closed')) { 817 elem.classList.add('closed'); 818 } 819 }); 820 }); 821 } 822}; 823 824if (document.readyState !== 'loading') { 825 mikio.ready(); 826} else { 827 document.addEventListener('DOMContentLoaded', function () { mikio.ready() }); 828} 829