mirror of
https://github.com/bigskysoftware/htmx.git
synced 2026-01-06 00:32:19 +00:00
1.8 release prep
This commit is contained in:
parent
de78dc0070
commit
83b60f41f1
176
dist/htmx.js
vendored
176
dist/htmx.js
vendored
@ -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
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.
10984
package-lock.json
generated
10984
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -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",
|
||||
|
||||
176
www/js/htmx.js
176
www/js/htmx.js
@ -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"});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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"});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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");
|
||||
});
|
||||
|
||||
|
||||
|
||||
})
|
||||
|
||||
19
www/test/1.8.0/test/manual/anchors/has-anchors.html
Normal file
19
www/test/1.8.0/test/manual/anchors/has-anchors.html
Normal 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>
|
||||
13
www/test/1.8.0/test/manual/anchors/index.html
Normal file
13
www/test/1.8.0/test/manual/anchors/index.html
Normal 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>
|
||||
@ -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>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user