htmx.org 2.0.6 → 2.0.8

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 CHANGED
@@ -32,7 +32,7 @@ By removing these arbitrary constraints htmx completes HTML as a
32
32
  ## quick start
33
33
 
34
34
  ```html
35
- <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.6/dist/htmx.min.js"></script>
35
+ <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js"></script>
36
36
  <!-- have a button POST a click via AJAX -->
37
37
  <button hx-post="/clicked" hx-swap="outerHTML">
38
38
  Click Me
package/dist/htmx.amd.js CHANGED
@@ -279,7 +279,14 @@ var htmx = (function() {
279
279
  * @type boolean
280
280
  * @default true
281
281
  */
282
- historyRestoreAsHxRequest: true
282
+ historyRestoreAsHxRequest: true,
283
+ /**
284
+ * Whether to report input validation errors to the end user and update focus to the first input that fails validation.
285
+ * This should always be enabled as this matches default browser form submit behaviour
286
+ * @type boolean
287
+ * @default false
288
+ */
289
+ reportValidityOfForms: false
283
290
  },
284
291
  /** @type {typeof parseInterval} */
285
292
  parseInterval: null,
@@ -290,7 +297,7 @@ var htmx = (function() {
290
297
  location,
291
298
  /** @type {typeof internalEval} */
292
299
  _: null,
293
- version: '2.0.6'
300
+ version: '2.0.8'
294
301
  }
295
302
  // Tsc madness part 2
296
303
  htmx.onLoad = onLoadHelper
@@ -519,6 +526,9 @@ var htmx = (function() {
519
526
  * @returns {Document}
520
527
  */
521
528
  function parseHTML(resp) {
529
+ if ('parseHTMLUnsafe' in Document) {
530
+ return Document.parseHTMLUnsafe(resp)
531
+ }
522
532
  const parser = new DOMParser()
523
533
  return parser.parseFromString(resp, 'text/html')
524
534
  }
@@ -1414,7 +1424,7 @@ var htmx = (function() {
1414
1424
  * @param {Element} mergeFrom
1415
1425
  */
1416
1426
  function cloneAttributes(mergeTo, mergeFrom) {
1417
- forEach(mergeTo.attributes, function(attr) {
1427
+ forEach(Array.from(mergeTo.attributes), function(attr) {
1418
1428
  if (!mergeFrom.hasAttribute(attr.name) && shouldSettleAttribute(attr.name)) {
1419
1429
  mergeTo.removeAttribute(attr.name)
1420
1430
  }
@@ -2425,21 +2435,22 @@ var htmx = (function() {
2425
2435
  * @returns {boolean}
2426
2436
  */
2427
2437
  function shouldCancel(evt, elt) {
2428
- if (evt.type === 'submit' || evt.type === 'click') {
2429
- // use elt from event that was submitted/clicked where possible to determining if default form/link behavior should be canceled
2430
- elt = asElement(evt.target) || elt
2431
- if (elt.tagName === 'FORM') {
2432
- return true
2433
- }
2434
- // @ts-ignore Do not cancel on buttons that 1) don't have a related form or 2) have a type attribute of 'reset'/'button'.
2435
- // The properties will resolve to undefined for elements that don't define 'type' or 'form', which is fine
2436
- if (elt.form && elt.type === 'submit') {
2438
+ if (evt.type === 'submit' && elt.tagName === 'FORM') {
2439
+ return true
2440
+ } else if (evt.type === 'click') {
2441
+ // find button wrapping the trigger element
2442
+ const btn = /** @type {HTMLButtonElement|HTMLInputElement|null} */ (elt.closest('input[type="submit"], button'))
2443
+ // Do not cancel on buttons that 1) don't have a related form or 2) have a type attribute of 'reset'/'button'.
2444
+ if (btn && btn.form && btn.type === 'submit') {
2437
2445
  return true
2438
2446
  }
2439
- elt = elt.closest('a')
2440
- // @ts-ignore check for a link wrapping the event elt or if elt is a link. elt will be link so href check is fine
2441
- if (elt && elt.href &&
2442
- (elt.getAttribute('href') === '#' || elt.getAttribute('href').indexOf('#') !== 0)) {
2447
+
2448
+ // find link wrapping the trigger element
2449
+ const link = elt.closest('a')
2450
+ // Allow links with href="#fragment" (anchors with content after #) to perform normal fragment navigation.
2451
+ // Cancel default action for links with href="#" (bare hash) to prevent scrolling to top and unwanted URL changes.
2452
+ const samePageAnchor = /^#.+/
2453
+ if (link && link.href && !samePageAnchor.test(link.getAttribute('href'))) {
2443
2454
  return true
2444
2455
  }
2445
2456
  }
@@ -2516,7 +2527,7 @@ var htmx = (function() {
2516
2527
  if (ignoreBoostedAnchorCtrlClick(elt, evt)) {
2517
2528
  return
2518
2529
  }
2519
- if (explicitCancel || shouldCancel(evt, elt)) {
2530
+ if (explicitCancel || shouldCancel(evt, eltToListenOn)) {
2520
2531
  evt.preventDefault()
2521
2532
  }
2522
2533
  if (maybeFilterEvent(triggerSpec, elt, evt)) {
@@ -2856,6 +2867,9 @@ var htmx = (function() {
2856
2867
  return
2857
2868
  }
2858
2869
  const form = getRelatedForm(elt)
2870
+ if (!form) {
2871
+ return
2872
+ }
2859
2873
  return getInternalData(form)
2860
2874
  }
2861
2875
 
@@ -3116,7 +3130,7 @@ var htmx = (function() {
3116
3130
  //= ===================================================================
3117
3131
  // History Support
3118
3132
  //= ===================================================================
3119
- let currentPathForHistory = location.pathname + location.search
3133
+ let currentPathForHistory
3120
3134
 
3121
3135
  /**
3122
3136
  * @param {string} path
@@ -3128,6 +3142,8 @@ var htmx = (function() {
3128
3142
  }
3129
3143
  }
3130
3144
 
3145
+ setCurrentPathForHistory(location.pathname + location.search)
3146
+
3131
3147
  /**
3132
3148
  * @returns {Element}
3133
3149
  */
@@ -3547,8 +3563,17 @@ var htmx = (function() {
3547
3563
  if (element.willValidate) {
3548
3564
  triggerEvent(element, 'htmx:validation:validate')
3549
3565
  if (!element.checkValidity()) {
3566
+ if (
3567
+ triggerEvent(element, 'htmx:validation:failed', {
3568
+ message: element.validationMessage,
3569
+ validity: element.validity
3570
+ }) &&
3571
+ !errors.length &&
3572
+ htmx.config.reportValidityOfForms
3573
+ ) {
3574
+ element.reportValidity()
3575
+ }
3550
3576
  errors.push({ elt: element, message: element.validationMessage, validity: element.validity })
3551
- triggerEvent(element, 'htmx:validation:failed', { message: element.validationMessage, validity: element.validity })
3552
3577
  }
3553
3578
  }
3554
3579
  }
@@ -4054,7 +4079,10 @@ var htmx = (function() {
4054
4079
  targetOverride: resolvedTarget,
4055
4080
  swapOverride: context.swap,
4056
4081
  select: context.select,
4057
- returnPromise: true
4082
+ returnPromise: true,
4083
+ push: context.push,
4084
+ replace: context.replace,
4085
+ selectOOB: context.selectOOB
4058
4086
  })
4059
4087
  }
4060
4088
  } else {
@@ -4669,8 +4697,8 @@ var htmx = (function() {
4669
4697
  const requestPath = responseInfo.pathInfo.finalRequestPath
4670
4698
  const responsePath = responseInfo.pathInfo.responsePath
4671
4699
 
4672
- const pushUrl = getClosestAttributeValue(elt, 'hx-push-url')
4673
- const replaceUrl = getClosestAttributeValue(elt, 'hx-replace-url')
4700
+ const pushUrl = responseInfo.etc.push || getClosestAttributeValue(elt, 'hx-push-url')
4701
+ const replaceUrl = responseInfo.etc.replace || getClosestAttributeValue(elt, 'hx-replace-url')
4674
4702
  const elementIsBoosted = getInternalData(elt).boosted
4675
4703
 
4676
4704
  let saveType = null
@@ -4789,19 +4817,17 @@ var htmx = (function() {
4789
4817
  }
4790
4818
 
4791
4819
  if (hasHeader(xhr, /HX-Location:/i)) {
4792
- saveCurrentPageToHistory()
4793
4820
  let redirectPath = xhr.getResponseHeader('HX-Location')
4794
- /** @type {HtmxAjaxHelperContext&{path:string}} */
4795
- var redirectSwapSpec
4821
+ /** @type {HtmxAjaxHelperContext&{path?:string}} */
4822
+ var redirectSwapSpec = {}
4796
4823
  if (redirectPath.indexOf('{') === 0) {
4797
4824
  redirectSwapSpec = parseJSON(redirectPath)
4798
4825
  // what's the best way to throw an error if the user didn't include this
4799
4826
  redirectPath = redirectSwapSpec.path
4800
4827
  delete redirectSwapSpec.path
4801
4828
  }
4802
- ajaxHelper('get', redirectPath, redirectSwapSpec).then(function() {
4803
- pushUrlIntoHistory(redirectPath)
4804
- })
4829
+ redirectSwapSpec.push = redirectSwapSpec.push || 'true'
4830
+ ajaxHelper('get', redirectPath, redirectSwapSpec)
4805
4831
  return
4806
4832
  }
4807
4833
 
@@ -4900,7 +4926,7 @@ var htmx = (function() {
4900
4926
  selectOverride = xhr.getResponseHeader('HX-Reselect')
4901
4927
  }
4902
4928
 
4903
- const selectOOB = getClosestAttributeValue(elt, 'hx-select-oob')
4929
+ const selectOOB = etc.selectOOB || getClosestAttributeValue(elt, 'hx-select-oob')
4904
4930
  const select = getClosestAttributeValue(elt, 'hx-select')
4905
4931
 
4906
4932
  swap(target, serverResponse, swapSpec, {
@@ -5061,12 +5087,14 @@ var htmx = (function() {
5061
5087
  function insertIndicatorStyles() {
5062
5088
  if (htmx.config.includeIndicatorStyles !== false) {
5063
5089
  const nonceAttribute = htmx.config.inlineStyleNonce ? ` nonce="${htmx.config.inlineStyleNonce}"` : ''
5090
+ const indicator = htmx.config.indicatorClass
5091
+ const request = htmx.config.requestClass
5064
5092
  getDocument().head.insertAdjacentHTML('beforeend',
5065
- '<style' + nonceAttribute + '>\
5066
- .' + htmx.config.indicatorClass + '{opacity:0}\
5067
- .' + htmx.config.requestClass + ' .' + htmx.config.indicatorClass + '{opacity:1; transition: opacity 200ms ease-in;}\
5068
- .' + htmx.config.requestClass + '.' + htmx.config.indicatorClass + '{opacity:1; transition: opacity 200ms ease-in;}\
5069
- </style>')
5093
+ `<style${nonceAttribute}>` +
5094
+ `.${indicator}{opacity:0;visibility: hidden} ` +
5095
+ `.${request} .${indicator}, .${request}.${indicator}{opacity:1;visibility: visible;transition: opacity 200ms ease-in}` +
5096
+ '</style>'
5097
+ )
5070
5098
  }
5071
5099
  }
5072
5100
 
@@ -5097,7 +5125,7 @@ var htmx = (function() {
5097
5125
  "[hx-trigger='restored'],[data-hx-trigger='restored']"
5098
5126
  )
5099
5127
  body.addEventListener('htmx:abort', function(evt) {
5100
- const target = evt.target
5128
+ const target = (/** @type {CustomEvent} */(evt)).detail.elt || evt.target
5101
5129
  const internalData = getInternalData(target)
5102
5130
  if (internalData && internalData.xhr) {
5103
5131
  internalData.xhr.abort()
@@ -5217,6 +5245,9 @@ var htmx = (function() {
5217
5245
  * @property {Object|FormData} [values]
5218
5246
  * @property {Record<string,string>} [headers]
5219
5247
  * @property {string} [select]
5248
+ * @property {string} [push]
5249
+ * @property {string} [replace]
5250
+ * @property {string} [selectOOB]
5220
5251
  */
5221
5252
 
5222
5253
  /**
@@ -5263,6 +5294,9 @@ var htmx = (function() {
5263
5294
  * @property {Object|FormData} [values]
5264
5295
  * @property {boolean} [credentials]
5265
5296
  * @property {number} [timeout]
5297
+ * @property {string} [push]
5298
+ * @property {string} [replace]
5299
+ * @property {string} [selectOOB]
5266
5300
  */
5267
5301
 
5268
5302
  /**
package/dist/htmx.cjs.js CHANGED
@@ -278,7 +278,14 @@ var htmx = (function() {
278
278
  * @type boolean
279
279
  * @default true
280
280
  */
281
- historyRestoreAsHxRequest: true
281
+ historyRestoreAsHxRequest: true,
282
+ /**
283
+ * Whether to report input validation errors to the end user and update focus to the first input that fails validation.
284
+ * This should always be enabled as this matches default browser form submit behaviour
285
+ * @type boolean
286
+ * @default false
287
+ */
288
+ reportValidityOfForms: false
282
289
  },
283
290
  /** @type {typeof parseInterval} */
284
291
  parseInterval: null,
@@ -289,7 +296,7 @@ var htmx = (function() {
289
296
  location,
290
297
  /** @type {typeof internalEval} */
291
298
  _: null,
292
- version: '2.0.6'
299
+ version: '2.0.8'
293
300
  }
294
301
  // Tsc madness part 2
295
302
  htmx.onLoad = onLoadHelper
@@ -518,6 +525,9 @@ var htmx = (function() {
518
525
  * @returns {Document}
519
526
  */
520
527
  function parseHTML(resp) {
528
+ if ('parseHTMLUnsafe' in Document) {
529
+ return Document.parseHTMLUnsafe(resp)
530
+ }
521
531
  const parser = new DOMParser()
522
532
  return parser.parseFromString(resp, 'text/html')
523
533
  }
@@ -1413,7 +1423,7 @@ var htmx = (function() {
1413
1423
  * @param {Element} mergeFrom
1414
1424
  */
1415
1425
  function cloneAttributes(mergeTo, mergeFrom) {
1416
- forEach(mergeTo.attributes, function(attr) {
1426
+ forEach(Array.from(mergeTo.attributes), function(attr) {
1417
1427
  if (!mergeFrom.hasAttribute(attr.name) && shouldSettleAttribute(attr.name)) {
1418
1428
  mergeTo.removeAttribute(attr.name)
1419
1429
  }
@@ -2424,21 +2434,22 @@ var htmx = (function() {
2424
2434
  * @returns {boolean}
2425
2435
  */
2426
2436
  function shouldCancel(evt, elt) {
2427
- if (evt.type === 'submit' || evt.type === 'click') {
2428
- // use elt from event that was submitted/clicked where possible to determining if default form/link behavior should be canceled
2429
- elt = asElement(evt.target) || elt
2430
- if (elt.tagName === 'FORM') {
2431
- return true
2432
- }
2433
- // @ts-ignore Do not cancel on buttons that 1) don't have a related form or 2) have a type attribute of 'reset'/'button'.
2434
- // The properties will resolve to undefined for elements that don't define 'type' or 'form', which is fine
2435
- if (elt.form && elt.type === 'submit') {
2437
+ if (evt.type === 'submit' && elt.tagName === 'FORM') {
2438
+ return true
2439
+ } else if (evt.type === 'click') {
2440
+ // find button wrapping the trigger element
2441
+ const btn = /** @type {HTMLButtonElement|HTMLInputElement|null} */ (elt.closest('input[type="submit"], button'))
2442
+ // Do not cancel on buttons that 1) don't have a related form or 2) have a type attribute of 'reset'/'button'.
2443
+ if (btn && btn.form && btn.type === 'submit') {
2436
2444
  return true
2437
2445
  }
2438
- elt = elt.closest('a')
2439
- // @ts-ignore check for a link wrapping the event elt or if elt is a link. elt will be link so href check is fine
2440
- if (elt && elt.href &&
2441
- (elt.getAttribute('href') === '#' || elt.getAttribute('href').indexOf('#') !== 0)) {
2446
+
2447
+ // find link wrapping the trigger element
2448
+ const link = elt.closest('a')
2449
+ // Allow links with href="#fragment" (anchors with content after #) to perform normal fragment navigation.
2450
+ // Cancel default action for links with href="#" (bare hash) to prevent scrolling to top and unwanted URL changes.
2451
+ const samePageAnchor = /^#.+/
2452
+ if (link && link.href && !samePageAnchor.test(link.getAttribute('href'))) {
2442
2453
  return true
2443
2454
  }
2444
2455
  }
@@ -2515,7 +2526,7 @@ var htmx = (function() {
2515
2526
  if (ignoreBoostedAnchorCtrlClick(elt, evt)) {
2516
2527
  return
2517
2528
  }
2518
- if (explicitCancel || shouldCancel(evt, elt)) {
2529
+ if (explicitCancel || shouldCancel(evt, eltToListenOn)) {
2519
2530
  evt.preventDefault()
2520
2531
  }
2521
2532
  if (maybeFilterEvent(triggerSpec, elt, evt)) {
@@ -2855,6 +2866,9 @@ var htmx = (function() {
2855
2866
  return
2856
2867
  }
2857
2868
  const form = getRelatedForm(elt)
2869
+ if (!form) {
2870
+ return
2871
+ }
2858
2872
  return getInternalData(form)
2859
2873
  }
2860
2874
 
@@ -3115,7 +3129,7 @@ var htmx = (function() {
3115
3129
  //= ===================================================================
3116
3130
  // History Support
3117
3131
  //= ===================================================================
3118
- let currentPathForHistory = location.pathname + location.search
3132
+ let currentPathForHistory
3119
3133
 
3120
3134
  /**
3121
3135
  * @param {string} path
@@ -3127,6 +3141,8 @@ var htmx = (function() {
3127
3141
  }
3128
3142
  }
3129
3143
 
3144
+ setCurrentPathForHistory(location.pathname + location.search)
3145
+
3130
3146
  /**
3131
3147
  * @returns {Element}
3132
3148
  */
@@ -3546,8 +3562,17 @@ var htmx = (function() {
3546
3562
  if (element.willValidate) {
3547
3563
  triggerEvent(element, 'htmx:validation:validate')
3548
3564
  if (!element.checkValidity()) {
3565
+ if (
3566
+ triggerEvent(element, 'htmx:validation:failed', {
3567
+ message: element.validationMessage,
3568
+ validity: element.validity
3569
+ }) &&
3570
+ !errors.length &&
3571
+ htmx.config.reportValidityOfForms
3572
+ ) {
3573
+ element.reportValidity()
3574
+ }
3549
3575
  errors.push({ elt: element, message: element.validationMessage, validity: element.validity })
3550
- triggerEvent(element, 'htmx:validation:failed', { message: element.validationMessage, validity: element.validity })
3551
3576
  }
3552
3577
  }
3553
3578
  }
@@ -4053,7 +4078,10 @@ var htmx = (function() {
4053
4078
  targetOverride: resolvedTarget,
4054
4079
  swapOverride: context.swap,
4055
4080
  select: context.select,
4056
- returnPromise: true
4081
+ returnPromise: true,
4082
+ push: context.push,
4083
+ replace: context.replace,
4084
+ selectOOB: context.selectOOB
4057
4085
  })
4058
4086
  }
4059
4087
  } else {
@@ -4668,8 +4696,8 @@ var htmx = (function() {
4668
4696
  const requestPath = responseInfo.pathInfo.finalRequestPath
4669
4697
  const responsePath = responseInfo.pathInfo.responsePath
4670
4698
 
4671
- const pushUrl = getClosestAttributeValue(elt, 'hx-push-url')
4672
- const replaceUrl = getClosestAttributeValue(elt, 'hx-replace-url')
4699
+ const pushUrl = responseInfo.etc.push || getClosestAttributeValue(elt, 'hx-push-url')
4700
+ const replaceUrl = responseInfo.etc.replace || getClosestAttributeValue(elt, 'hx-replace-url')
4673
4701
  const elementIsBoosted = getInternalData(elt).boosted
4674
4702
 
4675
4703
  let saveType = null
@@ -4788,19 +4816,17 @@ var htmx = (function() {
4788
4816
  }
4789
4817
 
4790
4818
  if (hasHeader(xhr, /HX-Location:/i)) {
4791
- saveCurrentPageToHistory()
4792
4819
  let redirectPath = xhr.getResponseHeader('HX-Location')
4793
- /** @type {HtmxAjaxHelperContext&{path:string}} */
4794
- var redirectSwapSpec
4820
+ /** @type {HtmxAjaxHelperContext&{path?:string}} */
4821
+ var redirectSwapSpec = {}
4795
4822
  if (redirectPath.indexOf('{') === 0) {
4796
4823
  redirectSwapSpec = parseJSON(redirectPath)
4797
4824
  // what's the best way to throw an error if the user didn't include this
4798
4825
  redirectPath = redirectSwapSpec.path
4799
4826
  delete redirectSwapSpec.path
4800
4827
  }
4801
- ajaxHelper('get', redirectPath, redirectSwapSpec).then(function() {
4802
- pushUrlIntoHistory(redirectPath)
4803
- })
4828
+ redirectSwapSpec.push = redirectSwapSpec.push || 'true'
4829
+ ajaxHelper('get', redirectPath, redirectSwapSpec)
4804
4830
  return
4805
4831
  }
4806
4832
 
@@ -4899,7 +4925,7 @@ var htmx = (function() {
4899
4925
  selectOverride = xhr.getResponseHeader('HX-Reselect')
4900
4926
  }
4901
4927
 
4902
- const selectOOB = getClosestAttributeValue(elt, 'hx-select-oob')
4928
+ const selectOOB = etc.selectOOB || getClosestAttributeValue(elt, 'hx-select-oob')
4903
4929
  const select = getClosestAttributeValue(elt, 'hx-select')
4904
4930
 
4905
4931
  swap(target, serverResponse, swapSpec, {
@@ -5060,12 +5086,14 @@ var htmx = (function() {
5060
5086
  function insertIndicatorStyles() {
5061
5087
  if (htmx.config.includeIndicatorStyles !== false) {
5062
5088
  const nonceAttribute = htmx.config.inlineStyleNonce ? ` nonce="${htmx.config.inlineStyleNonce}"` : ''
5089
+ const indicator = htmx.config.indicatorClass
5090
+ const request = htmx.config.requestClass
5063
5091
  getDocument().head.insertAdjacentHTML('beforeend',
5064
- '<style' + nonceAttribute + '>\
5065
- .' + htmx.config.indicatorClass + '{opacity:0}\
5066
- .' + htmx.config.requestClass + ' .' + htmx.config.indicatorClass + '{opacity:1; transition: opacity 200ms ease-in;}\
5067
- .' + htmx.config.requestClass + '.' + htmx.config.indicatorClass + '{opacity:1; transition: opacity 200ms ease-in;}\
5068
- </style>')
5092
+ `<style${nonceAttribute}>` +
5093
+ `.${indicator}{opacity:0;visibility: hidden} ` +
5094
+ `.${request} .${indicator}, .${request}.${indicator}{opacity:1;visibility: visible;transition: opacity 200ms ease-in}` +
5095
+ '</style>'
5096
+ )
5069
5097
  }
5070
5098
  }
5071
5099
 
@@ -5096,7 +5124,7 @@ var htmx = (function() {
5096
5124
  "[hx-trigger='restored'],[data-hx-trigger='restored']"
5097
5125
  )
5098
5126
  body.addEventListener('htmx:abort', function(evt) {
5099
- const target = evt.target
5127
+ const target = (/** @type {CustomEvent} */(evt)).detail.elt || evt.target
5100
5128
  const internalData = getInternalData(target)
5101
5129
  if (internalData && internalData.xhr) {
5102
5130
  internalData.xhr.abort()
@@ -5216,6 +5244,9 @@ var htmx = (function() {
5216
5244
  * @property {Object|FormData} [values]
5217
5245
  * @property {Record<string,string>} [headers]
5218
5246
  * @property {string} [select]
5247
+ * @property {string} [push]
5248
+ * @property {string} [replace]
5249
+ * @property {string} [selectOOB]
5219
5250
  */
5220
5251
 
5221
5252
  /**
@@ -5262,6 +5293,9 @@ var htmx = (function() {
5262
5293
  * @property {Object|FormData} [values]
5263
5294
  * @property {boolean} [credentials]
5264
5295
  * @property {number} [timeout]
5296
+ * @property {string} [push]
5297
+ * @property {string} [replace]
5298
+ * @property {string} [selectOOB]
5265
5299
  */
5266
5300
 
5267
5301
  /**
@@ -60,6 +60,9 @@ export type HtmxAjaxHelperContext = {
60
60
  values?: any | FormData;
61
61
  headers?: Record<string, string>;
62
62
  select?: string;
63
+ push?: string;
64
+ replace?: string;
65
+ selectOOB?: string;
63
66
  };
64
67
  export type HtmxRequestConfig = {
65
68
  boosted: boolean;
@@ -111,6 +114,9 @@ export type HtmxAjaxEtc = {
111
114
  values?: any | FormData;
112
115
  credentials?: boolean;
113
116
  timeout?: number;
117
+ push?: string;
118
+ replace?: string;
119
+ selectOOB?: string;
114
120
  };
115
121
  export type HtmxResponseHandlingConfig = {
116
122
  code?: string;
@@ -204,6 +210,7 @@ declare namespace htmx {
204
210
  let responseHandling: HtmxResponseHandlingConfig[];
205
211
  let allowNestedOobSwaps: boolean;
206
212
  let historyRestoreAsHxRequest: boolean;
213
+ let reportValidityOfForms: boolean;
207
214
  }
208
215
  let parseInterval: (str: string) => number | undefined;
209
216
  let location: Location;