summaryrefslogtreecommitdiffstatshomepage
path: root/www/themes
diff options
context:
space:
mode:
authorCarson Gross <carson@bigsky.software>2023-07-14 14:15:31 -0600
committerCarson Gross <carson@bigsky.software>2023-07-14 14:15:31 -0600
commitac6839e0785a2a38ac8c539ff174381b6e342703 (patch)
treef0bba32bdb5949f763deae4074e209a64e50c4f6 /www/themes
parent2edb023f2004fb4240aa6f1de50a48e2b36591be (diff)
downloadhtmx-ac6839e0785a2a38ac8c539ff174381b6e342703.tar.gz
htmx-ac6839e0785a2a38ac8c539ff174381b6e342703.zip
htmx 1.9.3 release prep
Diffstat (limited to 'www/themes')
-rw-r--r--www/themes/htmx-theme/static/js/htmx.js115
-rw-r--r--www/themes/htmx-theme/static/js/preload.js9
2 files changed, 92 insertions, 32 deletions
diff --git a/www/themes/htmx-theme/static/js/htmx.js b/www/themes/htmx-theme/static/js/htmx.js
index c7ea3f45..556247b2 100644
--- a/www/themes/htmx-theme/static/js/htmx.js
+++ b/www/themes/htmx-theme/static/js/htmx.js
@@ -44,6 +44,7 @@ return (function () {
defineExtension : defineExtension,
removeExtension : removeExtension,
logAll : logAll,
+ logNone : logNone,
logger : null,
config : {
historyEnabled:true,
@@ -71,6 +72,7 @@ return (function () {
defaultFocusScroll: false,
getCacheBusterParam: false,
globalViewTransitions: false,
+ methodsThatUseUrlParams: ["get"],
},
parseInterval:parseInterval,
_:internalEval,
@@ -82,7 +84,7 @@ return (function () {
sock.binaryType = htmx.config.wsBinaryType;
return sock;
},
- version: "1.9.2"
+ version: "1.9.3"
};
/** @type {import("./htmx").HtmxInternalApi} */
@@ -90,9 +92,11 @@ return (function () {
addTriggerHandler: addTriggerHandler,
bodyContains: bodyContains,
canAccessLocalStorage: canAccessLocalStorage,
+ findThisElement: findThisElement,
filterValues: filterValues,
hasAttribute: hasAttribute,
getAttributeValue: getAttributeValue,
+ getClosestAttributeValue: getClosestAttributeValue,
getClosestMatch: getClosestMatch,
getExpressionVars: getExpressionVars,
getHeaders: getHeaders,
@@ -105,6 +109,7 @@ return (function () {
mergeObjects: mergeObjects,
makeSettleInfo: makeSettleInfo,
oobSwap: oobSwap,
+ querySelectorExt: querySelectorExt,
selectAndSwap: selectAndSwap,
settleImmediately: settleImmediately,
shouldCancel: shouldCancel,
@@ -475,6 +480,10 @@ return (function () {
}
}
+ function logNone() {
+ htmx.logger = null
+ }
+
function find(eltOrSelector, selector) {
if (selector) {
return eltOrSelector.querySelector(selector);
@@ -902,6 +911,17 @@ return (function () {
return hash;
}
+ function deInitOnHandlers(elt) {
+ var internalData = getInternalData(elt);
+ if (internalData.onHandlers) {
+ for (let i = 0; i < internalData.onHandlers.length; i++) {
+ const handlerInfo = internalData.onHandlers[i];
+ elt.removeEventListener(handlerInfo.name, handlerInfo.handler);
+ }
+ delete internalData.onHandlers
+ }
+ }
+
function deInitNode(element) {
var internalData = getInternalData(element);
if (internalData.timeout) {
@@ -920,12 +940,7 @@ return (function () {
}
});
}
- if (internalData.onHandlers) {
- for (let i = 0; i < internalData.onHandlers.length; i++) {
- const handlerInfo = internalData.onHandlers[i];
- element.removeEventListener(handlerInfo.name, handlerInfo.handler);
- }
- }
+ deInitOnHandlers(element);
}
function cleanUpElement(element) {
@@ -950,7 +965,7 @@ return (function () {
newElt = eltBeforeNewContent.nextSibling;
}
getInternalData(target).replacedWith = newElt; // tuck away so we can fire events on it later
- settleInfo.elts = [] // clear existing elements
+ settleInfo.elts = settleInfo.elts.filter(e => e != target);
while(newElt && newElt !== target) {
if (newElt.nodeType === Node.ELEMENT_NODE) {
settleInfo.elts.push(newElt);
@@ -1299,7 +1314,10 @@ return (function () {
var nodeData = getInternalData(elt);
nodeData.timeout = setTimeout(function () {
if (bodyContains(elt) && nodeData.cancelled !== true) {
- if (!maybeFilterEvent(spec, makeEvent('hx:poll:trigger', {triggerSpec:spec, target:elt}))) {
+ if (!maybeFilterEvent(spec, elt, makeEvent('hx:poll:trigger', {
+ triggerSpec: spec,
+ target: elt
+ }))) {
handler(elt);
}
processPolling(elt, handler, spec);
@@ -1361,11 +1379,11 @@ return (function () {
return getInternalData(elt).boosted && elt.tagName === "A" && evt.type === "click" && (evt.ctrlKey || evt.metaKey);
}
- function maybeFilterEvent(triggerSpec, evt) {
+ function maybeFilterEvent(triggerSpec, elt, evt) {
var eventFilter = triggerSpec.eventFilter;
if(eventFilter){
try {
- return eventFilter(evt) !== true;
+ return eventFilter.call(elt, evt) !== true;
} catch(e) {
triggerErrorEvent(getDocument().body, "htmx:eventFilter:error", {error: e, source:eventFilter.source});
return true;
@@ -1398,7 +1416,7 @@ return (function () {
if (explicitCancel || shouldCancel(evt, elt)) {
evt.preventDefault();
}
- if (maybeFilterEvent(triggerSpec, evt)) {
+ if (maybeFilterEvent(triggerSpec, elt, evt)) {
return;
}
var eventData = getInternalData(evt);
@@ -1650,6 +1668,9 @@ return (function () {
var sseEventSource = getInternalData(sseSourceElt).sseEventSource;
var sseListener = function (event) {
if (maybeCloseSSESource(sseSourceElt)) {
+ return;
+ }
+ if (!bodyContains(elt)) {
sseEventSource.removeEventListener(sseEventName, sseListener);
return;
}
@@ -1666,7 +1687,7 @@ return (function () {
var target = getTarget(elt)
var settleInfo = makeSettleInfo(elt);
- selectAndSwap(swapSpec.swapStyle, elt, target, response, settleInfo)
+ selectAndSwap(swapSpec.swapStyle, target, elt, response, settleInfo)
settleImmediately(settleInfo.tasks)
triggerEvent(elt, "htmx:sseMessage", event)
};
@@ -1770,7 +1791,7 @@ return (function () {
observer.observe(elt);
addEventListener(elt, handler, nodeData, triggerSpec);
} else if (triggerSpec.trigger === "load") {
- if (!maybeFilterEvent(triggerSpec, makeEvent("load", {elt:elt}))) {
+ if (!maybeFilterEvent(triggerSpec, elt, makeEvent("load", {elt: elt}))) {
loadImmediately(elt, handler, nodeData, triggerSpec.delay);
}
} else if (triggerSpec.pollInterval) {
@@ -1820,6 +1841,16 @@ return (function () {
return document.querySelector("[hx-boost], [data-hx-boost]");
}
+ function findHxOnWildcardElements(elt) {
+ if (!document.evaluate) return []
+
+ let node = null
+ const elements = []
+ const iter = document.evaluate('//*[@*[ starts-with(name(), "hx-on:") or starts-with(name(), "data-hx-on:") ]]', elt)
+ while (node = iter.iterateNext()) elements.push(node)
+ return elements
+ }
+
function findElementsToProcess(elt) {
if (elt.querySelectorAll) {
var boostedElts = hasChanceOfBeingBoosted() ? ", a, form" : "";
@@ -1879,7 +1910,7 @@ return (function () {
function processHxOn(elt) {
var hxOnValue = getAttributeValue(elt, 'hx-on');
- if (hxOnValue) {
+ if (hxOnValue && htmx.config.allowEval) {
var handlers = {}
var lines = hxOnValue.split("\n");
var currentEvent = null;
@@ -1903,6 +1934,22 @@ return (function () {
}
}
+ function processHxOnWildcard(elt) {
+ // wipe any previous on handlers so that this function takes precedence
+ deInitOnHandlers(elt)
+
+ for (const attr of elt.attributes) {
+ const { name, value } = attr
+ if (name.startsWith("hx-on:") || name.startsWith("data-hx-on:")) {
+ let eventName = name.slice(name.indexOf(":") + 1)
+ // if the eventName starts with a colon, prepend "htmx" for shorthand support
+ if (eventName.startsWith(":")) eventName = "htmx" + eventName
+
+ addHxOnEventHandler(elt, eventName, value)
+ }
+ }
+ }
+
function initNode(elt) {
if (elt.closest && elt.closest(htmx.config.disableSelector)) {
return;
@@ -1959,6 +2006,9 @@ return (function () {
elt = resolveTarget(elt);
initNode(elt);
forEach(findElementsToProcess(elt), function(child) { initNode(child) });
+ // Because it happens second, the new way of adding onHandlers superseeds the old one
+ // i.e. if there are any hx-on:eventName attributes, the hx-on attribute will be ignored
+ forEach(findHxOnWildcardElements(elt), processHxOnWildcard);
}
//====================================================================
@@ -2196,7 +2246,9 @@ return (function () {
swapInnerHTML(historyElement, fragment, settleInfo)
settleImmediately(settleInfo.tasks);
document.title = cached.title;
- window.scrollTo(0, cached.scroll);
+ setTimeout(function () {
+ window.scrollTo(0, cached.scroll);
+ }, 0); // next 'tick', so browser has time to render layout
currentPathForHistory = path;
triggerEvent(getDocument().body, "htmx:historyRestore", {path:path, item:cached});
} else {
@@ -2925,8 +2977,12 @@ return (function () {
var requestAttrValues = getValuesForElement(elt, 'hx-request');
var eltIsBoosted = getInternalData(elt).boosted;
+
+ var useUrlParams = htmx.config.methodsThatUseUrlParams.indexOf(verb) >= 0
+
var requestConfig = {
boosted: eltIsBoosted,
+ useUrlParams: useUrlParams,
parameters: filteredParameters,
unfilteredParameters: allParameters,
headers:headers,
@@ -2951,6 +3007,7 @@ return (function () {
headers = requestConfig.headers;
filteredParameters = requestConfig.parameters;
errors = requestConfig.errors;
+ useUrlParams = requestConfig.useUrlParams;
if(errors && errors.length > 0){
triggerEvent(elt, 'htmx:validation:halted', requestConfig)
@@ -2962,26 +3019,25 @@ return (function () {
var splitPath = path.split("#");
var pathNoAnchor = splitPath[0];
var anchor = splitPath[1];
- var finalPathForGet = null;
- if (verb === 'get') {
- finalPathForGet = pathNoAnchor;
+
+ var finalPath = path
+ if (useUrlParams) {
+ finalPath = pathNoAnchor;
var values = Object.keys(filteredParameters).length !== 0;
if (values) {
- if (finalPathForGet.indexOf("?") < 0) {
- finalPathForGet += "?";
+ if (finalPath.indexOf("?") < 0) {
+ finalPath += "?";
} else {
- finalPathForGet += "&";
+ finalPath += "&";
}
- finalPathForGet += urlEncode(filteredParameters);
+ finalPath += urlEncode(filteredParameters);
if (anchor) {
- finalPathForGet += "#" + anchor;
+ finalPath += "#" + anchor;
}
}
- xhr.open('GET', finalPathForGet, true);
- } else {
- xhr.open(verb.toUpperCase(), path, true);
}
+ xhr.open(verb.toUpperCase(), finalPath, true);
xhr.overrideMimeType("text/html");
xhr.withCredentials = requestConfig.withCredentials;
xhr.timeout = requestConfig.timeout;
@@ -3002,7 +3058,7 @@ return (function () {
xhr: xhr, target: target, requestConfig: requestConfig, etc: etc, boosted: eltIsBoosted,
pathInfo: {
requestPath: path,
- finalRequestPath: finalPathForGet || path,
+ finalRequestPath: finalPath,
anchor: anchor
}
};
@@ -3077,7 +3133,8 @@ return (function () {
});
});
triggerEvent(elt, 'htmx:beforeSend', responseInfo);
- xhr.send(verb === 'get' ? null : encodeParamsForBody(xhr, elt, filteredParameters));
+ var params = useUrlParams ? null : encodeParamsForBody(xhr, elt, filteredParameters)
+ xhr.send(params);
return promise;
}
diff --git a/www/themes/htmx-theme/static/js/preload.js b/www/themes/htmx-theme/static/js/preload.js
index 21e966f8..f68feab5 100644
--- a/www/themes/htmx-theme/static/js/preload.js
+++ b/www/themes/htmx-theme/static/js/preload.js
@@ -48,9 +48,12 @@ htmx.defineExtension("preload", {
// in the future
var hxGet = node.getAttribute("hx-get") || node.getAttribute("data-hx-get")
if (hxGet) {
- htmx.ajax("GET", hxGet, {handler:function(elt, info) {
- done(info.xhr.responseText);
- }});
+ htmx.ajax("GET", hxGet, {
+ source: node,
+ handler:function(elt, info) {
+ done(info.xhr.responseText);
+ }
+ });
return;
}