Add live reload to style CSS
authorTim Düsterhus <duesterhus@woltlab.com>
Tue, 23 Feb 2021 15:08:38 +0000 (16:08 +0100)
committerTim Düsterhus <duesterhus@woltlab.com>
Tue, 23 Feb 2021 15:32:43 +0000 (16:32 +0100)
After submitting StyleAddForm or StyleGlobalValuesForm the CSS within the
frontend will be reloaded automatically.

com.woltlab.wcf/templates/headIncludeJavaScript.tpl
ts/WoltLabSuite/Core/Devtools/Style/LiveReload.ts [new file with mode: 0644]
wcfsetup/install/files/acp/templates/styleAdd.tpl
wcfsetup/install/files/acp/templates/styleGlobalValues.tpl
wcfsetup/install/files/js/WoltLabSuite/Core/Devtools/Style/LiveReload.js [new file with mode: 0644]

index 1ead75ef94229401d3eb96b83ca8ee796d2392bb..8a389eaac19b7e97c4afb2586849086c6739371a 100644 (file)
@@ -162,6 +162,12 @@ window.addEventListener('pageshow', function(event) {
 
 {include file='__devtoolsLanguageChooser'}
 
+{if ENABLE_DEBUG_MODE && ENABLE_DEVELOPER_TOOLS}
+<script data-relocate="true">
+       require(["WoltLabSuite/Core/Devtools/Style/LiveReload"], (LiveReload) => LiveReload.watch());
+</script>
+{/if}
+
 {js application='wcf' lib='jquery' hasTiny=true}
 {js application='wcf' lib='jquery-ui' hasTiny=true}
 {js application='wcf' lib='jquery-ui' file='touchPunch' bundle='WCF.Combined' hasTiny=true}
diff --git a/ts/WoltLabSuite/Core/Devtools/Style/LiveReload.ts b/ts/WoltLabSuite/Core/Devtools/Style/LiveReload.ts
new file mode 100644 (file)
index 0000000..6dd0f26
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Schedules a live reload of the style's CSS.
+ *
+ * @author  Tim Duesterhus
+ * @copyright  2001-2021 WoltLab GmbH
+ * @license  GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module  WoltLabSuite/Core/Devtools/Style/LiveReload
+ */
+
+const channelName = "com.woltlab.wcf#DevTools/Style/LiveReload";
+
+type UpdateMessage = undefined;
+
+export function watch(): void {
+  if (!window.BroadcastChannel) {
+    return;
+  }
+
+  const channel = new BroadcastChannel(channelName);
+
+  channel.onmessage = (_ev: MessageEvent<UpdateMessage>) => {
+    const link: HTMLLinkElement | null = document.querySelector("head link[rel=stylesheet]");
+    if (!link) {
+      return;
+    }
+
+    const url = new URL(link.href);
+    url.searchParams.set("m", Math.trunc(Date.now() / 1_000).toString());
+
+    const newLink = document.createElement("link");
+    newLink.rel = "stylesheet";
+    newLink.addEventListener("load", () => {
+      link.remove();
+    });
+    newLink.addEventListener("error", () => {
+      newLink.remove();
+    });
+    newLink.href = url.toString();
+    link.insertAdjacentElement("afterend", newLink);
+  };
+}
+
+export function notify(): void {
+  if (!window.BroadcastChannel) {
+    return;
+  }
+
+  const channel = new BroadcastChannel(channelName);
+  channel.postMessage(undefined);
+}
index eb493d9c3e89a4f301f47a6baaa7d27b3abd8da4..56cdea49a5f158f37584a2d9c27d26f75c4f77ea 100644 (file)
 
 {include file='formNotice'}
 
+{if $success|isset}
+<script data-relocate="true">
+       require(["WoltLabSuite/Core/Devtools/Style/LiveReload"], (LiveReload) => LiveReload.notify());
+</script>
+{/if}
+
 <form method="post" action="{if $action == 'add'}{link controller='StyleAdd'}{/link}{else}{link controller='StyleEdit' id=$styleID}{/link}{/if}">
        <div class="section tabMenuContainer" data-active="{$activeTabMenuItem}" data-store="activeTabMenuItem" id="styleTabMenuContainer">
                <nav class="tabMenu">
index 034acea58c662223e951900ba987d946a106147f..0f0c6976d88c202accb149f1be27aebc0e9fe3ef 100644 (file)
 
 {if $success|isset}
        <p class="success">{lang}wcf.global.success{/lang}</p>
+
+       <script data-relocate="true">
+               require(["WoltLabSuite/Core/Devtools/Style/LiveReload"], (LiveReload) => LiveReload.notify());
+       </script>
 {/if}
 
 <form method="post" action="{link controller='StyleGlobalValues'}{/link}">
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Devtools/Style/LiveReload.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Devtools/Style/LiveReload.js
new file mode 100644 (file)
index 0000000..31bde27
--- /dev/null
@@ -0,0 +1,47 @@
+/**
+ * Schedules a live reload of the style's CSS.
+ *
+ * @author  Tim Duesterhus
+ * @copyright  2001-2021 WoltLab GmbH
+ * @license  GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module  WoltLabSuite/Core/Devtools/Style/LiveReload
+ */
+define(["require", "exports"], function (require, exports) {
+    "use strict";
+    Object.defineProperty(exports, "__esModule", { value: true });
+    exports.notify = exports.watch = void 0;
+    const channelName = "com.woltlab.wcf#DevTools/Style/LiveReload";
+    function watch() {
+        if (!window.BroadcastChannel) {
+            return;
+        }
+        const channel = new BroadcastChannel(channelName);
+        channel.onmessage = (_ev) => {
+            const link = document.querySelector("head link[rel=stylesheet]");
+            if (!link) {
+                return;
+            }
+            const url = new URL(link.href);
+            url.searchParams.set("m", Math.trunc(Date.now() / 1000).toString());
+            const newLink = document.createElement("link");
+            newLink.rel = "stylesheet";
+            newLink.addEventListener("load", () => {
+                link.remove();
+            });
+            newLink.addEventListener("error", () => {
+                newLink.remove();
+            });
+            newLink.href = url.toString();
+            link.insertAdjacentElement("afterend", newLink);
+        };
+    }
+    exports.watch = watch;
+    function notify() {
+        if (!window.BroadcastChannel) {
+            return;
+        }
+        const channel = new BroadcastChannel(channelName);
+        channel.postMessage(undefined);
+    }
+    exports.notify = notify;
+});