diff options
author | Carson Gross <carson@bigsky.software> | 2023-01-17 13:38:51 -0700 |
---|---|---|
committer | Carson Gross <carson@bigsky.software> | 2023-01-17 13:38:51 -0700 |
commit | 307e3eb227823c8094927aec5f1c7359d211faa6 (patch) | |
tree | 192841b2311abc21e53e308f36b6211f8576daa1 /dist/htmx.js | |
parent | 8d35686cf9856c82818ca8838eeba382c45d0f43 (diff) | |
download | htmx-307e3eb227823c8094927aec5f1c7359d211faa6.tar.gz htmx-307e3eb227823c8094927aec5f1c7359d211faa6.zip |
prep for 1.8.5 release
Diffstat (limited to 'dist/htmx.js')
-rw-r--r-- | dist/htmx.js | 61 |
1 files changed, 49 insertions, 12 deletions
diff --git a/dist/htmx.js b/dist/htmx.js index c5d03423..39fe8d35 100644 --- a/dist/htmx.js +++ b/dist/htmx.js @@ -58,10 +58,12 @@ return (function () { withCredentials:false, timeout:0, wsReconnectDelay: 'full-jitter', + wsBinaryType: 'blob', disableSelector: "[hx-disable], [data-hx-disable]", useTemplateFragments: false, scrollBehavior: 'smooth', defaultFocusScroll: false, + getCacheBusterParam: false, }, parseInterval:parseInterval, _:internalEval, @@ -69,9 +71,11 @@ return (function () { return new EventSource(url, {withCredentials:true}) }, createWebSocket: function(url){ - return new WebSocket(url, []); + var sock = new WebSocket(url, []); + sock.binaryType = htmx.config.wsBinaryType; + return sock; }, - version: "1.8.4" + version: "1.8.5" }; /** @type {import("./htmx").HtmxInternalApi} */ @@ -509,12 +513,14 @@ return (function () { if (elt.closest) { return elt.closest(selector); } else { + // TODO remove when IE goes away do{ if (elt == null || matches(elt, selector)){ return elt; } } while (elt = elt && parentElt(elt)); + return null; } } @@ -1261,7 +1267,7 @@ return (function () { path = getRawAttribute(elt, 'action'); } triggerSpecs.forEach(function(triggerSpec) { - addEventListener(elt, function(evt) { + addEventListener(elt, function(elt, evt) { issueAjaxRequest(verb, path, elt, evt) }, nodeData, triggerSpec, true); }); @@ -1727,7 +1733,10 @@ return (function () { } catch (e) { logError(e); } finally { - parent.removeChild(script); + // remove old script element, but only if it is still in DOM + if (script.parentElement) { + script.parentElement.removeChild(script); + } } } } @@ -1758,9 +1767,10 @@ return (function () { function initButtonTracking(form){ var maybeSetLastButtonClicked = function(evt){ - if (matches(evt.target, "button, input[type='submit']")) { + var elt = closest(evt.target, "button, input[type='submit']"); + if (elt !== null) { var internalData = getInternalData(form); - internalData.lastButtonClicked = evt.target; + internalData.lastButtonClicked = elt; } }; @@ -1969,13 +1979,32 @@ return (function () { function saveCurrentPageToHistory() { var elt = getHistoryElement(); var path = currentPathForHistory || location.pathname+location.search; - triggerEvent(getDocument().body, "htmx:beforeHistorySave", {path:path, historyElt:elt}); - if(htmx.config.historyEnabled) history.replaceState({htmx:true}, getDocument().title, window.location.href); - saveToHistoryCache(path, cleanInnerHtmlForHistory(elt), getDocument().title, window.scrollY); + + // Allow history snapshot feature to be disabled where hx-history="false" + // is present *anywhere* in the current document we're about to save, + // so we can prevent privileged data entering the cache. + // The page will still be reachable as a history entry, but htmx will fetch it + // live from the server onpopstate rather than look in the localStorage cache + var disableHistoryCache = getDocument().querySelector('[hx-history="false" i],[data-hx-history="false" i]'); + if (!disableHistoryCache) { + triggerEvent(getDocument().body, "htmx:beforeHistorySave", {path: path, historyElt: elt}); + saveToHistoryCache(path, cleanInnerHtmlForHistory(elt), getDocument().title, window.scrollY); + } + + if (htmx.config.historyEnabled) history.replaceState({htmx: true}, getDocument().title, window.location.href); } function pushUrlIntoHistory(path) { - if(htmx.config.historyEnabled) history.pushState({htmx:true}, "", path); + // remove the cache buster parameter, if any + if (htmx.config.getCacheBusterParam) { + path = path.replace(/org\.htmx\.cache-buster=[^&]*&?/, '') + if (path.endsWith('&') || path.endsWith("?")) { + path = path.slice(0, -1); + } + } + if(htmx.config.historyEnabled) { + history.pushState({htmx:true}, "", path); + } currentPathForHistory = path; } @@ -2121,7 +2150,7 @@ return (function () { // and the new value could be arrays, so we have to handle all four cases :/ if (name != null && value != null) { var current = values[name]; - if(current) { + if (current !== undefined) { if (Array.isArray(current)) { if (Array.isArray(value)) { values[name] = current.concat(value); @@ -2749,6 +2778,10 @@ return (function () { headers['Content-Type'] = 'application/x-www-form-urlencoded'; } + if (htmx.config.getCacheBusterParam && verb === 'get') { + filteredParameters['org.htmx.cache-buster'] = getRawAttribute(target, "id") || "true"; + } + // behavior of anchors w/ empty href is to use the current URL if (path == null || path === "") { path = getDocument().location.href; @@ -3108,7 +3141,11 @@ return (function () { // @ts-ignore if (selectionInfo.start && newActiveElt.setSelectionRange) { // @ts-ignore - newActiveElt.setSelectionRange(selectionInfo.start, selectionInfo.end); + try { + newActiveElt.setSelectionRange(selectionInfo.start, selectionInfo.end); + } catch (e) { + // the setSelectionRange method is present on fields that don't support it, so just let this fail + } } newActiveElt.focus(focusOptions); } |