Merge branch 'dev' into feature_event_filtering

# Conflicts:
#	src/htmx.js
This commit is contained in:
carson
2020-10-17 08:22:48 -06:00
5 changed files with 103 additions and 24 deletions

View File

@@ -516,8 +516,10 @@ return (function () {
}
getInternalData(target).replacedWith = newElt; // tuck away so we can fire events on it later
while(newElt && newElt !== target) {
settleInfo.elts.push(newElt);
newElt = newElt.nextSibling;
if (newElt.nodeType === Node.ELEMENT_NODE) {
settleInfo.elts.push(newElt);
}
newElt = newElt.nextElementSibling;
}
closeConnections(target);
parentElt(target).removeChild(target);
@@ -619,22 +621,21 @@ return (function () {
}
}
function handleTrigger(elt, trigger) {
if (trigger) {
if (trigger.indexOf("{") === 0) {
var triggers = parseJSON(trigger);
for (var eventName in triggers) {
if (triggers.hasOwnProperty(eventName)) {
var detail = triggers[eventName];
if (!isRawObject(detail)) {
detail = {"value": detail}
}
triggerEvent(elt, eventName, detail);
function handleTrigger(xhr, header, elt) {
var triggerBody = xhr.getResponseHeader(header);
if (triggerBody.indexOf("{") === 0) {
var triggers = parseJSON(triggerBody);
for (var eventName in triggers) {
if (triggers.hasOwnProperty(eventName)) {
var detail = triggers[eventName];
if (!isRawObject(detail)) {
detail = {"value": detail}
}
triggerEvent(elt, eventName, detail);
}
} else {
triggerEvent(elt, trigger, []);
}
} else {
triggerEvent(elt, triggerBody, []);
}
}
@@ -1286,7 +1287,11 @@ return (function () {
while (historyCache.length > htmx.config.historyCacheSize) {
historyCache.shift();
}
localStorage.setItem("htmx-history-cache", JSON.stringify(historyCache));
try {
localStorage.setItem("htmx-history-cache", JSON.stringify(historyCache));
} catch (e) {
triggerErrorEvent(getDocument().body, "htmx:historyCacheError", {cause:e})
}
}
function getCachedHistory(url) {
@@ -1721,6 +1726,10 @@ return (function () {
}
}
function hasHeader(xhr, regexp) {
return xhr.getAllResponseHeaders().match(regexp);
}
function issueAjaxRequest(elt, verb, path, eventTarget, triggeringEvent) {
var target = getTarget(elt);
if (target == null) {
@@ -1835,11 +1844,11 @@ return (function () {
try {
if (!triggerEvent(elt, 'htmx:beforeOnLoad', eventDetail)) return;
if (xhr.getAllResponseHeaders().search(/HX-Trigger/i) >= 0) {
handleTrigger(elt, this.getResponseHeader("HX-Trigger"));
if (hasHeader(xhr, /HX-Trigger:/i)) {
handleTrigger(xhr, "HX-Trigger", elt);
}
if (xhr.getAllResponseHeaders().search(/HX-Push/i) >= 0) {
if (hasHeader(xhr,/HX-Push:/i)) {
var pushedUrl = this.getResponseHeader("HX-Push");
}
@@ -1901,6 +1910,11 @@ return (function () {
if (anchor) {
location.hash = anchor;
}
if (hasHeader(xhr, /HX-Trigger-After-Swap:/i)) {
handleTrigger(xhr, "HX-Trigger-After-Swap", elt);
}
var doSettle = function(){
forEach(settleInfo.tasks, function (task) {
task.call();
@@ -1918,6 +1932,10 @@ return (function () {
triggerEvent(getDocument().body, 'htmx:pushedIntoHistory', {path:pathToPush});
}
updateScrollState(target, settleInfo.elts, swapSpec);
if (hasHeader(xhr, /HX-Trigger-After-Settle:/i)) {
handleTrigger(xhr, "HX-Trigger-After-Settle", elt);
}
}
if (swapSpec.settleDelay > 0) {

View File

@@ -188,4 +188,20 @@ describe("hx-push-url attribute", function() {
}
});
it("saveToHistoryCache should not throw", function () {
var bigContent = "Dummy";
for (var i = 0; i < 20; i++) {
bigContent += bigContent;
}
console.log(bigContent.length);
try {
localStorage.removeItem("htmx-history-cache");
htmx._("saveToHistoryCache")("/dummy", bigContent, "Foo", 0);
should.equal(localStorage.getItem("htmx-history-cache"), null);
} finally {
// clear history cache afterwards
localStorage.removeItem("htmx-history-cache");
}
});
});

View File

@@ -133,10 +133,10 @@ describe("Core htmx Events", function() {
}
});
it("htmx:afterSettle is called when replacing outerHTML", function () {
var called = false;
it("htmx:afterSettle is called once when replacing outerHTML", function () {
var called = 0;
var handler = htmx.on("htmx:afterSettle", function (evt) {
called = true;
called++;
});
try {
this.server.respondWith("POST", "/test", function (xhr) {
@@ -145,7 +145,43 @@ describe("Core htmx Events", function() {
var div = make("<button hx-post='/test' hx-swap='outerHTML'>Foo</button>");
div.click();
this.server.respond();
should.equal(called, true);
should.equal(called, 1);
} finally {
htmx.off("htmx:afterSettle", handler);
}
});
it("htmx:afterSettle is called once when replacing outerHTML with whitespace", function () {
var called = 0;
var handler = htmx.on("htmx:afterSettle", function (evt) {
called++;
});
try {
this.server.respondWith("POST", "/test", function (xhr) {
xhr.respond(200, {}, "<button>Bar</button>\n");
});
var div = make("<button hx-post='/test' hx-swap='outerHTML'>Foo</button>");
div.click();
this.server.respond();
should.equal(called, 1);
} finally {
htmx.off("htmx:afterSettle", handler);
}
});
it("htmx:afterSettle is called twice when replacing outerHTML with whitespace separated elements", function () {
var called = 0;
var handler = htmx.on("htmx:afterSettle", function (evt) {
called++;
});
try {
this.server.respondWith("POST", "/test", function (xhr) {
xhr.respond(200, {}, "<button>Bar</button>\n <a>Foo</a>");
});
var div = make("<button hx-post='/test' hx-swap='outerHTML'>Foo</button>");
div.click();
this.server.respond();
should.equal(called, 2);
} finally {
htmx.off("htmx:afterSettle", handler);
}
@@ -254,7 +290,7 @@ describe("Core htmx Events", function() {
} finally {
htmx.off("htmx:afterOnLoad", handler);
}
});
});
});

View File

@@ -111,6 +111,14 @@ than a single value.
* `detail.target` - the target of the request
* `detail.verb` - the HTTP verb in use
### <a name="htmx:historyCacheError"></a> Event - [`htmx:historyCacheError`](#htmx:historyCacheError)
This event is triggered when an attempt to save the cache to `localStorage` fails
##### Details
* `detail.cause` - the `Exception` that was thrown when attempting to save history to `localStorage`
### <a name="htmx:historyCacheMiss"></a> Event - [`htmx:historyCacheMiss`](#htmx:historyCacheMiss)
This event is triggered when a cache miss occurs when restoring history

View File

@@ -105,6 +105,7 @@ title: </> htmx - Attributes
| [`htmx:beforeRequest`](/events#htmx:beforeRequest) | triggered before an AJAX request is made
| [`htmx:beforeSwap`](/events#htmx:beforeSwap) | triggered before a swap is done
| [`htmx:configRequest`](/events#htmx:configRequest) | triggered before the request, allows you to customize parameters, headers
| [`htmx:historyCacheError`](/events#htmx:historyCacheError) | triggered on an error during cache writing
| [`htmx:historyCacheMiss`](/events#htmx:historyCacheMiss) | triggered on a cache miss in the history subsystem
| [`htmx:historyCacheMissError`](/events#htmx:historyCacheMissError) | triggered on a unsuccessful remote retrieval
| [`htmx:historyCacheMissLoad`](/events#htmx:historyCacheMissLoad) | triggered on a succesful remote retrieval