Save cursor position

This commit is contained in:
Shadowfacts 2016-09-30 19:48:42 -04:00
parent b62ac18656
commit 4a0315d927
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
2 changed files with 128 additions and 88 deletions

View File

@ -12,6 +12,7 @@
<script src="codemirror/codemirror.js"></script> <script src="codemirror/codemirror.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/localforage/1.4.2/localforage.min.js"></script>
<script src="languages.js"></script> <script src="languages.js"></script>
<script src="main.js"></script> <script src="main.js"></script>
</body> </body>

215
main.js
View File

@ -5,11 +5,14 @@ var focused = false;
let invalids = []; let invalids = [];
// fetch file and setup // fetch file and setup
let file = window.location.hash.substring(1); let hash = window.location.hash.substring(1);
let hashBits = hash.split("/");
let repo = hashBits.slice(0, 3).join("/");
let filePath = hashBits.slice(3, hashBits.length).join("/");
$.get({ $.get({
url: `https://raw.githubusercontent.com/${file}`, url: `https://raw.githubusercontent.com/${repo}/${filePath}`,
success: (code) => { success: (code) => {
let parts = file.split("."); let parts = filePath.split(".");
let fileExtension = parts[parts.length - 1]; let fileExtension = parts[parts.length - 1];
let lang = getLanguageByExtension(fileExtension); let lang = getLanguageByExtension(fileExtension);
$.get({ $.get({
@ -40,107 +43,124 @@ function setup(data, mime) {
editor.setSize("100%", "100%"); editor.setSize("100%", "100%");
incompleteMark = editor.doc.markText({ line: 0, ch: 0 }, getEndPos(), { localforage.getItem(repo)
className: "incomplete" .then((val) => {
}); var startPos; // the initial position of the cursor
if (val && val[filePath] && val[filePath].pos) {
focused = true; startPos = val[filePath].pos;
} else {
editor.on("focus", (instance, event) => { startPos = { line: 0, ch: 0 };
focused = true;
});
editor.on("blur", (instance, event) => {
focused = false;
});
editor.on("mousedown", (instance, event) => {
event.preventDefault();
editor.focus();
});
document.addEventListener("keypress", (event) => {
if (focused) {
event.preventDefault();
let pos = editor.getCursor();
let line = editor.doc.getLine(pos.line);
let char = line.charCodeAt(pos.ch);
if (event.charCode != char) {
let mark = editor.doc.markText(pos, {line: pos.line, ch: pos.ch + 1}, {
className: "invalid"
});
if (!invalids[pos.line]) invalids[pos.line] = [];
invalids[pos.line][pos.ch] = mark;
} }
editor.setCursor({ line: pos.line, ch: pos.ch + 1 });
updateIncompleteMark();
}
});
document.addEventListener("keydown", (event) => { saveCursor();
if (focused) { editor.setCursor(startPos);
var result = false;
if (event.keyCode == 8) { // delete incompleteMark = editor.doc.markText(editor.getCursor(), getEndPos(), {
result = true; className: "incomplete"
});
let pos = editor.getCursor(); focused = true;
if (pos.ch == 0) { // move up 1 line {
moveToEndOfPreviousLine(); editor.on("focus", (instance, event) => {
} else { // move back 1 char focused = true;
});
editor.on("blur", (instance, event) => {
focused = false;
});
editor.on("mousedown", (instance, event) => {
event.preventDefault();
editor.focus();
});
document.addEventListener("keypress", (event) => {
if (focused) {
event.preventDefault();
let pos = editor.getCursor();
let line = editor.doc.getLine(pos.line); let line = editor.doc.getLine(pos.line);
if (line.hasOnlyWhiteSpaceBeforeIndex(pos.ch)) { let char = line.charCodeAt(pos.ch);
moveToEndOfPreviousLine(); if (event.charCode != char) {
} else { let mark = editor.doc.markText(pos, {line: pos.line, ch: pos.ch + 1}, {
editor.setCursor({ line: pos.line, ch: pos.ch - 1 }); className: "invalid"
});
if (!invalids[pos.line]) invalids[pos.line] = [];
invalids[pos.line][pos.ch] = mark;
} }
editor.setCursor({ line: pos.line, ch: pos.ch + 1 });
updateIncompleteMark();
} }
});
let newPos = editor.getCursor(); document.addEventListener("keydown", (event) => {
let lineInvalids = invalids[newPos.line]; if (focused) {
if (lineInvalids) { var result = false;
let mark = lineInvalids[newPos.ch];
if (mark) {
mark.clear();
lineInvalids.splice(newPos.ch, 1);
}
}
updateIncompleteMark(); if (event.keyCode == 8) { // delete
} else if (event.keyCode == 13) { // enter result = true;
result = true;
let pos = editor.getCursor(); let pos = editor.getCursor();
if (pos.line != editor.doc.size - 1) { if (pos.ch == 0) { // move up 1 line {
let currentLine = editor.doc.getLine(pos.line); moveToEndOfPreviousLine();
let trimmed = currentLine.trim(); } else { // move back 1 char
if (editor.getCursor().ch >= currentLine.indexOf(trimmed) + trimmed.length) { let line = editor.doc.getLine(pos.line);
var newLine = pos.line; if (line.hasOnlyWhiteSpaceBeforeIndex(pos.ch)) {
while (true) { moveToEndOfPreviousLine();
newLine++; } else {
if (newLine >= editor.doc.size) { // go to end of last line editor.setCursor({ line: pos.line, ch: pos.ch - 1 });
editor.setCursor(getEndPos());
break;
} else { // try go to next line
let newText = editor.doc.getLine(newLine);
let newTrimmed = newText.trim();
if (newTrimmed.length != 0) { // line is not empty (whitespace-only)
let ch = newText.indexOf(newTrimmed);
editor.setCursor({ line: newLine, ch: ch });
break;
}
} }
} }
let newPos = editor.getCursor();
let lineInvalids = invalids[newPos.line];
if (lineInvalids) {
let mark = lineInvalids[newPos.ch];
if (mark) {
mark.clear();
lineInvalids.splice(newPos.ch, 1);
}
}
updateIncompleteMark(); updateIncompleteMark();
} else if (event.keyCode == 13) { // enter
result = true;
let pos = editor.getCursor();
if (pos.line != editor.doc.size - 1) {
let currentLine = editor.doc.getLine(pos.line);
let trimmed = currentLine.trim();
if (editor.getCursor().ch >= currentLine.indexOf(trimmed) + trimmed.length) {
var newLine = pos.line;
while (true) {
newLine++;
if (newLine >= editor.doc.size) { // go to end of last line
editor.setCursor(getEndPos());
break;
} else { // try go to next line
let newText = editor.doc.getLine(newLine);
let newTrimmed = newText.trim();
if (newTrimmed.length != 0) { // line is not empty (whitespace-only)
let ch = newText.indexOf(newTrimmed);
editor.setCursor({ line: newLine, ch: ch });
break;
}
}
}
updateIncompleteMark();
}
}
}
if (result) {
event.preventDefault();
} }
} }
} });
if (result) { })
event.preventDefault(); .catch((e) => {
} throw e;
} });
});
} }
function moveToEndOfPreviousLine() { function moveToEndOfPreviousLine() {
@ -202,6 +222,25 @@ function updateIncompleteMark() {
}); });
} }
function saveCursor() {
localforage.getItem(repo)
.then((val) => {
if (!val) val = {};
val[filePath] = {
pos: editor.getCursor()
};
localforage.setItem(repo, val)
.catch((e) => {
throw e;
});
})
.catch((e) => {
throw e;
});
setTimeout(saveCursor, 15000);
}
String.prototype.hasOnlyWhiteSpaceBeforeIndex = function(index) { String.prototype.hasOnlyWhiteSpaceBeforeIndex = function(index) {
return this.substring(index) == this.trim(); return this.substring(index) == this.trim();
}; };