refactor local serialization
This commit is contained in:
		
							parent
							
								
									d633cf719d
								
							
						
					
					
						commit
						de6268d86f
					
				
							
								
								
									
										302
									
								
								main.js
								
								
								
								
							
							
						
						
									
										302
									
								
								main.js
								
								
								
								
							| 
						 | 
					@ -19,37 +19,18 @@ var defaultsettings =
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//builtin
 | 
					//builtin
 | 
				
			||||||
var markerslist = ["* ", "- ", "    * ", "    - ", ">> ", "> ", "=> ", "— ", "[ ] ", "    ", "• ", "- [ ]", "[x] ", "- [x]"];
 | 
					const markerslist = ["* ", "- ", "    * ", "    - ", ">> ", "> ", "=> ", "— ", "[ ] ", "    ", "• ", "- [ ]", "[x] ", "- [x]"];
 | 
				
			||||||
var codelanguages = ["xml", "js", "sql"];
 | 
					const codelanguages = ["xml", "js", "sql"];
 | 
				
			||||||
var tagmark = "+";
 | 
					const tagmark = "+";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// globals
 | 
					// globals
 | 
				
			||||||
 | 
					var previoustitle = "";
 | 
				
			||||||
var metadata = null;
 | 
					var metadata = null;
 | 
				
			||||||
var fileindex = 0;
 | 
					var fileindex = 0;
 | 
				
			||||||
var workerid = null;
 | 
					var workerid = null;
 | 
				
			||||||
var backup = "";
 | 
					var backup = "";var settings = null;
 | 
				
			||||||
var saved = true;
 | 
					 | 
				
			||||||
var lastsaved = "";
 | 
					 | 
				
			||||||
var pending = false;
 | 
					 | 
				
			||||||
var settings = null;
 | 
					 | 
				
			||||||
