Proyectos de Subversion Moodle

Rev

Rev 11 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
// This file is part of Moodle - http://moodle.org/
2
//
3
// Moodle is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, either version 3 of the License, or
6
// (at your option) any later version.
7
//
8
// Moodle is distributed in the hope that it will be useful,
9
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
// GNU General Public License for more details.
12
//
13
// You should have received a copy of the GNU General Public License
14
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
15
 
16
/**
17
 * Javascript popover for the `core_calendar` subsystem.
18
 *
19
 * @module core_calendar/popover
20
 * @copyright 2021 Huong Nguyen <huongnv13@gmail.com>
21
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22
 * @since 4.0
23
 */
24
 
1441 ariadna 25
import Popover from 'theme_boost/bootstrap/popover';
1 efrain 26
import * as CalendarSelectors from 'core_calendar/selectors';
27
 
28
/**
29
 * Check if we are allowing to enable the popover or not.
30
 * @param {Element} dateContainer
31
 * @returns {boolean}
32
 */
33
const isPopoverAvailable = (dateContainer) => {
34
    return window.getComputedStyle(dateContainer.querySelector(CalendarSelectors.elements.dateContent)).display === 'none';
35
};
36
 
37
const isPopoverConfigured = new Map();
38
const showPopover = target => {
39
    const dateContainer = target.closest(CalendarSelectors.elements.dateContainer);
40
    if (!isPopoverConfigured.has(dateContainer)) {
1441 ariadna 41
        const config = {
1 efrain 42
            trigger: 'manual',
43
            placement: 'top',
44
            html: true,
45
            title: dateContainer.dataset.title,
46
            content: () => {
1441 ariadna 47
                const source = dateContainer.querySelector(CalendarSelectors.elements.dateContent);
48
                return source ? source.querySelector('.hidden').innerHTML : '';
11 efrain 49
            },
50
            'animation': false,
1441 ariadna 51
        };
52
        new Popover(target, config);
1 efrain 53
 
54
        isPopoverConfigured.set(dateContainer, true);
55
    }
56
 
57
    if (isPopoverAvailable(dateContainer)) {
1441 ariadna 58
        Popover.getInstance(target).show();
1 efrain 59
        target.addEventListener('mouseleave', hidePopover);
60
        target.addEventListener('focusout', hidePopover);
11 efrain 61
        // Set up the hide function to the click event type.
62
        target.addEventListener('click', hidePopover);
1 efrain 63
    }
64
};
65
 
66
const hidePopover = e => {
67
    const target = e.target;
68
    const dateContainer = e.target.closest(CalendarSelectors.elements.dateContainer);
69
    if (!dateContainer) {
70
        return;
71
    }
72
    if (isPopoverConfigured.has(dateContainer)) {
73
        const isTargetActive = target.contains(document.activeElement);
74
        const isTargetHover = target.matches(':hover');
11 efrain 75
 
76
        // Checks if a target element is clicked or pressed.
77
        const isTargetClicked = document.activeElement.contains(target);
78
 
79
        let removeListener = true;
1 efrain 80
        if (!isTargetActive && !isTargetHover) {
1441 ariadna 81
            Popover.getOrCreateInstance(target).hide();
11 efrain 82
        } else if (isTargetClicked) {
1441 ariadna 83
            Popover.getOrCreateInstance(document.activeElement).hide();
11 efrain 84
        } else {
85
            removeListener = false;
86
        }
87
 
88
        if (removeListener) {
1 efrain 89
            target.removeEventListener('mouseleave', hidePopover);
90
            target.removeEventListener('focusout', hidePopover);
11 efrain 91
            target.removeEventListener('click', hidePopover);
1 efrain 92
        }
93
    }
94
};
95
 
96
/**
97
 * Register events for date container.
98
 */
99
const registerEventListeners = () => {
100
    const showPopoverHandler = (e) => {
101
        const dayLink = e.target.closest(CalendarSelectors.links.dayLink);
102
        if (!dayLink) {
103
            return;
104
        }
105
 
106
        e.preventDefault();
107
        showPopover(dayLink);
108
    };
109
 
110
    document.addEventListener('mouseover', showPopoverHandler);
111
    document.addEventListener('focusin', showPopoverHandler);
112
};
113
 
114
let listenersRegistered = false;
115
if (!listenersRegistered) {
116
    registerEventListeners();
117
    listenersRegistered = true;
118
}