diff options
author | Carson Gross <carson@bigsky.software> | 2024-08-05 13:53:33 -0600 |
---|---|---|
committer | Carson Gross <carson@bigsky.software> | 2024-08-05 13:53:33 -0600 |
commit | 82355a741d62ea495bb1f83e8f7597c4a2202a6d (patch) | |
tree | 90e5cf40e56af9966c87949ecc07e8aea459c5ad /www/static/src/htmx.js | |
parent | 97b8c68dd3af4ee13e7933b4ca710a0761acee96 (diff) | |
download | htmx-82355a741d62ea495bb1f83e8f7597c4a2202a6d.tar.gz htmx-82355a741d62ea495bb1f83e8f7597c4a2202a6d.zip |
release prep
Diffstat (limited to 'www/static/src/htmx.js')
-rw-r--r-- | www/static/src/htmx.js | 64 |
1 files changed, 43 insertions, 21 deletions
diff --git a/www/static/src/htmx.js b/www/static/src/htmx.js index 834c6779..e7613d15 100644 --- a/www/static/src/htmx.js +++ b/www/static/src/htmx.js @@ -206,7 +206,7 @@ var htmx = (function() { disableSelector: '[hx-disable], [data-hx-disable]', /** * @type {'auto' | 'instant' | 'smooth'} - * @default 'smooth' + * @default 'instant' */ scrollBehavior: 'instant', /** @@ -277,7 +277,7 @@ var htmx = (function() { parseInterval: null, /** @type {typeof internalEval} */ _: null, - version: '2.0.1' + version: '2.0.2' } // Tsc madness part 2 htmx.onLoad = onLoadHelper @@ -1639,13 +1639,13 @@ var htmx = (function() { newElt = eltBeforeNewContent.nextSibling } settleInfo.elts = settleInfo.elts.filter(function(e) { return e !== target }) + // scan through all newly added content and add all elements to the settle info so we trigger + // events properly on them while (newElt && newElt !== target) { if (newElt instanceof Element) { settleInfo.elts.push(newElt) - newElt = newElt.nextElementSibling - } else { - newElt = null } + newElt = newElt.nextSibling } cleanUpElement(target) if (target instanceof Element) { @@ -1753,7 +1753,7 @@ var htmx = (function() { try { const newElements = ext.handleSwap(swapStyle, target, fragment, settleInfo) if (newElements) { - if (typeof newElements.length !== 'undefined') { + if (Array.isArray(newElements)) { // if handleSwap returns an array (like) of elements, we handle them for (let j = 0; j < newElements.length; j++) { const child = newElements[j] @@ -1781,7 +1781,8 @@ var htmx = (function() { * @param {HtmxSettleInfo} settleInfo */ function findAndSwapOobElements(fragment, settleInfo) { - forEach(findAll(fragment, '[hx-swap-oob], [data-hx-swap-oob]'), function(oobElement) { + var oobElts = findAll(fragment, '[hx-swap-oob], [data-hx-swap-oob]') + forEach(oobElts, function(oobElement) { if (htmx.config.allowNestedOobSwaps || oobElement.parentElement === null) { const oobValue = getAttributeValue(oobElement, 'hx-swap-oob') if (oobValue != null) { @@ -1792,6 +1793,7 @@ var htmx = (function() { oobElement.removeAttribute('data-hx-swap-oob') } }) + return oobElts.length > 0 } /** @@ -1853,9 +1855,8 @@ var htmx = (function() { // oob swaps findAndSwapOobElements(fragment, settleInfo) forEach(findAll(fragment, 'template'), /** @param {HTMLTemplateElement} template */function(template) { - findAndSwapOobElements(template.content, settleInfo) - if (template.content.childElementCount === 0 && template.content.textContent.trim() === '') { - // Avoid polluting the DOM with empty templates that were only used to encapsulate oob swap + if (findAndSwapOobElements(template.content, settleInfo)) { + // Avoid polluting the DOM with empty templates that were only used to encapsulate oob swap template.remove() } }) @@ -1952,7 +1953,10 @@ var htmx = (function() { for (const eventName in triggers) { if (triggers.hasOwnProperty(eventName)) { let detail = triggers[eventName] - if (!isRawObject(detail)) { + if (isRawObject(detail)) { + // @ts-ignore + elt = detail.target !== undefined ? detail.target : elt + } else { detail = { value: detail } } triggerEvent(elt, eventName, detail) @@ -2273,7 +2277,7 @@ var htmx = (function() { * @param {HtmxTriggerSpecification[]} triggerSpecs */ function boostElement(elt, nodeData, triggerSpecs) { - if ((elt instanceof HTMLAnchorElement && isLocalLink(elt) && (elt.target === '' || elt.target === '_self')) || elt.tagName === 'FORM') { + if ((elt instanceof HTMLAnchorElement && isLocalLink(elt) && (elt.target === '' || elt.target === '_self')) || (elt.tagName === 'FORM' && String(getRawAttribute(elt, 'method')).toLowerCase() !== 'dialog')) { nodeData.boosted = true let verb, path if (elt.tagName === 'A') { @@ -2435,13 +2439,17 @@ var htmx = (function() { if (triggerSpec.throttle > 0) { if (!elementData.throttle) { + triggerEvent(elt, 'htmx:trigger') handler(elt, evt) elementData.throttle = getWindow().setTimeout(function() { elementData.throttle = null }, triggerSpec.throttle) } } else if (triggerSpec.delay > 0) { - elementData.delayed = getWindow().setTimeout(function() { handler(elt, evt) }, triggerSpec.delay) + elementData.delayed = getWindow().setTimeout(function() { + triggerEvent(elt, 'htmx:trigger') + handler(elt, evt) + }, triggerSpec.delay) } else { triggerEvent(elt, 'htmx:trigger') handler(elt, evt) @@ -3059,6 +3067,10 @@ var htmx = (function() { forEach(findAll(clone, '.' + className), function(child) { removeClassFromElement(child, className) }) + // remove the disabled attribute for any element disabled due to an htmx request + forEach(findAll(clone, '[data-disabled-by-htmx]'), function(child) { + child.removeAttribute('disabled') + }) return clone.innerHTML } @@ -3212,6 +3224,7 @@ var htmx = (function() { const internalData = getInternalData(disabledElement) internalData.requestCount = (internalData.requestCount || 0) + 1 disabledElement.setAttribute('disabled', '') + disabledElement.setAttribute('data-disabled-by-htmx', '') }) return disabledElts } @@ -3233,6 +3246,7 @@ var htmx = (function() { internalData.requestCount = (internalData.requestCount || 0) - 1 if (internalData.requestCount === 0) { disabledElement.removeAttribute('disabled') + disabledElement.removeAttribute('data-disabled-by-htmx') } }) } @@ -3382,10 +3396,10 @@ var htmx = (function() { function overrideFormData(receiver, donor) { for (const key of donor.keys()) { receiver.delete(key) - donor.getAll(key).forEach(function(value) { - receiver.append(key, value) - }) } + donor.forEach(function(value, key) { + receiver.append(key, value) + }) return receiver } @@ -3915,7 +3929,7 @@ var htmx = (function() { if (obj.hasOwnProperty(key)) { if (typeof obj[key].forEach === 'function') { obj[key].forEach(function(v) { formData.append(key, v) }) - } else if (typeof obj[key] === 'object') { + } else if (typeof obj[key] === 'object' && !(obj[key] instanceof Blob)) { formData.append(key, JSON.stringify(obj[key])) } else { formData.append(key, obj[key]) @@ -4008,6 +4022,8 @@ var htmx = (function() { target.delete(name) if (typeof value.forEach === 'function') { value.forEach(function(v) { target.append(name, v) }) + } else if (typeof value === 'object' && !(value instanceof Blob)) { + target.append(name, JSON.stringify(value)) } else { target.append(name, value) } @@ -4343,7 +4359,9 @@ var htmx = (function() { const hierarchy = hierarchyForElt(elt) responseInfo.pathInfo.responsePath = getPathFromResponse(xhr) responseHandler(elt, responseInfo) - removeRequestIndicators(indicators, disableElts) + if (responseInfo.keepIndicators !== true) { + removeRequestIndicators(indicators, disableElts) + } triggerEvent(elt, 'htmx:afterRequest', responseInfo) triggerEvent(elt, 'htmx:afterOnLoad', responseInfo) // if the body no longer contains the element, trigger the event on the closest parent @@ -4583,12 +4601,14 @@ var htmx = (function() { const shouldRefresh = hasHeader(xhr, /HX-Refresh:/i) && xhr.getResponseHeader('HX-Refresh') === 'true' if (hasHeader(xhr, /HX-Redirect:/i)) { + responseInfo.keepIndicators = true location.href = xhr.getResponseHeader('HX-Redirect') shouldRefresh && location.reload() return } if (shouldRefresh) { + responseInfo.keepIndicators = true location.reload() return } @@ -5072,6 +5092,7 @@ var htmx = (function() { * @property {{requestPath: string, finalRequestPath: string, responsePath: string|null, anchor: string}} pathInfo * @property {boolean} [failed] * @property {boolean} [successful] + * @property {boolean} [keepIndicators] */ /** @@ -5121,12 +5142,13 @@ var htmx = (function() { */ /** + * @see https://github.com/bigskysoftware/htmx-extensions/blob/main/README.md * @typedef {Object} HtmxExtension - * @see https://htmx.org/extensions/#defining * @property {(api: any) => void} init * @property {(name: string, event: Event|CustomEvent) => boolean} onEvent * @property {(text: string, xhr: XMLHttpRequest, elt: Element) => string} transformResponse * @property {(swapStyle: HtmxSwapStyle) => boolean} isInlineSwap - * @property {(swapStyle: HtmxSwapStyle, target: Element, fragment: Node, settleInfo: HtmxSettleInfo) => boolean} handleSwap - * @property {(xhr: XMLHttpRequest, parameters: FormData, elt: Element) => *|string|null} encodeParameters + * @property {(swapStyle: HtmxSwapStyle, target: Node, fragment: Node, settleInfo: HtmxSettleInfo) => boolean|Node[]} handleSwap + * @property {(xhr: XMLHttpRequest, parameters: FormData, elt: Node) => *|string|null} encodeParameters + * @property {() => string[]|null} getSelectors */ |