var tags = null;
 | 
					var tags = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var stat =
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	ses:
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		q: 0,
 | 
					 | 
				
			||||||
		t: timestamp(),
 | 
					 | 
				
			||||||
		d: 0
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
	cur:
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		q: 0,
 | 
					 | 
				
			||||||
		t: timestamp(),
 | 
					 | 
				
			||||||
		d: 0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var commands = [
 | 
					var commands = [
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hint: "Close menu"
 | 
						hint: "Close menu"
 | 
				
			||||||
| 
						 | 
					@ -57,9 +38,7 @@ var commands = [
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	shortcut: "ctrl+shift+P",
 | 
						shortcut: "ctrl+shift+P",
 | 
				
			||||||
	hint: "Command palette",
 | 
						hint: "Command palette",
 | 
				
			||||||
	allowunsaved: true,
 | 
					 | 
				
			||||||
	action: commandpalette,
 | 
						action: commandpalette,
 | 
				
			||||||
	excludepalette: true
 | 
					 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	shortcut: "ctrl+p",
 | 
						shortcut: "ctrl+p",
 | 
				
			||||||
| 
						 | 
					@ -78,14 +57,12 @@ var commands = [
 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hint: "Force save",
 | 
						hint: "Force save",
 | 
				
			||||||
	action: save,
 | 
						action: serialize,
 | 
				
			||||||
	shortcut: "ctrl+s",
 | 
						shortcut: "ctrl+s"
 | 
				
			||||||
	allowunsaved: true
 | 
					 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hint: "Share note",
 | 
						hint: "Share note",
 | 
				
			||||||
	action: share,
 | 
						action: share
 | 
				
			||||||
	allowunsaved: true
 | 
					 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hint: "Share note (html)",
 | 
						hint: "Share note (html)",
 | 
				
			||||||
| 
						 | 
					@ -99,20 +76,17 @@ var commands = [
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	shortcut: "ctrl+i",
 | 
						shortcut: "ctrl+i",
 | 
				
			||||||
	hint: "Toggle title",
 | 
						hint: "Toggle title",
 | 
				
			||||||
	action: toggletitle,
 | 
						action: toggletitle
 | 
				
			||||||
	allowunsaved: true
 | 
					 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	shortcut: "ctrl+m",
 | 
						shortcut: "ctrl+m",
 | 
				
			||||||
	hint: "Toggle preview",
 | 
						hint: "Toggle preview",
 | 
				
			||||||
	action: togglepreview,
 | 
						action: togglepreview
 | 
				
			||||||
	allowunsaved: true
 | 
					 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	shortcut: "ctrl+shift+M",
 | 
						shortcut: "ctrl+shift+M",
 | 
				
			||||||
	hint: "Toggle preview with merged subnotes",
 | 
						hint: "Toggle preview with merged subnotes",
 | 
				
			||||||
	action: togglepreviewwithsubs,
 | 
						action: togglepreviewwithsubs
 | 
				
			||||||
	allowunsaved: true
 | 
					 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	shortcut: "ctrl+d",
 | 
						shortcut: "ctrl+d",
 | 
				
			||||||
| 
						 | 
					@ -125,8 +99,7 @@ var commands = [
 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hint: "Insert markdown header",
 | 
						hint: "Insert markdown header",
 | 
				
			||||||
	action: insertheader,
 | 
						action: insertheader
 | 
				
			||||||
	allowunsaved: true
 | 
					 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hint: "Show help",
 | 
						hint: "Show help",
 | 
				
			||||||
| 
						 | 
					@ -166,8 +139,7 @@ var commands = [
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hint: "Note outline",
 | 
						hint: "Note outline",
 | 
				
			||||||
	action: showoutline,
 | 
						action: showoutline,
 | 
				
			||||||
	shortcut: "ctrl+o",
 | 
						shortcut: "ctrl+o"
 | 
				
			||||||
	allowunsaved: true
 | 
					 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hint: "Show connected notes",
 | 
						hint: "Show connected notes",
 | 
				
			||||||
| 
						 | 
					@ -177,13 +149,11 @@ var commands = [
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hint: "Show stats",
 | 
						hint: "Show stats",
 | 
				
			||||||
	action: showinfo,
 | 
						action: showinfo,
 | 
				
			||||||
	shortcut: "ctrl+w",
 | 
						shortcut: "ctrl+w"
 | 
				
			||||||
	allowunsaved: true
 | 
					 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hint: "Toggle spell check",
 | 
						hint: "Toggle spell check",
 | 
				
			||||||
	action: togglespellcheck,
 | 
						action: togglespellcheck,
 | 
				
			||||||
	allowunsaved: true,
 | 
					 | 
				
			||||||
	shortcut: "F7"
 | 
						shortcut: "F7"
 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -255,8 +225,7 @@ var commands = [
 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hint: "Sort text",
 | 
						hint: "Sort text",
 | 
				
			||||||
	action: sortselection,
 | 
						action: sortselection
 | 
				
			||||||
	allowunsaved: true
 | 
					 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hint: "Show backlinks",
 | 
						hint: "Show backlinks",
 | 
				
			||||||
| 
						 | 
					@ -264,8 +233,7 @@ var commands = [
 | 
				
			||||||
},
 | 
					},
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	hint: "Remove completed tasks",
 | 
						hint: "Remove completed tasks",
 | 
				
			||||||
	action: purgetodo,
 | 
						action: purgetodo
 | 
				
			||||||
	allowunsaved: true
 | 
					 | 
				
			||||||
}];
 | 
					}];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var snippets = [
 | 
					var snippets = [
 | 
				
			||||||
| 
						 | 
					@ -316,21 +284,19 @@ function genguid()
 | 
				
			||||||
	return crypto.randomUUID();
 | 
						return crypto.randomUUID();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function purgetodo() {
 | 
					function purgetodo()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
	if (currentistodo() && confirm("Remove completed tasks?"))
 | 
						if (currentistodo() && confirm("Remove completed tasks?"))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		seteditorcontent(currentnote.content.replace(/\nx .*/g, ""));
 | 
							seteditorcontent(currentnote.content.replace(/\nx .*/g, ""));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function seteditorcontent(content, silent)
 | 
					function seteditorcontent(content)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	md.value = content;
 | 
						md.value = content;
 | 
				
			||||||
	applycolors();
 | 
						applycolors();
 | 
				
			||||||
	if (!silent)
 | 
						serialize();
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		datachanged();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	resize();
 | 
						resize();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -453,7 +419,7 @@ function includesub()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (confirm("Delete '" + title + "'?"))
 | 
								if (confirm("Delete '" + title + "'?"))
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				deletenote(subnote);
 | 
									deletenote(title);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -490,19 +456,12 @@ function showinfo()
 | 
				
			||||||
	var tags = gettags(currentnote);
 | 
						var tags = gettags(currentnote);
 | 
				
			||||||
	showtemporaryinfo(
 | 
						showtemporaryinfo(
 | 
				
			||||||
		[
 | 
							[
 | 
				
			||||||
			"saved: " + saved + (lastsaved? " (" + lastsaved + ")": ""),
 | 
					 | 
				
			||||||
			"sync: " + (settings.sync ? "en" : "dis") + "abled",
 | 
								"sync: " + (settings.sync ? "en" : "dis") + "abled",
 | 
				
			||||||
			"title: " + currentnote.title,
 | 
								"title: " + currentnote.title,
 | 
				
			||||||
			"line count: " + md.value.split("\n").length,
 | 
								"line count: " + md.value.split("\n").length,
 | 
				
			||||||
			"word count: " + getwords(),
 | 
								"word count: " + getwords(),
 | 
				
			||||||
			"cursor position: " + md.selectionStart + " (" + pospercent() + "%)",
 | 
								"cursor position: " + md.selectionStart + " (" + pospercent() + "%)",
 | 
				
			||||||
			(tags ? "tags: " + tags : ""),
 | 
								(tags ? "tags: " + tags : ""),
 | 
				
			||||||
			"current note start: " + stat.cur.t,
 | 
					 | 
				
			||||||
			"current note queries: " + stat.cur.q,
 | 
					 | 
				
			||||||
			"current note data sent: " + formatsize(stat.cur.d),
 | 
					 | 
				
			||||||
			"session start: " + stat.ses.t,
 | 
					 | 
				
			||||||
			"session queries: " + stat.ses.q,
 | 
					 | 
				
			||||||
			"session data sent: " + formatsize(stat.ses.d),
 | 
					 | 
				
			||||||
			"notes count: " + localdata.length,
 | 
								"notes count: " + localdata.length,
 | 
				
			||||||
			"spell check: " + (md.spellcheck ? "en" : "dis") + "abled"
 | 
								"spell check: " + (md.spellcheck ? "en" : "dis") + "abled"
 | 
				
			||||||
		].join("\n"));
 | 
							].join("\n"));
 | 
				
			||||||
| 
						 | 
					@ -877,11 +836,7 @@ function restoresettings()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function editsettings()
 | 
					function editsettings()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	bind(
 | 
						bind("settings.json", JSON.stringify(settings, null, "    "));
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		title: "settings.json",
 | 
					 | 
				
			||||||
		content: JSON.stringify(settings, null, "    ")
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function editsetting(name)
 | 
					function editsetting(name)
 | 
				
			||||||
| 
						 | 
					@ -932,11 +887,7 @@ function decryptnote()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function editpgpkeys()
 | 
					function editpgpkeys()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	bind(
 | 
						bind("pgpkeys", localStorage.getItem("pgpkeys") || "");
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		title: "pgpkeys",
 | 
					 | 
				
			||||||
		content: localStorage.getItem("pgpkeys") || ""
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function showtemporaryinfo(info)
 | 
					function showtemporaryinfo(info)
 | 
				
			||||||
| 
						 | 
					@ -1101,14 +1052,24 @@ function headerandtext(content)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function inserttodo(text)
 | 
					function inserttodo(text)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	var todo = getorcreate("todo", "");
 | 
						var guid = getguid("todo");
 | 
				
			||||||
	var split = headerandtext(todo);
 | 
						if (!guid)
 | 
				
			||||||
	todo.content = split.header + text + "\n" + split.text;
 | 
					 | 
				
			||||||
	if (todo == currentnote)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		seteditorcontent(todo.content, true);
 | 
							guid = createnote("todo");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var content = localStorage.getItem(guid);
 | 
				
			||||||
 | 
						var split = headerandtext(content);
 | 
				
			||||||
 | 
						content = split.header + text + "\n" + split.text;
 | 
				
			||||||
 | 
						if (title.value == "todo")
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							seteditorcontent(content);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							localStorage.setItem(guid, content);
 | 
				
			||||||
 | 
							metadata[guid].lastchanged = Date.now();
 | 
				
			||||||
 | 
							serialize();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return datachanged();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function promptinserttodo()
 | 
					function promptinserttodo()
 | 
				
			||||||
| 
						 | 
					@ -1228,7 +1189,8 @@ function loadstorage()
 | 
				
			||||||
		msg.innerText = "Clipping...";
 | 
							msg.innerText = "Clipping...";
 | 
				
			||||||
		notepage.appendChild(msg);
 | 
							notepage.appendChild(msg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inserttodo("@clip " + clip).then(window.close);
 | 
							inserttodo("@clip " + clip)
 | 
				
			||||||
 | 
							window.close();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// when multiple tabs or split?
 | 
						// when multiple tabs or split?
 | 
				
			||||||
| 
						 | 
					@ -1249,8 +1211,7 @@ function loadstorage()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (window.title.value)
 | 
						if (window.title.value)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		var guid = getguid(window.title.value);
 | 
							bind(window.title.value);
 | 
				
			||||||
		bind(guid);
 | 
					 | 
				
			||||||
		if (line)
 | 
							if (line)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			gotoline(line);
 | 
								gotoline(line);
 | 
				
			||||||
| 
						 | 
					@ -1354,14 +1315,14 @@ function migratelegacystorage()
 | 
				
			||||||
	var legacy = localStorage.getItem("data");
 | 
						var legacy = localStorage.getItem("data");
 | 
				
			||||||
	if (legacy)
 | 
						if (legacy)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		// todo: use title as key and guid as property. or not.
 | 
					 | 
				
			||||||
		var legacy = JSON.parse(legacy);
 | 
							var legacy = JSON.parse(legacy);
 | 
				
			||||||
		var index = {};
 | 
							var index = {};
 | 
				
			||||||
		legacy.forEach(note =>
 | 
							legacy.reverse().forEach(note =>
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			var guid = genguid();
 | 
								var guid = genguid();
 | 
				
			||||||
			localStorage.setItem(guid, note.content);
 | 
								localStorage.setItem(guid, note.content);
 | 
				
			||||||
			note.header = indexheader(note.content);
 | 
								note.header = indexheader(note.content);
 | 
				
			||||||
 | 
								note.lastchanged = Date.now();
 | 
				
			||||||
			delete note.content;
 | 
								delete note.content;
 | 
				
			||||||
			index[guid] = note;
 | 
								index[guid] = note;
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
| 
						 | 
					@ -1448,9 +1409,6 @@ function queryremote(params)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return new Promise( (apply, failed) => {
 | 
						return new Promise( (apply, failed) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		stat.cur.q++;
 | 
					 | 
				
			||||||
		stat.ses.q++;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		params.password = settings.password;
 | 
							params.password = settings.password;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		var paramlist = [];
 | 
							var paramlist = [];
 | 
				
			||||||
| 
						 | 
					@ -1459,9 +1417,6 @@ function queryremote(params)
 | 
				
			||||||
			paramlist.push(i + "=" + encodeURIComponent(params[i]));
 | 
								paramlist.push(i + "=" + encodeURIComponent(params[i]));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		stat.cur.d += paramlist.join("&").length;
 | 
					 | 
				
			||||||
		stat.ses.d += paramlist.join("&").length;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		var xhr = new XMLHttpRequest();
 | 
							var xhr = new XMLHttpRequest();
 | 
				
			||||||
		xhr.open("POST", "handler.php");
 | 
							xhr.open("POST", "handler.php");
 | 
				
			||||||
		xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
 | 
							xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
 | 
				
			||||||
| 
						 | 
					@ -1661,11 +1616,7 @@ function showgrepresult(needle, grepresult)
 | 
				
			||||||
		grepcontent.push("No result.");
 | 
							grepcontent.push("No result.");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bind(
 | 
						bind("Search result", grepcontent.join("\n"));
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		title: "Search result",
 | 
					 | 
				
			||||||
		content: grepcontent.join("\n")
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (preview.hidden)
 | 
						if (preview.hidden)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -1877,12 +1828,6 @@ function resize()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function putontop()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	console.warn("todo: put on top");
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function postpone()
 | 
					function postpone()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return new Promise(function(resolve)
 | 
						return new Promise(function(resolve)
 | 
				
			||||||
| 
						 | 
					@ -1892,31 +1837,37 @@ function postpone()
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function setsaved()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	unsavedmark.hidden = true;
 | 
					 | 
				
			||||||
	saved = true;
 | 
					 | 
				
			||||||
	lastsaved = timestamp();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function serialize()
 | 
					function serialize()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	// serialize all gui stuff to local storage
 | 
						clearTimeout(workerid);
 | 
				
			||||||
 | 
						workerid = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var guid = getguid(window.title.value);
 | 
						var guid = getguid(window.title.value);
 | 
				
			||||||
	var item = metadata[guid];
 | 
						if (guid)
 | 
				
			||||||
	item.title = title.value;
 | 
						{
 | 
				
			||||||
	item.pos = md.selectionStart;
 | 
							var item = metadata[guid];
 | 
				
			||||||
	item.header = indexheader(md.value);
 | 
							item.title = title.value;
 | 
				
			||||||
 | 
							item.pos = md.selectionStart;
 | 
				
			||||||
	// is it the right place?
 | 
							item.header = indexheader(md.value);
 | 
				
			||||||
	putontop();
 | 
							item.lastchanged = Date.now();
 | 
				
			||||||
 | 
					 | 
				
			||||||
	localStorage.setItem("index", JSON.stringify(metadata));
 | 
					 | 
				
			||||||
	localStorage.setItem(guid, md.value);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							localStorage.setItem("index", JSON.stringify(metadata));
 | 
				
			||||||
 | 
							localStorage.setItem(guid, md.value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if (title.value == "settings.json")
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							settings = JSON.parse(md.value);
 | 
				
			||||||
 | 
							savesettings();
 | 
				
			||||||
 | 
							loadsettings();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else if (title.value == "pgpkeys")
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							localStorage.setItem("pgpkeys", md.value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						console.log("data serialized");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function save()
 | 
					/*function save()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return new Promise(function(resolve, reject)
 | 
						return new Promise(function(resolve, reject)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -2001,7 +1952,7 @@ function save()
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
}
 | 
					}*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function escapeHtml(unsafe) {
 | 
					function escapeHtml(unsafe) {
 | 
				
			||||||
	return unsafe
 | 
						return unsafe
 | 
				
			||||||
| 
						 | 
					@ -2263,19 +2214,10 @@ function editorinput()
 | 
				
			||||||
	// criteria to improve. Or redraw only after?
 | 
						// criteria to improve. Or redraw only after?
 | 
				
			||||||
	var multiline = md.value.substring(md.selectionStart, md.selectionEnd).includes("\n");
 | 
						var multiline = md.value.substring(md.selectionStart, md.selectionEnd).includes("\n");
 | 
				
			||||||
	applycolors(!multiline && event.data && (event.inputType == "insertText" || event.inputType == "deleteContentBackward" || event.inputType == "deleteContentForward"));
 | 
						applycolors(!multiline && event.data && (event.inputType == "insertText" || event.inputType == "deleteContentBackward" || event.inputType == "deleteContentForward"));
 | 
				
			||||||
	datachanged();
 | 
						postpone().then(serialize);
 | 
				
			||||||
	resize();
 | 
						resize();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function datachanged()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	saved = false;
 | 
					 | 
				
			||||||
	unsavedmark.hidden = !settings.sync;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return postpone()
 | 
					 | 
				
			||||||
	.then(save);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function timestamp()
 | 
					function timestamp()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	var utc = new Date();
 | 
						var utc = new Date();
 | 
				
			||||||
| 
						 | 
					@ -2286,17 +2228,17 @@ function timestamp()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function quicknewnote()
 | 
					function quicknewnote()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						serialize();
 | 
				
			||||||
	loadnote(timestamp());
 | 
						loadnote(timestamp());
 | 
				
			||||||
	datachanged();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function startnewnote()
 | 
					function startnewnote()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						serialize();
 | 
				
			||||||
	var title = prompt("Note title: ", timestamp());
 | 
						var title = prompt("Note title: ", timestamp());
 | 
				
			||||||
	if (title)
 | 
						if (title)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		loadnote(title);
 | 
							loadnote(title);
 | 
				
			||||||
		datachanged();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2334,11 +2276,7 @@ function showhelp()
 | 
				
			||||||
	help.push("##Sources");
 | 
						help.push("##Sources");
 | 
				
			||||||
	help.push("https://github.com/quenousimporte/notes");
 | 
						help.push("https://github.com/quenousimporte/notes");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bind(
 | 
						bind("Help", help.join("\n"));
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		title: "Help",
 | 
					 | 
				
			||||||
		content: help.join("\n")
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (preview.hidden)
 | 
						if (preview.hidden)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -2362,6 +2300,7 @@ function toggletitle()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function selectnote()
 | 
					function selectnote()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						// todo: sort by lastchanged
 | 
				
			||||||
	return searchinlist(
 | 
						return searchinlist(
 | 
				
			||||||
		Object.values(metadata).map(item =>
 | 
							Object.values(metadata).map(item =>
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
| 
						 | 
					@ -2491,6 +2430,7 @@ function renamereferences(newname)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function restoredeleted()
 | 
					function restoredeleted()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						// todo: parse local storage starting with "deleted" and reindex with a new guid
 | 
				
			||||||
	var trash = window.localStorage.getItem("trash");
 | 
						var trash = window.localStorage.getItem("trash");
 | 
				
			||||||
	if (trash)
 | 
						if (trash)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -2518,24 +2458,22 @@ function restoredeleted()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function deletenote(note)
 | 
					function deletenote(title)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	var trash = JSON.parse(window.localStorage.getItem("trash") || "[]");
 | 
						var guid = getguid(title);
 | 
				
			||||||
	note.deletiondate = timestamp();
 | 
						delete metadata[guid];
 | 
				
			||||||
	trash.push(note);
 | 
						renameinternallinks(title, title + " (deleted)");
 | 
				
			||||||
	window.localStorage.setItem("trash", JSON.stringify(trash));
 | 
						var content = localStorage.getItem(guid);
 | 
				
			||||||
 | 
						localStorage.removeItem(guid);
 | 
				
			||||||
	localdata = localdata.filter(n => n != note);
 | 
						localStorage.setItem("deleted_" + title, content);
 | 
				
			||||||
 | 
						localStorage.setItem("index", JSON.stringify(metadata));
 | 
				
			||||||
	renamereferences(note.title + " (deleted)");
 | 
					 | 
				
			||||||
	datachanged();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function deletecurrentnote()
 | 
					function deletecurrentnote()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (confirm('delete "' + currentnote.title + '"?'))
 | 
						if (confirm('delete "' + title.value + '"?'))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		deletenote(currentnote);
 | 
							deletenote(title.value);
 | 
				
			||||||
		loadlast();
 | 
							loadlast();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2578,11 +2516,7 @@ function shortcutmatches(event, shortcut)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function executecommand(command)
 | 
					function executecommand(command)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!command.allowunsaved && !saved)
 | 
						if (command.remoteonly && !settings.sync)
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		showtemporaryinfo("Cannot perform '" + command.hint + "' because current note is not saved.");
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else if (command.remoteonly && !settings.sync)
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		showtemporaryinfo(command.hint + " is not available in local mode.");
 | 
							showtemporaryinfo(command.hint + " is not available in local mode.");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -2748,31 +2682,41 @@ function setwindowtitle()
 | 
				
			||||||
	document.title = title.value;
 | 
						document.title = title.value;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function renameinternallinks(from, to)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						foreachmetadata( (guid, item) =>
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							var content = localStorage.getItem(guid);
 | 
				
			||||||
 | 
							var newcontent = content.replaceAll("[[" + from + "]]", "[[" + to + "]]");
 | 
				
			||||||
 | 
							if (content != newcontent)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								localStorage.setItem(guid, newcontent);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function ontitlechange()
 | 
					function ontitlechange()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (localdata.find(n => n.title == title.value))
 | 
						var guid = getguid(title.value);
 | 
				
			||||||
 | 
						if (guid)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		showtemporaryinfo(title.value + " alreday exists");
 | 
							showtemporaryinfo(title.value + " alreday exists");
 | 
				
			||||||
		title.value = currentnote.title;
 | 
							title.value = previoustitle;
 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
	// rename internal references
 | 
					 | 
				
			||||||
	localdata
 | 
					 | 
				
			||||||
	.filter(note => note != currentnote)
 | 
					 | 
				
			||||||
	.forEach(note =>
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		note.content = note.content.replaceAll("[[" + currentnote.title + "]]", "[[" + title.value + "]]");
 | 
							renameinternallinks(previoustitle, title.value);
 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	currentnote.title = title.value;
 | 
							guid = getguid(previoustitle);
 | 
				
			||||||
 | 
							previoustitle = title.value;
 | 
				
			||||||
 | 
							metadata[guid].title = title.value;
 | 
				
			||||||
 | 
							setwindowtitle();
 | 
				
			||||||
 | 
							serialize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	datachanged();
 | 
							if (!settings.titlebydefault)
 | 
				
			||||||
	setwindowtitle();
 | 
							{
 | 
				
			||||||
 | 
								toggletitle();
 | 
				
			||||||
	if (!settings.titlebydefault)
 | 
							}
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		toggletitle();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2961,18 +2905,16 @@ function togglepreviewwithsubs()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function bind(title, content, pos)
 | 
					function bind(title, content, pos)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	var changed = title.value != title;
 | 
						previoustitle = title;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	backup = content;
 | 
						backup = content;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	window.title.value = title;
 | 
						window.title.value = title;
 | 
				
			||||||
	setwindowtitle();
 | 
						setwindowtitle();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	seteditorcontent(content || "", true);
 | 
						md.value = content || "";
 | 
				
			||||||
 | 
						applycolors();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (changed)
 | 
						md.style.height = "0px";
 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		md.style.height = "0px";
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	resize();
 | 
						resize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	setpos(pos || 0);
 | 
						setpos(pos || 0);
 | 
				
			||||||
| 
						 | 
					@ -3027,10 +2969,6 @@ function loadnote(title)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bind(item.title, content, item.pos);
 | 
						bind(item.title, content, item.pos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stat.cur.q = 0;
 | 
					 | 
				
			||||||
	stat.cur.d = 0;
 | 
					 | 
				
			||||||
	stat.cur.t = timestamp();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!preview.hidden || (preview.hidden && (gettags(md.value).indexOf("preview") !== -1)))
 | 
						if (!preview.hidden || (preview.hidden && (gettags(md.value).indexOf("preview") !== -1)))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		togglepreview();
 | 
							togglepreview();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue