| 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 |  * Template renderer for Moodle. Load and render Moodle templates with Mustache.
 | 
        
           |  |  | 18 |  *
 | 
        
           |  |  | 19 |  * @module     theme_universe/loader
 | 
        
           |  |  | 20 |  * @copyright  2015 Damyon Wiese <damyon@moodle.com>
 | 
        
           |  |  | 21 |  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 | 
        
           |  |  | 22 |  * @since      2.9
 | 
        
           |  |  | 23 |  */
 | 
        
           |  |  | 24 |   | 
        
           |  |  | 25 | import $ from 'jquery';
 | 
        
           |  |  | 26 | import * as Aria from './aria';
 | 
        
           |  |  | 27 | import Bootstrap from './index';
 | 
        
           |  |  | 28 | import Pending from 'core/pending';
 | 
        
           |  |  | 29 | import {DefaultWhitelist} from './bootstrap/tools/sanitizer';
 | 
        
           |  |  | 30 | import setupBootstrapPendingChecks from './pending';
 | 
        
           |  |  | 31 |   | 
        
           |  |  | 32 | /**
 | 
        
           |  |  | 33 |  * Rember the last visited tabs.
 | 
        
           |  |  | 34 |  */
 | 
        
           |  |  | 35 | const rememberTabs = () => {
 | 
        
           |  |  | 36 |     $('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
 | 
        
           |  |  | 37 |         var hash = $(e.target).attr('href');
 | 
        
           |  |  | 38 |         if (history.replaceState) {
 | 
        
           |  |  | 39 |             history.replaceState(null, null, hash);
 | 
        
           |  |  | 40 |         } else {
 | 
        
           |  |  | 41 |             location.hash = hash;
 | 
        
           |  |  | 42 |         }
 | 
        
           |  |  | 43 |     });
 | 
        
           |  |  | 44 |     const hash = window.location.hash;
 | 
        
           |  |  | 45 |     if (hash) {
 | 
        
           |  |  | 46 |         const tab = document.querySelector('[role="tablist"] [href="' + hash + '"]');
 | 
        
           |  |  | 47 |         if (tab) {
 | 
        
           |  |  | 48 |             tab.click();
 | 
        
           |  |  | 49 |         }
 | 
        
           |  |  | 50 |     }
 | 
        
           |  |  | 51 | };
 | 
        
           |  |  | 52 |   | 
        
           |  |  | 53 | /**
 | 
        
           |  |  | 54 |  * Enable all popovers
 | 
        
           |  |  | 55 |  *
 | 
        
           |  |  | 56 |  */
 | 
        
           |  |  | 57 | const enablePopovers = () => {
 | 
        
           |  |  | 58 |     $('body').popover({
 | 
        
           |  |  | 59 |         container: 'body',
 | 
        
           |  |  | 60 |         selector: '[data-toggle="popover"]',
 | 
        
           |  |  | 61 |         trigger: 'focus',
 | 
        
           |  |  | 62 |         whitelist: Object.assign(DefaultWhitelist, {
 | 
        
           |  |  | 63 |             table: [],
 | 
        
           |  |  | 64 |             thead: [],
 | 
        
           |  |  | 65 |             tbody: [],
 | 
        
           |  |  | 66 |             tr: [],
 | 
        
           |  |  | 67 |             th: [],
 | 
        
           |  |  | 68 |             td: [],
 | 
        
           |  |  | 69 |         }),
 | 
        
           |  |  | 70 |     });
 | 
        
           |  |  | 71 |   | 
        
           |  |  | 72 |     document.addEventListener('keydown', e => {
 | 
        
           |  |  | 73 |         if (e.key === 'Escape' && e.target.closest('[data-toggle="popover"]')) {
 | 
        
           |  |  | 74 |             $(e.target).popover('hide');
 | 
        
           |  |  | 75 |         }
 | 
        
           |  |  | 76 |     });
 | 
        
           |  |  | 77 | };
 | 
        
           |  |  | 78 |   | 
        
           |  |  | 79 | /**
 | 
        
           |  |  | 80 |  * Enable tooltips
 | 
        
           |  |  | 81 |  *
 | 
        
           |  |  | 82 |  */
 | 
        
           |  |  | 83 | const enableTooltips = () => {
 | 
        
           |  |  | 84 |     $('body').tooltip({
 | 
        
           |  |  | 85 |         container: 'body',
 | 
        
           |  |  | 86 |         selector: '[data-toggle="tooltip"]',
 | 
        
           |  |  | 87 |     });
 | 
        
           |  |  | 88 | };
 | 
        
           |  |  | 89 |   | 
        
           |  |  | 90 | const pendingPromise = new Pending('theme_universe/loader:init');
 | 
        
           |  |  | 91 |   | 
        
           |  |  | 92 | // Add pending promise event listeners to relevant Bootstrap custom events.
 | 
        
           |  |  | 93 | setupBootstrapPendingChecks();
 | 
        
           |  |  | 94 |   | 
        
           |  |  | 95 | // Setup Aria helpers for Bootstrap features.
 | 
        
           |  |  | 96 | Aria.init();
 | 
        
           |  |  | 97 |   | 
        
           |  |  | 98 | // Remember the last visited tabs.
 | 
        
           |  |  | 99 | rememberTabs();
 | 
        
           |  |  | 100 |   | 
        
           |  |  | 101 | // Enable all popovers.
 | 
        
           |  |  | 102 | enablePopovers();
 | 
        
           |  |  | 103 |   | 
        
           |  |  | 104 | // Enable all tooltips.
 | 
        
           |  |  | 105 | enableTooltips();
 | 
        
           |  |  | 106 |   | 
        
           |  |  | 107 | // Disables flipping the dropdowns up or dynamically repositioning them along the Y-axis (based on the viewport)
 | 
        
           |  |  | 108 | // to prevent the dropdowns getting hidden behind the navbar or them covering the trigger element.
 | 
        
           |  |  | 109 | $.fn.dropdown.Constructor.Default.popperConfig = {
 | 
        
           |  |  | 110 |     modifiers: {
 | 
        
           |  |  | 111 |         flip: {
 | 
        
           |  |  | 112 |             enabled: false,
 | 
        
           |  |  | 113 |         },
 | 
        
           |  |  | 114 |         storeTopPosition: {
 | 
        
           |  |  | 115 |             enabled: true,
 | 
        
           |  |  | 116 |             // eslint-disable-next-line no-unused-vars
 | 
        
           |  |  | 117 |             fn(data, options) {
 | 
        
           |  |  | 118 |                 data.storedTop = data.offsets.popper.top;
 | 
        
           |  |  | 119 |                 return data;
 | 
        
           |  |  | 120 |             },
 | 
        
           |  |  | 121 |             order: 299
 | 
        
           |  |  | 122 |         },
 | 
        
           |  |  | 123 |         restoreTopPosition: {
 | 
        
           |  |  | 124 |             enabled: true,
 | 
        
           |  |  | 125 |             // eslint-disable-next-line no-unused-vars
 | 
        
           |  |  | 126 |             fn(data, options) {
 | 
        
           |  |  | 127 |                 data.offsets.popper.top = data.storedTop;
 | 
        
           |  |  | 128 |                 return data;
 | 
        
           |  |  | 129 |             },
 | 
        
           |  |  | 130 |             order: 301
 | 
        
           |  |  | 131 |         }
 | 
        
           |  |  | 132 |     },
 | 
        
           |  |  | 133 | };
 | 
        
           |  |  | 134 |   | 
        
           |  |  | 135 | pendingPromise.resolve();
 | 
        
           |  |  | 136 |   | 
        
           |  |  | 137 | export {
 | 
        
           |  |  | 138 |     Bootstrap,
 | 
        
           |  |  | 139 | };
 |