mirror of
https://github.com/bigskysoftware/htmx.git
synced 2025-09-27 04:50:43 +00:00
docs + config of head handling
This commit is contained in:
parent
5cdd50ebbe
commit
8b59cb9383
36
src/htmx.js
36
src/htmx.js
@ -61,7 +61,7 @@ var htmx = (function() {
|
||||
disableInheritance: false,
|
||||
head : {
|
||||
boost : "merge",
|
||||
other: "title",
|
||||
other: "none",
|
||||
},
|
||||
responseHandling: [
|
||||
{ code: '204', swap: false },
|
||||
@ -1143,17 +1143,12 @@ var htmx = (function() {
|
||||
}
|
||||
}
|
||||
|
||||
function handleHeadTag(head, defaultStrategy) {
|
||||
|
||||
if (head && htmx.config.head) {
|
||||
|
||||
if (defaultStrategy === "none") {
|
||||
return
|
||||
}
|
||||
function handleHeadTag(head, strategy) {
|
||||
|
||||
if (head && (strategy === "merge" || strategy === "append")) {
|
||||
// allow new head to override merge strategy
|
||||
let elementMergeStrategy = getAttributeValue(head, "hx-head") || defaultStrategy;
|
||||
if (elementMergeStrategy === "append" || elementMergeStrategy === "merge") {
|
||||
let elementMergeStrategy = getAttributeValue(head, "hx-head") || strategy;
|
||||
if (elementMergeStrategy === "merge" || elementMergeStrategy === "append") {
|
||||
let removed = []
|
||||
let appended = []
|
||||
|
||||
@ -2216,7 +2211,7 @@ var htmx = (function() {
|
||||
const historyElement = getHistoryElement()
|
||||
const settleInfo = makeSettleInfo(historyElement)
|
||||
handleTitle(fragment.title);
|
||||
handleHeadTag(fragment.head, "merge");
|
||||
handleHeadTag(fragment.head, htmx.config.head.boost);
|
||||
|
||||
// @ts-ignore
|
||||
swapInnerHTML(historyElement, content, settleInfo)
|
||||
@ -2239,7 +2234,7 @@ var htmx = (function() {
|
||||
const historyElement = getHistoryElement()
|
||||
const settleInfo = makeSettleInfo(historyElement)
|
||||
handleTitle(fragment.title);
|
||||
handleHeadTag(fragment.head, "merge");
|
||||
handleHeadTag(fragment.head, htmx.config.head.boost);
|
||||
swapInnerHTML(historyElement, fragment, settleInfo)
|
||||
settleImmediately(settleInfo.tasks);
|
||||
setTimeout(function() {
|
||||
@ -2586,6 +2581,8 @@ var htmx = (function() {
|
||||
swapSpec.transition = value.substr(11) === 'true'
|
||||
} else if (value.indexOf('ignoreTitle:') === 0) {
|
||||
swapSpec.ignoreTitle = value.substr(12) === 'true'
|
||||
} else if (value.indexOf('head:') === 0) {
|
||||
swapSpec.head = value.substr(5)
|
||||
} else if (value.indexOf('scroll:') === 0) {
|
||||
const scrollSpec = value.substr(7)
|
||||
var splitSpec = scrollSpec.split(':')
|
||||
@ -3381,6 +3378,7 @@ var htmx = (function() {
|
||||
const shouldSwap = responseHandling.swap
|
||||
let isError = !!responseHandling.error
|
||||
let ignoreTitle = htmx.config.ignoreTitle || responseHandling.ignoreTitle
|
||||
let head = responseInfo.boosted ? htmx.config.head.boost : htmx.config.head.other
|
||||
let selectOverride = responseHandling.select
|
||||
if (responseHandling.target) {
|
||||
responseInfo.target = querySelectorExt(elt, responseHandling.target)
|
||||
@ -3408,7 +3406,8 @@ var htmx = (function() {
|
||||
serverResponse,
|
||||
isError,
|
||||
ignoreTitle,
|
||||
selectOverride
|
||||
selectOverride,
|
||||
head
|
||||
}, responseInfo)
|
||||
|
||||
if (responseHandling.event && !triggerEvent(target, responseHandling.event, beforeSwapDetails)) return
|
||||
@ -3419,6 +3418,7 @@ var htmx = (function() {
|
||||
serverResponse = beforeSwapDetails.serverResponse // allow updating content
|
||||
isError = beforeSwapDetails.isError // allow updating error
|
||||
ignoreTitle = beforeSwapDetails.ignoreTitle // allow updating ignoring title
|
||||
head = beforeSwapDetails.head // allow updating head algorithm
|
||||
selectOverride = beforeSwapDetails.selectOverride // allow updating select override
|
||||
|
||||
responseInfo.target = target // Make updated target available to response events
|
||||
@ -3447,6 +3447,9 @@ var htmx = (function() {
|
||||
if (swapSpec.hasOwnProperty('ignoreTitle')) {
|
||||
ignoreTitle = swapSpec.ignoreTitle
|
||||
}
|
||||
if (swapSpec.hasOwnProperty('head')) {
|
||||
head = swapSpec.head
|
||||
}
|
||||
|
||||
target.classList.add(htmx.config.swappingClass)
|
||||
|
||||
@ -3524,10 +3527,10 @@ var htmx = (function() {
|
||||
handleTitle(settleInfo.title);
|
||||
}
|
||||
|
||||
console.log("Here", head)
|
||||
// merge in new head after swap but before settle
|
||||
if (triggerEvent(document.body, "htmx:beforeHeadMerge", {head: settleInfo.head})) {
|
||||
handleHeadTag(settleInfo.head, responseInfo.boosted ? htmx.config.head.boost :
|
||||
htmx.config.head.other);
|
||||
handleHeadTag(settleInfo.head, head);
|
||||
}
|
||||
|
||||
if (hasHeader(xhr, /HX-Trigger-After-Swap:/i)) {
|
||||
@ -3642,8 +3645,9 @@ var htmx = (function() {
|
||||
* @param {import("./htmx").HtmxExtension} extension
|
||||
*/
|
||||
function defineExtension(name, extension) {
|
||||
if (name === "head-support") return; // ignore the head support extension, now integrated into htmx
|
||||
if (extension.init) {
|
||||
extension.init(internalAPI)
|
||||
extension.init(internalAPI);
|
||||
}
|
||||
extensions[name] = mergeObjects(extensionBase(), extension)
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
<meta http-equiv="expires" content="0" />
|
||||
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
|
||||
<meta http-equiv="pragma" content="no-cache" />
|
||||
<meta name="htmx-config" content='{"historyEnabled":false,"defaultSettleDelay":0,"head":false}'>
|
||||
<meta name="htmx-config" content='{"historyEnabled":false,"defaultSettleDelay":0,"head":{"boost":"none","other":"none"}}'>
|
||||
</head>
|
||||
<body style="padding:20px;font-family: sans-serif">
|
||||
|
||||
|
@ -39,6 +39,15 @@ If you want to use the new [View Transitions](https://developer.mozilla.org/en-U
|
||||
when a swap occurs, you can use the `transition:true` option for your swap. You can also enable this feature globally by
|
||||
setting the `htmx.config.globalViewTransitions` config setting to `true`.
|
||||
|
||||
#### `head` tag handling: `head`
|
||||
|
||||
If you want to modify how a `head` tag found in the new content is handled, you can use the `head` modifier, with one
|
||||
of the following values:
|
||||
|
||||
* `merge` - merge the new head tag elements into the existing element
|
||||
* `append` - append the new head tag elements to the existing head tag
|
||||
* `none` - ignore any new head tag elements
|
||||
|
||||
#### Timing: `swap` & `settle`
|
||||
|
||||
You can modify the amount of time that htmx will wait after receiving a response to swap the content
|
||||
|
@ -29,6 +29,7 @@ custom_classes = "wide-content"
|
||||
* [confirming](#confirming)
|
||||
* [inheritance](#inheritance)
|
||||
* [boosting](#boosting)
|
||||
* [head tag handling](#head)
|
||||
* [websockets & SSE](#websockets-and-sse)
|
||||
* [history](#history)
|
||||
* [requests & responses](#requests)
|
||||
@ -182,10 +183,6 @@ To upgrade to htmx 2.0 from htmx 1.0, you will need to do the following:
|
||||
`htmx.config.methodsThatUseUrlParams` to `["get"]` (it's a little crazy, but `DELETE`, according to the spec, should
|
||||
use request parameters.)
|
||||
* If you want to make cross-domain requests with htmx, revert `htmx.config.selfRequestsOnly` to `false`
|
||||
* If you want to revert these to the htmx 1.x defaults, you can use the following meta tag:
|
||||
```html
|
||||
<meta name="htmx-config" content='{"scrollBehavior":"smooth", "methodsThatUseUrlParams":["get"], "selfRequestsOnly": false}'>
|
||||
```
|
||||
* Convert any `hx-on` attributes to their `hx-on:` equivalent:
|
||||
```html
|
||||
<button hx-get="/info" hx-on="htmx:beforeRequest: alert('Making a request!')
|
||||
@ -202,6 +199,9 @@ To upgrade to htmx 2.0 from htmx 1.0, you will need to do the following:
|
||||
Note that you must use the kebab-case of the event name due to the fact that attributes are case-insensitive in HTML.
|
||||
```
|
||||
* The `htmx.makeFragment()` method now **always** returns a `DocumentFragment` rather than either an `Element` or `DocumentFragment`
|
||||
* If you are using htmx in a module setting, we now provide module-type specific files for all three of the major
|
||||
JavaScript module types: `/dist/htmx.esm.js`, `/dist/htmx.umd.js` & `/dist/htmx.amd.js`
|
||||
* htmx 2.0 offers [automatic head merging](#head-support) with boosted links. If you do not want this behavior, set you can set `htmx.config.head.boosted` to `"none"`
|
||||
|
||||
IE is no longer supported in htmx 2.0, but htmx 1.x continues to support IE and will be supported for the foreseeable
|
||||
future.
|
||||
@ -779,6 +779,46 @@ Here is an example:
|
||||
|
||||
The anchor tag in this div will issue an AJAX `GET` request to `/blog` and swap the response into the `body` tag.
|
||||
|
||||
### `head` tag support
|
||||
|
||||
In boosted requests, if a head tag is detected in the response, htmx will automatically synchronize the content of
|
||||
the current head tag with the new content. This means that elements that are already found in the current head will
|
||||
be left alone (and, therefore, not trigger another request), but new elements found in the new header will be added
|
||||
to the existing header tag. Elements that are not found in the new head will be removed from the existing head tag.
|
||||
|
||||
This allows you to include page-specific header related elements and have them added or removed via boosted requests.
|
||||
|
||||
htmx also supports an "append" mode, that will simply append the content of the new head tag to the current head, if
|
||||
the new content is not already in it. You can control the mode that htmx will use with the `hx-head` attribute on
|
||||
the head tag in the *new* content:
|
||||
|
||||
* `merge` - follow the merging algorithm outlined above
|
||||
* `append` - append elements that do not exist in it to the existing head, but don't remove any elements
|
||||
|
||||
#### Controlling Merge Behavior Per Element
|
||||
|
||||
You may also control merging behavior of individual elements with the following attributes:
|
||||
|
||||
* If you place `hx-head="re-eval"` on a head element, it will be re-added (removed and appended) to the head tag on every
|
||||
request, even if it already exists. This can be useful to execute a script on every htmx request, for example.
|
||||
* If you place `hx-preserve="true"` on an element, it will never be removed from the head, regardless
|
||||
|
||||
#### Configuring Boost & Non-Boost `head` behavior
|
||||
|
||||
You can configure the default head behavior by setting the `boost` and `other` attributes in the `htmx.config.head` object,
|
||||
using the following values:
|
||||
|
||||
* `merge` - merge the new head tag elements into the existing element
|
||||
* `append` - append the new head tag elements to the existing head tag
|
||||
* `none` - ignore any new head tag elements
|
||||
|
||||
By default, `htmx.config.head.boost` is `merge` and will apply to boosted links and forms.
|
||||
|
||||
`htmx.config.head.other` will apply to non-boosted requests, and defaults to `none` (that is, new head information) will
|
||||
be ignored.
|
||||
|
||||
You can also configure the head behavior using the [`hx-swap`](/attributes/hx-swap) attribute's `head` option.
|
||||
|
||||
### Progressive Enhancement {#progressive_enhancement}
|
||||
|
||||
A feature of `hx-boost` is that it degrades gracefully if javascript is not enabled: the links and forms continue
|
||||
|
Loading…
x
Reference in New Issue
Block a user