mirror of
https://github.com/bigskysoftware/htmx.git
synced 2025-10-02 15:25:26 +00:00
oob supports various swap styles + docs update
This commit is contained in:
parent
e6b5db915a
commit
a9868cb966
25
README.md
25
README.md
@ -8,14 +8,15 @@
|
||||
|
||||
## introduction
|
||||
|
||||
htmx is a set of extensions (attributes, request headers, etc.) that help you build
|
||||
[modern UI](https://htmx.org/examples) with the [simplicity](https://en.wikipedia.org/wiki/HATEOAS) and
|
||||
[power](https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm) of HTML.
|
||||
htmx is a set of HTML extensions give you to access to [AJAX](https://htmx.org/docs#ajax),
|
||||
[WebSockets](https://htmx.org/docs#websockets) and [Server Sent Events](https://htmx.org/docs#sse)
|
||||
via [attributes](https://htmx.org/reference#attributes), allowing you to build [modern UI](https://htmx.org/examples) with the [simplicity](https://en.wikipedia.org/wiki/HATEOAS) and
|
||||
[power](https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm) of hypertext
|
||||
|
||||
htmx is small ([~6k min.gz'd](https://unpkg.com/htmx.org/dist/)),
|
||||
[dependency-free](https://github.com/bigskysoftware/htmx/blob/master/package.json),
|
||||
[extendable](https://htmx.org/extensions),
|
||||
IE11 compatible & you can try it out quickly & easily, without a huge rewrite.
|
||||
IE11 compatible & you can try it out quickly, without a huge rewrite
|
||||
|
||||
## quick start
|
||||
|
||||
@ -28,11 +29,11 @@ IE11 compatible & you can try it out quickly & easily, without a huge rewrite.
|
||||
</button>
|
||||
```
|
||||
|
||||
The `hx-post` and `hx-swap` attributes tell htmx:
|
||||
The [`hx-post`](https://htmx.org/attributes/hx-post) and [`hx-swap`](https://htmx.org/attributes/hx-swap) attributes tell htmx:
|
||||
|
||||
> "When a user clicks on this button, issue an AJAX request to /example, and replace the entire button with the response"
|
||||
> "When a user clicks on this button, issue an AJAX request to /clicked, and replace the entire button with the response"
|
||||
|
||||
htmx is based on [intercooler.js](http://intercoolerjs.org) and is the successor to that project.
|
||||
htmx is the successor to [intercooler.js](http://intercoolerjs.org)
|
||||
|
||||
## website & docs
|
||||
|
||||
@ -40,8 +41,16 @@ htmx is based on [intercooler.js](http://intercoolerjs.org) and is the successor
|
||||
|
||||
<https://htmx.org/docs>
|
||||
|
||||
## contributing
|
||||
|
||||
* please write code, including tests, in ES5 for [IE 11 compatibility](https://stackoverflow.com/questions/39902809/support-for-es6-in-internet-explorer-11)
|
||||
* please include test cases in `/test` and docs in `/www`
|
||||
* if you are adding a feature, consider doing it as an [extension](https://htmx.org/extensions) instead to
|
||||
keep the core htmx code tidy
|
||||
* development pull requests should be against the `dev` branch, docs fixes can be made directly against `master`
|
||||
|
||||
## haiku
|
||||
|
||||
*javascript fatigue:<br/>
|
||||
longing for a hypertext<br/>
|
||||
already in hand*
|
||||
already in hand*
|
3
dist/ext/morphdom-swap.js
vendored
3
dist/ext/morphdom-swap.js
vendored
@ -1,4 +1,7 @@
|
||||
htmx.defineExtension('morphdom-swap', {
|
||||
isInlineSwap: function(swapStyle) {
|
||||
return swapStyle === 'morphdom';
|
||||
},
|
||||
handleSwap: function (swapStyle, target, fragment) {
|
||||
if (swapStyle === 'morphdom') {
|
||||
morphdom(target, fragment.outerHTML);
|
||||
|
56
dist/htmx.js
vendored
56
dist/htmx.js
vendored
@ -328,18 +328,44 @@ return (function () {
|
||||
});
|
||||
}
|
||||
|
||||
function isInlineSwap(swapStyle, target) {
|
||||
var extensions = getExtensions(target);
|
||||
for (var i = 0; i < extensions.length; i++) {
|
||||
var extension = extensions[i];
|
||||
if (extension.isInlineSwap(swapStyle)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return swapStyle === "outerHTML";
|
||||
}
|
||||
|
||||
function oobSwap(oobValue, child, settleInfo) {
|
||||
if (oobValue === "true") {
|
||||
oobValue = "outerHTML"
|
||||
}
|
||||
var target = getDocument().getElementById(child.id);
|
||||
if (target) {
|
||||
var fragment;
|
||||
if (isInlineSwap(oobValue, target)) {
|
||||
fragment = getDocument().createDocumentFragment();
|
||||
fragment.appendChild(child);
|
||||
} else {
|
||||
fragment = child;
|
||||
}
|
||||
fragment.appendChild(child);
|
||||
swap(oobValue, target, target, fragment, settleInfo);
|
||||
} else {
|
||||
child.parentNode.removeChild(child);
|
||||
triggerErrorEvent(getDocument().body, "oobErrorNoTarget.htmx", {content: child})
|
||||
}
|
||||
return oobValue;
|
||||
}
|
||||
|
||||
function handleOutOfBandSwaps(fragment, settleInfo) {
|
||||
forEach(toArray(fragment.children), function (child) {
|
||||
if (getAttributeValue(child, "hx-swap-oob") === "true") {
|
||||
var target = getDocument().getElementById(child.id);
|
||||
if (target) {
|
||||
var fragment = getDocument().createDocumentFragment();
|
||||
fragment.appendChild(child);
|
||||
swapOuterHTML(target, fragment, settleInfo);
|
||||
} else {
|
||||
child.parentNode.removeChild(child);
|
||||
triggerErrorEvent(getDocument().body, "oobErrorNoTarget.htmx", {content: child})
|
||||
}
|
||||
var oobValue = getAttributeValue(child, "hx-swap-oob");
|
||||
if (oobValue != null) {
|
||||
oobSwap(oobValue, child, settleInfo);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -675,14 +701,7 @@ return (function () {
|
||||
var children = toArray(fragment.children);
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
if (child.id) {
|
||||
var target = getDocument().getElementById(child.id);
|
||||
if (target) {
|
||||
var tmp = getDocument().createDocumentFragment();
|
||||
tmp.appendChild(child);
|
||||
swapOuterHTML(target, fragment, settleInfo);
|
||||
}
|
||||
}
|
||||
oobSwap(getAttributeValue(child, "hx-swap-oob") || "true", child, settleInfo);
|
||||
}
|
||||
|
||||
settleImmediately(settleInfo.tasks);
|
||||
@ -1413,6 +1432,7 @@ return (function () {
|
||||
return {
|
||||
onEvent : function(name, evt) {return true;},
|
||||
transformResponse : function(text, xhr, elt) {return text;},
|
||||
isInlineSwap : function(swapStyle) {return false;},
|
||||
handleSwap : function(swapStyle, target, fragment, settleInfo) {return false;},
|
||||
encodeParameters : function(xhr, parameters, elt) {return null;}
|
||||
}
|
||||
|
2
dist/htmx.min.js
vendored
2
dist/htmx.min.js
vendored
File diff suppressed because one or more lines are too long
BIN
dist/htmx.min.js.gz
vendored
BIN
dist/htmx.min.js.gz
vendored
Binary file not shown.
@ -1,4 +1,7 @@
|
||||
htmx.defineExtension('morphdom-swap', {
|
||||
isInlineSwap: function(swapStyle) {
|
||||
return swapStyle === 'morphdom';
|
||||
},
|
||||
handleSwap: function (swapStyle, target, fragment) {
|
||||
if (swapStyle === 'morphdom') {
|
||||
morphdom(target, fragment.outerHTML);
|
||||
|
56
src/htmx.js
56
src/htmx.js
@ -328,18 +328,44 @@ return (function () {
|
||||
});
|
||||
}
|
||||
|
||||
function isInlineSwap(swapStyle, target) {
|
||||
var extensions = getExtensions(target);
|
||||
for (var i = 0; i < extensions.length; i++) {
|
||||
var extension = extensions[i];
|
||||
if (extension.isInlineSwap(swapStyle)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return swapStyle === "outerHTML";
|
||||
}
|
||||
|
||||
function oobSwap(oobValue, child, settleInfo) {
|
||||
if (oobValue === "true") {
|
||||
oobValue = "outerHTML"
|
||||
}
|
||||
var target = getDocument().getElementById(child.id);
|
||||
if (target) {
|
||||
var fragment;
|
||||
if (isInlineSwap(oobValue, target)) {
|
||||
fragment = getDocument().createDocumentFragment();
|
||||
fragment.appendChild(child);
|
||||
} else {
|
||||
fragment = child;
|
||||
}
|
||||
fragment.appendChild(child);
|
||||
swap(oobValue, target, target, fragment, settleInfo);
|
||||
} else {
|
||||
child.parentNode.removeChild(child);
|
||||
triggerErrorEvent(getDocument().body, "oobErrorNoTarget.htmx", {content: child})
|
||||
}
|
||||
return oobValue;
|
||||
}
|
||||
|
||||
function handleOutOfBandSwaps(fragment, settleInfo) {
|
||||
forEach(toArray(fragment.children), function (child) {
|
||||
if (getAttributeValue(child, "hx-swap-oob") === "true") {
|
||||
var target = getDocument().getElementById(child.id);
|
||||
if (target) {
|
||||
var fragment = getDocument().createDocumentFragment();
|
||||
fragment.appendChild(child);
|
||||
swapOuterHTML(target, fragment, settleInfo);
|
||||
} else {
|
||||
child.parentNode.removeChild(child);
|
||||
triggerErrorEvent(getDocument().body, "oobErrorNoTarget.htmx", {content: child})
|
||||
}
|
||||
var oobValue = getAttributeValue(child, "hx-swap-oob");
|
||||
if (oobValue != null) {
|
||||
oobSwap(oobValue, child, settleInfo);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -675,14 +701,7 @@ return (function () {
|
||||
var children = toArray(fragment.children);
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
if (child.id) {
|
||||
var target = getDocument().getElementById(child.id);
|
||||
if (target) {
|
||||
var tmp = getDocument().createDocumentFragment();
|
||||
tmp.appendChild(child);
|
||||
swapOuterHTML(target, fragment, settleInfo);
|
||||
}
|
||||
}
|
||||
oobSwap(getAttributeValue(child, "hx-swap-oob") || "true", child, settleInfo);
|
||||
}
|
||||
|
||||
settleImmediately(settleInfo.tasks);
|
||||
@ -1413,6 +1432,7 @@ return (function () {
|
||||
return {
|
||||
onEvent : function(name, evt) {return true;},
|
||||
transformResponse : function(text, xhr, elt) {return text;},
|
||||
isInlineSwap : function(swapStyle) {return false;},
|
||||
handleSwap : function(swapStyle, target, fragment, settleInfo) {return false;},
|
||||
encodeParameters : function(xhr, parameters, elt) {return null;}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ title: </> htmx - high power tools for html
|
||||
* [swapping](#swapping)
|
||||
* [parameters](#parameters)
|
||||
* [boosting](#boosting)
|
||||
* [websockets & SSE](#web-sockets-and-sse)
|
||||
* [websockets & SSE](#websockets-and-sse)
|
||||
* [history](#history)
|
||||
* [requests & responses](#requests)
|
||||
* [animations](#animations)
|
||||
@ -359,7 +359,7 @@ The anchor tag in this div will issue an AJAX `GET` request to `/blog` and swap
|
||||
This functionality is somewhat similar to [Turbolinks](https://github.com/turbolinks/turbolinks) and allows you to use
|
||||
htmx for [progressive enhancement](https://en.wikipedia.org/wiki/Progressive_enhancement).
|
||||
|
||||
### <a name="web-sockets-and-sse"></a> [Web Sockets & SSE](#web-sockets-and-sse)
|
||||
### <a name="websockets-and-sse"></a> [Web Sockets & SSE](#websockets-and-sse)
|
||||
|
||||
Htmx has experimental support for declarative use of both
|
||||
[WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications)
|
||||
|
13
www/index.md
13
www/index.md
@ -11,14 +11,15 @@ title: </> htmx - high power tools for html
|
||||
|
||||
## introduction
|
||||
|
||||
htmx is a set of extensions (attributes, request headers, etc.) that help you build
|
||||
[modern UI](/examples) with the [simplicity](https://en.wikipedia.org/wiki/HATEOAS) and
|
||||
[power](https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm) of HTML.
|
||||
htmx is a set of HTML extensions give you to access to [AJAX](https://htmx.org/docs#ajax),
|
||||
[WebSockets](https://htmx.org/docs#websockets) and [Server Sent Events](https://htmx.org/docs#sse)
|
||||
via [attributes](https://htmx.org/reference#attributes), allowing you to build [modern UI](https://htmx.org/examples) with the [simplicity](https://en.wikipedia.org/wiki/HATEOAS) and
|
||||
[power](https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm) of hypertext
|
||||
|
||||
htmx is small ([~6k min.gz'd](https://unpkg.com/htmx.org/dist/)),
|
||||
[dependency-free](https://github.com/bigskysoftware/htmx/blob/master/package.json),
|
||||
[extendable](/extensions),
|
||||
IE11 compatible & you can try it out quickly & easily, without a huge rewrite.
|
||||
IE11 compatible & you can try it out quickly, without a huge rewrite
|
||||
|
||||
## quick start
|
||||
|
||||
@ -31,11 +32,11 @@ IE11 compatible & you can try it out quickly & easily, without a huge rewrite.
|
||||
</button>
|
||||
```
|
||||
|
||||
The `hx-post` and `hx-swap` attributes tell htmx:
|
||||
The [`hx-post`](https://htmx.org/attributes/hx-post) and [`hx-swap`](https://htmx.org/attributes/hx-swap) attributes tell htmx:
|
||||
|
||||
> "When a user clicks on this button, issue an AJAX request to /clicked, and replace the entire button with the response"
|
||||
|
||||
htmx is based on [intercooler.js](http://intercoolerjs.org) and is the successor to that project.
|
||||
htmx is the successor to [intercooler.js](http://intercoolerjs.org)
|
||||
|
||||
## haiku
|
||||
|
||||
|
@ -328,18 +328,44 @@ return (function () {
|
||||
});
|
||||
}
|
||||
|
||||
function isInlineSwap(swapStyle, target) {
|
||||
var extensions = getExtensions(target);
|
||||
for (var i = 0; i < extensions.length; i++) {
|
||||
var extension = extensions[i];
|
||||
if (extension.isInlineSwap(swapStyle)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return swapStyle === "outerHTML";
|
||||
}
|
||||
|
||||
function oobSwap(oobValue, child, settleInfo) {
|
||||
if (oobValue === "true") {
|
||||
oobValue = "outerHTML"
|
||||
}
|
||||
var target = getDocument().getElementById(child.id);
|
||||
if (target) {
|
||||
var fragment;
|
||||
if (isInlineSwap(oobValue, target)) {
|
||||
fragment = getDocument().createDocumentFragment();
|
||||
fragment.appendChild(child);
|
||||
} else {
|
||||
fragment = child;
|
||||
}
|
||||
fragment.appendChild(child);
|
||||
swap(oobValue, target, target, fragment, settleInfo);
|
||||
} else {
|
||||
child.parentNode.removeChild(child);
|
||||
triggerErrorEvent(getDocument().body, "oobErrorNoTarget.htmx", {content: child})
|
||||
}
|
||||
return oobValue;
|
||||
}
|
||||
|
||||
function handleOutOfBandSwaps(fragment, settleInfo) {
|
||||
forEach(toArray(fragment.children), function (child) {
|
||||
if (getAttributeValue(child, "hx-swap-oob") === "true") {
|
||||
var target = getDocument().getElementById(child.id);
|
||||
if (target) {
|
||||
var fragment = getDocument().createDocumentFragment();
|
||||
fragment.appendChild(child);
|
||||
swapOuterHTML(target, fragment, settleInfo);
|
||||
} else {
|
||||
child.parentNode.removeChild(child);
|
||||
triggerErrorEvent(getDocument().body, "oobErrorNoTarget.htmx", {content: child})
|
||||
}
|
||||
var oobValue = getAttributeValue(child, "hx-swap-oob");
|
||||
if (oobValue != null) {
|
||||
oobSwap(oobValue, child, settleInfo);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -675,14 +701,7 @@ return (function () {
|
||||
var children = toArray(fragment.children);
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
if (child.id) {
|
||||
var target = getDocument().getElementById(child.id);
|
||||
if (target) {
|
||||
var tmp = getDocument().createDocumentFragment();
|
||||
tmp.appendChild(child);
|
||||
swapOuterHTML(target, fragment, settleInfo);
|
||||
}
|
||||
}
|
||||
oobSwap(getAttributeValue(child, "hx-swap-oob") || "true", child, settleInfo);
|
||||
}
|
||||
|
||||
settleImmediately(settleInfo.tasks);
|
||||
@ -1413,6 +1432,7 @@ return (function () {
|
||||
return {
|
||||
onEvent : function(name, evt) {return true;},
|
||||
transformResponse : function(text, xhr, elt) {return text;},
|
||||
isInlineSwap : function(swapStyle) {return false;},
|
||||
handleSwap : function(swapStyle, target, fragment, settleInfo) {return false;},
|
||||
encodeParameters : function(xhr, parameters, elt) {return null;}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
htmx.defineExtension('morphdom-swap', {
|
||||
isInlineSwap: function(swapStyle) {
|
||||
return swapStyle === 'morphdom';
|
||||
},
|
||||
handleSwap: function (swapStyle, target, fragment) {
|
||||
if (swapStyle === 'morphdom') {
|
||||
morphdom(target, fragment.outerHTML);
|
||||
|
@ -328,18 +328,44 @@ return (function () {
|
||||
});
|
||||
}
|
||||
|
||||
function isInlineSwap(swapStyle, target) {
|
||||
var extensions = getExtensions(target);
|
||||
for (var i = 0; i < extensions.length; i++) {
|
||||
var extension = extensions[i];
|
||||
if (extension.isInlineSwap(swapStyle)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return swapStyle === "outerHTML";
|
||||
}
|
||||
|
||||
function oobSwap(oobValue, child, settleInfo) {
|
||||
if (oobValue === "true") {
|
||||
oobValue = "outerHTML"
|
||||
}
|
||||
var target = getDocument().getElementById(child.id);
|
||||
if (target) {
|
||||
var fragment;
|
||||
if (isInlineSwap(oobValue, target)) {
|
||||
fragment = getDocument().createDocumentFragment();
|
||||
fragment.appendChild(child);
|
||||
} else {
|
||||
fragment = child;
|
||||
}
|
||||
fragment.appendChild(child);
|
||||
swap(oobValue, target, target, fragment, settleInfo);
|
||||
} else {
|
||||
child.parentNode.removeChild(child);
|
||||
triggerErrorEvent(getDocument().body, "oobErrorNoTarget.htmx", {content: child})
|
||||
}
|
||||
return oobValue;
|
||||
}
|
||||
|
||||
function handleOutOfBandSwaps(fragment, settleInfo) {
|
||||
forEach(toArray(fragment.children), function (child) {
|
||||
if (getAttributeValue(child, "hx-swap-oob") === "true") {
|
||||
var target = getDocument().getElementById(child.id);
|
||||
if (target) {
|
||||
var fragment = getDocument().createDocumentFragment();
|
||||
fragment.appendChild(child);
|
||||
swapOuterHTML(target, fragment, settleInfo);
|
||||
} else {
|
||||
child.parentNode.removeChild(child);
|
||||
triggerErrorEvent(getDocument().body, "oobErrorNoTarget.htmx", {content: child})
|
||||
}
|
||||
var oobValue = getAttributeValue(child, "hx-swap-oob");
|
||||
if (oobValue != null) {
|
||||
oobSwap(oobValue, child, settleInfo);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -675,14 +701,7 @@ return (function () {
|
||||
var children = toArray(fragment.children);
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
if (child.id) {
|
||||
var target = getDocument().getElementById(child.id);
|
||||
if (target) {
|
||||
var tmp = getDocument().createDocumentFragment();
|
||||
tmp.appendChild(child);
|
||||
swapOuterHTML(target, fragment, settleInfo);
|
||||
}
|
||||
}
|
||||
oobSwap(getAttributeValue(child, "hx-swap-oob") || "true", child, settleInfo);
|
||||
}
|
||||
|
||||
settleImmediately(settleInfo.tasks);
|
||||
@ -1413,6 +1432,7 @@ return (function () {
|
||||
return {
|
||||
onEvent : function(name, evt) {return true;},
|
||||
transformResponse : function(text, xhr, elt) {return text;},
|
||||
isInlineSwap : function(swapStyle) {return false;},
|
||||
handleSwap : function(swapStyle, target, fragment, settleInfo) {return false;},
|
||||
encodeParameters : function(xhr, parameters, elt) {return null;}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user