Updated HTMX
This commit is contained in:
parent
43050b4c3b
commit
ecb83a96c6
3 changed files with 48 additions and 35 deletions
2
public/js/htmx.base.js
vendored
2
public/js/htmx.base.js
vendored
File diff suppressed because one or more lines are too long
76
public/js/htmx.sse.js
vendored
76
public/js/htmx.sse.js
vendored
|
@ -5,7 +5,7 @@ This extension adds support for Server Sent Events to htmx. See /www/extensions
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function () {
|
(function() {
|
||||||
|
|
||||||
/** @type {import("../htmx").HtmxInternalApi} */
|
/** @type {import("../htmx").HtmxInternalApi} */
|
||||||
var api;
|
var api;
|
||||||
|
@ -18,7 +18,7 @@ This extension adds support for Server Sent Events to htmx. See /www/extensions
|
||||||
* @param {import("../htmx").HtmxInternalApi} api
|
* @param {import("../htmx").HtmxInternalApi} api
|
||||||
* @returns void
|
* @returns void
|
||||||
*/
|
*/
|
||||||
init: function (apiRef) {
|
init: function(apiRef) {
|
||||||
// store a reference to the internal API.
|
// store a reference to the internal API.
|
||||||
api = apiRef;
|
api = apiRef;
|
||||||
|
|
||||||
|
@ -35,12 +35,13 @@ This extension adds support for Server Sent Events to htmx. See /www/extensions
|
||||||
* @param {Event} evt
|
* @param {Event} evt
|
||||||
* @returns void
|
* @returns void
|
||||||
*/
|
*/
|
||||||
onEvent: function (name, evt) {
|
onEvent: function(name, evt) {
|
||||||
|
|
||||||
|
var parent = evt.target || evt.detail.elt;
|
||||||
switch (name) {
|
switch (name) {
|
||||||
|
|
||||||
case "htmx:beforeCleanupElement":
|
case "htmx:beforeCleanupElement":
|
||||||
var internalData = api.getInternalData(evt.target)
|
var internalData = api.getInternalData(parent)
|
||||||
// Try to remove remove an EventSource when elements are removed
|
// Try to remove remove an EventSource when elements are removed
|
||||||
if (internalData.sseEventSource) {
|
if (internalData.sseEventSource) {
|
||||||
internalData.sseEventSource.close();
|
internalData.sseEventSource.close();
|
||||||
|
@ -50,8 +51,7 @@ This extension adds support for Server Sent Events to htmx. See /www/extensions
|
||||||
|
|
||||||
// Try to create EventSources when elements are processed
|
// Try to create EventSources when elements are processed
|
||||||
case "htmx:afterProcessNode":
|
case "htmx:afterProcessNode":
|
||||||
ensureEventSourceOnElement(evt.target);
|
ensureEventSourceOnElement(parent);
|
||||||
registerSSE(evt.target);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -112,19 +112,18 @@ This extension adds support for Server Sent Events to htmx. See /www/extensions
|
||||||
* @param {HTMLElement} elt
|
* @param {HTMLElement} elt
|
||||||
*/
|
*/
|
||||||
function registerSSE(elt) {
|
function registerSSE(elt) {
|
||||||
// Find closest existing event source
|
|
||||||
var sourceElement = api.getClosestMatch(elt, hasEventSource);
|
|
||||||
if (sourceElement == null) {
|
|
||||||
// api.triggerErrorEvent(elt, "htmx:noSSESourceError")
|
|
||||||
return null; // no eventsource in parentage, orphaned element
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set internalData and source
|
|
||||||
var internalData = api.getInternalData(sourceElement);
|
|
||||||
var source = internalData.sseEventSource;
|
|
||||||
|
|
||||||
// Add message handlers for every `sse-swap` attribute
|
// Add message handlers for every `sse-swap` attribute
|
||||||
queryAttributeOnThisOrChildren(elt, "sse-swap").forEach(function (child) {
|
queryAttributeOnThisOrChildren(elt, "sse-swap").forEach(function (child) {
|
||||||
|
// Find closest existing event source
|
||||||
|
var sourceElement = api.getClosestMatch(child, hasEventSource);
|
||||||
|
if (sourceElement == null) {
|
||||||
|
// api.triggerErrorEvent(elt, "htmx:noSSESourceError")
|
||||||
|
return null; // no eventsource in parentage, orphaned element
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set internalData and source
|
||||||
|
var internalData = api.getInternalData(sourceElement);
|
||||||
|
var source = internalData.sseEventSource;
|
||||||
|
|
||||||
var sseSwapAttr = api.getAttributeValue(child, "sse-swap");
|
var sseSwapAttr = api.getAttributeValue(child, "sse-swap");
|
||||||
if (sseSwapAttr) {
|
if (sseSwapAttr) {
|
||||||
|
@ -135,7 +134,7 @@ This extension adds support for Server Sent Events to htmx. See /www/extensions
|
||||||
|
|
||||||
for (var i = 0; i < sseEventNames.length; i++) {
|
for (var i = 0; i < sseEventNames.length; i++) {
|
||||||
var sseEventName = sseEventNames[i].trim();
|
var sseEventName = sseEventNames[i].trim();
|
||||||
var listener = function (event) {
|
var listener = function(event) {
|
||||||
|
|
||||||
// If the source is missing then close SSE
|
// If the source is missing then close SSE
|
||||||
if (maybeCloseSSESource(sourceElement)) {
|
if (maybeCloseSSESource(sourceElement)) {
|
||||||
|
@ -145,9 +144,13 @@ This extension adds support for Server Sent Events to htmx. See /www/extensions
|
||||||
// If the body no longer contains the element, remove the listener
|
// If the body no longer contains the element, remove the listener
|
||||||
if (!api.bodyContains(child)) {
|
if (!api.bodyContains(child)) {
|
||||||
source.removeEventListener(sseEventName, listener);
|
source.removeEventListener(sseEventName, listener);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// swap the response into the DOM and trigger a notification
|
// swap the response into the DOM and trigger a notification
|
||||||
|
if(!api.triggerEvent(elt, "htmx:sseBeforeMessage", event)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
swap(child, event.data);
|
swap(child, event.data);
|
||||||
api.triggerEvent(elt, "htmx:sseMessage", event);
|
api.triggerEvent(elt, "htmx:sseMessage", event);
|
||||||
};
|
};
|
||||||
|
@ -159,7 +162,17 @@ This extension adds support for Server Sent Events to htmx. See /www/extensions
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add message handlers for every `hx-trigger="sse:*"` attribute
|
// Add message handlers for every `hx-trigger="sse:*"` attribute
|
||||||
queryAttributeOnThisOrChildren(elt, "hx-trigger").forEach(function (child) {
|
queryAttributeOnThisOrChildren(elt, "hx-trigger").forEach(function(child) {
|
||||||
|
// Find closest existing event source
|
||||||
|
var sourceElement = api.getClosestMatch(child, hasEventSource);
|
||||||
|
if (sourceElement == null) {
|
||||||
|
// api.triggerErrorEvent(elt, "htmx:noSSESourceError")
|
||||||
|
return null; // no eventsource in parentage, orphaned element
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set internalData and source
|
||||||
|
var internalData = api.getInternalData(sourceElement);
|
||||||
|
var source = internalData.sseEventSource;
|
||||||
|
|
||||||
var sseEventName = api.getAttributeValue(child, "hx-trigger");
|
var sseEventName = api.getAttributeValue(child, "hx-trigger");
|
||||||
if (sseEventName == null) {
|
if (sseEventName == null) {
|
||||||
|
@ -174,7 +187,7 @@ This extension adds support for Server Sent Events to htmx. See /www/extensions
|
||||||
// remove the sse: prefix from here on out
|
// remove the sse: prefix from here on out
|
||||||
sseEventName = sseEventName.substr(4);
|
sseEventName = sseEventName.substr(4);
|
||||||
|
|
||||||
var listener = function () {
|
var listener = function() {
|
||||||
if (maybeCloseSSESource(sourceElement)) {
|
if (maybeCloseSSESource(sourceElement)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -201,7 +214,7 @@ This extension adds support for Server Sent Events to htmx. See /www/extensions
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle extension source creation attribute
|
// handle extension source creation attribute
|
||||||
queryAttributeOnThisOrChildren(elt, "sse-connect").forEach(function (child) {
|
queryAttributeOnThisOrChildren(elt, "sse-connect").forEach(function(child) {
|
||||||
var sseURL = api.getAttributeValue(child, "sse-connect");
|
var sseURL = api.getAttributeValue(child, "sse-connect");
|
||||||
if (sseURL == null) {
|
if (sseURL == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -211,7 +224,7 @@ This extension adds support for Server Sent Events to htmx. See /www/extensions
|
||||||
});
|
});
|
||||||
|
|
||||||
// handle legacy sse, remove for HTMX2
|
// handle legacy sse, remove for HTMX2
|
||||||
queryAttributeOnThisOrChildren(elt, "hx-sse").forEach(function (child) {
|
queryAttributeOnThisOrChildren(elt, "hx-sse").forEach(function(child) {
|
||||||
var sseURL = getLegacySSEURL(child);
|
var sseURL = getLegacySSEURL(child);
|
||||||
if (sseURL == null) {
|
if (sseURL == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -220,12 +233,13 @@ This extension adds support for Server Sent Events to htmx. See /www/extensions
|
||||||
ensureEventSource(child, sseURL, retryCount);
|
ensureEventSource(child, sseURL, retryCount);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
registerSSE(elt);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureEventSource(elt, url, retryCount) {
|
function ensureEventSource(elt, url, retryCount) {
|
||||||
var source = htmx.createEventSource(url);
|
var source = htmx.createEventSource(url);
|
||||||
|
|
||||||
source.onerror = function (err) {
|
source.onerror = function(err) {
|
||||||
|
|
||||||
// Log an error event
|
// Log an error event
|
||||||
api.triggerErrorEvent(elt, "htmx:sseError", { error: err, source: source });
|
api.triggerErrorEvent(elt, "htmx:sseError", { error: err, source: source });
|
||||||
|
@ -239,13 +253,13 @@ This extension adds support for Server Sent Events to htmx. See /www/extensions
|
||||||
if (source.readyState === EventSource.CLOSED) {
|
if (source.readyState === EventSource.CLOSED) {
|
||||||
retryCount = retryCount || 0;
|
retryCount = retryCount || 0;
|
||||||
var timeout = Math.random() * (2 ^ retryCount) * 500;
|
var timeout = Math.random() * (2 ^ retryCount) * 500;
|
||||||
window.setTimeout(function () {
|
window.setTimeout(function() {
|
||||||
ensureEventSourceOnElement(elt, Math.min(7, retryCount + 1));
|
ensureEventSourceOnElement(elt, Math.min(7, retryCount + 1));
|
||||||
}, timeout);
|
}, timeout);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
source.onopen = function (evt) {
|
source.onopen = function(evt) {
|
||||||
api.triggerEvent(elt, "htmx:sseOpen", { source: source });
|
api.triggerEvent(elt, "htmx:sseOpen", { source: source });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +301,7 @@ This extension adds support for Server Sent Events to htmx. See /www/extensions
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search all child nodes that match the requested attribute
|
// Search all child nodes that match the requested attribute
|
||||||
elt.querySelectorAll("[" + attributeName + "], [data-" + attributeName + "]").forEach(function (node) {
|
elt.querySelectorAll("[" + attributeName + "], [data-" + attributeName + "]").forEach(function(node) {
|
||||||
result.push(node);
|
result.push(node);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -300,7 +314,7 @@ This extension adds support for Server Sent Events to htmx. See /www/extensions
|
||||||
*/
|
*/
|
||||||
function swap(elt, content) {
|
function swap(elt, content) {
|
||||||
|
|
||||||
api.withExtensions(elt, function (extension) {
|
api.withExtensions(elt, function(extension) {
|
||||||
content = extension.transformResponse(content, null, elt);
|
content = extension.transformResponse(content, null, elt);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -310,7 +324,7 @@ This extension adds support for Server Sent Events to htmx. See /www/extensions
|
||||||
|
|
||||||
api.selectAndSwap(swapSpec.swapStyle, target, elt, content, settleInfo);
|
api.selectAndSwap(swapSpec.swapStyle, target, elt, content, settleInfo);
|
||||||
|
|
||||||
settleInfo.elts.forEach(function (elt) {
|
settleInfo.elts.forEach(function(elt) {
|
||||||
if (elt.classList) {
|
if (elt.classList) {
|
||||||
elt.classList.add(htmx.config.settlingClass);
|
elt.classList.add(htmx.config.settlingClass);
|
||||||
}
|
}
|
||||||
|
@ -334,12 +348,12 @@ This extension adds support for Server Sent Events to htmx. See /www/extensions
|
||||||
*/
|
*/
|
||||||
function doSettle(settleInfo) {
|
function doSettle(settleInfo) {
|
||||||
|
|
||||||
return function () {
|
return function() {
|
||||||
settleInfo.tasks.forEach(function (task) {
|
settleInfo.tasks.forEach(function(task) {
|
||||||
task.call();
|
task.call();
|
||||||
});
|
});
|
||||||
|
|
||||||
settleInfo.elts.forEach(function (elt) {
|
settleInfo.elts.forEach(function(elt) {
|
||||||
if (elt.classList) {
|
if (elt.classList) {
|
||||||
elt.classList.remove(htmx.config.settlingClass);
|
elt.classList.remove(htmx.config.settlingClass);
|
||||||
}
|
}
|
||||||
|
|
5
public/js/htmx.ws.js
vendored
5
public/js/htmx.ws.js
vendored
|
@ -38,13 +38,14 @@ This extension adds support for WebSockets to htmx. See /www/extensions/ws.md f
|
||||||
* @param {Event} evt
|
* @param {Event} evt
|
||||||
*/
|
*/
|
||||||
onEvent: function (name, evt) {
|
onEvent: function (name, evt) {
|
||||||
|
var parent = evt.target || evt.detail.elt;
|
||||||
|
|
||||||
switch (name) {
|
switch (name) {
|
||||||
|
|
||||||
// Try to close the socket when elements are removed
|
// Try to close the socket when elements are removed
|
||||||
case "htmx:beforeCleanupElement":
|
case "htmx:beforeCleanupElement":
|
||||||
|
|
||||||
var internalData = api.getInternalData(evt.target)
|
var internalData = api.getInternalData(parent)
|
||||||
|
|
||||||
if (internalData.webSocket) {
|
if (internalData.webSocket) {
|
||||||
internalData.webSocket.close();
|
internalData.webSocket.close();
|
||||||
|
@ -53,8 +54,6 @@ This extension adds support for WebSockets to htmx. See /www/extensions/ws.md f
|
||||||
|
|
||||||
// Try to create websockets when elements are processed
|
// Try to create websockets when elements are processed
|
||||||
case "htmx:beforeProcessNode":
|
case "htmx:beforeProcessNode":
|
||||||
var parent = evt.target;
|
|
||||||
|
|
||||||
forEach(queryAttributeOnThisOrChildren(parent, "ws-connect"), function (child) {
|
forEach(queryAttributeOnThisOrChildren(parent, "ws-connect"), function (child) {
|
||||||
ensureWebSocket(child)
|
ensureWebSocket(child)
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue