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