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