From 5e12dabced6ce55031f5c7f13afb15048d03edcd Mon Sep 17 00:00:00 2001
From: Steven Le Rouzic <steven.lerouzic@gmail.com>
Date: Thu, 11 Apr 2024 00:19:44 +0200
Subject: Timer create & delete

---
 static/response-targets.js | 130 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 130 insertions(+)
 create mode 100644 static/response-targets.js

(limited to 'static/response-targets.js')

diff --git a/static/response-targets.js b/static/response-targets.js
new file mode 100644
index 0000000..dd6fd41
--- /dev/null
+++ b/static/response-targets.js
@@ -0,0 +1,130 @@
+(function(){
+
+    /** @type {import("../htmx").HtmxInternalApi} */
+    var api;
+
+    var attrPrefix = 'hx-target-';
+
+    // IE11 doesn't support string.startsWith
+    function startsWith(str, prefix) {
+        return str.substring(0, prefix.length) === prefix
+    }
+
+    /**
+     * @param {HTMLElement} elt
+     * @param {number} respCode
+     * @returns {HTMLElement | null}
+     */
+    function getRespCodeTarget(elt, respCodeNumber) {
+        if (!elt || !respCodeNumber) return null;
+
+        var respCode = respCodeNumber.toString();
+
+        // '*' is the original syntax, as the obvious character for a wildcard.
+        // The 'x' alternative was added for maximum compatibility with HTML
+        // templating engines, due to ambiguity around which characters are
+        // supported in HTML attributes.
+        //
+        // Start with the most specific possible attribute and generalize from
+        // there.
+        var attrPossibilities = [
+            respCode,
+
+            respCode.substr(0, 2) + '*',
+            respCode.substr(0, 2) + 'x',
+
+            respCode.substr(0, 1) + '*',
+            respCode.substr(0, 1) + 'x',
+            respCode.substr(0, 1) + '**',
+            respCode.substr(0, 1) + 'xx',
+
+            '*',
+            'x',
+            '***',
+            'xxx',
+        ];
+        if (startsWith(respCode, '4') || startsWith(respCode, '5')) {
+            attrPossibilities.push('error');
+        }
+
+        for (var i = 0; i < attrPossibilities.length; i++) {
+            var attr = attrPrefix + attrPossibilities[i];
+            var attrValue = api.getClosestAttributeValue(elt, attr);
+            if (attrValue) {
+                if (attrValue === "this") {
+                    return api.findThisElement(elt, attr);
+                } else {
+                    return api.querySelectorExt(elt, attrValue);
+                }
+            }
+        }
+        
+        return null;
+    }
+
+    /** @param {Event} evt */
+    function handleErrorFlag(evt) {
+        if (evt.detail.isError) {
+            if (htmx.config.responseTargetUnsetsError) {
+                evt.detail.isError = false;
+            }
+        } else if (htmx.config.responseTargetSetsError) {
+            evt.detail.isError = true;
+        }
+    }
+
+    htmx.defineExtension('response-targets', {
+
+        /** @param {import("../htmx").HtmxInternalApi} apiRef */
+        init: function (apiRef) {
+            api = apiRef;
+
+            if (htmx.config.responseTargetUnsetsError === undefined) {
+                htmx.config.responseTargetUnsetsError = true;
+            }
+            if (htmx.config.responseTargetSetsError === undefined) {
+                htmx.config.responseTargetSetsError = false;
+            }
+            if (htmx.config.responseTargetPrefersExisting === undefined) {
+                htmx.config.responseTargetPrefersExisting = false;
+            }
+            if (htmx.config.responseTargetPrefersRetargetHeader === undefined) {
+                htmx.config.responseTargetPrefersRetargetHeader = true;
+            }
+        },
+
+        /**
+         * @param {string} name
+         * @param {Event} evt
+         */
+        onEvent: function (name, evt) {
+            if (name === "htmx:beforeSwap"    &&
+                evt.detail.xhr                &&
+                evt.detail.xhr.status !== 200) {
+                if (evt.detail.target) {
+                    if (htmx.config.responseTargetPrefersExisting) {
+                        evt.detail.shouldSwap = true;
+                        handleErrorFlag(evt);
+                        return true;
+                    }
+                    if (htmx.config.responseTargetPrefersRetargetHeader &&
+                        evt.detail.xhr.getAllResponseHeaders().match(/HX-Retarget:/i)) {
+                        evt.detail.shouldSwap = true;
+                        handleErrorFlag(evt);
+                        return true;
+                    }
+                }
+                if (!evt.detail.requestConfig) {
+                    return true;
+                }
+                var target = getRespCodeTarget(evt.detail.requestConfig.elt, evt.detail.xhr.status);
+                if (target) {
+                    handleErrorFlag(evt);
+                    evt.detail.shouldSwap = true;
+                    evt.detail.target = target;
+                }
+                return true;
+            }
+        }
+    });
+})();
-- 
cgit