xref: /plugin/combo/resources/snippet/js/combo-popover.js (revision 3ffa7219b3517087a95f60724d1c7fc6bb0e8573)
1
2window.combos = (function (module) {
3    module.popover = {
4        getDataNamespace: function () {
5            let defaultNamespace = "-bs";
6            let bootstrapVersion = 5;
7            if (typeof window.bootstrap.Popover.VERSION !== 'undefined') {
8                bootstrapVersion = parseInt(window.bootstrap.Popover.VERSION.substr(0, 1), 10);
9                if (bootstrapVersion < 5) {
10                    return "";
11                }
12                return defaultNamespace;
13            }
14            if (typeof jQuery != 'undefined' && typeof jQuery.fn.tooltip.constructor.VERSION !== 'undefined') {
15                bootstrapVersion = parseInt(jQuery.fn.tooltip.constructor.VERSION.substr(0, 1), 10);
16                if (bootstrapVersion < 5) {
17                    return "";
18                }
19                return defaultNamespace;
20            }
21            return defaultNamespace;
22        },
23        /**
24         *
25         * @param cssSelector - the popovers css selector to enable, if undefined, all
26         * element found with the `data[-bs]-toggle=popover` selector will be used
27         */
28        enable: function (cssSelector) {
29            let options = {};
30            if (typeof cssSelector === 'undefined') {
31                let namespace = this.getDataNamespace();
32                cssSelector = `[data${namespace}-toggle="popover"]`;
33            }
34            options.sanitize = false;
35            if (typeof window.bootstrap.Popover.VERSION !== 'undefined') {
36                document.querySelectorAll(cssSelector)
37                    .forEach(el => {
38                        let popover = window.bootstrap.Popover.getInstance(el);
39                        if (popover === null) {
40                            popover = new window.bootstrap.Popover(el, options);
41                        }
42                        el.onclick = (event) => {
43                            const popoverOnClick = window.bootstrap.Popover.getInstance(el)
44                            // to not navigate on `a` anchor
45                            event.preventDefault();
46                            // https://stackoverflow.com/a/70498530/297420
47                            const areaListener = new AbortController();
48                            // to dismiss the popover
49                            document.addEventListener(
50                                'mousedown',
51                                event => {
52                                    if (el.contains(event.target)) {
53                                        return;
54                                    }
55                                    const rootPopoverDomId = el.getAttribute("aria-describedby");
56                                    if (!rootPopoverDomId) {
57                                        areaListener.abort();
58                                        return;
59                                    }
60                                    const rootPopOverElement = document.getElementById(rootPopoverDomId);
61                                    if (!rootPopOverElement) {
62                                        areaListener.abort();
63                                        return;
64                                    }
65                                    if (rootPopOverElement.contains(event.target)) {
66                                        return;
67                                    }
68                                    popoverOnClick.hide();
69                                    areaListener.abort();
70                                },
71                                { signal: areaListener.signal }
72                            );
73                        };
74
75
76                    });
77                return;
78            }
79            if (typeof jQuery != 'undefined' && typeof jQuery.fn.tooltip.constructor.VERSION !== 'undefined') {
80                jQuery(cssSelector).popover(options);
81            }
82        }
83    }
84    return module;
85})(window.combos || {});
86