prep 2.0.8 release

This commit is contained in:
Carson Gross
2025-10-24 20:42:29 -06:00
parent a6c3323e61
commit 49d6aa3752
20 changed files with 128 additions and 74 deletions

View File

@@ -32,7 +32,7 @@ By removing these arbitrary constraints htmx completes HTML as a
## quick start ## quick start
```html ```html
<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.7/dist/htmx.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js"></script>
<!-- have a button POST a click via AJAX --> <!-- have a button POST a click via AJAX -->
<button hx-post="/clicked" hx-swap="outerHTML"> <button hx-post="/clicked" hx-swap="outerHTML">
Click Me Click Me

40
dist/htmx.amd.js vendored
View File

@@ -281,7 +281,7 @@ var htmx = (function() {
*/ */
historyRestoreAsHxRequest: true, historyRestoreAsHxRequest: true,
/** /**
* Weather to report input validation errors to the end user and update focus to the first input that fails validation. * Whether to report input validation errors to the end user and update focus to the first input that fails validation.
* This should always be enabled as this matches default browser form submit behaviour * This should always be enabled as this matches default browser form submit behaviour
* @type boolean * @type boolean
* @default false * @default false
@@ -297,7 +297,7 @@ var htmx = (function() {
location, location,
/** @type {typeof internalEval} */ /** @type {typeof internalEval} */
_: null, _: null,
version: '2.0.7' version: '2.0.8'
} }
// Tsc madness part 2 // Tsc madness part 2
htmx.onLoad = onLoadHelper htmx.onLoad = onLoadHelper
@@ -526,6 +526,9 @@ var htmx = (function() {
* @returns {Document} * @returns {Document}
*/ */
function parseHTML(resp) { function parseHTML(resp) {
if ('parseHTMLUnsafe' in Document) {
return Document.parseHTMLUnsafe(resp)
}
const parser = new DOMParser() const parser = new DOMParser()
return parser.parseFromString(resp, 'text/html') return parser.parseFromString(resp, 'text/html')
} }
@@ -3127,7 +3130,7 @@ var htmx = (function() {
//= =================================================================== //= ===================================================================
// History Support // History Support
//= =================================================================== //= ===================================================================
let currentPathForHistory = location.pathname + location.search let currentPathForHistory
/** /**
* @param {string} path * @param {string} path
@@ -3139,6 +3142,8 @@ var htmx = (function() {
} }
} }
setCurrentPathForHistory(location.pathname + location.search)
/** /**
* @returns {Element} * @returns {Element}
*/ */
@@ -4074,7 +4079,10 @@ var htmx = (function() {
targetOverride: resolvedTarget, targetOverride: resolvedTarget,
swapOverride: context.swap, swapOverride: context.swap,
select: context.select, select: context.select,
returnPromise: true returnPromise: true,
push: context.push,
replace: context.replace,
selectOOB: context.selectOOB
}) })
} }
} else { } else {
@@ -4689,8 +4697,8 @@ var htmx = (function() {
const requestPath = responseInfo.pathInfo.finalRequestPath const requestPath = responseInfo.pathInfo.finalRequestPath
const responsePath = responseInfo.pathInfo.responsePath const responsePath = responseInfo.pathInfo.responsePath
const pushUrl = getClosestAttributeValue(elt, 'hx-push-url') const pushUrl = responseInfo.etc.push || getClosestAttributeValue(elt, 'hx-push-url')
const replaceUrl = getClosestAttributeValue(elt, 'hx-replace-url') const replaceUrl = responseInfo.etc.replace || getClosestAttributeValue(elt, 'hx-replace-url')
const elementIsBoosted = getInternalData(elt).boosted const elementIsBoosted = getInternalData(elt).boosted
let saveType = null let saveType = null
@@ -4809,19 +4817,17 @@ var htmx = (function() {
} }
if (hasHeader(xhr, /HX-Location:/i)) { if (hasHeader(xhr, /HX-Location:/i)) {
saveCurrentPageToHistory()
let redirectPath = xhr.getResponseHeader('HX-Location') let redirectPath = xhr.getResponseHeader('HX-Location')
/** @type {HtmxAjaxHelperContext&{path:string}} */ /** @type {HtmxAjaxHelperContext&{path?:string}} */
var redirectSwapSpec var redirectSwapSpec = {}
if (redirectPath.indexOf('{') === 0) { if (redirectPath.indexOf('{') === 0) {
redirectSwapSpec = parseJSON(redirectPath) redirectSwapSpec = parseJSON(redirectPath)
// what's the best way to throw an error if the user didn't include this // what's the best way to throw an error if the user didn't include this
redirectPath = redirectSwapSpec.path redirectPath = redirectSwapSpec.path
delete redirectSwapSpec.path delete redirectSwapSpec.path
} }
ajaxHelper('get', redirectPath, redirectSwapSpec).then(function() { redirectSwapSpec.push = redirectSwapSpec.push || 'true'
pushUrlIntoHistory(redirectPath) ajaxHelper('get', redirectPath, redirectSwapSpec)
})
return return
} }
@@ -4920,7 +4926,7 @@ var htmx = (function() {
selectOverride = xhr.getResponseHeader('HX-Reselect') selectOverride = xhr.getResponseHeader('HX-Reselect')
} }
const selectOOB = getClosestAttributeValue(elt, 'hx-select-oob') const selectOOB = etc.selectOOB || getClosestAttributeValue(elt, 'hx-select-oob')
const select = getClosestAttributeValue(elt, 'hx-select') const select = getClosestAttributeValue(elt, 'hx-select')
swap(target, serverResponse, swapSpec, { swap(target, serverResponse, swapSpec, {
@@ -5119,7 +5125,7 @@ var htmx = (function() {
"[hx-trigger='restored'],[data-hx-trigger='restored']" "[hx-trigger='restored'],[data-hx-trigger='restored']"
) )
body.addEventListener('htmx:abort', function(evt) { body.addEventListener('htmx:abort', function(evt) {
const target = evt.target const target = (/** @type {CustomEvent} */(evt)).detail.elt || evt.target
const internalData = getInternalData(target) const internalData = getInternalData(target)
if (internalData && internalData.xhr) { if (internalData && internalData.xhr) {
internalData.xhr.abort() internalData.xhr.abort()
@@ -5239,6 +5245,9 @@ var htmx = (function() {
* @property {Object|FormData} [values] * @property {Object|FormData} [values]
* @property {Record<string,string>} [headers] * @property {Record<string,string>} [headers]
* @property {string} [select] * @property {string} [select]
* @property {string} [push]
* @property {string} [replace]
* @property {string} [selectOOB]
*/ */
/** /**
@@ -5285,6 +5294,9 @@ var htmx = (function() {
* @property {Object|FormData} [values] * @property {Object|FormData} [values]
* @property {boolean} [credentials] * @property {boolean} [credentials]
* @property {number} [timeout] * @property {number} [timeout]
* @property {string} [push]
* @property {string} [replace]
* @property {string} [selectOOB]
*/ */
/** /**

40
dist/htmx.cjs.js vendored
View File

@@ -280,7 +280,7 @@ var htmx = (function() {
*/ */
historyRestoreAsHxRequest: true, historyRestoreAsHxRequest: true,
/** /**
* Weather to report input validation errors to the end user and update focus to the first input that fails validation. * Whether to report input validation errors to the end user and update focus to the first input that fails validation.
* This should always be enabled as this matches default browser form submit behaviour * This should always be enabled as this matches default browser form submit behaviour
* @type boolean * @type boolean
* @default false * @default false
@@ -296,7 +296,7 @@ var htmx = (function() {
location, location,
/** @type {typeof internalEval} */ /** @type {typeof internalEval} */
_: null, _: null,
version: '2.0.7' version: '2.0.8'
} }
// Tsc madness part 2 // Tsc madness part 2
htmx.onLoad = onLoadHelper htmx.onLoad = onLoadHelper
@@ -525,6 +525,9 @@ var htmx = (function() {
* @returns {Document} * @returns {Document}
*/ */
function parseHTML(resp) { function parseHTML(resp) {
if ('parseHTMLUnsafe' in Document) {
return Document.parseHTMLUnsafe(resp)
}
const parser = new DOMParser() const parser = new DOMParser()
return parser.parseFromString(resp, 'text/html') return parser.parseFromString(resp, 'text/html')
} }
@@ -3126,7 +3129,7 @@ var htmx = (function() {
//= =================================================================== //= ===================================================================
// History Support // History Support
//= =================================================================== //= ===================================================================
let currentPathForHistory = location.pathname + location.search let currentPathForHistory
/** /**
* @param {string} path * @param {string} path
@@ -3138,6 +3141,8 @@ var htmx = (function() {
} }
} }
setCurrentPathForHistory(location.pathname + location.search)
/** /**
* @returns {Element} * @returns {Element}
*/ */
@@ -4073,7 +4078,10 @@ var htmx = (function() {
targetOverride: resolvedTarget, targetOverride: resolvedTarget,
swapOverride: context.swap, swapOverride: context.swap,
select: context.select, select: context.select,
returnPromise: true returnPromise: true,
push: context.push,
replace: context.replace,
selectOOB: context.selectOOB
}) })
} }
} else { } else {
@@ -4688,8 +4696,8 @@ var htmx = (function() {
const requestPath = responseInfo.pathInfo.finalRequestPath const requestPath = responseInfo.pathInfo.finalRequestPath
const responsePath = responseInfo.pathInfo.responsePath const responsePath = responseInfo.pathInfo.responsePath
const pushUrl = getClosestAttributeValue(elt, 'hx-push-url') const pushUrl = responseInfo.etc.push || getClosestAttributeValue(elt, 'hx-push-url')
const replaceUrl = getClosestAttributeValue(elt, 'hx-replace-url') const replaceUrl = responseInfo.etc.replace || getClosestAttributeValue(elt, 'hx-replace-url')
const elementIsBoosted = getInternalData(elt).boosted const elementIsBoosted = getInternalData(elt).boosted
let saveType = null let saveType = null
@@ -4808,19 +4816,17 @@ var htmx = (function() {
} }
if (hasHeader(xhr, /HX-Location:/i)) { if (hasHeader(xhr, /HX-Location:/i)) {
saveCurrentPageToHistory()
let redirectPath = xhr.getResponseHeader('HX-Location') let redirectPath = xhr.getResponseHeader('HX-Location')
/** @type {HtmxAjaxHelperContext&{path:string}} */ /** @type {HtmxAjaxHelperContext&{path?:string}} */
var redirectSwapSpec var redirectSwapSpec = {}
if (redirectPath.indexOf('{') === 0) { if (redirectPath.indexOf('{') === 0) {
redirectSwapSpec = parseJSON(redirectPath) redirectSwapSpec = parseJSON(redirectPath)
// what's the best way to throw an error if the user didn't include this // what's the best way to throw an error if the user didn't include this
redirectPath = redirectSwapSpec.path redirectPath = redirectSwapSpec.path
delete redirectSwapSpec.path delete redirectSwapSpec.path
} }
ajaxHelper('get', redirectPath, redirectSwapSpec).then(function() { redirectSwapSpec.push = redirectSwapSpec.push || 'true'
pushUrlIntoHistory(redirectPath) ajaxHelper('get', redirectPath, redirectSwapSpec)
})
return return
} }
@@ -4919,7 +4925,7 @@ var htmx = (function() {
selectOverride = xhr.getResponseHeader('HX-Reselect') selectOverride = xhr.getResponseHeader('HX-Reselect')
} }
const selectOOB = getClosestAttributeValue(elt, 'hx-select-oob') const selectOOB = etc.selectOOB || getClosestAttributeValue(elt, 'hx-select-oob')
const select = getClosestAttributeValue(elt, 'hx-select') const select = getClosestAttributeValue(elt, 'hx-select')
swap(target, serverResponse, swapSpec, { swap(target, serverResponse, swapSpec, {
@@ -5118,7 +5124,7 @@ var htmx = (function() {
"[hx-trigger='restored'],[data-hx-trigger='restored']" "[hx-trigger='restored'],[data-hx-trigger='restored']"
) )
body.addEventListener('htmx:abort', function(evt) { body.addEventListener('htmx:abort', function(evt) {
const target = evt.target const target = (/** @type {CustomEvent} */(evt)).detail.elt || evt.target
const internalData = getInternalData(target) const internalData = getInternalData(target)
if (internalData && internalData.xhr) { if (internalData && internalData.xhr) {
internalData.xhr.abort() internalData.xhr.abort()
@@ -5238,6 +5244,9 @@ var htmx = (function() {
* @property {Object|FormData} [values] * @property {Object|FormData} [values]
* @property {Record<string,string>} [headers] * @property {Record<string,string>} [headers]
* @property {string} [select] * @property {string} [select]
* @property {string} [push]
* @property {string} [replace]
* @property {string} [selectOOB]
*/ */
/** /**
@@ -5284,6 +5293,9 @@ var htmx = (function() {
* @property {Object|FormData} [values] * @property {Object|FormData} [values]
* @property {boolean} [credentials] * @property {boolean} [credentials]
* @property {number} [timeout] * @property {number} [timeout]
* @property {string} [push]
* @property {string} [replace]
* @property {string} [selectOOB]
*/ */
/** /**

6
dist/htmx.esm.d.ts vendored
View File

@@ -60,6 +60,9 @@ export type HtmxAjaxHelperContext = {
values?: any | FormData; values?: any | FormData;
headers?: Record<string, string>; headers?: Record<string, string>;
select?: string; select?: string;
push?: string;
replace?: string;
selectOOB?: string;
}; };
export type HtmxRequestConfig = { export type HtmxRequestConfig = {
boosted: boolean; boosted: boolean;
@@ -111,6 +114,9 @@ export type HtmxAjaxEtc = {
values?: any | FormData; values?: any | FormData;
credentials?: boolean; credentials?: boolean;
timeout?: number; timeout?: number;
push?: string;
replace?: string;
selectOOB?: string;
}; };
export type HtmxResponseHandlingConfig = { export type HtmxResponseHandlingConfig = {
code?: string; code?: string;

40
dist/htmx.esm.js vendored
View File

@@ -280,7 +280,7 @@ var htmx = (function() {
*/ */
historyRestoreAsHxRequest: true, historyRestoreAsHxRequest: true,
/** /**
* Weather to report input validation errors to the end user and update focus to the first input that fails validation. * Whether to report input validation errors to the end user and update focus to the first input that fails validation.
* This should always be enabled as this matches default browser form submit behaviour * This should always be enabled as this matches default browser form submit behaviour
* @type boolean * @type boolean
* @default false * @default false
@@ -296,7 +296,7 @@ var htmx = (function() {
location, location,
/** @type {typeof internalEval} */ /** @type {typeof internalEval} */
_: null, _: null,
version: '2.0.7' version: '2.0.8'
} }
// Tsc madness part 2 // Tsc madness part 2
htmx.onLoad = onLoadHelper htmx.onLoad = onLoadHelper
@@ -525,6 +525,9 @@ var htmx = (function() {
* @returns {Document} * @returns {Document}
*/ */
function parseHTML(resp) { function parseHTML(resp) {
if ('parseHTMLUnsafe' in Document) {
return Document.parseHTMLUnsafe(resp)
}
const parser = new DOMParser() const parser = new DOMParser()
return parser.parseFromString(resp, 'text/html') return parser.parseFromString(resp, 'text/html')
} }
@@ -3126,7 +3129,7 @@ var htmx = (function() {
//= =================================================================== //= ===================================================================
// History Support // History Support
//= =================================================================== //= ===================================================================
let currentPathForHistory = location.pathname + location.search let currentPathForHistory
/** /**
* @param {string} path * @param {string} path
@@ -3138,6 +3141,8 @@ var htmx = (function() {
} }
} }
setCurrentPathForHistory(location.pathname + location.search)
/** /**
* @returns {Element} * @returns {Element}
*/ */
@@ -4073,7 +4078,10 @@ var htmx = (function() {
targetOverride: resolvedTarget, targetOverride: resolvedTarget,
swapOverride: context.swap, swapOverride: context.swap,
select: context.select, select: context.select,
returnPromise: true returnPromise: true,
push: context.push,
replace: context.replace,
selectOOB: context.selectOOB
}) })
} }
} else { } else {
@@ -4688,8 +4696,8 @@ var htmx = (function() {
const requestPath = responseInfo.pathInfo.finalRequestPath const requestPath = responseInfo.pathInfo.finalRequestPath
const responsePath = responseInfo.pathInfo.responsePath const responsePath = responseInfo.pathInfo.responsePath
const pushUrl = getClosestAttributeValue(elt, 'hx-push-url') const pushUrl = responseInfo.etc.push || getClosestAttributeValue(elt, 'hx-push-url')
const replaceUrl = getClosestAttributeValue(elt, 'hx-replace-url') const replaceUrl = responseInfo.etc.replace || getClosestAttributeValue(elt, 'hx-replace-url')
const elementIsBoosted = getInternalData(elt).boosted const elementIsBoosted = getInternalData(elt).boosted
let saveType = null let saveType = null
@@ -4808,19 +4816,17 @@ var htmx = (function() {
} }
if (hasHeader(xhr, /HX-Location:/i)) { if (hasHeader(xhr, /HX-Location:/i)) {
saveCurrentPageToHistory()
let redirectPath = xhr.getResponseHeader('HX-Location') let redirectPath = xhr.getResponseHeader('HX-Location')
/** @type {HtmxAjaxHelperContext&{path:string}} */ /** @type {HtmxAjaxHelperContext&{path?:string}} */
var redirectSwapSpec var redirectSwapSpec = {}
if (redirectPath.indexOf('{') === 0) { if (redirectPath.indexOf('{') === 0) {
redirectSwapSpec = parseJSON(redirectPath) redirectSwapSpec = parseJSON(redirectPath)
// what's the best way to throw an error if the user didn't include this // what's the best way to throw an error if the user didn't include this
redirectPath = redirectSwapSpec.path redirectPath = redirectSwapSpec.path
delete redirectSwapSpec.path delete redirectSwapSpec.path
} }
ajaxHelper('get', redirectPath, redirectSwapSpec).then(function() { redirectSwapSpec.push = redirectSwapSpec.push || 'true'
pushUrlIntoHistory(redirectPath) ajaxHelper('get', redirectPath, redirectSwapSpec)
})
return return
} }
@@ -4919,7 +4925,7 @@ var htmx = (function() {
selectOverride = xhr.getResponseHeader('HX-Reselect') selectOverride = xhr.getResponseHeader('HX-Reselect')
} }
const selectOOB = getClosestAttributeValue(elt, 'hx-select-oob') const selectOOB = etc.selectOOB || getClosestAttributeValue(elt, 'hx-select-oob')
const select = getClosestAttributeValue(elt, 'hx-select') const select = getClosestAttributeValue(elt, 'hx-select')
swap(target, serverResponse, swapSpec, { swap(target, serverResponse, swapSpec, {
@@ -5118,7 +5124,7 @@ var htmx = (function() {
"[hx-trigger='restored'],[data-hx-trigger='restored']" "[hx-trigger='restored'],[data-hx-trigger='restored']"
) )
body.addEventListener('htmx:abort', function(evt) { body.addEventListener('htmx:abort', function(evt) {
const target = evt.target const target = (/** @type {CustomEvent} */(evt)).detail.elt || evt.target
const internalData = getInternalData(target) const internalData = getInternalData(target)
if (internalData && internalData.xhr) { if (internalData && internalData.xhr) {
internalData.xhr.abort() internalData.xhr.abort()
@@ -5238,6 +5244,9 @@ var htmx = (function() {
* @property {Object|FormData} [values] * @property {Object|FormData} [values]
* @property {Record<string,string>} [headers] * @property {Record<string,string>} [headers]
* @property {string} [select] * @property {string} [select]
* @property {string} [push]
* @property {string} [replace]
* @property {string} [selectOOB]
*/ */
/** /**
@@ -5284,6 +5293,9 @@ var htmx = (function() {
* @property {Object|FormData} [values] * @property {Object|FormData} [values]
* @property {boolean} [credentials] * @property {boolean} [credentials]
* @property {number} [timeout] * @property {number} [timeout]
* @property {string} [push]
* @property {string} [replace]
* @property {string} [selectOOB]
*/ */
/** /**

40
dist/htmx.js vendored
View File

@@ -280,7 +280,7 @@ var htmx = (function() {
*/ */
historyRestoreAsHxRequest: true, historyRestoreAsHxRequest: true,
/** /**
* Weather to report input validation errors to the end user and update focus to the first input that fails validation. * Whether to report input validation errors to the end user and update focus to the first input that fails validation.
* This should always be enabled as this matches default browser form submit behaviour * This should always be enabled as this matches default browser form submit behaviour
* @type boolean * @type boolean
* @default false * @default false
@@ -296,7 +296,7 @@ var htmx = (function() {
location, location,
/** @type {typeof internalEval} */ /** @type {typeof internalEval} */
_: null, _: null,
version: '2.0.7' version: '2.0.8'
} }
// Tsc madness part 2 // Tsc madness part 2
htmx.onLoad = onLoadHelper htmx.onLoad = onLoadHelper
@@ -525,6 +525,9 @@ var htmx = (function() {
* @returns {Document} * @returns {Document}
*/ */
function parseHTML(resp) { function parseHTML(resp) {
if ('parseHTMLUnsafe' in Document) {
return Document.parseHTMLUnsafe(resp)
}
const parser = new DOMParser() const parser = new DOMParser()
return parser.parseFromString(resp, 'text/html') return parser.parseFromString(resp, 'text/html')
} }
@@ -3126,7 +3129,7 @@ var htmx = (function() {
//= =================================================================== //= ===================================================================
// History Support // History Support
//= =================================================================== //= ===================================================================
let currentPathForHistory = location.pathname + location.search let currentPathForHistory
/** /**
* @param {string} path * @param {string} path
@@ -3138,6 +3141,8 @@ var htmx = (function() {
} }
} }
setCurrentPathForHistory(location.pathname + location.search)
/** /**
* @returns {Element} * @returns {Element}
*/ */
@@ -4073,7 +4078,10 @@ var htmx = (function() {
targetOverride: resolvedTarget, targetOverride: resolvedTarget,
swapOverride: context.swap, swapOverride: context.swap,
select: context.select, select: context.select,
returnPromise: true returnPromise: true,
push: context.push,
replace: context.replace,
selectOOB: context.selectOOB
}) })
} }
} else { } else {
@@ -4688,8 +4696,8 @@ var htmx = (function() {
const requestPath = responseInfo.pathInfo.finalRequestPath const requestPath = responseInfo.pathInfo.finalRequestPath
const responsePath = responseInfo.pathInfo.responsePath const responsePath = responseInfo.pathInfo.responsePath
const pushUrl = getClosestAttributeValue(elt, 'hx-push-url') const pushUrl = responseInfo.etc.push || getClosestAttributeValue(elt, 'hx-push-url')
const replaceUrl = getClosestAttributeValue(elt, 'hx-replace-url') const replaceUrl = responseInfo.etc.replace || getClosestAttributeValue(elt, 'hx-replace-url')
const elementIsBoosted = getInternalData(elt).boosted const elementIsBoosted = getInternalData(elt).boosted
let saveType = null let saveType = null
@@ -4808,19 +4816,17 @@ var htmx = (function() {
} }
if (hasHeader(xhr, /HX-Location:/i)) { if (hasHeader(xhr, /HX-Location:/i)) {
saveCurrentPageToHistory()
let redirectPath = xhr.getResponseHeader('HX-Location') let redirectPath = xhr.getResponseHeader('HX-Location')
/** @type {HtmxAjaxHelperContext&{path:string}} */ /** @type {HtmxAjaxHelperContext&{path?:string}} */
var redirectSwapSpec var redirectSwapSpec = {}
if (redirectPath.indexOf('{') === 0) { if (redirectPath.indexOf('{') === 0) {
redirectSwapSpec = parseJSON(redirectPath) redirectSwapSpec = parseJSON(redirectPath)
// what's the best way to throw an error if the user didn't include this // what's the best way to throw an error if the user didn't include this
redirectPath = redirectSwapSpec.path redirectPath = redirectSwapSpec.path
delete redirectSwapSpec.path delete redirectSwapSpec.path
} }
ajaxHelper('get', redirectPath, redirectSwapSpec).then(function() { redirectSwapSpec.push = redirectSwapSpec.push || 'true'
pushUrlIntoHistory(redirectPath) ajaxHelper('get', redirectPath, redirectSwapSpec)
})
return return
} }
@@ -4919,7 +4925,7 @@ var htmx = (function() {
selectOverride = xhr.getResponseHeader('HX-Reselect') selectOverride = xhr.getResponseHeader('HX-Reselect')
} }
const selectOOB = getClosestAttributeValue(elt, 'hx-select-oob') const selectOOB = etc.selectOOB || getClosestAttributeValue(elt, 'hx-select-oob')
const select = getClosestAttributeValue(elt, 'hx-select') const select = getClosestAttributeValue(elt, 'hx-select')
swap(target, serverResponse, swapSpec, { swap(target, serverResponse, swapSpec, {
@@ -5118,7 +5124,7 @@ var htmx = (function() {
"[hx-trigger='restored'],[data-hx-trigger='restored']" "[hx-trigger='restored'],[data-hx-trigger='restored']"
) )
body.addEventListener('htmx:abort', function(evt) { body.addEventListener('htmx:abort', function(evt) {
const target = evt.target const target = (/** @type {CustomEvent} */(evt)).detail.elt || evt.target
const internalData = getInternalData(target) const internalData = getInternalData(target)
if (internalData && internalData.xhr) { if (internalData && internalData.xhr) {
internalData.xhr.abort() internalData.xhr.abort()
@@ -5238,6 +5244,9 @@ var htmx = (function() {
* @property {Object|FormData} [values] * @property {Object|FormData} [values]
* @property {Record<string,string>} [headers] * @property {Record<string,string>} [headers]
* @property {string} [select] * @property {string} [select]
* @property {string} [push]
* @property {string} [replace]
* @property {string} [selectOOB]
*/ */
/** /**
@@ -5284,6 +5293,9 @@ var htmx = (function() {
* @property {Object|FormData} [values] * @property {Object|FormData} [values]
* @property {boolean} [credentials] * @property {boolean} [credentials]
* @property {number} [timeout] * @property {number} [timeout]
* @property {string} [push]
* @property {string} [replace]
* @property {string} [selectOOB]
*/ */
/** /**

2
dist/htmx.min.js vendored

File diff suppressed because one or more lines are too long

BIN
dist/htmx.min.js.gz vendored

Binary file not shown.

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "https://json.schemastore.org/web-types", "$schema": "https://json.schemastore.org/web-types",
"name": "htmx", "name": "htmx",
"version": "2.0.7", "version": "2.0.8",
"default-icon": "./htmx.svg", "default-icon": "./htmx.svg",
"js-types-syntax": "typescript", "js-types-syntax": "typescript",
"description-markup": "markdown", "description-markup": "markdown",

View File

@@ -5,7 +5,7 @@
"AJAX", "AJAX",
"HTML" "HTML"
], ],
"version": "2.0.7", "version": "2.0.8",
"homepage": "https://htmx.org/", "homepage": "https://htmx.org/",
"bugs": { "bugs": {
"url": "https://github.com/bigskysoftware/htmx/issues" "url": "https://github.com/bigskysoftware/htmx/issues"

View File

@@ -296,7 +296,7 @@ var htmx = (function() {
location, location,
/** @type {typeof internalEval} */ /** @type {typeof internalEval} */
_: null, _: null,
version: '2.0.7' version: '2.0.8'
} }
// Tsc madness part 2 // Tsc madness part 2
htmx.onLoad = onLoadHelper htmx.onLoad = onLoadHelper

View File

@@ -117,7 +117,7 @@ By removing these constraints, htmx completes HTML as a [hypertext](https://en.w
<h2>quick start</h2> <h2>quick start</h2>
```html ```html
<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.7/dist/htmx.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js"></script>
<!-- have a button POST a click via AJAX --> <!-- have a button POST a click via AJAX -->
<button hx-post="/clicked" hx-swap="outerHTML"> <button hx-post="/clicked" hx-swap="outerHTML">
Click Me Click Me

View File

@@ -123,13 +123,13 @@ The fastest way to get going with htmx is to load it via a CDN. You can simply a
your head tag and get going: your head tag and get going:
```html ```html
<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.7/dist/htmx.min.js" integrity="sha384-ZBXiYtYQ6hJ2Y0ZNoYuI+Nq5MqWBr+chMrS/RkXpNzQCApHEhOt2aY8EJgqwHLkJ" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js" integrity="sha384-ZBXiYtYQ6hJ2Y0ZNoYuI+Nq5MqWBr+chMrS/RkXpNzQCApHEhOt2aY8EJgqwHLkJ" crossorigin="anonymous"></script>
``` ```
An unminified version is also available as well: An unminified version is also available as well:
```html ```html
<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.7/dist/htmx.js" integrity="sha384-yWakaGAFicqusuwOYEmoRjLNOC+6OFsdmwC2lbGQaRELtuVEqNzt11c2J711DeCZ" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.js" integrity="sha384-yWakaGAFicqusuwOYEmoRjLNOC+6OFsdmwC2lbGQaRELtuVEqNzt11c2J711DeCZ" crossorigin="anonymous"></script>
``` ```
While the CDN approach is extremely simple, you may want to consider While the CDN approach is extremely simple, you may want to consider
@@ -139,7 +139,7 @@ While the CDN approach is extremely simple, you may want to consider
The next easiest way to install htmx is to simply copy it into your project. The next easiest way to install htmx is to simply copy it into your project.
Download `htmx.min.js` [from jsDelivr](https://cdn.jsdelivr.net/npm/htmx.org@2.0.7/dist/htmx.min.js) and add it to the appropriate directory in your project Download `htmx.min.js` [from jsDelivr](https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js) and add it to the appropriate directory in your project
and include it where necessary with a `<script>` tag: and include it where necessary with a `<script>` tag:
```html ```html
@@ -151,7 +151,7 @@ and include it where necessary with a `<script>` tag:
For npm-style build systems, you can install htmx via [npm](https://www.npmjs.com/): For npm-style build systems, you can install htmx via [npm](https://www.npmjs.com/):
```sh ```sh
npm install htmx.org@2.0.7 npm install htmx.org@2.0.8
``` ```
After installing, youll need to use appropriate tooling to use `node_modules/htmx.org/dist/htmx.js` (or `.min.js`). After installing, youll need to use appropriate tooling to use `node_modules/htmx.org/dist/htmx.js` (or `.min.js`).
@@ -1142,7 +1142,7 @@ You can see all available extensions on the [Extensions](/extensions) page.
The fastest way to install htmx extensions created by others is to load them via a CDN. Remember to always include the core htmx library before the extensions and [enable the extension](#enabling-extensions). For example, if you would like to use the [response-targets](/extensions/response-targets) extension, you can add this to your head tag: The fastest way to install htmx extensions created by others is to load them via a CDN. Remember to always include the core htmx library before the extensions and [enable the extension](#enabling-extensions). For example, if you would like to use the [response-targets](/extensions/response-targets) extension, you can add this to your head tag:
```HTML ```HTML
<head> <head>
<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.7/dist/htmx.min.js" integrity="sha384-ZBXiYtYQ6hJ2Y0ZNoYuI+Nq5MqWBr+chMrS/RkXpNzQCApHEhOt2aY8EJgqwHLkJ" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js" integrity="sha384-ZBXiYtYQ6hJ2Y0ZNoYuI+Nq5MqWBr+chMrS/RkXpNzQCApHEhOt2aY8EJgqwHLkJ" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/htmx-ext-response-targets@2.0.4" integrity="sha384-T41oglUPvXLGBVyRdZsVRxNWnOOqCynaPubjUVjxhsjFTKrFJGEMm3/0KGmNQ+Pg" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/htmx-ext-response-targets@2.0.4" integrity="sha384-T41oglUPvXLGBVyRdZsVRxNWnOOqCynaPubjUVjxhsjFTKrFJGEMm3/0KGmNQ+Pg" crossorigin="anonymous"></script>
</head> </head>
<body hx-ext="extension-name"> <body hx-ext="extension-name">

View File

@@ -18,7 +18,7 @@ a feature of the library. This extension addresses that shortcoming.
The fastest way to install `head-support` is to load it via a CDN. Remember to always include the core htmx library before the extension and [enable the extension](#usage). The fastest way to install `head-support` is to load it via a CDN. Remember to always include the core htmx library before the extension and [enable the extension](#usage).
```HTML ```HTML
<head> <head>
<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.7/dist/htmx.min.js" integrity="sha384-ZBXiYtYQ6hJ2Y0ZNoYuI+Nq5MqWBr+chMrS/RkXpNzQCApHEhOt2aY8EJgqwHLkJ" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js" integrity="sha384-ZBXiYtYQ6hJ2Y0ZNoYuI+Nq5MqWBr+chMrS/RkXpNzQCApHEhOt2aY8EJgqwHLkJ" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/htmx-ext-head-support@2.0.5" integrity="sha384-cvMqHzjCJsOHgGuyB3sWXaUSv/Krm0BdzjuI1rtkjCbL1l1oHJx+cHyVRJhyuEz0" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/htmx-ext-head-support@2.0.5" integrity="sha384-cvMqHzjCJsOHgGuyB3sWXaUSv/Krm0BdzjuI1rtkjCbL1l1oHJx+cHyVRJhyuEz0" crossorigin="anonymous"></script>
</head> </head>
<body hx-ext="head-support"> <body hx-ext="head-support">

View File

@@ -9,7 +9,7 @@ The `htmx-1-compat` extension allows you to almost seamlessly upgrade from htmx
The fastest way to install `htmx-1-compat` is to load it via a CDN. Remember to always include the core htmx library before the extension and enable the extension. The fastest way to install `htmx-1-compat` is to load it via a CDN. Remember to always include the core htmx library before the extension and enable the extension.
```HTML ```HTML
<head> <head>
<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.7/dist/htmx.min.js" integrity="sha384-ZBXiYtYQ6hJ2Y0ZNoYuI+Nq5MqWBr+chMrS/RkXpNzQCApHEhOt2aY8EJgqwHLkJ" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js" integrity="sha384-ZBXiYtYQ6hJ2Y0ZNoYuI+Nq5MqWBr+chMrS/RkXpNzQCApHEhOt2aY8EJgqwHLkJ" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/htmx-ext-htmx-1-compat@2.0.2" integrity="sha384-lcvVWaNjF5zPPUeeWmC0OkJ2MLqoWLlkAabuGm+EuMSTfGo5WRyHrNaAp0cJr9Pg" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/htmx-ext-htmx-1-compat@2.0.2" integrity="sha384-lcvVWaNjF5zPPUeeWmC0OkJ2MLqoWLlkAabuGm+EuMSTfGo5WRyHrNaAp0cJr9Pg" crossorigin="anonymous"></script>
</head> </head>
<body hx-ext="htmx-1-compat"> <body hx-ext="htmx-1-compat">

View File

@@ -16,7 +16,7 @@ The fastest way to install `idiomorph` is to load it via a CDN. Remember to alwa
```HTML ```HTML
<head> <head>
<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.7/dist/htmx.min.js@2.0.7" integrity="sha384-ZBXiYtYQ6hJ2Y0ZNoYuI+Nq5MqWBr+chMrS/RkXpNzQCApHEhOt2aY8EJgqwHLkJ" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js@2.0.7" integrity="sha384-ZBXiYtYQ6hJ2Y0ZNoYuI+Nq5MqWBr+chMrS/RkXpNzQCApHEhOt2aY8EJgqwHLkJ" crossorigin="anonymous"></script>
<script src="https://unpkg.com/idiomorph@0.7.4/dist/idiomorph-ext.min.js" integrity="sha384-SsScJKzATF/w6suEEdLbgYGsYFLzeKfOA6PY+/C5ZPxOSuA+ARquqtz/BZz9JWU8" crossorigin="anonymous"></script> <script src="https://unpkg.com/idiomorph@0.7.4/dist/idiomorph-ext.min.js" integrity="sha384-SsScJKzATF/w6suEEdLbgYGsYFLzeKfOA6PY+/C5ZPxOSuA+ARquqtz/BZz9JWU8" crossorigin="anonymous"></script>
</head> </head>
<body hx-ext="morph"> <body hx-ext="morph">

View File

@@ -15,7 +15,7 @@ unused requests. Use this extension carefully!
The fastest way to install `preload` is to load it via a CDN. Remember to always include the core htmx library before the extension and [enable the extension](#usage). The fastest way to install `preload` is to load it via a CDN. Remember to always include the core htmx library before the extension and [enable the extension](#usage).
```HTML ```HTML
<head> <head>
<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.7/dist/htmx.min.js" integrity="sha384-ZBXiYtYQ6hJ2Y0ZNoYuI+Nq5MqWBr+chMrS/RkXpNzQCApHEhOt2aY8EJgqwHLkJ" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js" integrity="sha384-ZBXiYtYQ6hJ2Y0ZNoYuI+Nq5MqWBr+chMrS/RkXpNzQCApHEhOt2aY8EJgqwHLkJ" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/htmx-ext-preload@2.1.2" integrity="sha384-PRIcY6hH1Y5784C76/Y8SqLyTanY9rnI3B8F3+hKZFNED55hsEqMJyqWhp95lgfk" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/htmx-ext-preload@2.1.2" integrity="sha384-PRIcY6hH1Y5784C76/Y8SqLyTanY9rnI3B8F3+hKZFNED55hsEqMJyqWhp95lgfk" crossorigin="anonymous"></script>
</head> </head>
<body hx-ext="preload"> <body hx-ext="preload">

View File

@@ -27,7 +27,7 @@ The value of each attribute can be:
The fastest way to install `response-targets` is to load it via a CDN. Remember to always include the core htmx library before the extension and [enable the extension](#usage). The fastest way to install `response-targets` is to load it via a CDN. Remember to always include the core htmx library before the extension and [enable the extension](#usage).
```HTML ```HTML
<head> <head>
<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.7/dist/htmx.min.js" integrity="sha384-ZBXiYtYQ6hJ2Y0ZNoYuI+Nq5MqWBr+chMrS/RkXpNzQCApHEhOt2aY8EJgqwHLkJ" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js" integrity="sha384-ZBXiYtYQ6hJ2Y0ZNoYuI+Nq5MqWBr+chMrS/RkXpNzQCApHEhOt2aY8EJgqwHLkJ" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/htmx-ext-response-targets@2.0.4" integrity="sha384-T41oglUPvXLGBVyRdZsVRxNWnOOqCynaPubjUVjxhsjFTKrFJGEMm3/0KGmNQ+Pg" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/htmx-ext-response-targets@2.0.4" integrity="sha384-T41oglUPvXLGBVyRdZsVRxNWnOOqCynaPubjUVjxhsjFTKrFJGEMm3/0KGmNQ+Pg" crossorigin="anonymous"></script>
</head> </head>
<body hx-ext="response-targets"> <body hx-ext="response-targets">

View File

@@ -29,7 +29,7 @@ Use the following attributes to configure how SSE connections behave:
The fastest way to install `sse` is to load it via a CDN. Remember to always include the core htmx library before the extension and [enable the extension](#usage). The fastest way to install `sse` is to load it via a CDN. Remember to always include the core htmx library before the extension and [enable the extension](#usage).
```HTML ```HTML
<head> <head>
<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.7/dist/htmx.min.js" integrity="sha384-ZBXiYtYQ6hJ2Y0ZNoYuI+Nq5MqWBr+chMrS/RkXpNzQCApHEhOt2aY8EJgqwHLkJ" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js" integrity="sha384-ZBXiYtYQ6hJ2Y0ZNoYuI+Nq5MqWBr+chMrS/RkXpNzQCApHEhOt2aY8EJgqwHLkJ" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/htmx-ext-sse@2.2.4" integrity="sha384-A986SAtodyH8eg8x8irJnYUk7i9inVQqYigD6qZ9evobksGNIXfeFvDwLSHcp31N" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/htmx-ext-sse@2.2.4" integrity="sha384-A986SAtodyH8eg8x8irJnYUk7i9inVQqYigD6qZ9evobksGNIXfeFvDwLSHcp31N" crossorigin="anonymous"></script>
</head> </head>
<body hx-ext="sse"> <body hx-ext="sse">

View File

@@ -23,7 +23,7 @@ Use the following attributes to configure how WebSockets behave:
The fastest way to install `ws` is to load it via a CDN. Remember to always include the core htmx library before the extension and [enable the extension](#usage). The fastest way to install `ws` is to load it via a CDN. Remember to always include the core htmx library before the extension and [enable the extension](#usage).
```HTML ```HTML
<head> <head>
<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.7/dist/htmx.min.js" integrity="sha384-ZBXiYtYQ6hJ2Y0ZNoYuI+Nq5MqWBr+chMrS/RkXpNzQCApHEhOt2aY8EJgqwHLkJ" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.8/dist/htmx.min.js" integrity="sha384-ZBXiYtYQ6hJ2Y0ZNoYuI+Nq5MqWBr+chMrS/RkXpNzQCApHEhOt2aY8EJgqwHLkJ" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/htmx-ext-ws@2.0.4" integrity="sha384-1RwI/nvUSrMRuNj7hX1+27J8XDdCoSLf0EjEyF69nacuWyiJYoQ/j39RT1mSnd2G" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/htmx-ext-ws@2.0.4" integrity="sha384-1RwI/nvUSrMRuNj7hX1+27J8XDdCoSLf0EjEyF69nacuWyiJYoQ/j39RT1mSnd2G" crossorigin="anonymous"></script>
</head> </head>
<body hx-ext="ws"> <body hx-ext="ws">