mirror of
https://github.com/bigskysoftware/htmx.git
synced 2025-10-02 15:25:26 +00:00
192 lines
5.8 KiB
JavaScript
192 lines
5.8 KiB
JavaScript
//====================================
|
|
// Server setup
|
|
//====================================
|
|
var server = sinon.fakeServer.create();
|
|
server.fakeHTTPMethods = true;
|
|
server.getHTTPMethod = function (xhr) {
|
|
return xhr.requestHeaders['X-HTTP-Method-Override'] || xhr.method;
|
|
}
|
|
server.autoRespond = true;
|
|
server.autoRespondAfter = 80;
|
|
server.xhr.useFilters = true;
|
|
server.xhr.addFilter(function (method, url, async, username, password) {
|
|
return url === "/" || url.indexOf("http") === 0;
|
|
})
|
|
|
|
//====================================
|
|
// Request Handling
|
|
//====================================
|
|
|
|
function parseParams(str) {
|
|
var re = /([^&=]+)=?([^&]*)/g;
|
|
var decode = function (str) {
|
|
return decodeURIComponent(str.replace(/\+/g, ' '));
|
|
};
|
|
var params = {}, e;
|
|
if (str) {
|
|
if (str.substr(0, 1) == '?') {
|
|
str = str.substr(1);
|
|
}
|
|
while (e = re.exec(str)) {
|
|
var k = decode(e[1]);
|
|
var v = decode(e[2]);
|
|
if (params[k] !== undefined) {
|
|
if (!Array.isArray(params[k])) {
|
|
params[k] = [params[k]];
|
|
}
|
|
params[k].push(v);
|
|
} else {
|
|
params[k] = v;
|
|
}
|
|
}
|
|
}
|
|
return params;
|
|
}
|
|
|
|
function getQuery(url) {
|
|
var question = url.indexOf("?");
|
|
var hash = url.indexOf("#");
|
|
if (hash == -1 && question == -1) return "";
|
|
if (hash == -1) hash = url.length;
|
|
return question == -1 || hash == question + 1 ? url.substring(hash) :
|
|
url.substring(question + 1, hash);
|
|
}
|
|
|
|
function params(request) {
|
|
if (server.getHTTPMethod(request) == "GET") {
|
|
return parseParams(getQuery(request.url));
|
|
} else {
|
|
return parseParams(request.requestBody);
|
|
}
|
|
}
|
|
function headers(request) {
|
|
return request.getAllResponseHeaders().split("\r\n").filter(h => h.toLowerCase().startsWith("hx-")).map(h => h.split(": ")).reduce((acc, v) => ({ ...acc, [v[0]]: v[1] }), {})
|
|
}
|
|
|
|
//====================================
|
|
// Routing
|
|
//====================================
|
|
|
|
function init(path, response) {
|
|
onGet(path, response);
|
|
let content = response(null, {});
|
|
let canvas = document.getElementById("demo-canvas");
|
|
if (canvas) {
|
|
canvas.innerHTML = content;
|
|
pushActivityChip("Initial State", "init", demoInitialStateTemplate(content));
|
|
}
|
|
}
|
|
|
|
function onGet(path, response) {
|
|
server.respondWith("GET", path, function (request) {
|
|
let headers = {};
|
|
let body = response(request, params(request), headers);
|
|
request.respond(200, headers, body);
|
|
});
|
|
}
|
|
|
|
function onPut(path, response) {
|
|
server.respondWith("PUT", path, function (request) {
|
|
let headers = {};
|
|
let body = response(request, params(request), headers);
|
|
request.respond(200, headers, body);
|
|
});
|
|
}
|
|
|
|
function onPost(path, response) {
|
|
server.respondWith("POST", path, function (request) {
|
|
let headers = {};
|
|
let body = response(request, params(request), headers);
|
|
request.respond(200, headers, body);
|
|
});
|
|
}
|
|
|
|
function onDelete(path, response) {
|
|
server.respondWith("DELETE", path, function (request) {
|
|
let headers = {};
|
|
let body = response(request, params(request), headers);
|
|
request.respond(200, headers, body);
|
|
});
|
|
}
|
|
|
|
//====================================
|
|
// Activites
|
|
//====================================
|
|
|
|
var requestId = 0;
|
|
htmx.on("htmx:beforeSwap", function (event) {
|
|
if (document.getElementById("request-count")) {
|
|
requestId++;
|
|
pushActivityChip(`${server.getHTTPMethod(event.detail.xhr)} ${event.detail.xhr.url}`, `req-${requestId}`, demoResponseTemplate(event.detail));
|
|
document.getElementById("request-count").innerText = ": " + requestId;
|
|
}
|
|
});
|
|
|
|
function showTimelineEntry(id) {
|
|
var children = document.getElementById("demo-current-request").children;
|
|
for (var i = 0; i < children.length; i++) {
|
|
var child = children[i];
|
|
if (child.id == id) {
|
|
child.classList.remove('hide');
|
|
} else {
|
|
child.classList.add('hide');
|
|
}
|
|
}
|
|
var children = document.getElementById("demo-timeline").children;
|
|
for (var i = 0; i < children.length; i++) {
|
|
var child = children[i];
|
|
if (child.id == id + "-link") {
|
|
child.classList.add('active');
|
|
} else {
|
|
child.classList.remove('active');
|
|
}
|
|
}
|
|
}
|
|
|
|
function pushActivityChip(name, id, content) {
|
|
document.getElementById("demo-timeline").insertAdjacentHTML("afterbegin", `<li id="${id}-link"><a onclick="showTimelineEntry('${id}')" style="cursor: pointer">${name}</a></li>`);
|
|
if (content.length > 750) {
|
|
content = content.substr(0, 750) + "...";
|
|
}
|
|
var contentDiv = `<div id="${id}">${content}</div>`;
|
|
document.getElementById("demo-current-request").insertAdjacentHTML("afterbegin", contentDiv);
|
|
showTimelineEntry(id);
|
|
//Prism.highlightAll();
|
|
}
|
|
|
|
//====================================
|
|
// Templates
|
|
//====================================
|
|
|
|
function escapeHtml(string) {
|
|
var pre = document.createElement('pre');
|
|
var text = document.createTextNode(string);
|
|
pre.appendChild(text);
|
|
return pre.innerHTML;
|
|
}
|
|
|
|
function demoInitialStateTemplate(html) {
|
|
return `<span class="activity initial">
|
|
<b>HTML</b>
|
|
<pre class="language-html"><code class="language-html">${escapeHtml(html)}</code></pre>
|
|
</span>`
|
|
}
|
|
|
|
function demoResponseTemplate(details) {
|
|
return `<span class="activity response">
|
|
<div>
|
|
<b>${server.getHTTPMethod(details.xhr)}</b> ${details.xhr.url}
|
|
</div>
|
|
<div>
|
|
parameters: ${JSON.stringify(params(details.xhr))}
|
|
</div>
|
|
<div>
|
|
headers: ${JSON.stringify(headers(details.xhr))}
|
|
</div>
|
|
<div>
|
|
<b>Response</b>
|
|
<pre class="language-html"><code class="language-html">${escapeHtml(details.xhr.response)}</code> </pre>
|
|
</div>
|
|
</span>`;
|
|
}
|