Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
1cg committed Jul 25, 2023
2 parents c59fe79 + 88a57cb commit 4cb85e9
Show file tree
Hide file tree
Showing 21 changed files with 769 additions and 80 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
behavior for now, but allowing people to fix it for their use cases by updating the `htmx.config.methodsThatUseUrlParams` config
option. Thank you to Alex and Vincent for their feedback and work on this issue!
* The `this` symbol is now available in event filter expressions, and refers to the element the `hx-trigger` is on
* Fix bug where the `htmx:afterSettle` event was raised multiple times with oob swaps occured
* Fix bug where the `htmx:afterSettle` event was raised multiple times with oob swaps occurred
* A large number of accessibility fixes were made in the docs (Thank you Denis & crew!)
* Fixed bug w/ WebSocket extension initialization caused by "naked" `hx-trigger` feature
* The `HX-Reselect` HTTP response header has been added to change the selection from the returned content
Expand Down Expand Up @@ -130,7 +130,7 @@
to both of them without compromising the core file size of htmx. You are encouraged to move over to the new
extensions, but `hx-sse` and `hx-ws` will continue to work indefinitely in htmx 1.x.
* You can now mask out [attribute inheritance](/docs#inheritance) via the [`hx-disinherit`](https://htmx.org/attributes/hx-disinherit) attribute.
* The `HX-Push` header can now have the `false` value, which will prevent a history snapshot from occuring.
* The `HX-Push` header can now have the `false` value, which will prevent a history snapshot from occurring.
* Many new extensions, with a big thanks to all the contributors!
* A new [`alpine-morph`](/extensions/alpine-morph) allows you to use Alpine's swapping engine, which preserves Alpine
* A [restored](/extensions/restored) extension was added that will trigger a `restore` event on all elements in the DOM
Expand Down
3 changes: 0 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@
"types": "dist/htmx.d.ts",
"unpkg": "dist/htmx.min.js",
"web-types": "editors/jetbrains/htmx.web-types.json",
"engines": {
"node": "15.x"
},
"scripts": {
"test": "mocha-chrome test/index.html",
"test-types": "tsc --project ./jsconfig.json",
Expand Down
2 changes: 1 addition & 1 deletion src/ext/preload.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ htmx.defineExtension("preload", {
// Apply the listener to the node
node.addEventListener(on, function(evt) {
if (node.preloadState === "PAUSE") { // Only add one event listener
node.preloadState = "READY"; // Requred for the `load` function to trigger
node.preloadState = "READY"; // Required for the `load` function to trigger

// Special handling for "mouseover" events. Wait 100ms before triggering load.
if (on === "mouseover") {
Expand Down
2 changes: 1 addition & 1 deletion src/ext/response-targets.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
evt.detail.xhr.status !== 200) {
if (evt.detail.target) {
if (htmx.config.responseTargetPrefersExisting) {
evt.detail.shoudSwap = true;
evt.detail.shouldSwap = true;
handleErrorFlag(evt);
return true;
}
Expand Down
152 changes: 93 additions & 59 deletions src/htmx.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion test/attributes/hx-sse.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ describe("hx-sse attribute", function() {
byId("d1").innerHTML.should.equal("div1 updated");
})

it('does not trigger events not on decendents', function () {
it('does not trigger events not on descendents', function () {

this.server.respondWith("GET", "/d1", "div1 updated");

Expand Down
70 changes: 69 additions & 1 deletion test/attributes/hx-trigger.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,74 @@ describe("hx-trigger attribute", function(){
div.innerHTML.should.equal("Requests: 1");
});

it('changed modifier works along from clause with single input', function()
{
var requests = 0;
this.server.respondWith("GET", "/test", function (xhr) {
requests++;
xhr.respond(200, {}, "Requests: " + requests);
});
var input = make('<input type="text"/>');
make('<div hx-trigger="click changed from:input" hx-target="#d1" hx-get="/test"></div>')
var div = make('<div id="d1"></div>');
input.click();
this.server.respond();
div.innerHTML.should.equal("");
input.click();
this.server.respond();
div.innerHTML.should.equal("");
input.value = "bar";
input.click();
this.server.respond();
div.innerHTML.should.equal("Requests: 1");
input.click();
this.server.respond();
div.innerHTML.should.equal("Requests: 1");
});

it('changed modifier works along from clause with two inputs', function()
{
var requests = 0;
this.server.respondWith("GET", "/test", function (xhr) {
requests++;
xhr.respond(200, {}, "Requests: " + requests);
});
var input1 = make('<input type="text"/>');
var input2 = make('<input type="text"/>');
make('<div hx-trigger="click changed from:input" hx-target="#d1" hx-get="/test"></div>')
var div = make('<div id="d1"></div>');

input1.click();
this.server.respond();
div.innerHTML.should.equal("");
input2.click();
this.server.respond();
div.innerHTML.should.equal("");

input1.value = "bar";
input2.click();
this.server.respond();
div.innerHTML.should.equal("");
input1.click();
this.server.respond();
div.innerHTML.should.equal("Requests: 1");

input1.click();
this.server.respond();
div.innerHTML.should.equal("Requests: 1");
input2.click();
this.server.respond();
div.innerHTML.should.equal("Requests: 1");

input2.value = "foo";
input1.click();
this.server.respond();
div.innerHTML.should.equal("Requests: 1");
input2.click();
this.server.respond();
div.innerHTML.should.equal("Requests: 2");
});

it('once modifier works', function()
{
var requests = 0;
Expand Down Expand Up @@ -525,7 +593,7 @@ describe("hx-trigger attribute", function(){

});

it('consume prevents event propogation', function()
it('consume prevents event propagation', function()
{
this.server.respondWith("GET", "/foo", "foo");
this.server.respondWith("GET", "/bar", "bar");
Expand Down
197 changes: 196 additions & 1 deletion test/core/ajax.js
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ describe("Core htmx AJAX Tests", function(){
}
});

it('script nodes do not evaluate when explicity marked as something other than javascript', function()
it('script nodes do not evaluate when explicitly marked as something other than javascript', function()
{
var globalWasCalled = false;
window.callGlobal = function() {
Expand Down Expand Up @@ -989,4 +989,199 @@ describe("Core htmx AJAX Tests", function(){
btn.innerHTML.should.equal('<with:colon id="foobar">Foobar</with:colon>');
});

it('properly handles clicked submit button with a value inside a htmx form', function () {
var values;
this.server.respondWith("Post", "/test", function (xhr) {
values = getParameters(xhr);
xhr.respond(204, {}, "");
});

make('<form hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'<button id="submit" type="submit" name="b1" value="buttonValue">button</button>' +
'</form>');

byId("submit").click();
this.server.respond();
values.should.deep.equal({t1: 'textValue', b1: 'buttonValue'});
})

it('properly handles clicked submit input with a value inside a htmx form', function () {
var values;
this.server.respondWith("Post", "/test", function (xhr) {
values = getParameters(xhr);
xhr.respond(204, {}, "");
});

make('<form hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'<input id="submit" type="submit" name="b1" value="buttonValue">' +
'</form>');

byId("submit").click();
this.server.respond();
values.should.deep.equal({t1: 'textValue', b1: 'buttonValue'});
})

it('properly handles clicked submit button with a value inside a non-htmx form', function () {
var values;
this.server.respondWith("Post", "/test", function (xhr) {
values = getParameters(xhr);
xhr.respond(204, {}, "");
});

make('<form>' +
'<input type="text" name="t1" value="textValue">' +
'<button id="submit" type="submit" name="b1" value="buttonValue" hx-post="/test">button</button>' +
'</form>');

byId("submit").click();
this.server.respond();
values.should.deep.equal({t1: 'textValue', b1: 'buttonValue'});
})

it('properly handles clicked submit input with a value inside a non-htmx form', function () {
var values;
this.server.respondWith("Post", "/test", function (xhr) {
values = getParameters(xhr);
xhr.respond(204, {}, "");
});

make('<form>' +
'<input type="text" name="t1" value="textValue">' +
'<input id="submit" type="submit" name="b1" value="buttonValue" hx-post="/test">' +
'</form>');

byId("submit").click();
this.server.respond();
values.should.deep.equal({t1: 'textValue', b1: 'buttonValue'});
})

it('properly handles clicked submit button with a value outside a htmx form', function () {
var values;
this.server.respondWith("Post", "/test", function (xhr) {
values = getParameters(xhr);
xhr.respond(204, {}, "");
});

make('<form id="externalForm" hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'</form>' +
'<button id="submit" form="externalForm" type="submit" name="b1" value="buttonValue">button</button>');

byId("submit").click();
this.server.respond();
values.should.deep.equal({t1: 'textValue', b1: 'buttonValue'});
})

it('properly handles clicked submit input with a value outside a htmx form', function () {
var values;
this.server.respondWith("Post", "/test", function (xhr) {
values = getParameters(xhr);
xhr.respond(204, {}, "");
});

make('<form id="externalForm" hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'</form>' +
'<input id="submit" form="externalForm" type="submit" name="b1" value="buttonValue">');

byId("submit").click();
this.server.respond();
values.should.deep.equal({t1: 'textValue', b1: 'buttonValue'});
})

it('properly handles clicked submit button with a value stacking with regular input', function () {
var values;
this.server.respondWith("Post", "/test", function (xhr) {
values = getParameters(xhr);
xhr.respond(204, {}, "");
});

make('<form hx-post="/test">' +
'<input type="hidden" name="action" value="A">' +
'<button id="btnA" type="submit">A</button>' +
'<button id="btnB" type="submit" name="action" value="B">B</button>' +
'<button id="btnC" type="submit" name="action" value="C">C</button>' +
'</form>');

byId("btnA").click();
this.server.respond();
values.should.deep.equal({action: 'A'});

byId("btnB").click();
this.server.respond();
values.should.deep.equal({action: ['A', 'B']});

byId("btnC").click();
this.server.respond();
values.should.deep.equal({action: ['A', 'C']});
})

it('properly handles clicked submit input with a value stacking with regular input', function () {
var values;
this.server.respondWith("Post", "/test", function (xhr) {
values = getParameters(xhr);
xhr.respond(204, {}, "");
});

make('<form hx-post="/test">' +
'<input type="hidden" name="action" value="A">' +
'<input id="btnA" type="submit">A</input>' +
'<input id="btnB" type="submit" name="action" value="B">B</input>' +
'<input id="btnC" type="submit" name="action" value="C">C</input>' +
'</form>');

byId("btnA").click();
this.server.respond();
values.should.deep.equal({action: 'A'});

byId("btnB").click();
this.server.respond();
values.should.deep.equal({action: ['A', 'B']});

byId("btnC").click();
this.server.respond();
values.should.deep.equal({action: ['A', 'C']});
})

it('properly handles clicked submit button with a value inside a form, referencing another form', function () {
var values;
this.server.respondWith("Post", "/test", function (xhr) {
values = getParameters(xhr);
xhr.respond(204, {}, "");
});

make('<form id="externalForm" hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'<input type="hidden" name="b1" value="inputValue">' +
'</form>' +
'<form hx-post="/test2">' +
'<button id="submit" form="externalForm" type="submit" name="b1" value="buttonValue">button</button>' +
'</form>');

byId("submit").click();
this.server.respond();
values.should.deep.equal({t1: 'textValue', b1: ['inputValue', 'buttonValue']});
})

it('properly handles clicked submit input with a value inside a form, referencing another form', function () {
var values;
this.server.respondWith("Post", "/test", function (xhr) {
values = getParameters(xhr);
xhr.respond(204, {}, "");
});

make('<form id="externalForm" hx-post="/test">' +
'<input type="text" name="t1" value="textValue">' +
'<input type="hidden" name="b1" value="inputValue">' +
'</form>' +
'<form hx-post="/test2">' +
'<input id="submit" form="externalForm" type="submit" name="b1" value="buttonValue">' +
'</form>');

byId("submit").click();
this.server.respond();
values.should.deep.equal({t1: 'textValue', b1: ['inputValue', 'buttonValue']});
})
})

0 comments on commit 4cb85e9

Please sign in to comment.