bookish-press 0.7.1 → 0.8.2
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/README.md +8 -0
- package/dist/components/Auth.svelte +29 -39
- package/dist/components/Auth.svelte.d.ts +5 -17
- package/dist/components/BookPreview.svelte +14 -20
- package/dist/components/BookPreview.svelte.d.ts +6 -18
- package/dist/components/Link.svelte +19 -30
- package/dist/components/Link.svelte.d.ts +7 -20
- package/dist/components/app/BookList.svelte +2 -3
- package/dist/components/app/BookList.svelte.d.ts +6 -18
- package/dist/components/app/Button.svelte +12 -8
- package/dist/components/app/Button.svelte.d.ts +10 -23
- package/dist/components/app/Feedback.svelte +4 -4
- package/dist/components/app/Feedback.svelte.d.ts +6 -19
- package/dist/components/app/Head.svelte +2 -2
- package/dist/components/app/Head.svelte.d.ts +6 -19
- package/dist/components/app/Large.svelte +4 -1
- package/dist/components/app/Large.svelte.d.ts +5 -28
- package/dist/components/app/Lead.svelte +4 -1
- package/dist/components/app/Lead.svelte.d.ts +5 -28
- package/dist/components/app/Link.svelte +12 -9
- package/dist/components/app/Link.svelte.d.ts +9 -22
- package/dist/components/app/Options.svelte +8 -6
- package/dist/components/app/Options.svelte.d.ts +8 -20
- package/dist/components/app/Paragraph.svelte +2 -2
- package/dist/components/app/Paragraph.svelte.d.ts +6 -19
- package/dist/components/app/Section.svelte +4 -1
- package/dist/components/app/Section.svelte.d.ts +5 -28
- package/dist/components/app/Table.svelte +4 -1
- package/dist/components/app/Table.svelte.d.ts +5 -28
- package/dist/components/app/TextInput.svelte +10 -8
- package/dist/components/app/TextInput.svelte.d.ts +12 -23
- package/dist/components/chapter/Atom.svelte +4 -7
- package/dist/components/chapter/Atom.svelte.d.ts +6 -19
- package/dist/components/chapter/Block.svelte +21 -23
- package/dist/components/chapter/Block.svelte.d.ts +5 -17
- package/dist/components/chapter/Callout.svelte +3 -5
- package/dist/components/chapter/Callout.svelte.d.ts +5 -17
- package/dist/components/chapter/CaptionedCode.svelte +12 -14
- package/dist/components/chapter/CaptionedCode.svelte.d.ts +5 -17
- package/dist/components/chapter/ChapterBody.svelte +14 -17
- package/dist/components/chapter/ChapterBody.svelte.d.ts +7 -19
- package/dist/components/chapter/ChapterBody.test.d.ts +1 -0
- package/dist/components/chapter/ChapterBody.test.js +85 -0
- package/dist/components/chapter/Citations.svelte +39 -45
- package/dist/components/chapter/Citations.svelte.d.ts +5 -17
- package/dist/components/chapter/Code.svelte +158 -155
- package/dist/components/chapter/Code.svelte.d.ts +10 -23
- package/dist/components/chapter/Comment.svelte +30 -23
- package/dist/components/chapter/Comment.svelte.d.ts +5 -17
- package/dist/components/chapter/Definition.svelte +36 -34
- package/dist/components/chapter/Definition.svelte.d.ts +5 -17
- package/dist/components/chapter/Embed.svelte +78 -72
- package/dist/components/chapter/Embed.svelte.d.ts +8 -20
- package/dist/components/chapter/ErrorMessage.svelte +2 -4
- package/dist/components/chapter/ErrorMessage.svelte.d.ts +5 -17
- package/dist/components/chapter/Figure.svelte +22 -29
- package/dist/components/chapter/Figure.svelte.d.ts +9 -22
- package/dist/components/chapter/Footnote.svelte +40 -32
- package/dist/components/chapter/Footnote.svelte.d.ts +5 -17
- package/dist/components/chapter/Format.svelte +26 -41
- package/dist/components/chapter/Format.svelte.d.ts +7 -18
- package/dist/components/chapter/InlineCode.svelte +7 -8
- package/dist/components/chapter/InlineCode.svelte.d.ts +5 -17
- package/dist/components/chapter/Label.svelte +5 -11
- package/dist/components/chapter/Label.svelte.d.ts +5 -17
- package/dist/components/chapter/LineBreak.svelte +1 -3
- package/dist/components/chapter/LineBreak.svelte.d.ts +5 -17
- package/dist/components/chapter/Link.svelte +17 -23
- package/dist/components/chapter/Link.svelte.d.ts +5 -17
- package/dist/components/chapter/List.svelte +9 -9
- package/dist/components/chapter/List.svelte.d.ts +6 -17
- package/dist/components/chapter/Marginal.svelte +59 -60
- package/dist/components/chapter/Marginal.svelte.d.ts +10 -22
- package/dist/components/chapter/Paragraph.svelte +8 -23
- package/dist/components/chapter/Paragraph.svelte.d.ts +6 -18
- package/dist/components/chapter/Positioned.svelte +2 -4
- package/dist/components/chapter/Positioned.svelte.d.ts +6 -19
- package/dist/components/chapter/Problem.svelte +3 -2
- package/dist/components/chapter/Problem.svelte.d.ts +5 -28
- package/dist/components/chapter/Python.svelte +45 -58
- package/dist/components/chapter/Python.svelte.d.ts +6 -18
- package/dist/components/chapter/Quote.svelte +5 -7
- package/dist/components/chapter/Quote.svelte.d.ts +5 -17
- package/dist/components/chapter/Rule.svelte +1 -3
- package/dist/components/chapter/Rule.svelte.d.ts +5 -17
- package/dist/components/chapter/Table.svelte +6 -8
- package/dist/components/chapter/Table.svelte.d.ts +5 -17
- package/dist/components/chapter/Text.svelte +54 -69
- package/dist/components/chapter/Text.svelte.d.ts +6 -18
- package/dist/components/controls/DarkToggle.svelte +7 -8
- package/dist/components/controls/DarkToggle.svelte.d.ts +6 -18
- package/dist/components/editor/BookishEditor.svelte +583 -761
- package/dist/components/editor/BookishEditor.svelte.d.ts +14 -26
- package/dist/components/editor/CalloutEditor.svelte +3 -3
- package/dist/components/editor/CalloutEditor.svelte.d.ts +5 -17
- package/dist/components/editor/CaptionedCodeEditor.svelte +5 -5
- package/dist/components/editor/CaptionedCodeEditor.svelte.d.ts +5 -17
- package/dist/components/editor/CaretView.svelte +23 -25
- package/dist/components/editor/CaretView.svelte.d.ts +15 -27
- package/dist/components/editor/CitationsEditor.svelte +25 -28
- package/dist/components/editor/CitationsEditor.svelte.d.ts +5 -17
- package/dist/components/editor/ConfirmButton.svelte +9 -6
- package/dist/components/editor/ConfirmButton.svelte.d.ts +8 -21
- package/dist/components/editor/DefinitionEditor.svelte +11 -15
- package/dist/components/editor/DefinitionEditor.svelte.d.ts +5 -17
- package/dist/components/editor/EmbedEditor.svelte +43 -44
- package/dist/components/editor/EmbedEditor.svelte.d.ts +5 -17
- package/dist/components/editor/Icon.svelte +1 -1
- package/dist/components/editor/Icon.svelte.d.ts +5 -17
- package/dist/components/editor/ImageChooser.svelte +15 -18
- package/dist/components/editor/ImageChooser.svelte.d.ts +6 -18
- package/dist/components/editor/ImageThumbnail.svelte +29 -24
- package/dist/components/editor/ImageThumbnail.svelte.d.ts +7 -19
- package/dist/components/editor/InlineCodeEditor.svelte +3 -3
- package/dist/components/editor/InlineCodeEditor.svelte.d.ts +5 -17
- package/dist/components/editor/LabelEditor.svelte +5 -6
- package/dist/components/editor/LabelEditor.svelte.d.ts +5 -17
- package/dist/components/editor/LanguageEditor.svelte +4 -5
- package/dist/components/editor/LanguageEditor.svelte.d.ts +6 -18
- package/dist/components/editor/LinkEditor.svelte +52 -68
- package/dist/components/editor/LinkEditor.svelte.d.ts +5 -17
- package/dist/components/editor/Note.svelte +4 -1
- package/dist/components/editor/Note.svelte.d.ts +5 -28
- package/dist/components/editor/Permissions.svelte +55 -51
- package/dist/components/editor/Permissions.svelte.d.ts +9 -21
- package/dist/components/editor/PositionEditor.svelte +6 -7
- package/dist/components/editor/PositionEditor.svelte.d.ts +6 -18
- package/dist/components/editor/QuoteEditor.svelte +3 -3
- package/dist/components/editor/QuoteEditor.svelte.d.ts +5 -17
- package/dist/components/editor/Switch.svelte +16 -11
- package/dist/components/editor/Switch.svelte.d.ts +9 -21
- package/dist/components/editor/TableEditor.svelte +3 -3
- package/dist/components/editor/TableEditor.svelte.d.ts +5 -17
- package/dist/components/editor/TextEditor.svelte +74 -87
- package/dist/components/editor/TextEditor.svelte.d.ts +13 -25
- package/dist/components/editor/Toggle.svelte +18 -21
- package/dist/components/editor/Toggle.svelte.d.ts +7 -20
- package/dist/components/editor/Toolbar.svelte +140 -145
- package/dist/components/editor/Toolbar.svelte.d.ts +5 -17
- package/dist/components/editor/ToolbarGroup.svelte +4 -4
- package/dist/components/editor/ToolbarGroup.svelte.d.ts +6 -19
- package/dist/components/editor/ToolbarSpacer.svelte +1 -1
- package/dist/components/editor/ToolbarSpacer.svelte.d.ts +22 -21
- package/dist/components/editor/URLEditor.svelte +3 -5
- package/dist/components/editor/URLEditor.svelte.d.ts +7 -19
- package/dist/components/page/Acknowledgements.svelte +14 -8
- package/dist/components/page/Acknowledgements.svelte.d.ts +3 -16
- package/dist/components/page/Analytics.svelte +2 -3
- package/dist/components/page/Analytics.svelte.d.ts +6 -17
- package/dist/components/page/Authors.svelte +29 -29
- package/dist/components/page/Authors.svelte.d.ts +11 -23
- package/dist/components/page/BookLoader.svelte +47 -43
- package/dist/components/page/BookLoader.svelte.d.ts +5 -17
- package/dist/components/page/BulkReferenceEditor.svelte +43 -26
- package/dist/components/page/BulkReferenceEditor.svelte.d.ts +3 -16
- package/dist/components/page/Chapter.svelte +226 -250
- package/dist/components/page/Chapter.svelte.d.ts +6 -18
- package/dist/components/page/ChapterContext.d.ts +3 -1
- package/dist/components/page/ChapterNumber.svelte +4 -1
- package/dist/components/page/ChapterNumber.svelte.d.ts +5 -28
- package/dist/components/page/ChapterTitle.svelte +4 -4
- package/dist/components/page/ChapterTitle.svelte.d.ts +6 -19
- package/dist/components/page/Contexts.js +2 -2
- package/dist/components/page/DefinitionView.svelte +51 -44
- package/dist/components/page/DefinitionView.svelte.d.ts +6 -18
- package/dist/components/page/Description.svelte +10 -4
- package/dist/components/page/Description.svelte.d.ts +16 -14
- package/dist/components/page/EditableHeader.svelte +4 -6
- package/dist/components/page/EditableHeader.svelte.d.ts +7 -18
- package/dist/components/page/Edition.svelte +57 -71
- package/dist/components/page/Edition.svelte.d.ts +7 -20
- package/dist/components/page/EditionLoader.svelte +119 -82
- package/dist/components/page/EditionLoader.svelte.d.ts +6 -19
- package/dist/components/page/Editions.svelte +61 -41
- package/dist/components/page/Editions.svelte.d.ts +5 -17
- package/dist/components/page/Glossary.svelte +31 -35
- package/dist/components/page/Glossary.svelte.d.ts +3 -16
- package/dist/components/page/Header.svelte +43 -49
- package/dist/components/page/Header.svelte.d.ts +19 -30
- package/dist/components/page/Index.svelte +46 -46
- package/dist/components/page/Index.svelte.d.ts +3 -16
- package/dist/components/page/Instructions.svelte +2 -2
- package/dist/components/page/Instructions.svelte.d.ts +6 -19
- package/dist/components/page/License.svelte +13 -7
- package/dist/components/page/License.svelte.d.ts +16 -14
- package/dist/components/page/Loading.svelte +9 -9
- package/dist/components/page/Loading.svelte.d.ts +22 -21
- package/dist/components/page/Media.svelte +36 -27
- package/dist/components/page/Media.svelte.d.ts +3 -16
- package/dist/components/page/MediaPreview.svelte +22 -19
- package/dist/components/page/MediaPreview.svelte.d.ts +8 -21
- package/dist/components/page/Muted.svelte +4 -1
- package/dist/components/page/Muted.svelte.d.ts +5 -28
- package/dist/components/page/Outline.svelte +76 -97
- package/dist/components/page/Outline.svelte.d.ts +8 -20
- package/dist/components/page/Page.svelte +27 -35
- package/dist/components/page/Page.svelte.d.ts +7 -20
- package/dist/components/page/PageHeader.svelte +2 -2
- package/dist/components/page/PageHeader.svelte.d.ts +6 -19
- package/dist/components/page/PageParagraph.svelte +4 -1
- package/dist/components/page/PageParagraph.svelte.d.ts +5 -28
- package/dist/components/page/PossibleChapter.svelte +7 -7
- package/dist/components/page/PossibleChapter.svelte.d.ts +3 -16
- package/dist/components/page/PossibleReference.svelte +4 -5
- package/dist/components/page/PossibleReference.svelte.d.ts +6 -18
- package/dist/components/page/Print.svelte +18 -2
- package/dist/components/page/Print.svelte.d.ts +3 -16
- package/dist/components/page/Publish.svelte +47 -47
- package/dist/components/page/Publish.svelte.d.ts +3 -16
- package/dist/components/page/Reference.svelte +24 -35
- package/dist/components/page/Reference.svelte.d.ts +6 -18
- package/dist/components/page/References.svelte +21 -22
- package/dist/components/page/References.svelte.d.ts +3 -16
- package/dist/components/page/Rows.svelte +4 -1
- package/dist/components/page/Rows.svelte.d.ts +5 -28
- package/dist/components/page/Search.svelte +58 -60
- package/dist/components/page/Search.svelte.d.ts +3 -16
- package/dist/components/page/Status.svelte +2 -2
- package/dist/components/page/Status.svelte.d.ts +16 -14
- package/dist/components/page/SubdomainEditor.svelte +11 -11
- package/dist/components/page/SubdomainEditor.svelte.d.ts +16 -14
- package/dist/components/page/TableOfContents.svelte +143 -125
- package/dist/components/page/TableOfContents.svelte.d.ts +3 -16
- package/dist/components/page/TableOfContentsImage.svelte +6 -7
- package/dist/components/page/TableOfContentsImage.svelte.d.ts +6 -18
- package/dist/components/page/TableOfContentsRow.svelte +32 -32
- package/dist/components/page/TableOfContentsRow.svelte.d.ts +10 -22
- package/dist/components/page/ThemeEditor.svelte +35 -28
- package/dist/components/page/ThemeEditor.svelte.d.ts +3 -16
- package/dist/components/page/ThemeEditorPreview.svelte +11 -13
- package/dist/components/page/ThemeEditorPreview.svelte.d.ts +5 -17
- package/dist/components/page/ThemeSetEditor.svelte +4 -6
- package/dist/components/page/ThemeSetEditor.svelte.d.ts +7 -19
- package/dist/components/page/ThemeVariableEditor.svelte +9 -11
- package/dist/components/page/ThemeVariableEditor.svelte.d.ts +7 -19
- package/dist/components/page/Title.svelte +4 -1
- package/dist/components/page/Title.svelte.d.ts +5 -28
- package/dist/components/page/Unknown.svelte +11 -8
- package/dist/components/page/Unknown.svelte.d.ts +5 -17
- package/dist/models/CRUD.js +23 -4
- package/dist/models/Firebase.js +18 -4
- package/dist/models/book/Book.d.ts +1 -1
- package/dist/models/book/Book.js +4 -3
- package/dist/models/book/BookMedia.js +1 -2
- package/dist/models/book/Chapter.js +3 -2
- package/dist/models/book/Edition.d.ts +1 -1
- package/dist/models/book/Edition.js +5 -1
- package/dist/models/chapter/BlocksNode.js +3 -1
- package/dist/models/chapter/BlocksNode.test.js +5 -1
- package/dist/models/chapter/Node.test.js +2 -2
- package/package.json +36 -25
|
@@ -1,203 +1,173 @@
|
|
|
1
|
-
<script>import Parser from
|
|
2
|
-
import Header from
|
|
3
|
-
import Authors from
|
|
4
|
-
import Outline from
|
|
5
|
-
import Page from
|
|
6
|
-
import TextEditor from
|
|
7
|
-
import BookishEditor from
|
|
8
|
-
import Toggle from
|
|
9
|
-
import Instructions from
|
|
10
|
-
import ChapterBody from
|
|
11
|
-
import PossibleReference from
|
|
12
|
-
import ChapterNumber from
|
|
13
|
-
import Problem from
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
1
|
+
<script lang="ts">import Parser from "../../models/chapter/Parser";
|
|
2
|
+
import Header from "./Header.svelte";
|
|
3
|
+
import Authors from "./Authors.svelte";
|
|
4
|
+
import Outline from "./Outline.svelte";
|
|
5
|
+
import Page from "./Page.svelte";
|
|
6
|
+
import TextEditor from "../editor/TextEditor.svelte";
|
|
7
|
+
import BookishEditor from "../editor/BookishEditor.svelte";
|
|
8
|
+
import Toggle from "../editor/Toggle.svelte";
|
|
9
|
+
import Instructions from "./Instructions.svelte";
|
|
10
|
+
import ChapterBody from "../chapter/ChapterBody.svelte";
|
|
11
|
+
import PossibleReference from "./PossibleReference.svelte";
|
|
12
|
+
import ChapterNumber from "./ChapterNumber.svelte";
|
|
13
|
+
import Problem from "../chapter/Problem.svelte";
|
|
14
|
+
import {
|
|
15
|
+
CHAPTER,
|
|
16
|
+
getUser,
|
|
17
|
+
getBook,
|
|
18
|
+
getEdition,
|
|
19
|
+
isBookEditable,
|
|
20
|
+
isChapterEditable,
|
|
21
|
+
isEditionPartiallyEditable,
|
|
22
|
+
getLeasee,
|
|
23
|
+
lease,
|
|
24
|
+
setChapter,
|
|
25
|
+
isEditionEditable
|
|
26
|
+
} from "./Contexts";
|
|
27
|
+
import { writable } from "svelte/store";
|
|
28
|
+
import { onMount, setContext } from "svelte";
|
|
29
|
+
import { hideOutlineIfObscured, layoutMarginals } from "./margins";
|
|
30
|
+
import scrollToEyeLevel from "../../util/scrollToEyeLevel";
|
|
31
|
+
import { goto } from "$app/navigation";
|
|
32
|
+
import ChapterNode from "../../models/chapter/ChapterNode";
|
|
33
|
+
import Muted from "./Muted.svelte";
|
|
34
|
+
import Title from "./Title.svelte";
|
|
35
|
+
import PageHeader from "./PageHeader.svelte";
|
|
36
|
+
import Permissions from "../editor/Permissions.svelte";
|
|
37
|
+
let { chapter, print = false } = $props();
|
|
27
38
|
let book = getBook();
|
|
28
39
|
let edition = getEdition();
|
|
29
40
|
let auth = getUser();
|
|
30
|
-
// Keep track of the scroll position to facilitate reading during reloads.
|
|
31
41
|
function rememberPosition() {
|
|
32
|
-
|
|
42
|
+
localStorage.setItem("scrollposition", "" + window.scrollY);
|
|
33
43
|
}
|
|
34
|
-
|
|
35
|
-
let
|
|
36
|
-
// Keep track of which hash mark is scrolled to
|
|
37
|
-
let highlightedID = undefined;
|
|
38
|
-
// When this component is mounted...
|
|
39
|
-
// 1) Subscribe and unsubscribe to window listeners
|
|
40
|
-
// 2) Do initial layout of marginals
|
|
41
|
-
// 3) Start observing any elements corresponding to the ID in the URL's hash string
|
|
42
|
-
// 4) Clean up our mess after unmounting.
|
|
44
|
+
let marginal = writable(void 0);
|
|
45
|
+
let highlightedID = $state(void 0);
|
|
43
46
|
onMount(() => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
highlightedID = elementID;
|
|
55
|
-
// Start watching this a few seconds after we see it, giving the for in-page scrolling.
|
|
56
|
-
setTimeout(() => observer.observe(element), 2500);
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
// Do things to do when scrolling
|
|
60
|
-
const handleScroll = () => {
|
|
61
|
-
// See if the outline is obscured by an image
|
|
62
|
-
hideOutlineIfObscured();
|
|
63
|
-
// See if there are any new hashes to observe. This is because
|
|
64
|
-
// we're using react-router-hash-link, which doesn't trigger hashchange events for some reason.
|
|
65
|
-
observeHash();
|
|
66
|
-
};
|
|
67
|
-
// Lay things out when the window or scroll changes.
|
|
68
|
-
window.addEventListener('scroll', handleScroll);
|
|
69
|
-
// When the chapter view resizes, the responsive layout might cause the marginals to move to the footer.
|
|
70
|
-
// when this happens, we want to immediately remove all of the explicit positioning.
|
|
71
|
-
const resize = new ResizeObserver(() => layoutMarginals());
|
|
72
|
-
resize.observe(document.body);
|
|
73
|
-
// Remember the scroll position before a refresh.
|
|
74
|
-
// We have to do all of these because browser support varies.
|
|
75
|
-
window.addEventListener('beforeunload', rememberPosition);
|
|
76
|
-
window.addEventListener('visibilitychange', rememberPosition);
|
|
77
|
-
window.addEventListener('pagehide', rememberPosition);
|
|
78
|
-
// Start listening for hash changes, since we want to remove them upon scrolling away from them.
|
|
79
|
-
window.addEventListener('pushstate', observeHash);
|
|
80
|
-
window.addEventListener('popstate', observeHash);
|
|
81
|
-
window.addEventListener('hashchange', observeHash);
|
|
82
|
-
// Make an intersection observer to monitor the location of elements selected by the URL hash ID.
|
|
83
|
-
const observer = new IntersectionObserver((entries) => {
|
|
84
|
-
// Go through all of the monitored elements
|
|
85
|
-
entries.forEach((entry) => {
|
|
86
|
-
// If the observed element is out of view and in the hash, remove the hash
|
|
87
|
-
if (entry.intersectionRatio === 0 &&
|
|
88
|
-
entry.target.id === window.location.hash.substring(1)) {
|
|
89
|
-
history.pushState('', document.title, window.location.pathname + window.location.search);
|
|
90
|
-
observer.unobserve(entry.target);
|
|
91
|
-
highlightedID = undefined;
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
// Do an initial check the hash to see if there's an ID to scroll to
|
|
47
|
+
const observeHash = () => {
|
|
48
|
+
const elementID = window.location.hash.substring(1);
|
|
49
|
+
const element = elementID ? document.getElementById(elementID) : null;
|
|
50
|
+
if (element) {
|
|
51
|
+
highlightedID = elementID;
|
|
52
|
+
setTimeout(() => observer.observe(element), 2500);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
const handleScroll = () => {
|
|
56
|
+
hideOutlineIfObscured();
|
|
96
57
|
observeHash();
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
58
|
+
};
|
|
59
|
+
window.addEventListener("scroll", handleScroll);
|
|
60
|
+
const resize = new ResizeObserver(() => requestLayout());
|
|
61
|
+
resize.observe(document.body);
|
|
62
|
+
window.addEventListener("beforeunload", rememberPosition);
|
|
63
|
+
window.addEventListener("visibilitychange", rememberPosition);
|
|
64
|
+
window.addEventListener("pagehide", rememberPosition);
|
|
65
|
+
window.addEventListener("pushstate", observeHash);
|
|
66
|
+
window.addEventListener("popstate", observeHash);
|
|
67
|
+
window.addEventListener("hashchange", observeHash);
|
|
68
|
+
const observer = new IntersectionObserver((entries) => {
|
|
69
|
+
entries.forEach((entry) => {
|
|
70
|
+
if (entry.intersectionRatio === 0 && entry.target.id === window.location.hash.substring(1)) {
|
|
71
|
+
history.pushState(
|
|
72
|
+
"",
|
|
73
|
+
document.title,
|
|
74
|
+
window.location.pathname + window.location.search
|
|
75
|
+
);
|
|
76
|
+
observer.unobserve(entry.target);
|
|
77
|
+
highlightedID = void 0;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
observeHash();
|
|
82
|
+
layoutMarginals();
|
|
83
|
+
return () => {
|
|
84
|
+
window.removeEventListener("scroll", handleScroll);
|
|
85
|
+
resize.unobserve(document.body);
|
|
86
|
+
window.removeEventListener("beforeunload", rememberPosition);
|
|
87
|
+
window.removeEventListener("visibilitychange", rememberPosition);
|
|
88
|
+
window.removeEventListener("pagehide", rememberPosition);
|
|
89
|
+
localStorage.removeItem("scrollposition");
|
|
90
|
+
window.removeEventListener("pushstate", observeHash);
|
|
91
|
+
window.removeEventListener("popstate", observeHash);
|
|
92
|
+
window.removeEventListener("hashchange", observeHash);
|
|
93
|
+
observer.disconnect();
|
|
94
|
+
};
|
|
116
95
|
});
|
|
117
|
-
// Position the marginals on mount.
|
|
118
96
|
onMount(() => layoutMarginals());
|
|
119
|
-
// This gets called after the page is done loading. There are various things we scroll to.
|
|
120
97
|
function scrollToLastLocation() {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
num < highlights.length &&
|
|
130
|
-
num >= 0) {
|
|
131
|
-
scrollToEyeLevel(highlights[num]);
|
|
132
|
-
}
|
|
98
|
+
layoutMarginals();
|
|
99
|
+
if (location.search) {
|
|
100
|
+
const highlights = document.getElementsByClassName(
|
|
101
|
+
"bookish-text bookish-content-highlight"
|
|
102
|
+
);
|
|
103
|
+
const num = getHighlightedNumber();
|
|
104
|
+
if (num && highlights.length > 0 && num < highlights.length && num >= 0) {
|
|
105
|
+
scrollToEyeLevel(highlights[num]);
|
|
133
106
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (el) {
|
|
139
|
-
scrollToEyeLevel(el);
|
|
140
|
-
}
|
|
107
|
+
} else if (highlightedID) {
|
|
108
|
+
const el = document.getElementById(highlightedID);
|
|
109
|
+
if (el) {
|
|
110
|
+
scrollToEyeLevel(el);
|
|
141
111
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
.type === 'reload') {
|
|
150
|
-
// Scroll to the previous position, if there was one, so that refresh preserves position.
|
|
151
|
-
window.scrollTo(0, parseInt(position));
|
|
152
|
-
}
|
|
153
|
-
// Otherwise, just scroll to the top.
|
|
154
|
-
else {
|
|
155
|
-
window.scrollTo(0, 0);
|
|
156
|
-
}
|
|
112
|
+
} else {
|
|
113
|
+
const entries = performance.getEntriesByType("navigation");
|
|
114
|
+
const position = localStorage.getItem("scrollposition");
|
|
115
|
+
if (position !== null && entries.length > 0 && entries[entries.length - 1].type === "reload") {
|
|
116
|
+
window.scrollTo(0, parseInt(position));
|
|
117
|
+
} else {
|
|
118
|
+
window.scrollTo(0, 0);
|
|
157
119
|
}
|
|
120
|
+
}
|
|
158
121
|
}
|
|
159
|
-
/** Account for static builds, where location isn't defined */
|
|
160
122
|
function getLocation() {
|
|
161
|
-
|
|
123
|
+
return typeof location === "undefined" ? void 0 : location;
|
|
162
124
|
}
|
|
163
125
|
function getHighlightedWord() {
|
|
164
|
-
|
|
126
|
+
return getLocation()?.search.split("&")[0]?.split("=")[1] ?? void 0;
|
|
165
127
|
}
|
|
166
128
|
function getHighlightedNumber() {
|
|
167
|
-
|
|
168
|
-
|
|
129
|
+
const number = getLocation()?.search.split("&")[1]?.split("=")[1];
|
|
130
|
+
return number === void 0 ? void 0 : parseInt(number);
|
|
131
|
+
}
|
|
132
|
+
let chapterID = $derived(chapter.getID());
|
|
133
|
+
let chapterNumber = $derived($edition?.getChapterNumber(chapterID));
|
|
134
|
+
let chapterSection = $derived($edition?.getChapterSection(chapterID));
|
|
135
|
+
let chapterAST = $derived($edition ? chapter.getAST($edition) : void 0);
|
|
136
|
+
let citations = $derived(chapterAST ? chapterAST.getCitations() : void 0);
|
|
137
|
+
let editionNumber = $derived($edition ? $edition.getEditionNumber() : void 0);
|
|
138
|
+
let layoutRequested = false;
|
|
139
|
+
function requestLayout() {
|
|
140
|
+
if (typeof requestAnimationFrame === "undefined") return;
|
|
141
|
+
if (layoutRequested) return;
|
|
142
|
+
layoutRequested = true;
|
|
143
|
+
requestAnimationFrame(() => {
|
|
144
|
+
layoutRequested = false;
|
|
145
|
+
layoutMarginals();
|
|
146
|
+
});
|
|
169
147
|
}
|
|
170
|
-
// Prepare to render the chapter by getting some data from the chapter and book.
|
|
171
|
-
$: chapterID = chapter.getID();
|
|
172
|
-
$: chapterNumber = $edition?.getChapterNumber(chapterID);
|
|
173
|
-
$: chapterSection = $edition?.getChapterSection(chapterID);
|
|
174
|
-
$: chapterAST = $edition ? chapter.getAST($edition) : undefined;
|
|
175
|
-
$: citations = chapterAST ? chapterAST.getCitations() : undefined;
|
|
176
|
-
$: editionNumber = $edition ? $edition.getEditionNumber() : undefined;
|
|
177
148
|
let chapterStore = writable();
|
|
178
149
|
setContext(CHAPTER, chapterStore);
|
|
179
|
-
|
|
150
|
+
$effect.pre(() => {
|
|
151
|
+
chapterStore.set({
|
|
180
152
|
chapter,
|
|
181
153
|
highlightedWord: getHighlightedWord(),
|
|
182
154
|
highlightedID,
|
|
183
155
|
marginal,
|
|
184
|
-
|
|
156
|
+
requestLayout
|
|
157
|
+
});
|
|
185
158
|
});
|
|
186
|
-
let editable =
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
($auth !== undefined &&
|
|
190
|
-
$auth.user !== null &&
|
|
191
|
-
chapter.isEditor($auth.user.uid));
|
|
159
|
+
let editable = $derived(
|
|
160
|
+
!print && (isBookEditable() || isEditionEditable() || isChapterEditable() || $auth !== void 0 && $auth.user !== null && chapter.isEditor($auth.user.uid))
|
|
161
|
+
);
|
|
192
162
|
</script>
|
|
193
163
|
|
|
194
164
|
{#if $edition}
|
|
195
165
|
<Page
|
|
196
166
|
afterLoaded={scrollToLastLocation}
|
|
197
|
-
title={`${$edition.getTitle()} - ${chapter.getTitle()}`}
|
|
167
|
+
title={print ? undefined : `${$edition.getTitle()} - ${chapter.getTitle()}`}
|
|
198
168
|
>
|
|
199
169
|
<Header
|
|
200
|
-
editable
|
|
170
|
+
{editable}
|
|
201
171
|
id={chapter.id}
|
|
202
172
|
header={chapter.getTitle()}
|
|
203
173
|
label="Chapter title"
|
|
@@ -210,94 +180,100 @@ let editable = isBookEditable() ||
|
|
|
210
180
|
{print}
|
|
211
181
|
>
|
|
212
182
|
<!-- Collapse the outline if a marginal is selected. -->
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
183
|
+
{#snippet outline()}
|
|
184
|
+
<Outline
|
|
185
|
+
|
|
186
|
+
collapse={$marginal !== undefined}
|
|
187
|
+
previous={$edition.getPreviousChapterID(chapterID, editable)}
|
|
188
|
+
next={$edition.getNextChapterID(chapterID, editable)}
|
|
189
|
+
listener={(expanded) => {
|
|
190
|
+
// If the outline is being expanded, hide the marginal, otherwise leave it alone.
|
|
191
|
+
if (expanded) marginal.set(undefined);
|
|
221
192
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
193
|
+
// Check if we need to hide the outline after positioning.
|
|
194
|
+
hideOutlineIfObscured();
|
|
195
|
+
}}
|
|
196
|
+
/>
|
|
197
|
+
{/snippet}
|
|
226
198
|
<!-- Add an editable chapter ID if in editor mode -->
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
<
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
<ChapterNumber
|
|
273
|
-
>{#if chapterNumber !== undefined}Chapter {chapterNumber}{:else}<Muted
|
|
274
|
-
>Unnumbered</Muted
|
|
275
|
-
>{/if}</ChapterNumber
|
|
199
|
+
{#snippet before()}
|
|
200
|
+
|
|
201
|
+
{#if editable && $book}
|
|
202
|
+
<Muted>
|
|
203
|
+
<em>bookish.press/book/</em><TextEditor
|
|
204
|
+
text={chapter.getID()}
|
|
205
|
+
label="Chapter URL ID editor"
|
|
206
|
+
save={// After the ID is edited, reload the page with the new URL.
|
|
207
|
+
async (newChapterID) => {
|
|
208
|
+
if ($book) {
|
|
209
|
+
setChapter(
|
|
210
|
+
edition,
|
|
211
|
+
chapter,
|
|
212
|
+
chapter.withChapterID(newChapterID),
|
|
213
|
+
);
|
|
214
|
+
// Navigate to the new ID
|
|
215
|
+
goto(
|
|
216
|
+
`/write/${$book.getID()}/${editionNumber}/${newChapterID}`,
|
|
217
|
+
{
|
|
218
|
+
keepFocus: true,
|
|
219
|
+
},
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
}}
|
|
223
|
+
placeholder="chapter name"
|
|
224
|
+
valid={(newChapterID) =>
|
|
225
|
+
!/^[a-zA-Z0-9]+$/.test(newChapterID)
|
|
226
|
+
? 'Chapter IDs must be one or more letters or numbers'
|
|
227
|
+
: chapter.getID() !== newChapterID &&
|
|
228
|
+
$edition?.hasChapter(newChapterID)
|
|
229
|
+
? "There's already a chapter that has this ID."
|
|
230
|
+
: undefined}
|
|
231
|
+
saveOnExit={true}
|
|
232
|
+
/>
|
|
233
|
+
</Muted>
|
|
234
|
+
{/if}
|
|
235
|
+
{#if editable}
|
|
236
|
+
<Toggle
|
|
237
|
+
on={chapter.isNumbered()}
|
|
238
|
+
save={(on) =>
|
|
239
|
+
setChapter(
|
|
240
|
+
edition,
|
|
241
|
+
chapter,
|
|
242
|
+
chapter.asNumbered(on),
|
|
243
|
+
)}
|
|
276
244
|
>
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
245
|
+
<ChapterNumber
|
|
246
|
+
>{#if chapterNumber !== undefined}Chapter {chapterNumber}{:else}<Muted
|
|
247
|
+
>Unnumbered</Muted
|
|
248
|
+
>{/if}</ChapterNumber
|
|
249
|
+
>
|
|
250
|
+
</Toggle>
|
|
251
|
+
{:else if chapterNumber !== undefined}
|
|
252
|
+
<ChapterNumber>Chapter {chapterNumber}</ChapterNumber>
|
|
253
|
+
{/if}
|
|
254
|
+
{#if chapterSection !== undefined && chapterSection.length > 0}
|
|
255
|
+
<span class="section-name">{chapterSection}</span>
|
|
256
|
+
{/if}
|
|
257
|
+
|
|
258
|
+
{/snippet}
|
|
285
259
|
<!-- If there are chapter authors, render those, otherwise use the book authors -->
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
260
|
+
{#snippet after()}
|
|
261
|
+
<Authors
|
|
262
|
+
editable={isChapterEditable()}
|
|
263
|
+
|
|
264
|
+
authors={chapter.getAuthors()}
|
|
265
|
+
inheritedAuthors={$edition.getAuthors()}
|
|
266
|
+
add={() => setChapter(edition, chapter, chapter.withAuthor(''))}
|
|
267
|
+
edit={(index, text) =>
|
|
268
|
+
setChapter(
|
|
269
|
+
edition,
|
|
270
|
+
chapter,
|
|
271
|
+
chapter.withRenamedAuthor(index, text),
|
|
272
|
+
)}
|
|
273
|
+
remove={(index) =>
|
|
274
|
+
setChapter(edition, chapter, chapter.withoutAuthor(index))}
|
|
275
|
+
/>
|
|
276
|
+
{/snippet}
|
|
301
277
|
</Header>
|
|
302
278
|
|
|
303
279
|
<Instructions {editable}>
|
|
@@ -1,20 +1,8 @@
|
|
|
1
|
-
import { SvelteComponent } from "svelte";
|
|
2
1
|
import type ChapterModel from '../../models/book/Chapter';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
print?: boolean;
|
|
7
|
-
};
|
|
8
|
-
events: {
|
|
9
|
-
[evt: string]: CustomEvent<any>;
|
|
10
|
-
};
|
|
11
|
-
slots: {};
|
|
12
|
-
exports?: {} | undefined;
|
|
13
|
-
bindings?: string | undefined;
|
|
14
|
-
};
|
|
15
|
-
export type ChapterProps = typeof __propDef.props;
|
|
16
|
-
export type ChapterEvents = typeof __propDef.events;
|
|
17
|
-
export type ChapterSlots = typeof __propDef.slots;
|
|
18
|
-
export default class Chapter extends SvelteComponent<ChapterProps, ChapterEvents, ChapterSlots> {
|
|
2
|
+
interface Props {
|
|
3
|
+
chapter: ChapterModel;
|
|
4
|
+
print?: boolean;
|
|
19
5
|
}
|
|
20
|
-
|
|
6
|
+
declare const Chapter: import("svelte").Component<Props, {}, "">;
|
|
7
|
+
type Chapter = ReturnType<typeof Chapter>;
|
|
8
|
+
export default Chapter;
|
|
@@ -5,6 +5,8 @@ type ChapterContext = {
|
|
|
5
5
|
highlightedWord?: string;
|
|
6
6
|
highlightedID?: string;
|
|
7
7
|
marginal: Writable<string | undefined>;
|
|
8
|
-
|
|
8
|
+
/** Request a chapter-wide marginal layout pass. Requests are
|
|
9
|
+
* coalesced into a single pass per animation frame. */
|
|
10
|
+
requestLayout: () => void;
|
|
9
11
|
} | undefined;
|
|
10
12
|
export type { ChapterContext as default };
|
|
@@ -1,29 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/** @typedef {typeof __propDef.slots} ChapterNumberSlots */
|
|
4
|
-
export default class ChapterNumber extends SvelteComponent<{
|
|
5
|
-
[x: string]: never;
|
|
6
|
-
}, {
|
|
7
|
-
[evt: string]: CustomEvent<any>;
|
|
8
|
-
}, {
|
|
9
|
-
default: {};
|
|
10
|
-
}> {
|
|
1
|
+
interface Props {
|
|
2
|
+
children?: import('svelte').Snippet;
|
|
11
3
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export
|
|
15
|
-
import { SvelteComponent } from "svelte";
|
|
16
|
-
declare const __propDef: {
|
|
17
|
-
props: {
|
|
18
|
-
[x: string]: never;
|
|
19
|
-
};
|
|
20
|
-
events: {
|
|
21
|
-
[evt: string]: CustomEvent<any>;
|
|
22
|
-
};
|
|
23
|
-
slots: {
|
|
24
|
-
default: {};
|
|
25
|
-
};
|
|
26
|
-
exports?: undefined;
|
|
27
|
-
bindings?: undefined;
|
|
28
|
-
};
|
|
29
|
-
export {};
|
|
4
|
+
declare const ChapterNumber: import("svelte").Component<Props, {}, "">;
|
|
5
|
+
type ChapterNumber = ReturnType<typeof ChapterNumber>;
|
|
6
|
+
export default ChapterNumber;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
<script>import Link from
|
|
2
|
-
|
|
1
|
+
<script lang="ts">import Link from "../Link.svelte";
|
|
2
|
+
let { link = void 0, children } = $props();
|
|
3
3
|
</script>
|
|
4
4
|
|
|
5
5
|
{#if link}
|
|
6
|
-
<Link to={link}><h3>
|
|
6
|
+
<Link to={link}><h3> {@render children?.()}</h3></Link>
|
|
7
7
|
{:else}
|
|
8
|
-
<h3
|
|
8
|
+
<h3>{@render children?.()}</h3>
|
|
9
9
|
{/if}
|
|
10
10
|
|
|
11
11
|
<style>
|