Skip to content

Commit

Permalink
Link to main website/repo docs in each core extension's README
Browse files Browse the repository at this point in the history
  • Loading branch information
Telroshan committed Oct 6, 2024
1 parent d414a54 commit ef1c12e
Show file tree
Hide file tree
Showing 6 changed files with 6 additions and 809 deletions.
110 changes: 1 addition & 109 deletions src/head-support/README.md
Original file line number Diff line number Diff line change
@@ -1,109 +1 @@

The `head-support` extension adds support for [head tags](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/head)
in responses to htmx requests.

htmx began as a library focused on _partial replacement_ of HTML within the `body` tag. As such, merging additional
information such as the head tag was not a focus of the library. (This is in contrast with, for example, TurboLinks,
which was focused on merging entire web pages retrieved via AJAX into the browser.)

The [`hx-boost`](@/attributes/hx-boost.md) attribute moved htmx closer to this world of full HTML-document support &
support for extracting the `title` tag out of head elements was eventually added, but full head tag support has never been
a feature of the library. This extension addresses that shortcoming.

## Install

```html
<script src="https://unpkg.com/htmx-ext-head-support@2.0.1/head-support.js"></script>
```

## Usage

```html
<body hx-ext="head-support">
...
```

With this installed, all responses that htmx receives that contain a `head` tag in them (even if they are not complete
HTML documents with a root `<html>` element) will be processed.

How the head tag is handled depends on the type of htmx request.

If the htmx request is from a boosted element, then the following merge algorithm is used:

* Elements that exist in the current head as exact textual matches will be left in place
* Elements that do not exist in the current head will be added at the end of the head tag
* Elements that exist in the current head, but not in the new head will be removed from the head

If the htmx request is from a non-boosted element, then all content will be _appended_ to the existing head element.

If you wish to override this behavior in either case, you can place the `hx-head` attribute on the new `<head>` tag,
with either of the following two values:

* `merge` - follow the merging algorithm outlined above
* `append` - append the elements to the existing head

### Controlling Merge Behavior

Beyond this, 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

### Example

As an example, consider the following head tag in an existing document:

```html
<head>
<link rel="stylesheet" href="https://the.missing.style">
<link rel="stylesheet" href="/css/site1.css">
<script src="/js/script1.js"></script>
<script src="/js/script2.js"></script>
</head>
```

If htmx receives a request containing this new head tag:

```html
<head>
<link rel="stylesheet" href="https://the.missing.style">
<link rel="stylesheet" href="/css/site2.css">
<script src="/js/script2.js"></script>
<script src="/js/script3.js"></script>
</head>
```

Then the following operations will occur:

* `<link rel="stylesheet" href="https://the.missing.style">` will be left alone
* `<link rel="stylesheet" href="/css/site1.css">` will be removed from the head
* `<link rel="stylesheet" href="/css/site2.css">` will be added to the head
* `<script src="/js/script1.js"></script>` will be removed from the head
* `<script src="/js/script2.js"></script>` will be left alone
* `<script src="/js/script3.js"></script>` will be added to the head

The final head element will look like this:

```html
<head>
<link rel="stylesheet" href="https://the.missing.style">
<script src="/js/script2.js"></script>
<link rel="stylesheet" href="/css/site2.css">
<script src="/js/script3.js"></script>
</head>
```

## Events

This extension triggers the following events:

* `htmx:removingHeadElement` - triggered when a head element is about to be removed, with the element being removed
available in `event.detail.headElement`. If `preventDefault()` is invoked on the event, the element will not be removed.
* `htmx:addingHeadElement` - triggered when a head element is about to be added, with the element being added
available in `event.detail.headElement`. If `preventDefault()` is invoked on the event, the element will not be added.
* `htmx:afterHeadMerge` - triggered after a head tag merge has occurred, with the following values available in the event `detail`:
* `added` - added head elements
* `kept` - kept head elements
* `removed` - removed head elements
* `htmx:beforeHeadMerge` - triggered before a head merge occurs
See https://htmx.org/extensions/head-support/, or https://github.com/bigskysoftware/htmx/blob/master/www/content/extensions/head-support.md
26 changes: 1 addition & 25 deletions src/htmx-1-compat/README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1 @@
The `htmx-1-compat` extension allows you to almost seamlessly upgrade from htmx 1.x to htmx 2.

## Install

