htmx.org 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -4
- package/dist/ext/README.md +9 -0
- package/dist/ext/ajax-header.js +11 -0
- package/dist/ext/alpine-morph.js +20 -0
- package/dist/ext/class-tools.js +97 -0
- package/dist/ext/client-side-templates.js +100 -0
- package/dist/ext/debug.js +15 -0
- package/dist/ext/disable-element.js +20 -0
- package/dist/ext/event-header.js +41 -0
- package/dist/ext/head-support.js +146 -0
- package/dist/ext/include-vals.js +28 -0
- package/dist/ext/json-enc.js +16 -0
- package/dist/ext/loading-states.js +189 -0
- package/dist/ext/method-override.js +15 -0
- package/dist/ext/morphdom-swap.js +21 -0
- package/dist/ext/multi-swap.js +50 -0
- package/dist/ext/path-deps.js +63 -0
- package/dist/ext/path-params.js +15 -0
- package/dist/ext/preload.js +151 -0
- package/dist/ext/rails-method.js +14 -0
- package/dist/ext/remove-me.js +31 -0
- package/dist/ext/response-targets.js +135 -0
- package/dist/ext/restored.js +19 -0
- package/dist/ext/sse.js +374 -0
- package/dist/ext/ws.js +481 -0
- package/dist/htmx.amd.js +47 -22
- package/dist/htmx.cjs.js +47 -22
- package/dist/htmx.esm.d.ts +205 -0
- package/dist/htmx.esm.js +47 -22
- package/dist/htmx.js +47 -22
- package/dist/htmx.min.js +1 -1
- package/dist/htmx.min.js.gz +0 -0
- package/editors/jetbrains/htmx.web-types.json +1 -1
- package/package.json +11 -8
- package/CHANGELOG.md +0 -485
package/dist/htmx.amd.js
CHANGED
|
@@ -207,7 +207,7 @@ var htmx = (function() {
|
|
|
207
207
|
disableSelector: '[hx-disable], [data-hx-disable]',
|
|
208
208
|
/**
|
|
209
209
|
* @type {'auto' | 'instant' | 'smooth'}
|
|
210
|
-
* @default '
|
|
210
|
+
* @default 'instant'
|
|
211
211
|
*/
|
|
212
212
|
scrollBehavior: 'instant',
|
|
213
213
|
/**
|
|
@@ -278,7 +278,7 @@ var htmx = (function() {
|
|
|
278
278
|
parseInterval: null,
|
|
279
279
|
/** @type {typeof internalEval} */
|
|
280
280
|
_: null,
|
|
281
|
-
version: '2.0.
|
|
281
|
+
version: '2.0.2'
|
|
282
282
|
}
|
|
283
283
|
// Tsc madness part 2
|
|
284
284
|
htmx.onLoad = onLoadHelper
|
|
@@ -1627,6 +1627,9 @@ var htmx = (function() {
|
|
|
1627
1627
|
* @param {HtmxSettleInfo} settleInfo
|
|
1628
1628
|
*/
|
|
1629
1629
|
function swapOuterHTML(target, fragment, settleInfo) {
|
|
1630
|
+
if (target instanceof Element && target.tagName === 'BODY') { // special case the body to innerHTML because DocumentFragments can't contain a body elt unfortunately
|
|
1631
|
+
return swapInnerHTML(target, fragment, settleInfo)
|
|
1632
|
+
}
|
|
1630
1633
|
/** @type {Node} */
|
|
1631
1634
|
let newElt
|
|
1632
1635
|
const eltBeforeNewContent = target.previousSibling
|
|
@@ -1637,13 +1640,13 @@ var htmx = (function() {
|
|
|
1637
1640
|
newElt = eltBeforeNewContent.nextSibling
|
|
1638
1641
|
}
|
|
1639
1642
|
settleInfo.elts = settleInfo.elts.filter(function(e) { return e !== target })
|
|
1643
|
+
// scan through all newly added content and add all elements to the settle info so we trigger
|
|
1644
|
+
// events properly on them
|
|
1640
1645
|
while (newElt && newElt !== target) {
|
|
1641
1646
|
if (newElt instanceof Element) {
|
|
1642
1647
|
settleInfo.elts.push(newElt)
|
|
1643
|
-
newElt = newElt.nextElementSibling
|
|
1644
|
-
} else {
|
|
1645
|
-
newElt = null
|
|
1646
1648
|
}
|
|
1649
|
+
newElt = newElt.nextSibling
|
|
1647
1650
|
}
|
|
1648
1651
|
cleanUpElement(target)
|
|
1649
1652
|
if (target instanceof Element) {
|
|
@@ -1751,7 +1754,7 @@ var htmx = (function() {
|
|
|
1751
1754
|
try {
|
|
1752
1755
|
const newElements = ext.handleSwap(swapStyle, target, fragment, settleInfo)
|
|
1753
1756
|
if (newElements) {
|
|
1754
|
-
if (
|
|
1757
|
+
if (Array.isArray(newElements)) {
|
|
1755
1758
|
// if handleSwap returns an array (like) of elements, we handle them
|
|
1756
1759
|
for (let j = 0; j < newElements.length; j++) {
|
|
1757
1760
|
const child = newElements[j]
|
|
@@ -1779,7 +1782,8 @@ var htmx = (function() {
|
|
|
1779
1782
|
* @param {HtmxSettleInfo} settleInfo
|
|
1780
1783
|
*/
|
|
1781
1784
|
function findAndSwapOobElements(fragment, settleInfo) {
|
|
1782
|
-
|
|
1785
|
+
var oobElts = findAll(fragment, '[hx-swap-oob], [data-hx-swap-oob]')
|
|
1786
|
+
forEach(oobElts, function(oobElement) {
|
|
1783
1787
|
if (htmx.config.allowNestedOobSwaps || oobElement.parentElement === null) {
|
|
1784
1788
|
const oobValue = getAttributeValue(oobElement, 'hx-swap-oob')
|
|
1785
1789
|
if (oobValue != null) {
|
|
@@ -1790,6 +1794,7 @@ var htmx = (function() {
|
|
|
1790
1794
|
oobElement.removeAttribute('data-hx-swap-oob')
|
|
1791
1795
|
}
|
|
1792
1796
|
})
|
|
1797
|
+
return oobElts.length > 0
|
|
1793
1798
|
}
|
|
1794
1799
|
|
|
1795
1800
|
/**
|
|
@@ -1851,9 +1856,8 @@ var htmx = (function() {
|
|
|
1851
1856
|
// oob swaps
|
|
1852
1857
|
findAndSwapOobElements(fragment, settleInfo)
|
|
1853
1858
|
forEach(findAll(fragment, 'template'), /** @param {HTMLTemplateElement} template */function(template) {
|
|
1854
|
-
findAndSwapOobElements(template.content, settleInfo)
|
|
1855
|
-
|
|
1856
|
-
// Avoid polluting the DOM with empty templates that were only used to encapsulate oob swap
|
|
1859
|
+
if (findAndSwapOobElements(template.content, settleInfo)) {
|
|
1860
|
+
// Avoid polluting the DOM with empty templates that were only used to encapsulate oob swap
|
|
1857
1861
|
template.remove()
|
|
1858
1862
|
}
|
|
1859
1863
|
})
|
|
@@ -1950,7 +1954,10 @@ var htmx = (function() {
|
|
|
1950
1954
|
for (const eventName in triggers) {
|
|
1951
1955
|
if (triggers.hasOwnProperty(eventName)) {
|
|
1952
1956
|
let detail = triggers[eventName]
|
|
1953
|
-
if (
|
|
1957
|
+
if (isRawObject(detail)) {
|
|
1958
|
+
// @ts-ignore
|
|
1959
|
+
elt = detail.target !== undefined ? detail.target : elt
|
|
1960
|
+
} else {
|
|
1954
1961
|
detail = { value: detail }
|
|
1955
1962
|
}
|
|
1956
1963
|
triggerEvent(elt, eventName, detail)
|
|
@@ -2271,7 +2278,7 @@ var htmx = (function() {
|
|
|
2271
2278
|
* @param {HtmxTriggerSpecification[]} triggerSpecs
|
|
2272
2279
|
*/
|
|
2273
2280
|
function boostElement(elt, nodeData, triggerSpecs) {
|
|
2274
|
-
if ((elt instanceof HTMLAnchorElement && isLocalLink(elt) && (elt.target === '' || elt.target === '_self')) || elt.tagName === 'FORM') {
|
|
2281
|
+
if ((elt instanceof HTMLAnchorElement && isLocalLink(elt) && (elt.target === '' || elt.target === '_self')) || (elt.tagName === 'FORM' && String(getRawAttribute(elt, 'method')).toLowerCase() !== 'dialog')) {
|
|
2275
2282
|
nodeData.boosted = true
|
|
2276
2283
|
let verb, path
|
|
2277
2284
|
if (elt.tagName === 'A') {
|
|
@@ -2433,13 +2440,17 @@ var htmx = (function() {
|
|
|
2433
2440
|
|
|
2434
2441
|
if (triggerSpec.throttle > 0) {
|
|
2435
2442
|
if (!elementData.throttle) {
|
|
2443
|
+
triggerEvent(elt, 'htmx:trigger')
|
|
2436
2444
|
handler(elt, evt)
|
|
2437
2445
|
elementData.throttle = getWindow().setTimeout(function() {
|
|
2438
2446
|
elementData.throttle = null
|
|
2439
2447
|
}, triggerSpec.throttle)
|
|
2440
2448
|
}
|
|
2441
2449
|
} else if (triggerSpec.delay > 0) {
|
|
2442
|
-
elementData.delayed = getWindow().setTimeout(function() {
|
|
2450
|
+
elementData.delayed = getWindow().setTimeout(function() {
|
|
2451
|
+
triggerEvent(elt, 'htmx:trigger')
|
|
2452
|
+
handler(elt, evt)
|
|
2453
|
+
}, triggerSpec.delay)
|
|
2443
2454
|
} else {
|
|
2444
2455
|
triggerEvent(elt, 'htmx:trigger')
|
|
2445
2456
|
handler(elt, evt)
|
|
@@ -3057,6 +3068,10 @@ var htmx = (function() {
|
|
|
3057
3068
|
forEach(findAll(clone, '.' + className), function(child) {
|
|
3058
3069
|
removeClassFromElement(child, className)
|
|
3059
3070
|
})
|
|
3071
|
+
// remove the disabled attribute for any element disabled due to an htmx request
|
|
3072
|
+
forEach(findAll(clone, '[data-disabled-by-htmx]'), function(child) {
|
|
3073
|
+
child.removeAttribute('disabled')
|
|
3074
|
+
})
|
|
3060
3075
|
return clone.innerHTML
|
|
3061
3076
|
}
|
|
3062
3077
|
|
|
@@ -3210,6 +3225,7 @@ var htmx = (function() {
|
|
|
3210
3225
|
const internalData = getInternalData(disabledElement)
|
|
3211
3226
|
internalData.requestCount = (internalData.requestCount || 0) + 1
|
|
3212
3227
|
disabledElement.setAttribute('disabled', '')
|
|
3228
|
+
disabledElement.setAttribute('data-disabled-by-htmx', '')
|
|
3213
3229
|
})
|
|
3214
3230
|
return disabledElts
|
|
3215
3231
|
}
|
|
@@ -3231,6 +3247,7 @@ var htmx = (function() {
|
|
|
3231
3247
|
internalData.requestCount = (internalData.requestCount || 0) - 1
|
|
3232
3248
|
if (internalData.requestCount === 0) {
|
|
3233
3249
|
disabledElement.removeAttribute('disabled')
|
|
3250
|
+
disabledElement.removeAttribute('data-disabled-by-htmx')
|
|
3234
3251
|
}
|
|
3235
3252
|
})
|
|
3236
3253
|
}
|
|
@@ -3380,10 +3397,10 @@ var htmx = (function() {
|
|
|
3380
3397
|
function overrideFormData(receiver, donor) {
|
|
3381
3398
|
for (const key of donor.keys()) {
|
|
3382
3399
|
receiver.delete(key)
|
|
3383
|
-
donor.getAll(key).forEach(function(value) {
|
|
3384
|
-
receiver.append(key, value)
|
|
3385
|
-
})
|
|
3386
3400
|
}
|
|
3401
|
+
donor.forEach(function(value, key) {
|
|
3402
|
+
receiver.append(key, value)
|
|
3403
|
+
})
|
|
3387
3404
|
return receiver
|
|
3388
3405
|
}
|
|
3389
3406
|
|
|
@@ -3913,7 +3930,7 @@ var htmx = (function() {
|
|
|
3913
3930
|
if (obj.hasOwnProperty(key)) {
|
|
3914
3931
|
if (typeof obj[key].forEach === 'function') {
|
|
3915
3932
|
obj[key].forEach(function(v) { formData.append(key, v) })
|
|
3916
|
-
} else if (typeof obj[key] === 'object') {
|
|
3933
|
+
} else if (typeof obj[key] === 'object' && !(obj[key] instanceof Blob)) {
|
|
3917
3934
|
formData.append(key, JSON.stringify(obj[key]))
|
|
3918
3935
|
} else {
|
|
3919
3936
|
formData.append(key, obj[key])
|
|
@@ -4006,6 +4023,8 @@ var htmx = (function() {
|
|
|
4006
4023
|
target.delete(name)
|
|
4007
4024
|
if (typeof value.forEach === 'function') {
|
|
4008
4025
|
value.forEach(function(v) { target.append(name, v) })
|
|
4026
|
+
} else if (typeof value === 'object' && !(value instanceof Blob)) {
|
|
4027
|
+
target.append(name, JSON.stringify(value))
|
|
4009
4028
|
} else {
|
|
4010
4029
|
target.append(name, value)
|
|
4011
4030
|
}
|
|
@@ -4341,7 +4360,9 @@ var htmx = (function() {
|
|
|
4341
4360
|
const hierarchy = hierarchyForElt(elt)
|
|
4342
4361
|
responseInfo.pathInfo.responsePath = getPathFromResponse(xhr)
|
|
4343
4362
|
responseHandler(elt, responseInfo)
|
|
4344
|
-
|
|
4363
|
+
if (responseInfo.keepIndicators !== true) {
|
|
4364
|
+
removeRequestIndicators(indicators, disableElts)
|
|
4365
|
+
}
|
|
4345
4366
|
triggerEvent(elt, 'htmx:afterRequest', responseInfo)
|
|
4346
4367
|
triggerEvent(elt, 'htmx:afterOnLoad', responseInfo)
|
|
4347
4368
|
// if the body no longer contains the element, trigger the event on the closest parent
|
|
@@ -4581,12 +4602,14 @@ var htmx = (function() {
|
|
|
4581
4602
|
const shouldRefresh = hasHeader(xhr, /HX-Refresh:/i) && xhr.getResponseHeader('HX-Refresh') === 'true'
|
|
4582
4603
|
|
|
4583
4604
|
if (hasHeader(xhr, /HX-Redirect:/i)) {
|
|
4605
|
+
responseInfo.keepIndicators = true
|
|
4584
4606
|
location.href = xhr.getResponseHeader('HX-Redirect')
|
|
4585
4607
|
shouldRefresh && location.reload()
|
|
4586
4608
|
return
|
|
4587
4609
|
}
|
|
4588
4610
|
|
|
4589
4611
|
if (shouldRefresh) {
|
|
4612
|
+
responseInfo.keepIndicators = true
|
|
4590
4613
|
location.reload()
|
|
4591
4614
|
return
|
|
4592
4615
|
}
|
|
@@ -5034,7 +5057,7 @@ var htmx = (function() {
|
|
|
5034
5057
|
* @property {Element|string} [source]
|
|
5035
5058
|
* @property {Event} [event]
|
|
5036
5059
|
* @property {HtmxAjaxHandler} [handler]
|
|
5037
|
-
* @property {Element|string} target
|
|
5060
|
+
* @property {Element|string} [target]
|
|
5038
5061
|
* @property {HtmxSwapStyle} [swap]
|
|
5039
5062
|
* @property {Object|FormData} [values]
|
|
5040
5063
|
* @property {Record<string,string>} [headers]
|
|
@@ -5070,6 +5093,7 @@ var htmx = (function() {
|
|
|
5070
5093
|
* @property {{requestPath: string, finalRequestPath: string, responsePath: string|null, anchor: string}} pathInfo
|
|
5071
5094
|
* @property {boolean} [failed]
|
|
5072
5095
|
* @property {boolean} [successful]
|
|
5096
|
+
* @property {boolean} [keepIndicators]
|
|
5073
5097
|
*/
|
|
5074
5098
|
|
|
5075
5099
|
/**
|
|
@@ -5119,14 +5143,15 @@ var htmx = (function() {
|
|
|
5119
5143
|
*/
|
|
5120
5144
|
|
|
5121
5145
|
/**
|
|
5146
|
+
* @see https://github.com/bigskysoftware/htmx-extensions/blob/main/README.md
|
|
5122
5147
|
* @typedef {Object} HtmxExtension
|
|
5123
|
-
* @see https://htmx.org/extensions/#defining
|
|
5124
5148
|
* @property {(api: any) => void} init
|
|
5125
5149
|
* @property {(name: string, event: Event|CustomEvent) => boolean} onEvent
|
|
5126
5150
|
* @property {(text: string, xhr: XMLHttpRequest, elt: Element) => string} transformResponse
|
|
5127
5151
|
* @property {(swapStyle: HtmxSwapStyle) => boolean} isInlineSwap
|
|
5128
|
-
* @property {(swapStyle: HtmxSwapStyle, target:
|
|
5129
|
-
* @property {(xhr: XMLHttpRequest, parameters: FormData, elt:
|
|
5152
|
+
* @property {(swapStyle: HtmxSwapStyle, target: Node, fragment: Node, settleInfo: HtmxSettleInfo) => boolean|Node[]} handleSwap
|
|
5153
|
+
* @property {(xhr: XMLHttpRequest, parameters: FormData, elt: Node) => *|string|null} encodeParameters
|
|
5154
|
+
* @property {() => string[]|null} getSelectors
|
|
5130
5155
|
*/
|
|
5131
5156
|
return htmx
|
|
5132
5157
|
})
|
package/dist/htmx.cjs.js
CHANGED
|
@@ -206,7 +206,7 @@ var htmx = (function() {
|
|
|
206
206
|
disableSelector: '[hx-disable], [data-hx-disable]',
|
|
207
207
|
/**
|
|
208
208
|
* @type {'auto' | 'instant' | 'smooth'}
|
|
209
|
-
* @default '
|
|
209
|
+
* @default 'instant'
|
|
210
210
|
*/
|
|
211
211
|
scrollBehavior: 'instant',
|
|
212
212
|
/**
|
|
@@ -277,7 +277,7 @@ var htmx = (function() {
|
|
|
277
277
|
parseInterval: null,
|
|
278
278
|
/** @type {typeof internalEval} */
|
|
279
279
|
_: null,
|
|
280
|
-
version: '2.0.
|
|
280
|
+
version: '2.0.2'
|
|
281
281
|
}
|
|
282
282
|
// Tsc madness part 2
|
|
283
283
|
htmx.onLoad = onLoadHelper
|
|
@@ -1626,6 +1626,9 @@ var htmx = (function() {
|
|
|
1626
1626
|
* @param {HtmxSettleInfo} settleInfo
|
|
1627
1627
|
*/
|
|
1628
1628
|
function swapOuterHTML(target, fragment, settleInfo) {
|
|
1629
|
+
if (target instanceof Element && target.tagName === 'BODY') { // special case the body to innerHTML because DocumentFragments can't contain a body elt unfortunately
|
|
1630
|
+
return swapInnerHTML(target, fragment, settleInfo)
|
|
1631
|
+
}
|
|
1629
1632
|
/** @type {Node} */
|
|
1630
1633
|
let newElt
|
|
1631
1634
|
const eltBeforeNewContent = target.previousSibling
|
|
@@ -1636,13 +1639,13 @@ var htmx = (function() {
|
|
|
1636
1639
|
newElt = eltBeforeNewContent.nextSibling
|
|
1637
1640
|
}
|
|
1638
1641
|
settleInfo.elts = settleInfo.elts.filter(function(e) { return e !== target })
|
|
1642
|
+
// scan through all newly added content and add all elements to the settle info so we trigger
|
|
1643
|
+
// events properly on them
|
|
1639
1644
|
while (newElt && newElt !== target) {
|
|
1640
1645
|
if (newElt instanceof Element) {
|
|
1641
1646
|
settleInfo.elts.push(newElt)
|
|
1642
|
-
newElt = newElt.nextElementSibling
|
|
1643
|
-
} else {
|
|
1644
|
-
newElt = null
|
|
1645
1647
|
}
|
|
1648
|
+
newElt = newElt.nextSibling
|
|
1646
1649
|
}
|
|
1647
1650
|
cleanUpElement(target)
|
|
1648
1651
|
if (target instanceof Element) {
|
|
@@ -1750,7 +1753,7 @@ var htmx = (function() {
|
|
|
1750
1753
|
try {
|
|
1751
1754
|
const newElements = ext.handleSwap(swapStyle, target, fragment, settleInfo)
|
|
1752
1755
|
if (newElements) {
|
|
1753
|
-
if (
|
|
1756
|
+
if (Array.isArray(newElements)) {
|
|
1754
1757
|
// if handleSwap returns an array (like) of elements, we handle them
|
|
1755
1758
|
for (let j = 0; j < newElements.length; j++) {
|
|
1756
1759
|
const child = newElements[j]
|
|
@@ -1778,7 +1781,8 @@ var htmx = (function() {
|
|
|
1778
1781
|
* @param {HtmxSettleInfo} settleInfo
|
|
1779
1782
|
*/
|
|
1780
1783
|
function findAndSwapOobElements(fragment, settleInfo) {
|
|
1781
|
-
|
|
1784
|
+
var oobElts = findAll(fragment, '[hx-swap-oob], [data-hx-swap-oob]')
|
|
1785
|
+
forEach(oobElts, function(oobElement) {
|
|
1782
1786
|
if (htmx.config.allowNestedOobSwaps || oobElement.parentElement === null) {
|
|
1783
1787
|
const oobValue = getAttributeValue(oobElement, 'hx-swap-oob')
|
|
1784
1788
|
if (oobValue != null) {
|
|
@@ -1789,6 +1793,7 @@ var htmx = (function() {
|
|
|
1789
1793
|
oobElement.removeAttribute('data-hx-swap-oob')
|
|
1790
1794
|
}
|
|
1791
1795
|
})
|
|
1796
|
+
return oobElts.length > 0
|
|
1792
1797
|
}
|
|
1793
1798
|
|
|
1794
1799
|
/**
|
|
@@ -1850,9 +1855,8 @@ var htmx = (function() {
|
|
|
1850
1855
|
// oob swaps
|
|
1851
1856
|
findAndSwapOobElements(fragment, settleInfo)
|
|
1852
1857
|
forEach(findAll(fragment, 'template'), /** @param {HTMLTemplateElement} template */function(template) {
|
|
1853
|
-
findAndSwapOobElements(template.content, settleInfo)
|
|
1854
|
-
|
|
1855
|
-
// Avoid polluting the DOM with empty templates that were only used to encapsulate oob swap
|
|
1858
|
+
if (findAndSwapOobElements(template.content, settleInfo)) {
|
|
1859
|
+
// Avoid polluting the DOM with empty templates that were only used to encapsulate oob swap
|
|
1856
1860
|
template.remove()
|
|
1857
1861
|
}
|
|
1858
1862
|
})
|
|
@@ -1949,7 +1953,10 @@ var htmx = (function() {
|
|
|
1949
1953
|
for (const eventName in triggers) {
|
|
1950
1954
|
if (triggers.hasOwnProperty(eventName)) {
|
|
1951
1955
|
let detail = triggers[eventName]
|
|
1952
|
-
if (
|
|
1956
|
+
if (isRawObject(detail)) {
|
|
1957
|
+
// @ts-ignore
|
|
1958
|
+
elt = detail.target !== undefined ? detail.target : elt
|
|
1959
|
+
} else {
|
|
1953
1960
|
detail = { value: detail }
|
|
1954
1961
|
}
|
|
1955
1962
|
triggerEvent(elt, eventName, detail)
|
|
@@ -2270,7 +2277,7 @@ var htmx = (function() {
|
|
|
2270
2277
|
* @param {HtmxTriggerSpecification[]} triggerSpecs
|
|
2271
2278
|
*/
|
|
2272
2279
|
function boostElement(elt, nodeData, triggerSpecs) {
|
|
2273
|
-
if ((elt instanceof HTMLAnchorElement && isLocalLink(elt) && (elt.target === '' || elt.target === '_self')) || elt.tagName === 'FORM') {
|
|
2280
|
+
if ((elt instanceof HTMLAnchorElement && isLocalLink(elt) && (elt.target === '' || elt.target === '_self')) || (elt.tagName === 'FORM' && String(getRawAttribute(elt, 'method')).toLowerCase() !== 'dialog')) {
|
|
2274
2281
|
nodeData.boosted = true
|
|
2275
2282
|
let verb, path
|
|
2276
2283
|
if (elt.tagName === 'A') {
|
|
@@ -2432,13 +2439,17 @@ var htmx = (function() {
|
|
|
2432
2439
|
|
|
2433
2440
|
if (triggerSpec.throttle > 0) {
|
|
2434
2441
|
if (!elementData.throttle) {
|
|
2442
|
+
triggerEvent(elt, 'htmx:trigger')
|
|
2435
2443
|
handler(elt, evt)
|
|
2436
2444
|
elementData.throttle = getWindow().setTimeout(function() {
|
|
2437
2445
|
elementData.throttle = null
|
|
2438
2446
|
}, triggerSpec.throttle)
|
|
2439
2447
|
}
|
|
2440
2448
|
} else if (triggerSpec.delay > 0) {
|
|
2441
|
-
elementData.delayed = getWindow().setTimeout(function() {
|
|
2449
|
+
elementData.delayed = getWindow().setTimeout(function() {
|
|
2450
|
+
triggerEvent(elt, 'htmx:trigger')
|
|
2451
|
+
handler(elt, evt)
|
|
2452
|
+
}, triggerSpec.delay)
|
|
2442
2453
|
} else {
|
|
2443
2454
|
triggerEvent(elt, 'htmx:trigger')
|
|
2444
2455
|
handler(elt, evt)
|
|
@@ -3056,6 +3067,10 @@ var htmx = (function() {
|
|
|
3056
3067
|
forEach(findAll(clone, '.' + className), function(child) {
|
|
3057
3068
|
removeClassFromElement(child, className)
|
|
3058
3069
|
})
|
|
3070
|
+
// remove the disabled attribute for any element disabled due to an htmx request
|
|
3071
|
+
forEach(findAll(clone, '[data-disabled-by-htmx]'), function(child) {
|
|
3072
|
+
child.removeAttribute('disabled')
|
|
3073
|
+
})
|
|
3059
3074
|
return clone.innerHTML
|
|
3060
3075
|
}
|
|
3061
3076
|
|
|
@@ -3209,6 +3224,7 @@ var htmx = (function() {
|
|
|
3209
3224
|
const internalData = getInternalData(disabledElement)
|
|
3210
3225
|
internalData.requestCount = (internalData.requestCount || 0) + 1
|
|
3211
3226
|
disabledElement.setAttribute('disabled', '')
|
|
3227
|
+
disabledElement.setAttribute('data-disabled-by-htmx', '')
|
|
3212
3228
|
})
|
|
3213
3229
|
return disabledElts
|
|
3214
3230
|
}
|
|
@@ -3230,6 +3246,7 @@ var htmx = (function() {
|
|
|
3230
3246
|
internalData.requestCount = (internalData.requestCount || 0) - 1
|
|
3231
3247
|
if (internalData.requestCount === 0) {
|
|
3232
3248
|
disabledElement.removeAttribute('disabled')
|
|
3249
|
+
disabledElement.removeAttribute('data-disabled-by-htmx')
|
|
3233
3250
|
}
|
|
3234
3251
|
})
|
|
3235
3252
|
}
|
|
@@ -3379,10 +3396,10 @@ var htmx = (function() {
|
|
|
3379
3396
|
function overrideFormData(receiver, donor) {
|
|
3380
3397
|
for (const key of donor.keys()) {
|
|
3381
3398
|
receiver.delete(key)
|
|
3382
|
-
donor.getAll(key).forEach(function(value) {
|
|
3383
|
-
receiver.append(key, value)
|
|
3384
|
-
})
|
|
3385
3399
|
}
|
|
3400
|
+
donor.forEach(function(value, key) {
|
|
3401
|
+
receiver.append(key, value)
|
|
3402
|
+
})
|
|
3386
3403
|
return receiver
|
|
3387
3404
|
}
|
|
3388
3405
|
|
|
@@ -3912,7 +3929,7 @@ var htmx = (function() {
|
|
|
3912
3929
|
if (obj.hasOwnProperty(key)) {
|
|
3913
3930
|
if (typeof obj[key].forEach === 'function') {
|
|
3914
3931
|
obj[key].forEach(function(v) { formData.append(key, v) })
|
|
3915
|
-
} else if (typeof obj[key] === 'object') {
|
|
3932
|
+
} else if (typeof obj[key] === 'object' && !(obj[key] instanceof Blob)) {
|
|
3916
3933
|
formData.append(key, JSON.stringify(obj[key]))
|
|
3917
3934
|
} else {
|
|
3918
3935
|
formData.append(key, obj[key])
|
|
@@ -4005,6 +4022,8 @@ var htmx = (function() {
|
|
|
4005
4022
|
target.delete(name)
|
|
4006
4023
|
if (typeof value.forEach === 'function') {
|
|
4007
4024
|
value.forEach(function(v) { target.append(name, v) })
|
|
4025
|
+
} else if (typeof value === 'object' && !(value instanceof Blob)) {
|
|
4026
|
+
target.append(name, JSON.stringify(value))
|
|
4008
4027
|
} else {
|
|
4009
4028
|
target.append(name, value)
|
|
4010
4029
|
}
|
|
@@ -4340,7 +4359,9 @@ var htmx = (function() {
|
|
|
4340
4359
|
const hierarchy = hierarchyForElt(elt)
|
|
4341
4360
|
responseInfo.pathInfo.responsePath = getPathFromResponse(xhr)
|
|
4342
4361
|
responseHandler(elt, responseInfo)
|
|
4343
|
-
|
|
4362
|
+
if (responseInfo.keepIndicators !== true) {
|
|
4363
|
+
removeRequestIndicators(indicators, disableElts)
|
|
4364
|
+
}
|
|
4344
4365
|
triggerEvent(elt, 'htmx:afterRequest', responseInfo)
|
|
4345
4366
|
triggerEvent(elt, 'htmx:afterOnLoad', responseInfo)
|
|
4346
4367
|
// if the body no longer contains the element, trigger the event on the closest parent
|
|
@@ -4580,12 +4601,14 @@ var htmx = (function() {
|
|
|
4580
4601
|
const shouldRefresh = hasHeader(xhr, /HX-Refresh:/i) && xhr.getResponseHeader('HX-Refresh') === 'true'
|
|
4581
4602
|
|
|
4582
4603
|
if (hasHeader(xhr, /HX-Redirect:/i)) {
|
|
4604
|
+
responseInfo.keepIndicators = true
|
|
4583
4605
|
location.href = xhr.getResponseHeader('HX-Redirect')
|
|
4584
4606
|
shouldRefresh && location.reload()
|
|
4585
4607
|
return
|
|
4586
4608
|
}
|
|
4587
4609
|
|
|
4588
4610
|
if (shouldRefresh) {
|
|
4611
|
+
responseInfo.keepIndicators = true
|
|
4589
4612
|
location.reload()
|
|
4590
4613
|
return
|
|
4591
4614
|
}
|
|
@@ -5033,7 +5056,7 @@ var htmx = (function() {
|
|
|
5033
5056
|
* @property {Element|string} [source]
|
|
5034
5057
|
* @property {Event} [event]
|
|
5035
5058
|
* @property {HtmxAjaxHandler} [handler]
|
|
5036
|
-
* @property {Element|string} target
|
|
5059
|
+
* @property {Element|string} [target]
|
|
5037
5060
|
* @property {HtmxSwapStyle} [swap]
|
|
5038
5061
|
* @property {Object|FormData} [values]
|
|
5039
5062
|
* @property {Record<string,string>} [headers]
|
|
@@ -5069,6 +5092,7 @@ var htmx = (function() {
|
|
|
5069
5092
|
* @property {{requestPath: string, finalRequestPath: string, responsePath: string|null, anchor: string}} pathInfo
|
|
5070
5093
|
* @property {boolean} [failed]
|
|
5071
5094
|
* @property {boolean} [successful]
|
|
5095
|
+
* @property {boolean} [keepIndicators]
|
|
5072
5096
|
*/
|
|
5073
5097
|
|
|
5074
5098
|
/**
|
|
@@ -5118,13 +5142,14 @@ var htmx = (function() {
|
|
|
5118
5142
|
*/
|
|
5119
5143
|
|
|
5120
5144
|
/**
|
|
5145
|
+
* @see https://github.com/bigskysoftware/htmx-extensions/blob/main/README.md
|
|
5121
5146
|
* @typedef {Object} HtmxExtension
|
|
5122
|
-
* @see https://htmx.org/extensions/#defining
|
|
5123
5147
|
* @property {(api: any) => void} init
|
|
5124
5148
|
* @property {(name: string, event: Event|CustomEvent) => boolean} onEvent
|
|
5125
5149
|
* @property {(text: string, xhr: XMLHttpRequest, elt: Element) => string} transformResponse
|
|
5126
5150
|
* @property {(swapStyle: HtmxSwapStyle) => boolean} isInlineSwap
|
|
5127
|
-
* @property {(swapStyle: HtmxSwapStyle, target:
|
|
5128
|
-
* @property {(xhr: XMLHttpRequest, parameters: FormData, elt:
|
|
5151
|
+
* @property {(swapStyle: HtmxSwapStyle, target: Node, fragment: Node, settleInfo: HtmxSettleInfo) => boolean|Node[]} handleSwap
|
|
5152
|
+
* @property {(xhr: XMLHttpRequest, parameters: FormData, elt: Node) => *|string|null} encodeParameters
|
|
5153
|
+
* @property {() => string[]|null} getSelectors
|
|
5129
5154
|
*/
|
|
5130
5155
|
module.exports = htmx;
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
export default htmx;
|
|
2
|
+
export type HttpVerb = 'get' | 'head' | 'post' | 'put' | 'delete' | 'connect' | 'options' | 'trace' | 'patch';
|
|
3
|
+
export type SwapOptions = {
|
|
4
|
+
select?: string;
|
|
5
|
+
selectOOB?: string;
|
|
6
|
+
eventInfo?: any;
|
|
7
|
+
anchor?: string;
|
|
8
|
+
contextElement?: Element;
|
|
9
|
+
afterSwapCallback?: swapCallback;
|
|
10
|
+
afterSettleCallback?: swapCallback;
|
|
11
|
+
};
|
|
12
|
+
export type swapCallback = () => any;
|
|
13
|
+
export type HtmxSwapStyle = 'innerHTML' | 'outerHTML' | 'beforebegin' | 'afterbegin' | 'beforeend' | 'afterend' | 'delete' | 'none' | string;
|
|
14
|
+
export type HtmxSwapSpecification = {
|
|
15
|
+
swapStyle: HtmxSwapStyle;
|
|
16
|
+
swapDelay: number;
|
|
17
|
+
settleDelay: number;
|
|
18
|
+
transition?: boolean;
|
|
19
|
+
ignoreTitle?: boolean;
|
|
20
|
+
head?: string;
|
|
21
|
+
scroll?: 'top' | 'bottom';
|
|
22
|
+
scrollTarget?: string;
|
|
23
|
+
show?: string;
|
|
24
|
+
showTarget?: string;
|
|
25
|
+
focusScroll?: boolean;
|
|
26
|
+
};
|
|
27
|
+
export type ConditionalFunction = ((this: Node, evt: Event) => boolean) & {
|
|
28
|
+
source: string;
|
|
29
|
+
};
|
|
30
|
+
export type HtmxTriggerSpecification = {
|
|
31
|
+
trigger: string;
|
|
32
|
+
pollInterval?: number;
|
|
33
|
+
eventFilter?: ConditionalFunction;
|
|
34
|
+
changed?: boolean;
|
|
35
|
+
once?: boolean;
|
|
36
|
+
consume?: boolean;
|
|
37
|
+
delay?: number;
|
|
38
|
+
from?: string;
|
|
39
|
+
target?: string;
|
|
40
|
+
throttle?: number;
|
|
41
|
+
queue?: string;
|
|
42
|
+
root?: string;
|
|
43
|
+
threshold?: string;
|
|
44
|
+
};
|
|
45
|
+
export type HtmxElementValidationError = {
|
|
46
|
+
elt: Element;
|
|
47
|
+
message: string;
|
|
48
|
+
validity: ValidityState;
|
|
49
|
+
};
|
|
50
|
+
export type HtmxHeaderSpecification = Record<string, string>;
|
|
51
|
+
export type HtmxAjaxHelperContext = {
|
|
52
|
+
source?: Element | string;
|
|
53
|
+
event?: Event;
|
|
54
|
+
handler?: HtmxAjaxHandler;
|
|
55
|
+
target?: Element | string;
|
|
56
|
+
swap?: HtmxSwapStyle;
|
|
57
|
+
values?: any | FormData;
|
|
58
|
+
headers?: Record<string, string>;
|
|
59
|
+
select?: string;
|
|
60
|
+
};
|
|
61
|
+
export type HtmxRequestConfig = {
|
|
62
|
+
boosted: boolean;
|
|
63
|
+
useUrlParams: boolean;
|
|
64
|
+
formData: FormData;
|
|
65
|
+
/**
|
|
66
|
+
* formData proxy
|
|
67
|
+
*/
|
|
68
|
+
parameters: any;
|
|
69
|
+
unfilteredFormData: FormData;
|
|
70
|
+
/**
|
|
71
|
+
* unfilteredFormData proxy
|
|
72
|
+
*/
|
|
73
|
+
unfilteredParameters: any;
|
|
74
|
+
headers: HtmxHeaderSpecification;
|
|
75
|
+
target: Element;
|
|
76
|
+
verb: HttpVerb;
|
|
77
|
+
errors: HtmxElementValidationError[];
|
|
78
|
+
withCredentials: boolean;
|
|
79
|
+
timeout: number;
|
|
80
|
+
path: string;
|
|
81
|
+
triggeringEvent: Event;
|
|
82
|
+
};
|
|
83
|
+
export type HtmxResponseInfo = {
|
|
84
|
+
xhr: XMLHttpRequest;
|
|
85
|
+
target: Element;
|
|
86
|
+
requestConfig: HtmxRequestConfig;
|
|
87
|
+
etc: HtmxAjaxEtc;
|
|
88
|
+
boosted: boolean;
|
|
89
|
+
select: string;
|
|
90
|
+
pathInfo: {
|
|
91
|
+
requestPath: string;
|
|
92
|
+
finalRequestPath: string;
|
|
93
|
+
responsePath: string | null;
|
|
94
|
+
anchor: string;
|
|
95
|
+
};
|
|
96
|
+
failed?: boolean;
|
|
97
|
+
successful?: boolean;
|
|
98
|
+
keepIndicators?: boolean;
|
|
99
|
+
};
|
|
100
|
+
export type HtmxAjaxEtc = {
|
|
101
|
+
returnPromise?: boolean;
|
|
102
|
+
handler?: HtmxAjaxHandler;
|
|
103
|
+
select?: string;
|
|
104
|
+
targetOverride?: Element;
|
|
105
|
+
swapOverride?: HtmxSwapStyle;
|
|
106
|
+
headers?: Record<string, string>;
|
|
107
|
+
values?: any | FormData;
|
|
108
|
+
credentials?: boolean;
|
|
109
|
+
timeout?: number;
|
|
110
|
+
};
|
|
111
|
+
export type HtmxResponseHandlingConfig = {
|
|
112
|
+
code?: string;
|
|
113
|
+
swap: boolean;
|
|
114
|
+
error?: boolean;
|
|
115
|
+
ignoreTitle?: boolean;
|
|
116
|
+
select?: string;
|
|
117
|
+
target?: string;
|
|
118
|
+
swapOverride?: string;
|
|
119
|
+
event?: string;
|
|
120
|
+
};
|
|
121
|
+
export type HtmxBeforeSwapDetails = HtmxResponseInfo & {
|
|
122
|
+
shouldSwap: boolean;
|
|
123
|
+
serverResponse: any;
|
|
124
|
+
isError: boolean;
|
|
125
|
+
ignoreTitle: boolean;
|
|
126
|
+
selectOverride: string;
|
|
127
|
+
};
|
|
128
|
+
export type HtmxAjaxHandler = (elt: Element, responseInfo: HtmxResponseInfo) => any;
|
|
129
|
+
export type HtmxSettleTask = (() => void);
|
|
130
|
+
export type HtmxSettleInfo = {
|
|
131
|
+
tasks: HtmxSettleTask[];
|
|
132
|
+
elts: Element[];
|
|
133
|
+
title?: string;
|
|
134
|
+
};
|
|
135
|
+
export type HtmxExtension = {
|
|
136
|
+
init: (api: any) => void;
|
|
137
|
+
onEvent: (name: string, event: Event | CustomEvent) => boolean;
|
|
138
|
+
transformResponse: (text: string, xhr: XMLHttpRequest, elt: Element) => string;
|
|
139
|
+
isInlineSwap: (swapStyle: HtmxSwapStyle) => boolean;
|
|
140
|
+
handleSwap: (swapStyle: HtmxSwapStyle, target: Node, fragment: Node, settleInfo: HtmxSettleInfo) => boolean | Node[];
|
|
141
|
+
encodeParameters: (xhr: XMLHttpRequest, parameters: FormData, elt: Node) => any | string | null;
|
|
142
|
+
getSelectors: () => string[] | null;
|
|
143
|
+
};
|
|
144
|
+
declare namespace htmx {
|
|
145
|
+
const onLoad: (callback: (elt: Node) => void) => EventListener;
|
|
146
|
+
const process: (elt: string | Element) => void;
|
|
147
|
+
const on: (arg1: string | EventTarget, arg2: string | EventListener, arg3?: EventListener) => EventListener;
|
|
148
|
+
const off: (arg1: string | EventTarget, arg2: string | EventListener, arg3?: EventListener) => EventListener;
|
|
149
|
+
const trigger: (elt: string | EventTarget, eventName: string, detail?: any) => boolean;
|
|
150
|
+
const ajax: (verb: HttpVerb, path: string, context: string | Element | HtmxAjaxHelperContext) => Promise<void>;
|
|
151
|
+
const find: (eltOrSelector: string | ParentNode, selector?: string) => Element;
|
|
152
|
+
const findAll: (eltOrSelector: string | ParentNode, selector?: string) => NodeListOf<Element>;
|
|
153
|
+
const closest: (elt: string | Element, selector: string) => Element;
|
|
154
|
+
function values(elt: Element, type: HttpVerb): any;
|
|
155
|
+
const remove: (elt: Node, delay?: number) => void;
|
|
156
|
+
const addClass: (elt: string | Element, clazz: string, delay?: number) => void;
|
|
157
|
+
const removeClass: (node: string | Node, clazz: string, delay?: number) => void;
|
|
158
|
+
const toggleClass: (elt: string | Element, clazz: string) => void;
|
|
159
|
+
const takeClass: (elt: string | Node, clazz: string) => void;
|
|
160
|
+
const swap: (target: string | Element, content: string, swapSpec: HtmxSwapSpecification, swapOptions?: SwapOptions) => void;
|
|
161
|
+
const defineExtension: (name: string, extension: HtmxExtension) => void;
|
|
162
|
+
const removeExtension: (name: string) => void;
|
|
163
|
+
const logAll: () => void;
|
|
164
|
+
const logNone: () => void;
|
|
165
|
+
const logger: any;
|
|
166
|
+
namespace config {
|
|
167
|
+
const historyEnabled: boolean;
|
|
168
|
+
const historyCacheSize: number;
|
|
169
|
+
const refreshOnHistoryMiss: boolean;
|
|
170
|
+
const defaultSwapStyle: HtmxSwapStyle;
|
|
171
|
+
const defaultSwapDelay: number;
|
|
172
|
+
const defaultSettleDelay: number;
|
|
173
|
+
const includeIndicatorStyles: boolean;
|
|
174
|
+
const indicatorClass: string;
|
|
175
|
+
const requestClass: string;
|
|
176
|
+
const addedClass: string;
|
|
177
|
+
const settlingClass: string;
|
|
178
|
+
const swappingClass: string;
|
|
179
|
+
const allowEval: boolean;
|
|
180
|
+
const allowScriptTags: boolean;
|
|
181
|
+
const inlineScriptNonce: string;
|
|
182
|
+
const inlineStyleNonce: string;
|
|
183
|
+
const attributesToSettle: string[];
|
|
184
|
+
const withCredentials: boolean;
|
|
185
|
+
const timeout: number;
|
|
186
|
+
const wsReconnectDelay: "full-jitter" | ((retryCount: number) => number);
|
|
187
|
+
const wsBinaryType: BinaryType;
|
|
188
|
+
const disableSelector: string;
|
|
189
|
+
const scrollBehavior: 'auto' | 'instant' | 'smooth';
|
|
190
|
+
const defaultFocusScroll: boolean;
|
|
191
|
+
const getCacheBusterParam: boolean;
|
|
192
|
+
const globalViewTransitions: boolean;
|
|
193
|
+
const methodsThatUseUrlParams: (HttpVerb)[];
|
|
194
|
+
const selfRequestsOnly: boolean;
|
|
195
|
+
const ignoreTitle: boolean;
|
|
196
|
+
const scrollIntoViewOnBoost: boolean;
|
|
197
|
+
const triggerSpecsCache: any | null;
|
|
198
|
+
const disableInheritance: boolean;
|
|
199
|
+
const responseHandling: HtmxResponseHandlingConfig[];
|
|
200
|
+
const allowNestedOobSwaps: boolean;
|
|
201
|
+
}
|
|
202
|
+
const parseInterval: (str: string) => number;
|
|
203
|
+
const _: (str: string) => any;
|
|
204
|
+
const version: string;
|
|
205
|
+
}
|