Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 102 additions & 9 deletions src-ui/js/ui/Boot.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,35 @@
// ★boot() window.onload直後の処理
//---------------------------------------------------------------------------
pzpr.on("load", function boot() {
if (importData()) {
startPuzzle();
var pzl;
// Get URL search hash and check localStorage to see if a board state is saved
if (!pzpr.env.localStorageAvailable) {
pzl = importData();
} else {
var key = "pzpr_" + getPuzzleString();
var valStr = localStorage.getItem(key);
if (!valStr) {
pzl = importData();
} else {
var valObject = JSON.parse(valStr);
pzl = importData(valObject.pzl); // Local storage was available and key was found
}
}
if (!pzl) {
setTimeout(boot, 0);
}
startPuzzle();
});

function importData() {
function importData(string) {
if (!onload_pzl) {
/* 1) 盤面複製・index.htmlからのファイル入力/Database入力か */
/* 2) URL(?以降)をチェック */
onload_pzl = importURL();
if (!string) {
onload_pzl = importURL();
} else {
onload_pzl = importFromString(string);
}

/* 指定されたパズルがない場合はさようなら~ */
if (!onload_pzl || !onload_pzl.pid) {
Expand Down Expand Up @@ -90,26 +107,102 @@
//---------------------------------------------------------------------------
function importURL() {
/* index.htmlからURLが入力されていない場合は現在のURLの?以降をとってくる */
var puzString = getPuzzleString();
return importFromString(puzString);
}
//Splitting functionality from above for flexibility.

//Return the string associated with the puzzle
function getPuzzleString() {
var search = location.search;
if (!search) {
return null;
}

/* 一旦先頭の?記号を取り除く */
if (search.charAt(0) === "?") {
search = search.substr(1);
search = search.slice(1); //Non-deprecated version of substr
}

while (search.match(/^(\w+)\=(\w+)\&(.*)/)) {
onload_option[RegExp.$1] = RegExp.$2;
search = RegExp.$3;
}
return search;
}
//Import from a puzzle string. This can come from the URL or from localStorage
function importFromString(string) {
if (!string) {
return null;
}

onload_pzv = search;
var pzl = pzpr.parser.parseURL(search);
onload_pzv = string;
var pzl = pzpr.parser.parseURL(string);
var startmode = pzl.mode || (!pzl.body ? "editor" : "player");
onload_option.type = onload_option.type || startmode;

return pzl;
}

//---------------------------------------------------------------------------
// Functionality to support browser caching
//---------------------------------------------------------------------------

//Save board state. Creates an entry in localStorage whose key is a 'pzpr_' identifier plus the current board state puzzle string.
//Board state puzzle string is the same thing you get from duplicating the board state
function saveBoardState() {
var key = "pzpr_" + getPuzzleString();
var url = ui.puzzle.getURL(
pzpr.parser.URL_PZPRFILE,
ui.puzzle.playeronly ? "player" : "editor"
);
//Strip url to the last option. This is the "puzzle string" we want
url = url.substring(url.indexOf("?") + 1); //Skip to the search parameters part of the url
while (url.match(/^(\w+)\=(\w+)\&(.*)/)) {
url = RegExp.$3;
}
//Add a time signifier so that we can sort and delete oldest if setting fails
var valObject = {
t: Date.now(),
pzl: url
// bufferToForceStorageLimitErrors: "0".repeat(1700000) //Include for testing to force out-of-storage errors
};
try {
localStorage.setItem(key, JSON.stringify(valObject));
} catch (e) {
if (e.name === "QuotaExceededError") {
//If storage was full: load all of the puzzles in localStorage, sort by least recent, and delete until saving is successful
var saveSuccess = false;
var pairs = [];
for (var i = 0; i < localStorage.length; i++) {
var lsKey = localStorage.key(i);
var lsValue = localStorage.getItem(lsKey);
pairs.push({ key: lsKey, value: lsValue });
}
pairs = pairs.filter(function(item) {
return item.key.indexOf("pzpr_") === 0;
});
pairs = pairs.sort(function(a, b) {
var ta = JSON.parse(a.value).t;
var tb = JSON.parse(b.value).t;
return ta > tb;
});
while (!saveSuccess && pairs.length > 0) {
console.log(pairs);
try {
localStorage.setItem(key, JSON.stringify(valObject));
saveSuccess = true;
} catch (e) {
localStorage.removeItem(pairs[0].key);
pairs = pairs.slice(1);
}
}
}
}
}

//Events that trigger a board state save
document.addEventListener("visibilitychange", function() {
if (document.visibilityState === "hidden") {
saveBoardState();
}
});
})();
14 changes: 13 additions & 1 deletion src/pzpr/env.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,25 @@ pzpr.env = (function() {
anchor_download:
isbrowser && document.createElement("a").download !== void 0
};
//Taken directly from stackoverflow. Apparently this is the most broadly compatible version. https://stackoverflow.com/questions/16427636/check-if-localstorage-is-available
var localStorageAvailable = (function() {
var test = "test";
try {
localStorage.setItem(test, test);
localStorage.removeItem(test);
return true;
} catch (e) {
return false;
}
})();

return {
bz: bz,
OS: os,
API: api,
browser: isbrowser,
node: pzpr.Candle.env.node
node: pzpr.Candle.env.node,
localStorageAvailable: localStorageAvailable
};
})();

Expand Down