mirror of
https://github.com/bigskysoftware/htmx.git
synced 2025-09-26 20:40:41 +00:00
Merge branch 'master' into dev
# Conflicts: # www/content/docs.md
This commit is contained in:
commit
ccdce87ec3
@ -10,7 +10,7 @@ This guide outlines how to test htmx, focusing on running tests headlessly or in
|
||||
npm install
|
||||
npm run test
|
||||
```
|
||||
During test runs it will auto install playwrite
|
||||
During test runs it will auto install playwright
|
||||
|
||||
## Running All Tests
|
||||
|
||||
|
@ -431,12 +431,12 @@
|
||||
},
|
||||
{
|
||||
"name": "historyCacheHit",
|
||||
"description": "This event is triggered when a cache hit occurs when restoring history\n\nYou can prevent the history restoration via `preventDefault()` to allow alternative restore handling.\nYou can also override the details of the history restoration request in this event if required\n\n##### Details\n\n* `detail.historyElt` - the history element or body that will get replaced\n* `detail.item.content` - the content of the cache that will be swapped in\n* `detail.item.title` - the page title to update from the cache\n* `detail.path` - the path and query of the page being restored\n* `detial.swapSpec` - the swapSpec to be used containing the defatul swapStyle='innerHTML'\n\n",
|
||||
"description": "This event is triggered when a cache hit occurs when restoring history\n\nYou can prevent the history restoration via `preventDefault()` to allow alternative restore handling.\nYou can also override the details of the history restoration request in this event if required\n\n##### Details\n\n* `detail.historyElt` - the history element or body that will get replaced\n* `detail.item.content` - the content of the cache that will be swapped in\n* `detail.item.title` - the page title to update from the cache\n* `detail.path` - the path and query of the page being restored\n* `detail.swapSpec` - the swapSpec to be used containing the defatul swapStyle='innerHTML'\n\n",
|
||||
"doc-url": "https://htmx.org/events/#htmx:historyCacheHit"
|
||||
},
|
||||
{
|
||||
"name": "historyCacheMiss",
|
||||
"description": "This event is triggered when a cache miss occurs when restoring history\n\nYou can prevent the history restoration via `preventDefault()` to allow alternative restore handling.\nYou can also modify the xhr request or other details before it makes the the request to restore history\n\n##### Details\n\n* `detail.historyElt` - the history element or body that will get replaced\n* `detail.xhr` - the `XMLHttpRequest` that will retrieve the remote content for restoration\n* `detail.path` - the path and query of the page being restored\n* `detial.swapSpec` - the swapSpec to be used containing the defatul swapStyle='innerHTML'\n\n",
|
||||
"description": "This event is triggered when a cache miss occurs when restoring history\n\nYou can prevent the history restoration via `preventDefault()` to allow alternative restore handling.\nYou can also modify the xhr request or other details before it makes the the request to restore history\n\n##### Details\n\n* `detail.historyElt` - the history element or body that will get replaced\n* `detail.xhr` - the `XMLHttpRequest` that will retrieve the remote content for restoration\n* `detail.path` - the path and query of the page being restored\n* `detail.swapSpec` - the swapSpec to be used containing the defatul swapStyle='innerHTML'\n\n",
|
||||
"doc-url": "https://htmx.org/events/#htmx:historyCacheMiss"
|
||||
},
|
||||
{
|
||||
@ -446,7 +446,7 @@
|
||||
},
|
||||
{
|
||||
"name": "historyCacheMissLoad",
|
||||
"description": "This event is triggered when a cache miss occurs and a response has been retrieved successfully from the server\nfor the content to restore\n\nYou can modify the details before it makes the swap to restore the history\n\n##### Details\n\n* `detail.historyElt` - the history element or body that will get replaced\n* `detail.xhr` - the `XMLHttpRequest`\n* `detail.path` - the path and query of the page being restored\n* `detail.response` - the response text that will be swapped in\n* `detial.swapSpec` - the swapSpec to be used containing the defatul swapStyle='innerHTML'\n\n",
|
||||
"description": "This event is triggered when a cache miss occurs and a response has been retrieved successfully from the server\nfor the content to restore\n\nYou can modify the details before it makes the swap to restore the history\n\n##### Details\n\n* `detail.historyElt` - the history element or body that will get replaced\n* `detail.xhr` - the `XMLHttpRequest`\n* `detail.path` - the path and query of the page being restored\n* `detail.response` - the response text that will be swapped in\n* `detail.swapSpec` - the swapSpec to be used containing the defatul swapStyle='innerHTML'\n\n",
|
||||
"doc-url": "https://htmx.org/events/#htmx:historyCacheMissLoad"
|
||||
},
|
||||
{
|
||||
|
@ -349,7 +349,7 @@ describe('hx-swap-oob attribute', function() {
|
||||
}
|
||||
|
||||
it.skip('triggers htmx:oobErrorNoTarget when no targets found', function(done) {
|
||||
// this test fails right now because when targets not found it returns an empty array which makes it miss the event as it should be if (targets.lenght)
|
||||
// this test fails right now because when targets not found it returns an empty array which makes it miss the event as it should be if (targets.length)
|
||||
this.server.respondWith('GET', '/test', "Clicked<div id='nonexistent' hx-swap-oob='true'>Swapped</div>")
|
||||
var div = make('<div hx-get="/test">click me</div>')
|
||||
|
||||
|
@ -176,6 +176,17 @@ that "If something magically works, then it can also magically break."
|
||||
Despite this fact, I (Carson) still feel it is useful in many situations, and it is used on the <https://htmx.org>
|
||||
website.
|
||||
|
||||
## Loading htmx asynchronously is unreliable
|
||||
|
||||
htmx is designed to be loaded with a standard, blocking `<script>` tag, not one that is a [module](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/script#module) or [deferred](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/script#defer).
|
||||
Although we make a [best-effort attempt](https://github.com/bigskysoftware/htmx/blob/7ae66f9b33a5d39ad4084b0697ea34a6bf559cda/src/htmx.js#L5039-L5058) to initialize htmx regardless of when in the document lifecycle the script is loaded, there are some use-cases that slip through the cracks, typically ones that involve bundling or AJAX insertion of htmx itself.
|
||||
|
||||
Our [past attempts](https://github.com/bigskysoftware/htmx/pull/3365#issuecomment-3065080028) to close this gap have all lead to unacceptable regressions.
|
||||
Therefore, although htmx can be loaded asynchronously, do so at your own risk.
|
||||
|
||||
Keep in mind, also, that if your DOM content loads before htmx does, all the htmx-provided functionality will be nonfunctional until htmx loads.
|
||||
[Prefetching](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/rel/prefetch) (or even "regular" fetching) htmx before you need it is one possible way to resolve this problem.
|
||||
|
||||
## The JavaScript API Is Not A Focus
|
||||
|
||||
htmx is a hypermedia-oriented front end library. This means that htmx enhances HTML via
|
||||
|
@ -258,7 +258,7 @@ Thank you to all our generous <a href="https://github.com/sponsors/bigskysoftwar
|
||||
<div>
|
||||
<a data-github-account="tracebit-com" href="https://tracebit.com/?utm_source=htmx">
|
||||
<img class="dark-hidden" alt="Tracebit Cloud Canaries" src="/img/tracebit-logo.png">
|
||||
<img class="dark-visbile" alt="Tracebit Cloud Canaries" src="/img/tracebit-logo-dark.png">
|
||||
<img class="dark-visible" alt="Tracebit Cloud Canaries" src="/img/tracebit-logo-dark.png">
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
@ -334,6 +334,13 @@ Thank you to all our generous <a href="https://github.com/sponsors/bigskysoftwar
|
||||
<img class="dark-visible" src="/img/edubirdie-dark.png" style="width:100%;max-width:250px">
|
||||
</a>
|
||||
</div>
|
||||
<div></div>
|
||||
<div>
|
||||
<a data-github-account="TrackityApp" alt="Trackity server side tracking" href="https://www.trackity.com">
|
||||
<img class="dark-hidden" src="/img/trackity-light.png" style="width:100%;max-width:250px">
|
||||
<img class="dark-visible" src="/img/trackity-dark.png" style="width:100%;max-width:250px">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="text-align: center;font-style: italic;margin-top: 26px;">ʕ •ᴥ•ʔ made in montana</div>
|
||||
|
@ -1699,6 +1699,8 @@ for exploring this topic.
|
||||
|
||||
The assignment and checking of CSRF tokens are typically backend responsibilities, but `htmx` can support returning the CSRF token automatically with every request using the `hx-headers` attribute. The attribute needs to be added to the element issuing the request or one of its ancestor elements. This makes the `html` and `body` elements effective global vehicles for adding the CSRF token to the `HTTP` request header, as illustrated below.
|
||||
|
||||
Note: `hx-boost` does not not update the `<html>` or `<body>` tags; if using this feature with `hx-boost`, make sure to include the CSRF token on an element that _will_ get replaced. Many web frameworks support automatically inserting the CSRF token as a hidden input in HTML forms. This is encouraged whenever possible.
|
||||
|
||||
```html
|
||||
<html lang="en" hx-headers='{"X-CSRF-TOKEN": "CSRF_TOKEN_INSERTED_HERE"}'>
|
||||
:
|
||||
|
@ -142,6 +142,7 @@ Here are some known implementations of the fragment concept:
|
||||
|
||||
* Go
|
||||
* [Standard Library (use block actions)](https://pkg.go.dev/text/template) [[demo]](https://gist.github.com/benpate/f92b77ea9b3a8503541eb4b9eb515d8a)
|
||||
* [templ](https://templ.guide) [[Fragment documentation]](https://templ.guide/syntax-and-usage/fragments) [[repo]](https://github.com/a-h/templ)
|
||||
* Java
|
||||
* [Thymeleaf](https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#fragment-specification-syntax)
|
||||
* [Chill Templates (currently in early alpha)](https://github.com/bigskysoftware/chill/tree/master/chill-script)
|
||||
|
@ -275,7 +275,7 @@ You can also override the details of the history restoration request in this eve
|
||||
* `detail.item.content` - the content of the cache that will be swapped in
|
||||
* `detail.item.title` - the page title to update from the cache
|
||||
* `detail.path` - the path and query of the page being restored
|
||||
* `detial.swapSpec` - the swapSpec to be used containing the defatul swapStyle='innerHTML'
|
||||
* `detail.swapSpec` - the swapSpec to be used containing the defatul swapStyle='innerHTML'
|
||||
|
||||
### Event - `htmx:historyCacheMiss` {#htmx:historyCacheMiss}
|
||||
|
||||
@ -289,7 +289,7 @@ You can also modify the xhr request or other details before it makes the the req
|
||||
* `detail.historyElt` - the history element or body that will get replaced
|
||||
* `detail.xhr` - the `XMLHttpRequest` that will retrieve the remote content for restoration
|
||||
* `detail.path` - the path and query of the page being restored
|
||||
* `detial.swapSpec` - the swapSpec to be used containing the defatul swapStyle='innerHTML'
|
||||
* `detail.swapSpec` - the swapSpec to be used containing the defatul swapStyle='innerHTML'
|
||||
|
||||
### Event - `htmx:historyCacheMissLoadError` {#htmx:historyCacheMissLoadError}
|
||||
|
||||
@ -314,7 +314,7 @@ You can modify the details before it makes the swap to restore the history
|
||||
* `detail.xhr` - the `XMLHttpRequest`
|
||||
* `detail.path` - the path and query of the page being restored
|
||||
* `detail.response` - the response text that will be swapped in
|
||||
* `detial.swapSpec` - the swapSpec to be used containing the defatul swapStyle='innerHTML'
|
||||
* `detail.swapSpec` - the swapSpec to be used containing the defatul swapStyle='innerHTML'
|
||||
|
||||
### Event - `htmx:historyRestore` {#htmx:historyRestore}
|
||||
|
||||
|
@ -34,7 +34,7 @@ The click to edit pattern provides a way to offer inline editing of all or part
|
||||
<label>Email Address</label>
|
||||
<input type="email" name="email" value="joe@blow.com">
|
||||
</div>
|
||||
<button class="btn">Submit</button>
|
||||
<button class="btn" type="submit">Submit</button>
|
||||
<button class="btn" hx-get="/contact/1">Cancel</button>
|
||||
</form>
|
||||
```
|
||||
|
@ -132,8 +132,6 @@ example.
|
||||
}
|
||||
```
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/htmx.org"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/hyperscript.org"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
//=========================================================================
|
||||
|
@ -89,7 +89,6 @@ window.document.getElementById("cancelButton").addEventListener("click", functio
|
||||
@import "https://cdnjs.cloudflare.com/ajax/libs/uikit/3.5.9/css/uikit-core.min.css";
|
||||
</style>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/hyperscript.org"></script>
|
||||
<script>
|
||||
//=========================================================================
|
||||
// Fake Server Side Code
|
||||
|
@ -49,7 +49,6 @@ when the content is swapped into the DOM.
|
||||
|
||||
<div id="tab-contents" role="tabpanel" hx-get="/tab1" hx-trigger="load"></div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/hyperscript.org"></script>
|
||||
<script>
|
||||
onGet("/tab1", function() {
|
||||
return `
|
||||
|
@ -116,7 +116,7 @@ htmx extensions are split into two categories:
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% markdown() %} [restored](https://github.com/bigskysoftware/htmx-extensions/blob/main/src/restored/README.md) {% end %}</td>
|
||||
<td>{% markdown() %} Triggers an event whenever a back button even is detected while using `hx-boost` {% end %}</td>
|
||||
<td>{% markdown() %} Triggers an event whenever a back button event is detected while using `hx-boost` {% end %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% markdown() %} [safe-nonce](https://github.com/MichaelWest22/htmx-extensions/blob/main/src/safe-nonce/README.md) {% end %}</td>
|
||||
@ -149,6 +149,10 @@ htmx extensions are split into two categories:
|
||||
<td>{% markdown() %} [json-enc-custom](https://github.com/Emtyloc/json-enc-custom/blob/main/README.md) {% end %}</td>
|
||||
<td>{% markdown() %} This extension works similarly to json-enc but allows for very complex structures, such as embedding JSON objects, lists, or handling indexes, just by using the name attribute. {% end %}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% markdown() %} [htmx-json](https://github.com/mariusGundersen/htmx-json) {% end %}</td>
|
||||
<td>{% markdown() %} Support JSON response by transforming the html directly. This is a slightly different appreach than client-side-templates. {% end %}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody>
|
||||
<tr><th scope="rowgroup" colspan="2">Integrations</th></tr>
|
||||
|
@ -138,6 +138,7 @@ These examples may make it a bit easier to get started using htmx with your plat
|
||||
## Rust
|
||||
|
||||
- <https://github.com/paultuckey/example-todo-app-rust-htmx>
|
||||
- <https://github.com/welshdave/actix-htmx>
|
||||
|
||||
## Scala
|
||||
|
||||
|
@ -107,10 +107,14 @@ title = "htmx webring"
|
||||
<tr><td><a rel="nofollow" target="_blank" href="https://xrss.infogulch.com">XRSS</a></td><td>A simple RSS reader inspired by Google Reader</td></tr>
|
||||
<tr><td><a rel="nofollow" target="_blank" href="https://openunited.com/">OpenUnited</a></td><td>A Digital Talent match-making platform</td></tr>
|
||||
<tr><td><a rel="nofollow" target="_blank" href="https://gophemeral.com">Gophemeral</a></td><td>Share secrets securely!</td></tr>
|
||||
<tr><td><a rel="nofollow" target="_blank" href="https://www.thomasricci.dev">thomasricci.dev</a></td><td>Super fast portfolio website</td></tr>
|
||||
<tr><td><a rel="nofollow" target="_blank" href="https://signup.casa">Signup Casa</a></td><td>Simple, convenient sign-up forms.</td></tr>
|
||||
<tr><td><a rel="nofollow" target="_blank" href="https://recipes.musicavis.ca">Recipya</a></td><td>A clean, simple and powerful recipe manager your whole family can enjoy.</td></tr>
|
||||
<tr><td><a rel="noopener" target="_blank" href="https://statusnook.com">Statusnook</a></td><td>Effortlessly deploy a status page and start monitoring endpoints in minutes.</td></tr>
|
||||
<tr><td><a rel="noopener" target="_blank" href="https://photoquest.wedding/ ">PhotoQuest</a></td><td>The interactive wedding photo game for unique moments that connect.</td></tr>
|
||||
<tr><td><a rel="noopener" target="_blank" href="https://todo.dankstuff.net/">DankTodo</a></td><td>The First Ever HTMX C (Ulfius) Todo App in History!</td></tr>
|
||||
<tr><td><a rel="noopener" target="_blank" href="https://dankmuzikk.com/">DankMuzikk</a></td><td>Create, share and play music playlists with the fully hypermedia music player.</td></tr>
|
||||
<tr><td><a rel="noopener" target="_blank" href="https://danklyrics.com/">DankLyrics</a></td><td>A lyrics finder API, Website and Go package.</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
BIN
www/static/img/trackity-dark.png
Normal file
BIN
www/static/img/trackity-dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
www/static/img/trackity-light.png
Normal file
BIN
www/static/img/trackity-light.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
@ -349,7 +349,7 @@ describe('hx-swap-oob attribute', function() {
|
||||
}
|
||||
|
||||
it.skip('triggers htmx:oobErrorNoTarget when no targets found', function(done) {
|
||||
// this test fails right now because when targets not found it returns an empty array which makes it miss the event as it should be if (targets.lenght)
|
||||
// this test fails right now because when targets not found it returns an empty array which makes it miss the event as it should be if (targets.length)
|
||||
this.server.respondWith('GET', '/test', "Clicked<div id='nonexistent' hx-swap-oob='true'>Swapped</div>")
|
||||
var div = make('<div hx-get="/test">click me</div>')
|
||||
|
||||
|
@ -402,7 +402,7 @@ tbody > tr > th[scope="rowgroup"] {
|
||||
padding: 1em;
|
||||
letter-spacing: .1em;
|
||||
text-transform: uppercase;
|
||||
background: white;
|
||||
background: Canvas;
|
||||
border: solid;
|
||||
cursor:pointer;
|
||||
border-radius: 8px;
|
||||
|
@ -51,7 +51,7 @@
|
||||
<div><a href="/essays/">essays</a></div>
|
||||
<div hx-disable>
|
||||
<form action="https://google.com/search" role="search" aria-label="Sitewide">
|
||||
<input type="hidden" name="q" value="site:htmx.org">
|
||||
<input type="hidden" name="q" value="+[inurl:https://htmx.org]">
|
||||
<label>
|
||||
<span style="display:none;">Search</span>
|
||||
<input type="text" name="q" placeholder="🔍️" class="search-box">
|
||||
|
Loading…
x
Reference in New Issue
Block a user