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