Move the reCAPTCHA widget overlay to the `pageOverlayContainer` when widget form...
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / js / WoltLabSuite / Core / Bootstrap.js
CommitLineData
a3a09eff
TD
1/**
2 * Bootstraps WCF's JavaScript.
3 * It defines globals needed for backwards compatibility
4 * and runs modules that are needed on page load.
50aa3a01 5 *
95418cc6 6 * @author Tim Duesterhus
edcc45a2 7 * @copyright 2001-2023 WoltLab GmbH
95418cc6 8 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
a3a09eff 9 */
b8ef3d4c 10define(["require", "exports", "tslib", "./Core", "./Date/Picker", "./Devtools", "./Dom/Change/Listener", "./Environment", "./Event/Handler", "./Form/XsrfToken", "./Language", "./Ui/Dialog", "./Ui/Dropdown/Simple", "./Ui/Mobile", "./Ui/Page/Action", "./Ui/TabMenu", "./Ui/Tooltip", "./Ui/Page/JumpTo", "./Ui/Password", "./Ui/Empty", "./Ui/Object/Action", "./Ui/Object/Action/Delete", "./Ui/Object/Action/Toggle", "./Ui/Search", "./LazyLoader", "./Helper/PageOverlay", "perfect-scrollbar"], function (require, exports, tslib_1, Core, Picker_1, Devtools_1, Listener_1, Environment, EventHandler, XsrfToken, Language, Dialog_1, Simple_1, UiMobile, UiPageAction, UiTabMenu, UiTooltip, UiPageJumpTo, UiPassword, UiEmpty, UiObjectAction, UiObjectActionDelete, UiObjectActionToggle, Search_1, LazyLoader_1, PageOverlay_1) {
50aa3a01 11 "use strict";
93fdc495
AE
12 Object.defineProperty(exports, "__esModule", { value: true });
13 exports.setup = void 0;
716617cf
TD
14 Core = tslib_1.__importStar(Core);
15 Picker_1 = tslib_1.__importDefault(Picker_1);
716617cf
TD
16 Devtools_1 = tslib_1.__importDefault(Devtools_1);
17 Listener_1 = tslib_1.__importDefault(Listener_1);
18 Environment = tslib_1.__importStar(Environment);
19 EventHandler = tslib_1.__importStar(EventHandler);
1efd0b8b 20 XsrfToken = tslib_1.__importStar(XsrfToken);
716617cf 21 Language = tslib_1.__importStar(Language);
716617cf
TD
22 Dialog_1 = tslib_1.__importDefault(Dialog_1);
23 Simple_1 = tslib_1.__importDefault(Simple_1);
24 UiMobile = tslib_1.__importStar(UiMobile);
25 UiPageAction = tslib_1.__importStar(UiPageAction);
26 UiTabMenu = tslib_1.__importStar(UiTabMenu);
27 UiTooltip = tslib_1.__importStar(UiTooltip);
28 UiPageJumpTo = tslib_1.__importStar(UiPageJumpTo);
29 UiPassword = tslib_1.__importStar(UiPassword);
30 UiEmpty = tslib_1.__importStar(UiEmpty);
31 UiObjectAction = tslib_1.__importStar(UiObjectAction);
32 UiObjectActionDelete = tslib_1.__importStar(UiObjectActionDelete);
33 UiObjectActionToggle = tslib_1.__importStar(UiObjectActionToggle);
50aa3a01 34 // non strict equals by intent
93fdc495 35 if (window.WCF == null) {
50aa3a01 36 window.WCF = {};
93fdc495
AE
37 }
38 if (window.WCF.Language == null) {
50aa3a01 39 window.WCF.Language = {};
93fdc495 40 }
50aa3a01
TD
41 window.WCF.Language.get = Language.get;
42 window.WCF.Language.add = Language.add;
43 window.WCF.Language.addObject = Language.addObject;
44 // WCF.System.Event compatibility
45 window.__wcf_bc_eventHandler = EventHandler;
93fdc495
AE
46 function initA11y() {
47 document
48 .querySelectorAll("nav:not([aria-label]):not([aria-labelledby]):not([role])")
49 .forEach((element) => {
50 element.setAttribute("role", "presentation");
51 });
52 document
53 .querySelectorAll("article:not([aria-label]):not([aria-labelledby]):not([role])")
54 .forEach((element) => {
55 element.setAttribute("role", "presentation");
56 });
57 }
50aa3a01 58 /**
93fdc495 59 * Initializes the core UI modifications and unblocks jQuery's ready event.
50aa3a01 60 */
93fdc495
AE
61 function setup(options) {
62 options = Core.extend({
0165cb0e 63 colorScheme: "light",
93fdc495 64 enableMobileMenu: true,
c7bacb86 65 pageMenuMainProvider: undefined,
93fdc495 66 }, options);
e40d3148 67 XsrfToken.setup();
93fdc495
AE
68 if (window.ENABLE_DEVELOPER_TOOLS) {
69 Devtools_1.default._internal_.enable();
50aa3a01 70 }
c7b9c92a 71 (0, PageOverlay_1.adoptPageOverlayContainer)(document.body);
93fdc495 72 Environment.setup();
93fdc495
AE
73 Picker_1.default.init();
74 Simple_1.default.setup();
c7bacb86 75 UiMobile.setup(options.enableMobileMenu, options.pageMenuMainProvider);
93fdc495
AE
76 UiTabMenu.setup();
77 Dialog_1.default.setup();
78 UiTooltip.setup();
3eb03c87 79 UiPassword.setup();
44ecc27f 80 UiEmpty.setup();
1d810709
MS
81 UiObjectAction.setup();
82 UiObjectActionDelete.setup();
83 UiObjectActionToggle.setup();
8267194f 84 (0, Search_1.init)();
93fdc495
AE
85 // Convert forms with `method="get"` into `method="post"`
86 document.querySelectorAll("form[method=get]").forEach((form) => {
87 form.method = "post";
88 });
89 if (Environment.browser() === "microsoft") {
90 window.onbeforeunload = () => {
91 /* Prevent "Back navigation caching" (http://msdn.microsoft.com/en-us/library/ie/dn265017%28v=vs.85%29.aspx) */
92 };
93 }
94 let interval = 0;
95 interval = window.setInterval(() => {
96 if (typeof window.jQuery === "function") {
97 window.clearInterval(interval);
98 // The 'jump to top' button triggers a style recalculation/"layout".
99 // Placing it at the end of the jQuery queue avoids trashing the
100 // layout too early and thus delaying the page initialization.
101 window.jQuery(() => {
102 UiPageAction.setup();
103 });
dce90297
AE
104 // jQuery.browser.mobile is a deprecated legacy property that was used
105 // to determine the class of devices being used.
106 const jq = window.jQuery;
107 jq.browser = jq.browser || {};
108 jq.browser.mobile = Environment.platform() !== "desktop";
93fdc495
AE
109 window.jQuery.holdReady(false);
110 }
111 }, 20);
a1dfdada 112 document.querySelectorAll(".pagination").forEach((el) => UiPageJumpTo.init(el));
8f7273ff
AE
113 window.requestAnimationFrame(() => {
114 const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
115 document.documentElement.style.setProperty("--scrollbar-width", `${scrollbarWidth}px`);
116 });
93fdc495
AE
117 initA11y();
118 Listener_1.default.add("WoltLabSuite/Core/Bootstrap", () => initA11y);
d732bab3
AE
119 if (options.dynamicColorScheme) {
120 void new Promise((resolve_1, reject_1) => { require(["./Controller/Style/ColorScheme"], resolve_1, reject_1); }).then(tslib_1.__importStar).then(({ setup }) => {
121 setup();
122 });
0165cb0e 123 }
a31f5145 124 (0, LazyLoader_1.whenFirstSeen)("[data-report-content]", () => {
0165cb0e 125 void new Promise((resolve_2, reject_2) => { require(["./Ui/Moderation/Report"], resolve_2, reject_2); }).then(tslib_1.__importStar).then(({ setup }) => setup());
a31f5145 126 });
c46884fe 127 (0, LazyLoader_1.whenFirstSeen)("woltlab-core-pagination", () => {
0165cb0e 128 void new Promise((resolve_3, reject_3) => { require(["./Ui/Pagination/JumpToPage"], resolve_3, reject_3); }).then(tslib_1.__importStar).then(({ setup }) => setup());
c46884fe 129 });
ad7b029b 130 (0, LazyLoader_1.whenFirstSeen)("woltlab-core-google-maps", () => {
0165cb0e 131 void new Promise((resolve_4, reject_4) => { require(["./Component/GoogleMaps/woltlab-core-google-maps"], resolve_4, reject_4); }).then(tslib_1.__importStar);
ad7b029b 132 });
9a6f0a59 133 (0, LazyLoader_1.whenFirstSeen)("[data-google-maps-geocoding]", () => {
0165cb0e 134 void new Promise((resolve_5, reject_5) => { require(["./Component/GoogleMaps/Geocoding"], resolve_5, reject_5); }).then(tslib_1.__importStar).then(({ setup }) => setup());
9a6f0a59 135 });
457b8907
C
136 // Move the reCAPTCHA widget overlay to the `pageOverlayContainer`
137 // when widget form elements are placed in a dialog.
138 const observer = new MutationObserver((mutations) => {
139 for (const mutation of mutations) {
140 for (const node of mutation.addedNodes) {
141 if (!(node instanceof HTMLElement)) {
142 continue;
143 }
144 if (node.querySelectorAll(".g-recaptcha-bubble-arrow").length === 0) {
145 return;
146 }
147 const iframe = node.querySelector("iframe");
148 if (!iframe) {
149 return;
150 }
151 const name = "a-" + iframe.name.split("-")[1];
152 const widget = document.querySelector(`iframe[name="${name}"]`);
153 if (!widget) {
154 return;
155 }
156 const dialog = widget.closest("woltlab-core-dialog");
157 if (!dialog) {
158 return;
159 }
160 (0, PageOverlay_1.getPageOverlayContainer)().append(node);
161 node.classList.add("g-recaptcha-container");
162 }
163 }
164 });
165 observer.observe(document.body, {
166 childList: true,
167 });
93fdc495
AE
168 }
169 exports.setup = setup;
a3a09eff 170});