Remove individual .html files + other refactorings (#1588)
* Move some AddCards specific code to NoteCreator.svelte * Add new strings for Toggling the Visual / HTML editor * Set LabelContainer vertical-align to text-top - Makes them look more centered * Remove appendInParentheses helper * Make all ts/*.html files include only module.js and module.css * Move any JS from .html to index files * Remove .html files from ts modules * Remove Python with Starlark implemenation * Remove reference to non-existing file * Remove deck-option.html as well * fix change-notetype screen (dae)
This commit is contained in:
parent
492f0a5e32
commit
478b3a53f1
@ -19,7 +19,6 @@ editing-fields = Fields
|
||||
editing-float-left = Float left
|
||||
editing-float-right = Float right
|
||||
editing-float-none = No float
|
||||
editing-html-editor = HTML Editor
|
||||
editing-indent = Increase indent
|
||||
editing-italic-text = Italic text
|
||||
editing-jump-to-tags-with-ctrlandshiftandt = Jump to tags with Ctrl+Shift+T
|
||||
@ -44,10 +43,13 @@ editing-subscript = Subscript
|
||||
editing-superscript = Superscript
|
||||
editing-tags = Tags
|
||||
editing-to-make-a-cloze-deletion-on = To make a cloze deletion on an existing note, you need to change it to a cloze type first, via 'Notes>Change Note Type'
|
||||
editing-toggle-html-editor = Toggle HTML Editor
|
||||
editing-toggle-sticky = Toggle sticky
|
||||
editing-toggle-visual-editor = Toggle Visual Editor
|
||||
editing-underline-text = Underline text
|
||||
editing-unordered-list = Unordered list
|
||||
editing-warning-cloze-deletions-will-not-work = Warning, cloze deletions will not work until you switch the type at the top to Cloze.
|
||||
|
||||
## You don't need to translate these strings, as they will be replaced with different ones soon.
|
||||
|
||||
editing-html-editor = HTML Editor
|
||||
|
@ -77,7 +77,6 @@ class AddCards(QMainWindow):
|
||||
self,
|
||||
editor_mode=aqt.editor.EditorMode.ADD_CARDS,
|
||||
)
|
||||
self.editor.web.eval("noteEditorPromise.then(() => activateStickyShortcuts());")
|
||||
|
||||
def setup_choosers(self) -> None:
|
||||
defaults = self.col.defaults_for_adding(
|
||||
|
@ -63,15 +63,11 @@ class CardInfoDialog(QDialog):
|
||||
layout.addWidget(buttons)
|
||||
qconnect(buttons.rejected, self.reject)
|
||||
self.setLayout(layout)
|
||||
|
||||
self.web.eval(
|
||||
"const cardInfo = anki.cardInfo(document.getElementById('main'));"
|
||||
)
|
||||
self.update_card(card_id)
|
||||
|
||||
def update_card(self, card_id: CardId | None) -> None:
|
||||
self.web.eval(
|
||||
f"cardInfo.then((c) => c.$set({{ cardId: {json.dumps(card_id)} }}));"
|
||||
f"anki.cardInfoPromise.then((c) => c.$set({{ cardId: {json.dumps(card_id)} }}));"
|
||||
)
|
||||
|
||||
def reject(self) -> None:
|
||||
|
@ -59,8 +59,7 @@ class ChangeNotetypeDialog(QDialog):
|
||||
self.setLayout(layout)
|
||||
|
||||
self.web.eval(
|
||||
f"""anki.changeNotetypePage(
|
||||
document.getElementById('main'), {notetype_id}, {notetype_id});"""
|
||||
f"""anki.setupChangeNotetypePage({notetype_id}, {notetype_id});"""
|
||||
)
|
||||
self.setWindowTitle(tr.browsing_change_notetype())
|
||||
|
||||
|
@ -51,8 +51,7 @@ class DeckOptionsDialog(QDialog):
|
||||
self.setLayout(layout)
|
||||
|
||||
self.web.eval(
|
||||
f"""const $deckOptions = anki.deckOptions(
|
||||
document.getElementById('main'), {self._deck["id"]});"""
|
||||
f"""const $deckOptions = anki.setupDeckOptions({self._deck["id"]});"""
|
||||
)
|
||||
self.setWindowTitle(
|
||||
without_unicode_isolation(tr.actions_options_for(val=self._deck["name"]))
|
||||
|
@ -15,6 +15,7 @@ exports_files([
|
||||
"jest.config.js",
|
||||
"package.json",
|
||||
"protobuf-no-long.js",
|
||||
"page.html",
|
||||
])
|
||||
|
||||
# a copy needs to be placed in bazel-bin for libs with
|
||||
|
@ -2,12 +2,15 @@ load("//ts:prettier.bzl", "prettier_test")
|
||||
load("//ts:eslint.bzl", "eslint_test")
|
||||
load("//ts/svelte:svelte.bzl", "compile_svelte", "svelte_check")
|
||||
load("//ts:esbuild.bzl", "esbuild")
|
||||
load("//ts:generate_page.bzl", "generate_page")
|
||||
load("//ts:compile_sass.bzl", "compile_sass")
|
||||
load("//ts:typescript.bzl", "typescript")
|
||||
|
||||
generate_page(page = "card-info")
|
||||
|
||||
compile_sass(
|
||||
srcs = ["card-info-base.scss"],
|
||||
group = "base_css",
|
||||
srcs = ["card-info-base.scss"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//sass:base_lib",
|
||||
@ -17,8 +20,8 @@ compile_sass(
|
||||
)
|
||||
|
||||
_ts_deps = [
|
||||
"//ts/components",
|
||||
"//ts/lib",
|
||||
"//ts/components",
|
||||
"@npm//@fluent",
|
||||
]
|
||||
|
||||
@ -50,8 +53,6 @@ esbuild(
|
||||
],
|
||||
)
|
||||
|
||||
exports_files(["card-info.html"])
|
||||
|
||||
# Tests
|
||||
################
|
||||
|
||||
|
@ -1,23 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" id="viewport" content="width=device-width" />
|
||||
<link href="card-info-base.css" rel="stylesheet" />
|
||||
<link href="card-info.css" rel="stylesheet" />
|
||||
<script src="../js/vendor/bootstrap.bundle.min.js"></script>
|
||||
<script src="card-info.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main"></div>
|
||||
|
||||
<script>
|
||||
// use #testXXXX where XXXX is card ID to test
|
||||
if (window.location.hash.startsWith("#test")) {
|
||||
const cid = parseInt(window.location.hash.substr("#test".length), 10);
|
||||
const cardInfo = anki.cardInfo(document.getElementById("main"));
|
||||
cardInfo.then((c) => c.$set({ cardId: cid, includeRevlog: true }));
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -5,11 +5,23 @@ import { setupI18n, ModuleName } from "../lib/i18n";
|
||||
import { checkNightMode } from "../lib/nightmode";
|
||||
|
||||
import CardInfo from "./CardInfo.svelte";
|
||||
import "./card-info-base.css";
|
||||
|
||||
export async function cardInfo(target: HTMLDivElement): Promise<CardInfo> {
|
||||
const i18n = setupI18n({
|
||||
modules: [ModuleName.CARD_STATS, ModuleName.SCHEDULING, ModuleName.STATISTICS],
|
||||
});
|
||||
|
||||
export async function setupCardInfo(): Promise<CardInfo> {
|
||||
checkNightMode();
|
||||
await setupI18n({
|
||||
modules: [ModuleName.CARD_STATS, ModuleName.SCHEDULING, ModuleName.STATISTICS],
|
||||
});
|
||||
return new CardInfo({ target });
|
||||
await i18n;
|
||||
|
||||
return new CardInfo({ target: document.body, props: { includeRevlog: true } });
|
||||
}
|
||||
|
||||
export const cardInfoPromise = setupCardInfo();
|
||||
|
||||
if (window.location.hash.startsWith("#test")) {
|
||||
// use #testXXXX where XXXX is card ID to test
|
||||
const cardId = parseInt(window.location.hash.substr("#test".length), 10);
|
||||
cardInfoPromise.then((cardInfo: CardInfo): void => cardInfo.$set({ cardId }));
|
||||
}
|
||||
|
@ -2,10 +2,13 @@ load("//ts:prettier.bzl", "prettier_test")
|
||||
load("//ts:eslint.bzl", "eslint_test")
|
||||
load("//ts/svelte:svelte.bzl", "compile_svelte", "svelte_check")
|
||||
load("//ts:esbuild.bzl", "esbuild")
|
||||
load("//ts:generate_page.bzl", "generate_page")
|
||||
load("//ts:compile_sass.bzl", "compile_sass")
|
||||
load("//ts:typescript.bzl", "typescript")
|
||||
load("//ts:jest.bzl", "jest_test")
|
||||
|
||||
generate_page(page = "change-notetype")
|
||||
|
||||
compile_sass(
|
||||
srcs = ["change-notetype-base.scss"],
|
||||
group = "base_css",
|
||||
@ -54,8 +57,6 @@ esbuild(
|
||||
],
|
||||
)
|
||||
|
||||
exports_files(["change-notetype.html"])
|
||||
|
||||
# Tests
|
||||
################
|
||||
|
||||
|
@ -1,22 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" id="viewport" content="width=device-width" />
|
||||
<link href="change-notetype-base.css" rel="stylesheet" />
|
||||
<link href="change-notetype.css" rel="stylesheet" />
|
||||
<script src="../js/vendor/bootstrap.bundle.min.js"></script>
|
||||
<script src="change-notetype.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main"></div>
|
||||
|
||||
<script>
|
||||
// use #testXXXX where XXXX is notetype ID to test
|
||||
if (window.location.hash.startsWith("#test")) {
|
||||
const ntid = parseInt(window.location.hash.substr("#test".length), 10);
|
||||
anki.changeNotetypePage(document.getElementById("main"), ntid, ntid);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -8,10 +8,11 @@
|
||||
import { ChangeNotetypeState, getChangeNotetypeInfo, getNotetypeNames } from "./lib";
|
||||
import { setupI18n, ModuleName } from "../lib/i18n";
|
||||
import { checkNightMode } from "../lib/nightmode";
|
||||
import ChangeNotetypePage from "./ChangeNotetypePage.svelte";
|
||||
|
||||
export async function changeNotetypePage(
|
||||
target: HTMLDivElement,
|
||||
import ChangeNotetypePage from "./ChangeNotetypePage.svelte";
|
||||
import "./change-notetype-base.css";
|
||||
|
||||
export async function setupChangeNotetypePage(
|
||||
oldNotetypeId: number,
|
||||
newNotetypeId: number,
|
||||
): Promise<ChangeNotetypePage> {
|
||||
@ -31,7 +32,13 @@ export async function changeNotetypePage(
|
||||
|
||||
const state = new ChangeNotetypeState(names, info);
|
||||
return new ChangeNotetypePage({
|
||||
target,
|
||||
props: { state },
|
||||
} as any);
|
||||
target: document.body,
|
||||
props: { state } as any,
|
||||
});
|
||||
}
|
||||
|
||||
// use #testXXXX where XXXX is notetype ID to test
|
||||
if (window.location.hash.startsWith("#test")) {
|
||||
const ntid = parseInt(window.location.hash.substr("#test".length), 10);
|
||||
setupChangeNotetypePage(ntid, ntid);
|
||||
}
|
||||
|
@ -5,8 +5,6 @@ def compile_sass(group, srcs, deps = [], visibility = ["//visibility:private"]):
|
||||
for scss_file in srcs:
|
||||
base = scss_file.replace(".scss", "")
|
||||
name = base + "_sass"
|
||||
css_file = base + ".css"
|
||||
css_files.append(css_file)
|
||||
|
||||
sass_binary(
|
||||
name = name,
|
||||
@ -22,6 +20,9 @@ def compile_sass(group, srcs, deps = [], visibility = ["//visibility:private"]):
|
||||
],
|
||||
)
|
||||
|
||||
css_file = base + ".css"
|
||||
css_files.append(css_file)
|
||||
|
||||
native.filegroup(
|
||||
name = group,
|
||||
srcs = css_files,
|
||||
|
@ -85,12 +85,14 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
api = {
|
||||
show: dropdown.show.bind(dropdown),
|
||||
toggle: dropdown.toggle.bind(dropdown),
|
||||
// TODO this is quite confusing, but commenting this fixes Bootstrap
|
||||
// in the deck-options when not including Bootstrap via <script />
|
||||
toggle: () => {}, // toggle: dropdown.toggle.bind(dropdown),
|
||||
hide: dropdown.hide.bind(dropdown),
|
||||
update: dropdown.update.bind(dropdown),
|
||||
dispose: dropdown.dispose.bind(dropdown),
|
||||
isVisible,
|
||||
};
|
||||
} as any;
|
||||
|
||||
return api;
|
||||
}
|
||||
|
@ -2,12 +2,15 @@ load("//ts:prettier.bzl", "prettier_test")
|
||||
load("//ts:eslint.bzl", "eslint_test")
|
||||
load("//ts/svelte:svelte.bzl", "compile_svelte", "svelte_check")
|
||||
load("//ts:esbuild.bzl", "esbuild")
|
||||
load("//ts:generate_page.bzl", "generate_page")
|
||||
load("//ts:compile_sass.bzl", "compile_sass")
|
||||
load("//ts:typescript.bzl", "typescript")
|
||||
|
||||
generate_page(page = "congrats")
|
||||
|
||||
compile_sass(
|
||||
srcs = ["congrats-base.scss"],
|
||||
group = "congrats_css",
|
||||
group = "base_css",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//sass:base_lib",
|
||||
@ -20,7 +23,7 @@ compile_svelte(
|
||||
)
|
||||
|
||||
typescript(
|
||||
name = "congrats_ts",
|
||||
name = "index",
|
||||
deps = [
|
||||
":svelte",
|
||||
"//ts/components",
|
||||
@ -35,19 +38,18 @@ esbuild(
|
||||
name = "congrats",
|
||||
args = {
|
||||
"globalName": "anki",
|
||||
"loader": {".svg": "text"},
|
||||
},
|
||||
entry_point = "index.ts",
|
||||
output_css = "congrats.css",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":congrats_css",
|
||||
":congrats_ts",
|
||||
":base_css",
|
||||
":index",
|
||||
":svelte",
|
||||
],
|
||||
)
|
||||
|
||||
exports_files(["congrats.html"])
|
||||
|
||||
# Tests
|
||||
################
|
||||
|
||||
|
@ -1,17 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" id="viewport" content="width=device-width" />
|
||||
<link href="congrats-base.css" rel="stylesheet" />
|
||||
<link href="congrats.css" rel="stylesheet" />
|
||||
<script src="congrats.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main"></div>
|
||||
|
||||
<script>
|
||||
anki.congrats(document.getElementById("main"));
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -6,18 +6,27 @@ import { setupI18n, ModuleName } from "../lib/i18n";
|
||||
import { checkNightMode } from "../lib/nightmode";
|
||||
|
||||
import CongratsPage from "./CongratsPage.svelte";
|
||||
import "./congrats-base.css";
|
||||
|
||||
export async function congrats(target: HTMLDivElement): Promise<void> {
|
||||
const i18n = setupI18n({ modules: [ModuleName.SCHEDULING] });
|
||||
|
||||
export async function setupCongrats(): Promise<CongratsPage> {
|
||||
checkNightMode();
|
||||
await setupI18n({ modules: [ModuleName.SCHEDULING] });
|
||||
await i18n;
|
||||
|
||||
const info = await getCongratsInfo();
|
||||
const page = new CongratsPage({
|
||||
target,
|
||||
target: document.body,
|
||||
props: { info },
|
||||
});
|
||||
|
||||
setInterval(() => {
|
||||
getCongratsInfo().then((info) => {
|
||||
page.$set({ info });
|
||||
});
|
||||
}, 60000);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
setupCongrats();
|
||||
|
@ -2,10 +2,13 @@ load("//ts:prettier.bzl", "prettier_test")
|
||||
load("//ts:eslint.bzl", "eslint_test")
|
||||
load("//ts/svelte:svelte.bzl", "compile_svelte", "svelte_check")
|
||||
load("//ts:esbuild.bzl", "esbuild")
|
||||
load("//ts:generate_page.bzl", "generate_page")
|
||||
load("//ts:compile_sass.bzl", "compile_sass")
|
||||
load("//ts:jest.bzl", "jest_test")
|
||||
load("//ts:typescript.bzl", "typescript")
|
||||
|
||||
generate_page(page = "deck-options")
|
||||
|
||||
compile_sass(
|
||||
srcs = ["deck-options-base.scss"],
|
||||
group = "base_css",
|
||||
@ -26,6 +29,7 @@ _ts_deps = [
|
||||
"@npm//@popperjs",
|
||||
"@npm//@types/jest",
|
||||
"@npm//bootstrap-icons",
|
||||
"@npm//bootstrap",
|
||||
"@npm//lodash-es",
|
||||
"@npm//svelte",
|
||||
"@npm//marked",
|
||||
@ -60,8 +64,6 @@ esbuild(
|
||||
],
|
||||
)
|
||||
|
||||
exports_files(["deck-options.html"])
|
||||
|
||||
# Tests
|
||||
################
|
||||
|
||||
@ -79,11 +81,11 @@ svelte_check(
|
||||
"//sass:night_mode_lib",
|
||||
"//sass:breakpoints_lib",
|
||||
"//sass/bootstrap",
|
||||
"//ts/components",
|
||||
"//ts/sveltelib:sveltelib_pkg",
|
||||
"@npm//@types/bootstrap",
|
||||
"@npm//@types/lodash-es",
|
||||
"@npm//@types/marked",
|
||||
"//ts/components",
|
||||
"//ts/sveltelib:sveltelib_pkg",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -62,7 +62,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
<ButtonGroup>
|
||||
<ButtonGroupItem>
|
||||
<WithShortcut shortcut={"Control+Enter"} let:createShortcut let:shortcutLabel>
|
||||
<WithShortcut shortcut="Control+Enter" let:createShortcut let:shortcutLabel>
|
||||
<LabelButton
|
||||
theme="primary"
|
||||
on:click={() => save(false)}
|
||||
|
@ -1,20 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" id="viewport" content="width=device-width" />
|
||||
<link href="deck-options-base.css" rel="stylesheet" />
|
||||
<link href="deck-options.css" rel="stylesheet" />
|
||||
<script src="../js/vendor/bootstrap.bundle.min.js"></script>
|
||||
<script src="deck-options.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main"></div>
|
||||
|
||||
<script>
|
||||
if (window.location.hash.startsWith("#test")) {
|
||||
anki.deckOptions(document.getElementById("main"), 1);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -10,41 +10,35 @@ import "../sveltelib/export-runtime";
|
||||
import { getDeckOptionsInfo, DeckOptionsState } from "./lib";
|
||||
import { setupI18n, ModuleName } from "../lib/i18n";
|
||||
import { checkNightMode } from "../lib/nightmode";
|
||||
import DeckOptionsPage from "./DeckOptionsPage.svelte";
|
||||
import { touchDeviceKey, modalsKey } from "../components/context-keys";
|
||||
|
||||
export async function deckOptions(
|
||||
target: HTMLDivElement,
|
||||
deckId: number,
|
||||
): Promise<DeckOptionsPage> {
|
||||
const [info] = await Promise.all([
|
||||
getDeckOptionsInfo(deckId),
|
||||
setupI18n({
|
||||
modules: [
|
||||
ModuleName.SCHEDULING,
|
||||
ModuleName.ACTIONS,
|
||||
ModuleName.DECK_CONFIG,
|
||||
ModuleName.KEYBOARD,
|
||||
],
|
||||
}),
|
||||
]);
|
||||
import DeckOptionsPage from "./DeckOptionsPage.svelte";
|
||||
import "./deck-options-base.css";
|
||||
|
||||
const i18n = setupI18n({
|
||||
modules: [
|
||||
ModuleName.SCHEDULING,
|
||||
ModuleName.ACTIONS,
|
||||
ModuleName.DECK_CONFIG,
|
||||
ModuleName.KEYBOARD,
|
||||
],
|
||||
});
|
||||
|
||||
export async function setupDeckOptions(deckId: number): Promise<DeckOptionsPage> {
|
||||
const [info] = await Promise.all([getDeckOptionsInfo(deckId), i18n]);
|
||||
|
||||
checkNightMode();
|
||||
|
||||
const context = new Map();
|
||||
|
||||
const modals = new Map();
|
||||
context.set(modalsKey, modals);
|
||||
|
||||
const touchDevice = "ontouchstart" in document.documentElement;
|
||||
context.set(touchDeviceKey, touchDevice);
|
||||
context.set(modalsKey, new Map());
|
||||
context.set(touchDeviceKey, "ontouchstart" in document.documentElement);
|
||||
|
||||
const state = new DeckOptionsState(deckId, info);
|
||||
return new DeckOptionsPage({
|
||||
target,
|
||||
target: document.body,
|
||||
props: { state },
|
||||
context,
|
||||
} as any);
|
||||
});
|
||||
}
|
||||
|
||||
import TitledContainer from "./TitledContainer.svelte";
|
||||
@ -60,3 +54,7 @@ export const components = {
|
||||
EnumSelectorRow,
|
||||
SwitchRow,
|
||||
};
|
||||
|
||||
if (window.location.hash.startsWith("#test")) {
|
||||
setupDeckOptions(1);
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import { on, preventDefault } from "../lib/events";
|
||||
import { registerShortcut } from "../lib/shortcuts";
|
||||
import { placeCaretAfterContent } from "../domlib/place-caret";
|
||||
import { saveSelection, restoreSelection } from "../domlib/location";
|
||||
import { isApplePlatform } from "../lib/platform";
|
||||
import { bridgeCommand } from "../lib/bridgecommand";
|
||||
import type { SelectionLocation } from "../domlib/location";
|
||||
|
||||
const locationEvents: (() => void)[] = [];
|
||||
@ -76,6 +78,10 @@ export function saveLocation(editable: HTMLElement): { destroy(): void } {
|
||||
};
|
||||
}
|
||||
|
||||
if (isApplePlatform()) {
|
||||
registerShortcut(() => bridgeCommand("paste"), "Control+Shift+V");
|
||||
}
|
||||
|
||||
export function preventBuiltinContentEditableShortcuts(editable: HTMLElement): void {
|
||||
for (const keyCombination of ["Control+B", "Control+U", "Control+I", "Control+R"]) {
|
||||
registerShortcut(preventDefault, keyCombination, editable);
|
||||
|
@ -7,7 +7,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
import Badge from "../components/Badge.svelte";
|
||||
|
||||
import { withSpan } from "../components/helpers";
|
||||
import { appendInParentheses } from "./helpers";
|
||||
import { tagIcon, addTagIcon } from "./icons";
|
||||
|
||||
const tooltip = "Add tag";
|
||||
@ -17,7 +16,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
<div class="add-icon">
|
||||
<Badge
|
||||
class="d-flex me-1"
|
||||
tooltip={appendInParentheses(tooltip, shortcutLabel)}
|
||||
tooltip="{tooltip} ({shortcutLabel})"
|
||||
on:click
|
||||
on:mount={withSpan(createShortcut)}
|
||||
>
|
||||
|
@ -14,7 +14,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
import { bridgeCommand } from "../lib/bridgecommand";
|
||||
import { withButton } from "../components/helpers";
|
||||
import { textColorIcon, highlightColorIcon, arrowIcon } from "./icons";
|
||||
import { appendInParentheses, execCommand } from "./helpers";
|
||||
import { execCommand } from "./helpers";
|
||||
import { getNoteEditor } from "./OldEditorAdapter.svelte";
|
||||
|
||||
export let api = {};
|
||||
@ -41,10 +41,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
<ButtonGroupItem>
|
||||
<WithShortcut shortcut={"F7"} let:createShortcut let:shortcutLabel>
|
||||
<IconButton
|
||||
tooltip={appendInParentheses(
|
||||
tr.editingSetTextColor(),
|
||||
shortcutLabel,
|
||||
)}
|
||||
tooltip="{tr.editingSetTextColor()} ({shortcutLabel})"
|
||||
{disabled}
|
||||
on:click={forecolorWrap}
|
||||
on:mount={withButton(createShortcut)}
|
||||
@ -58,10 +55,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
<ButtonGroupItem>
|
||||
<WithShortcut shortcut={"F8"} let:createShortcut let:shortcutLabel>
|
||||
<IconButton
|
||||
tooltip={appendInParentheses(
|
||||
tr.editingChangeColor(),
|
||||
shortcutLabel,
|
||||
)}
|
||||
tooltip="{tr.editingChangeColor()} ({shortcutLabel})"
|
||||
{disabled}
|
||||
widthMultiplier={0.5}
|
||||
>
|
||||
|
@ -8,7 +8,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
import WithState from "../components/WithState.svelte";
|
||||
|
||||
import { withButton } from "../components/helpers";
|
||||
import { appendInParentheses, execCommand, queryCommandState } from "./helpers";
|
||||
import { execCommand, queryCommandState } from "./helpers";
|
||||
import { getNoteEditor } from "./OldEditorAdapter.svelte";
|
||||
|
||||
export let key: string;
|
||||
@ -49,7 +49,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
{:else if withoutState}
|
||||
<WithShortcut {shortcut} let:createShortcut let:shortcutLabel>
|
||||
<IconButton
|
||||
tooltip={appendInParentheses(tooltip, shortcutLabel)}
|
||||
tooltip="{tooltip} ({shortcutLabel})"
|
||||
{disabled}
|
||||
on:click={() => execCommand(key)}
|
||||
on:mount={withButton(createShortcut)}
|
||||
@ -66,7 +66,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
let:updateState
|
||||
>
|
||||
<IconButton
|
||||
tooltip={appendInParentheses(tooltip, shortcutLabel)}
|
||||
tooltip="{tooltip} ({shortcutLabel})"
|
||||
{active}
|
||||
{disabled}
|
||||
on:click={(event) => {
|
||||
|
@ -1,23 +0,0 @@
|
||||
<!--
|
||||
Copyright: Ankitects Pty Ltd and contributors
|
||||
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
-->
|
||||
<script context="module" lang="ts">
|
||||
import IconButton from "../components/IconButton.svelte";
|
||||
import LabelButton from "../components/LabelButton.svelte";
|
||||
import WithShortcut from "../components/WithShortcut.svelte";
|
||||
import WithContext from "../components/WithContext.svelte";
|
||||
import WithState from "../components/WithState.svelte";
|
||||
|
||||
import * as contextKeys from "../components/context-keys";
|
||||
import * as editorContextKeys from "./NoteEditor.svelte";
|
||||
|
||||
export const components = {
|
||||
IconButton,
|
||||
LabelButton,
|
||||
WithShortcut,
|
||||
WithContext,
|
||||
WithState,
|
||||
contextKeys: { ...contextKeys, ...editorContextKeys },
|
||||
};
|
||||
</script>
|
@ -13,7 +13,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
import * as tr from "../lib/ftl";
|
||||
import { getListItem } from "../lib/dom";
|
||||
import { appendInParentheses, execCommand } from "./helpers";
|
||||
import { execCommand } from "./helpers";
|
||||
import {
|
||||
ulIcon,
|
||||
olIcon,
|
||||
@ -129,10 +129,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
<IconButton
|
||||
on:click={outdentListItem}
|
||||
on:mount={withButton(createShortcut)}
|
||||
tooltip={appendInParentheses(
|
||||
tr.editingOutdent(),
|
||||
shortcutLabel,
|
||||
)}
|
||||
tooltip="{tr.editingOutdent()} ({shortcutLabel})"
|
||||
{disabled}
|
||||
>
|
||||
{@html outdentIcon}
|
||||
@ -149,10 +146,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
<IconButton
|
||||
on:click={indentListItem}
|
||||
on:mount={withButton(createShortcut)}
|
||||
tooltip={appendInParentheses(
|
||||
tr.editingIndent(),
|
||||
shortcutLabel,
|
||||
)}
|
||||
tooltip="{tr.editingIndent()} ({shortcutLabel})"
|
||||
{disabled}
|
||||
>
|
||||
{@html indentIcon}
|
||||
|
@ -3,8 +3,12 @@ Copyright: Ankitects Pty Ltd and contributors
|
||||
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
-->
|
||||
<script lang="ts">
|
||||
import OldEditorAdapter from "../editor/OldEditorAdapter.svelte";
|
||||
import type { NoteEditorAPI } from "../editor/OldEditorAdapter.svelte";
|
||||
import { onMount, onDestroy } from "svelte";
|
||||
import { bridgeCommand } from "../lib/bridgecommand";
|
||||
import { registerShortcut } from "../lib/shortcuts";
|
||||
import StickyBadge from "./StickyBadge.svelte";
|
||||
import OldEditorAdapter from "./OldEditorAdapter.svelte";
|
||||
import type { NoteEditorAPI } from "./OldEditorAdapter.svelte";
|
||||
|
||||
const api: Partial<NoteEditorAPI> = {};
|
||||
let noteEditor: OldEditorAdapter;
|
||||
@ -14,6 +18,33 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
$: if (noteEditor) {
|
||||
uiResolve(api as NoteEditorAPI);
|
||||
}
|
||||
|
||||
let stickies: boolean[] = [];
|
||||
|
||||
function setSticky(stckies: boolean[]): void {
|
||||
stickies = stckies;
|
||||
}
|
||||
|
||||
function toggleStickyAll(): void {
|
||||
bridgeCommand("toggleStickyAll", (values: boolean[]) => (stickies = values));
|
||||
}
|
||||
|
||||
let deregisterSticky: () => void;
|
||||
export function activateStickyShortcuts() {
|
||||
deregisterSticky = registerShortcut(toggleStickyAll, "Shift+F9");
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
Object.assign(globalThis, {
|
||||
setSticky,
|
||||
});
|
||||
});
|
||||
|
||||
onDestroy(() => deregisterSticky);
|
||||
</script>
|
||||
|
||||
<OldEditorAdapter bind:this={noteEditor} {api} />
|
||||
<OldEditorAdapter bind:this={noteEditor} {api}>
|
||||
<svelte:fragment slot="field-state" let:index>
|
||||
<StickyBadge active={stickies[index]} {index} />
|
||||
</svelte:fragment>
|
||||
</OldEditorAdapter>
|
||||
|
@ -52,12 +52,10 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
import RichTextBadge from "./RichTextBadge.svelte";
|
||||
import PlainTextBadge from "./PlainTextBadge.svelte";
|
||||
import StickyBadge from "./StickyBadge.svelte";
|
||||
|
||||
import { onMount, onDestroy } from "svelte";
|
||||
import { onMount } from "svelte";
|
||||
import type { Writable } from "svelte/store";
|
||||
import { bridgeCommand } from "../lib/bridgecommand";
|
||||
import { registerShortcut } from "../lib/shortcuts";
|
||||
import { isApplePlatform } from "../lib/platform";
|
||||
import { ChangeTimer } from "./change-timer";
|
||||
import { alertIcon } from "./icons";
|
||||
@ -146,11 +144,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
$tags = ts;
|
||||
}
|
||||
|
||||
let stickies: boolean[] | null = null;
|
||||
export function setSticky(sts: boolean[]): void {
|
||||
stickies = sts;
|
||||
}
|
||||
|
||||
let noteId: number | null = null;
|
||||
export function setNoteId(ntid: number): void {
|
||||
noteId = ntid;
|
||||
@ -203,15 +196,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
}
|
||||
}
|
||||
|
||||
function toggleStickyAll(): void {
|
||||
bridgeCommand("toggleStickyAll", (values: boolean[]) => (stickies = values));
|
||||
}
|
||||
|
||||
let deregisterSticky: () => void;
|
||||
export function activateStickyShortcuts() {
|
||||
deregisterSticky = registerShortcut(toggleStickyAll, "Shift+F9");
|
||||
}
|
||||
|
||||
export function focusIfField(x: number, y: number): boolean {
|
||||
const elements = document.elementsFromPoint(x, y);
|
||||
const first = elements[0];
|
||||
@ -249,6 +233,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
);
|
||||
|
||||
import { wrapInternal } from "../lib/wrap";
|
||||
import * as oldEditorAdapter from "./old-editor-adapter";
|
||||
|
||||
onMount(() => {
|
||||
function wrap(before: string, after: string): void {
|
||||
@ -270,21 +255,18 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
focusField,
|
||||
setColorButtons,
|
||||
setTags,
|
||||
setSticky,
|
||||
setBackgrounds,
|
||||
setClozeHint,
|
||||
saveNow: saveFieldNow,
|
||||
activateStickyShortcuts,
|
||||
focusIfField,
|
||||
setNoteId,
|
||||
wrap,
|
||||
...oldEditorAdapter,
|
||||
});
|
||||
|
||||
document.addEventListener("visibilitychange", saveOnPageHide);
|
||||
return () => document.removeEventListener("visibilitychange", saveOnPageHide);
|
||||
});
|
||||
|
||||
onDestroy(() => deregisterSticky);
|
||||
</script>
|
||||
|
||||
<NoteEditor>
|
||||
@ -332,9 +314,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
{/if}
|
||||
<RichTextBadge bind:off={richTextsHidden[index]} />
|
||||
<PlainTextBadge bind:off={plainTextsHidden[index]} />
|
||||
{#if stickies}
|
||||
<StickyBadge active={stickies[index]} {index} />
|
||||
{/if}
|
||||
|
||||
<slot name="field-state" {field} {index} />
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="editing-inputs">
|
||||
|
@ -4,7 +4,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
-->
|
||||
<script lang="ts">
|
||||
import Badge from "../components/Badge.svelte";
|
||||
|
||||
import * as tr from "../lib/ftl";
|
||||
import { onMount } from "svelte";
|
||||
import { htmlOn, htmlOff } from "./icons";
|
||||
@ -29,10 +28,15 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
onMount(() => editorField.element.then(shortcut));
|
||||
</script>
|
||||
|
||||
<span class:highlighted={!off} on:click|stopPropagation={toggle}>
|
||||
<span
|
||||
class="plain-text-badge"
|
||||
class:highlighted={!off}
|
||||
on:click|stopPropagation={toggle}
|
||||
>
|
||||
<Badge
|
||||
tooltip="{tr.editingHtmlEditor()} ({getPlatformString(keyCombination)})"
|
||||
iconSize={80}>{@html icon}</Badge
|
||||
tooltip="{tr.editingToggleHtmlEditor()} ({getPlatformString(keyCombination)})"
|
||||
iconSize={80}
|
||||
--icon-align="text-top">{@html icon}</Badge
|
||||
>
|
||||
</span>
|
||||
|
||||
|
@ -4,6 +4,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
-->
|
||||
<script lang="ts">
|
||||
import Badge from "../components/Badge.svelte";
|
||||
import * as tr from "../lib/ftl";
|
||||
import { richTextOn, richTextOff } from "./icons";
|
||||
|
||||
export let off: boolean;
|
||||
@ -15,8 +16,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
$: icon = off ? richTextOff : richTextOn;
|
||||
</script>
|
||||
|
||||
<span class:highlighted={off} on:click|stopPropagation={toggle}>
|
||||
<Badge iconSize={80}>{@html icon}</Badge>
|
||||
<span class="rich-text-badge" class:highlighted={off} on:click|stopPropagation={toggle}>
|
||||
<Badge
|
||||
tooltip={tr.editingToggleVisualEditor()}
|
||||
iconSize={80}
|
||||
--icon-align="text-top">{@html icon}</Badge
|
||||
>
|
||||
</span>
|
||||
|
||||
<style lang="scss">
|
||||
|
@ -12,7 +12,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
import DropdownItem from "../components/DropdownItem.svelte";
|
||||
|
||||
import { withSpan, withButton } from "../components/helpers";
|
||||
import { appendInParentheses } from "./helpers";
|
||||
import { dotsIcon } from "./icons";
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
@ -34,21 +33,21 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
event.stopImmediatePropagation();
|
||||
}}
|
||||
on:mount={withButton(createShortcut)}
|
||||
>{appendInParentheses(allLabel, shortcutLabel)}</DropdownItem
|
||||
>{allLabel} ({shortcutLabel})</DropdownItem
|
||||
>
|
||||
</WithShortcut>
|
||||
<WithShortcut shortcut="Control+C" let:createShortcut let:shortcutLabel>
|
||||
<DropdownItem
|
||||
on:click={() => dispatch("tagcopy")}
|
||||
on:mount={withButton(createShortcut)}
|
||||
>{appendInParentheses(copyLabel, shortcutLabel)}</DropdownItem
|
||||
>{copyLabel} ({shortcutLabel})</DropdownItem
|
||||
>
|
||||
</WithShortcut>
|
||||
<WithShortcut shortcut="Backspace" let:createShortcut let:shortcutLabel>
|
||||
<DropdownItem
|
||||
on:click={() => dispatch("tagdelete")}
|
||||
on:mount={withButton(createShortcut)}
|
||||
>{appendInParentheses(removeLabel, shortcutLabel)}</DropdownItem
|
||||
>{removeLabel} ({shortcutLabel})</DropdownItem
|
||||
>
|
||||
</WithShortcut>
|
||||
</DropdownMenu>
|
||||
|
@ -36,7 +36,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
<span class:highlighted={active} on:click|stopPropagation={toggle}>
|
||||
<Badge
|
||||
tooltip="{tr.editingToggleSticky()} ({getPlatformString(keyCombination)})"
|
||||
widthMultiplier={0.7}>{@html icon}</Badge
|
||||
widthMultiplier={0.7}
|
||||
--icon-align="text-top">{@html icon}</Badge
|
||||
>
|
||||
</span>
|
||||
|
||||
|
@ -16,7 +16,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
import { bridgeCommand } from "../lib/bridgecommand";
|
||||
import { wrapInternal } from "../lib/wrap";
|
||||
import { getNoteEditor } from "./OldEditorAdapter.svelte";
|
||||
import { appendInParentheses } from "./helpers";
|
||||
import { withButton } from "../components/helpers";
|
||||
import { paperclipIcon, micIcon, functionIcon } from "./icons";
|
||||
import type { RichTextInputAPI } from "./RichTextInput.svelte";
|
||||
@ -45,10 +44,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
<ButtonGroupItem>
|
||||
<WithShortcut shortcut="F3" let:createShortcut let:shortcutLabel>
|
||||
<IconButton
|
||||
tooltip={appendInParentheses(
|
||||
tr.editingAttachPicturesaudiovideo(),
|
||||
shortcutLabel,
|
||||
)}
|
||||
tooltip="{tr.editingAttachPicturesaudiovideo} ({shortcutLabel})"
|
||||
iconSize={70}
|
||||
{disabled}
|
||||
on:click={onAttachment}
|
||||
@ -62,7 +58,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
<ButtonGroupItem>
|
||||
<WithShortcut shortcut="F5" let:createShortcut let:shortcutLabel>
|
||||
<IconButton
|
||||
tooltip={appendInParentheses(tr.editingRecordAudio(), shortcutLabel)}
|
||||
tooltip="{tr.editingRecordAudio()} ({shortcutLabel})"
|
||||
iconSize={70}
|
||||
{disabled}
|
||||
on:click={onRecord}
|
||||
|
49
ts/editor/base.ts
Normal file
49
ts/editor/base.ts
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
/**
|
||||
* Code that is shared among all entry points in /ts/editor
|
||||
*/
|
||||
import "./legacy.css";
|
||||
import "./editor-base.css";
|
||||
|
||||
import "../lib/register-package";
|
||||
import "../sveltelib/export-runtime";
|
||||
|
||||
declare global {
|
||||
interface Selection {
|
||||
modify(s: string, t: string, u: string): void;
|
||||
addRange(r: Range): void;
|
||||
removeAllRanges(): void;
|
||||
getRangeAt(n: number): Range;
|
||||
}
|
||||
}
|
||||
|
||||
import { ModuleName } from "../lib/i18n";
|
||||
|
||||
export const editorModules = [
|
||||
ModuleName.EDITING,
|
||||
ModuleName.KEYBOARD,
|
||||
ModuleName.ACTIONS,
|
||||
ModuleName.BROWSING,
|
||||
];
|
||||
|
||||
export { editorToolbar } from "./EditorToolbar.svelte";
|
||||
|
||||
import IconButton from "../components/IconButton.svelte";
|
||||
import LabelButton from "../components/LabelButton.svelte";
|
||||
import WithShortcut from "../components/WithShortcut.svelte";
|
||||
import WithContext from "../components/WithContext.svelte";
|
||||
import WithState from "../components/WithState.svelte";
|
||||
|
||||
import * as contextKeys from "../components/context-keys";
|
||||
import * as editorContextKeys from "./NoteEditor.svelte";
|
||||
|
||||
export const components = {
|
||||
IconButton,
|
||||
LabelButton,
|
||||
WithShortcut,
|
||||
WithContext,
|
||||
WithState,
|
||||
contextKeys: { ...contextKeys, ...editorContextKeys },
|
||||
};
|
@ -1,10 +1,6 @@
|
||||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
export function appendInParentheses(text: string, appendix: string): string {
|
||||
return `${text} (${appendix})`;
|
||||
}
|
||||
|
||||
/// trivial wrapper to silence Svelte deprecation warnings
|
||||
export function execCommand(
|
||||
command: string,
|
||||
|
@ -1,63 +0,0 @@
|
||||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
import "./legacy.css";
|
||||
import "./editor-base.css";
|
||||
|
||||
/* eslint
|
||||
@typescript-eslint/no-explicit-any: "off",
|
||||
*/
|
||||
|
||||
import "../sveltelib/export-runtime";
|
||||
import "../lib/register-package";
|
||||
import "../domlib/surround";
|
||||
|
||||
import { filterHTML } from "../html-filter";
|
||||
import { execCommand } from "./helpers";
|
||||
import { updateAllState } from "../components/WithState.svelte";
|
||||
|
||||
export function pasteHTML(
|
||||
html: string,
|
||||
internal: boolean,
|
||||
extendedMode: boolean,
|
||||
): void {
|
||||
html = filterHTML(html, internal, extendedMode);
|
||||
|
||||
if (html !== "") {
|
||||
setFormat("inserthtml", html);
|
||||
}
|
||||
}
|
||||
|
||||
export function setFormat(cmd: string, arg?: string, _nosave = false): void {
|
||||
execCommand(cmd, false, arg);
|
||||
updateAllState(new Event(cmd));
|
||||
}
|
||||
|
||||
import { setupI18n, ModuleName } from "../lib/i18n";
|
||||
import { isApplePlatform } from "../lib/platform";
|
||||
import { registerShortcut } from "../lib/shortcuts";
|
||||
import { bridgeCommand } from "../lib/bridgecommand";
|
||||
|
||||
declare global {
|
||||
interface Selection {
|
||||
modify(s: string, t: string, u: string): void;
|
||||
addRange(r: Range): void;
|
||||
removeAllRanges(): void;
|
||||
getRangeAt(n: number): Range;
|
||||
}
|
||||
}
|
||||
|
||||
if (isApplePlatform()) {
|
||||
registerShortcut(() => bridgeCommand("paste"), "Control+Shift+V");
|
||||
}
|
||||
|
||||
export const i18n = setupI18n({
|
||||
modules: [
|
||||
ModuleName.EDITING,
|
||||
ModuleName.KEYBOARD,
|
||||
ModuleName.ACTIONS,
|
||||
ModuleName.BROWSING,
|
||||
],
|
||||
});
|
||||
|
||||
export { editorToolbar } from "./EditorToolbar.svelte";
|
@ -1,14 +1,15 @@
|
||||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
import { i18n } from ".";
|
||||
import BrowserEditor from "./BrowserEditor.svelte";
|
||||
import { editorModules } from "./base";
|
||||
import { promiseWithResolver } from "../lib/promise";
|
||||
import { globalExport } from "../lib/globals";
|
||||
import { setupI18n } from "../lib/i18n";
|
||||
|
||||
const [uiPromise, uiResolve] = promiseWithResolver();
|
||||
|
||||
async function setupBrowserEditor(): Promise<void> {
|
||||
await i18n;
|
||||
await setupI18n({ modules: editorModules });
|
||||
|
||||
new BrowserEditor({
|
||||
target: document.body,
|
||||
@ -18,10 +19,10 @@ async function setupBrowserEditor(): Promise<void> {
|
||||
|
||||
setupBrowserEditor();
|
||||
|
||||
import * as editor from ".";
|
||||
import * as base from "./base";
|
||||
|
||||
globalExport({
|
||||
...editor,
|
||||
...base,
|
||||
uiPromise,
|
||||
noteEditorPromise: uiPromise,
|
||||
});
|
||||
|
@ -1,14 +1,15 @@
|
||||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
import { i18n } from ".";
|
||||
import NoteCreator from "./NoteCreator.svelte";
|
||||
import { editorModules } from "./base";
|
||||
import { promiseWithResolver } from "../lib/promise";
|
||||
import { globalExport } from "../lib/globals";
|
||||
import { setupI18n } from "../lib/i18n";
|
||||
|
||||
const [uiPromise, uiResolve] = promiseWithResolver();
|
||||
|
||||
async function setupNoteCreator(): Promise<void> {
|
||||
await i18n;
|
||||
await setupI18n({ modules: editorModules });
|
||||
|
||||
new NoteCreator({
|
||||
target: document.body,
|
||||
@ -18,10 +19,10 @@ async function setupNoteCreator(): Promise<void> {
|
||||
|
||||
setupNoteCreator();
|
||||
|
||||
import * as editor from ".";
|
||||
import * as base from "./base";
|
||||
|
||||
globalExport({
|
||||
...editor,
|
||||
...base,
|
||||
uiPromise,
|
||||
noteEditorPromise: uiPromise,
|
||||
});
|
||||
|
@ -1,14 +1,15 @@
|
||||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
import { i18n } from "../editor";
|
||||
import ReviewerEditor from "./ReviewerEditor.svelte";
|
||||
import { editorModules } from "./base";
|
||||
import { promiseWithResolver } from "../lib/promise";
|
||||
import { globalExport } from "../lib/globals";
|
||||
import { setupI18n } from "../lib/i18n";
|
||||
|
||||
const [uiPromise, uiResolve] = promiseWithResolver();
|
||||
|
||||
async function setupReviewerEditor(): Promise<void> {
|
||||
await i18n;
|
||||
await setupI18n({ modules: editorModules });
|
||||
|
||||
new ReviewerEditor({
|
||||
target: document.body,
|
||||
@ -18,10 +19,10 @@ async function setupReviewerEditor(): Promise<void> {
|
||||
|
||||
setupReviewerEditor();
|
||||
|
||||
import * as editor from "../editor";
|
||||
import * as base from "./base";
|
||||
|
||||
globalExport({
|
||||
...editor,
|
||||
...base,
|
||||
uiPromise,
|
||||
noteEditorPromise: uiPromise,
|
||||
});
|
||||
|
23
ts/editor/old-editor-adapter.ts
Normal file
23
ts/editor/old-editor-adapter.ts
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
import { filterHTML } from "../html-filter";
|
||||
import { updateAllState } from "../components/WithState.svelte";
|
||||
import { execCommand } from "./helpers";
|
||||
|
||||
export function pasteHTML(
|
||||
html: string,
|
||||
internal: boolean,
|
||||
extendedMode: boolean,
|
||||
): void {
|
||||
html = filterHTML(html, internal, extendedMode);
|
||||
|
||||
if (html !== "") {
|
||||
setFormat("inserthtml", html);
|
||||
}
|
||||
}
|
||||
|
||||
export function setFormat(cmd: string, arg?: string, _nosave = false): void {
|
||||
execCommand(cmd, false, arg);
|
||||
updateAllState(new Event(cmd));
|
||||
}
|
30
ts/generate_page.bzl
Normal file
30
ts/generate_page.bzl
Normal file
@ -0,0 +1,30 @@
|
||||
def _generate_html_page_impl(ctx):
|
||||
ctx.actions.expand_template(
|
||||
template = ctx.file.template,
|
||||
output = ctx.outputs.output,
|
||||
substitutions = {
|
||||
"{PAGE}": ctx.attr.page,
|
||||
},
|
||||
)
|
||||
|
||||
generate_html_page = rule(
|
||||
implementation = _generate_html_page_impl,
|
||||
attrs = {
|
||||
"template": attr.label(
|
||||
default = Label("//ts:page.html"),
|
||||
allow_single_file = [".html"],
|
||||
),
|
||||
"page": attr.string(mandatory = True),
|
||||
"output": attr.output(mandatory = True),
|
||||
},
|
||||
)
|
||||
|
||||
def generate_page(page, name = "page"):
|
||||
output = page + ".html"
|
||||
|
||||
generate_html_page(
|
||||
name = name,
|
||||
page = page,
|
||||
output = output,
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
@ -2,9 +2,12 @@ load("//ts/svelte:svelte.bzl", "compile_svelte", "svelte_check")
|
||||
load("//ts:prettier.bzl", "prettier_test")
|
||||
load("//ts:eslint.bzl", "eslint_test")
|
||||
load("//ts:esbuild.bzl", "esbuild")
|
||||
load("//ts:generate_page.bzl", "generate_page")
|
||||
load("//ts:compile_sass.bzl", "compile_sass")
|
||||
load("//ts:typescript.bzl", "typescript")
|
||||
|
||||
generate_page(page = "graphs")
|
||||
|
||||
compile_sass(
|
||||
srcs = ["graphs-base.scss"],
|
||||
group = "base_css",
|
||||
@ -52,8 +55,6 @@ esbuild(
|
||||
],
|
||||
)
|
||||
|
||||
exports_files(["graphs.html"])
|
||||
|
||||
# Tests
|
||||
################
|
||||
|
||||
|
@ -3,23 +3,21 @@ Copyright: Ankitects Pty Ltd and contributors
|
||||
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
-->
|
||||
<script lang="ts">
|
||||
import type { SvelteComponent } from "svelte/internal";
|
||||
import type { SvelteComponentDev } from "svelte/internal";
|
||||
import { writable } from "svelte/store";
|
||||
import { pageTheme } from "../sveltelib/theme";
|
||||
|
||||
import { bridgeCommand } from "../lib/bridgecommand";
|
||||
|
||||
import WithGraphData from "./WithGraphData.svelte";
|
||||
|
||||
export let graphs: SvelteComponent[];
|
||||
|
||||
export let initialSearch: string;
|
||||
export let initialDays: number;
|
||||
export let controller: SvelteComponent | null;
|
||||
|
||||
const search = writable(initialSearch);
|
||||
const days = writable(initialDays);
|
||||
|
||||
export let graphs: typeof SvelteComponentDev[];
|
||||
export let controller: typeof SvelteComponentDev | null;
|
||||
|
||||
function browserSearch(event: CustomEvent) {
|
||||
bridgeCommand(`browserSearch: ${$search} ${event.detail.query}`);
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" id="viewport" content="width=device-width" />
|
||||
<link href="graphs-base.css" rel="stylesheet" />
|
||||
<link href="graphs.css" rel="stylesheet" />
|
||||
<script src="graphs.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main"></div>
|
||||
|
||||
<script>
|
||||
anki.graphs(
|
||||
document.getElementById("main"),
|
||||
[
|
||||
anki.TodayStats,
|
||||
anki.FutureDue,
|
||||
anki.CalendarGraph,
|
||||
anki.ReviewsGraph,
|
||||
anki.CardCounts,
|
||||
anki.IntervalsGraph,
|
||||
anki.EaseGraph,
|
||||
anki.HourGraph,
|
||||
anki.ButtonsGraph,
|
||||
anki.AddedGraph,
|
||||
],
|
||||
{
|
||||
controller: anki.RangeBox,
|
||||
},
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,46 +1,79 @@
|
||||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
import type { SvelteComponent } from "svelte/internal";
|
||||
|
||||
import type { SvelteComponentDev } from "svelte/internal";
|
||||
import { setupI18n, ModuleName } from "../lib/i18n";
|
||||
import { checkNightMode } from "../lib/nightmode";
|
||||
|
||||
import GraphsPage from "./GraphsPage.svelte";
|
||||
import "./graphs-base.css";
|
||||
|
||||
export { default as RangeBox } from "./RangeBox.svelte";
|
||||
const i18n = setupI18n({ modules: [ModuleName.STATISTICS, ModuleName.SCHEDULING] });
|
||||
|
||||
export { default as IntervalsGraph } from "./IntervalsGraph.svelte";
|
||||
export { default as EaseGraph } from "./EaseGraph.svelte";
|
||||
export { default as AddedGraph } from "./AddedGraph.svelte";
|
||||
export { default as TodayStats } from "./TodayStats.svelte";
|
||||
export { default as ButtonsGraph } from "./ButtonsGraph.svelte";
|
||||
export { default as CardCounts } from "./CardCounts.svelte";
|
||||
export { default as HourGraph } from "./HourGraph.svelte";
|
||||
export { default as FutureDue } from "./FutureDue.svelte";
|
||||
export { default as ReviewsGraph } from "./ReviewsGraph.svelte";
|
||||
export { default as CalendarGraph } from "./CalendarGraph.svelte";
|
||||
export { RevlogRange } from "./graph-helpers";
|
||||
|
||||
export function graphs(
|
||||
target: HTMLDivElement,
|
||||
graphs: SvelteComponent[],
|
||||
export async function setupGraphs(
|
||||
graphs: typeof SvelteComponentDev[],
|
||||
{
|
||||
search = "deck:current",
|
||||
days = 365,
|
||||
controller = null as SvelteComponent | null,
|
||||
controller = null as typeof SvelteComponentDev | null,
|
||||
} = {},
|
||||
): void {
|
||||
): Promise<GraphsPage> {
|
||||
checkNightMode();
|
||||
setupI18n({ modules: [ModuleName.STATISTICS, ModuleName.SCHEDULING] }).then(() => {
|
||||
new GraphsPage({
|
||||
target,
|
||||
props: {
|
||||
graphs,
|
||||
initialSearch: search,
|
||||
initialDays: days,
|
||||
controller,
|
||||
},
|
||||
});
|
||||
await i18n;
|
||||
|
||||
return new GraphsPage({
|
||||
target: document.body,
|
||||
props: {
|
||||
initialSearch: search,
|
||||
initialDays: days,
|
||||
graphs,
|
||||
controller,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
import TodayStats from "./TodayStats.svelte";
|
||||
import FutureDue from "./FutureDue.svelte";
|
||||
import CalendarGraph from "./CalendarGraph.svelte";
|
||||
import ReviewsGraph from "./ReviewsGraph.svelte";
|
||||
import CardCounts from "./CardCounts.svelte";
|
||||
import IntervalsGraph from "./IntervalsGraph.svelte";
|
||||
import EaseGraph from "./EaseGraph.svelte";
|
||||
import HourGraph from "./HourGraph.svelte";
|
||||
import ButtonsGraph from "./ButtonsGraph.svelte";
|
||||
import AddedGraph from "./AddedGraph.svelte";
|
||||
import { RevlogRange } from "./graph-helpers";
|
||||
import RangeBox from "./RangeBox.svelte";
|
||||
|
||||
setupGraphs(
|
||||
[
|
||||
TodayStats,
|
||||
FutureDue,
|
||||
CalendarGraph,
|
||||
ReviewsGraph,
|
||||
CardCounts,
|
||||
IntervalsGraph,
|
||||
EaseGraph,
|
||||
HourGraph,
|
||||
ButtonsGraph,
|
||||
AddedGraph,
|
||||
],
|
||||
{
|
||||
controller: RangeBox,
|
||||
},
|
||||
);
|
||||
|
||||
export const graphComponents = {
|
||||
TodayStats,
|
||||
FutureDue,
|
||||
CalendarGraph,
|
||||
ReviewsGraph,
|
||||
CardCounts,
|
||||
IntervalsGraph,
|
||||
EaseGraph,
|
||||
HourGraph,
|
||||
ButtonsGraph,
|
||||
AddedGraph,
|
||||
RangeBox,
|
||||
RevlogRange,
|
||||
};
|
||||
|
10
ts/page.html
Normal file
10
ts/page.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" id="viewport" content="width=device-width" />
|
||||
<link href="{PAGE}.css" rel="stylesheet" />
|
||||
<script src="{PAGE}.js"></script>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
@ -1,6 +1,6 @@
|
||||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
//
|
||||
|
||||
// Expose the Svelte runtime bundled with Anki, so that add-ons can require() it.
|
||||
// If they were to bundle their own runtime, things like bindings and contexts
|
||||
// would not work.
|
||||
|
Loading…
Reference in New Issue
Block a user