bookish-press 0.9.4 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Auth.svelte +37 -21
- package/dist/components/BookPreview.svelte +4 -4
- package/dist/components/BookPreview.svelte.d.ts +1 -1
- package/dist/components/Link.svelte +19 -12
- package/dist/components/app/Button.svelte +1 -8
- package/dist/components/app/Link.svelte +1 -7
- package/dist/components/app/Options.svelte +1 -6
- package/dist/components/app/TextInput.svelte +2 -8
- package/dist/components/chapter/Atom.svelte +2 -1
- package/dist/components/chapter/Atom.svelte.d.ts +1 -1
- package/dist/components/chapter/Block.svelte +9 -9
- package/dist/components/chapter/Block.svelte.d.ts +1 -1
- package/dist/components/chapter/Callout.svelte.d.ts +1 -1
- package/dist/components/chapter/CaptionedCode.svelte +1 -0
- package/dist/components/chapter/CaptionedCode.svelte.d.ts +1 -1
- package/dist/components/chapter/ChapterBody.svelte +5 -2
- package/dist/components/chapter/ChapterBody.svelte.d.ts +1 -1
- package/dist/components/chapter/ChapterBody.test.js +3 -3
- package/dist/components/chapter/Citations.svelte +17 -16
- package/dist/components/chapter/Citations.svelte.d.ts +1 -1
- package/dist/components/chapter/Code.svelte +8 -14
- package/dist/components/chapter/Comment.svelte +7 -12
- package/dist/components/chapter/Comment.svelte.d.ts +1 -1
- package/dist/components/chapter/Definition.svelte +8 -9
- package/dist/components/chapter/Definition.svelte.d.ts +1 -1
- package/dist/components/chapter/Embed.svelte +41 -61
- package/dist/components/chapter/Embed.svelte.d.ts +1 -1
- package/dist/components/chapter/ErrorMessage.svelte.d.ts +1 -1
- package/dist/components/chapter/Figure.svelte +14 -14
- package/dist/components/chapter/Figure.svelte.d.ts +4 -4
- package/dist/components/chapter/Footnote.svelte +11 -17
- package/dist/components/chapter/Footnote.svelte.d.ts +1 -1
- package/dist/components/chapter/Format.svelte +11 -11
- package/dist/components/chapter/Format.svelte.d.ts +1 -1
- package/dist/components/chapter/InlineCode.svelte.d.ts +1 -1
- package/dist/components/chapter/Label.svelte +1 -1
- package/dist/components/chapter/Label.svelte.d.ts +1 -1
- package/dist/components/chapter/LineBreak.svelte +1 -0
- package/dist/components/chapter/LineBreak.svelte.d.ts +1 -1
- package/dist/components/chapter/Link.svelte +14 -12
- package/dist/components/chapter/Link.svelte.d.ts +1 -1
- package/dist/components/chapter/List.svelte +1 -1
- package/dist/components/chapter/List.svelte.d.ts +1 -1
- package/dist/components/chapter/Marginal.svelte +36 -42
- package/dist/components/chapter/Paragraph.svelte +4 -4
- package/dist/components/chapter/Paragraph.svelte.d.ts +1 -1
- package/dist/components/chapter/Positioned.svelte +1 -0
- package/dist/components/chapter/Positioned.svelte.d.ts +1 -1
- package/dist/components/chapter/Python.svelte +42 -31
- package/dist/components/chapter/Python.svelte.d.ts +1 -1
- package/dist/components/chapter/Quote.svelte.d.ts +1 -1
- package/dist/components/chapter/Rule.svelte +1 -0
- package/dist/components/chapter/Rule.svelte.d.ts +1 -1
- package/dist/components/chapter/Table.svelte.d.ts +1 -1
- package/dist/components/chapter/Text.svelte +41 -50
- package/dist/components/chapter/Text.svelte.d.ts +1 -1
- package/dist/components/controls/DarkToggle.svelte +4 -4
- package/dist/components/editor/BookishEditor.svelte +605 -569
- package/dist/components/editor/BookishEditor.svelte.d.ts +1 -1
- package/dist/components/editor/CalloutEditor.svelte +1 -1
- package/dist/components/editor/CalloutEditor.svelte.d.ts +1 -1
- package/dist/components/editor/CaptionedCodeEditor.svelte +1 -1
- package/dist/components/editor/CaptionedCodeEditor.svelte.d.ts +1 -1
- package/dist/components/editor/CaretContext.d.ts +14 -14
- package/dist/components/editor/CaretState.d.ts +3 -3
- package/dist/components/editor/CaretView.svelte +8 -19
- package/dist/components/editor/CitationsEditor.svelte +10 -18
- package/dist/components/editor/CitationsEditor.svelte.d.ts +1 -1
- package/dist/components/editor/Clipboard.d.ts +1 -1
- package/dist/components/editor/Command.d.ts +1 -1
- package/dist/components/editor/Commands.js +19 -19
- package/dist/components/editor/ConfirmButton.svelte +1 -6
- package/dist/components/editor/DefinitionEditor.svelte +9 -7
- package/dist/components/editor/DefinitionEditor.svelte.d.ts +1 -1
- package/dist/components/editor/EmbedEditor.svelte +25 -34
- package/dist/components/editor/EmbedEditor.svelte.d.ts +1 -1
- package/dist/components/editor/ImageChooser.svelte +8 -7
- package/dist/components/editor/ImageChooser.svelte.d.ts +1 -1
- package/dist/components/editor/ImageThumbnail.svelte +21 -18
- package/dist/components/editor/InlineCodeEditor.svelte +1 -1
- package/dist/components/editor/InlineCodeEditor.svelte.d.ts +1 -1
- package/dist/components/editor/LabelEditor.svelte +2 -2
- package/dist/components/editor/LabelEditor.svelte.d.ts +1 -1
- package/dist/components/editor/LanguageEditor.svelte +8 -1
- package/dist/components/editor/LinkEditor.svelte +42 -44
- package/dist/components/editor/LinkEditor.svelte.d.ts +1 -1
- package/dist/components/editor/Permissions.svelte +23 -29
- package/dist/components/editor/PositionEditor.svelte +1 -1
- package/dist/components/editor/PositionEditor.svelte.d.ts +1 -1
- package/dist/components/editor/QuoteEditor.svelte +1 -1
- package/dist/components/editor/QuoteEditor.svelte.d.ts +1 -1
- package/dist/components/editor/Switch.svelte +5 -11
- package/dist/components/editor/TableEditor.svelte +1 -1
- package/dist/components/editor/TableEditor.svelte.d.ts +1 -1
- package/dist/components/editor/TextEditor.svelte +61 -58
- package/dist/components/editor/Toggle.svelte +16 -14
- package/dist/components/editor/Toolbar.svelte +81 -94
- package/dist/components/editor/UndoState.d.ts +2 -2
- package/dist/components/page/Acknowledgements.svelte +2 -8
- package/dist/components/page/Authors.svelte +12 -21
- package/dist/components/page/BookLoader.svelte +32 -34
- package/dist/components/page/BulkReferenceEditor.svelte +21 -41
- package/dist/components/page/Chapter.svelte +139 -114
- package/dist/components/page/Chapter.svelte.d.ts +1 -1
- package/dist/components/page/ChapterTitle.svelte +1 -1
- package/dist/components/page/Contexts.js +3 -1
- package/dist/components/page/DefinitionView.svelte +30 -42
- package/dist/components/page/DefinitionView.svelte.d.ts +1 -1
- package/dist/components/page/Description.svelte +2 -8
- package/dist/components/page/DownloadEPUB.svelte +83 -41
- package/dist/components/page/EditableHeader.svelte.d.ts +1 -1
- package/dist/components/page/Edition.svelte +44 -30
- package/dist/components/page/Edition.svelte.d.ts +1 -1
- package/dist/components/page/EditionLoader.svelte +101 -100
- package/dist/components/page/Editions.svelte +13 -13
- package/dist/components/page/Glossary.svelte +9 -10
- package/dist/components/page/Header.svelte +15 -28
- package/dist/components/page/Index.svelte +17 -18
- package/dist/components/page/License.svelte +2 -8
- package/dist/components/page/Media.svelte +7 -14
- package/dist/components/page/MediaPreview.svelte +14 -17
- package/dist/components/page/Outline.svelte +74 -66
- package/dist/components/page/Page.svelte +23 -17
- package/dist/components/page/PossibleChapter.svelte +2 -2
- package/dist/components/page/PossibleReference.svelte +1 -1
- package/dist/components/page/PossibleReference.svelte.d.ts +2 -2
- package/dist/components/page/Print.svelte +5 -8
- package/dist/components/page/Publish.svelte +33 -39
- package/dist/components/page/Reference.svelte +9 -11
- package/dist/components/page/Reference.svelte.d.ts +1 -1
- package/dist/components/page/References.svelte +1 -1
- package/dist/components/page/Search.svelte +39 -40
- package/dist/components/page/SubdomainEditor.svelte +11 -10
- package/dist/components/page/TableOfContents.svelte +52 -48
- package/dist/components/page/TableOfContentsImage.svelte +2 -2
- package/dist/components/page/TableOfContentsRow.svelte +9 -22
- package/dist/components/page/TableOfContentsRow.svelte.d.ts +2 -2
- package/dist/components/page/ThemeEditor.svelte +10 -17
- package/dist/components/page/ThemeEditorPreview.svelte +3 -6
- package/dist/components/page/ThemeEditorPreview.svelte.d.ts +1 -1
- package/dist/components/page/ThemeVariableEditor.svelte +6 -6
- package/dist/components/page/Unknown.svelte +1 -1
- package/dist/epub/build.d.ts +6 -0
- package/dist/epub/build.js +16 -3
- package/dist/epub/build.test.js +65 -0
- package/dist/epub/images.d.ts +7 -5
- package/dist/epub/images.js +15 -10
- package/dist/epub/images.test.js +8 -6
- package/dist/epub/package.js +25 -3
- package/dist/models/FirebaseAvailable.d.ts +9 -0
- package/dist/models/FirebaseAvailable.js +10 -0
- package/dist/models/book/BookMedia.d.ts +2 -1
- package/dist/models/book/BookMedia.js +33 -9
- package/package.json +18 -14
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">import LanguageEditor from "./LanguageEditor.svelte";
|
|
2
2
|
import PositionEditor from "./PositionEditor.svelte";
|
|
3
3
|
import Switch from "./Switch.svelte";
|
|
4
|
-
import { getCaret } from "../page/Contexts";
|
|
4
|
+
import { getCaret } from "../page/Contexts.js";
|
|
5
5
|
let { code } = $props();
|
|
6
6
|
let caret = getCaret();
|
|
7
7
|
</script>
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import type Caret from '../../models/chapter/Caret';
|
|
2
|
-
import type { CaretRange } from '../../models/chapter/Caret';
|
|
3
|
-
import type ParagraphNode from '../../models/chapter/ParagraphNode';
|
|
4
|
-
import type AtomNode from '../../models/chapter/AtomNode';
|
|
5
|
-
import type FormatNode from '../../models/chapter/FormatNode';
|
|
6
|
-
import type BlocksNode from '../../models/chapter/BlocksNode';
|
|
7
|
-
import type ListNode from '../../models/chapter/ListNode';
|
|
8
|
-
import type TableNode from '../../models/chapter/TableNode';
|
|
9
|
-
import type MetadataNode from '../../models/chapter/MetadataNode';
|
|
10
|
-
import type RootNode from '../../models/chapter/RootNode';
|
|
11
|
-
import type Edit from '../../models/chapter/Edit';
|
|
12
|
-
import type CodeNode from '../../models/chapter/CodeNode';
|
|
13
|
-
import type BlockNode from '../../models/chapter/BlockNode';
|
|
1
|
+
import type Caret from '../../models/chapter/Caret.js';
|
|
2
|
+
import type { CaretRange } from '../../models/chapter/Caret.js';
|
|
3
|
+
import type ParagraphNode from '../../models/chapter/ParagraphNode.js';
|
|
4
|
+
import type AtomNode from '../../models/chapter/AtomNode.js';
|
|
5
|
+
import type FormatNode from '../../models/chapter/FormatNode.js';
|
|
6
|
+
import type BlocksNode from '../../models/chapter/BlocksNode.js';
|
|
7
|
+
import type ListNode from '../../models/chapter/ListNode.js';
|
|
8
|
+
import type TableNode from '../../models/chapter/TableNode.js';
|
|
9
|
+
import type MetadataNode from '../../models/chapter/MetadataNode.js';
|
|
10
|
+
import type RootNode from '../../models/chapter/RootNode.js';
|
|
11
|
+
import type Edit from '../../models/chapter/Edit.js';
|
|
12
|
+
import type CodeNode from '../../models/chapter/CodeNode.js';
|
|
13
|
+
import type BlockNode from '../../models/chapter/BlockNode.js';
|
|
14
14
|
import type Clipboard from './Clipboard';
|
|
15
15
|
import type UndoState from './UndoState';
|
|
16
|
-
import type Node from '../../models/chapter/Node';
|
|
16
|
+
import type Node from '../../models/chapter/Node.js';
|
|
17
17
|
export type PasteContent = {
|
|
18
18
|
plain: string | undefined;
|
|
19
19
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { CaretRange } from '../../models/chapter/Caret';
|
|
2
|
-
import type RootNode from '../../models/chapter/RootNode';
|
|
1
|
+
import type { CaretRange } from '../../models/chapter/Caret.js';
|
|
2
|
+
import type RootNode from '../../models/chapter/RootNode.js';
|
|
3
3
|
import type CaretContext from './CaretContext';
|
|
4
|
-
import type Node from '../../models/chapter/Node';
|
|
4
|
+
import type Node from '../../models/chapter/Node.js';
|
|
5
5
|
import type Command from './Command';
|
|
6
6
|
type CaretState = {
|
|
7
7
|
root: RootNode;
|
|
@@ -1,26 +1,15 @@
|
|
|
1
1
|
<script lang="ts">import { tick } from "svelte";
|
|
2
|
-
let {
|
|
3
|
-
left,
|
|
4
|
-
top,
|
|
5
|
-
height,
|
|
6
|
-
linked,
|
|
7
|
-
italic,
|
|
8
|
-
bold,
|
|
9
|
-
disabled,
|
|
10
|
-
ignored,
|
|
11
|
-
blink,
|
|
12
|
-
locked,
|
|
13
|
-
accent
|
|
14
|
-
} = $props();
|
|
2
|
+
let { left, top, height, linked, italic, bold, disabled, ignored, blink, locked, accent } = $props();
|
|
15
3
|
let element = $state();
|
|
16
4
|
let headerHeight = $state(0);
|
|
5
|
+
// When the caret updates position, scroll the element into view after
|
|
6
|
+
// the render is complete, and re-measure the header height so we can
|
|
7
|
+
// snap to the caret position.
|
|
17
8
|
$effect(() => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
);
|
|
23
|
-
headerHeight = document.querySelector(".bookish-app > .header")?.offsetHeight ?? 0;
|
|
9
|
+
void left;
|
|
10
|
+
void top;
|
|
11
|
+
tick().then(() => element ? element.scrollIntoView({ block: "nearest" }) : undefined);
|
|
12
|
+
headerHeight = document.querySelector(".bookish-app > .header")?.offsetHeight ?? 0;
|
|
24
13
|
});
|
|
25
14
|
</script>
|
|
26
15
|
|
|
@@ -1,35 +1,27 @@
|
|
|
1
1
|
<script lang="ts">import Note from "./Note.svelte";
|
|
2
2
|
import Options from "../app/Options.svelte";
|
|
3
3
|
import Button from "../app/Button.svelte";
|
|
4
|
-
import { getCaret, getEdition } from "../page/Contexts";
|
|
4
|
+
import { getCaret, getEdition } from "../page/Contexts.js";
|
|
5
5
|
let { citations } = $props();
|
|
6
6
|
let caret = getCaret();
|
|
7
7
|
let edition = getEdition();
|
|
8
8
|
let value = $state("");
|
|
9
9
|
function handleSelection(selection) {
|
|
10
|
-
|
|
11
|
-
update(/* @__PURE__ */ new Set([...citations.getMeta(), selection]));
|
|
10
|
+
if (selection.length > 0) update(new Set([...citations.getMeta(), selection]));
|
|
12
11
|
}
|
|
13
12
|
function removeSelection(citationID) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
let ids = new Set(citations.getMeta());
|
|
14
|
+
ids.delete(citationID);
|
|
15
|
+
update(ids);
|
|
17
16
|
}
|
|
18
17
|
function update(set) {
|
|
19
|
-
|
|
18
|
+
$caret?.edit(citations, citations.withMeta(Array.from(set)));
|
|
20
19
|
}
|
|
21
|
-
let uncited = $derived($edition ===
|
|
22
|
-
(citationID) => !citations.getMeta().includes(citationID)
|
|
23
|
-
).sort());
|
|
20
|
+
let uncited = $derived($edition === undefined ? [] : Object.keys($edition.getReferences()).filter((citationID) => !citations.getMeta().includes(citationID)).sort());
|
|
24
21
|
let options = $derived.by(() => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
""
|
|
29
|
-
]
|
|
30
|
-
];
|
|
31
|
-
for (const citationID of uncited) list.push([citationID, citationID]);
|
|
32
|
-
return list;
|
|
22
|
+
const list = [[uncited.length > 0 ? "Choose references" : "No uncited references", ""]];
|
|
23
|
+
for (const citationID of uncited) list.push([citationID, citationID]);
|
|
24
|
+
return list;
|
|
33
25
|
});
|
|
34
26
|
</script>
|
|
35
27
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type Edit from '../../models/chapter/Edit';
|
|
1
|
+
import type Edit from '../../models/chapter/Edit.js';
|
|
2
2
|
import type CaretUtilities from './CaretUtilities';
|
|
3
3
|
import type CaretContext from './CaretContext';
|
|
4
4
|
export type CommandCategory = 'navigation' | 'selection' | 'text' | 'history' | 'clipboard' | 'annotation' | 'block' | 'level' | 'list' | 'table';
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import CalloutNode from '../../models/chapter/CalloutNode';
|
|
2
|
-
import CitationsNode from '../../models/chapter/CitationsNode';
|
|
3
|
-
import CodeNode from '../../models/chapter/CodeNode';
|
|
4
|
-
import CommentNode from '../../models/chapter/CommentNode';
|
|
5
|
-
import DefinitionNode from '../../models/chapter/DefinitionNode';
|
|
6
|
-
import EmbedNode from '../../models/chapter/EmbedNode';
|
|
7
|
-
import FootnoteNode from '../../models/chapter/FootnoteNode';
|
|
8
|
-
import FormatNode from '../../models/chapter/FormatNode';
|
|
9
|
-
import InlineCodeNode from '../../models/chapter/InlineCodeNode';
|
|
10
|
-
import LabelNode from '../../models/chapter/LabelNode';
|
|
11
|
-
import LinkNode from '../../models/chapter/LinkNode';
|
|
12
|
-
import ListNode from '../../models/chapter/ListNode';
|
|
13
|
-
import ParagraphNode from '../../models/chapter/ParagraphNode';
|
|
14
|
-
import QuoteNode from '../../models/chapter/QuoteNode';
|
|
15
|
-
import RuleNode from '../../models/chapter/RuleNode';
|
|
16
|
-
import TableNode from '../../models/chapter/TableNode';
|
|
17
|
-
import TextNode from '../../models/chapter/TextNode';
|
|
18
|
-
import AtomNode from '../../models/chapter/AtomNode';
|
|
19
|
-
import BlocksNode from '../../models/chapter/BlocksNode';
|
|
1
|
+
import CalloutNode from '../../models/chapter/CalloutNode.js';
|
|
2
|
+
import CitationsNode from '../../models/chapter/CitationsNode.js';
|
|
3
|
+
import CodeNode from '../../models/chapter/CodeNode.js';
|
|
4
|
+
import CommentNode from '../../models/chapter/CommentNode.js';
|
|
5
|
+
import DefinitionNode from '../../models/chapter/DefinitionNode.js';
|
|
6
|
+
import EmbedNode from '../../models/chapter/EmbedNode.js';
|
|
7
|
+
import FootnoteNode from '../../models/chapter/FootnoteNode.js';
|
|
8
|
+
import FormatNode from '../../models/chapter/FormatNode.js';
|
|
9
|
+
import InlineCodeNode from '../../models/chapter/InlineCodeNode.js';
|
|
10
|
+
import LabelNode from '../../models/chapter/LabelNode.js';
|
|
11
|
+
import LinkNode from '../../models/chapter/LinkNode.js';
|
|
12
|
+
import ListNode from '../../models/chapter/ListNode.js';
|
|
13
|
+
import ParagraphNode from '../../models/chapter/ParagraphNode.js';
|
|
14
|
+
import QuoteNode from '../../models/chapter/QuoteNode.js';
|
|
15
|
+
import RuleNode from '../../models/chapter/RuleNode.js';
|
|
16
|
+
import TableNode from '../../models/chapter/TableNode.js';
|
|
17
|
+
import TextNode from '../../models/chapter/TextNode.js';
|
|
18
|
+
import AtomNode from '../../models/chapter/AtomNode.js';
|
|
19
|
+
import BlocksNode from '../../models/chapter/BlocksNode.js';
|
|
20
20
|
import BoldIcon from './icons/bold.svg?raw';
|
|
21
21
|
import BulletsIcon from './icons/bullets.svg?raw';
|
|
22
22
|
import CalloutIcon from './icons/callout.svg?raw';
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
<script lang="ts">import Options from "../app/Options.svelte";
|
|
2
2
|
import Note from "./Note.svelte";
|
|
3
|
-
import { getCaret, getEdition } from "../page/Contexts";
|
|
3
|
+
import { getCaret, getEdition } from "../page/Contexts.js";
|
|
4
4
|
let { definition } = $props();
|
|
5
5
|
let caret = getCaret();
|
|
6
6
|
let edition = getEdition();
|
|
7
7
|
let glossary = $derived($edition?.getGlossary());
|
|
8
8
|
function handleChange(glossaryID) {
|
|
9
|
-
|
|
9
|
+
$caret?.edit(definition, definition.withMeta(glossaryID));
|
|
10
10
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
// Sort the glossary entries by phrase
|
|
12
|
+
let entries = $derived(glossary === undefined ? undefined : Object.entries(glossary).map(([key, value]) => {
|
|
13
|
+
return {
|
|
14
|
+
glossaryID: key,
|
|
15
|
+
phrase: value.phrase
|
|
16
|
+
};
|
|
17
|
+
}).sort((a, b) => a && b ? a.phrase.localeCompare(b.phrase) : 0));
|
|
16
18
|
</script>
|
|
17
19
|
|
|
18
20
|
{#if entries !== undefined && glossary !== undefined}
|
|
@@ -1,52 +1,43 @@
|
|
|
1
1
|
<script lang="ts">import PositionEditor from "./PositionEditor.svelte";
|
|
2
|
-
import EmbedNode from "../../models/chapter/EmbedNode";
|
|
2
|
+
import EmbedNode from "../../models/chapter/EmbedNode.js";
|
|
3
3
|
import TextEditor from "./TextEditor.svelte";
|
|
4
|
-
import { storage } from "../../models/Firebase";
|
|
4
|
+
import { storage } from "../../models/Firebase.js";
|
|
5
5
|
import ToolbarSpacer from "./ToolbarSpacer.svelte";
|
|
6
6
|
import ImageChooser from "./ImageChooser.svelte";
|
|
7
7
|
import URLEditor from "./URLEditor.svelte";
|
|
8
8
|
import Note from "./Note.svelte";
|
|
9
|
-
import { getBook, getCaret } from "../page/Contexts";
|
|
9
|
+
import { getBook, getCaret } from "../page/Contexts.js";
|
|
10
10
|
let { embed } = $props();
|
|
11
11
|
let caret = getCaret();
|
|
12
|
-
let upload = $state(
|
|
12
|
+
let upload = $state(undefined);
|
|
13
13
|
let description = $derived(embed.getDescription());
|
|
14
14
|
let book = getBook();
|
|
15
15
|
function isValidURL(url) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
// Is it a valid URL?
|
|
17
|
+
try {
|
|
18
|
+
let test = new URL(url);
|
|
19
|
+
if (test.protocol === "http:" || test.protocol === "https:") return;
|
|
20
|
+
} catch (_) {}
|
|
21
|
+
return "URL doesn't seem valid";
|
|
22
22
|
}
|
|
23
23
|
function handleImageChange(event) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
upload = void 0;
|
|
39
|
-
}
|
|
40
|
-
);
|
|
24
|
+
if ($book === undefined) return;
|
|
25
|
+
if ($caret === undefined) return;
|
|
26
|
+
const target = event.target;
|
|
27
|
+
const file = target.files === null ? undefined : target.files[0];
|
|
28
|
+
const media = $book.getMedia();
|
|
29
|
+
if (file === undefined) return;
|
|
30
|
+
if (storage === undefined) return;
|
|
31
|
+
if (media === undefined) return;
|
|
32
|
+
media.upload(file, (progress) => upload = `${progress}% done`, (error) => upload = error, (url, thumbnail) => {
|
|
33
|
+
// Upload completed successfully, update the front end.
|
|
34
|
+
// Preserve the description, in case it's an image revision, to avoid data loss.
|
|
35
|
+
$caret?.edit(embed, embed.withURLs(url, thumbnail));
|
|
36
|
+
upload = undefined;
|
|
37
|
+
});
|
|
41
38
|
}
|
|
42
39
|
function handleImageSelection(image) {
|
|
43
|
-
|
|
44
|
-
embed,
|
|
45
|
-
embed.getURL() === image.url ? (
|
|
46
|
-
// Toggle the embed if choosing the same image
|
|
47
|
-
embed.withURL("").withDescription("")
|
|
48
|
-
) : embed.withURLs(image.url, image.thumb)
|
|
49
|
-
);
|
|
40
|
+
$caret?.edit(embed, embed.getURL() === image.url ? embed.withURL("").withDescription("") : embed.withURLs(image.url, image.thumb));
|
|
50
41
|
}
|
|
51
42
|
</script>
|
|
52
43
|
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
<script lang="ts">import { onMount } from "svelte";
|
|
2
|
-
import { getBook } from "../page/Contexts";
|
|
2
|
+
import { getBook } from "../page/Contexts.js";
|
|
3
3
|
import ImageThumbnail from "./ImageThumbnail.svelte";
|
|
4
4
|
let { select, selection } = $props();
|
|
5
5
|
let book = getBook();
|
|
6
|
-
let images = $state(
|
|
6
|
+
let images = $state(undefined);
|
|
7
7
|
let expanded = $state(false);
|
|
8
8
|
function updateImages(newImages) {
|
|
9
|
-
|
|
9
|
+
images = newImages;
|
|
10
10
|
}
|
|
11
|
+
// Load the latest images in the book, and keep them updated as they change.
|
|
11
12
|
onMount(() => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
if ($book === undefined) return;
|
|
14
|
+
const media = $book.getMedia();
|
|
15
|
+
media.notify(updateImages);
|
|
16
|
+
return () => media.stopNotifying(updateImages);
|
|
16
17
|
});
|
|
17
18
|
</script>
|
|
18
19
|
|
|
@@ -3,27 +3,30 @@ let retries = 3;
|
|
|
3
3
|
let error = $state(false);
|
|
4
4
|
let loading = $state(true);
|
|
5
5
|
function loadImage(url) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
6
|
+
retries--;
|
|
7
|
+
let img = new Image();
|
|
8
|
+
img.onerror = () => {
|
|
9
|
+
if (retries > 0) {
|
|
10
|
+
setTimeout(() => loadImage(url), 1e3);
|
|
11
|
+
} else {
|
|
12
|
+
loading = false;
|
|
13
|
+
error = true;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
img.onload = () => {
|
|
17
|
+
loading = false;
|
|
18
|
+
};
|
|
19
|
+
img.src = url;
|
|
20
20
|
}
|
|
21
|
+
// Load now and whenever the image prop changes (thumbnails can be
|
|
22
|
+
// reused for a different image by an unkeyed list).
|
|
21
23
|
$effect(() => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
retries = 3;
|
|
25
|
+
loading = true;
|
|
26
|
+
error = false;
|
|
27
|
+
loadImage(image.thumb);
|
|
26
28
|
});
|
|
29
|
+
export {};
|
|
27
30
|
</script>
|
|
28
31
|
|
|
29
32
|
{#if loading}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<script lang="ts">import TextEditor from "./TextEditor.svelte";
|
|
2
2
|
import { getChapter, getEdition } from "../page/Contexts";
|
|
3
|
-
import { getCaret } from "../page/Contexts";
|
|
3
|
+
import { getCaret } from "../page/Contexts.js";
|
|
4
4
|
let { label } = $props();
|
|
5
5
|
let edition = getEdition();
|
|
6
6
|
let chapter = getChapter();
|
|
7
7
|
let caret = getCaret();
|
|
8
|
-
let ast = $derived($edition && $chapter ? $chapter.chapter.getAST($edition) :
|
|
8
|
+
let ast = $derived($edition && $chapter ? $chapter.chapter.getAST($edition) : undefined);
|
|
9
9
|
</script>
|
|
10
10
|
|
|
11
11
|
<code>
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
<script lang="ts">import Options from "../app/Options.svelte";
|
|
2
2
|
import Note from "./Note.svelte";
|
|
3
3
|
let { language, edit } = $props();
|
|
4
|
-
const languages = [
|
|
4
|
+
const languages = [
|
|
5
|
+
"",
|
|
6
|
+
"html",
|
|
7
|
+
"css",
|
|
8
|
+
"javascript",
|
|
9
|
+
"python",
|
|
10
|
+
"java"
|
|
11
|
+
];
|
|
5
12
|
</script>
|
|
6
13
|
|
|
7
14
|
<Options
|
|
@@ -4,7 +4,7 @@ import Icon from "./Icon.svelte";
|
|
|
4
4
|
import Button from "../app/Button.svelte";
|
|
5
5
|
import UnlinkIcon from "./icons/unlink.svg?raw";
|
|
6
6
|
import Options from "../app/Options.svelte";
|
|
7
|
-
import { getCaret } from "../page/Contexts";
|
|
7
|
+
import { getCaret } from "../page/Contexts.js";
|
|
8
8
|
let { link } = $props();
|
|
9
9
|
let caret = getCaret();
|
|
10
10
|
let edition = getEdition();
|
|
@@ -12,54 +12,52 @@ let chapter = getChapter();
|
|
|
12
12
|
let root = getRoot();
|
|
13
13
|
let url = $derived(link.getMeta());
|
|
14
14
|
function saveEdit(value) {
|
|
15
|
-
|
|
15
|
+
$caret?.edit(link, link.withMeta(value));
|
|
16
16
|
}
|
|
17
|
-
function isValidURL(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return false;
|
|
17
|
+
function isValidURL(url) {
|
|
18
|
+
// Is it a valid URL?
|
|
19
|
+
try {
|
|
20
|
+
let test = new URL(url);
|
|
21
|
+
if (test.protocol === "http:" || test.protocol === "https:") return true;
|
|
22
|
+
} catch (_) {}
|
|
23
|
+
return false;
|
|
25
24
|
}
|
|
26
25
|
function validate(urlOrChapter) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
26
|
+
if (urlOrChapter.length === 0) return "link URL can't be empty";
|
|
27
|
+
if ($edition === undefined) return;
|
|
28
|
+
if (isValidURL(urlOrChapter)) return;
|
|
29
|
+
// If not, is it a valid chapterID?
|
|
30
|
+
if ($edition.hasChapter(urlOrChapter)) return;
|
|
31
|
+
// If not, is it a valid chapterID:label?
|
|
32
|
+
const [chapterID, labelID] = urlOrChapter.split(":");
|
|
33
|
+
if (chapterID === undefined || labelID === undefined) return;
|
|
34
|
+
// The chapter ID is optional; if it's missing, it refers to this chapter.
|
|
35
|
+
const correspondingChapter = chapterID === "" ? $root : $edition?.getChapter(chapterID)?.getAST($edition);
|
|
36
|
+
if (correspondingChapter === undefined) return "Not a valid URL or chapter.";
|
|
37
|
+
if (!correspondingChapter.hasLabel(labelID)) return "Not a valid chapter label.";
|
|
38
38
|
}
|
|
39
39
|
let options = $derived.by(() => {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
return list;
|
|
40
|
+
const list = [];
|
|
41
|
+
// Add an empty option.
|
|
42
|
+
list.push(["External link", url.startsWith("http") ? url : ""]);
|
|
43
|
+
// Add an option for each chapter and it's labels.
|
|
44
|
+
if ($edition) {
|
|
45
|
+
for (const chap of $edition?.getChapters() ?? []) {
|
|
46
|
+
// Include the chapter itself
|
|
47
|
+
list.push([`Chapter: ${chap.getTitle()}`, chap.getID()]);
|
|
48
|
+
const root = chap.getAST($edition);
|
|
49
|
+
if (root) {
|
|
50
|
+
// Include the chapter's headers
|
|
51
|
+
const headers = root.getHeaders();
|
|
52
|
+
for (let number = 0; number < headers.length; number++) {
|
|
53
|
+
list.push([chap.getTitle() + ": " + headers[number].toText(), `${chap.getID()}#header-${number}`]);
|
|
54
|
+
}
|
|
55
|
+
// Include all of the labels in the chapter
|
|
56
|
+
for (const label of root.getLabels()) list.push([chap.getTitle() + ": " + label.getMeta(), `${chap.getID()}:${label.getMeta()}`]);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return list;
|
|
63
61
|
});
|
|
64
62
|
</script>
|
|
65
63
|
|