mirror of
https://github.com/bigskysoftware/htmx.git
synced 2025-09-30 14:31:47 +00:00
history testing and rework
This commit is contained in:
parent
fe7b878952
commit
00e2249f0b
6
TODO.md
6
TODO.md
@ -7,19 +7,19 @@
|
||||
## TODOS
|
||||
|
||||
* Testing
|
||||
* history
|
||||
* polling
|
||||
* kt-boost
|
||||
* interval parsing
|
||||
* table elements in responses
|
||||
* scrolling/'revealed' event
|
||||
* checkbox inputs
|
||||
* history
|
||||
* kt-boost
|
||||
* kt-swap-oob (verify, chrome coverage tool bad?)
|
||||
* X-KT-Trigger response header
|
||||
* SSE stuff
|
||||
* kt-trigger delay
|
||||
* class operation parsing
|
||||
* class toggling
|
||||
* polling
|
||||
* transition model for content swaps
|
||||
|
||||
|
||||
|
69
dist/kutty.js
vendored
69
dist/kutty.js
vendored
@ -8,6 +8,21 @@ var kutty = kutty || (function () {
|
||||
// Utilities
|
||||
//====================================================================
|
||||
|
||||
function makeBrowserHistorySupport() {
|
||||
return {
|
||||
getFullPath: function () {
|
||||
return location.pathname + location.search;
|
||||
},
|
||||
getLocalStorage: function () {
|
||||
return localStorage;
|
||||
},
|
||||
getHistory: function () {
|
||||
return history;
|
||||
}
|
||||
};
|
||||
}
|
||||
var browserHistorySupport = makeBrowserHistorySupport();
|
||||
|
||||
function parseInterval(str) {
|
||||
if (str === "null" || str === "false" || str === "") {
|
||||
return null;
|
||||
@ -36,6 +51,10 @@ var kutty = kutty || (function () {
|
||||
function getDocument() {
|
||||
return document;
|
||||
}
|
||||
|
||||
function getBody() {
|
||||
return getDocument().body;
|
||||
}
|
||||
|
||||
function getClosestMatch(elt, condition) {
|
||||
if (condition(elt)) {
|
||||
@ -147,7 +166,7 @@ var kutty = kutty || (function () {
|
||||
}
|
||||
|
||||
function bodyContains(elt) {
|
||||
return getDocument().body.contains(elt);
|
||||
return getBody().contains(elt);
|
||||
}
|
||||
|
||||
function concat(arr1, arr2) {
|
||||
@ -179,7 +198,7 @@ var kutty = kutty || (function () {
|
||||
} else {
|
||||
var data = getInternalData(elt);
|
||||
if (data.boosted) {
|
||||
return getDocument().body;
|
||||
return getBody();
|
||||
} else {
|
||||
return elt;
|
||||
}
|
||||
@ -208,7 +227,7 @@ var kutty = kutty || (function () {
|
||||
settleTasks = settleTasks.concat(swapOuterHTML(target, fragment));
|
||||
} else {
|
||||
child.parentNode.removeChild(child);
|
||||
triggerEvent(getDocument().body, "oobErrorNoTarget.kutty", {content: child})
|
||||
triggerEvent(getBody(), "oobErrorNoTarget.kutty", {content: child})
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -665,14 +684,14 @@ var kutty = kutty || (function () {
|
||||
var target, event, listener;
|
||||
if (isFunction(arg1)) {
|
||||
ready(function(){
|
||||
target = getDocument().body;
|
||||
target = getBody();
|
||||
event = "all.kutty";
|
||||
listener = arg1;
|
||||
target.addEventListener(event, listener);
|
||||
})
|
||||
} else if (isFunction(arg2)) {
|
||||
ready(function () {
|
||||
target = getDocument().body;
|
||||
target = getBody();
|
||||
event = arg1;
|
||||
listener = arg2;
|
||||
target.addEventListener(event, listener);
|
||||
@ -690,7 +709,7 @@ var kutty = kutty || (function () {
|
||||
//====================================================================
|
||||
function getHistoryElement() {
|
||||
var historyElt = getDocument().querySelector('[kt-history-elt]');
|
||||
return historyElt || getDocument().body;
|
||||
return historyElt || getBody();
|
||||
}
|
||||
|
||||
function purgeOldestPaths(paths, historyTimestamps) {
|
||||
@ -702,32 +721,32 @@ var kutty = kutty || (function () {
|
||||
slot++;
|
||||
if (slot > 20) {
|
||||
delete historyTimestamps[path];
|
||||
localStorage.removeItem(path);
|
||||
browserHistorySupport.getLocalStorage().removeItem(path);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function bumpHistoryAccessDate(pathAndSearch) {
|
||||
var historyTimestamps = JSON.parse(localStorage.getItem("kt-history-timestamps")) || {};
|
||||
var historyTimestamps = JSON.parse(browserHistorySupport.getLocalStorage().getItem("kt-history-timestamps")) || {};
|
||||
historyTimestamps[pathAndSearch] = Date.now();
|
||||
var paths = Object.keys(historyTimestamps);
|
||||
if (paths.length > 20) {
|
||||
purgeOldestPaths(paths, historyTimestamps);
|
||||
}
|
||||
localStorage.setItem("kt-history-timestamps", JSON.stringify(historyTimestamps));
|
||||
browserHistorySupport.getLocalStorage().setItem("kt-history-timestamps", JSON.stringify(historyTimestamps));
|
||||
}
|
||||
|
||||
function saveHistory() {
|
||||
var elt = getHistoryElement();
|
||||
var pathAndSearch = location.pathname+location.search;
|
||||
triggerEvent(getDocument().body, "historyUpdate.kutty", {path:pathAndSearch, historyElt:elt});
|
||||
history.replaceState({}, getDocument().title, window.location.href);
|
||||
localStorage.setItem('kt-history:' + pathAndSearch, elt.innerHTML);
|
||||
var pathAndSearch = browserHistorySupport.getFullPath();
|
||||
triggerEvent(getBody(), "historyUpdate.kutty", {path:pathAndSearch, historyElt:elt});
|
||||
browserHistorySupport.getHistory().replaceState({}, getDocument().title);
|
||||
browserHistorySupport.getLocalStorage().setItem('kt-history:' + pathAndSearch, elt.innerHTML);
|
||||
bumpHistoryAccessDate(pathAndSearch);
|
||||
}
|
||||
|
||||
function pushUrlIntoHistory(url) {
|
||||
history.pushState({}, "", url );
|
||||
browserHistorySupport.getHistory().pushState({}, "", url );
|
||||
}
|
||||
|
||||
function settleImmediately(settleTasks) {
|
||||
@ -739,25 +758,25 @@ var kutty = kutty || (function () {
|
||||
function loadHistoryFromServer(pathAndSearch) {
|
||||
var request = new XMLHttpRequest();
|
||||
var details = {path: pathAndSearch, xhr:request};
|
||||
triggerEvent(getDocument().body, "historyCacheMiss.kutty", details);
|
||||
triggerEvent(getBody(), "historyCacheMiss.kutty", details);
|
||||
request.open('GET', pathAndSearch, true);
|
||||
request.onload = function () {
|
||||
if (this.status >= 200 && this.status < 400) {
|
||||
triggerEvent(getDocument().body, "historyCacheMissLoad.kutty", details);
|
||||
triggerEvent(getBody(), "historyCacheMissLoad.kutty", details);
|
||||
var fragment = makeFragment(this.response);
|
||||
fragment = fragment.querySelector('[kt-history-elt]') || fragment;
|
||||
settleImmediately(swapInnerHTML(getHistoryElement(), fragment));
|
||||
} else {
|
||||
triggerEvent(getDocument().body, "historyCacheMissLoadError.kutty", details);
|
||||
triggerEvent(getBody(), "historyCacheMissLoadError.kutty", details);
|
||||
}
|
||||
};
|
||||
request.send();
|
||||
}
|
||||
|
||||
function restoreHistory() {
|
||||
var pathAndSearch = location.pathname+location.search;
|
||||
triggerEvent(getDocument().body, "historyRestore.kutty", {path:pathAndSearch});
|
||||
var content = localStorage.getItem('kt-history:' + pathAndSearch);
|
||||
var pathAndSearch = browserHistorySupport.getFullPath();
|
||||
triggerEvent(getBody(), "historyRestore.kutty", {path:pathAndSearch});
|
||||
var content = browserHistorySupport.getLocalStorage().getItem('kt-history:' + pathAndSearch);
|
||||
if (content) {
|
||||
bumpHistoryAccessDate(pathAndSearch);
|
||||
settleImmediately(swapInnerHTML(getHistoryElement(), makeFragment(content)));
|
||||
@ -1138,7 +1157,7 @@ var kutty = kutty || (function () {
|
||||
|
||||
// initialize the document
|
||||
ready(function () {
|
||||
var body = getDocument().body;
|
||||
var body = getBody();
|
||||
processNode(body);
|
||||
triggerEvent(body, 'load.kutty', {});
|
||||
window.onpopstate = function () {
|
||||
@ -1164,6 +1183,14 @@ var kutty = kutty || (function () {
|
||||
}
|
||||
}
|
||||
|
||||
function setBrowserHistorySupport(mock) {
|
||||
browserHistorySupport = mock;
|
||||
}
|
||||
|
||||
function restoreBrowserHistorySupport() {
|
||||
browserHistorySupport = browserHistorySupport();
|
||||
}
|
||||
|
||||
// Public API
|
||||
return {
|
||||
processElement: processNode,
|
||||
|
2
dist/kutty.min.js
vendored
2
dist/kutty.min.js
vendored
File diff suppressed because one or more lines are too long
BIN
dist/kutty.min.js.gz
vendored
BIN
dist/kutty.min.js.gz
vendored
Binary file not shown.
107
src/kutty.js
107
src/kutty.js
@ -1,5 +1,5 @@
|
||||
// noinspection JSUnusedAssignment
|
||||
var kutty = kutty || (function () {
|
||||
var kutty = (function () {
|
||||
'use strict';
|
||||
|
||||
var VERBS = ['get', 'post', 'put', 'delete', 'patch']
|
||||
@ -60,7 +60,7 @@ var kutty = kutty || (function () {
|
||||
var matchesFunction = elt.matches ||
|
||||
elt.matchesSelector || elt.msMatchesSelector || elt.mozMatchesSelector
|
||||
|| elt.webkitMatchesSelector || elt.oMatchesSelector;
|
||||
return (elt != null) && matchesFunction != null && matchesFunction.call(elt, selector);
|
||||
return matchesFunction && matchesFunction.call(elt, selector);
|
||||
}
|
||||
|
||||
function closest(elt, selector) {
|
||||
@ -395,7 +395,7 @@ var kutty = kutty || (function () {
|
||||
}
|
||||
}
|
||||
|
||||
function processClassList(elt, classList, operation) {
|
||||
function processClassList(elt, classList) {
|
||||
forEach(classList.split("&"), function (run) {
|
||||
var currentRunTime = 0;
|
||||
forEach(run.split(","), function(value){
|
||||
@ -688,46 +688,49 @@ var kutty = kutty || (function () {
|
||||
//====================================================================
|
||||
// History Support
|
||||
//====================================================================
|
||||
var currentPathForHistory = null;
|
||||
|
||||
function getHistoryElement() {
|
||||
var historyElt = getDocument().querySelector('[kt-history-elt]');
|
||||
return historyElt || getDocument().body;
|
||||
}
|
||||
|
||||
function purgeOldestPaths(paths, historyTimestamps) {
|
||||
paths = paths.sort(function (path1, path2) {
|
||||
return historyTimestamps[path2] - historyTimestamps[path1]
|
||||
});
|
||||
var slot = 0;
|
||||
forEach(paths, function (path) {
|
||||
slot++;
|
||||
if (slot > 20) {
|
||||
delete historyTimestamps[path];
|
||||
localStorage.removeItem(path);
|
||||
function saveToHistoryCache(url, content, title, scroll) {
|
||||
var historyCache = JSON.parse(localStorage.getItem("kutty-history-cache")) || [];
|
||||
for (var i = 0; i < historyCache.length; i++) {
|
||||
if (historyCache[i].url === url) {
|
||||
historyCache = historyCache.slice(i, 1);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
historyCache.push({url:url, content: content, title:title, scroll:scroll})
|
||||
while (historyCache.length > kutty.config.historyCacheSize) {
|
||||
historyCache.shift();
|
||||
}
|
||||
localStorage.setItem("kutty-history-cache", JSON.stringify(historyCache));
|
||||
}
|
||||
|
||||
function bumpHistoryAccessDate(pathAndSearch) {
|
||||
var historyTimestamps = JSON.parse(localStorage.getItem("kt-history-timestamps")) || {};
|
||||
historyTimestamps[pathAndSearch] = Date.now();
|
||||
var paths = Object.keys(historyTimestamps);
|
||||
if (paths.length > 20) {
|
||||
purgeOldestPaths(paths, historyTimestamps);
|
||||
function getCachedHistory(url) {
|
||||
var historyCache = JSON.parse(localStorage.getItem("kutty-history-cache")) || [];
|
||||
for (var i = 0; i < historyCache.length; i++) {
|
||||
if (historyCache[i].url === url) {
|
||||
return historyCache[i];
|
||||
}
|
||||
}
|
||||
localStorage.setItem("kt-history-timestamps", JSON.stringify(historyTimestamps));
|
||||
return null;
|
||||
}
|
||||
|
||||
function saveHistory() {
|
||||
var elt = getHistoryElement();
|
||||
var pathAndSearch = location.pathname+location.search;
|
||||
triggerEvent(getDocument().body, "historyUpdate.kutty", {path:pathAndSearch, historyElt:elt});
|
||||
history.replaceState({}, getDocument().title, window.location.href);
|
||||
localStorage.setItem('kt-history:' + pathAndSearch, elt.innerHTML);
|
||||
bumpHistoryAccessDate(pathAndSearch);
|
||||
var path = currentPathForHistory || location.pathname+location.search;
|
||||
triggerEvent(getDocument().body, "beforeHistorySave.kutty", {path:path, historyElt:elt});
|
||||
if(kutty.config.historyEnabled) history.replaceState({}, getDocument().title, window.location.href);
|
||||
saveToHistoryCache(path, elt.innerHTML, getDocument().title, window.scrollY);
|
||||
}
|
||||
|
||||
function pushUrlIntoHistory(url) {
|
||||
history.pushState({}, "", url );
|
||||
function pushUrlIntoHistory(path) {
|
||||
if(kutty.config.historyEnabled) history.pushState({}, "", path);
|
||||
currentPathForHistory = path;
|
||||
}
|
||||
|
||||
function settleImmediately(settleTasks) {
|
||||
@ -736,17 +739,18 @@ var kutty = kutty || (function () {
|
||||
});
|
||||
}
|
||||
|
||||
function loadHistoryFromServer(pathAndSearch) {
|
||||
function loadHistoryFromServer(path) {
|
||||
var request = new XMLHttpRequest();
|
||||
var details = {path: pathAndSearch, xhr:request};
|
||||
var details = {path: path, xhr:request};
|
||||
triggerEvent(getDocument().body, "historyCacheMiss.kutty", details);
|
||||
request.open('GET', pathAndSearch, true);
|
||||
request.open('GET', path, true);
|
||||
request.onload = function () {
|
||||
if (this.status >= 200 && this.status < 400) {
|
||||
triggerEvent(getDocument().body, "historyCacheMissLoad.kutty", details);
|
||||
var fragment = makeFragment(this.response);
|
||||
fragment = fragment.querySelector('[kt-history-elt]') || fragment;
|
||||
settleImmediately(swapInnerHTML(getHistoryElement(), fragment));
|
||||
currentPathForHistory = path;
|
||||
} else {
|
||||
triggerEvent(getDocument().body, "historyCacheMissLoadError.kutty", details);
|
||||
}
|
||||
@ -754,15 +758,18 @@ var kutty = kutty || (function () {
|
||||
request.send();
|
||||
}
|
||||
|
||||
function restoreHistory() {
|
||||
var pathAndSearch = location.pathname+location.search;
|
||||
triggerEvent(getDocument().body, "historyRestore.kutty", {path:pathAndSearch});
|
||||
var content = localStorage.getItem('kt-history:' + pathAndSearch);
|
||||
if (content) {
|
||||
bumpHistoryAccessDate(pathAndSearch);
|
||||
settleImmediately(swapInnerHTML(getHistoryElement(), makeFragment(content)));
|
||||
function restoreHistory(path) {
|
||||
saveHistory(currentPathForHistory);
|
||||
path = path || location.pathname+location.search;
|
||||
triggerEvent(getDocument().body, "historyRestore.kutty", {path:path});
|
||||
var cached = getCachedHistory(path);
|
||||
if (cached) {
|
||||
settleImmediately(swapInnerHTML(getHistoryElement(), makeFragment(cached.content)));
|
||||
document.title = cached.title;
|
||||
window.scrollTo(0, cached.scroll);
|
||||
currentPathForHistory = path;
|
||||
} else {
|
||||
loadHistoryFromServer(pathAndSearch);
|
||||
loadHistoryFromServer(path);
|
||||
}
|
||||
}
|
||||
|
||||
@ -958,9 +965,9 @@ var kutty = kutty || (function () {
|
||||
function getSwapSpecification(elt) {
|
||||
var swapInfo = getClosestAttributeValue(elt, "kt-swap");
|
||||
var swapSpec = {
|
||||
"swapStyle" : "innerHTML",
|
||||
"swapDelay" : 0,
|
||||
"settleDelay" : 100
|
||||
"swapStyle" : kutty.config.defaultSwapStyle,
|
||||
"swapDelay" : kutty.config.defaultSwapDelay,
|
||||
"settleDelay" : kutty.config.defaultSettleDelay
|
||||
}
|
||||
if (swapInfo) {
|
||||
var split = splitOnWhitespace(swapInfo);
|
||||
@ -1075,7 +1082,6 @@ var kutty = kutty || (function () {
|
||||
// push URL and save new page
|
||||
if (shouldSaveHistory) {
|
||||
pushUrlIntoHistory(pushedUrl || requestURL );
|
||||
saveHistory();
|
||||
}
|
||||
triggerEvent(elt, 'afterSettle.kutty', eventDetail);
|
||||
}
|
||||
@ -1136,8 +1142,19 @@ var kutty = kutty || (function () {
|
||||
addRule(".kutty-request .kutty-indicator{opacity:1}");
|
||||
addRule(".kutty-request.kutty-indicator{opacity:1}");
|
||||
|
||||
function getConfig() {
|
||||
return Object.assign({
|
||||
historyEnabled:true,
|
||||
historyCacheSize:10,
|
||||
defaultSwapStyle:'innerHTML',
|
||||
defaultSwapDelay:0,
|
||||
defaultSettleDelay:100
|
||||
}, JSON.parse(getDocument().querySelector('meta[name="kutty-config"]').content))
|
||||
}
|
||||
|
||||
// initialize the document
|
||||
ready(function () {
|
||||
kutty.config = getConfig();
|
||||
var body = getDocument().body;
|
||||
processNode(body);
|
||||
triggerEvent(body, 'load.kutty', {});
|
||||
@ -1170,8 +1187,10 @@ var kutty = kutty || (function () {
|
||||
on: addKuttyEventListener,
|
||||
onLoad: onLoadHelper,
|
||||
logAll : logAll,
|
||||
logger : null,
|
||||
config : null,
|
||||
version: "0.0.1",
|
||||
_:internalEval
|
||||
}
|
||||
}
|
||||
)();
|
||||
)() || kutty;
|
@ -18,8 +18,85 @@
|
||||
</script>
|
||||
|
||||
<script src="util.js"></script>
|
||||
<script src="kt-push-url.js"></script>
|
||||
<script src="kt-boost.js"></script>
|
||||
<script>
|
||||
describe("Browser Only Tests", function() {
|
||||
|
||||
beforeEach(function () {
|
||||
this.server = makeServer();
|
||||
clearWorkArea();
|
||||
});
|
||||
afterEach(function () {
|
||||
this.server.restore();
|
||||
clearWorkArea();
|
||||
});
|
||||
|
||||
it("should handle a basic back button click", function (done) {
|
||||
this.server.respondWith("GET", "/test", "second");
|
||||
|
||||
getWorkArea().innerHTML.should.be.equal("");
|
||||
var div = make('<div kt-push-url="true" kt-get="/test">first</div>');
|
||||
div.click();
|
||||
this.server.respond();
|
||||
getWorkArea().textContent.should.equal("second")
|
||||
history.back();
|
||||
setTimeout(function(){
|
||||
getWorkArea().textContent.should.equal("first");
|
||||
done();
|
||||
}, 20);
|
||||
});
|
||||
|
||||
it("should handle two forward clicks then back twice", function (done) {
|
||||
var i = 0;
|
||||
this.server.respondWith("GET", "/test", function(xhr){
|
||||
i++;
|
||||
xhr.respond(200, {}, "" + i);
|
||||
});
|
||||
|
||||
getWorkArea().innerHTML.should.equal("");
|
||||
var div = make('<div kt-push-url="true" kt-get="/test" class="">0</div>');
|
||||
div.click();
|
||||
this.server.respond();
|
||||
getWorkArea().textContent.should.equal("1")
|
||||
|
||||
div.click();
|
||||
this.server.respond();
|
||||
getWorkArea().textContent.should.equal("2")
|
||||
|
||||
history.back();
|
||||
setTimeout(function(){
|
||||
getWorkArea().textContent.should.equal("1");
|
||||
history.back();
|
||||
setTimeout(function(){
|
||||
getWorkArea().textContent.should.equal("0");
|
||||
done();
|
||||
}, 20);
|
||||
}, 20);
|
||||
})
|
||||
|
||||
it("should handle a back, forward, back button click", function (done) {
|
||||
this.server.respondWith("GET", "/test", "second");
|
||||
|
||||
getWorkArea().innerHTML.should.equal("");
|
||||
var div = make('<div kt-push-url="true" kt-get="/test" class="">first</div>');
|
||||
div.click();
|
||||
this.server.respond();
|
||||
getWorkArea().textContent.should.equal("second")
|
||||
history.back();
|
||||
setTimeout(function(){
|
||||
getWorkArea().textContent.should.equal("first");
|
||||
history.forward();
|
||||
setTimeout(function() {
|
||||
getWorkArea().textContent.should.equal("second");
|
||||
history.back();
|
||||
setTimeout(function() {
|
||||
getWorkArea().textContent.should.equal("first");
|
||||
done();
|
||||
}, 20);
|
||||
}, 20);
|
||||
}, 20);
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<script class="mocha-exec">
|
||||
|
@ -9,6 +9,7 @@
|
||||
<meta http-equiv="expires" content="0" />
|
||||
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
|
||||
<meta http-equiv="pragma" content="no-cache" />
|
||||
<meta name="kutty-config" content='{"historyEnabled":false}'>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
@ -39,6 +40,7 @@
|
||||
<script src="kt-params.js"></script>
|
||||
<script src="kt-patch.js"></script>
|
||||
<script src="kt-post.js"></script>
|
||||
<script src="kt-push-url.js"></script>
|
||||
<script src="kt-put.js"></script>
|
||||
<script src="kt-swap-oob.js"></script>
|
||||
<script src="kt-swap.js"></script>
|
||||
|
@ -1,77 +1,77 @@
|
||||
describe("kt-push-url attribute", function() {
|
||||
|
||||
var KUTTY_HISTORY_CACHE = "kutty-history-cache";
|
||||
beforeEach(function () {
|
||||
this.server = makeServer();
|
||||
clearWorkArea();
|
||||
localStorage.removeItem(KUTTY_HISTORY_CACHE);
|
||||
});
|
||||
afterEach(function () {
|
||||
this.server.restore();
|
||||
clearWorkArea();
|
||||
localStorage.removeItem(KUTTY_HISTORY_CACHE);
|
||||
});
|
||||
|
||||
it("should handle a basic back button click", function (done) {
|
||||
it("navigation should push an element into the cache ", function () {
|
||||
this.server.respondWith("GET", "/test", "second");
|
||||
|
||||
getWorkArea().innerHTML.should.be.equal("");
|
||||
var div = make('<div kt-push-url="true" kt-get="/test">first</div>');
|
||||
div.click();
|
||||
this.server.respond();
|
||||
getWorkArea().textContent.should.equal("second")
|
||||
history.back();
|
||||
setTimeout(function(){
|
||||
getWorkArea().textContent.should.equal("first");
|
||||
done();
|
||||
}, 20);
|
||||
var cache = JSON.parse(localStorage.getItem(KUTTY_HISTORY_CACHE));
|
||||
cache.length.should.equal(1);
|
||||
});
|
||||
|
||||
it("should handle two forward clicks then back twice", function (done) {
|
||||
var i = 0;
|
||||
this.server.respondWith("GET", "/test", function(xhr){
|
||||
i++;
|
||||
xhr.respond(200, {}, "" + i);
|
||||
});
|
||||
|
||||
getWorkArea().innerHTML.should.equal("");
|
||||
var div = make('<div kt-push-url="true" kt-get="/test" class="">0</div>');
|
||||
div.click();
|
||||
this.server.respond();
|
||||
getWorkArea().textContent.should.equal("1")
|
||||
|
||||
div.click();
|
||||
this.server.respond();
|
||||
getWorkArea().textContent.should.equal("2")
|
||||
|
||||
history.back();
|
||||
setTimeout(function(){
|
||||
getWorkArea().textContent.should.equal("1");
|
||||
history.back();
|
||||
setTimeout(function(){
|
||||
getWorkArea().textContent.should.equal("0");
|
||||
done();
|
||||
}, 20);
|
||||
}, 20);
|
||||
})
|
||||
|
||||
it("should handle a back, forward, back button click", function (done) {
|
||||
it("restore should return old value", function () {
|
||||
this.server.respondWith("GET", "/test", "second");
|
||||
|
||||
getWorkArea().innerHTML.should.equal("");
|
||||
var div = make('<div kt-push-url="true" kt-get="/test" class="">first</div>');
|
||||
getWorkArea().innerHTML.should.be.equal("");
|
||||
var div = make('<div kt-push-url="true" kt-get="/test">first</div>');
|
||||
div.click();
|
||||
this.server.respond();
|
||||
getWorkArea().textContent.should.equal("second")
|
||||
history.back();
|
||||
setTimeout(function(){
|
||||
getWorkArea().textContent.should.equal("first");
|
||||
history.forward();
|
||||
setTimeout(function() {
|
||||
getWorkArea().textContent.should.equal("second");
|
||||
history.back();
|
||||
setTimeout(function() {
|
||||
getWorkArea().textContent.should.equal("first");
|
||||
done();
|
||||
}, 20);
|
||||
}, 20);
|
||||
}, 20);
|
||||
})
|
||||
});
|
||||
kutty._('restoreHistory')(location.pathname+location.search)
|
||||
getWorkArea().textContent.should.equal("first")
|
||||
});
|
||||
|
||||
it("cache should only store 10 entries", function () {
|
||||
var x = 0;
|
||||
this.server.respondWith("GET", /test.*/, function(xhr){
|
||||
x++;
|
||||
xhr.respond(200, {}, '<div id="d1" kt-push-url="true" kt-get="/test' + x + '" kt-swap="outerHTML settle:0"></div>')
|
||||
});
|
||||
getWorkArea().innerHTML.should.be.equal("");
|
||||
make('<div id="d1" kt-push-url="true" kt-get="/test" kt-swap="outerHTML settle:0"></div>');
|
||||
for (var i = 0; i < 20; i++) { // issue 20 requests
|
||||
byId("d1").click();
|
||||
this.server.respond();
|
||||
}
|
||||
var cache = JSON.parse(localStorage.getItem(KUTTY_HISTORY_CACHE));
|
||||
cache.length.should.equal(10); // should only be 10 elements
|
||||
});
|
||||
|
||||
it("cache miss should issue another GET", function () {
|
||||
this.server.respondWith("GET", "/test1", '<div id="d2" kt-push-url="true" kt-get="/test2" kt-swap="outerHTML settle:0">test1</div>');
|
||||
this.server.respondWith("GET", "/test2", '<div id="d3" kt-push-url="true" kt-get="/test3" kt-swap="outerHTML settle:0">test2</div>');
|
||||
|
||||
make('<div id="d1" kt-push-url="true" kt-get="/test1" kt-swap="outerHTML settle:0">init</div>');
|
||||
|
||||
byId("d1").click();
|
||||
this.server.respond();
|
||||
var workArea = getWorkArea();
|
||||
workArea.textContent.should.equal("test1")
|
||||
|
||||
byId("d2").click();
|
||||
this.server.respond();
|
||||
workArea.textContent.should.equal("test2")
|
||||
|
||||
var cache = JSON.parse(localStorage.getItem(KUTTY_HISTORY_CACHE));
|
||||
|
||||
cache.length.should.equal(2);
|
||||
localStorage.removeItem(KUTTY_HISTORY_CACHE); // clear cache
|
||||
kutty._('restoreHistory')("/test1")
|
||||
this.server.respond();
|
||||
getWorkArea().textContent.should.equal("test1")
|
||||
});
|
||||
|
||||
});
|
@ -97,7 +97,7 @@ This event is triggered when kutty handles a history restoration action
|
||||
|
||||
* `detail.path` - the path and query of the page being restored
|
||||
|
||||
### <a name="historyUpdate.kutty"></a> Event - [`historyUpdate.kutty`](#historyUpdate.kutty)
|
||||
### <a name="beforeHistorySave.kutty"></a> Event - [`beforeHistorySave.kutty`](#beforeHistorySave.kutty)
|
||||
|
||||
This event is triggered when kutty handles a history restoration action
|
||||
|
||||
|
@ -76,7 +76,7 @@ title: </> kutty - Attributes
|
||||
| [`historyCacheMissError.kutty`](/events#historyCacheMissError.kutty) | triggered on a unsuccessful remote retrieval
|
||||
| [`historyCacheMissLoad.kutty`](/events#historyCacheMissLoad.kutty) | triggered on a succesful remote retrieval
|
||||
| [`historyRestore.kutty`](/events#historyRestore.kutty) | triggered when kutty handles a history restoration action
|
||||
| [`historyUpdate.kutty`](/events#historyUpdate.kutty) | triggered when a new history element is added to the local cache
|
||||
| [`beforeHistorySave.kutty`](/events#beforeHistorySave.kutty) | triggered before content is saved to the history cache
|
||||
| [`initSSE.kutty`](/events#initSSE.kutty) | triggered when a new Server Sent Event source is created
|
||||
| [`load.kutty`](/events#load.kutty) | triggered when new content is added to the DOM
|
||||
| [`noSSESourceError.kutty`](/events#noSSESourceError.kutty) | triggered when an element refers to a SSE event in its trigger, but no parent SSE source has been defined
|
||||
|
Loading…
x
Reference in New Issue
Block a user