htmx.org 2.0.2 → 2.0.3
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 +2 -2
- package/dist/ext/README.md +1 -1
- package/dist/ext/ajax-header.js +1 -1
- package/dist/ext/alpine-morph.js +1 -1
- package/dist/ext/class-tools.js +1 -1
- package/dist/ext/client-side-templates.js +1 -1
- package/dist/ext/debug.js +1 -1
- package/dist/ext/disable-element.js +1 -1
- package/dist/ext/event-header.js +1 -1
- package/dist/ext/head-support.js +1 -1
- package/dist/ext/include-vals.js +1 -1
- package/dist/ext/json-enc.js +1 -1
- package/dist/ext/loading-states.js +1 -1
- package/dist/ext/method-override.js +1 -1
- package/dist/ext/morphdom-swap.js +1 -1
- package/dist/ext/multi-swap.js +1 -1
- package/dist/ext/path-deps.js +1 -1
- package/dist/ext/path-params.js +1 -1
- package/dist/ext/preload.js +1 -1
- package/dist/ext/rails-method.js +1 -1
- package/dist/ext/remove-me.js +1 -1
- package/dist/ext/response-targets.js +1 -1
- package/dist/ext/restored.js +1 -1
- package/dist/ext/sse.js +1 -1
- package/dist/ext/ws.js +1 -1
- package/dist/htmx.amd.js +115 -66
- package/dist/htmx.cjs.js +115 -66
- package/dist/htmx.esm.d.ts +61 -60
- package/dist/htmx.esm.js +115 -66
- package/dist/htmx.js +115 -66
- package/dist/htmx.min.js +1 -1
- package/dist/htmx.min.js.gz +0 -0
- package/package.json +2 -3
package/dist/htmx.js
CHANGED
|
@@ -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.3'
|
|
281
281
|
}
|
|
282
282
|
// Tsc madness part 2
|
|
283
283
|
htmx.onLoad = onLoadHelper
|
|
@@ -337,22 +337,10 @@ var htmx = (function() {
|
|
|
337
337
|
return '[hx-' + verb + '], [data-hx-' + verb + ']'
|
|
338
338
|
}).join(', ')
|
|
339
339
|
|
|
340
|
-
const HEAD_TAG_REGEX = makeTagRegEx('head')
|
|
341
|
-
|
|
342
340
|
//= ===================================================================
|
|
343
341
|
// Utilities
|
|
344
342
|
//= ===================================================================
|
|
345
343
|
|
|
346
|
-
/**
|
|
347
|
-
* @param {string} tag
|
|
348
|
-
* @param {boolean} global
|
|
349
|
-
* @returns {RegExp}
|
|
350
|
-
*/
|
|
351
|
-
function makeTagRegEx(tag, global = false) {
|
|
352
|
-
return new RegExp(`<${tag}(\\s[^>]*>|>)([\\s\\S]*?)<\\/${tag}>`,
|
|
353
|
-
global ? 'gim' : 'im')
|
|
354
|
-
}
|
|
355
|
-
|
|
356
344
|
/**
|
|
357
345
|
* Parses an interval string consistent with the way htmx does. Useful for plugins that have timing-related attributes.
|
|
358
346
|
*
|
|
@@ -595,7 +583,7 @@ var htmx = (function() {
|
|
|
595
583
|
*/
|
|
596
584
|
function makeFragment(response) {
|
|
597
585
|
// strip head tag to determine shape of response we are dealing with
|
|
598
|
-
const responseWithNoHead = response.replace(
|
|
586
|
+
const responseWithNoHead = response.replace(/<head(\s[^>]*)?>[\s\S]*?<\/head>/i, '')
|
|
599
587
|
const startTag = getStartTag(responseWithNoHead)
|
|
600
588
|
/** @type DocumentFragmentWithTitle */
|
|
601
589
|
let fragment
|
|
@@ -695,7 +683,7 @@ var htmx = (function() {
|
|
|
695
683
|
* @property {boolean} [triggeredOnce]
|
|
696
684
|
* @property {number} [delayed]
|
|
697
685
|
* @property {number|null} [throttle]
|
|
698
|
-
* @property {string} [lastValue]
|
|
686
|
+
* @property {WeakMap<HtmxTriggerSpecification,WeakMap<EventTarget,string>>} [lastValue]
|
|
699
687
|
* @property {boolean} [loaded]
|
|
700
688
|
* @property {string} [path]
|
|
701
689
|
* @property {string} [verb]
|
|
@@ -1161,6 +1149,8 @@ var htmx = (function() {
|
|
|
1161
1149
|
return [document.body]
|
|
1162
1150
|
} else if (selector === 'root') {
|
|
1163
1151
|
return [getRootNode(elt, !!global)]
|
|
1152
|
+
} else if (selector === 'host') {
|
|
1153
|
+
return [(/** @type ShadowRoot */(elt.getRootNode())).host]
|
|
1164
1154
|
} else if (selector.indexOf('global ') === 0) {
|
|
1165
1155
|
return querySelectorAllExt(elt, selector.slice(7), true)
|
|
1166
1156
|
} else {
|
|
@@ -1236,26 +1226,30 @@ var htmx = (function() {
|
|
|
1236
1226
|
* @property {EventTarget} target
|
|
1237
1227
|
* @property {AnyEventName} event
|
|
1238
1228
|
* @property {EventListener} listener
|
|
1229
|
+
* @property {Object|boolean} options
|
|
1239
1230
|
*/
|
|
1240
1231
|
|
|
1241
1232
|
/**
|
|
1242
1233
|
* @param {EventTarget|AnyEventName} arg1
|
|
1243
1234
|
* @param {AnyEventName|EventListener} arg2
|
|
1244
|
-
* @param {EventListener} [arg3]
|
|
1235
|
+
* @param {EventListener|Object|boolean} [arg3]
|
|
1236
|
+
* @param {Object|boolean} [arg4]
|
|
1245
1237
|
* @returns {EventArgs}
|
|
1246
1238
|
*/
|
|
1247
|
-
function processEventArgs(arg1, arg2, arg3) {
|
|
1239
|
+
function processEventArgs(arg1, arg2, arg3, arg4) {
|
|
1248
1240
|
if (isFunction(arg2)) {
|
|
1249
1241
|
return {
|
|
1250
1242
|
target: getDocument().body,
|
|
1251
1243
|
event: asString(arg1),
|
|
1252
|
-
listener: arg2
|
|
1244
|
+
listener: arg2,
|
|
1245
|
+
options: arg3
|
|
1253
1246
|
}
|
|
1254
1247
|
} else {
|
|
1255
1248
|
return {
|
|
1256
1249
|
target: resolveTarget(arg1),
|
|
1257
1250
|
event: asString(arg2),
|
|
1258
|
-
listener: arg3
|
|
1251
|
+
listener: arg3,
|
|
1252
|
+
options: arg4
|
|
1259
1253
|
}
|
|
1260
1254
|
}
|
|
1261
1255
|
}
|
|
@@ -1267,13 +1261,14 @@ var htmx = (function() {
|
|
|
1267
1261
|
*
|
|
1268
1262
|
* @param {EventTarget|string} arg1 the element to add the listener to | the event name to add the listener for
|
|
1269
1263
|
* @param {string|EventListener} arg2 the event name to add the listener for | the listener to add
|
|
1270
|
-
* @param {EventListener} [arg3] the listener to add
|
|
1264
|
+
* @param {EventListener|Object|boolean} [arg3] the listener to add | options to add
|
|
1265
|
+
* @param {Object|boolean} [arg4] options to add
|
|
1271
1266
|
* @returns {EventListener}
|
|
1272
1267
|
*/
|
|
1273
|
-
function addEventListenerImpl(arg1, arg2, arg3) {
|
|
1268
|
+
function addEventListenerImpl(arg1, arg2, arg3, arg4) {
|
|
1274
1269
|
ready(function() {
|
|
1275
|
-
const eventArgs = processEventArgs(arg1, arg2, arg3)
|
|
1276
|
-
eventArgs.target.addEventListener(eventArgs.event, eventArgs.listener)
|
|
1270
|
+
const eventArgs = processEventArgs(arg1, arg2, arg3, arg4)
|
|
1271
|
+
eventArgs.target.addEventListener(eventArgs.event, eventArgs.listener, eventArgs.options)
|
|
1277
1272
|
})
|
|
1278
1273
|
const b = isFunction(arg2)
|
|
1279
1274
|
return b ? arg2 : arg3
|
|
@@ -1412,9 +1407,11 @@ var htmx = (function() {
|
|
|
1412
1407
|
* @param {string} oobValue
|
|
1413
1408
|
* @param {Element} oobElement
|
|
1414
1409
|
* @param {HtmxSettleInfo} settleInfo
|
|
1410
|
+
* @param {Node|Document} [rootNode]
|
|
1415
1411
|
* @returns
|
|
1416
1412
|
*/
|
|
1417
|
-
function oobSwap(oobValue, oobElement, settleInfo) {
|
|
1413
|
+
function oobSwap(oobValue, oobElement, settleInfo, rootNode) {
|
|
1414
|
+
rootNode = rootNode || getDocument()
|
|
1418
1415
|
let selector = '#' + getRawAttribute(oobElement, 'id')
|
|
1419
1416
|
/** @type HtmxSwapStyle */
|
|
1420
1417
|
let swapStyle = 'outerHTML'
|
|
@@ -1426,8 +1423,10 @@ var htmx = (function() {
|
|
|
1426
1423
|
} else {
|
|
1427
1424
|
swapStyle = oobValue
|
|
1428
1425
|
}
|
|
1426
|
+
oobElement.removeAttribute('hx-swap-oob')
|
|
1427
|
+
oobElement.removeAttribute('data-hx-swap-oob')
|
|
1429
1428
|
|
|
1430
|
-
const targets =
|
|
1429
|
+
const targets = querySelectorAllExt(rootNode, selector, false)
|
|
1431
1430
|
if (targets) {
|
|
1432
1431
|
forEach(
|
|
1433
1432
|
targets,
|
|
@@ -1445,7 +1444,9 @@ var htmx = (function() {
|
|
|
1445
1444
|
|
|
1446
1445
|
target = beforeSwapDetails.target // allow re-targeting
|
|
1447
1446
|
if (beforeSwapDetails.shouldSwap) {
|
|
1447
|
+
handlePreservedElements(fragment)
|
|
1448
1448
|
swapWithStyle(swapStyle, target, target, fragment, settleInfo)
|
|
1449
|
+
restorePreservedElements()
|
|
1449
1450
|
}
|
|
1450
1451
|
forEach(settleInfo.elts, function(elt) {
|
|
1451
1452
|
triggerEvent(elt, 'htmx:oobAfterSwap', beforeSwapDetails)
|
|
@@ -1460,15 +1461,39 @@ var htmx = (function() {
|
|
|
1460
1461
|
return oobValue
|
|
1461
1462
|
}
|
|
1462
1463
|
|
|
1464
|
+
function restorePreservedElements() {
|
|
1465
|
+
const pantry = find('#--htmx-preserve-pantry--')
|
|
1466
|
+
if (pantry) {
|
|
1467
|
+
for (const preservedElt of [...pantry.children]) {
|
|
1468
|
+
const existingElement = find('#' + preservedElt.id)
|
|
1469
|
+
// @ts-ignore - use proposed moveBefore feature
|
|
1470
|
+
existingElement.parentNode.moveBefore(preservedElt, existingElement)
|
|
1471
|
+
existingElement.remove()
|
|
1472
|
+
}
|
|
1473
|
+
pantry.remove()
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1463
1477
|
/**
|
|
1464
|
-
* @param {DocumentFragment} fragment
|
|
1478
|
+
* @param {DocumentFragment|ParentNode} fragment
|
|
1465
1479
|
*/
|
|
1466
1480
|
function handlePreservedElements(fragment) {
|
|
1467
1481
|
forEach(findAll(fragment, '[hx-preserve], [data-hx-preserve]'), function(preservedElt) {
|
|
1468
1482
|
const id = getAttributeValue(preservedElt, 'id')
|
|
1469
|
-
const
|
|
1470
|
-
if (
|
|
1471
|
-
preservedElt.
|
|
1483
|
+
const existingElement = getDocument().getElementById(id)
|
|
1484
|
+
if (existingElement != null) {
|
|
1485
|
+
if (preservedElt.moveBefore) { // if the moveBefore API exists, use it
|
|
1486
|
+
// get or create a storage spot for stuff
|
|
1487
|
+
let pantry = find('#--htmx-preserve-pantry--')
|
|
1488
|
+
if (pantry == null) {
|
|
1489
|
+
getDocument().body.insertAdjacentHTML('afterend', "<div id='--htmx-preserve-pantry--'></div>")
|
|
1490
|
+
pantry = find('#--htmx-preserve-pantry--')
|
|
1491
|
+
}
|
|
1492
|
+
// @ts-ignore - use proposed moveBefore feature
|
|
1493
|
+
pantry.moveBefore(existingElement, null)
|
|
1494
|
+
} else {
|
|
1495
|
+
preservedElt.parentNode.replaceChild(existingElement, preservedElt)
|
|
1496
|
+
}
|
|
1472
1497
|
}
|
|
1473
1498
|
})
|
|
1474
1499
|
}
|
|
@@ -1632,9 +1657,13 @@ var htmx = (function() {
|
|
|
1632
1657
|
/** @type {Node} */
|
|
1633
1658
|
let newElt
|
|
1634
1659
|
const eltBeforeNewContent = target.previousSibling
|
|
1635
|
-
|
|
1660
|
+
const parentNode = parentElt(target)
|
|
1661
|
+
if (!parentNode) { // when parent node disappears, we can't do anything
|
|
1662
|
+
return
|
|
1663
|
+
}
|
|
1664
|
+
insertNodesBefore(parentNode, target, fragment, settleInfo)
|
|
1636
1665
|
if (eltBeforeNewContent == null) {
|
|
1637
|
-
newElt =
|
|
1666
|
+
newElt = parentNode.firstChild
|
|
1638
1667
|
} else {
|
|
1639
1668
|
newElt = eltBeforeNewContent.nextSibling
|
|
1640
1669
|
}
|
|
@@ -1696,7 +1725,10 @@ var htmx = (function() {
|
|
|
1696
1725
|
*/
|
|
1697
1726
|
function swapDelete(target) {
|
|
1698
1727
|
cleanUpElement(target)
|
|
1699
|
-
|
|
1728
|
+
const parent = parentElt(target)
|
|
1729
|
+
if (parent) {
|
|
1730
|
+
return parent.removeChild(target)
|
|
1731
|
+
}
|
|
1700
1732
|
}
|
|
1701
1733
|
|
|
1702
1734
|
/**
|
|
@@ -1779,14 +1811,15 @@ var htmx = (function() {
|
|
|
1779
1811
|
/**
|
|
1780
1812
|
* @param {DocumentFragment} fragment
|
|
1781
1813
|
* @param {HtmxSettleInfo} settleInfo
|
|
1814
|
+
* @param {Node|Document} [rootNode]
|
|
1782
1815
|
*/
|
|
1783
|
-
function findAndSwapOobElements(fragment, settleInfo) {
|
|
1816
|
+
function findAndSwapOobElements(fragment, settleInfo, rootNode) {
|
|
1784
1817
|
var oobElts = findAll(fragment, '[hx-swap-oob], [data-hx-swap-oob]')
|
|
1785
1818
|
forEach(oobElts, function(oobElement) {
|
|
1786
1819
|
if (htmx.config.allowNestedOobSwaps || oobElement.parentElement === null) {
|
|
1787
1820
|
const oobValue = getAttributeValue(oobElement, 'hx-swap-oob')
|
|
1788
1821
|
if (oobValue != null) {
|
|
1789
|
-
oobSwap(oobValue, oobElement, settleInfo)
|
|
1822
|
+
oobSwap(oobValue, oobElement, settleInfo, rootNode)
|
|
1790
1823
|
}
|
|
1791
1824
|
} else {
|
|
1792
1825
|
oobElement.removeAttribute('hx-swap-oob')
|
|
@@ -1810,6 +1843,7 @@ var htmx = (function() {
|
|
|
1810
1843
|
}
|
|
1811
1844
|
|
|
1812
1845
|
target = resolveTarget(target)
|
|
1846
|
+
const rootNode = swapOptions.contextElement ? getRootNode(swapOptions.contextElement, false) : getDocument()
|
|
1813
1847
|
|
|
1814
1848
|
// preserve focus and selection
|
|
1815
1849
|
const activeElt = document.activeElement
|
|
@@ -1848,14 +1882,14 @@ var htmx = (function() {
|
|
|
1848
1882
|
const oobValue = oobSelectValue[1] || 'true'
|
|
1849
1883
|
const oobElement = fragment.querySelector('#' + id)
|
|
1850
1884
|
if (oobElement) {
|
|
1851
|
-
oobSwap(oobValue, oobElement, settleInfo)
|
|
1885
|
+
oobSwap(oobValue, oobElement, settleInfo, rootNode)
|
|
1852
1886
|
}
|
|
1853
1887
|
}
|
|
1854
1888
|
}
|
|
1855
1889
|
// oob swaps
|
|
1856
|
-
findAndSwapOobElements(fragment, settleInfo)
|
|
1890
|
+
findAndSwapOobElements(fragment, settleInfo, rootNode)
|
|
1857
1891
|
forEach(findAll(fragment, 'template'), /** @param {HTMLTemplateElement} template */function(template) {
|
|
1858
|
-
if (findAndSwapOobElements(template.content, settleInfo)) {
|
|
1892
|
+
if (findAndSwapOobElements(template.content, settleInfo, rootNode)) {
|
|
1859
1893
|
// Avoid polluting the DOM with empty templates that were only used to encapsulate oob swap
|
|
1860
1894
|
template.remove()
|
|
1861
1895
|
}
|
|
@@ -1871,6 +1905,7 @@ var htmx = (function() {
|
|
|
1871
1905
|
}
|
|
1872
1906
|
handlePreservedElements(fragment)
|
|
1873
1907
|
swapWithStyle(swapSpec.swapStyle, swapOptions.contextElement, target, fragment, settleInfo)
|
|
1908
|
+
restorePreservedElements()
|
|
1874
1909
|
}
|
|
1875
1910
|
|
|
1876
1911
|
// apply saved focus and selection information to swapped content
|
|
@@ -2141,8 +2176,8 @@ var htmx = (function() {
|
|
|
2141
2176
|
if (eventFilter) {
|
|
2142
2177
|
triggerSpec.eventFilter = eventFilter
|
|
2143
2178
|
}
|
|
2179
|
+
consumeUntil(tokens, NOT_WHITESPACE)
|
|
2144
2180
|
while (tokens.length > 0 && tokens[0] !== ',') {
|
|
2145
|
-
consumeUntil(tokens, NOT_WHITESPACE)
|
|
2146
2181
|
const token = tokens.shift()
|
|
2147
2182
|
if (token === 'changed') {
|
|
2148
2183
|
triggerSpec.changed = true
|
|
@@ -2187,6 +2222,7 @@ var htmx = (function() {
|
|
|
2187
2222
|
} else {
|
|
2188
2223
|
triggerErrorEvent(elt, 'htmx:syntax:error', { token: tokens.shift() })
|
|
2189
2224
|
}
|
|
2225
|
+
consumeUntil(tokens, NOT_WHITESPACE)
|
|
2190
2226
|
}
|
|
2191
2227
|
triggerSpecs.push(triggerSpec)
|
|
2192
2228
|
}
|
|
@@ -2281,14 +2317,15 @@ var htmx = (function() {
|
|
|
2281
2317
|
nodeData.boosted = true
|
|
2282
2318
|
let verb, path
|
|
2283
2319
|
if (elt.tagName === 'A') {
|
|
2284
|
-
verb = 'get'
|
|
2320
|
+
verb = (/** @type HttpVerb */('get'))
|
|
2285
2321
|
path = getRawAttribute(elt, 'href')
|
|
2286
2322
|
} else {
|
|
2287
2323
|
const rawAttribute = getRawAttribute(elt, 'method')
|
|
2288
|
-
verb = rawAttribute ? rawAttribute.toLowerCase() : 'get'
|
|
2289
|
-
if (verb === 'get') {
|
|
2290
|
-
}
|
|
2324
|
+
verb = (/** @type HttpVerb */(rawAttribute ? rawAttribute.toLowerCase() : 'get'))
|
|
2291
2325
|
path = getRawAttribute(elt, 'action')
|
|
2326
|
+
if (verb === 'get' && path.includes('?')) {
|
|
2327
|
+
path = path.replace(/\?[^#]+/, '')
|
|
2328
|
+
}
|
|
2292
2329
|
}
|
|
2293
2330
|
triggerSpecs.forEach(function(triggerSpec) {
|
|
2294
2331
|
addEventListener(elt, function(node, evt) {
|
|
@@ -2377,10 +2414,15 @@ var htmx = (function() {
|
|
|
2377
2414
|
}
|
|
2378
2415
|
// store the initial values of the elements, so we can tell if they change
|
|
2379
2416
|
if (triggerSpec.changed) {
|
|
2417
|
+
if (!('lastValue' in elementData)) {
|
|
2418
|
+
elementData.lastValue = new WeakMap()
|
|
2419
|
+
}
|
|
2380
2420
|
eltsToListenOn.forEach(function(eltToListenOn) {
|
|
2381
|
-
|
|
2421
|
+
if (!elementData.lastValue.has(triggerSpec)) {
|
|
2422
|
+
elementData.lastValue.set(triggerSpec, new WeakMap())
|
|
2423
|
+
}
|
|
2382
2424
|
// @ts-ignore value will be undefined for non-input elements, which is fine
|
|
2383
|
-
|
|
2425
|
+
elementData.lastValue.get(triggerSpec).set(eltToListenOn, eltToListenOn.value)
|
|
2384
2426
|
})
|
|
2385
2427
|
}
|
|
2386
2428
|
forEach(eltsToListenOn, function(eltToListenOn) {
|
|
@@ -2422,13 +2464,14 @@ var htmx = (function() {
|
|
|
2422
2464
|
}
|
|
2423
2465
|
}
|
|
2424
2466
|
if (triggerSpec.changed) {
|
|
2425
|
-
const
|
|
2467
|
+
const node = event.target
|
|
2426
2468
|
// @ts-ignore value will be undefined for non-input elements, which is fine
|
|
2427
|
-
const value =
|
|
2428
|
-
|
|
2469
|
+
const value = node.value
|
|
2470
|
+
const lastValue = elementData.lastValue.get(triggerSpec)
|
|
2471
|
+
if (lastValue.has(node) && lastValue.get(node) === value) {
|
|
2429
2472
|
return
|
|
2430
2473
|
}
|
|
2431
|
-
|
|
2474
|
+
lastValue.set(node, value)
|
|
2432
2475
|
}
|
|
2433
2476
|
if (elementData.delayed) {
|
|
2434
2477
|
clearTimeout(elementData.delayed)
|
|
@@ -2476,6 +2519,7 @@ var htmx = (function() {
|
|
|
2476
2519
|
windowIsScrolling = true
|
|
2477
2520
|
}
|
|
2478
2521
|
window.addEventListener('scroll', scrollHandler)
|
|
2522
|
+
window.addEventListener('resize', scrollHandler)
|
|
2479
2523
|
setInterval(function() {
|
|
2480
2524
|
if (windowIsScrolling) {
|
|
2481
2525
|
windowIsScrolling = false
|
|
@@ -2805,12 +2849,6 @@ var htmx = (function() {
|
|
|
2805
2849
|
|
|
2806
2850
|
triggerEvent(elt, 'htmx:beforeProcessNode')
|
|
2807
2851
|
|
|
2808
|
-
// @ts-ignore value will be undefined for non-input elements, which is fine
|
|
2809
|
-
if (elt.value) {
|
|
2810
|
-
// @ts-ignore
|
|
2811
|
-
nodeData.lastValue = elt.value
|
|
2812
|
-
}
|
|
2813
|
-
|
|
2814
2852
|
const triggerSpecs = getTriggerSpecs(elt)
|
|
2815
2853
|
const hasExplicitHttpAction = processVerbs(elt, nodeData, triggerSpecs)
|
|
2816
2854
|
|
|
@@ -3153,7 +3191,9 @@ var htmx = (function() {
|
|
|
3153
3191
|
const settleInfo = makeSettleInfo(historyElement)
|
|
3154
3192
|
handleTitle(fragment.title)
|
|
3155
3193
|
|
|
3194
|
+
handlePreservedElements(fragment)
|
|
3156
3195
|
swapInnerHTML(historyElement, content, settleInfo)
|
|
3196
|
+
restorePreservedElements()
|
|
3157
3197
|
settleImmediately(settleInfo.tasks)
|
|
3158
3198
|
currentPathForHistory = path
|
|
3159
3199
|
triggerEvent(getDocument().body, 'htmx:historyRestore', { path, cacheMiss: true, serverResponse: this.response })
|
|
@@ -3175,8 +3215,10 @@ var htmx = (function() {
|
|
|
3175
3215
|
const fragment = makeFragment(cached.content)
|
|
3176
3216
|
const historyElement = getHistoryElement()
|
|
3177
3217
|
const settleInfo = makeSettleInfo(historyElement)
|
|
3178
|
-
handleTitle(
|
|
3218
|
+
handleTitle(cached.title)
|
|
3219
|
+
handlePreservedElements(fragment)
|
|
3179
3220
|
swapInnerHTML(historyElement, fragment, settleInfo)
|
|
3221
|
+
restorePreservedElements()
|
|
3180
3222
|
settleImmediately(settleInfo.tasks)
|
|
3181
3223
|
getWindow().setTimeout(function() {
|
|
3182
3224
|
window.scrollTo(0, cached.scroll)
|
|
@@ -3234,16 +3276,18 @@ var htmx = (function() {
|
|
|
3234
3276
|
* @param {Element[]} disabled
|
|
3235
3277
|
*/
|
|
3236
3278
|
function removeRequestIndicators(indicators, disabled) {
|
|
3279
|
+
forEach(indicators.concat(disabled), function(ele) {
|
|
3280
|
+
const internalData = getInternalData(ele)
|
|
3281
|
+
internalData.requestCount = (internalData.requestCount || 1) - 1
|
|
3282
|
+
})
|
|
3237
3283
|
forEach(indicators, function(ic) {
|
|
3238
3284
|
const internalData = getInternalData(ic)
|
|
3239
|
-
internalData.requestCount = (internalData.requestCount || 0) - 1
|
|
3240
3285
|
if (internalData.requestCount === 0) {
|
|
3241
3286
|
ic.classList.remove.call(ic.classList, htmx.config.requestClass)
|
|
3242
3287
|
}
|
|
3243
3288
|
})
|
|
3244
3289
|
forEach(disabled, function(disabledElement) {
|
|
3245
3290
|
const internalData = getInternalData(disabledElement)
|
|
3246
|
-
internalData.requestCount = (internalData.requestCount || 0) - 1
|
|
3247
3291
|
if (internalData.requestCount === 0) {
|
|
3248
3292
|
disabledElement.removeAttribute('disabled')
|
|
3249
3293
|
disabledElement.removeAttribute('data-disabled-by-htmx')
|
|
@@ -3856,16 +3900,22 @@ var htmx = (function() {
|
|
|
3856
3900
|
if (context) {
|
|
3857
3901
|
if (context instanceof Element || typeof context === 'string') {
|
|
3858
3902
|
return issueAjaxRequest(verb, path, null, null, {
|
|
3859
|
-
targetOverride: resolveTarget(context),
|
|
3903
|
+
targetOverride: resolveTarget(context) || DUMMY_ELT,
|
|
3860
3904
|
returnPromise: true
|
|
3861
3905
|
})
|
|
3862
3906
|
} else {
|
|
3907
|
+
let resolvedTarget = resolveTarget(context.target)
|
|
3908
|
+
// If target is supplied but can't resolve OR both target and source can't be resolved
|
|
3909
|
+
// then use DUMMY_ELT to abort the request with htmx:targetError to avoid it replacing body by mistake
|
|
3910
|
+
if ((context.target && !resolvedTarget) || (!resolvedTarget && !resolveTarget(context.source))) {
|
|
3911
|
+
resolvedTarget = DUMMY_ELT
|
|
3912
|
+
}
|
|
3863
3913
|
return issueAjaxRequest(verb, path, resolveTarget(context.source), context.event,
|
|
3864
3914
|
{
|
|
3865
3915
|
handler: context.handler,
|
|
3866
3916
|
headers: context.headers,
|
|
3867
3917
|
values: context.values,
|
|
3868
|
-
targetOverride:
|
|
3918
|
+
targetOverride: resolvedTarget,
|
|
3869
3919
|
swapOverride: context.swap,
|
|
3870
3920
|
select: context.select,
|
|
3871
3921
|
returnPromise: true
|
|
@@ -3927,7 +3977,7 @@ var htmx = (function() {
|
|
|
3927
3977
|
const formData = new FormData()
|
|
3928
3978
|
for (const key in obj) {
|
|
3929
3979
|
if (obj.hasOwnProperty(key)) {
|
|
3930
|
-
if (typeof obj[key].forEach === 'function') {
|
|
3980
|
+
if (obj[key] && typeof obj[key].forEach === 'function') {
|
|
3931
3981
|
obj[key].forEach(function(v) { formData.append(key, v) })
|
|
3932
3982
|
} else if (typeof obj[key] === 'object' && !(obj[key] instanceof Blob)) {
|
|
3933
3983
|
formData.append(key, JSON.stringify(obj[key]))
|
|
@@ -4020,7 +4070,7 @@ var htmx = (function() {
|
|
|
4020
4070
|
return false
|
|
4021
4071
|
}
|
|
4022
4072
|
target.delete(name)
|
|
4023
|
-
if (typeof value.forEach === 'function') {
|
|
4073
|
+
if (value && typeof value.forEach === 'function') {
|
|
4024
4074
|
value.forEach(function(v) { target.append(name, v) })
|
|
4025
4075
|
} else if (typeof value === 'object' && !(value instanceof Blob)) {
|
|
4026
4076
|
target.append(name, JSON.stringify(value))
|
|
@@ -4655,7 +4705,8 @@ var htmx = (function() {
|
|
|
4655
4705
|
serverResponse,
|
|
4656
4706
|
isError,
|
|
4657
4707
|
ignoreTitle,
|
|
4658
|
-
selectOverride
|
|
4708
|
+
selectOverride,
|
|
4709
|
+
swapOverride
|
|
4659
4710
|
}, responseInfo)
|
|
4660
4711
|
|
|
4661
4712
|
if (responseHandling.event && !triggerEvent(target, responseHandling.event, beforeSwapDetails)) return
|
|
@@ -4667,6 +4718,7 @@ var htmx = (function() {
|
|
|
4667
4718
|
isError = beforeSwapDetails.isError // allow updating error
|
|
4668
4719
|
ignoreTitle = beforeSwapDetails.ignoreTitle // allow updating ignoring title
|
|
4669
4720
|
selectOverride = beforeSwapDetails.selectOverride // allow updating select override
|
|
4721
|
+
swapOverride = beforeSwapDetails.swapOverride // allow updating swap override
|
|
4670
4722
|
|
|
4671
4723
|
responseInfo.target = target // Make updated target available to response events
|
|
4672
4724
|
responseInfo.failed = isError // Make failed property available to response events
|
|
@@ -4686,9 +4738,6 @@ var htmx = (function() {
|
|
|
4686
4738
|
saveCurrentPageToHistory()
|
|
4687
4739
|
}
|
|
4688
4740
|
|
|
4689
|
-
if (hasHeader(xhr, /HX-Reswap:/i)) {
|
|
4690
|
-
swapOverride = xhr.getResponseHeader('HX-Reswap')
|
|
4691
|
-
}
|
|
4692
4741
|
var swapSpec = getSwapSpecification(elt, swapOverride)
|
|
4693
4742
|
|
|
4694
4743
|
if (!swapSpec.hasOwnProperty('ignoreTitle')) {
|
|
@@ -5121,7 +5170,7 @@ var htmx = (function() {
|
|
|
5121
5170
|
*/
|
|
5122
5171
|
|
|
5123
5172
|
/**
|
|
5124
|
-
* @typedef {HtmxResponseInfo & {shouldSwap: boolean, serverResponse: any, isError: boolean, ignoreTitle: boolean, selectOverride:string}} HtmxBeforeSwapDetails
|
|
5173
|
+
* @typedef {HtmxResponseInfo & {shouldSwap: boolean, serverResponse: any, isError: boolean, ignoreTitle: boolean, selectOverride:string, swapOverride:string}} HtmxBeforeSwapDetails
|
|
5125
5174
|
*/
|
|
5126
5175
|
|
|
5127
5176
|
/**
|