Convert `Bbcode/Collapsible` to TypeScript
authorAlexander Ebert <ebert@woltlab.com>
Sat, 2 Jan 2021 13:16:01 +0000 (14:16 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Sat, 2 Jan 2021 13:16:01 +0000 (14:16 +0100)
wcfsetup/install/files/js/WoltLabSuite/Core/Bbcode/Collapsible.js
wcfsetup/install/files/ts/WoltLabSuite/Core/Bbcode/Collapsible.js [deleted file]
wcfsetup/install/files/ts/WoltLabSuite/Core/Bbcode/Collapsible.ts [new file with mode: 0644]

index f86e20feb548b2666357481fb8f2cc4e44b0f3cb..0e35100716748966dd2ef2858c707a4a6644af6f 100644 (file)
@@ -1,88 +1,86 @@
 /**
  * Generic handler for collapsible bbcode boxes.
  *
- * @author     Alexander Ebert
- * @copyright  2001-2019 WoltLab GmbH
- * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module     WoltLabSuite/Core/Bbcode/Collapsible
+ * @author  Alexander Ebert
+ * @copyright  2001-2019 WoltLab GmbH
+ * @license  GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module  WoltLabSuite/Core/Bbcode/Collapsible
  */
-define([], function () {
+define(["require", "exports"], function (require, exports) {
     "use strict";
-    var _containers = elByClass('jsCollapsibleBbcode');
-    /**
-     * @exports        WoltLabSuite/Core/Bbcode/Collapsible
-     */
-    return {
-        observe: function () {
-            var container, toggleButtons, overflowContainer;
-            while (_containers.length) {
-                container = _containers[0];
-                // find the matching toggle button
-                toggleButtons = [];
-                elBySelAll('.toggleButton:not(.jsToggleButtonEnabled)', container, function (button) {
-                    //noinspection JSReferencingMutableVariableFromClosure
-                    if (button.closest('.jsCollapsibleBbcode') === container) {
-                        toggleButtons.push(button);
+    Object.defineProperty(exports, "__esModule", { value: true });
+    exports.observe = void 0;
+    function initContainer(container, toggleButtons, overflowContainer) {
+        toggleButtons.forEach((toggleButton) => {
+            toggleButton.classList.add("jsToggleButtonEnabled");
+            toggleButton.addEventListener("click", (ev) => toggleContainer(container, toggleButtons, ev));
+        });
+        // expand boxes that are initially scrolled
+        if (overflowContainer.scrollTop !== 0) {
+            overflowContainer.scrollTop = 0;
+            toggleContainer(container, toggleButtons);
+        }
+        overflowContainer.addEventListener("scroll", () => {
+            overflowContainer.scrollTop = 0;
+            if (container.classList.contains("collapsed")) {
+                toggleContainer(container, toggleButtons);
+            }
+        });
+    }
+    function toggleContainer(container, toggleButtons, event) {
+        if (container.classList.toggle("collapsed")) {
+            toggleButtons.forEach((toggleButton) => {
+                const title = toggleButton.dataset.titleExpand;
+                if (toggleButton.classList.contains("icon")) {
+                    toggleButton.classList.remove("fa-compress");
+                    toggleButton.classList.add("fa-expand");
+                    toggleButton.title = title;
+                }
+                else {
+                    toggleButton.textContent = title;
+                }
+            });
+            if (event instanceof Event) {
+                // negative top value means the upper boundary is not within the viewport
+                const top = container.getBoundingClientRect().top;
+                if (top < 0) {
+                    let y = window.pageYOffset + (top - 100);
+                    if (y < 0) {
+                        y = 0;
                     }
-                });
-                overflowContainer = elBySel('.collapsibleBbcodeOverflow', container) || container;
-                if (toggleButtons.length > 0) {
-                    (function (container, toggleButtons) {
-                        var toggle = function (event) {
-                            if (container.classList.toggle('collapsed')) {
-                                toggleButtons.forEach(function (toggleButton) {
-                                    if (toggleButton.classList.contains('icon')) {
-                                        toggleButton.classList.remove('fa-compress');
-                                        toggleButton.classList.add('fa-expand');
-                                        toggleButton.title = elData(toggleButton, 'title-expand');
-                                    }
-                                    else {
-                                        toggleButton.textContent = elData(toggleButton, 'title-expand');
-                                    }
-                                });
-                                if (event instanceof Event) {
-                                    // negative top value means the upper boundary is not within the viewport
-                                    var top = container.getBoundingClientRect().top;
-                                    if (top < 0) {
-                                        var y = window.pageYOffset + (top - 100);
-                                        if (y < 0)
-                                            y = 0;
-                                        window.scrollTo(window.pageXOffset, y);
-                                    }
-                                }
-                            }
-                            else {
-                                toggleButtons.forEach(function (toggleButton) {
-                                    if (toggleButton.classList.contains('icon')) {
-                                        toggleButton.classList.add('fa-compress');
-                                        toggleButton.classList.remove('fa-expand');
-                                        toggleButton.title = elData(toggleButton, 'title-collapse');
-                                    }
-                                    else {
-                                        toggleButton.textContent = elData(toggleButton, 'title-collapse');
-                                    }
-                                });
-                            }
-                        };
-                        toggleButtons.forEach(function (toggleButton) {
-                            toggleButton.classList.add('jsToggleButtonEnabled');
-                            toggleButton.addEventListener('click', toggle);
-                        });
-                        // expand boxes that are initially scrolled
-                        if (overflowContainer.scrollTop !== 0) {
-                            overflowContainer.scrollTop = 0;
-                            toggle();
-                        }
-                        overflowContainer.addEventListener('scroll', function () {
-                            overflowContainer.scrollTop = 0;
-                            if (container.classList.contains('collapsed')) {
-                                toggle();
-                            }
-                        });
-                    })(container, toggleButtons);
+                    window.scrollTo(window.pageXOffset, y);
                 }
-                container.classList.remove('jsCollapsibleBbcode');
             }
         }
-    };
+        else {
+            toggleButtons.forEach((toggleButton) => {
+                const title = toggleButton.dataset.titleCollapse;
+                if (toggleButton.classList.contains("icon")) {
+                    toggleButton.classList.add("fa-compress");
+                    toggleButton.classList.remove("fa-expand");
+                    toggleButton.title = title;
+                }
+                else {
+                    toggleButton.textContent = title;
+                }
+            });
+        }
+    }
+    function observe() {
+        document.querySelectorAll(".jsCollapsibleBbcode").forEach((container) => {
+            // find the matching toggle button
+            const toggleButtons = [];
+            container.querySelectorAll(".toggleButton:not(.jsToggleButtonEnabled)").forEach((button) => {
+                if (button.closest(".jsCollapsibleBbcode") === container) {
+                    toggleButtons.push(button);
+                }
+            });
+            const overflowContainer = container.querySelector(".collapsibleBbcodeOverflow") || container;
+            if (toggleButtons.length > 0) {
+                initContainer(container, toggleButtons, overflowContainer);
+            }
+            container.classList.remove("jsCollapsibleBbcode");
+        });
+    }
+    exports.observe = observe;
 });
diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Bbcode/Collapsible.js b/wcfsetup/install/files/ts/WoltLabSuite/Core/Bbcode/Collapsible.js
deleted file mode 100644 (file)
index 6333ceb..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * Generic handler for collapsible bbcode boxes.
- * 
- * @author     Alexander Ebert
- * @copyright  2001-2019 WoltLab GmbH
- * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module     WoltLabSuite/Core/Bbcode/Collapsible
- */
-define([], function() {
-       "use strict";
-       
-       var _containers = elByClass('jsCollapsibleBbcode');
-       
-       /**
-        * @exports     WoltLabSuite/Core/Bbcode/Collapsible
-        */
-       return {
-               observe: function() {
-                       var container, toggleButtons, overflowContainer;
-                       while (_containers.length) {
-                               container = _containers[0];
-                               
-                               // find the matching toggle button
-                               toggleButtons = [];
-                               elBySelAll('.toggleButton:not(.jsToggleButtonEnabled)', container, function (button) {
-                                       //noinspection JSReferencingMutableVariableFromClosure
-                                       if (button.closest('.jsCollapsibleBbcode') === container) {
-                                               toggleButtons.push(button);
-                                       }
-                               });
-                               overflowContainer = elBySel('.collapsibleBbcodeOverflow', container) || container;
-                               
-                               if (toggleButtons.length > 0) {
-                                       (function (container, toggleButtons) {
-                                               var toggle = function (event) {
-                                                       if (container.classList.toggle('collapsed')) {
-                                                               toggleButtons.forEach(function (toggleButton) {
-                                                                       if (toggleButton.classList.contains('icon')) {
-                                                                               toggleButton.classList.remove('fa-compress');
-                                                                               toggleButton.classList.add('fa-expand');
-                                                                               toggleButton.title = elData(toggleButton, 'title-expand');
-                                                                       }
-                                                                       else {
-                                                                               toggleButton.textContent = elData(toggleButton, 'title-expand');
-                                                                       }
-                                                               });
-                                                               
-                                                               if (event instanceof Event) {
-                                                                       // negative top value means the upper boundary is not within the viewport
-                                                                       var top = container.getBoundingClientRect().top;
-                                                                       if (top < 0) {
-                                                                               var y = window.pageYOffset + (top - 100);
-                                                                               if (y < 0) y = 0;
-                                                                               window.scrollTo(window.pageXOffset, y);
-                                                                       }
-                                                               }
-                                                       }
-                                                       else {
-                                                               toggleButtons.forEach(function (toggleButton) {
-                                                                       if (toggleButton.classList.contains('icon')) {
-                                                                               toggleButton.classList.add('fa-compress');
-                                                                               toggleButton.classList.remove('fa-expand');
-                                                                               toggleButton.title = elData(toggleButton, 'title-collapse');
-                                                                       }
-                                                                       else {
-                                                                               toggleButton.textContent = elData(toggleButton, 'title-collapse');
-                                                                       }
-                                                               });
-                                                       }
-                                               };
-                                               
-                                               toggleButtons.forEach(function (toggleButton) {
-                                                       toggleButton.classList.add('jsToggleButtonEnabled');
-                                                       toggleButton.addEventListener('click', toggle);
-                                               });
-                                               
-                                               // expand boxes that are initially scrolled
-                                               if (overflowContainer.scrollTop !== 0) {
-                                                       overflowContainer.scrollTop = 0;
-                                                       toggle();
-                                               }
-                                               overflowContainer.addEventListener('scroll', function () {
-                                                       overflowContainer.scrollTop = 0;
-                                                       if (container.classList.contains('collapsed')) {
-                                                               toggle();
-                                                       }
-                                               });
-                                       })(container, toggleButtons);
-                               }
-                               
-                               container.classList.remove('jsCollapsibleBbcode');
-                       }
-               }
-       };
-});
diff --git a/wcfsetup/install/files/ts/WoltLabSuite/Core/Bbcode/Collapsible.ts b/wcfsetup/install/files/ts/WoltLabSuite/Core/Bbcode/Collapsible.ts
new file mode 100644 (file)
index 0000000..cf0c0e5
--- /dev/null
@@ -0,0 +1,86 @@
+/**
+ * Generic handler for collapsible bbcode boxes.
+ *
+ * @author  Alexander Ebert
+ * @copyright  2001-2019 WoltLab GmbH
+ * @license  GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module  WoltLabSuite/Core/Bbcode/Collapsible
+ */
+
+function initContainer(container: HTMLElement, toggleButtons: HTMLElement[], overflowContainer: HTMLElement): void {
+  toggleButtons.forEach((toggleButton) => {
+    toggleButton.classList.add("jsToggleButtonEnabled");
+    toggleButton.addEventListener("click", (ev) => toggleContainer(container, toggleButtons, ev));
+  });
+
+  // expand boxes that are initially scrolled
+  if (overflowContainer.scrollTop !== 0) {
+    overflowContainer.scrollTop = 0;
+    toggleContainer(container, toggleButtons);
+  }
+  overflowContainer.addEventListener("scroll", () => {
+    overflowContainer.scrollTop = 0;
+    if (container.classList.contains("collapsed")) {
+      toggleContainer(container, toggleButtons);
+    }
+  });
+}
+
+function toggleContainer(container: HTMLElement, toggleButtons: HTMLElement[], event?: Event): void {
+  if (container.classList.toggle("collapsed")) {
+    toggleButtons.forEach((toggleButton) => {
+      const title = toggleButton.dataset.titleExpand!;
+      if (toggleButton.classList.contains("icon")) {
+        toggleButton.classList.remove("fa-compress");
+        toggleButton.classList.add("fa-expand");
+        toggleButton.title = title;
+      } else {
+        toggleButton.textContent = title;
+      }
+    });
+
+    if (event instanceof Event) {
+      // negative top value means the upper boundary is not within the viewport
+      const top = container.getBoundingClientRect().top;
+      if (top < 0) {
+        let y = window.pageYOffset + (top - 100);
+        if (y < 0) {
+          y = 0;
+        }
+
+        window.scrollTo(window.pageXOffset, y);
+      }
+    }
+  } else {
+    toggleButtons.forEach((toggleButton) => {
+      const title = toggleButton.dataset.titleCollapse!;
+      if (toggleButton.classList.contains("icon")) {
+        toggleButton.classList.add("fa-compress");
+        toggleButton.classList.remove("fa-expand");
+        toggleButton.title = title;
+      } else {
+        toggleButton.textContent = title;
+      }
+    });
+  }
+}
+
+export function observe(): void {
+  document.querySelectorAll(".jsCollapsibleBbcode").forEach((container: HTMLElement) => {
+    // find the matching toggle button
+    const toggleButtons: HTMLElement[] = [];
+    container.querySelectorAll(".toggleButton:not(.jsToggleButtonEnabled)").forEach((button: HTMLElement) => {
+      if (button.closest(".jsCollapsibleBbcode") === container) {
+        toggleButtons.push(button);
+      }
+    });
+
+    const overflowContainer = (container.querySelector(".collapsibleBbcodeOverflow") as HTMLElement) || container;
+
+    if (toggleButtons.length > 0) {
+      initContainer(container, toggleButtons, overflowContainer);
+    }
+
+    container.classList.remove("jsCollapsibleBbcode");
+  });
+}