Switch to using IndexedDB from LocalStorage
Automatically imports from old LocalStorage data
This commit is contained in:
parent
d86fbae8ed
commit
c91f76b197
181
js/main.js
181
js/main.js
|
@ -1,3 +1,6 @@
|
||||||
|
// use this when making changes so that there is no need to parse the page
|
||||||
|
var bookmarkList;
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
calcBackground();
|
calcBackground();
|
||||||
loadBookmarks();
|
loadBookmarks();
|
||||||
|
@ -14,7 +17,7 @@ $(document).ready(function () {
|
||||||
var combo = $("#newBookmarkGroup");
|
var combo = $("#newBookmarkGroup");
|
||||||
var data = getList();
|
var data = getList();
|
||||||
for (var i = 0; i < data.length; i++) {
|
for (var i = 0; i < data.length; i++) {
|
||||||
combo.append($("<option></option>").attr({ "value": i }).text(data[i].title));
|
combo.append($("<option>").attr({ "value": i }).text(data[i].title));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,27 +39,88 @@ function importBookmarks() {
|
||||||
var newData = $.parseJSON($("#importText").val());
|
var newData = $.parseJSON($("#importText").val());
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Import failed: " + err.message);
|
console.error("Import failed: " + err.message);
|
||||||
window.alert("Failed to import");
|
window.alert("Invalid Format");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (verifyBookmarks(newData)) {
|
||||||
setList(newData);
|
setList(newData);
|
||||||
|
|
||||||
$(".bookmarkGroup").remove();
|
|
||||||
loadBookmarks();
|
|
||||||
$("#importExportModal").modal("hide");
|
$("#importExportModal").modal("hide");
|
||||||
|
} else {
|
||||||
|
window.alert("Invalid Format");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadBookmarks() {
|
function loadBookmarks() {
|
||||||
var groups = getList();
|
$("#cardList").empty();
|
||||||
|
var openDBRequest = window.indexedDB.open("bookmarks");
|
||||||
|
|
||||||
if (groups != null) {
|
openDBRequest.onsuccess = function (dbEvt) {
|
||||||
for (var i = 0; i < groups.length; i++) {
|
console.log("Opened database");
|
||||||
var item = groups[i];
|
db = dbEvt.target.result;
|
||||||
buildCard(item.title, item.bookmarks);
|
bookmarkList = [];
|
||||||
|
|
||||||
|
db.transaction(["groupIndexes"], "readonly")
|
||||||
|
.objectStore("groupIndexes")
|
||||||
|
.getAll()
|
||||||
|
.onsuccess = function (indexEvt) {
|
||||||
|
var indexes = indexEvt.target.result;
|
||||||
|
|
||||||
|
// use a placholder because getting the group info is async
|
||||||
|
// and groups could finish loading in a different order
|
||||||
|
var cardList = $("#cardList");
|
||||||
|
for (var i = 0; i < indexes.length; i++) {
|
||||||
|
var placeholder = $("<div>").attr("id", "group-" + i).appendTo(cardList);
|
||||||
|
buildGroup(indexes[i], placeholder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
openDBRequest.onerror = function (e) { console.log(e); }
|
||||||
|
|
||||||
|
openDBRequest.onupgradeneeded = function (e) {
|
||||||
|
// the database doesn't exist
|
||||||
|
console.log("Creating database");
|
||||||
|
db = e.target.result;
|
||||||
|
|
||||||
|
var data = window.localStorage.getItem("bookmarks");
|
||||||
|
if (data != null) {
|
||||||
|
console.log("Importing data from old version");
|
||||||
|
data = JSON.parse(data);
|
||||||
|
db.close();
|
||||||
|
setList(data);
|
||||||
|
window.localStorage.removeItem("bookmarks");
|
||||||
} else {
|
} else {
|
||||||
$("#aboutModal").modal("show");
|
var groupStore = initDB(db);
|
||||||
|
|
||||||
|
// add example bookmarks
|
||||||
|
var exBookmarks = db.createObjectStore("Examples");
|
||||||
|
exBookmarks.createIndex("name", "name", { unique: false });
|
||||||
|
exBookmarks.createIndex("address", "address", { unique: false });
|
||||||
|
groupStore.add({ "title": "Examples", "groupIndex": 0 });
|
||||||
|
|
||||||
|
exBookmarks.add({ "name": "Github", "address": "https://github.com/" }, 0);
|
||||||
|
exBookmarks.add({ "name": "This project on Github", "address": "https://github.com/NeilBrommer/NewTabPage" }, 1);
|
||||||
|
exBookmarks.add({ "name": "Hacker News", "address": "https://news.ycombinator.com/" }, 2);
|
||||||
|
exBookmarks.add({ "name": "reddit", "address": "https://www.reddit.com/" }, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildGroup(groupInfo, placeholder) {
|
||||||
|
var groupTransaction = db.transaction([groupInfo.title], "readonly");
|
||||||
|
var groupStore = groupTransaction.objectStore(groupInfo.title);
|
||||||
|
var groupRequest = groupStore.getAll();
|
||||||
|
groupRequest.onsuccess = function (e) {
|
||||||
|
var bookmarks = e.target.result;
|
||||||
|
|
||||||
|
bookmarkList[groupInfo.groupIndex] = { "title": groupInfo.title, "bookmarks": bookmarks };
|
||||||
|
|
||||||
|
buildCard(groupInfo.title, bookmarks).appendTo(placeholder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +149,7 @@ function buildCard(title, itemList) {
|
||||||
cardList.append(link);
|
cardList.append(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#cardList").append(card);
|
return card;
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectGroupChanged(value) {
|
function selectGroupChanged(value) {
|
||||||
|
@ -129,19 +193,92 @@ function setBackground(num, dark) {
|
||||||
$(".btn-dark").removeClass("btn-dark").addClass("btn-light");
|
$(".btn-dark").removeClass("btn-dark").addClass("btn-light");
|
||||||
}
|
}
|
||||||
|
|
||||||
function getList() {
|
|
||||||
return $.parseJSON(window.localStorage.getItem("bookmarks"));
|
|
||||||
}
|
|
||||||
|
|
||||||
function getListString() {
|
function getListString() {
|
||||||
return window.localStorage.getItem("bookmarks");
|
return JSON.stringify(bookmarkList, null, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setList(list) {
|
function setList(data) {
|
||||||
if (typeof list == "string") {
|
// empty the DB and fill it with the new data
|
||||||
window.localStorage.setItem("bookmarks", list);
|
bookmarkList = data;
|
||||||
} else {
|
|
||||||
var stringified = JSON.stringify(list, null, 4);
|
try {
|
||||||
window.localStorage.setItem("bookmarks", stringified);
|
indexedDB.deleteDatabase("bookmarks");
|
||||||
|
} catch (err) {
|
||||||
|
// it's OK if the DB doesn't exist
|
||||||
|
if (err.name != "NotFoundError") {
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var openDBRequest = window.indexedDB.open("bookmarks", 1);
|
||||||
|
|
||||||
|
openDBRequest.onsuccess = function (e) {
|
||||||
|
db.close();
|
||||||
|
loadBookmarks();
|
||||||
|
}
|
||||||
|
|
||||||
|
openDBRequest.onerror = function (err) { console.error(err); }
|
||||||
|
|
||||||
|
openDBRequest.onupgradeneeded = function (e) {
|
||||||
|
console.log("filling db");
|
||||||
|
db = e.target.result;
|
||||||
|
|
||||||
|
var groupStore = initDB(db);
|
||||||
|
|
||||||
|
// create the object stores
|
||||||
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
addGroup(data[i], groupStore, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function initDB(db) {
|
||||||
|
// use a table to keep track of the order of groups
|
||||||
|
var groupStore = db.createObjectStore("groupIndexes", { keyPath: "title" });
|
||||||
|
groupStore.createIndex("title", "groupName", { unique: true });
|
||||||
|
groupStore.createIndex("groupIndex", "groupIndex", { unique: true });
|
||||||
|
return groupStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addGroup(group, groupStore, index) {
|
||||||
|
var objStore = db.createObjectStore(group.title);
|
||||||
|
objStore.createIndex("name", "name", { unique: false });
|
||||||
|
objStore.createIndex("address", "address", { unique: false });
|
||||||
|
groupStore.add({ "title": group.title, "groupIndex": index });
|
||||||
|
|
||||||
|
var bookmarks = group.bookmarks;
|
||||||
|
for (var i = 0; i < bookmarks.length; i++) {
|
||||||
|
var bkmk = bookmarks[i];
|
||||||
|
objStore.add({ "name": bkmk.name, "address": bkmk.address }, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyBookmarks(bookmarks) {
|
||||||
|
if (!Array.isArray(bookmarks))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (var i = 0; i < bookmarks.length; i++) {
|
||||||
|
var item = bookmarks[i];
|
||||||
|
|
||||||
|
if (item == null || typeof item != "object")
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (item.title == null || typeof item.title != "string")
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (var j = 0; j < item.bookmarks.length; j++) {
|
||||||
|
var bkmk = item.bookmarks[j];
|
||||||
|
|
||||||
|
if (bkmk == null || typeof bkmk != "object")
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (bkmk.name == null || typeof bkmk.name != "string")
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (bkmk.address == null || typeof bkmk.address != "string")
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue