mirror of
https://github.com/bigskysoftware/htmx.git
synced 2025-10-03 07:45:21 +00:00
fix www generation
This commit is contained in:
parent
d1ffd58ae6
commit
cb52f71cd2
@ -14,9 +14,9 @@ fs.copySync("node_modules/sinon/pkg/sinon.js", currentReleaseRoot + "/node_modul
|
|||||||
fs.copySync("node_modules/mock-socket/dist/mock-socket.js", currentReleaseRoot + "/node_modules/mock-socket/dist/mock-socket.js");
|
fs.copySync("node_modules/mock-socket/dist/mock-socket.js", currentReleaseRoot + "/node_modules/mock-socket/dist/mock-socket.js");
|
||||||
fs.copySync("test/", currentReleaseRoot + "/test");
|
fs.copySync("test/", currentReleaseRoot + "/test");
|
||||||
fs.copySync("src/", currentReleaseRoot + "/src");
|
fs.copySync("src/", currentReleaseRoot + "/src");
|
||||||
fs.copySync("src/htmx.js", "www/js/htmx.js");
|
fs.copySync("src/htmx.js", "www/themes/htmx-theme/static/js/htmx.js");
|
||||||
fs.copySync("src/ext/class-tools.js", "www/js/class-tools.js");
|
fs.copySync("src/ext/class-tools.js", "www/themes/htmx-theme/static/js/class-tools.js");
|
||||||
fs.copySync("src/ext/preload.js", "www/js/preload.js");
|
fs.copySync("src/ext/preload.js", "www/themes/htmx-theme/static/js/preload.js");
|
||||||
|
|
||||||
var testHTML = "<html><body style='font-family: sans-serif'><h1>HTMX TESTS</h1><ul>\n"
|
var testHTML = "<html><body style='font-family: sans-serif'><h1>HTMX TESTS</h1><ul>\n"
|
||||||
fs.readdirSync(testRoot).reverse().forEach(function (file) {
|
fs.readdirSync(testRoot).reverse().forEach(function (file) {
|
||||||
|
@ -1,92 +0,0 @@
|
|||||||
(function () {
|
|
||||||
|
|
||||||
function splitOnWhitespace(trigger) {
|
|
||||||
return trigger.split(/\s+/);
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseClassOperation(trimmedValue) {
|
|
||||||
var split = splitOnWhitespace(trimmedValue);
|
|
||||||
if (split.length > 1) {
|
|
||||||
var operation = split[0];
|
|
||||||
var classDef = split[1].trim();
|
|
||||||
var cssClass;
|
|
||||||
var delay;
|
|
||||||
if (classDef.indexOf(":") > 0) {
|
|
||||||
var splitCssClass = classDef.split(':');
|
|
||||||
cssClass = splitCssClass[0];
|
|
||||||
delay = htmx.parseInterval(splitCssClass[1]);
|
|
||||||
} else {
|
|
||||||
cssClass = classDef;
|
|
||||||
delay = 100;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
operation: operation,
|
|
||||||
cssClass: cssClass,
|
|
||||||
delay: delay
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function performOperation(elt, classOperation, classList, currentRunTime) {
|
|
||||||
setTimeout(function () {
|
|
||||||
elt.classList[classOperation.operation].call(elt.classList, classOperation.cssClass);
|
|
||||||
}, currentRunTime)
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleOperation(elt, classOperation, classList, currentRunTime) {
|
|
||||||
setTimeout(function () {
|
|
||||||
setInterval(function () {
|
|
||||||
elt.classList[classOperation.operation].call(elt.classList, classOperation.cssClass);
|
|
||||||
}, classOperation.delay);
|
|
||||||
}, currentRunTime)
|
|
||||||
}
|
|
||||||
|
|
||||||
function processClassList(elt, classList) {
|
|
||||||
var runs = classList.split("&");
|
|
||||||
for (var i = 0; i < runs.length; i++) {
|
|
||||||
var run = runs[i];
|
|
||||||
var currentRunTime = 0;
|
|
||||||
var classOperations = run.split(",");
|
|
||||||
for (var j = 0; j < classOperations.length; j++) {
|
|
||||||
var value = classOperations[j];
|
|
||||||
var trimmedValue = value.trim();
|
|
||||||
var classOperation = parseClassOperation(trimmedValue);
|
|
||||||
if (classOperation) {
|
|
||||||
if (classOperation.operation === "toggle") {
|
|
||||||
toggleOperation(elt, classOperation, classList, currentRunTime);
|
|
||||||
currentRunTime = currentRunTime + classOperation.delay;
|
|
||||||
} else {
|
|
||||||
currentRunTime = currentRunTime + classOperation.delay;
|
|
||||||
performOperation(elt, classOperation, classList, currentRunTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function maybeProcessClasses(elt) {
|
|
||||||
if (elt.getAttribute) {
|
|
||||||
var classList = elt.getAttribute("classes") || elt.getAttribute("data-classes");
|
|
||||||
if (classList) {
|
|
||||||
processClassList(elt, classList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
htmx.defineExtension('class-tools', {
|
|
||||||
onEvent: function (name, evt) {
|
|
||||||
if (name === "htmx:afterProcessNode") {
|
|
||||||
var elt = evt.detail.elt;
|
|
||||||
maybeProcessClasses(elt);
|
|
||||||
if (elt.querySelectorAll) {
|
|
||||||
var children = elt.querySelectorAll("[classes], [data-classes]");
|
|
||||||
for (var i = 0; i < children.length; i++) {
|
|
||||||
maybeProcessClasses(children[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})();
|
|
3538
www/js/htmx.js
3538
www/js/htmx.js
File diff suppressed because it is too large
Load Diff
@ -1,144 +0,0 @@
|
|||||||
// This adds the "preload" extension to htmx. By default, this will
|
|
||||||
// preload the targets of any tags with `href` or `hx-get` attributes
|
|
||||||
// if they also have a `preload` attribute as well. See documentation
|
|
||||||
// for more details
|
|
||||||
htmx.defineExtension("preload", {
|
|
||||||
|
|
||||||
onEvent: function(name, event) {
|
|
||||||
|
|
||||||
// Only take actions on "htmx:afterProcessNode"
|
|
||||||
if (name !== "htmx:afterProcessNode") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SOME HELPER FUNCTIONS WE'LL NEED ALONG THE WAY
|
|
||||||
|
|
||||||
// attr gets the closest non-empty value from the attribute.
|
|
||||||
var attr = function(node, property) {
|
|
||||||
if (node == undefined) {return undefined;}
|
|
||||||
return node.getAttribute(property) || node.getAttribute("data-" + property) || attr(node.parentElement, property)
|
|
||||||
}
|
|
||||||
|
|
||||||
// load handles the actual HTTP fetch, and uses htmx.ajax in cases where we're
|
|
||||||
// preloading an htmx resource (this sends the same HTTP headers as a regular htmx request)
|
|
||||||
var load = function(node) {
|
|
||||||
|
|
||||||
// Called after a successful AJAX request, to mark the
|
|
||||||
// content as loaded (and prevent additional AJAX calls.)
|
|
||||||
var done = function(html) {
|
|
||||||
if (!node.preloadAlways) {
|
|
||||||
node.preloadState = "DONE"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attr(node, "preload-images") == "true") {
|
|
||||||
document.createElement("div").innerHTML = html // create and populate a node to load linked resources, too.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return function() {
|
|
||||||
|
|
||||||
// If this value has already been loaded, then do not try again.
|
|
||||||
if (node.preloadState !== "READY") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Special handling for HX-GET - use built-in htmx.ajax function
|
|
||||||
// so that headers match other htmx requests, then set
|
|
||||||
// node.preloadState = TRUE so that requests are not duplicated
|
|
||||||
// in the future
|
|
||||||
var hxGet = node.getAttribute("hx-get") || node.getAttribute("data-hx-get")
|
|
||||||
if (hxGet) {
|
|
||||||
htmx.ajax("GET", hxGet, {handler:function(elt, info) {
|
|
||||||
done(info.xhr.responseText);
|
|
||||||
}});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, perform a standard xhr request, then set
|
|
||||||
// node.preloadState = TRUE so that requests are not duplicated
|
|
||||||
// in the future.
|
|
||||||
if (node.getAttribute("href")) {
|
|
||||||
var r = new XMLHttpRequest();
|
|
||||||
r.open("GET", node.getAttribute("href"));
|
|
||||||
r.onload = function() {done(r.responseText);};
|
|
||||||
r.send();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function processes a specific node and sets up event handlers.
|
|
||||||
// We'll search for nodes and use it below.
|
|
||||||
var init = function(node) {
|
|
||||||
|
|
||||||
// If this node DOES NOT include a "GET" transaction, then there's nothing to do here.
|
|
||||||
if (node.getAttribute("href") + node.getAttribute("hx-get") + node.getAttribute("data-hx-get") == "") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Guarantee that we only initialize each node once.
|
|
||||||
if (node.preloadState !== undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get event name from config.
|
|
||||||
var on = attr(node, "preload") || "mousedown"
|
|
||||||
const always = on.indexOf("always") !== -1
|
|
||||||
if (always) {
|
|
||||||
on = on.replace('always', '').trim()
|
|
||||||
}
|
|
||||||
|
|
||||||
// FALL THROUGH to here means we need to add an EventListener
|
|
||||||
|
|
||||||
// Apply the listener to the node
|
|
||||||
node.addEventListener(on, function(evt) {
|
|
||||||
if (node.preloadState === "PAUSE") { // Only add one event listener
|
|
||||||
node.preloadState = "READY"; // Requred for the `load` function to trigger
|
|
||||||
|
|
||||||
// Special handling for "mouseover" events. Wait 100ms before triggering load.
|
|
||||||
if (on === "mouseover") {
|
|
||||||
window.setTimeout(load(node), 100);
|
|
||||||
} else {
|
|
||||||
load(node)() // all other events trigger immediately.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Special handling for certain built-in event handlers
|
|
||||||
switch (on) {
|
|
||||||
|
|
||||||
case "mouseover":
|
|
||||||
// Mirror `touchstart` events (fires immediately)
|
|
||||||
node.addEventListener("touchstart", load(node));
|
|
||||||
|
|
||||||
// WHhen the mouse leaves, immediately disable the preload
|
|
||||||
node.addEventListener("mouseout", function(evt) {
|
|
||||||
if ((evt.target === node) && (node.preloadState === "READY")) {
|
|
||||||
node.preloadState = "PAUSE";
|
|
||||||
}
|
|
||||||
})
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "mousedown":
|
|
||||||
// Mirror `touchstart` events (fires immediately)
|
|
||||||
node.addEventListener("touchstart", load(node));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark the node as ready to run.
|
|
||||||
node.preloadState = "PAUSE";
|
|
||||||
node.preloadAlways = always;
|
|
||||||
htmx.trigger(node, "preload:init") // This event can be used to load content immediately.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search for all child nodes that have a "preload" attribute
|
|
||||||
event.target.querySelectorAll("[preload]").forEach(function(node) {
|
|
||||||
|
|
||||||
// Initialize the node with the "preload" attribute
|
|
||||||
init(node)
|
|
||||||
|
|
||||||
// Initialize all child elements that are anchors or have `hx-get` (use with care)
|
|
||||||
node.querySelectorAll("a,[hx-get],[data-hx-get]").forEach(init)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
@ -155,6 +155,10 @@ This extension adds support for Server Sent Events to htmx. See /www/extensions
|
|||||||
}, timeout);
|
}, timeout);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
source.onopen = function (evt) {
|
||||||
|
api.triggerEvent(elt, "htmx::sseOpen", {source: source});
|
||||||
|
}
|
||||||
|
|
||||||
// Add message handlers for every `sse-swap` attribute
|
// Add message handlers for every `sse-swap` attribute
|
||||||
queryAttributeOnThisOrChildren(elt, "sse-swap").forEach(function(child) {
|
queryAttributeOnThisOrChildren(elt, "sse-swap").forEach(function(child) {
|
||||||
|
@ -433,6 +433,23 @@ return (function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizePath(path) {
|
||||||
|
try {
|
||||||
|
var url = new URL(path);
|
||||||
|
if (url) {
|
||||||
|
path = url.pathname + url.search;
|
||||||
|
}
|
||||||
|
// remove trailing slash, unless index page
|
||||||
|
if (!path.match('^/$')) {
|
||||||
|
path = path.replace(/\/+$/, '');
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
} catch (e) {
|
||||||
|
// be kind to IE11, which doesn't support URL()
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================================
|
//==========================================================================================
|
||||||
// public API
|
// public API
|
||||||
//==========================================================================================
|
//==========================================================================================
|
||||||
@ -1301,7 +1318,7 @@ return (function () {
|
|||||||
var verb, path;
|
var verb, path;
|
||||||
if (elt.tagName === "A") {
|
if (elt.tagName === "A") {
|
||||||
verb = "get";
|
verb = "get";
|
||||||
path = getRawAttribute(elt, 'href');
|
path = elt.href; // DOM property gives the fully resolved href of a relative link
|
||||||
} else {
|
} else {
|
||||||
var rawAttribute = getRawAttribute(elt, "method");
|
var rawAttribute = getRawAttribute(elt, "method");
|
||||||
verb = rawAttribute ? rawAttribute.toLowerCase() : "get";
|
verb = rawAttribute ? rawAttribute.toLowerCase() : "get";
|
||||||
@ -2037,6 +2054,8 @@ return (function () {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
url = normalizePath(url);
|
||||||
|
|
||||||
var historyCache = parseJSON(localStorage.getItem("htmx-history-cache")) || [];
|
var historyCache = parseJSON(localStorage.getItem("htmx-history-cache")) || [];
|
||||||
for (var i = 0; i < historyCache.length; i++) {
|
for (var i = 0; i < historyCache.length; i++) {
|
||||||
if (historyCache[i].url === url) {
|
if (historyCache[i].url === url) {
|
||||||
@ -2066,6 +2085,8 @@ return (function () {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
url = normalizePath(url);
|
||||||
|
|
||||||
var historyCache = parseJSON(localStorage.getItem("htmx-history-cache")) || [];
|
var historyCache = parseJSON(localStorage.getItem("htmx-history-cache")) || [];
|
||||||
for (var i = 0; i < historyCache.length; i++) {
|
for (var i = 0; i < historyCache.length; i++) {
|
||||||
if (historyCache[i].url === url) {
|
if (historyCache[i].url === url) {
|
||||||
|
@ -100,7 +100,8 @@ describe("hx-disinherit attribute", function() {
|
|||||||
var div = make('<div hx-boost="true" hx-disinherit="false"><a id="a1" href="/test">Click me</a></div>');
|
var div = make('<div hx-boost="true" hx-disinherit="false"><a id="a1" href="/test">Click me</a></div>');
|
||||||
var link = byId("a1");
|
var link = byId("a1");
|
||||||
link.click();
|
link.click();
|
||||||
should.equal(request.detail.requestConfig.path, '/test');
|
// should match the fully resolved href of the boosted element
|
||||||
|
should.equal(request.detail.requestConfig.path, request.detail.elt.href);
|
||||||
should.equal(request.detail.elt["htmx-internal-data"].boosted, true);
|
should.equal(request.detail.elt["htmx-internal-data"].boosted, true);
|
||||||
} finally {
|
} finally {
|
||||||
htmx.off("htmx:beforeRequest", handler);
|
htmx.off("htmx:beforeRequest", handler);
|
||||||
|
@ -70,6 +70,7 @@ return (function () {
|
|||||||
scrollBehavior: 'smooth',
|
scrollBehavior: 'smooth',
|
||||||
defaultFocusScroll: false,
|
defaultFocusScroll: false,
|
||||||
getCacheBusterParam: false,
|
getCacheBusterParam: false,
|
||||||
|
globalViewTransitions: false,
|
||||||
},
|
},
|
||||||
parseInterval:parseInterval,
|
parseInterval:parseInterval,
|
||||||
_:internalEval,
|
_:internalEval,
|
||||||
@ -81,7 +82,7 @@ return (function () {
|
|||||||
sock.binaryType = htmx.config.wsBinaryType;
|
sock.binaryType = htmx.config.wsBinaryType;
|
||||||
return sock;
|
return sock;
|
||||||
},
|
},
|
||||||
version: "1.8.6"
|
version: "1.9.0"
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @type {import("./htmx").HtmxInternalApi} */
|
/** @type {import("./htmx").HtmxInternalApi} */
|
||||||
@ -265,13 +266,18 @@ return (function () {
|
|||||||
return responseNode;
|
return responseNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function aFullPageResponse(resp) {
|
||||||
|
return resp.match(/<body/);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {string} resp
|
* @param {string} resp
|
||||||
* @returns {Element}
|
* @returns {Element}
|
||||||
*/
|
*/
|
||||||
function makeFragment(resp) {
|
function makeFragment(resp) {
|
||||||
if (htmx.config.useTemplateFragments) {
|
var partialResponse = !aFullPageResponse(resp);
|
||||||
|
if (htmx.config.useTemplateFragments && partialResponse) {
|
||||||
var documentFragment = parseHTML("<body><template>" + resp + "</template></body>", 0);
|
var documentFragment = parseHTML("<body><template>" + resp + "</template></body>", 0);
|
||||||
// @ts-ignore type mismatch between DocumentFragment and Element.
|
// @ts-ignore type mismatch between DocumentFragment and Element.
|
||||||
// TODO: Are these close enough for htmx to use interchangably?
|
// TODO: Are these close enough for htmx to use interchangably?
|
||||||
@ -427,6 +433,23 @@ return (function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizePath(path) {
|
||||||
|
try {
|
||||||
|
var url = new URL(path);
|
||||||
|
if (url) {
|
||||||
|
path = url.pathname + url.search;
|
||||||
|
}
|
||||||
|
// remove trailing slash, unless index page
|
||||||
|
if (!path.match('^/$')) {
|
||||||
|
path = path.replace(/\/+$/, '');
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
} catch (e) {
|
||||||
|
// be kind to IE11, which doesn't support URL()
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================================
|
//==========================================================================================
|
||||||
// public API
|
// public API
|
||||||
//==========================================================================================
|
//==========================================================================================
|
||||||
@ -471,7 +494,10 @@ return (function () {
|
|||||||
function removeElement(elt, delay) {
|
function removeElement(elt, delay) {
|
||||||
elt = resolveTarget(elt);
|
elt = resolveTarget(elt);
|
||||||
if (delay) {
|
if (delay) {
|
||||||
setTimeout(function(){removeElement(elt);}, delay)
|
setTimeout(function(){
|
||||||
|
removeElement(elt);
|
||||||
|
elt = null;
|
||||||
|
}, delay);
|
||||||
} else {
|
} else {
|
||||||
elt.parentElement.removeChild(elt);
|
elt.parentElement.removeChild(elt);
|
||||||
}
|
}
|
||||||
@ -480,7 +506,10 @@ return (function () {
|
|||||||
function addClassToElement(elt, clazz, delay) {
|
function addClassToElement(elt, clazz, delay) {
|
||||||
elt = resolveTarget(elt);
|
elt = resolveTarget(elt);
|
||||||
if (delay) {
|
if (delay) {
|
||||||
setTimeout(function(){addClassToElement(elt, clazz);}, delay)
|
setTimeout(function(){
|
||||||
|
addClassToElement(elt, clazz);
|
||||||
|
elt = null;
|
||||||
|
}, delay);
|
||||||
} else {
|
} else {
|
||||||
elt.classList && elt.classList.add(clazz);
|
elt.classList && elt.classList.add(clazz);
|
||||||
}
|
}
|
||||||
@ -489,7 +518,10 @@ return (function () {
|
|||||||
function removeClassFromElement(elt, clazz, delay) {
|
function removeClassFromElement(elt, clazz, delay) {
|
||||||
elt = resolveTarget(elt);
|
elt = resolveTarget(elt);
|
||||||
if (delay) {
|
if (delay) {
|
||||||
setTimeout(function(){removeClassFromElement(elt, clazz);}, delay)
|
setTimeout(function(){
|
||||||
|
removeClassFromElement(elt, clazz);
|
||||||
|
elt = null;
|
||||||
|
}, delay);
|
||||||
} else {
|
} else {
|
||||||
if (elt.classList) {
|
if (elt.classList) {
|
||||||
elt.classList.remove(clazz);
|
elt.classList.remove(clazz);
|
||||||
@ -530,21 +562,30 @@ return (function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeSelector(selector) {
|
||||||
|
var trimmedSelector = selector.trim();
|
||||||
|
if (trimmedSelector.startsWith("<") && trimmedSelector.endsWith("/>")) {
|
||||||
|
return trimmedSelector.substring(1, trimmedSelector.length - 2);
|
||||||
|
} else {
|
||||||
|
return trimmedSelector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function querySelectorAllExt(elt, selector) {
|
function querySelectorAllExt(elt, selector) {
|
||||||
if (selector.indexOf("closest ") === 0) {
|
if (selector.indexOf("closest ") === 0) {
|
||||||
return [closest(elt, selector.substr(8))];
|
return [closest(elt, normalizeSelector(selector.substr(8)))];
|
||||||
} else if (selector.indexOf("find ") === 0) {
|
} else if (selector.indexOf("find ") === 0) {
|
||||||
return [find(elt, selector.substr(5))];
|
return [find(elt, normalizeSelector(selector.substr(5)))];
|
||||||
} else if (selector.indexOf("next ") === 0) {
|
} else if (selector.indexOf("next ") === 0) {
|
||||||
return [scanForwardQuery(elt, selector.substr(5))];
|
return [scanForwardQuery(elt, normalizeSelector(selector.substr(5)))];
|
||||||
} else if (selector.indexOf("previous ") === 0) {
|
} else if (selector.indexOf("previous ") === 0) {
|
||||||
return [scanBackwardsQuery(elt, selector.substr(9))];
|
return [scanBackwardsQuery(elt, normalizeSelector(selector.substr(9)))];
|
||||||
} else if (selector === 'document') {
|
} else if (selector === 'document') {
|
||||||
return [document];
|
return [document];
|
||||||
} else if (selector === 'window') {
|
} else if (selector === 'window') {
|
||||||
return [window];
|
return [window];
|
||||||
} else {
|
} else {
|
||||||
return getDocument().querySelectorAll(selector);
|
return getDocument().querySelectorAll(normalizeSelector(selector));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -760,7 +801,7 @@ return (function () {
|
|||||||
var oobSelectValues = oobSelects.split(",");
|
var oobSelectValues = oobSelects.split(",");
|
||||||
for (let i = 0; i < oobSelectValues.length; i++) {
|
for (let i = 0; i < oobSelectValues.length; i++) {
|
||||||
var oobSelectValue = oobSelectValues[i].split(":", 2);
|
var oobSelectValue = oobSelectValues[i].split(":", 2);
|
||||||
var id = oobSelectValue[0];
|
var id = oobSelectValue[0].trim();
|
||||||
if (id.indexOf("#") === 0) {
|
if (id.indexOf("#") === 0) {
|
||||||
id = id.substring(1);
|
id = id.substring(1);
|
||||||
}
|
}
|
||||||
@ -793,7 +834,8 @@ return (function () {
|
|||||||
forEach(fragment.querySelectorAll("[id]"), function (newNode) {
|
forEach(fragment.querySelectorAll("[id]"), function (newNode) {
|
||||||
if (newNode.id && newNode.id.length > 0) {
|
if (newNode.id && newNode.id.length > 0) {
|
||||||
var normalizedId = newNode.id.replace("'", "\\'");
|
var normalizedId = newNode.id.replace("'", "\\'");
|
||||||
var oldNode = parentNode.querySelector(newNode.tagName + "[id='" + normalizedId + "']");
|
var normalizedTag = newNode.tagName.replace(':', '\\:');
|
||||||
|
var oldNode = parentNode.querySelector(normalizedTag + "[id='" + normalizedId + "']");
|
||||||
if (oldNode && oldNode !== parentNode) {
|
if (oldNode && oldNode !== parentNode) {
|
||||||
var newAttributes = newNode.cloneNode();
|
var newAttributes = newNode.cloneNode();
|
||||||
cloneAttributes(newNode, oldNode);
|
cloneAttributes(newNode, oldNode);
|
||||||
@ -862,6 +904,9 @@ return (function () {
|
|||||||
|
|
||||||
function deInitNode(element) {
|
function deInitNode(element) {
|
||||||
var internalData = getInternalData(element);
|
var internalData = getInternalData(element);
|
||||||
|
if (internalData.timeout) {
|
||||||
|
clearTimeout(internalData.timeout);
|
||||||
|
}
|
||||||
if (internalData.webSocket) {
|
if (internalData.webSocket) {
|
||||||
internalData.webSocket.close();
|
internalData.webSocket.close();
|
||||||
}
|
}
|
||||||
@ -875,6 +920,11 @@ return (function () {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (internalData.onHandlers) {
|
||||||
|
for (var eventName of internalData.onHandlers) {
|
||||||
|
element.removeEventListener(eventName, internalData.onHandlers[eventName]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function cleanUpElement(element) {
|
function cleanUpElement(element) {
|
||||||
@ -1268,7 +1318,7 @@ return (function () {
|
|||||||
var verb, path;
|
var verb, path;
|
||||||
if (elt.tagName === "A") {
|
if (elt.tagName === "A") {
|
||||||
verb = "get";
|
verb = "get";
|
||||||
path = getRawAttribute(elt, 'href');
|
path = elt.href; // DOM property gives the fully resolved href of a relative link
|
||||||
} else {
|
} else {
|
||||||
var rawAttribute = getRawAttribute(elt, "method");
|
var rawAttribute = getRawAttribute(elt, "method");
|
||||||
verb = rawAttribute ? rawAttribute.toLowerCase() : "get";
|
verb = rawAttribute ? rawAttribute.toLowerCase() : "get";
|
||||||
@ -1396,6 +1446,7 @@ return (function () {
|
|||||||
} else if (triggerSpec.delay) {
|
} else if (triggerSpec.delay) {
|
||||||
elementData.delayed = setTimeout(function() { handler(elt, evt) }, triggerSpec.delay);
|
elementData.delayed = setTimeout(function() { handler(elt, evt) }, triggerSpec.delay);
|
||||||
} else {
|
} else {
|
||||||
|
triggerEvent(elt, 'htmx:trigger')
|
||||||
handler(elt, evt);
|
handler(elt, evt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1688,6 +1739,13 @@ return (function () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (!explicitAction && hasAttribute(elt, 'hx-trigger')) {
|
||||||
|
explicitAction = true
|
||||||
|
triggerSpecs.forEach(function(triggerSpec) {
|
||||||
|
// For "naked" triggers, don't do anything at all
|
||||||
|
addTriggerHandler(elt, triggerSpec, nodeData, function () { })
|
||||||
|
})
|
||||||
|
}
|
||||||
return explicitAction;
|
return explicitAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1772,7 +1830,7 @@ return (function () {
|
|||||||
if (elt.querySelectorAll) {
|
if (elt.querySelectorAll) {
|
||||||
var boostedElts = hasChanceOfBeingBoosted() ? ", a, form" : "";
|
var boostedElts = hasChanceOfBeingBoosted() ? ", a, form" : "";
|
||||||
var results = elt.querySelectorAll(VERB_SELECTOR + boostedElts + ", [hx-sse], [data-hx-sse], [hx-ws]," +
|
var results = elt.querySelectorAll(VERB_SELECTOR + boostedElts + ", [hx-sse], [data-hx-sse], [hx-ws]," +
|
||||||
" [data-hx-ws], [hx-ext], [data-hx-ext]");
|
" [data-hx-ws], [hx-ext], [data-hx-ext], [hx-trigger], [data-hx-trigger], [hx-on], [data-hx-on]");
|
||||||
return results;
|
return results;
|
||||||
} else {
|
} else {
|
||||||
return [];
|
return [];
|
||||||
@ -1800,6 +1858,57 @@ return (function () {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function countCurlies(line) {
|
||||||
|
var tokens = tokenizeString(line);
|
||||||
|
var netCurlies = 0;
|
||||||
|
for (let i = 0; i < tokens.length; i++) {
|
||||||
|
const token = tokens[i];
|
||||||
|
if (token === "{") {
|
||||||
|
netCurlies++;
|
||||||
|
} else if (token === "}") {
|
||||||
|
netCurlies--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return netCurlies;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addHxOnEventHandler(elt, eventName, code) {
|
||||||
|
var nodeData = getInternalData(elt);
|
||||||
|
nodeData.onHandlers ||= {};
|
||||||
|
var func = new Function("event", code + "; return;");
|
||||||
|
var listener = elt.addEventListener(eventName, function (e) {
|
||||||
|
return func.call(elt, e);
|
||||||
|
});
|
||||||
|
nodeData.onHandlers[eventName] = listener;
|
||||||
|
return {nodeData, code, func, listener};
|
||||||
|
}
|
||||||
|
|
||||||
|
function processHxOn(elt) {
|
||||||
|
var hxOnValue = getAttributeValue(elt, 'hx-on');
|
||||||
|
if (hxOnValue) {
|
||||||
|
var handlers = {}
|
||||||
|
var lines = hxOnValue.split("\n");
|
||||||
|
var currentEvent = null;
|
||||||
|
var curlyCount = 0;
|
||||||
|
while (lines.length > 0) {
|
||||||
|
var line = lines.shift();
|
||||||
|
var match = line.match(/^\s*([a-zA-Z:\-]+:)(.*)/);
|
||||||
|
if (curlyCount === 0 && match) {
|
||||||
|
line.split(":")
|
||||||
|
currentEvent = match[1].slice(0, -1); // strip last colon
|
||||||
|
handlers[currentEvent] = match[2];
|
||||||
|
} else {
|
||||||
|
handlers[currentEvent] += line;
|
||||||
|
}
|
||||||
|
curlyCount += countCurlies(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var eventName in handlers) {
|
||||||
|
addHxOnEventHandler(elt, eventName, handlers[eventName]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function initNode(elt) {
|
function initNode(elt) {
|
||||||
if (elt.closest && elt.closest(htmx.config.disableSelector)) {
|
if (elt.closest && elt.closest(htmx.config.disableSelector)) {
|
||||||
return;
|
return;
|
||||||
@ -1812,6 +1921,8 @@ return (function () {
|
|||||||
// clean up any previously processed info
|
// clean up any previously processed info
|
||||||
deInitNode(elt);
|
deInitNode(elt);
|
||||||
|
|
||||||
|
processHxOn(elt);
|
||||||
|
|
||||||
triggerEvent(elt, "htmx:beforeProcessNode")
|
triggerEvent(elt, "htmx:beforeProcessNode")
|
||||||
|
|
||||||
if (elt.value) {
|
if (elt.value) {
|
||||||
@ -1943,6 +2054,8 @@ return (function () {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
url = normalizePath(url);
|
||||||
|
|
||||||
var historyCache = parseJSON(localStorage.getItem("htmx-history-cache")) || [];
|
var historyCache = parseJSON(localStorage.getItem("htmx-history-cache")) || [];
|
||||||
for (var i = 0; i < historyCache.length; i++) {
|
for (var i = 0; i < historyCache.length; i++) {
|
||||||
if (historyCache[i].url === url) {
|
if (historyCache[i].url === url) {
|
||||||
@ -1972,6 +2085,8 @@ return (function () {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
url = normalizePath(url);
|
||||||
|
|
||||||
var historyCache = parseJSON(localStorage.getItem("htmx-history-cache")) || [];
|
var historyCache = parseJSON(localStorage.getItem("htmx-history-cache")) || [];
|
||||||
for (var i = 0; i < historyCache.length; i++) {
|
for (var i = 0; i < historyCache.length; i++) {
|
||||||
if (historyCache[i].url === url) {
|
if (historyCache[i].url === url) {
|
||||||
@ -2396,6 +2511,9 @@ return (function () {
|
|||||||
if (modifier.indexOf("settle:") === 0) {
|
if (modifier.indexOf("settle:") === 0) {
|
||||||
swapSpec["settleDelay"] = parseInterval(modifier.substr(7));
|
swapSpec["settleDelay"] = parseInterval(modifier.substr(7));
|
||||||
}
|
}
|
||||||
|
if (modifier.indexOf("transition:") === 0) {
|
||||||
|
swapSpec["transition"] = modifier.substr(11) === "true";
|
||||||
|
}
|
||||||
if (modifier.indexOf("scroll:") === 0) {
|
if (modifier.indexOf("scroll:") === 0) {
|
||||||
var scrollSpec = modifier.substr(7);
|
var scrollSpec = modifier.substr(7);
|
||||||
var splitSpec = scrollSpec.split(":");
|
var splitSpec = scrollSpec.split(":");
|
||||||
@ -3127,9 +3245,13 @@ return (function () {
|
|||||||
var swapSpec = getSwapSpecification(elt, swapOverride);
|
var swapSpec = getSwapSpecification(elt, swapOverride);
|
||||||
|
|
||||||
target.classList.add(htmx.config.swappingClass);
|
target.classList.add(htmx.config.swappingClass);
|
||||||
|
|
||||||
|
// optional transition API promise callbacks
|
||||||
|
var settleResolve = null;
|
||||||
|
var settleReject = null;
|
||||||
|
|
||||||
var doSwap = function () {
|
var doSwap = function () {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
var activeElt = document.activeElement;
|
var activeElt = document.activeElement;
|
||||||
var selectionInfo = {};
|
var selectionInfo = {};
|
||||||
try {
|
try {
|
||||||
@ -3228,6 +3350,7 @@ return (function () {
|
|||||||
}
|
}
|
||||||
handleTrigger(xhr, "HX-Trigger-After-Settle", finalElt);
|
handleTrigger(xhr, "HX-Trigger-After-Settle", finalElt);
|
||||||
}
|
}
|
||||||
|
maybeCall(settleResolve);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (swapSpec.settleDelay > 0) {
|
if (swapSpec.settleDelay > 0) {
|
||||||
@ -3237,10 +3360,34 @@ return (function () {
|
|||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
triggerErrorEvent(elt, 'htmx:swapError', responseInfo);
|
triggerErrorEvent(elt, 'htmx:swapError', responseInfo);
|
||||||
|
maybeCall(settleReject);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var shouldTransition = htmx.config.globalViewTransitions
|
||||||
|
if(swapSpec.hasOwnProperty('transition')){
|
||||||
|
shouldTransition = swapSpec.transition;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(shouldTransition &&
|
||||||
|
triggerEvent(elt, 'htmx:beforeTransition', responseInfo) &&
|
||||||
|
typeof Promise !== "undefined" && document.startViewTransition){
|
||||||
|
var settlePromise = new Promise(function (_resolve, _reject) {
|
||||||
|
settleResolve = _resolve;
|
||||||
|
settleReject = _reject;
|
||||||
|
});
|
||||||
|
// wrap the original doSwap() in a call to startViewTransition()
|
||||||
|
var innerDoSwap = doSwap;
|
||||||
|
doSwap = function() {
|
||||||
|
document.startViewTransition(function () {
|
||||||
|
innerDoSwap();
|
||||||
|
return settlePromise;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (swapSpec.swapDelay > 0) {
|
if (swapSpec.swapDelay > 0) {
|
||||||
setTimeout(doSwap, swapSpec.swapDelay)
|
setTimeout(doSwap, swapSpec.swapDelay)
|
||||||
} else {
|
} else {
|
||||||
@ -3402,6 +3549,7 @@ return (function () {
|
|||||||
};
|
};
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
triggerEvent(body, 'htmx:load', {}); // give ready handlers a chance to load up before firing this event
|
triggerEvent(body, 'htmx:load', {}); // give ready handlers a chance to load up before firing this event
|
||||||
|
body = null; // kill reference for gc
|
||||||
}, 0);
|
}, 0);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user