mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 06:22:22 -04:00
editor
This commit is contained in:
parent
b3f6199827
commit
ddb4db0c96
3 changed files with 26 additions and 18 deletions
2
Makefile
2
Makefile
|
@ -93,4 +93,4 @@ JSDEPS := $(patsubst ts/%.ts, web/%.js, $(TSDEPS))
|
||||||
js: $(JSDEPS)
|
js: $(JSDEPS)
|
||||||
|
|
||||||
web/%.js: ts/%.ts
|
web/%.js: ts/%.ts
|
||||||
(cd ts && ./node_modules/.bin/tsc lib/global.d.ts $(notdir $<) --outFile ../web/$(notdir $@))
|
(cd ts && ./node_modules/.bin/tsc --lib es6,dom lib/global.d.ts $(notdir $<) --outFile ../web/$(notdir $@))
|
||||||
|
|
|
@ -1,11 +1,18 @@
|
||||||
/* Copyright: Ankitects Pty Ltd and contributors
|
/* Copyright: Ankitects Pty Ltd and contributors
|
||||||
* License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */
|
* License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */
|
||||||
|
|
||||||
|
import DragOverEvent = JQuery.DragOverEvent;
|
||||||
|
|
||||||
var currentField = null;
|
var currentField = null;
|
||||||
var changeTimer = null;
|
var changeTimer = null;
|
||||||
var dropTarget = null;
|
var dropTarget = null;
|
||||||
var currentNoteId = null;
|
var currentNoteId = null;
|
||||||
|
|
||||||
|
declare interface String {
|
||||||
|
format(...args) : string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* kept for compatibility with add-ons */
|
||||||
String.prototype.format = function () {
|
String.prototype.format = function () {
|
||||||
var args = arguments;
|
var args = arguments;
|
||||||
return this.replace(/\{\d+\}/g, function (m) {
|
return this.replace(/\{\d+\}/g, function (m) {
|
||||||
|
@ -40,16 +47,16 @@ function triggerKeyTimer() {
|
||||||
}, 600);
|
}, 600);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onKey() {
|
function onKey(evt: KeyboardEvent) {
|
||||||
// esc clears focus, allowing dialog to close
|
// esc clears focus, allowing dialog to close
|
||||||
if (window.event.which === 27) {
|
if (evt.which === 27) {
|
||||||
currentField.blur();
|
currentField.blur();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// shift+tab goes to previous field
|
// shift+tab goes to previous field
|
||||||
if (navigator.platform === "MacIntel" &&
|
if (navigator.platform === "MacIntel" &&
|
||||||
window.event.which === 9 && window.event.shiftKey) {
|
evt.which === 9 && evt.shiftKey) {
|
||||||
window.event.preventDefault();
|
evt.preventDefault();
|
||||||
focusPrevious();
|
focusPrevious();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -83,9 +90,9 @@ function insertNewline() {
|
||||||
|
|
||||||
// is the cursor in an environment that respects whitespace?
|
// is the cursor in an environment that respects whitespace?
|
||||||
function inPreEnvironment() {
|
function inPreEnvironment() {
|
||||||
var n = window.getSelection().anchorNode;
|
let n = window.getSelection().anchorNode as Element;
|
||||||
if (n.nodeType === 3) {
|
if (n.nodeType === 3) {
|
||||||
n = n.parentNode;
|
n = n.parentNode as Element;
|
||||||
}
|
}
|
||||||
return window.getComputedStyle(n).whiteSpace.startsWith("pre");
|
return window.getComputedStyle(n).whiteSpace.startsWith("pre");
|
||||||
}
|
}
|
||||||
|
@ -123,7 +130,7 @@ function toggleEditorButton(buttonid) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setFormat(cmd, arg, nosave) {
|
function setFormat(cmd: string, arg?: any, nosave: boolean = false) {
|
||||||
document.execCommand(cmd, false, arg);
|
document.execCommand(cmd, false, arg);
|
||||||
if (!nosave) {
|
if (!nosave) {
|
||||||
saveField('key');
|
saveField('key');
|
||||||
|
@ -186,8 +193,8 @@ function focusPrevious() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function onDragOver(elem) {
|
function onDragOver(elem) {
|
||||||
var e = window.event;
|
var e = window.event as unknown as DragOverEvent;
|
||||||
e.dataTransfer.dropEffect = "copy";
|
//e.dataTransfer.dropEffect = "copy";
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
// if we focus the target element immediately, the drag&drop turns into a
|
// if we focus the target element immediately, the drag&drop turns into a
|
||||||
// copy, so note it down for later instead
|
// copy, so note it down for later instead
|
||||||
|
@ -316,12 +323,12 @@ function setFields(fields) {
|
||||||
if (!f) {
|
if (!f) {
|
||||||
f = "<br>";
|
f = "<br>";
|
||||||
}
|
}
|
||||||
txt += "<tr><td class=fname>{0}</td></tr><tr><td width=100%>".format(n);
|
txt += `<tr><td class=fname>${n}</td></tr><tr><td width=100%>`;
|
||||||
txt += "<div id=f{0} onkeydown='onKey();' oninput='onInput()' onmouseup='onKey();'".format(i);
|
txt += `<div id=f${i} onkeydown='onKey(window.event);' oninput='onInput()' onmouseup='onKey();'`;
|
||||||
txt += " onfocus='onFocus(this);' onblur='onBlur();' class='field clearfix' ";
|
txt += " onfocus='onFocus(this);' onblur='onBlur();' class='field clearfix' ";
|
||||||
txt += "ondragover='onDragOver(this);' onpaste='onPaste(this);' ";
|
txt += "ondragover='onDragOver(this);' onpaste='onPaste(this);' ";
|
||||||
txt += "oncopy='onCutOrCopy(this);' oncut='onCutOrCopy(this);' ";
|
txt += "oncopy='onCutOrCopy(this);' oncut='onCutOrCopy(this);' ";
|
||||||
txt += "contentEditable=true class=field>{0}</div>".format(f);
|
txt += `contentEditable=true class=field>${f}</div>`;
|
||||||
txt += "</td></tr>";
|
txt += "</td></tr>";
|
||||||
}
|
}
|
||||||
$("#fields").html("<table cellpadding=0 width=100% style='table-layout: fixed;'>" + txt + "</table>");
|
$("#fields").html("<table cellpadding=0 width=100% style='table-layout: fixed;'>" + txt + "</table>");
|
||||||
|
@ -368,13 +375,13 @@ var pasteHTML = function (html, internal, extendedMode) {
|
||||||
|
|
||||||
var filterHTML = function (html, internal, extendedMode) {
|
var filterHTML = function (html, internal, extendedMode) {
|
||||||
// wrap it in <top> as we aren't allowed to change top level elements
|
// wrap it in <top> as we aren't allowed to change top level elements
|
||||||
var top = $.parseHTML("<ankitop>" + html + "</ankitop>")[0];
|
const top = $.parseHTML("<ankitop>" + html + "</ankitop>")[0] as Element;
|
||||||
if (internal) {
|
if (internal) {
|
||||||
filterInternalNode(top);
|
filterInternalNode(top);
|
||||||
} else {
|
} else {
|
||||||
filterNode(top, extendedMode);
|
filterNode(top, extendedMode);
|
||||||
}
|
}
|
||||||
var outHtml = top.innerHTML;
|
let outHtml = top.innerHTML;
|
||||||
if (!extendedMode) {
|
if (!extendedMode) {
|
||||||
// collapse whitespace
|
// collapse whitespace
|
||||||
outHtml = outHtml.replace(/[\n\t ]+/g, " ");
|
outHtml = outHtml.replace(/[\n\t ]+/g, " ");
|
||||||
|
@ -538,12 +545,12 @@ $(function () {
|
||||||
mouseDown--;
|
mouseDown--;
|
||||||
};
|
};
|
||||||
|
|
||||||
document.onclick = function (evt) {
|
document.onclick = function (evt: MouseEvent) {
|
||||||
var src = window.event.srcElement;
|
let src = evt.target as Element;
|
||||||
if (src.tagName === "IMG") {
|
if (src.tagName === "IMG") {
|
||||||
// image clicked; find contenteditable parent
|
// image clicked; find contenteditable parent
|
||||||
var p = src;
|
var p = src;
|
||||||
while (p = p.parentNode) {
|
while (p = p.parentNode as Element) {
|
||||||
if (p.className === "field") {
|
if (p.className === "field") {
|
||||||
$("#" + p.id).focus();
|
$("#" + p.id).focus();
|
||||||
break;
|
break;
|
1
web/.gitignore
vendored
1
web/.gitignore
vendored
|
@ -3,3 +3,4 @@ deckbrowser.js
|
||||||
overview.js
|
overview.js
|
||||||
reviewer-bottom.js
|
reviewer-bottom.js
|
||||||
reviewer.js
|
reviewer.js
|
||||||
|
editor.js
|
||||||
|
|
Loading…
Reference in a new issue