1.8 release prep

This commit is contained in:
Carson Gross 2022-07-11 13:57:23 -06:00
parent de78dc0070
commit 83b60f41f1
11 changed files with 1080 additions and 10484 deletions

176
dist/htmx.js vendored
View File

@ -1369,7 +1369,7 @@ return (function () {
var windowIsScrolling = false // used by initScrollHandler
var scrollHandler = null;
function initScrollHandler(handler) {
function initScrollHandler() {
if (!scrollHandler) {
scrollHandler = function() {
windowIsScrolling = true
@ -1379,22 +1379,22 @@ return (function () {
if (windowIsScrolling) {
windowIsScrolling = false;
forEach(getDocument().querySelectorAll("[hx-trigger='revealed'],[data-hx-trigger='revealed']"), function (elt) {
maybeReveal(elt, handler);
maybeReveal(elt);
})
}
}, 200);
}
}
function maybeReveal(elt, handler) {
function maybeReveal(elt) {
if (!hasAttribute(elt,'data-hx-revealed') && isScrolledIntoView(elt)) {
elt.setAttribute('data-hx-revealed', 'true');
var nodeData = getInternalData(elt);
if (nodeData.initialized) {
handler(elt);
triggerEvent(elt, 'revealed');
} else {
// if the node isn't initialized, wait for it before triggering the request
elt.addEventListener("htmx:afterProcessNode", function(evt) { handler(elt) }, {once: true});
elt.addEventListener("htmx:afterProcessNode", function(evt) { triggerEvent(elt, 'revealed') }, {once: true});
}
}
}
@ -1650,8 +1650,9 @@ return (function () {
if (triggerSpec.sseEvent) {
processSSETrigger(elt, handler, triggerSpec.sseEvent);
} else if (triggerSpec.trigger === "revealed") {
initScrollHandler(handler);
maybeReveal(elt, handler);
initScrollHandler();
addEventListener(elt, handler, nodeData, triggerSpec);
maybeReveal(elt);
} else if (triggerSpec.trigger === "intersect") {
var observerOptions = {};
if (triggerSpec.root) {
@ -2008,21 +2009,6 @@ return (function () {
}
}
function shouldPushUrl(elt) {
var pushUrl = getClosestAttributeValue(elt, "hx-push-url");
return (pushUrl && pushUrl !== "false") || (getInternalData(elt).boosted);
}
function shouldReplaceUrl(elt) {
var replaceUrl = getClosestAttributeValue(elt, "hx-replace-url");
return (replaceUrl && replaceUrl !== "false");
}
function getPushOrReplaceUrl(elt, type) {
var urlValue = getClosestAttributeValue(elt, "hx-" + type + "-url");
return (urlValue === "true" || urlValue === "false") ? null : urlValue;
}
function addRequestIndicatorClasses(elt) {
var indicators = findAttributeTargets(elt, 'hx-indicator');
if (indicators == null) {
@ -2506,7 +2492,7 @@ return (function () {
}
}
function getResponseURL(xhr) {
function getPathFromResponse(xhr) {
// NB: IE11 does not support this stuff
if (xhr.responseURL && typeof(URL) !== "undefined") {
try {
@ -2745,8 +2731,9 @@ return (function () {
var splitPath = path.split("#");
var pathNoAnchor = splitPath[0];
var anchor = splitPath[1];
var finalPathForGet = null;
if (verb === 'get') {
var finalPathForGet = pathNoAnchor;
finalPathForGet = pathNoAnchor;
var values = Object.keys(filteredParameters).length !== 0;
if (values) {
if (finalPathForGet.indexOf("?") < 0) {
@ -2780,14 +2767,19 @@ return (function () {
}
}
var responseInfo = {xhr: xhr, target: target, requestConfig: requestConfig, etc:etc, pathInfo:{
path:path, finalPath:finalPathForGet, anchor:anchor
var responseInfo = {
xhr: xhr, target: target, requestConfig: requestConfig, etc: etc,
pathInfo: {
requestPath: path,
finalRequestPath: path || finalPathForGet,
anchor: anchor
}
};
xhr.onload = function () {
try {
var hierarchy = hierarchyForElt(elt);
responseInfo.pathInfo.responsePath = getPathFromResponse(xhr);
responseHandler(elt, responseInfo);
removeRequestIndicatorClasses(indicators);
triggerEvent(elt, 'htmx:afterRequest', responseInfo);
@ -2858,6 +2850,88 @@ return (function () {
return promise;
}
function determineHistoryUpdates(elt, responseInfo) {
var xhr = responseInfo.xhr;
//===========================================
// First consult response headers
//===========================================
var pathFromHeaders = null;
var typeFromHeaders = null;
if (hasHeader(xhr,/HX-Push:/i)) {
pathFromHeaders = xhr.getResponseHeader("HX-Push");
typeFromHeaders = "push";
} else if (hasHeader(xhr,/HX-Push-Url:/i)) {
pathFromHeaders = xhr.getResponseHeader("HX-Push-Url");
typeFromHeaders = "push";
} else if (hasHeader(xhr,/HX-Replace-Url:/i)) {
pathFromHeaders = xhr.getResponseHeader("HX-Replace-Url");
typeFromHeaders = "replace";
}
// if there was a response header, that has priority
if (pathFromHeaders) {
if (pathFromHeaders === "false") {
return {}
} else {
return {
type: typeFromHeaders,
path : pathFromHeaders
}
}
}
//===========================================
// Next resolve via DOM values
//===========================================
var requestPath = responseInfo.pathInfo.finalRequestPath;
var responsePath = responseInfo.pathInfo.responsePath;
var pushUrl = getClosestAttributeValue(elt, "hx-push-url");
var replaceUrl = getClosestAttributeValue(elt, "hx-replace-url");
var elementIsBoosted = getInternalData(elt).boosted;
var saveType = null;
var path = null;
if (pushUrl) {
saveType = "push";
path = pushUrl;
} else if (replaceUrl) {
saveType = "replace";
path = replaceUrl;
} else if (elementIsBoosted) {
saveType = "push";
path = responsePath || requestPath; // if there is no response path, go with the original request path
}
if (path) {
// false indicates no push, return empty object
if (path === "false") {
return {};
}
// true indicates we want to follow wherever the server ended up sending us
if (path === "true") {
path = responsePath;
}
// restore any anchor associated with the request
if (responseInfo.pathInfo.anchor &&
path.indexOf("#") === -1) {
path = path + "#" + responseInfo.pathInfo.anchor;
}
return {
type:saveType,
path: path
}
} else {
return {};
}
}
function handleAjaxResponse(elt, responseInfo) {
var xhr = responseInfo.xhr;
var target = responseInfo.target;
@ -2869,17 +2943,6 @@ return (function () {
handleTrigger(xhr, "HX-Trigger", elt);
}
if (hasHeader(xhr,/HX-Push:/i)) {
var pushedUrl = xhr.getResponseHeader("HX-Push");
}
if (hasHeader(xhr,/HX-Push-Url:/i)) {
var pushedUrl = xhr.getResponseHeader("HX-Push-Url");
}
if (hasHeader(xhr,/HX-Replace-Url:/i)) {
var replacementUrl = xhr.getResponseHeader("HX-Replace-Url");
}
if (hasHeader(xhr, /HX-Location:/i)) {
saveCurrentPageToHistory();
var redirectPath = xhr.getResponseHeader("HX-Location");
@ -2897,7 +2960,7 @@ return (function () {
}
if (hasHeader(xhr, /HX-Redirect:/i)) {
window.location.href = xhr.getResponseHeader("HX-Redirect");
location.href = xhr.getResponseHeader("HX-Redirect");
return;
}
@ -2912,14 +2975,7 @@ return (function () {
responseInfo.target = getDocument().querySelector(xhr.getResponseHeader("HX-Retarget"));
}
/** @type {boolean} */
var historySaveType;
if ((pushedUrl && pushedUrl !== "false") || shouldPushUrl(elt)) {
historySaveType = "push";
}
if ((replacementUrl && replacementUrl !== "false") || shouldReplaceUrl(elt)) {
historySaveType = "replace";
}
var historyUpdate = determineHistoryUpdates(elt, responseInfo);
// by default htmx only swaps on 200 return codes and does not swap
// on 204 'No Content'
@ -2948,7 +3004,7 @@ return (function () {
});
// Save current page
if (historySaveType) {
if (historyUpdate) {
saveCurrentPageToHistory();
}
@ -3001,9 +3057,6 @@ return (function () {
}
triggerEvent(elt, 'htmx:afterSwap', responseInfo);
});
if (responseInfo.pathInfo.anchor) {
location.hash = responseInfo.pathInfo.anchor;
}
if (hasHeader(xhr, /HX-Trigger-After-Swap:/i)) {
var finalElt = elt;
@ -3023,16 +3076,21 @@ return (function () {
}
triggerEvent(elt, 'htmx:afterSettle', responseInfo);
});
// push URL and save new page
if (historySaveType) {
var pathToPush = pushedUrl || getPushOrReplaceUrl(elt, "push") || getPushOrReplaceUrl(elt, "replace")
|| getResponseURL(xhr) || responseInfo.pathInfo.finalPath || responseInfo.pathInfo.path;
if (historySaveType === "push") {
pushUrlIntoHistory(pathToPush);
triggerEvent(getDocument().body, 'htmx:pushedIntoHistory', {path: pathToPush});
// if we need to save history, do so
if (historyUpdate.type) {
if (historyUpdate.type === "push") {
pushUrlIntoHistory(historyUpdate.path);
triggerEvent(getDocument().body, 'htmx:pushedIntoHistory', {path: historyUpdate.path});
} else {
replaceUrlInHistory(pathToPush);
triggerEvent(getDocument().body, 'htmx:replacedInHistory', {path: pathToPush});
replaceUrlInHistory(historyUpdate.path);
triggerEvent(getDocument().body, 'htmx:replacedInHistory', {path: historyUpdate.path});
}
}
if (responseInfo.pathInfo.anchor) {
var anchorTarget = find("#" + responseInfo.pathInfo.anchor);
if(anchorTarget) {
anchorTarget.scrollIntoView({block:'start', behavior: "auto"});
}
}

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.

10984
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@
"url": "git+https://github.com/bigskysoftware/htmx.git"
},
"devDependencies": {
"@11ty/eleventy": "^0.10.0",
"@11ty/eleventy": "^0.12.1",
"@11ty/eleventy-plugin-rss": "^1.1.2",
"chai": "^4.3.6",
"chai-dom": "^1.11.0",

View File

@ -1369,7 +1369,7 @@ return (function () {
var windowIsScrolling = false // used by initScrollHandler
var scrollHandler = null;
function initScrollHandler(handler) {
function initScrollHandler() {
if (!scrollHandler) {
scrollHandler = function() {
windowIsScrolling = true
@ -1379,22 +1379,22 @@ return (function () {
if (windowIsScrolling) {
windowIsScrolling = false;
forEach(getDocument().querySelectorAll("[hx-trigger='revealed'],[data-hx-trigger='revealed']"), function (elt) {
maybeReveal(elt, handler);
maybeReveal(elt);
})
}
}, 200);
}
}
function maybeReveal(elt, handler) {
function maybeReveal(elt) {
if (!hasAttribute(elt,'data-hx-revealed') && isScrolledIntoView(elt)) {
elt.setAttribute('data-hx-revealed', 'true');
var nodeData = getInternalData(elt);
if (nodeData.initialized) {
handler(elt);
triggerEvent(elt, 'revealed');
} else {
// if the node isn't initialized, wait for it before triggering the request
elt.addEventListener("htmx:afterProcessNode", function(evt) { handler(elt) }, {once: true});
elt.addEventListener("htmx:afterProcessNode", function(evt) { triggerEvent(elt, 'revealed') }, {once: true});
}
}
}
@ -1650,8 +1650,9 @@ return (function () {
if (triggerSpec.sseEvent) {
processSSETrigger(elt, handler, triggerSpec.sseEvent);
} else if (triggerSpec.trigger === "revealed") {
initScrollHandler(handler);
maybeReveal(elt, handler);
initScrollHandler();
addEventListener(elt, handler, nodeData, triggerSpec);
maybeReveal(elt);
} else if (triggerSpec.trigger === "intersect") {
var observerOptions = {};
if (triggerSpec.root) {
@ -2008,21 +2009,6 @@ return (function () {
}
}
function shouldPushUrl(elt) {
var pushUrl = getClosestAttributeValue(elt, "hx-push-url");
return (pushUrl && pushUrl !== "false") || (getInternalData(elt).boosted);
}
function shouldReplaceUrl(elt) {
var replaceUrl = getClosestAttributeValue(elt, "hx-replace-url");
return (replaceUrl && replaceUrl !== "false");
}
function getPushOrReplaceUrl(elt, type) {
var urlValue = getClosestAttributeValue(elt, "hx-" + type + "-url");
return (urlValue === "true" || urlValue === "false") ? null : urlValue;
}
function addRequestIndicatorClasses(elt) {
var indicators = findAttributeTargets(elt, 'hx-indicator');
if (indicators == null) {
@ -2506,7 +2492,7 @@ return (function () {
}
}
function getResponseURL(xhr) {
function getPathFromResponse(xhr) {
// NB: IE11 does not support this stuff
if (xhr.responseURL && typeof(URL) !== "undefined") {
try {
@ -2745,8 +2731,9 @@ return (function () {
var splitPath = path.split("#");
var pathNoAnchor = splitPath[0];
var anchor = splitPath[1];
var finalPathForGet = null;
if (verb === 'get') {
var finalPathForGet = pathNoAnchor;
finalPathForGet = pathNoAnchor;
var values = Object.keys(filteredParameters).length !== 0;
if (values) {
if (finalPathForGet.indexOf("?") < 0) {
@ -2780,14 +2767,19 @@ return (function () {
}
}
var responseInfo = {xhr: xhr, target: target, requestConfig: requestConfig, etc:etc, pathInfo:{
path:path, finalPath:finalPathForGet, anchor:anchor
var responseInfo = {
xhr: xhr, target: target, requestConfig: requestConfig, etc: etc,
pathInfo: {
requestPath: path,
finalRequestPath: path || finalPathForGet,
anchor: anchor
}
};
xhr.onload = function () {
try {
var hierarchy = hierarchyForElt(elt);
responseInfo.pathInfo.responsePath = getPathFromResponse(xhr);
responseHandler(elt, responseInfo);
removeRequestIndicatorClasses(indicators);
triggerEvent(elt, 'htmx:afterRequest', responseInfo);
@ -2858,6 +2850,88 @@ return (function () {
return promise;
}
function determineHistoryUpdates(elt, responseInfo) {
var xhr = responseInfo.xhr;
//===========================================
// First consult response headers
//===========================================
var pathFromHeaders = null;
var typeFromHeaders = null;
if (hasHeader(xhr,/HX-Push:/i)) {
pathFromHeaders = xhr.getResponseHeader("HX-Push");
typeFromHeaders = "push";
} else if (hasHeader(xhr,/HX-Push-Url:/i)) {
pathFromHeaders = xhr.getResponseHeader("HX-Push-Url");
typeFromHeaders = "push";
} else if (hasHeader(xhr,/HX-Replace-Url:/i)) {
pathFromHeaders = xhr.getResponseHeader("HX-Replace-Url");
typeFromHeaders = "replace";
}
// if there was a response header, that has priority
if (pathFromHeaders) {
if (pathFromHeaders === "false") {
return {}
} else {
return {
type: typeFromHeaders,
path : pathFromHeaders
}
}
}
//===========================================
// Next resolve via DOM values
//===========================================
var requestPath = responseInfo.pathInfo.finalRequestPath;
var responsePath = responseInfo.pathInfo.responsePath;
var pushUrl = getClosestAttributeValue(elt, "hx-push-url");
var replaceUrl = getClosestAttributeValue(elt, "hx-replace-url");
var elementIsBoosted = getInternalData(elt).boosted;
var saveType = null;
var path = null;
if (pushUrl) {
saveType = "push";
path = pushUrl;
} else if (replaceUrl) {
saveType = "replace";
path = replaceUrl;
} else if (elementIsBoosted) {
saveType = "push";
path = responsePath || requestPath; // if there is no response path, go with the original request path
}
if (path) {
// false indicates no push, return empty object
if (path === "false") {
return {};
}
// true indicates we want to follow wherever the server ended up sending us
if (path === "true") {
path = responsePath;
}
// restore any anchor associated with the request
if (responseInfo.pathInfo.anchor &&
path.indexOf("#") === -1) {
path = path + "#" + responseInfo.pathInfo.anchor;
}
return {
type:saveType,
path: path
}
} else {
return {};
}
}
function handleAjaxResponse(elt, responseInfo) {
var xhr = responseInfo.xhr;
var target = responseInfo.target;
@ -2869,17 +2943,6 @@ return (function () {
handleTrigger(xhr, "HX-Trigger", elt);
}
if (hasHeader(xhr,/HX-Push:/i)) {
var pushedUrl = xhr.getResponseHeader("HX-Push");
}
if (hasHeader(xhr,/HX-Push-Url:/i)) {
var pushedUrl = xhr.getResponseHeader("HX-Push-Url");
}
if (hasHeader(xhr,/HX-Replace-Url:/i)) {
var replacementUrl = xhr.getResponseHeader("HX-Replace-Url");
}
if (hasHeader(xhr, /HX-Location:/i)) {
saveCurrentPageToHistory();
var redirectPath = xhr.getResponseHeader("HX-Location");
@ -2897,7 +2960,7 @@ return (function () {
}
if (hasHeader(xhr, /HX-Redirect:/i)) {
window.location.href = xhr.getResponseHeader("HX-Redirect");
location.href = xhr.getResponseHeader("HX-Redirect");
return;
}
@ -2912,14 +2975,7 @@ return (function () {
responseInfo.target = getDocument().querySelector(xhr.getResponseHeader("HX-Retarget"));
}
/** @type {boolean} */
var historySaveType;
if ((pushedUrl && pushedUrl !== "false") || shouldPushUrl(elt)) {
historySaveType = "push";
}
if ((replacementUrl && replacementUrl !== "false") || shouldReplaceUrl(elt)) {
historySaveType = "replace";
}
var historyUpdate = determineHistoryUpdates(elt, responseInfo);
// by default htmx only swaps on 200 return codes and does not swap
// on 204 'No Content'
@ -2948,7 +3004,7 @@ return (function () {
});
// Save current page
if (historySaveType) {
if (historyUpdate) {
saveCurrentPageToHistory();
}
@ -3001,9 +3057,6 @@ return (function () {
}
triggerEvent(elt, 'htmx:afterSwap', responseInfo);
});
if (responseInfo.pathInfo.anchor) {
location.hash = responseInfo.pathInfo.anchor;
}
if (hasHeader(xhr, /HX-Trigger-After-Swap:/i)) {
var finalElt = elt;
@ -3023,16 +3076,21 @@ return (function () {
}
triggerEvent(elt, 'htmx:afterSettle', responseInfo);
});
// push URL and save new page
if (historySaveType) {
var pathToPush = pushedUrl || getPushOrReplaceUrl(elt, "push") || getPushOrReplaceUrl(elt, "replace")
|| getResponseURL(xhr) || responseInfo.pathInfo.finalPath || responseInfo.pathInfo.path;
if (historySaveType === "push") {
pushUrlIntoHistory(pathToPush);
triggerEvent(getDocument().body, 'htmx:pushedIntoHistory', {path: pathToPush});
// if we need to save history, do so
if (historyUpdate.type) {
if (historyUpdate.type === "push") {
pushUrlIntoHistory(historyUpdate.path);
triggerEvent(getDocument().body, 'htmx:pushedIntoHistory', {path: historyUpdate.path});
} else {
replaceUrlInHistory(pathToPush);
triggerEvent(getDocument().body, 'htmx:replacedInHistory', {path: pathToPush});
replaceUrlInHistory(historyUpdate.path);
triggerEvent(getDocument().body, 'htmx:replacedInHistory', {path: historyUpdate.path});
}
}
if (responseInfo.pathInfo.anchor) {
var anchorTarget = find("#" + responseInfo.pathInfo.anchor);
if(anchorTarget) {
anchorTarget.scrollIntoView({block:'start', behavior: "auto"});
}
}

View File

@ -1369,7 +1369,7 @@ return (function () {
var windowIsScrolling = false // used by initScrollHandler
var scrollHandler = null;
function initScrollHandler(handler) {
function initScrollHandler() {
if (!scrollHandler) {
scrollHandler = function() {
windowIsScrolling = true
@ -1379,22 +1379,22 @@ return (function () {
if (windowIsScrolling) {
windowIsScrolling = false;
forEach(getDocument().querySelectorAll("[hx-trigger='revealed'],[data-hx-trigger='revealed']"), function (elt) {
maybeReveal(elt, handler);
maybeReveal(elt);
})
}
}, 200);
}
}
function maybeReveal(elt, handler) {
function maybeReveal(elt) {
if (!hasAttribute(elt,'data-hx-revealed') && isScrolledIntoView(elt)) {
elt.setAttribute('data-hx-revealed', 'true');
var nodeData = getInternalData(elt);
if (nodeData.initialized) {
handler(elt);
triggerEvent(elt, 'revealed');
} else {
// if the node isn't initialized, wait for it before triggering the request
elt.addEventListener("htmx:afterProcessNode", function(evt) { handler(elt) }, {once: true});
elt.addEventListener("htmx:afterProcessNode", function(evt) { triggerEvent(elt, 'revealed') }, {once: true});
}
}
}
@ -1650,8 +1650,9 @@ return (function () {
if (triggerSpec.sseEvent) {
processSSETrigger(elt, handler, triggerSpec.sseEvent);
} else if (triggerSpec.trigger === "revealed") {
initScrollHandler(handler);
maybeReveal(elt, handler);
initScrollHandler();
addEventListener(elt, handler, nodeData, triggerSpec);
maybeReveal(elt);
} else if (triggerSpec.trigger === "intersect") {
var observerOptions = {};
if (triggerSpec.root) {
@ -2008,21 +2009,6 @@ return (function () {
}
}
function shouldPushUrl(elt) {
var pushUrl = getClosestAttributeValue(elt, "hx-push-url");
return (pushUrl && pushUrl !== "false") || (getInternalData(elt).boosted);
}
function shouldReplaceUrl(elt) {
var replaceUrl = getClosestAttributeValue(elt, "hx-replace-url");
return (replaceUrl && replaceUrl !== "false");
}
function getPushOrReplaceUrl(elt, type) {
var urlValue = getClosestAttributeValue(elt, "hx-" + type + "-url");
return (urlValue === "true" || urlValue === "false") ? null : urlValue;
}
function addRequestIndicatorClasses(elt) {
var indicators = findAttributeTargets(elt, 'hx-indicator');
if (indicators == null) {
@ -2506,7 +2492,7 @@ return (function () {
}
}
function getResponseURL(xhr) {
function getPathFromResponse(xhr) {
// NB: IE11 does not support this stuff
if (xhr.responseURL && typeof(URL) !== "undefined") {
try {
@ -2745,8 +2731,9 @@ return (function () {
var splitPath = path.split("#");
var pathNoAnchor = splitPath[0];
var anchor = splitPath[1];
var finalPathForGet = null;
if (verb === 'get') {
var finalPathForGet = pathNoAnchor;
finalPathForGet = pathNoAnchor;
var values = Object.keys(filteredParameters).length !== 0;
if (values) {
if (finalPathForGet.indexOf("?") < 0) {
@ -2780,14 +2767,19 @@ return (function () {
}
}
var responseInfo = {xhr: xhr, target: target, requestConfig: requestConfig, etc:etc, pathInfo:{
path:path, finalPath:finalPathForGet, anchor:anchor
var responseInfo = {
xhr: xhr, target: target, requestConfig: requestConfig, etc: etc,
pathInfo: {
requestPath: path,
finalRequestPath: path || finalPathForGet,
anchor: anchor
}
};
xhr.onload = function () {
try {
var hierarchy = hierarchyForElt(elt);
responseInfo.pathInfo.responsePath = getPathFromResponse(xhr);
responseHandler(elt, responseInfo);
removeRequestIndicatorClasses(indicators);
triggerEvent(elt, 'htmx:afterRequest', responseInfo);
@ -2858,6 +2850,88 @@ return (function () {
return promise;
}
function determineHistoryUpdates(elt, responseInfo) {
var xhr = responseInfo.xhr;
//===========================================
// First consult response headers
//===========================================
var pathFromHeaders = null;
var typeFromHeaders = null;
if (hasHeader(xhr,/HX-Push:/i)) {
pathFromHeaders = xhr.getResponseHeader("HX-Push");
typeFromHeaders = "push";
} else if (hasHeader(xhr,/HX-Push-Url:/i)) {
pathFromHeaders = xhr.getResponseHeader("HX-Push-Url");
typeFromHeaders = "push";
} else if (hasHeader(xhr,/HX-Replace-Url:/i)) {
pathFromHeaders = xhr.getResponseHeader("HX-Replace-Url");
typeFromHeaders = "replace";
}
// if there was a response header, that has priority
if (pathFromHeaders) {
if (pathFromHeaders === "false") {
return {}
} else {
return {
type: typeFromHeaders,
path : pathFromHeaders
}
}
}
//===========================================
// Next resolve via DOM values
//===========================================
var requestPath = responseInfo.pathInfo.finalRequestPath;
var responsePath = responseInfo.pathInfo.responsePath;
var pushUrl = getClosestAttributeValue(elt, "hx-push-url");
var replaceUrl = getClosestAttributeValue(elt, "hx-replace-url");
var elementIsBoosted = getInternalData(elt).boosted;
var saveType = null;
var path = null;
if (pushUrl) {
saveType = "push";
path = pushUrl;
} else if (replaceUrl) {
saveType = "replace";
path = replaceUrl;
} else if (elementIsBoosted) {
saveType = "push";
path = responsePath || requestPath; // if there is no response path, go with the original request path
}
if (path) {
// false indicates no push, return empty object
if (path === "false") {
return {};
}
// true indicates we want to follow wherever the server ended up sending us
if (path === "true") {
path = responsePath;
}
// restore any anchor associated with the request
if (responseInfo.pathInfo.anchor &&
path.indexOf("#") === -1) {
path = path + "#" + responseInfo.pathInfo.anchor;
}
return {
type:saveType,
path: path
}
} else {
return {};
}
}
function handleAjaxResponse(elt, responseInfo) {
var xhr = responseInfo.xhr;
var target = responseInfo.target;
@ -2869,17 +2943,6 @@ return (function () {
handleTrigger(xhr, "HX-Trigger", elt);
}
if (hasHeader(xhr,/HX-Push:/i)) {
var pushedUrl = xhr.getResponseHeader("HX-Push");
}
if (hasHeader(xhr,/HX-Push-Url:/i)) {
var pushedUrl = xhr.getResponseHeader("HX-Push-Url");
}
if (hasHeader(xhr,/HX-Replace-Url:/i)) {
var replacementUrl = xhr.getResponseHeader("HX-Replace-Url");
}
if (hasHeader(xhr, /HX-Location:/i)) {
saveCurrentPageToHistory();
var redirectPath = xhr.getResponseHeader("HX-Location");
@ -2897,7 +2960,7 @@ return (function () {
}
if (hasHeader(xhr, /HX-Redirect:/i)) {
window.location.href = xhr.getResponseHeader("HX-Redirect");
location.href = xhr.getResponseHeader("HX-Redirect");
return;
}
@ -2912,14 +2975,7 @@ return (function () {
responseInfo.target = getDocument().querySelector(xhr.getResponseHeader("HX-Retarget"));
}
/** @type {boolean} */
var historySaveType;
if ((pushedUrl && pushedUrl !== "false") || shouldPushUrl(elt)) {
historySaveType = "push";
}
if ((replacementUrl && replacementUrl !== "false") || shouldReplaceUrl(elt)) {
historySaveType = "replace";
}
var historyUpdate = determineHistoryUpdates(elt, responseInfo);
// by default htmx only swaps on 200 return codes and does not swap
// on 204 'No Content'
@ -2948,7 +3004,7 @@ return (function () {
});
// Save current page
if (historySaveType) {
if (historyUpdate) {
saveCurrentPageToHistory();
}
@ -3001,9 +3057,6 @@ return (function () {
}
triggerEvent(elt, 'htmx:afterSwap', responseInfo);
});
if (responseInfo.pathInfo.anchor) {
location.hash = responseInfo.pathInfo.anchor;
}
if (hasHeader(xhr, /HX-Trigger-After-Swap:/i)) {
var finalElt = elt;
@ -3023,16 +3076,21 @@ return (function () {
}
triggerEvent(elt, 'htmx:afterSettle', responseInfo);
});
// push URL and save new page
if (historySaveType) {
var pathToPush = pushedUrl || getPushOrReplaceUrl(elt, "push") || getPushOrReplaceUrl(elt, "replace")
|| getResponseURL(xhr) || responseInfo.pathInfo.finalPath || responseInfo.pathInfo.path;
if (historySaveType === "push") {
pushUrlIntoHistory(pathToPush);
triggerEvent(getDocument().body, 'htmx:pushedIntoHistory', {path: pathToPush});
// if we need to save history, do so
if (historyUpdate.type) {
if (historyUpdate.type === "push") {
pushUrlIntoHistory(historyUpdate.path);
triggerEvent(getDocument().body, 'htmx:pushedIntoHistory', {path: historyUpdate.path});
} else {
replaceUrlInHistory(pathToPush);
triggerEvent(getDocument().body, 'htmx:replacedInHistory', {path: pathToPush});
replaceUrlInHistory(historyUpdate.path);
triggerEvent(getDocument().body, 'htmx:replacedInHistory', {path: historyUpdate.path});
}
}
if (responseInfo.pathInfo.anchor) {
var anchorTarget = find("#" + responseInfo.pathInfo.anchor);
if(anchorTarget) {
anchorTarget.scrollIntoView({block:'start', behavior: "auto"});
}
}

View File

@ -732,6 +732,21 @@ describe("hx-trigger attribute", function(){
div.innerHTML.should.equal("Load Me!");
});
it('reveal event works on two elements', function()
{
this.server.respondWith("GET", "/test1", "test 1");
this.server.respondWith("GET", "/test2", "test 2");
var div = make('<div hx-get="/test1" hx-trigger="revealed"></div>');
var div2 = make('<div hx-get="/test2" hx-trigger="revealed"></div>');
div.innerHTML.should.equal("");
div2.innerHTML.should.equal("");
htmx.trigger(div, 'revealed')
htmx.trigger(div2, 'revealed')
this.server.respondAll();
div.innerHTML.should.equal("test 1");
div2.innerHTML.should.equal("test 2");
});
})

View File

@ -0,0 +1,19 @@
<div style="height: 800px;background-color: blue">
</div>
<h1 id="anchor1">Anchor 1</h1>
<div style="height: 800px;background-color: blue">
</div>
<h1 id="anchor2">Anchor 2</h1>
<div style="height: 800px;background-color: blue">
</div>
<h1 id="anchor3">Anchor 3</h1>
<div style="height: 800px;background-color: blue">
</div>
<h1 id="anchor4">Anchor 4</h1>
<div style="height: 1800px;background-color: blue">
</div>

View File

@ -0,0 +1,13 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Test if indicators are invisible by default</title>
<script src="../../../src/htmx.js"></script>
</head>
<body style="padding:20px;font-family: sans-serif">
<a hx-boost="true" href="has-anchors.html#anchor1">Anchor 1</a>
<button hx-push-url="true" hx-get="has-anchors.html#anchor2" hx-target="body">Anchor 2</button>
</body>

View File

@ -30,6 +30,7 @@
<li><a href="history_refresh">History Refresh Test</a></li>
<li><a href="restored">Restored Test</a></li>
<li><a href="history_regression">Navigate, Refresh, Back Regression</a></li>
<li><a href="anchors">Anchors</a></li>
</ul>
</li>
</ul>