```html
<script src="https://unpkg.com/htmx-ext-htmx-1-compat@2.0.0/htmx-1-compat.js"></script>
```

## What it covers
Htmx 2 introduced a few [breaking changes](https://v2-0v2-0.htmx.org/migration-guide-htmx-1/).

To make upgrading from htmx 1.x to htmx 2 easier, we're providing this extension that reverts most of those, so you're able to benefit from the other changes without breaking your application.

### Obsolete attributes
- htmx 2 removed the deprecated [hx-ws](https://htmx.org/attributes/hx-ws/) and [hx-sse](https://htmx.org/attributes/hx-sse/) attributes, that this extension restores.
- htmx 2 removed the deprecated `hx-on` attribute in favor of the wildcard [`hx-on*` attribute](https://htmx.org/attributes/hx-on/), that this extension restores.

### Default Changes
- reverts [htmx.config.scrollBehavior](https://htmx.org/reference/#config) to 'smooth'.
- makes `DELETE` requests use a form-encoded body rather than URL parameters (htmx 2 uses URL parameters for `DELETE` as default as per [the spec](https://www.rfc-editor.org/rfc/rfc9110.html#name-delete)).
- allows cross-domain requests by default (htmx 2 now forbids it by default).

## What it does not cover
- IE11 support was dropped in htmx 2, and this extension cannot revert that. If you need IE11 support, please stay with htmx 1 that will continue being supported.
- htmx 2 introduced the breaking change that is the [swap method](https://v2-0v2-0.htmx.org/api/#swap) to the extensions API. If you were only using core extensions, then you shouldn't need any additional work. If you were using custom or community extensions, make sure that they were updated to work with htmx 2's API.
See https://htmx.org/extensions/htmx-1-compat/, or https://github.com/bigskysoftware/htmx/blob/master/www/content/extensions/htmx-1-compat.md
102 changes: 1 addition & 101 deletions src/preload/README.md
Original file line number Diff line number Diff line change
@@ -1,101 +1 @@

The `preload` extension allows you to load HTML fragments into your browser's cache before they are requested by the user, so that additional pages appear to users to load nearly instantaneously. As a developer, you can customize its behavior to fit your applications needs and use cases.

**IMPORTANT:** Preloading content judiciously can improve your web application's perceived performance, but preloading too many resources can negatively impact your visitors' bandwidth and your server performance by initiating too many unused requests. Use this extension carefully!

## Install

```html
<script src="https://unpkg.com/htmx-ext-preload@2.0.1/preload.js"></script>
```

## Usage

Register the extension with htmx using the `hx-ext` attribute. Then, add a `preload` attribute to any hyperlinks and `hx-get` elements you want to preload. By default, resources will be loaded as soon as the `mousedown` event begins, giving your application a roughly 100-200ms head start on serving responses. See configuration below for other options.

```html
<body hx-ext="preload">
<h1>What Works</h2>
<a href="/server/1" preload>WILL BE requested using a standard XMLHttpRequest() and default options (below)</a>
<button hx-get="/server/2" preload>WILL BE requested with additional htmx headers.</button>

<h1>What WILL NOT WORK</h1>
<a href="/server/3">WILL NOT be preloaded because it does not have an explicit "preload" attribute</a>
<a hx-post="/server/4" preload>WILL NOT be preloaded because it is an HX-POST transaction.</a>
</body>
```

### Inheriting Preload Settings

You can add the `preload` attribute to the top-level element that contains several `<a href="">` or `hx-get=""` elements, and all of them will be preloaded. Be careful with this setting, because you can end up wasting bandwidth if you preload many more resources than you need.

```html
<body hx-ext="preload">
<ul preload>
<li><a href="/server/1">This will be preloaded because of the attribute in the node above.</a>
<li><a href="/server/2">This will also be preloaded for the same reason.</a>
<li><a href="/server/3">This will be preloaded, too. Lorem ipsum.</a>
</ul>
</body>
```

### Preloading of Linked Images

After an HTML page (or page fragment) is preloaded, this extension can also preload linked image resources. It will not load or run linked Javascript or Cascading Stylesheet content, whether linked or embedded in the preloaded HTML. To preload images as well, use the following syntax.

```html
<div hx-ext="preload">
<a href="/my-next-page" preload="mouseover" preload-images="true">Next Page</a>
</div>
```

### Configuration

Defaults for this extension are chosen to balance users' perceived performance with potential load on your servers from unused requests. As a developer, you can modify two settings to customize this behavior to your specific use cases.

#### preload="mousedown" (DEFAULT)

The default behavior for this extension is to begin loading a resource when the user presses the mouse down. This is a conservative setting that guarantees the user actually intends to use the linked resource. Because user click events typically take 100-200ms to complete, this setting gives your server a significant headstart compared with a regular click.

```html
<a href="/server/1" preload="mousedown">This will be preloaded when the user begins to click.</a>
```

#### preload="mouseover"

To preload links more aggressively, you can trigger the preload to happen when the user's mouse hovers over the link instead. To prevent many resources from being loaded when the user scrolls or moves the mouse across a large list of objects, a 100ms delay is built in to this action. If the user's mouse leaves the element *before* this timeout expires, then the resource is not preloaded.

Typical users hover over links for several hundred milliseconds before they click, which gives your server even more time to respond to the request than the `mousedown` option above. [Test your own hover timing here.](http://instantclick.io/click-test). However, be careful when using this option because it can increase server load by requesting resources unnecessarily.

```html
<a href="/server/1" preload="mouseover">This will be preloaded when the user's mouse remains over it for more than 100ms.</a>
```

#### preload="custom-event-name"

Preload can also listen to any custom event within the system, triggering resources to be preloaded (if they have not already been cached by the browser). The extension itself generates an event called `preload:init` that can be used to trigger preloads as soon as an object has been processed by htmx.

```html
<body hx-ext="preload">
<button hx-get="/server" preload="preload:init" hx-target="idLoadMore">Load More</a>
<div id="idLoadMore">
Content for this DIV will be preloaded as soon as the page is ready.
Clicking the button above will swap it into the DOM.
</div>
</body>
```

### About Touch Events

To accommodate touchscreen devices, an additional `ontouchstart` event handler is added whenever you specify a `mouseover` or `mousedown` trigger. This extra trigger fires immediately (no waiting period) whenever the user touches the screen, saving you 300ms of waiting time on Android, and 450ms on iOS.

### Limitations

* Links must be marked with a `preload` attribute, or have an ancestor node that has the `preload` attribute.
* Only `GET` transactions (including `<a href="">` and `hx-get=""`) can be preloaded. Following REST principles, `GET` transactions are assumed to not make any significant changes to a resource. Transactions that can potentially make a change (such as `POST`, `PUT`, and `DELETE`) will not be preloaded under any circumstances.
* When listening to `mouseover` events, preload waits for 100ms before downloading the linked resource. If the mouse leaves the resource before this timeout expires, the resource is not preloaded.
* Preloaded responses will only be cached in the browser if the response headers allow it. For example, the response header `Cache-Control: private, max-age=60` allows the browser to cache the response, whereas `Cache-Control: no-cache` prevents it.

## Credits

The behavior for this plugin was inspired by the work done by [Alexandre Dieulot](https://github.com/dieulot) on [InstantClick](http://instantclick.io/), which is released under the MIT license.
See https://htmx.org/extensions/preload, or https://github.com/bigskysoftware/htmx/blob/master/www/content/extensions/preload.md
139 changes: 1 addition & 138 deletions src/response-targets/README.md
Original file line number Diff line number Diff line change
@@ -1,138 +1 @@

This extension allows you to specify different target elements to be swapped when
different HTTP response codes are received.

It uses attribute names in a form of ``hx-target-[CODE]`` where `[CODE]` is a numeric
HTTP response code with the optional wildcard character at its end. You can also use
`hx-target-error`, which handles both 4xx and 5xx response codes.

The value of each attribute can be:

* A CSS query selector of the element to target.
* `this` which indicates that the element that the `hx-target` attribute is on is the target.
* `closest <CSS selector>` which will find the closest parent ancestor that matches the given CSS selector
(e.g. `closest tr` will target the closest table row to the element).
* `find <CSS selector>` which will find the first child descendant element that matches the given CSS selector.
* `next <CSS selector>` which will scan the DOM forward for the first element that matches the given CSS selector.
(e.g. `next .error` will target the closest following sibling element with `error` class)
* `previous <CSS selector>` which will scan the DOM backwards for the first element that matches the given CSS selector.
(e.g `previous .error` will target the closest previous sibling with `error` class)

## Install

```html
<script src="https://unpkg.com/htmx-ext-response-targets@2.0.0/response-targets.js"></script>
```

## Configure (optional)

* When `HX-Retarget` response header is received it disables any lookup that would be
performed by this extension but any responses with error status codes will be
swapped (normally they would not be, even with target set via header) and internal
error flag (`isError`) will be modified. You may change this and choose to ignore
`HX-Retarget` header when `hx-target-…` is in place by setting a configuration flag
`htmx.config.responseTargetPrefersRetargetHeader` to `false` (default is
`true`). Note that this extension only performs a simple check whether the header
is set and target exists. It is not extracting target's value from the header but
trusts it was set by HTMX core logic.

* Normally, any target which is already established by HTMX built-in functions or
extensions called before will be overwritten if a matching `hx-target-…` tag is
found. You may change it by using a configuration flag
`htmx.config.responseTargetPrefersExisting` to `true` (default is `false`). This is
kinky and risky option. It has a real-life applications similar to a skilled,
full-stack tardigrade eating parentheses when no one is watching.

* `isError` flag on the `detail` member of an event associated with swapping the
content with `hx-target-[CODE]` will be set to `false` when error response code is
received. This is different from the default behavior. You may change this by
setting a configuration flag `htmx.config.responseTargetUnsetsError` to `false`
(default is `true`).

* `isError` flag on the `detail` member of an event associated with swapping the
content with `hx-target-[CODE]` will be set to `false` when non-erroneous response
code is received. This is no different from the default behavior. You may change
this by setting a configuration flag `htmx.config.responseTargetSetsError` to
`true` (default is `false`). This setting will not affect the response code 200
since it is not handled by this extension.

## Usage

Here is an example that targets a `div` for normal (200) response but another `div`
for 404 (not found) response, and yet another for all 5xx response codes:

```html
<div hx-ext="response-targets">
<div id="response-div"></div>
<button hx-post="/register"
hx-target="#response-div"
hx-target-5*="#serious-errors"
hx-target-404="#not-found">
Register!
</button>
<div id="serious-errors"></div>
<div id="not-found"></div>
</div>
```

* The response from the `/register` URL will replace contents of the `div` with the
`id` `response-div` when response code is 200 (OK).

* The response from the `/register` URL will replace contents of the `div` with the `id`
`serious-errors` when response code begins with a digit 5 (server errors).

* The response from the `/register` URL will replace contents of the `div` with
the `id` `not-found` when response code is 404 (Not Found).

Sometimes you may not want to handle 5xx and 4xx errors separately, in which case you
can use `hx-target-error`:

```html
<div hx-ext="response-targets">
<div id="response-div"></div>
<button hx-post="/register"
hx-target="#response-div"
hx-target-error="#any-errors">
Register!
</button>
<div id="any-errors"></div>
</div>
```

2xx codes will be handled as in the previous example. However, when the response code is 5xx
or 4xx, the response from `/register` will replace the contents of the `div` with the `id`
`any-errors`.

## Wildcard resolution

When status response code does not match existing `hx-target-[CODE]` attribute name
then its numeric part expressed as a string is trimmed with last character being
replaced with the asterisk (`*`). This lookup process continues until the attribute
is found or there are no more digits.

For example, if a browser receives 404 error code, the following attribute names will
be looked up (in the given order):

* `hx-target-404`
* `hx-target-40*`
* `hx-target-4*`
* `hx-target-*`.


_If you are using tools that do not support asterisks in HTML attributes, you
may instead use the `x` character, e.g., `hx-target-4xx`._

## Notes

* `hx-target-…` is inherited and can be placed on a parent element.
* `hx-target-…` cannot be used to handle HTTP response code 200.
* `hx-target-…` will honor `HX-Retarget` by default and will prefer it over any
calculated target but it can be changed by disabling the
`htmx.config.responseTargetPrefersRetargetHeader` configuration option.
* To avoid surprises the `hx-ext` attribute used to enable this extension should be
placed on a parent element containing elements with `hx-target-…` and `hx-target`
attributes.

## See also

* [`hx-target`](https://htmx.org/reference/hx-target.md), specifies the target element to be swapped
See https://htmx.org/extensions/response-targets, or https://github.com/bigskysoftware/htmx/blob/master/www/content/extensions/response-targets.md
Loading

0 comments on commit ef1c12e

Please sign in to comment.