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