1 2 3jQuery().ready(function () { 4 var stripHtml = function(htmlString) { 5 var tempDiv = document.createElement("div"); 6 tempDiv.innerHTML = htmlString; 7 return tempDiv.textContent || tempDiv.innerText || ""; 8 }; 9 10 var urlMatches = function(url, start = 'start') { 11 const windowURL = new URL(window.location); 12 const urlObject = new URL(url.startsWith('http') ? url : window.origin + url); 13 let match = true; 14 15 // remove trailing slashes 16 let windowPath = windowURL.pathname.replace(/\/$/, '');; 17 let urlPath = urlObject.pathname.replace(/\/$/, '');; 18 19 // add in start page if missing 20 if(windowURL.searchParams.has('id') || urlObject.searchParams.has('id')) { 21 // using search params 22 if(windowURL.searchParams.has('id') === false) { 23 windowURL.searchParams.append('id', start); 24 } 25 26 if(urlObject.searchParams.has('id') === false) { 27 urlObject.searchParams.append('id', start); 28 } 29 } else { 30 // dont seem to be using search params 31 if (windowPath.endsWith('/doku.php')) { 32 windowPath = windowPath + '/' + start; 33 } 34 if (urlPath.endsWith('/doku.php')) { 35 urlPath = urlPath + '/' + start; 36 } 37 } 38 39 if(windowURL.origin !== urlObject.origin || windowPath !== urlPath) { 40 return false; 41 } 42 43 urlObject.searchParams.forEach((val, key) => { 44 if(!windowURL.searchParams.has(key) || windowURL.searchParams.get(key) !== val) { 45 match = false; 46 } 47 }); 48 49 return match; 50 }; 51 52 jQuery('.mikiop-button').on('click', function (event) { 53 if (jQuery(this).hasClass('mikiop-disabled')) { 54 event.preventDefault(); 55 } 56 57 if (jQuery(this).attr('data-toggle') == 'collapse') { 58 event.preventDefault(); 59 jQuery(jQuery(this).attr('data-target')).slideToggle(); 60 } 61 }); 62 63 jQuery('.mikiop-accordian-title').on('click', function (event) { 64 event.preventDefault(); 65 let accordianBody = jQuery(this).siblings('.mikiop-accordian-body'); 66 if (!accordianBody.is(':visible')) { 67 let accordian = jQuery(this).closest('.mikiop-accordian'); 68 if (accordian.hasClass('mikiop-autoclose')) { 69 accordian.find('.mikiop-accordian-body:visible').slideUp(); 70 } 71 } 72 73 jQuery(this).siblings('.mikiop-accordian-body').slideToggle(); 74 }); 75 76 jQuery('.mikiop-alert-close').on('click', function (event) { 77 event.preventDefault(); 78 jQuery(this).closest('.mikiop-alert').hide(); 79 }); 80 81 jQuery('.mikiop-carousel').each(function () { 82 var items = jQuery(this).find('.mikiop-carousel-item'); 83 var indicators = ''; 84 var active = false; 85 86 for (var i = 0; i < items.length; i++) { 87 if (jQuery(items[i]).hasClass('mikiop-active')) { 88 active = true; 89 indicators += '<li class="mikiop mikiop-carousel-indicator mikiop-active"></li>'; 90 } else { 91 indicators += '<li class="mikiop mikiop-carousel-indicator"></li>'; 92 } 93 }; 94 95 jQuery(this).find('.mikiop-carousel-indicators').html(indicators); 96 97 if (!active) { 98 jQuery(this).find('.mikiop-carousel-item').first().addClass('mikiop-active'); 99 jQuery(this).find('.mikiop-carousel-indicator').first().addClass('mikiop-active'); 100 } 101 102 if (jQuery(this).attr('data-auto-start') == 'true') { 103 var carousel = jQuery(this); 104 timeout = carousel.find('.mikiop-carousel-item.mikiop-active').attr('data-interval'); 105 106 if (timeout == 0) { 107 timeout = 3; 108 } 109 110 var nextSlide = function () { 111 var timeout = carouselNext(carousel); 112 113 if (timeout == 0) { 114 timeout = 3; 115 } 116 117 window.setTimeout(nextSlide, (timeout * 1000) + 500); 118 }; 119 120 window.setTimeout(nextSlide, (timeout * 1000) + 500); 121 } 122 }); 123 124 jQuery('.mikiop-carousel-control-prev').on('click', function (event) { 125 event.preventDefault(); 126 127 var parent = jQuery(this).parent(); 128 carouselPrev(parent); 129 }); 130 131 function carouselPrev(parent) { 132 133 var slides = parent.find('.mikiop-carousel-item'); 134 135 for (var i = 0; i < slides.length; i++) { 136 if (jQuery(slides[i]).hasClass('mikiop-active')) { 137 var target = null; 138 var next = 0; 139 140 if (i == 0) { 141 next = slides.length - 1; 142 } else { 143 next = i - 1; 144 } 145 target = jQuery(slides[next]); 146 147 if (jQuery(parent).hasClass('mikiop-transition-fade')) { 148 target.css('z-index', 0).addClass('mikiop-active'); 149 jQuery(slides[i]).fadeOut(function () { 150 jQuery(this).removeClass('mikiop-active').css('display', ''); 151 target.css('z-index', ''); 152 }); 153 } else if (jQuery(parent).hasClass('mikiop-transition-slide')) { 154 target.css('left', '-100%').addClass('mikiop-active'); 155 target.animate({ left: '0' }, 500); 156 jQuery(slides[i]).animate({ left: '100%' }, 500, function () { 157 jQuery(this).removeClass('mikiop-active').css('left', ''); 158 target.css('left', ''); 159 }) 160 } else { 161 target.addClass('mikiop-active'); 162 jQuery(slides[i]).removeClass('mikiop-active'); 163 } 164 165 parent.find('.mikiop-carousel-indicator').removeClass('mikiop-active'); 166 parent.find('.mikiop-carousel-indicator:nth-child(' + (next + 1) + ')').addClass('mikiop-active'); 167 168 break; 169 } 170 } 171 }; 172 173 jQuery('.mikiop-carousel-control-next').on('click', function (event) { 174 event.preventDefault(); 175 var parent = jQuery(this).parent(); 176 177 carouselNext(parent); 178 }); 179 180 function carouselNext(parent) { 181 var slides = parent.find('.mikiop-carousel-item'); 182 var delay = 0; 183 184 for (var i = 0; i < slides.length; i++) { 185 186 187 if (jQuery(slides[i]).hasClass('mikiop-active')) { 188 var target = null; 189 var next = 0; 190 191 192 if (i == slides.length - 1) { 193 next = 0; 194 } else { 195 next = i + 1; 196 } 197 target = jQuery(slides[next]); 198 199 delay = target.attr('data-interval'); 200 if (typeof delay == 'undefined') { 201 delay = 0; 202 } 203 204 if (jQuery(parent).hasClass('mikiop-transition-fade')) { 205 target.css('z-index', 0).addClass('mikiop-active'); 206 jQuery(slides[i]).fadeOut(function () { 207 jQuery(this).removeClass('mikiop-active').css('display', ''); 208 target.css('z-index', ''); 209 }); 210 } else if (jQuery(parent).hasClass('mikiop-transition-slide')) { 211 target.css('left', '100%').addClass('mikiop-active'); 212 target.animate({ left: '0' }, 500); 213 jQuery(slides[i]).animate({ left: '-100%' }, 500, function () { 214 jQuery(this).removeClass('mikiop-active').css('left', ''); 215 target.css('left', ''); 216 }) 217 } else { 218 target.addClass('mikiop-active'); 219 jQuery(slides[i]).removeClass('mikiop-active'); 220 } 221 222 parent.find('.mikiop-carousel-indicator').removeClass('mikiop-active'); 223 parent.find('.mikiop-carousel-indicator:nth-child(' + (next + 1) + ')').addClass('mikiop-active'); 224 225 break; 226 } 227 } 228 229 return (delay); 230 }; 231 232 jQuery('.mikiop-carousel-indicator').on('click', function (event) { 233 event.preventDefault(); 234 235 var parent = jQuery(this).closest('.mikiop-carousel-indicators'); 236 if (parent) { 237 var group = jQuery(this).closest('.mikiop-carousel'); 238 if (group) { 239 var items = jQuery(group).find('.mikiop-carousel-indicator'); 240 241 var item = -1; 242 var active = 0; 243 for (var i = 0; i < items.length; i++) { 244 if (jQuery(items[i]).hasClass('mikiop-active')) { 245 active = i; 246 } 247 248 if (items[i] == jQuery(this)[0]) { 249 item = i; 250 } 251 } 252 253 if (item != active) { 254 if (jQuery(group).hasClass('mikiop-transition-fade')) { 255 var target = jQuery(group).find('.mikiop-carousel-item:nth-child(' + (item + 1) + ')'); 256 257 target.css('z-index', 0).addClass('mikiop-active'); 258 jQuery(group).find('.mikiop-carousel-item:nth-child(' + (active + 1) + ')').fadeOut(function () { 259 jQuery(this).removeClass('mikiop-active').css('display', ''); 260 target.css('z-index', ''); 261 }); 262 263 jQuery(group).find('.mikiop-carousel-indicator:nth-child(' + (item + 1) + ')').addClass('mikiop-active'); 264 jQuery(group).find('.mikiop-carousel-indicator:nth-child(' + (active + 1) + ')').removeClass('mikiop-active'); 265 } else if (jQuery(group).hasClass('mikiop-transition-slide')) { 266 var target = jQuery(group).find('.mikiop-carousel-item:nth-child(' + (item + 1) + ')'); 267 268 if (item < active) { 269 target.css('left', '-100%').addClass('mikiop-active'); 270 target.animate({ left: '0' }, 500); 271 jQuery(group).find('.mikiop-carousel-item:nth-child(' + (active + 1) + ')').animate({ left: '100%' }, 500, function () { 272 jQuery(this).removeClass('mikiop-active').css('left', ''); 273 target.css('left', ''); 274 }); 275 } else { 276 target.css('left', '100%').addClass('mikiop-active'); 277 target.animate({ left: '0' }, 500); 278 jQuery(group).find('.mikiop-carousel-item:nth-child(' + (active + 1) + ')').animate({ left: '-100%' }, 500, function () { 279 jQuery(this).removeClass('mikiop-active').css('left', ''); 280 target.css('left', ''); 281 }); 282 } 283 284 jQuery(group).find('.mikiop-carousel-indicator:nth-child(' + (item + 1) + ')').addClass('mikiop-active'); 285 jQuery(group).find('.mikiop-carousel-indicator:nth-child(' + (active + 1) + ')').removeClass('mikiop-active'); 286 } else { 287 jQuery(group).find('.mikiop-carousel-item:nth-child(' + (item + 1) + ')').addClass('mikiop-active'); 288 jQuery(group).find('.mikiop-carousel-indicator:nth-child(' + (item + 1) + ')').addClass('mikiop-active'); 289 jQuery(group).find('.mikiop-carousel-item:nth-child(' + (active + 1) + ')').removeClass('mikiop-active'); 290 jQuery(group).find('.mikiop-carousel-indicator:nth-child(' + (active + 1) + ')').removeClass('mikiop-active'); 291 } 292 } 293 } 294 } 295 }); 296 297 jQuery('.mikiop-tab-item a').on('click', function (event) { 298 event.preventDefault(); 299 300 var parent = jQuery(this).closest('.mikiop-tab-item'); 301 if (parent) { 302 var group = jQuery(parent).closest('.mikiop-tab-group'); 303 if (group) { 304 var items = jQuery(group).find('.mikiop-tab-item'); 305 306 var item = -1; 307 for (var i = 0; i < items.length; i++) { 308 if (items[i] == parent[0]) { 309 item = i; 310 break; 311 } 312 } 313 314 if (item != -1) { 315 var panes = jQuery(group).siblings('.mikiop-tab-content').find('.mikiop-tab-pane'); 316 317 if (panes.length > item) { 318 if (!jQuery(panes[item]).hasClass('mikiop-show')) { 319 jQuery(panes).removeClass('mikiop-show'); 320 jQuery(panes[item]).addClass('mikiop-show'); 321 322 jQuery(items).find('a').removeClass('mikiop-active'); 323 jQuery(items[item]).find('a').addClass('mikiop-active'); 324 } 325 } 326 } 327 } 328 } 329 }); 330 331 // Quiz 332 var quizReset = function(quizRef) { 333 quizRef.find('.mikiop-quiz-button-prev').attr('disabled', true); 334 quizRef.find('.mikiop-quiz-result').hide(); 335 quizRef.find('.mikiop-quiz-button-submit').show().attr('disabled', false); 336 quizRef.find('.mikiop-quiz-button-reset').hide(); 337 338 var status = quizRef.attr('data-status'); 339 status = status.replace('$1', '1'); 340 status = status.replace('$2', quizRef.children('.mikiop-quiz-item').length); 341 quizRef.find('.mikiop-quiz-status-text').html(status); 342 343 if (quizRef.children('.mikiop-quiz-item').length == 1) { 344 quizRef.find('.mikiop-quiz-button-next').attr('disabled', true); 345 } else { 346 quizRef.find('.mikiop-quiz-button-next').attr('disabled', false); 347 } 348 349 quizRef.children('.mikiop-quiz-item').find('input[type="radio"], input[type="checkbox"]').prop('checked', false); 350 351 var full = quizRef.attr('data-full'); 352 if(!full) { 353 quizRef.children('.mikiop-quiz-item').not(':first-child').hide(); 354 quizRef.children('.mikiop-quiz-item:first-child').show(); 355 } else { 356 quizRef.children('.mikiop-quiz-item').show(); 357 } 358 }; 359 360 jQuery('.mikiop-quiz').each(function () { 361 quizReset(jQuery(this)); 362 }); 363 364 jQuery('.mikiop-quiz-button-prev').on('click', function (event) { 365 var parent = jQuery(this).closest('.mikiop-quiz'); 366 var questions = parent.children('.mikiop-quiz-item'); 367 parent.find('.mikiop-quiz-button-next').attr('disabled', false); 368 369 for (var i = 0; i < questions.length; i++) { 370 if (jQuery(questions[i]).is(':visible')) { 371 i--; 372 373 if (i <= 0) { 374 jQuery(this).attr('disabled', true); 375 } 376 377 jQuery(questions[i + 1]).hide(); 378 jQuery(questions[i]).show(); 379 parent.find('.mikiop-quiz-status-number').html(i + 1); 380 381 var status = parent.attr('data-status'); 382 status = status.replace('$1', i + 1); 383 status = status.replace('$2', parent.children('.mikiop-quiz-item').length); 384 parent.find('.mikiop-quiz-status-text').html(status); 385 386 break; 387 } 388 } 389 }); 390 391 jQuery('.mikiop-quiz-button-next').on('click', function (event) { 392 var parent = jQuery(this).closest('.mikiop-quiz'); 393 var questions = parent.children('.mikiop-quiz-item'); 394 parent.find('.mikiop-quiz-button-prev').attr('disabled', false); 395 396 for (var i = 0; i < questions.length; i++) { 397 if (jQuery(questions[i]).is(':visible')) { 398 i++; 399 400 if (i >= questions.length - 1) { 401 jQuery(this).attr('disabled', true); 402 } 403 404 jQuery(questions[i - 1]).hide(); 405 jQuery(questions[i]).show(); 406 407 var status = parent.attr('data-status'); 408 status = status.replace('$1', i + 1); 409 status = status.replace('$2', parent.children('.mikiop-quiz-item').length); 410 parent.find('.mikiop-quiz-status-text').html(status); 411 412 break; 413 } 414 } 415 }); 416 417 jQuery('.mikiop-quiz-button-submit').on('click', function (event) { 418 var parent = jQuery(this).closest('.mikiop-quiz'); 419 var questions = parent.children('.mikiop-quiz-item'); 420 var correct = 0; 421 var totalScore = 0; 422 var result = '<div class="mikiop-quiz-question">Result</div>'; 423 424 var usingScoring = false; 425 var usingCorrect = false; 426 var questionCount = 0; 427 428 parent.find('.mikiop-quiz-button-prev').attr('disabled', true); 429 parent.find('.mikiop-quiz-button-next').attr('disabled', true); 430 parent.find('.mikiop-quiz-button-submit').attr('disabled', true); 431 parent.find('.mikiop-quiz-status-text').html(''); 432 433 var resetButton = parent.find('.mikiop-quiz-button-reset'); 434 if(resetButton.length > 0) { 435 parent.find('.mikiop-quiz-button-submit').hide(); 436 resetButton.show(); 437 } 438 439 440 for (var i = 0; i < questions.length; i++) { 441 var showNewLine = true; 442 var question = stripHtml(jQuery(questions[i]).attr('data-question')); 443 var regex = /^((\w+ ?)*[):])/; 444 445 if (regex.test(question)) { 446 question = question.match(regex)[1]; 447 showNewLine = false; 448 } 449 450 result += '<p class="mikiop-quiz-result-question"><strong>' + question + '</strong>' + (showNewLine ? '<br>' : ' '); 451 452 var checked = jQuery(questions[i]).find("input:checked"); 453 var answer = jQuery(questions[i]).attr('data-answer'); 454 var value = checked.val(); 455 456 if(answer != undefined) { 457 usingCorrect = true; 458 questionCount++; 459 } 460 461 if (typeof value == 'undefined') { 462 result += 'Not answered'; 463 } else { 464 // check that input radio groups with the same name have at least 1 answer 465 let radioPass = true; 466 let radioGroups = {}; 467 const radios = jQuery(questions[i]).find('input[type="radio"]'); 468 469 radios.each(function () { 470 const groupName = jQuery(this).attr('name'); 471 472 if (!radioGroups[groupName]) { 473 radioGroups[groupName] = []; 474 } 475 476 radioGroups[groupName].push(jQuery(this)); 477 }); 478 479 for (const key in radioGroups) { 480 if (radioGroups.hasOwnProperty(key)) { 481 const group = radioGroups[key]; 482 const anySelected = group.some(function (radio) { 483 return radio.prop('checked'); 484 }); 485 486 if (!anySelected) { 487 result += 'An option was not answered'; 488 radioPass = false; 489 break; 490 } 491 } 492 } 493 494 if(radioPass) { 495 var totalItemScore = 0; 496 var selectedItems = []; 497 var itemIsScored = false; 498 499 checked.each(function() { 500 var item = jQuery(this); 501 502 var score = item.attr('data-score'); 503 504 if(score != undefined && score.length > 0) { 505 usingScoring = true; 506 itemIsScored = true; 507 totalItemScore += parseInt(score, 10); 508 } else if(answer != undefined) { 509 usingCorrect = true; 510 selectedItems.push(item.val()); 511 } 512 }); 513 514 if(itemIsScored) { 515 var scorePlaceholder = parent.attr('data-result-score'); 516 result += scorePlaceholder.replace('$1', totalItemScore); 517 totalScore += totalItemScore; 518 } else { 519 var correctText = parent.attr('data-correct'); 520 var incorrectText = parent.attr('data-incorrect'); 521 522 result += selectedItems.join(", ") + ' - '; 523 524 if(answer == undefined) { 525 result += "No answer set for question"; 526 } else if(answer.indexOf('|') !== -1) { 527 var answerArray = answer.split('|'); 528 if(answerArray.length == selectedItems.length) { 529 var totalMatch = true; 530 answerArray.forEach(function(answerItem) { 531 var matching = selectedItems.some(function(selectedItem) { 532 return answerItem.localeCompare(selectedItem) === 0; 533 }); 534 535 if(!matching) { 536 totalMatch = false; 537 } 538 }); 539 540 if(totalMatch) { 541 correct++; 542 result += correctText; 543 } else { 544 result += incorrectText; 545 } 546 } else { 547 result += incorrectText; 548 } 549 } else { 550 if (selectedItems.length > 0 && answer.localeCompare(selectedItems[0]) == 0) { 551 correct++; 552 result += correctText; 553 } else { 554 result += incorrectText; 555 } 556 } 557 } 558 } 559 } 560 561 result += '</p>'; 562 563 jQuery(questions[i]).hide(); 564 } 565 566 var status = []; 567 568 if(usingScoring) { 569 status.push(parent.attr('data-result-score-total').replace('$1', totalScore)); 570 } 571 572 if(usingCorrect) { 573 status.push(parent.attr('data-result-correct').replace('$1', correct).replace('$2', questionCount)); 574 } 575 576 result += '<p class="mikiop-quiz-result-total">' + status.join('<br>') + '</p>'; 577 578 parent.find('.mikiop-quiz-result').html(result).show(); 579 }); 580 581 jQuery('.mikiop-quiz-button-reset').on('click', function (event) { 582 quizReset(jQuery(this).closest('.mikiop-quiz')); 583 }); 584 585 // `Pagination 586 jQuery('.mikiop-pagination').each(function() { 587 var pagination = jQuery(this); 588 var startId = pagination.attr('data-start') || 'start'; 589 var pages = pagination.find('li:not(.mikiop-pagination-prev,.mikiop-pagination-next)'); 590 if (pages.length > 0) { 591 var active = -1; 592 var found = -1; 593 594 for (i = 0; i < pages.length; i++) { 595 if (jQuery(pages[i]).hasClass('mikiop-active')) { 596 if (active != -1) { 597 jQuery(pages[i]).removeClass('mikiop-active') 598 } else { 599 active = i; 600 } 601 } 602 603 var link = jQuery(pages[i]).find('a').attr('href'); 604 if(urlMatches(link, startId)) { 605 found = i; 606 } 607 } 608 609 if (active == -1 && found != -1) { 610 active = found; 611 jQuery(pages[found]).addClass('mikiop-active'); 612 } 613 614 if (active != -1) { 615 if (active == 0) { 616 jQuery('.mikiop-pagination').find('.mikiop-pagination-prev').addClass('mikiop-disabled'); 617 } else { 618 jQuery('.mikiop-pagination').find('.mikiop-pagination-prev').find('a').attr('href', jQuery(pages[active - 1]).find('a').attr('href')); 619 } 620 621 if (active == pages.length - 1) { 622 jQuery('.mikiop-pagination').find('.mikiop-pagination-next').addClass('mikiop-disabled'); 623 } else { 624 jQuery('.mikiop-pagination').find('.mikiop-pagination-next').find('a').attr('href', jQuery(pages[active + 1]).find('a').attr('href')); 625 } 626 } else { 627 jQuery('.mikiop-pagination').find('.mikiop-pagination-prev').addClass('mikiop-disabled'); 628 jQuery('.mikiop-pagination').find('.mikiop-pagination-next').addClass('mikiop-disabled'); 629 } 630 } else { 631 jQuery('.mikiop-pagination').find('.mikiop-pagination-prev').addClass('mikiop-disabled'); 632 jQuery('.mikiop-pagination').find('.mikiop-pagination-next').addClass('mikiop-disabled'); 633 } 634 }); 635 636 // Reveal 637 jQuery('.mikiop-box').on('mouseenter', function () { 638 jQuery(this).children('.mikiop-reveal').fadeOut(); 639 }); 640 641 jQuery('.mikiop-box').on('mouseleave', function () { 642 jQuery(this).children('.mikiop-reveal').fadeIn(); 643 }); 644 645 // Tooltip 646 jQuery('.mikiop-tooltip').hover(function (event) { 647 jQuery('<div class="mikiop-tooltip-banner">' + jQuery(this).attr('data-tooltip') + '</div>').appendTo('body'); 648 }, function () { 649 jQuery('.mikiop-tooltip-banner').remove(); 650 }); 651 652 jQuery('.mikiop-tooltip').on('mousemove', function (event) { 653 var moveLeft = 20; 654 var moveDown = 10; 655 jQuery('.mikiop-tooltip-banner').css('top', event.pageY + moveDown).css('left', event.pageX + moveLeft); 656 }); 657 658 // Nav 659 jQuery('.mikiop-nav').on('click', function (event) { 660 jQuery(this).toggleClass('mikiop-nav-open'); 661 }); 662 jQuery(document).on('click', function (event) { 663 if (!jQuery(event.target).closest('.mikiop-nav').length) { 664 // Hide the dropdown if clicked outside 665 jQuery('.mikiop-nav').removeClass('mikiop-nav-open'); 666 } 667 }); 668 669 jQuery('.mikiop-collapse').hide(); 670}); 671