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