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-left = Float left
|
||||||
editing-float-right = Float right
|
editing-float-right = Float right
|
||||||
editing-float-none = No float
|
editing-float-none = No float
|
||||||
editing-html-editor = HTML Editor
|
|
||||||
editing-indent = Increase indent
|
editing-indent = Increase indent
|
||||||
editing-italic-text = Italic text
|
editing-italic-text = Italic text
|
||||||
editing-jump-to-tags-with-ctrlandshiftandt = Jump to tags with Ctrl+Shift+T
|
editing-jump-to-tags-with-ctrlandshiftandt = Jump to tags with Ctrl+Shift+T
|
||||||
@ -44,10 +43,13 @@ editing-subscript = Subscript
|
|||||||
editing-superscript = Superscript
|
editing-superscript = Superscript
|
||||||
editing-tags = Tags
|
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-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-sticky = Toggle sticky
|
||||||
|
editing-toggle-visual-editor = Toggle Visual Editor
|
||||||
editing-underline-text = Underline text
|
editing-underline-text = Underline text
|
||||||
editing-unordered-list = Unordered list
|
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.
|
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.
|
## 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,
|
self,
|
||||||
editor_mode=aqt.editor.EditorMode.ADD_CARDS,
|
editor_mode=aqt.editor.EditorMode.ADD_CARDS,
|
||||||
)
|
)
|
||||||
self.editor.web.eval("noteEditorPromise.then(() => activateStickyShortcuts());")
|
|
||||||
|
|
||||||
def setup_choosers(self) -> None:
|
def setup_choosers(self) -> None:
|
||||||
defaults = self.col.defaults_for_adding(
|
defaults = self.col.defaults_for_adding(
|
||||||
|
@ -63,15 +63,11 @@ class CardInfoDialog(QDialog):
|
|||||||
layout.addWidget(buttons)
|
layout.addWidget(buttons)
|
||||||
qconnect(buttons.rejected, self.reject)
|
qconnect(buttons.rejected, self.reject)
|
||||||
self.setLayout(layout)
|
self.setLayout(layout)
|
||||||
|
|
||||||
self.web.eval(
|
|
||||||
"const cardInfo = anki.cardInfo(document.getElementById('main'));"
|
|
||||||
)
|
|
||||||
self.update_card(card_id)
|
self.update_card(card_id)
|
||||||
|
|
||||||
def update_card(self, card_id: CardId | None) -> None:
|
def update_card(self, card_id: CardId | None) -> None:
|
||||||
self.web.eval(
|
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:
|
def reject(self) -> None:
|
||||||
|
@ -59,8 +59,7 @@ class ChangeNotetypeDialog(QDialog):
|
|||||||
self.setLayout(layout)
|
self.setLayout(layout)
|
||||||
|
|
||||||
self.web.eval(
|
self.web.eval(
|
||||||
f"""anki.changeNotetypePage(
|
f"""anki.setupChangeNotetypePage({notetype_id}, {notetype_id});"""
|
||||||
document.getElementById('main'), {notetype_id}, {notetype_id});"""
|
|
||||||
)
|
)
|
||||||
self.setWindowTitle(tr.browsing_change_notetype())
|
self.setWindowTitle(tr.browsing_change_notetype())
|
||||||
|
|
||||||
|
@ -51,8 +51,7 @@ class DeckOptionsDialog(QDialog):
|
|||||||
self.setLayout(layout)
|
self.setLayout(layout)
|
||||||
|
|
||||||
self.web.eval(
|
self.web.eval(
|
||||||
f"""const $deckOptions = anki.deckOptions(
|
f"""const $deckOptions = anki.setupDeckOptions({self._deck["id"]});"""
|
||||||
document.getElementById('main'), {self._deck["id"]});"""
|
|
||||||
)
|
)
|
||||||
self.setWindowTitle(
|
self.setWindowTitle(
|
||||||
without_unicode_isolation(tr.actions_options_for(val=self._deck["name"]))
|
without_unicode_isolation(tr.actions_options_for(val=self._deck["name"]))
|
||||||
|
@ -15,6 +15,7 @@ exports_files([
|
|||||||
"jest.config.js",
|
"jest.config.js",
|
||||||
"package.json",
|
"package.json",
|
||||||
"protobuf-no-long.js",
|
"protobuf-no-long.js",
|
||||||
|
"page.html",
|
||||||
])
|
])
|
||||||
|
|
||||||
# a copy needs to be placed in bazel-bin for libs with
|
# 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:eslint.bzl", "eslint_test")
|
||||||
load("//ts/svelte:svelte.bzl", "compile_svelte", "svelte_check")
|
load("//ts/svelte:svelte.bzl", "compile_svelte", "svelte_check")
|
||||||
load("//ts:esbuild.bzl", "esbuild")
|
load("//ts:esbuild.bzl", "esbuild")
|
||||||
|
load("//ts:generate_page.bzl", "generate_page")
|
||||||
load("//ts:compile_sass.bzl", "compile_sass")
|
load("//ts:compile_sass.bzl", "compile_sass")
|
||||||
load("//ts:typescript.bzl", "typescript")
|
load("//ts:typescript.bzl", "typescript")
|
||||||
|
|
||||||
|
generate_page(page = "card-info")
|
||||||
|
|
||||||
compile_sass(
|
compile_sass(
|
||||||
srcs = ["card-info-base.scss"],
|
|
||||||
group = "base_css",
|
group = "base_css",
|
||||||
|
srcs = ["card-info-base.scss"],
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//sass:base_lib",
|
"//sass:base_lib",
|
||||||
@ -17,8 +20,8 @@ compile_sass(
|
|||||||
)
|
)
|
||||||
|
|
||||||
_ts_deps = [
|
_ts_deps = [
|
||||||
"//ts/components",
|
|
||||||
"//ts/lib",
|
"//ts/lib",
|
||||||
|
"//ts/components",
|
||||||
"@npm//@fluent",
|
"@npm//@fluent",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -50,8 +53,6 @@ esbuild(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
exports_files(["card-info.html"])
|
|
||||||
|
|
||||||
# Tests
|
# 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 { checkNightMode } from "../lib/nightmode";
|
||||||
|
|
||||||
import CardInfo from "./CardInfo.svelte";
|
import CardInfo from "./CardInfo.svelte";
|
||||||
|
import "./card-info-base.css";
|
||||||
|
|
||||||
export async function cardInfo(target: HTMLDivElement): Promise<CardInfo> {
|
const i18n = setupI18n({
|
||||||
checkNightMode();
|
|
||||||
await setupI18n({
|
|
||||||
modules: [ModuleName.CARD_STATS, ModuleName.SCHEDULING, ModuleName.STATISTICS],
|
modules: [ModuleName.CARD_STATS, ModuleName.SCHEDULING, ModuleName.STATISTICS],
|
||||||
});
|
});
|
||||||
return new CardInfo({ target });
|
|
||||||
|
export async function setupCardInfo(): Promise<CardInfo> {
|
||||||
|
checkNightMode();
|
||||||
|
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:eslint.bzl", "eslint_test")
|
||||||
load("//ts/svelte:svelte.bzl", "compile_svelte", "svelte_check")
|
load("//ts/svelte:svelte.bzl", "compile_svelte", "svelte_check")
|
||||||
load("//ts:esbuild.bzl", "esbuild")
|
load("//ts:esbuild.bzl", "esbuild")
|
||||||
|
load("//ts:generate_page.bzl", "generate_page")
|
||||||
load("//ts:compile_sass.bzl", "compile_sass")
|
load("//ts:compile_sass.bzl", "compile_sass")
|
||||||
load("//ts:typescript.bzl", "typescript")
|
load("//ts:typescript.bzl", "typescript")
|
||||||
load("//ts:jest.bzl", "jest_test")
|
load("//ts:jest.bzl", "jest_test")
|
||||||
|
|
||||||
|
generate_page(page = "change-notetype")
|
||||||
|
|
||||||
compile_sass(
|
compile_sass(
|
||||||
srcs = ["change-notetype-base.scss"],
|
srcs = ["change-notetype-base.scss"],
|
||||||
group = "base_css",
|
group = "base_css",
|
||||||
@ -54,8 +57,6 @@ esbuild(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
exports_files(["change-notetype.html"])
|
|
||||||
|
|
||||||
# Tests
|
# 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 { ChangeNotetypeState, getChangeNotetypeInfo, getNotetypeNames } from "./lib";
|
||||||
import { setupI18n, ModuleName } from "../lib/i18n";
|
import { setupI18n, ModuleName } from "../lib/i18n";
|
||||||
import { checkNightMode } from "../lib/nightmode";
|
import { checkNightMode } from "../lib/nightmode";
|
||||||
import ChangeNotetypePage from "./ChangeNotetypePage.svelte";
|
|
||||||
|
|
||||||
export async function changeNotetypePage(
|
import ChangeNotetypePage from "./ChangeNotetypePage.svelte";
|
||||||
target: HTMLDivElement,
|
import "./change-notetype-base.css";
|
||||||
|
|
||||||
|
export async function setupChangeNotetypePage(
|
||||||
oldNotetypeId: number,
|
oldNotetypeId: number,
|
||||||
newNotetypeId: number,
|
newNotetypeId: number,
|
||||||
): Promise<ChangeNotetypePage> {
|
): Promise<ChangeNotetypePage> {
|
||||||
@ -31,7 +32,13 @@ export async function changeNotetypePage(
|
|||||||
|
|
||||||
const state = new ChangeNotetypeState(names, info);
|
const state = new ChangeNotetypeState(names, info);
|
||||||
return new ChangeNotetypePage({
|
return new ChangeNotetypePage({
|
||||||
target,
|
target: document.body,
|
||||||
props: { state },
|
props: { state } as any,
|
||||||
} 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:
|
for scss_file in srcs:
|
||||||
base = scss_file.replace(".scss", "")
|
base = scss_file.replace(".scss", "")
|
||||||
name = base + "_sass"
|
name = base + "_sass"
|
||||||
css_file = base + ".css"
|
|
||||||
css_files.append(css_file)
|
|
||||||
|
|
||||||
sass_binary(
|
sass_binary(
|
||||||
name = name,
|
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(
|
native.filegroup(
|
||||||
name = group,
|
name = group,
|
||||||
srcs = css_files,
|
srcs = css_files,
|
||||||
|
@ -85,12 +85,14 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||||||
|
|
||||||
api = {
|
api = {
|
||||||
show: dropdown.show.bind(dropdown),
|
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),
|
hide: dropdown.hide.bind(dropdown),
|
||||||
update: dropdown.update.bind(dropdown),
|
update: dropdown.update.bind(dropdown),
|
||||||
dispose: dropdown.dispose.bind(dropdown),
|
dispose: dropdown.dispose.bind(dropdown),
|
||||||
isVisible,
|
isVisible,
|
||||||
};
|
} as any;
|
||||||
|
|
||||||
return api;
|
return api;
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,15 @@ load("//ts:prettier.bzl", "prettier_test")
|
|||||||
load("//ts:eslint.bzl", "eslint_test")
|
load("//ts:eslint.bzl", "eslint_test")
|
||||||
load("//ts/svelte:svelte.bzl", "compile_svelte", "svelte_check")
|
load("//ts/svelte:svelte.bzl", "compile_svelte", "svelte_check")
|
||||||
load("//ts:esbuild.bzl", "esbuild")
|
load("//ts:esbuild.bzl", "esbuild")
|
||||||
|
load("//ts:generate_page.bzl", "generate_page")
|
||||||
load("//ts:compile_sass.bzl", "compile_sass")
|
load("//ts:compile_sass.bzl", "compile_sass")
|
||||||
load("//ts:typescript.bzl", "typescript")
|
load("//ts:typescript.bzl", "typescript")
|
||||||
|
|
||||||
|
generate_page(page = "congrats")
|
||||||
|
|
||||||
compile_sass(
|
compile_sass(
|
||||||
srcs = ["congrats-base.scss"],
|
srcs = ["congrats-base.scss"],
|
||||||
group = "congrats_css",
|
group = "base_css",
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//sass:base_lib",
|
"//sass:base_lib",
|
||||||
@ -20,7 +23,7 @@ compile_svelte(
|
|||||||
)
|
)
|
||||||
|
|
||||||
typescript(
|
typescript(
|
||||||
name = "congrats_ts",
|
name = "index",
|
||||||
deps = [
|
deps = [
|
||||||
":svelte",
|
":svelte",
|
||||||
"//ts/components",
|
"//ts/components",
|
||||||
@ -35,19 +38,18 @@ esbuild(
|
|||||||
name = "congrats",
|
name = "congrats",
|
||||||
args = {
|
args = {
|
||||||
"globalName": "anki",
|
"globalName": "anki",
|
||||||
|
"loader": {".svg": "text"},
|
||||||
},
|
},
|
||||||
entry_point = "index.ts",
|
entry_point = "index.ts",
|
||||||
output_css = "congrats.css",
|
output_css = "congrats.css",
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
":congrats_css",
|
":base_css",
|
||||||
":congrats_ts",
|
":index",
|
||||||
":svelte",
|
":svelte",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
exports_files(["congrats.html"])
|
|
||||||
|
|
||||||
# Tests
|
# 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 { checkNightMode } from "../lib/nightmode";
|
||||||
|
|
||||||
import CongratsPage from "./CongratsPage.svelte";
|
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();
|
checkNightMode();
|
||||||
await setupI18n({ modules: [ModuleName.SCHEDULING] });
|
await i18n;
|
||||||
|
|
||||||
const info = await getCongratsInfo();
|
const info = await getCongratsInfo();
|
||||||
const page = new CongratsPage({
|
const page = new CongratsPage({
|
||||||
target,
|
target: document.body,
|
||||||
props: { info },
|
props: { info },
|
||||||
});
|
});
|
||||||
|
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
getCongratsInfo().then((info) => {
|
getCongratsInfo().then((info) => {
|
||||||
page.$set({ info });
|
page.$set({ info });
|
||||||
});
|
});
|
||||||
}, 60000);
|
}, 60000);
|
||||||
|
|
||||||
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setupCongrats();
|
||||||
|
@ -2,10 +2,13 @@ load("//ts:prettier.bzl", "prettier_test")
|
|||||||
load("//ts:eslint.bzl", "eslint_test")
|
load("//ts:eslint.bzl", "eslint_test")
|
||||||
load("//ts/svelte:svelte.bzl", "compile_svelte", "svelte_check")
|
load("//ts/svelte:svelte.bzl", "compile_svelte", "svelte_check")
|
||||||
load("//ts:esbuild.bzl", "esbuild")
|
load("//ts:esbuild.bzl", "esbuild")
|
||||||
|
load("//ts:generate_page.bzl", "generate_page")
|
||||||
load("//ts:compile_sass.bzl", "compile_sass")
|
load("//ts:compile_sass.bzl", "compile_sass")
|
||||||
load("//ts:jest.bzl", "jest_test")
|
load("//ts:jest.bzl", "jest_test")
|
||||||
load("//ts:typescript.bzl", "typescript")
|
load("//ts:typescript.bzl", "typescript")
|
||||||
|
|
||||||
|
generate_page(page = "deck-options")
|
||||||
|
|
||||||
compile_sass(
|
compile_sass(
|
||||||
srcs = ["deck-options-base.scss"],
|
srcs = ["deck-options-base.scss"],
|
||||||
group = "base_css",
|
group = "base_css",
|
||||||
@ -26,6 +29,7 @@ _ts_deps = [
|
|||||||
"@npm//@popperjs",
|
"@npm//@popperjs",
|
||||||
"@npm//@types/jest",
|
"@npm//@types/jest",
|
||||||
"@npm//bootstrap-icons",
|
"@npm//bootstrap-icons",
|
||||||
|
"@npm//bootstrap",
|
||||||
"@npm//lodash-es",
|
"@npm//lodash-es",
|
||||||
"@npm//svelte",
|
"@npm//svelte",
|
||||||
"@npm//marked",
|
"@npm//marked",
|
||||||
@ -60,8 +64,6 @@ esbuild(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
exports_files(["deck-options.html"])
|
|
||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
################
|
################
|
||||||
|
|
||||||
@ -79,11 +81,11 @@ svelte_check(
|
|||||||
"//sass:night_mode_lib",
|
"//sass:night_mode_lib",
|
||||||
"//sass:breakpoints_lib",
|
"//sass:breakpoints_lib",
|
||||||
"//sass/bootstrap",
|
"//sass/bootstrap",
|
||||||
|
"//ts/components",
|
||||||
|
"//ts/sveltelib:sveltelib_pkg",
|
||||||
"@npm//@types/bootstrap",
|
"@npm//@types/bootstrap",
|
||||||
"@npm//@types/lodash-es",
|
"@npm//@types/lodash-es",
|
||||||
"@npm//@types/marked",
|
"@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>
|
<ButtonGroup>
|
||||||
<ButtonGroupItem>
|
<ButtonGroupItem>
|
||||||
<WithShortcut shortcut={"Control+Enter"} let:createShortcut let:shortcutLabel>
|
<WithShortcut shortcut="Control+Enter" let:createShortcut let:shortcutLabel>
|
||||||
<LabelButton
|
<LabelButton
|
||||||
theme="primary"
|
theme="primary"
|
||||||
on:click={() => save(false)}
|
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 { getDeckOptionsInfo, DeckOptionsState } from "./lib";
|
||||||
import { setupI18n, ModuleName } from "../lib/i18n";
|
import { setupI18n, ModuleName } from "../lib/i18n";
|
||||||
import { checkNightMode } from "../lib/nightmode";
|
import { checkNightMode } from "../lib/nightmode";
|
||||||
import DeckOptionsPage from "./DeckOptionsPage.svelte";
|
|
||||||
import { touchDeviceKey, modalsKey } from "../components/context-keys";
|
import { touchDeviceKey, modalsKey } from "../components/context-keys";
|
||||||
|
|
||||||
export async function deckOptions(
|
import DeckOptionsPage from "./DeckOptionsPage.svelte";
|
||||||
target: HTMLDivElement,
|
import "./deck-options-base.css";
|
||||||
deckId: number,
|
|
||||||
): Promise<DeckOptionsPage> {
|
const i18n = setupI18n({
|
||||||
const [info] = await Promise.all([
|
|
||||||
getDeckOptionsInfo(deckId),
|
|
||||||
setupI18n({
|
|
||||||
modules: [
|
modules: [
|
||||||
ModuleName.SCHEDULING,
|
ModuleName.SCHEDULING,
|
||||||
ModuleName.ACTIONS,
|
ModuleName.ACTIONS,
|
||||||
ModuleName.DECK_CONFIG,
|
ModuleName.DECK_CONFIG,
|
||||||
ModuleName.KEYBOARD,
|
ModuleName.KEYBOARD,
|
||||||
],
|
],
|
||||||
}),
|
});
|
||||||
]);
|
|
||||||
|
export async function setupDeckOptions(deckId: number): Promise<DeckOptionsPage> {
|
||||||
|
const [info] = await Promise.all([getDeckOptionsInfo(deckId), i18n]);
|
||||||
|
|
||||||
checkNightMode();
|
checkNightMode();
|
||||||
|
|
||||||
const context = new Map();
|
const context = new Map();
|
||||||
|
context.set(modalsKey, new Map());
|
||||||
const modals = new Map();
|
context.set(touchDeviceKey, "ontouchstart" in document.documentElement);
|
||||||
context.set(modalsKey, modals);
|
|
||||||
|
|
||||||
const touchDevice = "ontouchstart" in document.documentElement;
|
|
||||||
context.set(touchDeviceKey, touchDevice);
|
|
||||||
|
|
||||||
const state = new DeckOptionsState(deckId, info);
|
const state = new DeckOptionsState(deckId, info);
|
||||||
return new DeckOptionsPage({
|
return new DeckOptionsPage({
|
||||||
target,
|
target: document.body,
|
||||||
props: { state },
|
props: { state },
|
||||||
context,
|
context,
|
||||||
} as any);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
import TitledContainer from "./TitledContainer.svelte";
|
import TitledContainer from "./TitledContainer.svelte";
|
||||||
@ -60,3 +54,7 @@ export const components = {
|
|||||||
EnumSelectorRow,
|
EnumSelectorRow,
|
||||||
SwitchRow,
|
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 { registerShortcut } from "../lib/shortcuts";
|
||||||
import { placeCaretAfterContent } from "../domlib/place-caret";
|
import { placeCaretAfterContent } from "../domlib/place-caret";
|
||||||
import { saveSelection, restoreSelection } from "../domlib/location";
|
import { saveSelection, restoreSelection } from "../domlib/location";
|
||||||
|
import { isApplePlatform } from "../lib/platform";
|
||||||
|
import { bridgeCommand } from "../lib/bridgecommand";
|
||||||
import type { SelectionLocation } from "../domlib/location";
|
import type { SelectionLocation } from "../domlib/location";
|
||||||
|
|
||||||
const locationEvents: (() => void)[] = [];
|
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 {
|
export function preventBuiltinContentEditableShortcuts(editable: HTMLElement): void {
|
||||||
for (const keyCombination of ["Control+B", "Control+U", "Control+I", "Control+R"]) {
|
for (const keyCombination of ["Control+B", "Control+U", "Control+I", "Control+R"]) {
|
||||||
registerShortcut(preventDefault, keyCombination, editable);
|
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 Badge from "../components/Badge.svelte";
|
||||||
|
|
||||||
import { withSpan } from "../components/helpers";
|
import { withSpan } from "../components/helpers";
|
||||||
import { appendInParentheses } from "./helpers";
|
|
||||||
import { tagIcon, addTagIcon } from "./icons";
|
import { tagIcon, addTagIcon } from "./icons";
|
||||||
|
|
||||||
const tooltip = "Add tag";
|
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">
|
<div class="add-icon">
|
||||||
<Badge
|
<Badge
|
||||||
class="d-flex me-1"
|
class="d-flex me-1"
|
||||||
tooltip={appendInParentheses(tooltip, shortcutLabel)}
|
tooltip="{tooltip} ({shortcutLabel})"
|
||||||
on:click
|
on:click
|
||||||
on:mount={withSpan(createShortcut)}
|
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 { bridgeCommand } from "../lib/bridgecommand";
|
||||||
import { withButton } from "../components/helpers";
|
import { withButton } from "../components/helpers";
|
||||||
import { textColorIcon, highlightColorIcon, arrowIcon } from "./icons";
|
import { textColorIcon, highlightColorIcon, arrowIcon } from "./icons";
|
||||||
import { appendInParentheses, execCommand } from "./helpers";
|
import { execCommand } from "./helpers";
|
||||||
import { getNoteEditor } from "./OldEditorAdapter.svelte";
|
import { getNoteEditor } from "./OldEditorAdapter.svelte";
|
||||||
|
|
||||||
export let api = {};
|
export let api = {};
|
||||||
@ -41,10 +41,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||||||
<ButtonGroupItem>
|
<ButtonGroupItem>
|
||||||
<WithShortcut shortcut={"F7"} let:createShortcut let:shortcutLabel>
|
<WithShortcut shortcut={"F7"} let:createShortcut let:shortcutLabel>
|
||||||
<IconButton
|
<IconButton
|
||||||
tooltip={appendInParentheses(
|
tooltip="{tr.editingSetTextColor()} ({shortcutLabel})"
|
||||||
tr.editingSetTextColor(),
|
|
||||||
shortcutLabel,
|
|
||||||
)}
|
|
||||||
{disabled}
|
{disabled}
|
||||||
on:click={forecolorWrap}
|
on:click={forecolorWrap}
|
||||||
on:mount={withButton(createShortcut)}
|
on:mount={withButton(createShortcut)}
|
||||||
@ -58,10 +55,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||||||
<ButtonGroupItem>
|
<ButtonGroupItem>
|
||||||
<WithShortcut shortcut={"F8"} let:createShortcut let:shortcutLabel>
|
<WithShortcut shortcut={"F8"} let:createShortcut let:shortcutLabel>
|
||||||
<IconButton
|
<IconButton
|
||||||
tooltip={appendInParentheses(
|
tooltip="{tr.editingChangeColor()} ({shortcutLabel})"
|
||||||
tr.editingChangeColor(),
|
|
||||||
shortcutLabel,
|
|
||||||
)}
|
|
||||||
{disabled}
|
{disabled}
|
||||||
widthMultiplier={0.5}
|
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 WithState from "../components/WithState.svelte";
|
||||||
|
|
||||||
import { withButton } from "../components/helpers";
|
import { withButton } from "../components/helpers";
|
||||||
import { appendInParentheses, execCommand, queryCommandState } from "./helpers";
|
import { execCommand, queryCommandState } from "./helpers";
|
||||||
import { getNoteEditor } from "./OldEditorAdapter.svelte";
|
import { getNoteEditor } from "./OldEditorAdapter.svelte";
|
||||||
|
|
||||||
export let key: string;
|
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}
|
{:else if withoutState}
|
||||||
<WithShortcut {shortcut} let:createShortcut let:shortcutLabel>
|
<WithShortcut {shortcut} let:createShortcut let:shortcutLabel>
|
||||||
<IconButton
|
<IconButton
|
||||||
tooltip={appendInParentheses(tooltip, shortcutLabel)}
|
tooltip="{tooltip} ({shortcutLabel})"
|
||||||
{disabled}
|
{disabled}
|
||||||
on:click={() => execCommand(key)}
|
on:click={() => execCommand(key)}
|
||||||
on:mount={withButton(createShortcut)}
|
on:mount={withButton(createShortcut)}
|
||||||
@ -66,7 +66,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||||||
let:updateState
|
let:updateState
|
||||||
>
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
tooltip={appendInParentheses(tooltip, shortcutLabel)}
|
tooltip="{tooltip} ({shortcutLabel})"
|
||||||
{active}
|
{active}
|
||||||
{disabled}
|
{disabled}
|
||||||
on:click={(event) => {
|
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 * as tr from "../lib/ftl";
|
||||||
import { getListItem } from "../lib/dom";
|
import { getListItem } from "../lib/dom";
|
||||||
import { appendInParentheses, execCommand } from "./helpers";
|
import { execCommand } from "./helpers";
|
||||||
import {
|
import {
|
||||||
ulIcon,
|
ulIcon,
|
||||||
olIcon,
|
olIcon,
|
||||||
@ -129,10 +129,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||||||
<IconButton
|
<IconButton
|
||||||
on:click={outdentListItem}
|
on:click={outdentListItem}
|
||||||
on:mount={withButton(createShortcut)}
|
on:mount={withButton(createShortcut)}
|
||||||
tooltip={appendInParentheses(
|
tooltip="{tr.editingOutdent()} ({shortcutLabel})"
|
||||||
tr.editingOutdent(),
|
|
||||||
shortcutLabel,
|
|
||||||
)}
|
|
||||||
{disabled}
|
{disabled}
|
||||||
>
|
>
|
||||||
{@html outdentIcon}
|
{@html outdentIcon}
|
||||||
@ -149,10 +146,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||||||
<IconButton
|
<IconButton
|
||||||
on:click={indentListItem}
|
on:click={indentListItem}
|
||||||
on:mount={withButton(createShortcut)}
|
on:mount={withButton(createShortcut)}
|
||||||
tooltip={appendInParentheses(
|
tooltip="{tr.editingIndent()} ({shortcutLabel})"
|
||||||
tr.editingIndent(),
|
|
||||||
shortcutLabel,
|
|
||||||
)}
|
|
||||||
{disabled}
|
{disabled}
|
||||||
>
|
>
|
||||||
{@html indentIcon}
|
{@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
|
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import OldEditorAdapter from "../editor/OldEditorAdapter.svelte";
|
import { onMount, onDestroy } from "svelte";
|
||||||
import type { NoteEditorAPI } from "../editor/OldEditorAdapter.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> = {};
|
const api: Partial<NoteEditorAPI> = {};
|
||||||
let noteEditor: OldEditorAdapter;
|
let noteEditor: OldEditorAdapter;
|
||||||
@ -14,6 +18,33 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||||||
$: if (noteEditor) {
|
$: if (noteEditor) {
|
||||||
uiResolve(api as NoteEditorAPI);
|
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>
|
</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 RichTextBadge from "./RichTextBadge.svelte";
|
||||||
import PlainTextBadge from "./PlainTextBadge.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 type { Writable } from "svelte/store";
|
||||||
import { bridgeCommand } from "../lib/bridgecommand";
|
import { bridgeCommand } from "../lib/bridgecommand";
|
||||||
import { registerShortcut } from "../lib/shortcuts";
|
|
||||||
import { isApplePlatform } from "../lib/platform";
|
import { isApplePlatform } from "../lib/platform";
|
||||||
import { ChangeTimer } from "./change-timer";
|
import { ChangeTimer } from "./change-timer";
|
||||||
import { alertIcon } from "./icons";
|
import { alertIcon } from "./icons";
|
||||||
@ -146,11 +144,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||||||
$tags = ts;
|
$tags = ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
let stickies: boolean[] | null = null;
|
|
||||||
export function setSticky(sts: boolean[]): void {
|
|
||||||
stickies = sts;
|
|
||||||
}
|
|
||||||
|
|
||||||
let noteId: number | null = null;
|
let noteId: number | null = null;
|
||||||
export function setNoteId(ntid: number): void {
|
export function setNoteId(ntid: number): void {
|
||||||
noteId = ntid;
|
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 {
|
export function focusIfField(x: number, y: number): boolean {
|
||||||
const elements = document.elementsFromPoint(x, y);
|
const elements = document.elementsFromPoint(x, y);
|
||||||
const first = elements[0];
|
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 { wrapInternal } from "../lib/wrap";
|
||||||
|
import * as oldEditorAdapter from "./old-editor-adapter";
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
function wrap(before: string, after: string): void {
|
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,
|
focusField,
|
||||||
setColorButtons,
|
setColorButtons,
|
||||||
setTags,
|
setTags,
|
||||||
setSticky,
|
|
||||||
setBackgrounds,
|
setBackgrounds,
|
||||||
setClozeHint,
|
setClozeHint,
|
||||||
saveNow: saveFieldNow,
|
saveNow: saveFieldNow,
|
||||||
activateStickyShortcuts,
|
|
||||||
focusIfField,
|
focusIfField,
|
||||||
setNoteId,
|
setNoteId,
|
||||||
wrap,
|
wrap,
|
||||||
|
...oldEditorAdapter,
|
||||||
});
|
});
|
||||||
|
|
||||||
document.addEventListener("visibilitychange", saveOnPageHide);
|
document.addEventListener("visibilitychange", saveOnPageHide);
|
||||||
return () => document.removeEventListener("visibilitychange", saveOnPageHide);
|
return () => document.removeEventListener("visibilitychange", saveOnPageHide);
|
||||||
});
|
});
|
||||||
|
|
||||||
onDestroy(() => deregisterSticky);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<NoteEditor>
|
<NoteEditor>
|
||||||
@ -332,9 +314,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||||||
{/if}
|
{/if}
|
||||||
<RichTextBadge bind:off={richTextsHidden[index]} />
|
<RichTextBadge bind:off={richTextsHidden[index]} />
|
||||||
<PlainTextBadge bind:off={plainTextsHidden[index]} />
|
<PlainTextBadge bind:off={plainTextsHidden[index]} />
|
||||||
{#if stickies}
|
|
||||||
<StickyBadge active={stickies[index]} {index} />
|
<slot name="field-state" {field} {index} />
|
||||||
{/if}
|
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
|
|
||||||
<svelte:fragment slot="editing-inputs">
|
<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">
|
<script lang="ts">
|
||||||
import Badge from "../components/Badge.svelte";
|
import Badge from "../components/Badge.svelte";
|
||||||
|
|
||||||
import * as tr from "../lib/ftl";
|
import * as tr from "../lib/ftl";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { htmlOn, htmlOff } from "./icons";
|
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));
|
onMount(() => editorField.element.then(shortcut));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<span class:highlighted={!off} on:click|stopPropagation={toggle}>
|
<span
|
||||||
|
class="plain-text-badge"
|
||||||
|
class:highlighted={!off}
|
||||||
|
on:click|stopPropagation={toggle}
|
||||||
|
>
|
||||||
<Badge
|
<Badge
|
||||||
tooltip="{tr.editingHtmlEditor()} ({getPlatformString(keyCombination)})"
|
tooltip="{tr.editingToggleHtmlEditor()} ({getPlatformString(keyCombination)})"
|
||||||
iconSize={80}>{@html icon}</Badge
|
iconSize={80}
|
||||||
|
--icon-align="text-top">{@html icon}</Badge
|
||||||
>
|
>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Badge from "../components/Badge.svelte";
|
import Badge from "../components/Badge.svelte";
|
||||||
|
import * as tr from "../lib/ftl";
|
||||||
import { richTextOn, richTextOff } from "./icons";
|
import { richTextOn, richTextOff } from "./icons";
|
||||||
|
|
||||||
export let off: boolean;
|
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;
|
$: icon = off ? richTextOff : richTextOn;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<span class:highlighted={off} on:click|stopPropagation={toggle}>
|
<span class="rich-text-badge" class:highlighted={off} on:click|stopPropagation={toggle}>
|
||||||
<Badge iconSize={80}>{@html icon}</Badge>
|
<Badge
|
||||||
|
tooltip={tr.editingToggleVisualEditor()}
|
||||||
|
iconSize={80}
|
||||||
|
--icon-align="text-top">{@html icon}</Badge
|
||||||
|
>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<style lang="scss">
|
<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 DropdownItem from "../components/DropdownItem.svelte";
|
||||||
|
|
||||||
import { withSpan, withButton } from "../components/helpers";
|
import { withSpan, withButton } from "../components/helpers";
|
||||||
import { appendInParentheses } from "./helpers";
|
|
||||||
import { dotsIcon } from "./icons";
|
import { dotsIcon } from "./icons";
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
@ -34,21 +33,21 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||||||
event.stopImmediatePropagation();
|
event.stopImmediatePropagation();
|
||||||
}}
|
}}
|
||||||
on:mount={withButton(createShortcut)}
|
on:mount={withButton(createShortcut)}
|
||||||
>{appendInParentheses(allLabel, shortcutLabel)}</DropdownItem
|
>{allLabel} ({shortcutLabel})</DropdownItem
|
||||||
>
|
>
|
||||||
</WithShortcut>
|
</WithShortcut>
|
||||||
<WithShortcut shortcut="Control+C" let:createShortcut let:shortcutLabel>
|
<WithShortcut shortcut="Control+C" let:createShortcut let:shortcutLabel>
|
||||||
<DropdownItem
|
<DropdownItem
|
||||||
on:click={() => dispatch("tagcopy")}
|
on:click={() => dispatch("tagcopy")}
|
||||||
on:mount={withButton(createShortcut)}
|
on:mount={withButton(createShortcut)}
|
||||||
>{appendInParentheses(copyLabel, shortcutLabel)}</DropdownItem
|
>{copyLabel} ({shortcutLabel})</DropdownItem
|
||||||
>
|
>
|
||||||
</WithShortcut>
|
</WithShortcut>
|
||||||
<WithShortcut shortcut="Backspace" let:createShortcut let:shortcutLabel>
|
<WithShortcut shortcut="Backspace" let:createShortcut let:shortcutLabel>
|
||||||
<DropdownItem
|
<DropdownItem
|
||||||
on:click={() => dispatch("tagdelete")}
|
on:click={() => dispatch("tagdelete")}
|
||||||
on:mount={withButton(createShortcut)}
|
on:mount={withButton(createShortcut)}
|
||||||
>{appendInParentheses(removeLabel, shortcutLabel)}</DropdownItem
|
>{removeLabel} ({shortcutLabel})</DropdownItem
|
||||||
>
|
>
|
||||||
</WithShortcut>
|
</WithShortcut>
|
||||||
</DropdownMenu>
|
</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}>
|
<span class:highlighted={active} on:click|stopPropagation={toggle}>
|
||||||
<Badge
|
<Badge
|
||||||
tooltip="{tr.editingToggleSticky()} ({getPlatformString(keyCombination)})"
|
tooltip="{tr.editingToggleSticky()} ({getPlatformString(keyCombination)})"
|
||||||
widthMultiplier={0.7}>{@html icon}</Badge
|
widthMultiplier={0.7}
|
||||||
|
--icon-align="text-top">{@html icon}</Badge
|
||||||
>
|
>
|
||||||
</span>
|
</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 { bridgeCommand } from "../lib/bridgecommand";
|
||||||
import { wrapInternal } from "../lib/wrap";
|
import { wrapInternal } from "../lib/wrap";
|
||||||
import { getNoteEditor } from "./OldEditorAdapter.svelte";
|
import { getNoteEditor } from "./OldEditorAdapter.svelte";
|
||||||
import { appendInParentheses } from "./helpers";
|
|
||||||
import { withButton } from "../components/helpers";
|
import { withButton } from "../components/helpers";
|
||||||
import { paperclipIcon, micIcon, functionIcon } from "./icons";
|
import { paperclipIcon, micIcon, functionIcon } from "./icons";
|
||||||
import type { RichTextInputAPI } from "./RichTextInput.svelte";
|
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>
|
<ButtonGroupItem>
|
||||||
<WithShortcut shortcut="F3" let:createShortcut let:shortcutLabel>
|
<WithShortcut shortcut="F3" let:createShortcut let:shortcutLabel>
|
||||||
<IconButton
|
<IconButton
|
||||||
tooltip={appendInParentheses(
|
tooltip="{tr.editingAttachPicturesaudiovideo} ({shortcutLabel})"
|
||||||
tr.editingAttachPicturesaudiovideo(),
|
|
||||||
shortcutLabel,
|
|
||||||
)}
|
|
||||||
iconSize={70}
|
iconSize={70}
|
||||||
{disabled}
|
{disabled}
|
||||||
on:click={onAttachment}
|
on:click={onAttachment}
|
||||||
@ -62,7 +58,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||||||
<ButtonGroupItem>
|
<ButtonGroupItem>
|
||||||
<WithShortcut shortcut="F5" let:createShortcut let:shortcutLabel>
|
<WithShortcut shortcut="F5" let:createShortcut let:shortcutLabel>
|
||||||
<IconButton
|
<IconButton
|
||||||
tooltip={appendInParentheses(tr.editingRecordAudio(), shortcutLabel)}
|
tooltip="{tr.editingRecordAudio()} ({shortcutLabel})"
|
||||||
iconSize={70}
|
iconSize={70}
|
||||||
{disabled}
|
{disabled}
|
||||||
on:click={onRecord}
|
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
|
// 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
|
||||||
|
|
||||||
export function appendInParentheses(text: string, appendix: string): string {
|
|
||||||
return `${text} (${appendix})`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// trivial wrapper to silence Svelte deprecation warnings
|
/// trivial wrapper to silence Svelte deprecation warnings
|
||||||
export function execCommand(
|
export function execCommand(
|
||||||
command: string,
|
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
|
// 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 { i18n } from ".";
|
|
||||||
import BrowserEditor from "./BrowserEditor.svelte";
|
import BrowserEditor from "./BrowserEditor.svelte";
|
||||||
|
import { editorModules } from "./base";
|
||||||
import { promiseWithResolver } from "../lib/promise";
|
import { promiseWithResolver } from "../lib/promise";
|
||||||
import { globalExport } from "../lib/globals";
|
import { globalExport } from "../lib/globals";
|
||||||
|
import { setupI18n } from "../lib/i18n";
|
||||||
|
|
||||||
const [uiPromise, uiResolve] = promiseWithResolver();
|
const [uiPromise, uiResolve] = promiseWithResolver();
|
||||||
|
|
||||||
async function setupBrowserEditor(): Promise<void> {
|
async function setupBrowserEditor(): Promise<void> {
|
||||||
await i18n;
|
await setupI18n({ modules: editorModules });
|
||||||
|
|
||||||
new BrowserEditor({
|
new BrowserEditor({
|
||||||
target: document.body,
|
target: document.body,
|
||||||
@ -18,10 +19,10 @@ async function setupBrowserEditor(): Promise<void> {
|
|||||||
|
|
||||||
setupBrowserEditor();
|
setupBrowserEditor();
|
||||||
|
|
||||||
import * as editor from ".";
|
import * as base from "./base";
|
||||||
|
|
||||||
globalExport({
|
globalExport({
|
||||||
...editor,
|
...base,
|
||||||
uiPromise,
|
uiPromise,
|
||||||
noteEditorPromise: uiPromise,
|
noteEditorPromise: uiPromise,
|
||||||
});
|
});
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
// 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 { i18n } from ".";
|
|
||||||
import NoteCreator from "./NoteCreator.svelte";
|
import NoteCreator from "./NoteCreator.svelte";
|
||||||
|
import { editorModules } from "./base";
|
||||||
import { promiseWithResolver } from "../lib/promise";
|
import { promiseWithResolver } from "../lib/promise";
|
||||||
import { globalExport } from "../lib/globals";
|
import { globalExport } from "../lib/globals";
|
||||||
|
import { setupI18n } from "../lib/i18n";
|
||||||
|
|
||||||
const [uiPromise, uiResolve] = promiseWithResolver();
|
const [uiPromise, uiResolve] = promiseWithResolver();
|
||||||
|
|
||||||
async function setupNoteCreator(): Promise<void> {
|
async function setupNoteCreator(): Promise<void> {
|
||||||
await i18n;
|
await setupI18n({ modules: editorModules });
|
||||||
|
|
||||||
new NoteCreator({
|
new NoteCreator({
|
||||||
target: document.body,
|
target: document.body,
|
||||||
@ -18,10 +19,10 @@ async function setupNoteCreator(): Promise<void> {
|
|||||||
|
|
||||||
setupNoteCreator();
|
setupNoteCreator();
|
||||||
|
|
||||||
import * as editor from ".";
|
import * as base from "./base";
|
||||||
|
|
||||||
globalExport({
|
globalExport({
|
||||||
...editor,
|
...base,
|
||||||
uiPromise,
|
uiPromise,
|
||||||
noteEditorPromise: uiPromise,
|
noteEditorPromise: uiPromise,
|
||||||
});
|
});
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
// 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 { i18n } from "../editor";
|
|
||||||
import ReviewerEditor from "./ReviewerEditor.svelte";
|
import ReviewerEditor from "./ReviewerEditor.svelte";
|
||||||
|
import { editorModules } from "./base";
|
||||||
import { promiseWithResolver } from "../lib/promise";
|
import { promiseWithResolver } from "../lib/promise";
|
||||||
import { globalExport } from "../lib/globals";
|
import { globalExport } from "../lib/globals";
|
||||||
|
import { setupI18n } from "../lib/i18n";
|
||||||
|
|
||||||
const [uiPromise, uiResolve] = promiseWithResolver();
|
const [uiPromise, uiResolve] = promiseWithResolver();
|
||||||
|
|
||||||
async function setupReviewerEditor(): Promise<void> {
|
async function setupReviewerEditor(): Promise<void> {
|
||||||
await i18n;
|
await setupI18n({ modules: editorModules });
|
||||||
|
|
||||||
new ReviewerEditor({
|
new ReviewerEditor({
|
||||||
target: document.body,
|
target: document.body,
|
||||||
@ -18,10 +19,10 @@ async function setupReviewerEditor(): Promise<void> {
|
|||||||
|
|
||||||
setupReviewerEditor();
|
setupReviewerEditor();
|
||||||
|
|
||||||
import * as editor from "../editor";
|
import * as base from "./base";
|
||||||
|
|
||||||
globalExport({
|
globalExport({
|
||||||
...editor,
|
...base,
|
||||||
uiPromise,
|
uiPromise,
|
||||||
noteEditorPromise: 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:prettier.bzl", "prettier_test")
|
||||||
load("//ts:eslint.bzl", "eslint_test")
|
load("//ts:eslint.bzl", "eslint_test")
|
||||||
load("//ts:esbuild.bzl", "esbuild")
|
load("//ts:esbuild.bzl", "esbuild")
|
||||||
|
load("//ts:generate_page.bzl", "generate_page")
|
||||||
load("//ts:compile_sass.bzl", "compile_sass")
|
load("//ts:compile_sass.bzl", "compile_sass")
|
||||||
load("//ts:typescript.bzl", "typescript")
|
load("//ts:typescript.bzl", "typescript")
|
||||||
|
|
||||||
|
generate_page(page = "graphs")
|
||||||
|
|
||||||
compile_sass(
|
compile_sass(
|
||||||
srcs = ["graphs-base.scss"],
|
srcs = ["graphs-base.scss"],
|
||||||
group = "base_css",
|
group = "base_css",
|
||||||
@ -52,8 +55,6 @@ esbuild(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
exports_files(["graphs.html"])
|
|
||||||
|
|
||||||
# Tests
|
# 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
|
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { SvelteComponent } from "svelte/internal";
|
import type { SvelteComponentDev } from "svelte/internal";
|
||||||
import { writable } from "svelte/store";
|
import { writable } from "svelte/store";
|
||||||
import { pageTheme } from "../sveltelib/theme";
|
import { pageTheme } from "../sveltelib/theme";
|
||||||
|
|
||||||
import { bridgeCommand } from "../lib/bridgecommand";
|
import { bridgeCommand } from "../lib/bridgecommand";
|
||||||
|
|
||||||
import WithGraphData from "./WithGraphData.svelte";
|
import WithGraphData from "./WithGraphData.svelte";
|
||||||
|
|
||||||
export let graphs: SvelteComponent[];
|
|
||||||
|
|
||||||
export let initialSearch: string;
|
export let initialSearch: string;
|
||||||
export let initialDays: number;
|
export let initialDays: number;
|
||||||
export let controller: SvelteComponent | null;
|
|
||||||
|
|
||||||
const search = writable(initialSearch);
|
const search = writable(initialSearch);
|
||||||
const days = writable(initialDays);
|
const days = writable(initialDays);
|
||||||
|
|
||||||
|
export let graphs: typeof SvelteComponentDev[];
|
||||||
|
export let controller: typeof SvelteComponentDev | null;
|
||||||
|
|
||||||
function browserSearch(event: CustomEvent) {
|
function browserSearch(event: CustomEvent) {
|
||||||
bridgeCommand(`browserSearch: ${$search} ${event.detail.query}`);
|
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
|
// 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 type { SvelteComponent } from "svelte/internal";
|
import type { SvelteComponentDev } from "svelte/internal";
|
||||||
|
|
||||||
import { setupI18n, ModuleName } from "../lib/i18n";
|
import { setupI18n, ModuleName } from "../lib/i18n";
|
||||||
import { checkNightMode } from "../lib/nightmode";
|
import { checkNightMode } from "../lib/nightmode";
|
||||||
|
|
||||||
import GraphsPage from "./GraphsPage.svelte";
|
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 async function setupGraphs(
|
||||||
export { default as EaseGraph } from "./EaseGraph.svelte";
|
graphs: typeof SvelteComponentDev[],
|
||||||
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[],
|
|
||||||
{
|
{
|
||||||
search = "deck:current",
|
search = "deck:current",
|
||||||
days = 365,
|
days = 365,
|
||||||
controller = null as SvelteComponent | null,
|
controller = null as typeof SvelteComponentDev | null,
|
||||||
} = {},
|
} = {},
|
||||||
): void {
|
): Promise<GraphsPage> {
|
||||||
checkNightMode();
|
checkNightMode();
|
||||||
setupI18n({ modules: [ModuleName.STATISTICS, ModuleName.SCHEDULING] }).then(() => {
|
await i18n;
|
||||||
new GraphsPage({
|
|
||||||
target,
|
return new GraphsPage({
|
||||||
|
target: document.body,
|
||||||
props: {
|
props: {
|
||||||
graphs,
|
|
||||||
initialSearch: search,
|
initialSearch: search,
|
||||||
initialDays: days,
|
initialDays: days,
|
||||||
|
graphs,
|
||||||
controller,
|
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
|
// 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
|
||||||
//
|
|
||||||
// Expose the Svelte runtime bundled with Anki, so that add-ons can require() it.
|
// 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
|
// If they were to bundle their own runtime, things like bindings and contexts
|
||||||
// would not work.
|
// would not work.
|
||||||
|
Loading…
Reference in New Issue
Block a user