oob supports various swap styles + docs update

This commit is contained in:
carson 2020-05-25 07:36:14 -07:00
parent e6b5db915a
commit a9868cb966
12 changed files with 188 additions and 89 deletions

View File

@ -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*

View File

@ -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
View File

@ -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

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,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);

View File

@ -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;}
}

View File

@ -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)

View File

@ -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

View File

@ -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;}
}

View File

@ -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);

View File

@ -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;}
}