Convert `Bootstrap` to TypeScript
authorAlexander Ebert <ebert@woltlab.com>
Fri, 1 Jan 2021 11:45:43 +0000 (12:45 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Fri, 1 Jan 2021 11:45:43 +0000 (12:45 +0100)
global.d.ts
package-lock.json
package.json
wcfsetup/install/files/js/WoltLabSuite/Core/Bootstrap.js
wcfsetup/install/files/ts/WoltLabSuite/Core/Bootstrap.js [deleted file]
wcfsetup/install/files/ts/WoltLabSuite/Core/Bootstrap.ts [new file with mode: 0644]

index 45b8cc974343fadb8fbae6ec1724ecd77a2cfeb4..d2933f9fb0f6b911a7555cd5625627e3018e0e9a 100644 (file)
@@ -2,6 +2,7 @@ import DatePicker from "./wcfsetup/install/files/ts/WoltLabSuite/Core/Date/Picke
 import Devtools from "./wcfsetup/install/files/ts/WoltLabSuite/Core/Devtools";
 import DomUtil from "./wcfsetup/install/files/ts/WoltLabSuite/Core/Dom/Util";
 import * as ColorUtil from "./wcfsetup/install/files/ts/WoltLabSuite/Core/ColorUtil";
+import * as EventHandler from "./wcfsetup/install/files/ts/WoltLabSuite/Core/Event/Handler";
 import UiDropdownSimple from "./wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Dropdown/Simple";
 import "@woltlab/zxcvbn";
 import { Reaction } from "./wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Reaction/Data";
@@ -20,6 +21,7 @@ declare global {
     WCF_PATH: string;
     WSC_API_URL: string;
 
+    Favico: any;
     jQuery: JQueryStatic;
     WCF: any;
     bc_wcfDomUtil: typeof DomUtil;
@@ -27,6 +29,7 @@ declare global {
     __wcf_bc_colorPickerInit?: () => void;
     __wcf_bc_colorUtil: typeof ColorUtil;
     __wcf_bc_datePicker: typeof DatePicker;
+    __wcf_bc_eventHandler: typeof EventHandler;
   }
 
   interface String {
index be241647fe225974402be2d4a42963b5b8e94295..159f6b19cf0f00edfe081b5273dfe3374b77fba4 100644 (file)
       "resolved": "https://registry.npmjs.org/@types/facebook-js-sdk/-/facebook-js-sdk-3.3.1.tgz",
       "integrity": "sha512-jRVPdOu237QxDDoBjc9/xzGsDz75FmdvcwVZdCEg1AjHAQxGmXoHfACUyUVtz7DSWA4E+jgj5MQME4snjGwOng=="
     },
+    "@types/favico.js": {
+      "version": "0.0.28",
+      "resolved": "https://registry.npmjs.org/@types/favico.js/-/favico.js-0.0.28.tgz",
+      "integrity": "sha1-u3t8qhGCFzGNA0Zmkg1oeljWXus=",
+      "dev": true
+    },
     "@types/jquery": {
       "version": "3.5.4",
       "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.4.tgz",
index 24987ad4c3389858cbc835a2213cdb15c251a3f4..2c82ef942138f02bffe9334ce060219449c85c08 100644 (file)
@@ -2,6 +2,7 @@
   "name": "@woltlab/wcf",
   "version": "5.4.0",
   "devDependencies": {
+    "@types/favico.js": "0.0.28",
     "@types/perfect-scrollbar": "^0.6.1",
     "@typescript-eslint/eslint-plugin": "^4.6.0",
     "@typescript-eslint/parser": "^4.6.0",
index 6869385597a2e2cd5e4becabc5d87b5c106e5aa2..65bec3ba5ee5b09788f34e310fb0d97f175c9954 100644 (file)
  * @license  GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @module  WoltLabSuite/Core/Bootstrap
  */
-define([
-    "favico",
-    "perfect-scrollbar",
-    "WoltLabSuite/Core/Date/Time/Relative",
-    "Ui/SimpleDropdown",
-    "WoltLabSuite/Core/Ui/Mobile",
-    "WoltLabSuite/Core/Ui/TabMenu",
-    "WoltLabSuite/Core/Ui/FlexibleMenu",
-    "Ui/Dialog",
-    "WoltLabSuite/Core/Ui/Tooltip",
-    "WoltLabSuite/Core/Language",
-    "WoltLabSuite/Core/Environment",
-    "WoltLabSuite/Core/Date/Picker",
-    "EventHandler",
-    "Core",
-    "WoltLabSuite/Core/Ui/Page/Action",
-    "Devtools",
-    "Dom/ChangeListener",
-    "StringUtil"
-], function (favico, perfectScrollbar, DateTimeRelative, UiSimpleDropdown, UiMobile, UiTabMenu, UiFlexibleMenu, UiDialog, UiTooltip, Language, Environment, DatePicker, EventHandler, Core, UiPageAction, Devtools, DomChangeListener, StringUtil) {
+define(["require", "exports", "tslib", "./Core", "./Date/Picker", "./Date/Time/Relative", "./Devtools", "./Dom/Change/Listener", "./Environment", "./Event/Handler", "./Language", "./StringUtil", "./Ui/Dialog", "./Ui/Dropdown/Simple", "./Ui/Mobile", "./Ui/Page/Action", "./Ui/TabMenu", "./Ui/Tooltip", "favico.js"], function (require, exports, tslib_1, Core, Picker_1, DateTimeRelative, Devtools_1, Listener_1, Environment, EventHandler, Language, StringUtil, Dialog_1, Simple_1, UiMobile, UiPageAction, UiTabMenu, UiTooltip) {
     "use strict";
-    // perfectScrollbar does not need to be bound anywhere, it just has to be loaded for WCF.js
-    window.Favico = favico;
+    Object.defineProperty(exports, "__esModule", { value: true });
+    exports.setup = void 0;
+    Core = tslib_1.__importStar(Core);
+    Picker_1 = tslib_1.__importDefault(Picker_1);
+    DateTimeRelative = tslib_1.__importStar(DateTimeRelative);
+    Devtools_1 = tslib_1.__importDefault(Devtools_1);
+    Listener_1 = tslib_1.__importDefault(Listener_1);
+    Environment = tslib_1.__importStar(Environment);
+    EventHandler = tslib_1.__importStar(EventHandler);
+    Language = tslib_1.__importStar(Language);
+    StringUtil = tslib_1.__importStar(StringUtil);
+    Dialog_1 = tslib_1.__importDefault(Dialog_1);
+    Simple_1 = tslib_1.__importDefault(Simple_1);
+    UiMobile = tslib_1.__importStar(UiMobile);
+    UiPageAction = tslib_1.__importStar(UiPageAction);
+    UiTabMenu = tslib_1.__importStar(UiTabMenu);
+    UiTooltip = tslib_1.__importStar(UiTooltip);
     // non strict equals by intent
-    if (window.WCF == null)
+    if (window.WCF == null) {
         window.WCF = {};
-    if (window.WCF.Language == null)
+    }
+    if (window.WCF.Language == null) {
         window.WCF.Language = {};
+    }
     window.WCF.Language.get = Language.get;
     window.WCF.Language.add = Language.add;
     window.WCF.Language.addObject = Language.addObject;
     // WCF.System.Event compatibility
     window.__wcf_bc_eventHandler = EventHandler;
+    function initA11y() {
+        document
+            .querySelectorAll("nav:not([aria-label]):not([aria-labelledby]):not([role])")
+            .forEach((element) => {
+            element.setAttribute("role", "presentation");
+        });
+        document
+            .querySelectorAll("article:not([aria-label]):not([aria-labelledby]):not([role])")
+            .forEach((element) => {
+            element.setAttribute("role", "presentation");
+        });
+    }
     /**
-     * @exports  WoltLabSuite/Core/Bootstrap
+     * Initializes the core UI modifications and unblocks jQuery's ready event.
      */
-    return {
-        /**
-         * Initializes the core UI modifications and unblocks jQuery's ready event.
-         *
-         * @param       {Object=}       options         initialization options
-         */
-        setup: function (options) {
-            options = Core.extend({
-                enableMobileMenu: true
-            }, options);
-            StringUtil.setupI18n({
-                decimalPoint: Language.get("wcf.global.decimalPoint"),
-                thousandsSeparator: Language.get("wcf.global.thousandsSeparator")
-            });
-            //noinspection JSUnresolvedVariable
-            if (window.ENABLE_DEVELOPER_TOOLS)
-                Devtools._internal_.enable();
-            Environment.setup();
-            DateTimeRelative.setup();
-            DatePicker.init();
-            UiSimpleDropdown.setup();
-            UiMobile.setup(options.enableMobileMenu);
-            UiTabMenu.setup();
-            //UiFlexibleMenu.setup();
-            UiDialog.setup();
-            UiTooltip.setup();
-            // convert method=get into method=post
-            var forms = elBySelAll("form[method=get]");
-            for (var i = 0, length = forms.length; i < length; i++) {
-                forms[i].setAttribute("method", "post");
-            }
-            if (Environment.browser() === "microsoft") {
-                window.onbeforeunload = function () {
-                    /* Prevent "Back navigation caching" (http://msdn.microsoft.com/en-us/library/ie/dn265017%28v=vs.85%29.aspx) */
-                };
-            }
-            var interval = 0;
-            interval = window.setInterval(function () {
-                if (typeof window.jQuery === "function") {
-                    window.clearInterval(interval);
-                    // the 'jump to top' button triggers style recalculation/layout,
-                    // putting it at the end of the jQuery queue avoids trashing the
-                    // layout too early and thus delaying the page initialization
-                    window.jQuery(function () {
-                        UiPageAction.setup();
-                    });
-                    window.jQuery.holdReady(false);
-                }
-            }, 20);
-            this._initA11y();
-            DomChangeListener.add("WoltLabSuite/Core/Bootstrap", this._initA11y.bind(this));
-        },
-        _initA11y: function () {
-            elBySelAll("nav:not([aria-label]):not([aria-labelledby]):not([role])", undefined, function (element) {
-                elAttr(element, "role", "presentation");
-            });
-            elBySelAll("article:not([aria-label]):not([aria-labelledby]):not([role])", undefined, function (element) {
-                elAttr(element, "role", "presentation");
-            });
+    function setup(options) {
+        options = Core.extend({
+            enableMobileMenu: true,
+        }, options);
+        StringUtil.setupI18n({
+            decimalPoint: Language.get("wcf.global.decimalPoint"),
+            thousandsSeparator: Language.get("wcf.global.thousandsSeparator"),
+        });
+        if (window.ENABLE_DEVELOPER_TOOLS) {
+            Devtools_1.default._internal_.enable();
         }
-    };
+        Environment.setup();
+        DateTimeRelative.setup();
+        Picker_1.default.init();
+        Simple_1.default.setup();
+        UiMobile.setup(options.enableMobileMenu);
+        UiTabMenu.setup();
+        Dialog_1.default.setup();
+        UiTooltip.setup();
+        // Convert forms with `method="get"` into `method="post"`
+        document.querySelectorAll("form[method=get]").forEach((form) => {
+            form.method = "post";
+        });
+        if (Environment.browser() === "microsoft") {
+            window.onbeforeunload = () => {
+                /* Prevent "Back navigation caching" (http://msdn.microsoft.com/en-us/library/ie/dn265017%28v=vs.85%29.aspx) */
+            };
+        }
+        let interval = 0;
+        interval = window.setInterval(() => {
+            if (typeof window.jQuery === "function") {
+                window.clearInterval(interval);
+                // The 'jump to top' button triggers a style recalculation/"layout".
+                // Placing it at the end of the jQuery queue avoids trashing the
+                // layout too early and thus delaying the page initialization.
+                window.jQuery(() => {
+                    UiPageAction.setup();
+                });
+                window.jQuery.holdReady(false);
+            }
+        }, 20);
+        initA11y();
+        Listener_1.default.add("WoltLabSuite/Core/Bootstrap", () => initA11y);
+    }
+    exports.setup = setup;
 });
diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Bootstrap.js b/wcfsetup/install/files/ts/WoltLabSuite/Core/Bootstrap.js
deleted file mode 100644 (file)
index 2d9bfca..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * Bootstraps WCF's JavaScript.
- * It defines globals needed for backwards compatibility
- * and runs modules that are needed on page load.
- *
- * @author  Tim Duesterhus
- * @copyright  2001-2019 WoltLab GmbH
- * @license  GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module  WoltLabSuite/Core/Bootstrap
- */
-define(
-  [
-    "favico",
-    "perfect-scrollbar",
-    "WoltLabSuite/Core/Date/Time/Relative",
-    "Ui/SimpleDropdown",
-    "WoltLabSuite/Core/Ui/Mobile",
-    "WoltLabSuite/Core/Ui/TabMenu",
-    "WoltLabSuite/Core/Ui/FlexibleMenu",
-    "Ui/Dialog",
-    "WoltLabSuite/Core/Ui/Tooltip",
-    "WoltLabSuite/Core/Language",
-    "WoltLabSuite/Core/Environment",
-    "WoltLabSuite/Core/Date/Picker",
-    "EventHandler",
-    "Core",
-    "WoltLabSuite/Core/Ui/Page/Action",
-    "Devtools",
-    "Dom/ChangeListener",
-    "StringUtil"
-  ],
-  function(favico, perfectScrollbar, DateTimeRelative, UiSimpleDropdown, UiMobile, UiTabMenu, UiFlexibleMenu, UiDialog, UiTooltip, Language, Environment, DatePicker, EventHandler, Core, UiPageAction, Devtools, DomChangeListener, StringUtil) {
-    "use strict";
-    // perfectScrollbar does not need to be bound anywhere, it just has to be loaded for WCF.js
-    window.Favico = favico;
-    // non strict equals by intent
-    if (window.WCF == null) window.WCF = {};
-    if (window.WCF.Language == null) window.WCF.Language = {};
-    window.WCF.Language.get = Language.get;
-    window.WCF.Language.add = Language.add;
-    window.WCF.Language.addObject = Language.addObject;
-    // WCF.System.Event compatibility
-    window.__wcf_bc_eventHandler = EventHandler;
-    
-    /**
-     * @exports  WoltLabSuite/Core/Bootstrap
-     */
-    return {
-      /**
-       * Initializes the core UI modifications and unblocks jQuery's ready event.
-       *
-       * @param       {Object=}       options         initialization options
-       */
-      setup: function(options) {
-        options = Core.extend({
-          enableMobileMenu: true
-        }, options);
-        
-        StringUtil.setupI18n({
-          decimalPoint: Language.get("wcf.global.decimalPoint"),
-          thousandsSeparator: Language.get("wcf.global.thousandsSeparator")
-        });
-        
-        //noinspection JSUnresolvedVariable
-        if (window.ENABLE_DEVELOPER_TOOLS) Devtools._internal_.enable();
-        Environment.setup();
-        DateTimeRelative.setup();
-        DatePicker.init();
-        UiSimpleDropdown.setup();
-        UiMobile.setup(options.enableMobileMenu);
-        UiTabMenu.setup();
-        //UiFlexibleMenu.setup();
-        UiDialog.setup();
-        UiTooltip.setup();
-        // convert method=get into method=post
-        var forms = elBySelAll("form[method=get]");
-        for (var i = 0, length = forms.length; i < length; i++) {
-          forms[i].setAttribute("method", "post");
-        }
-        if (Environment.browser() === "microsoft") {
-          window.onbeforeunload = function() {
-            /* Prevent "Back navigation caching" (http://msdn.microsoft.com/en-us/library/ie/dn265017%28v=vs.85%29.aspx) */
-          };
-        }
-        var interval = 0;
-        interval = window.setInterval(function() {
-          if (typeof window.jQuery === "function") {
-            window.clearInterval(interval);
-            // the 'jump to top' button triggers style recalculation/layout,
-            // putting it at the end of the jQuery queue avoids trashing the
-            // layout too early and thus delaying the page initialization
-            window.jQuery(function() {
-              UiPageAction.setup();
-            });
-            window.jQuery.holdReady(false);
-          }
-        }, 20);
-        this._initA11y();
-        DomChangeListener.add("WoltLabSuite/Core/Bootstrap", this._initA11y.bind(this));
-      },
-      _initA11y: function() {
-        elBySelAll("nav:not([aria-label]):not([aria-labelledby]):not([role])", undefined, function(element) {
-          elAttr(element, "role", "presentation");
-        });
-        elBySelAll("article:not([aria-label]):not([aria-labelledby]):not([role])", undefined, function(element) {
-          elAttr(element, "role", "presentation");
-        });
-      }
-    };
-  }
-);
diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Bootstrap.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Bootstrap.ts
new file mode 100644 (file)
index 0000000..0bde2bb
--- /dev/null
@@ -0,0 +1,124 @@
+/**
+ * Bootstraps WCF's JavaScript.
+ * It defines globals needed for backwards compatibility
+ * and runs modules that are needed on page load.
+ *
+ * @author  Tim Duesterhus
+ * @copyright  2001-2019 WoltLab GmbH
+ * @license  GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module  WoltLabSuite/Core/Bootstrap
+ */
+
+import * as Core from "./Core";
+import DatePicker from "./Date/Picker";
+import * as DateTimeRelative from "./Date/Time/Relative";
+import Devtools from "./Devtools";
+import DomChangeListener from "./Dom/Change/Listener";
+import * as Environment from "./Environment";
+import * as EventHandler from "./Event/Handler";
+import * as Language from "./Language";
+import * as StringUtil from "./StringUtil";
+import UiDialog from "./Ui/Dialog";
+import UiDropdownSimple from "./Ui/Dropdown/Simple";
+import * as UiMobile from "./Ui/Mobile";
+import * as UiPageAction from "./Ui/Page/Action";
+import * as UiTabMenu from "./Ui/TabMenu";
+import * as UiTooltip from "./Ui/Tooltip";
+
+// Import favico.js into the global namespace.
+import "favico.js";
+
+// perfectScrollbar does not need to be bound anywhere, it just has to be loaded for WCF.js
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+import perfectScrollbar from "perfect-scrollbar";
+
+// non strict equals by intent
+if (window.WCF == null) {
+  window.WCF = {};
+}
+if (window.WCF.Language == null) {
+  window.WCF.Language = {};
+}
+window.WCF.Language.get = Language.get;
+window.WCF.Language.add = Language.add;
+window.WCF.Language.addObject = Language.addObject;
+// WCF.System.Event compatibility
+window.__wcf_bc_eventHandler = EventHandler;
+
+interface BoostrapOptions {
+  enableMobileMenu: boolean;
+}
+
+function initA11y() {
+  document
+    .querySelectorAll("nav:not([aria-label]):not([aria-labelledby]):not([role])")
+    .forEach((element: HTMLElement) => {
+      element.setAttribute("role", "presentation");
+    });
+
+  document
+    .querySelectorAll("article:not([aria-label]):not([aria-labelledby]):not([role])")
+    .forEach((element: HTMLElement) => {
+      element.setAttribute("role", "presentation");
+    });
+}
+
+/**
+ * Initializes the core UI modifications and unblocks jQuery's ready event.
+ */
+export function setup(options: BoostrapOptions): void {
+  options = Core.extend(
+    {
+      enableMobileMenu: true,
+    },
+    options,
+  ) as BoostrapOptions;
+
+  StringUtil.setupI18n({
+    decimalPoint: Language.get("wcf.global.decimalPoint"),
+    thousandsSeparator: Language.get("wcf.global.thousandsSeparator"),
+  });
+
+  if (window.ENABLE_DEVELOPER_TOOLS) {
+    Devtools._internal_.enable();
+  }
+
+  Environment.setup();
+  DateTimeRelative.setup();
+  DatePicker.init();
+  UiDropdownSimple.setup();
+  UiMobile.setup(options.enableMobileMenu);
+  UiTabMenu.setup();
+  UiDialog.setup();
+  UiTooltip.setup();
+
+  // Convert forms with `method="get"` into `method="post"`
+  document.querySelectorAll("form[method=get]").forEach((form: HTMLFormElement) => {
+    form.method = "post";
+  });
+
+  if (Environment.browser() === "microsoft") {
+    window.onbeforeunload = () => {
+      /* Prevent "Back navigation caching" (http://msdn.microsoft.com/en-us/library/ie/dn265017%28v=vs.85%29.aspx) */
+    };
+  }
+
+  let interval = 0;
+  interval = window.setInterval(() => {
+    if (typeof window.jQuery === "function") {
+      window.clearInterval(interval);
+
+      // The 'jump to top' button triggers a style recalculation/"layout".
+      // Placing it at the end of the jQuery queue avoids trashing the
+      // layout too early and thus delaying the page initialization.
+      window.jQuery(() => {
+        UiPageAction.setup();
+      });
+      window.jQuery.holdReady(false);
+    }
+  }, 20);
+
+  initA11y();
+
+  DomChangeListener.add("WoltLabSuite/Core/Bootstrap", () => initA11y);
+}