diff --git a/src/ext/response-targets.js b/src/ext/response-targets.js
index 35db4e1f6..564a821b6 100644
--- a/src/ext/response-targets.js
+++ b/src/ext/response-targets.js
@@ -3,43 +3,55 @@
/** @type {import("../htmx").HtmxInternalApi} */
var api;
- const targetAttrPrefix = 'hx-target-';
- const targetAttrMinLen = targetAttrPrefix.length - 1;
+ var attrPrefix = 'hx-target-';
/**
* @param {HTMLElement} elt
* @param {number} respCode
* @returns {HTMLElement | null}
*/
- function getRespCodeTarget(elt, respCode) {
- if (!elt || !respCode) return null;
+ function getRespCodeTarget(elt, respCodeNumber) {
+ if (!elt || !respCodeNumber) return null;
- var targetAttr = targetAttrPrefix + respCode;
- var targetStr = api.getClosestAttributeValue(elt, targetAttr);
+ var respCode = respCodeNumber.toString();
- if (targetStr) {
- if (targetStr === "this") {
- return api.findThisElement(elt, targetAttr);
- } else {
- return api.querySelectorExt(elt, targetStr);
- }
- } else {
- for (let l = targetAttr.length - 1; l > targetAttrMinLen; l--) {
- targetAttr = targetAttr.substring(0, l) + '*';
- targetStr = api.getClosestAttributeValue(elt, targetAttr);
- if (targetStr) break;
- }
- }
+ // '*' 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',
- if (targetStr) {
- if (targetStr === "this") {
- return api.findThisElement(elt, targetAttr);
- } else {
- return api.querySelectorExt(elt, targetStr);
+ respCode.substr(0, 1) + '*',
+ respCode.substr(0, 1) + 'x',
+ respCode.substr(0, 1) + '**',
+ respCode.substr(0, 1) + 'xx',
+
+ '*',
+ 'x',
+ '***',
+ 'xxx',
+ ];
+
+ 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);
+ }
}
- } else {
- return null;
}
+
+ return null;
}
/** @param {Event} evt */
diff --git a/src/htmx.js b/src/htmx.js
index 005da3d7d..d6c12c5cf 100644
--- a/src/htmx.js
+++ b/src/htmx.js
@@ -3584,7 +3584,7 @@ return (function () {
//====================================================================
function ready(fn) {
- if (getDocument().readyState !== 'loading') {
+ if (getDocument().readyState === 'complete') {
fn();
} else {
getDocument().addEventListener('DOMContentLoaded', fn);
diff --git a/test/ext/response-targets.js b/test/ext/response-targets.js
index 1c670d664..2384c319b 100644
--- a/test/ext/response-targets.js
+++ b/test/ext/response-targets.js
@@ -263,4 +263,38 @@ describe("response-targets extension", function() {
htmx.config.responseTargetPrefersExisting = false;
}
});
+
+ describe('status code formatting', function()
+ {
+ var attributes = [
+ "hx-target-404",
+
+ "hx-target-40*",
+ "hx-target-40x",
+
+ "hx-target-4*",
+ "hx-target-4x",
+ "hx-target-4**",
+ "hx-target-4xx",
+
+ "hx-target-*",
+ "hx-target-x",
+ "hx-target-***",
+ "hx-target-xxx",
+ ];
+
+ // String replacement because IE11 doesn't support template literals
+ var btnMarkup = '';
+ // forEach because IE11 doesn't play nice with closures inside for loops
+ attributes.forEach(function(attribute) {
+ it('supports ' + attribute, function() {
+ this.server.respondWith("GET", "/test", [404, {}, "Not found!"]);
+ var btn = make(btnMarkup.replace("HX_TARGET", attribute));
+ var div1 = make('
')
+ btn.click();
+ this.server.respond();
+ div1.innerHTML.should.equal("Not found!");
+ });
+ });
+ });
});
diff --git a/www/config.toml b/www/config.toml
index 7dc7c9afe..20f42e3fa 100644
--- a/www/config.toml
+++ b/www/config.toml
@@ -7,7 +7,8 @@ build_search_index = false
generate_feed = true
taxonomies = [
- { name = "tag", render = false, feed = true }
+ { name = "tag", render = false, feed = true },
+ { name = "author", render = false, feed = false }
]
[markdown]
@@ -35,4 +36,4 @@ paths_keep_dates = true
# Tomorrow
# two-dark
# visual-studio-dark
-# zenburn
\ No newline at end of file
+# zenburn
diff --git a/www/content/attributes/hx-on.md b/www/content/attributes/hx-on.md
index af8ffc053..57bc03b33 100644
--- a/www/content/attributes/hx-on.md
+++ b/www/content/attributes/hx-on.md
@@ -7,11 +7,10 @@ The `hx-on` attribute allows you to embed scripts inline to respond to events di
`hx-on` improves upon `onevent` by enabling the handling of any event for enhanced [Locality of Behaviour (LoB)](/essays/locality-of-behaviour/). This also enables you to handle any htmx event.
There are two forms of this attribute, one in which you specify the event as part of the attribute name
-after a colon (`hx-on:click`, for example), and one that uses the `hx-on` attribute directly. The
-latter form should only be used if IE11 support is required.
+after a colon (`hx-on:click`, for example), and a deprecated form that uses the `hx-on` attribute directly. The
+latter should only be used if IE11 support is required.
-### Forms
-#### hx-on:* (recommended)
+### hx-on:* (recommended)
The event name follows a colon `:` in the attribute, and the attribute value is the script to be executed:
```html
@@ -40,22 +39,16 @@ events, and omit the "htmx" part:
Adding multiple handlers is easy, you just specify additional attributes:
```html
```
-#### hx-on (deprecated, except for IE11 support)
+### hx-on (deprecated)
The value is an event name, followed by a colon `:`, followed by the script:
-```html
-