bookish-press 0.4.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.
Files changed (309) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +5 -0
  3. package/components/Auth.svelte +52 -0
  4. package/components/Auth.svelte.d.ts +16 -0
  5. package/components/Authentication.d.ts +8 -0
  6. package/components/Authentication.js +1 -0
  7. package/components/BookPreview.svelte +87 -0
  8. package/components/BookPreview.svelte.d.ts +18 -0
  9. package/components/External.svelte +4 -0
  10. package/components/External.svelte.d.ts +18 -0
  11. package/components/Link.svelte +5 -0
  12. package/components/Link.svelte.d.ts +19 -0
  13. package/components/chapter/Atom.svelte +36 -0
  14. package/components/chapter/Atom.svelte.d.ts +19 -0
  15. package/components/chapter/Block.svelte +32 -0
  16. package/components/chapter/Block.svelte.d.ts +17 -0
  17. package/components/chapter/Callout.svelte +10 -0
  18. package/components/chapter/Callout.svelte.d.ts +17 -0
  19. package/components/chapter/CaptionedCode.svelte +34 -0
  20. package/components/chapter/CaptionedCode.svelte.d.ts +17 -0
  21. package/components/chapter/ChapterBody.svelte +23 -0
  22. package/components/chapter/ChapterBody.svelte.d.ts +18 -0
  23. package/components/chapter/Citations.svelte +66 -0
  24. package/components/chapter/Citations.svelte.d.ts +17 -0
  25. package/components/chapter/Code.svelte +35 -0
  26. package/components/chapter/Code.svelte.d.ts +22 -0
  27. package/components/chapter/Comment.svelte +46 -0
  28. package/components/chapter/Comment.svelte.d.ts +17 -0
  29. package/components/chapter/Definition.svelte +38 -0
  30. package/components/chapter/Definition.svelte.d.ts +20 -0
  31. package/components/chapter/Embed.svelte +122 -0
  32. package/components/chapter/Embed.svelte.d.ts +18 -0
  33. package/components/chapter/ErrorMessage.svelte +4 -0
  34. package/components/chapter/ErrorMessage.svelte.d.ts +17 -0
  35. package/components/chapter/Footnote.svelte +37 -0
  36. package/components/chapter/Footnote.svelte.d.ts +19 -0
  37. package/components/chapter/Format.svelte +57 -0
  38. package/components/chapter/Format.svelte.d.ts +18 -0
  39. package/components/chapter/InlineCode.svelte +12 -0
  40. package/components/chapter/InlineCode.svelte.d.ts +17 -0
  41. package/components/chapter/Label.svelte +20 -0
  42. package/components/chapter/Label.svelte.d.ts +17 -0
  43. package/components/chapter/Link.svelte +51 -0
  44. package/components/chapter/Link.svelte.d.ts +17 -0
  45. package/components/chapter/List.svelte +14 -0
  46. package/components/chapter/List.svelte.d.ts +17 -0
  47. package/components/chapter/Marginal.svelte +48 -0
  48. package/components/chapter/Marginal.svelte.d.ts +19 -0
  49. package/components/chapter/Paragraph.svelte +15 -0
  50. package/components/chapter/Paragraph.svelte.d.ts +18 -0
  51. package/components/chapter/Python.svelte +81 -0
  52. package/components/chapter/Python.svelte.d.ts +18 -0
  53. package/components/chapter/Quote.svelte +16 -0
  54. package/components/chapter/Quote.svelte.d.ts +17 -0
  55. package/components/chapter/Rule.svelte +4 -0
  56. package/components/chapter/Rule.svelte.d.ts +17 -0
  57. package/components/chapter/Table.svelte +29 -0
  58. package/components/chapter/Table.svelte.d.ts +17 -0
  59. package/components/chapter/Text.svelte +62 -0
  60. package/components/chapter/Text.svelte.d.ts +17 -0
  61. package/components/chapter/renderPosition.d.ts +3 -0
  62. package/components/chapter/renderPosition.js +4 -0
  63. package/components/editor/BookishEditor.svelte +755 -0
  64. package/components/editor/BookishEditor.svelte.d.ts +22 -0
  65. package/components/editor/CalloutEditor.svelte +10 -0
  66. package/components/editor/CalloutEditor.svelte.d.ts +17 -0
  67. package/components/editor/CaptionedCodeEditor.svelte +22 -0
  68. package/components/editor/CaptionedCodeEditor.svelte.d.ts +17 -0
  69. package/components/editor/CaretContext.d.ts +18 -0
  70. package/components/editor/CaretContext.js +1 -0
  71. package/components/editor/CaretState.d.ts +47 -0
  72. package/components/editor/CaretState.js +1 -0
  73. package/components/editor/CaretUtilities.d.ts +5 -0
  74. package/components/editor/CaretUtilities.js +1 -0
  75. package/components/editor/CitationsEditor.svelte +42 -0
  76. package/components/editor/CitationsEditor.svelte.d.ts +17 -0
  77. package/components/editor/Clipboard.d.ts +3 -0
  78. package/components/editor/Clipboard.js +1 -0
  79. package/components/editor/Command.d.ts +18 -0
  80. package/components/editor/Command.js +1 -0
  81. package/components/editor/Commands.d.ts +3 -0
  82. package/components/editor/Commands.js +951 -0
  83. package/components/editor/ConfirmButton.svelte +43 -0
  84. package/components/editor/ConfirmButton.svelte.d.ts +18 -0
  85. package/components/editor/DefinitionEditor.svelte +28 -0
  86. package/components/editor/DefinitionEditor.svelte.d.ts +17 -0
  87. package/components/editor/EmbedEditor.svelte +87 -0
  88. package/components/editor/EmbedEditor.svelte.d.ts +17 -0
  89. package/components/editor/ImageChooser.svelte +70 -0
  90. package/components/editor/ImageChooser.svelte.d.ts +18 -0
  91. package/components/editor/InlineCodeEditor.svelte +9 -0
  92. package/components/editor/InlineCodeEditor.svelte.d.ts +17 -0
  93. package/components/editor/LabelEditor.svelte +23 -0
  94. package/components/editor/LabelEditor.svelte.d.ts +17 -0
  95. package/components/editor/LanguageEditor.svelte +11 -0
  96. package/components/editor/LanguageEditor.svelte.d.ts +17 -0
  97. package/components/editor/LinkEditor.svelte +75 -0
  98. package/components/editor/LinkEditor.svelte.d.ts +17 -0
  99. package/components/editor/Note.svelte +9 -0
  100. package/components/editor/Note.svelte.d.ts +23 -0
  101. package/components/editor/PositionEditor.svelte +14 -0
  102. package/components/editor/PositionEditor.svelte.d.ts +18 -0
  103. package/components/editor/QuoteEditor.svelte +5 -0
  104. package/components/editor/QuoteEditor.svelte.d.ts +17 -0
  105. package/components/editor/Switch.svelte +56 -0
  106. package/components/editor/Switch.svelte.d.ts +20 -0
  107. package/components/editor/TextEditor.svelte +193 -0
  108. package/components/editor/TextEditor.svelte.d.ts +23 -0
  109. package/components/editor/Toggle.svelte +38 -0
  110. package/components/editor/Toggle.svelte.d.ts +19 -0
  111. package/components/editor/Toolbar.svelte +202 -0
  112. package/components/editor/Toolbar.svelte.d.ts +20 -0
  113. package/components/editor/ToolbarGroup.svelte +41 -0
  114. package/components/editor/ToolbarGroup.svelte.d.ts +19 -0
  115. package/components/editor/ToolbarIcon.svelte +22 -0
  116. package/components/editor/ToolbarIcon.svelte.d.ts +16 -0
  117. package/components/editor/ToolbarSpacer.svelte +1 -0
  118. package/components/editor/ToolbarSpacer.svelte.d.ts +19 -0
  119. package/components/editor/URLEditor.svelte +15 -0
  120. package/components/editor/URLEditor.svelte.d.ts +18 -0
  121. package/components/editor/UndoState.d.ts +8 -0
  122. package/components/editor/UndoState.js +1 -0
  123. package/components/page/Acknowledgements.svelte +29 -0
  124. package/components/page/Acknowledgements.svelte.d.ts +14 -0
  125. package/components/page/Alert.svelte +11 -0
  126. package/components/page/Alert.svelte.d.ts +23 -0
  127. package/components/page/Authors.svelte +62 -0
  128. package/components/page/Authors.svelte.d.ts +20 -0
  129. package/components/page/BulkReferenceEditor.svelte +32 -0
  130. package/components/page/BulkReferenceEditor.svelte.d.ts +14 -0
  131. package/components/page/Chapter.svelte +301 -0
  132. package/components/page/Chapter.svelte.d.ts +18 -0
  133. package/components/page/ChapterContext.d.ts +10 -0
  134. package/components/page/ChapterContext.js +1 -0
  135. package/components/page/Contexts.d.ts +27 -0
  136. package/components/page/Contexts.js +21 -0
  137. package/components/page/DefinitionView.svelte +129 -0
  138. package/components/page/DefinitionView.svelte.d.ts +18 -0
  139. package/components/page/Description.svelte +22 -0
  140. package/components/page/Description.svelte.d.ts +14 -0
  141. package/components/page/Edition.svelte +106 -0
  142. package/components/page/Edition.svelte.d.ts +21 -0
  143. package/components/page/Glossary.svelte +61 -0
  144. package/components/page/Glossary.svelte.d.ts +14 -0
  145. package/components/page/Header.svelte +105 -0
  146. package/components/page/Header.svelte.d.ts +27 -0
  147. package/components/page/Index.svelte +117 -0
  148. package/components/page/Index.svelte.d.ts +14 -0
  149. package/components/page/Instructions.svelte +30 -0
  150. package/components/page/Instructions.svelte.d.ts +16 -0
  151. package/components/page/License.svelte +29 -0
  152. package/components/page/License.svelte.d.ts +14 -0
  153. package/components/page/Loading.svelte +13 -0
  154. package/components/page/Loading.svelte.d.ts +19 -0
  155. package/components/page/Media.svelte +76 -0
  156. package/components/page/Media.svelte.d.ts +14 -0
  157. package/components/page/MediaPreview.svelte +11 -0
  158. package/components/page/MediaPreview.svelte.d.ts +19 -0
  159. package/components/page/Outline.svelte +173 -0
  160. package/components/page/Outline.svelte.d.ts +19 -0
  161. package/components/page/Page.svelte +53 -0
  162. package/components/page/Page.svelte.d.ts +19 -0
  163. package/components/page/PossibleChapter.svelte +14 -0
  164. package/components/page/PossibleChapter.svelte.d.ts +14 -0
  165. package/components/page/PossibleReference.svelte +16 -0
  166. package/components/page/PossibleReference.svelte.d.ts +19 -0
  167. package/components/page/Print.svelte +8 -0
  168. package/components/page/Print.svelte.d.ts +14 -0
  169. package/components/page/Reference.svelte +145 -0
  170. package/components/page/Reference.svelte.d.ts +17 -0
  171. package/components/page/References.svelte +58 -0
  172. package/components/page/References.svelte.d.ts +14 -0
  173. package/components/page/Revisions.svelte +124 -0
  174. package/components/page/Revisions.svelte.d.ts +14 -0
  175. package/components/page/Search.svelte +108 -0
  176. package/components/page/Search.svelte.d.ts +14 -0
  177. package/components/page/Status.svelte +49 -0
  178. package/components/page/Status.svelte.d.ts +19 -0
  179. package/components/page/SubdomainEditor.svelte +30 -0
  180. package/components/page/SubdomainEditor.svelte.d.ts +14 -0
  181. package/components/page/TableOfContents.svelte +234 -0
  182. package/components/page/TableOfContents.svelte.d.ts +14 -0
  183. package/components/page/TableOfContentsImage.svelte +15 -0
  184. package/components/page/TableOfContentsImage.svelte.d.ts +16 -0
  185. package/components/page/TableOfContentsRow.svelte +57 -0
  186. package/components/page/TableOfContentsRow.svelte.d.ts +24 -0
  187. package/components/page/ThemeEditor.svelte +52 -0
  188. package/components/page/ThemeEditor.svelte.d.ts +14 -0
  189. package/components/page/ThemeEditorPreview.svelte +37 -0
  190. package/components/page/ThemeEditorPreview.svelte.d.ts +17 -0
  191. package/components/page/ThemeSetEditor.svelte +17 -0
  192. package/components/page/ThemeSetEditor.svelte.d.ts +18 -0
  193. package/components/page/ThemeVariableEditor.svelte +28 -0
  194. package/components/page/ThemeVariableEditor.svelte.d.ts +18 -0
  195. package/components/page/Unknown.svelte +29 -0
  196. package/components/page/Unknown.svelte.d.ts +16 -0
  197. package/components/page/margins.d.ts +2 -0
  198. package/components/page/margins.js +132 -0
  199. package/models/BookLoader.d.ts +2 -0
  200. package/models/BookLoader.js +67 -0
  201. package/models/Firebase.d.ts +4 -0
  202. package/models/Firebase.js +26 -0
  203. package/models/Firestore.d.ts +22 -0
  204. package/models/Firestore.js +194 -0
  205. package/models/book/Book.d.ts +60 -0
  206. package/models/book/Book.js +135 -0
  207. package/models/book/BookMedia.d.ts +23 -0
  208. package/models/book/BookMedia.js +102 -0
  209. package/models/book/Chapter.d.ts +70 -0
  210. package/models/book/Chapter.js +221 -0
  211. package/models/book/ChapterID.d.ts +10 -0
  212. package/models/book/ChapterID.js +10 -0
  213. package/models/book/Definition.d.ts +6 -0
  214. package/models/book/Definition.js +1 -0
  215. package/models/book/Edition.d.ts +111 -0
  216. package/models/book/Edition.js +466 -0
  217. package/models/book/Theme.d.ts +106 -0
  218. package/models/book/Theme.js +76 -0
  219. package/models/book/ThemeColors.d.ts +15 -0
  220. package/models/book/ThemeColors.js +1 -0
  221. package/models/chapter/AtomNode.d.ts +18 -0
  222. package/models/chapter/AtomNode.js +31 -0
  223. package/models/chapter/BlockNode.d.ts +21 -0
  224. package/models/chapter/BlockNode.js +117 -0
  225. package/models/chapter/BlocksNode.d.ts +50 -0
  226. package/models/chapter/BlocksNode.js +709 -0
  227. package/models/chapter/BlocksNode.test.d.ts +1 -0
  228. package/models/chapter/BlocksNode.test.js +302 -0
  229. package/models/chapter/Bookkeeping.d.ts +4 -0
  230. package/models/chapter/Bookkeeping.js +1 -0
  231. package/models/chapter/CalloutNode.d.ts +17 -0
  232. package/models/chapter/CalloutNode.js +36 -0
  233. package/models/chapter/Caret.d.ts +21 -0
  234. package/models/chapter/Caret.js +69 -0
  235. package/models/chapter/ChapterNode.d.ts +34 -0
  236. package/models/chapter/ChapterNode.js +80 -0
  237. package/models/chapter/CitationsNode.d.ts +16 -0
  238. package/models/chapter/CitationsNode.js +17 -0
  239. package/models/chapter/CodeNode.d.ts +30 -0
  240. package/models/chapter/CodeNode.js +64 -0
  241. package/models/chapter/CommentNode.d.ts +18 -0
  242. package/models/chapter/CommentNode.js +32 -0
  243. package/models/chapter/DefinitionNode.d.ts +12 -0
  244. package/models/chapter/DefinitionNode.js +20 -0
  245. package/models/chapter/Edit.d.ts +7 -0
  246. package/models/chapter/Edit.js +1 -0
  247. package/models/chapter/EmbedNode.d.ts +40 -0
  248. package/models/chapter/EmbedNode.js +89 -0
  249. package/models/chapter/ErrorNode.d.ts +17 -0
  250. package/models/chapter/ErrorNode.js +21 -0
  251. package/models/chapter/FootnoteNode.d.ts +18 -0
  252. package/models/chapter/FootnoteNode.js +29 -0
  253. package/models/chapter/FormatNode.d.ts +60 -0
  254. package/models/chapter/FormatNode.js +614 -0
  255. package/models/chapter/FormatNode.test.d.ts +1 -0
  256. package/models/chapter/FormatNode.test.js +54 -0
  257. package/models/chapter/InlineCodeNode.d.ts +12 -0
  258. package/models/chapter/InlineCodeNode.js +18 -0
  259. package/models/chapter/LabelNode.d.ts +17 -0
  260. package/models/chapter/LabelNode.js +22 -0
  261. package/models/chapter/LinkNode.d.ts +12 -0
  262. package/models/chapter/LinkNode.js +16 -0
  263. package/models/chapter/ListNode.d.ts +51 -0
  264. package/models/chapter/ListNode.js +370 -0
  265. package/models/chapter/ListNode.test.d.ts +1 -0
  266. package/models/chapter/ListNode.test.js +49 -0
  267. package/models/chapter/MetadataNode.d.ts +17 -0
  268. package/models/chapter/MetadataNode.js +24 -0
  269. package/models/chapter/Node.d.ts +36 -0
  270. package/models/chapter/Node.js +173 -0
  271. package/models/chapter/Node.test.d.ts +1 -0
  272. package/models/chapter/Node.test.js +27 -0
  273. package/models/chapter/ParagraphNode.d.ts +33 -0
  274. package/models/chapter/ParagraphNode.js +93 -0
  275. package/models/chapter/ParagraphNode.test.d.ts +1 -0
  276. package/models/chapter/ParagraphNode.test.js +21 -0
  277. package/models/chapter/Parser.d.ts +75 -0
  278. package/models/chapter/Parser.js +824 -0
  279. package/models/chapter/Parser.test.d.ts +1 -0
  280. package/models/chapter/Parser.test.js +25 -0
  281. package/models/chapter/Position.d.ts +2 -0
  282. package/models/chapter/Position.js +1 -0
  283. package/models/chapter/QuoteNode.d.ts +25 -0
  284. package/models/chapter/QuoteNode.js +61 -0
  285. package/models/chapter/ReferenceNode.d.ts +29 -0
  286. package/models/chapter/ReferenceNode.js +48 -0
  287. package/models/chapter/RootNode.d.ts +5 -0
  288. package/models/chapter/RootNode.js +1 -0
  289. package/models/chapter/RuleNode.d.ts +15 -0
  290. package/models/chapter/RuleNode.js +16 -0
  291. package/models/chapter/TableNode.d.ts +35 -0
  292. package/models/chapter/TableNode.js +176 -0
  293. package/models/chapter/TableNode.test.d.ts +1 -0
  294. package/models/chapter/TableNode.test.js +31 -0
  295. package/models/chapter/TextNode.d.ts +36 -0
  296. package/models/chapter/TextNode.js +136 -0
  297. package/models/chapter/TextNode.test.d.ts +1 -0
  298. package/models/chapter/TextNode.test.js +6 -0
  299. package/models/loadEdition.d.ts +5 -0
  300. package/models/loadEdition.js +16 -0
  301. package/package.json +189 -0
  302. package/util/getSubdomain.d.ts +3 -0
  303. package/util/getSubdomain.js +22 -0
  304. package/util/isMobile.d.ts +2 -0
  305. package/util/isMobile.js +6 -0
  306. package/util/mineReference.d.ts +3 -0
  307. package/util/mineReference.js +62 -0
  308. package/util/scrollToEyeLevel.d.ts +2 -0
  309. package/util/scrollToEyeLevel.js +5 -0
@@ -0,0 +1,145 @@
1
+ <script>import { afterUpdate } from "svelte";
2
+ import TextEditor from "../editor/TextEditor.svelte";
3
+ import { getEdition, isEditable } from "./Contexts";
4
+ export let node;
5
+ let editable = isEditable();
6
+ let edition = getEdition();
7
+ let reference = null;
8
+ let editing = false;
9
+ let entered = false;
10
+ afterUpdate(() => {
11
+ if (editing && entered && reference) {
12
+ entered = false;
13
+ reference.querySelector("input")?.focus();
14
+ }
15
+ });
16
+ function startEditing() {
17
+ editing = true;
18
+ entered = true;
19
+ }
20
+ function stopEditing() {
21
+ editing = false;
22
+ }
23
+ </script>
24
+
25
+ <!-- If a short version was requested, try to abbreviate the authors. -->
26
+ {#if node.short }
27
+ {@const authorList = node.authors.split(",") }
28
+ {@const authors = authorList.length === 1 ? authorList[0] :
29
+ authorList.length === 2 ? authorList[0].trim() + " & " + authorList[1].trim() :
30
+ authorList[0].trim() + ", et al."}
31
+ <span data-nodeid={node.nodeID} class="bookish-reference-text">
32
+ {authors}
33
+ ({node.year}).
34
+ {#if node.url === null }
35
+ {node.title}
36
+ {:else}
37
+ <a href={node.url} target={"_blank"}>{node.title}</a>
38
+ {/if}
39
+ {node.title.charAt(node.title.length - 1) === "?" ? "" : "."}
40
+ <em>{node.source}</em>
41
+ </span>
42
+ {:else}
43
+ <!-- If editable, place in rows to make room for text editors to not have to wrap. -->
44
+ <span
45
+ data-nodeid={node.nodeID}
46
+ class="bookish-reference-text"
47
+ tabIndex=0
48
+ on:click|stopPropagation={() => { if(editable && !editing) startEditing(); }}
49
+ on:keydown={event => { if(editable && !editing && (event.key === "Enter" || event.key === " ")) { startEditing(); event.stopPropagation(); }}}
50
+ bind:this={reference}
51
+ >
52
+ <!-- Authors -->
53
+ {#if editable && editing }
54
+ <em>
55
+ <TextEditor
56
+ startText={node.authors}
57
+ label={'Author list editor.'}
58
+ placeholder="Authors"
59
+ valid={ text => {
60
+ if(text.length === 0) return "Authors can't be empty.";
61
+ }}
62
+ save={text => $edition.editReference(node.withAuthors(text))}
63
+ width={60}
64
+ />
65
+ </em>
66
+ {:else}
67
+ {#if node.authors }
68
+ {node.authors}
69
+ {:else}
70
+ <em>Authors</em>
71
+ {/if}
72
+ {/if}
73
+ <!-- Year -->
74
+ <br/>({#if editable && editing }
75
+ <TextEditor
76
+ startText={node.year}
77
+ label={'Year editor.'}
78
+ placeholder="Year"
79
+ valid={ text => {
80
+ if(text.length === 0) return "Year can't be empty";
81
+ if(!/1?[0-9)[0-9]{2}/.test(text)) return "Not a valid year"
82
+ }}
83
+ save={text => $edition.editReference(node.withYear(text))}
84
+ />
85
+ {:else}
86
+ {#if node.year }{node.year}{:else}<em>Year</em>{/if}
87
+ {/if}).
88
+ <!-- Title -->
89
+ {#if editable && editing }
90
+ <br/><TextEditor
91
+ startText={node.title}
92
+ label={'Title editor.'}
93
+ placeholder="Title"
94
+ valid={ text => {
95
+ if(text.length === 0) return "Title can't be empty.";
96
+ }}
97
+ save={text => $edition.editReference(node.withTitle(text))}
98
+ width={60}
99
+ />
100
+ {:else}
101
+ {#if node.url === null}
102
+ {#if node.title}{node.title}{:else}<em>Title</em>{/if}
103
+ {:else}
104
+ <a href={node.url} target={"_blank"}>{#if node.title}{node.title}{:else}<em>Title</em>{/if}</a>
105
+ {/if}
106
+ {/if}.
107
+ <!-- Source -->
108
+ {#if editable && editing }
109
+ <br/><em>
110
+ <TextEditor
111
+ startText={node.source}
112
+ label={'Source editor.'}
113
+ placeholder="Source"
114
+ valid={ text => {
115
+ if(text.length === 0) return "Source can't be empty";
116
+ }}
117
+ save={text => $edition.editReference(node.withSource(text))}
118
+ width={60}
119
+ />
120
+ </em>
121
+ {:else}
122
+ <em>{#if node.source}{node.source}{:else}Source{/if}</em>
123
+ {/if}.
124
+ {#if editable && editing }
125
+ <br/><TextEditor
126
+ startText={node.summary}
127
+ label={'Summary editor.'}
128
+ placeholder="Summary"
129
+ valid={ () => undefined }
130
+ save={text => $edition.editReference(node.withSummary(text))}
131
+ width={60}
132
+ />
133
+ {:else}
134
+ {#if node.summary}
135
+ <span class="bookish-reference-summary">{node.summary}</span>
136
+ {/if}
137
+ {/if}
138
+ {#if editing }
139
+ <br/><button
140
+ on:click|stopPropagation={() => stopEditing()}
141
+ on:keydown={event => { if(editing && (event.key === "Enter" || event.key === " ")) { stopEditing(); event.stopPropagation(); }}}
142
+ >done editing</button>
143
+ {/if}
144
+ </span>
145
+ {/if}
@@ -0,0 +1,17 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import type ReferenceNode from "../../models/chapter/ReferenceNode";
3
+ declare const __propDef: {
4
+ props: {
5
+ node: ReferenceNode;
6
+ };
7
+ events: {
8
+ [evt: string]: CustomEvent<any>;
9
+ };
10
+ slots: {};
11
+ };
12
+ export declare type ReferenceProps = typeof __propDef.props;
13
+ export declare type ReferenceEvents = typeof __propDef.events;
14
+ export declare type ReferenceSlots = typeof __propDef.slots;
15
+ export default class Reference extends SvelteComponentTyped<ReferenceProps, ReferenceEvents, ReferenceSlots> {
16
+ }
17
+ export {};
@@ -0,0 +1,58 @@
1
+ <script>import Header from "./Header.svelte";
2
+ import Outline from './Outline.svelte';
3
+ import Page from './Page.svelte';
4
+ import Parser from "../../models/chapter/Parser";
5
+ import ConfirmButton from '../editor/ConfirmButton.svelte';
6
+ import ChapterIDs from '../../models/book/ChapterID';
7
+ import BulkReferenceEditor from "./BulkReferenceEditor.svelte";
8
+ import PossibleReference from "./PossibleReference.svelte";
9
+ import { getEdition, isEditable } from "./Contexts";
10
+ let edition = getEdition();
11
+ let editable = isEditable();
12
+ $: references = $edition.hasReferences() ? $edition.getReferences() : null;
13
+ // Otherwise, map references to a list with letter headers.
14
+ if (references !== null) {
15
+ }
16
+ </script>
17
+
18
+ <Page title={`${$edition.getTitle()} - References`}>
19
+ <Header
20
+ label="References title"
21
+ getImage={() => $edition.getImage(ChapterIDs.ReferencesID)}
22
+ setImage={(embed) => $edition.setImage(ChapterIDs.ReferencesID, embed)}
23
+ header="References"
24
+ tags={$edition.getTags()}
25
+ >
26
+ <Outline
27
+ slot="outline"
28
+ previous={$edition.getPreviousChapterID(ChapterIDs.ReferencesID)}
29
+ next={$edition.getNextChapterID(ChapterIDs.ReferencesID)}
30
+ />
31
+ </Header>
32
+ {#if editable }<BulkReferenceEditor />{/if}
33
+ {#if references !== null }
34
+ <p><em>Sorted by last name of first author.</em></p>
35
+
36
+ {#each Object.keys(references).sort() as citationID }
37
+ {@const ref = Parser.parseReference(citationID, references === null ? "" : references[citationID], $edition) }
38
+ <!-- {#if letter === undefined || citationID.charAt(0) !== letter) {
39
+ letter = citationID.charAt(0);
40
+ renderedReferences.push(<h2 key={"letter-" + letter} className="bookish-header" id={"references-" + letter}>{letter.toUpperCase()}</h2>);
41
+ } -->
42
+
43
+ <p>
44
+ <PossibleReference node={ref} />
45
+ {#if editable}
46
+ <ConfirmButton
47
+ commandLabel="x"
48
+ confirmLabel="Confirm"
49
+ command={() => $edition.removeReference(citationID)}
50
+ />
51
+ {/if}
52
+ </p>
53
+ {/each}
54
+
55
+ {:else}
56
+ <p>This book has no references.</p>
57
+ {/if}
58
+ </Page>
@@ -0,0 +1,14 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {};
4
+ events: {
5
+ [evt: string]: CustomEvent<any>;
6
+ };
7
+ slots: {};
8
+ };
9
+ export declare type ReferencesProps = typeof __propDef.props;
10
+ export declare type ReferencesEvents = typeof __propDef.events;
11
+ export declare type ReferencesSlots = typeof __propDef.slots;
12
+ export default class References extends SvelteComponentTyped<ReferencesProps, ReferencesEvents, ReferencesSlots> {
13
+ }
14
+ export {};
@@ -0,0 +1,124 @@
1
+ <script>import Parser from "../../models/chapter/Parser";
2
+ import { addDraftInFirestore, publishDraftInFirestore } from "../../models/Firestore";
3
+ import Format from "../chapter/Format.svelte";
4
+ import BookishEditor from "../editor/BookishEditor.svelte";
5
+ import Switch from "../editor/Switch.svelte";
6
+ import Instructions from "./Instructions.svelte";
7
+ import Note from "../editor/Note.svelte";
8
+ import { getEdition, isEditable } from "./Contexts";
9
+ let edition = getEdition();
10
+ let editable = isEditable();
11
+ $: book = $edition.getBook();
12
+ // Legacy revisions
13
+ $: editionRevisions = $edition.getRevisions();
14
+ // Book revisions
15
+ $: bookRevisions = book?.getRevisions();
16
+ // Copy the current draft to create a new draft.
17
+ function handlePublish(index, published) {
18
+ if (book === undefined)
19
+ return;
20
+ publishDraftInFirestore(book, index, published);
21
+ }
22
+ function handleDraftEdition() {
23
+ if (book === undefined)
24
+ return;
25
+ addDraftInFirestore(book);
26
+ }
27
+ </script>
28
+
29
+ {#if editionRevisions.length > 0 }
30
+ <h2 class="bookish-header" id="revisions">Revisions</h2>
31
+ <ul>
32
+ {#each editionRevisions as revision }
33
+ <li><em>{revision[0]}</em>. <Format node={Parser.parseFormat($edition, revision[1])} /></li>
34
+ {/each}
35
+ </ul>
36
+ {/if}
37
+ {#if book && bookRevisions}
38
+ <h2 class="bookish-header" id="revisions">Editions {#if editable}<button on:click={handleDraftEdition}>+</button>{/if}</h2>
39
+ <Instructions>
40
+ Each book has one or more editions, allowing you to track revisions and ensure previous versions remain available.
41
+ When you're ready to revise, make a new edition, then publish it when you're done.
42
+ The edition with a * is the default edition readers will see, unless they explicitly choose to view a previous edition.
43
+ </Instructions>
44
+ <table class="bookish-table">
45
+ <colgroup>
46
+ <col width="5%" />
47
+ <col width="5%" />
48
+ <col width="50%" />
49
+ <col width="35%" />
50
+ </colgroup>
51
+ <tbody>
52
+ {#each bookRevisions as revision, index}
53
+ {@const editionNumber = bookRevisions === undefined ? -1 : bookRevisions.length - index }
54
+ {@const viewing = revision.ref.id === $edition.getRef()?.id }
55
+
56
+ {#if editable || revision.published}
57
+ <tr
58
+ class={`${!revision.published ? "bookish-edition-hidden" : ""} ${viewing ? "bookish-edition-editing": ""} `}
59
+ >
60
+ <td>
61
+ <em>{ editionNumber + (editionNumber === 1 ? "st" : editionNumber === 2 ? "nd" : editionNumber === 3 ? "rd" : "th") }</em> <Note>{(new Date(revision.time).toLocaleDateString("en-us"))}</Note>
62
+ </td>
63
+ <td>
64
+ {#if editable }
65
+ {#if viewing }
66
+ Editing
67
+ {:else}
68
+ <a href={`/write/${book.ref.id}/${bookRevisions.length - index}`}>Edit</a>
69
+ {/if}
70
+ {:else}
71
+ {#if viewing }
72
+ Viewing
73
+ {:else}
74
+ <a href={`/read/${book.ref.id}/${bookRevisions.length - index}`}>View</a>
75
+ {/if}
76
+ {/if}
77
+ </td>
78
+ <td>
79
+ { #if editable }
80
+ <BookishEditor
81
+ ast={Parser.parseFormat(undefined, revision.summary).withTextIfEmpty()}
82
+ save={ newSummary => book ? book.setEditionChangeSummary(newSummary.toBookdown(), index) : undefined }
83
+ chapter={false}
84
+ component={Format}
85
+ placeholder="Summarize this edition's changes."
86
+ />
87
+ {:else}
88
+ {#if revision.summary === ""}
89
+ <em>No summary of changes</em>
90
+ {:else}
91
+ { revision.summary }
92
+ {/if}
93
+ {/if}
94
+ </td>
95
+ <td style="whitespace: nowrap">
96
+ {#if editable}
97
+ <Switch
98
+ position=">"
99
+ options={["hidden", "published"]}
100
+ enabled={revision.published || revision.summary !== ""}
101
+ value={revision.published ? "published" : "hidden"}
102
+ edit={ published => handlePublish(index, published === "published") }
103
+ />
104
+ {#if revision === bookRevisions.find(e => e.published)}*{/if}
105
+ {/if}
106
+ </td>
107
+ </tr>
108
+ {/if}
109
+ {/each}
110
+ </tbody>
111
+ </table>
112
+ {/if}
113
+
114
+ <style>
115
+ .bookish-edition-hidden {
116
+ background: repeating-linear-gradient(
117
+ 45deg,
118
+ var(--bookish-app-background),
119
+ var(--bookish-app-background) 10px,
120
+ var(--bookish-app-chrome-background) 10px,
121
+ var(--bookish-app-chrome-background) 20px
122
+ );
123
+ }
124
+ </style>
@@ -0,0 +1,14 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {};
4
+ events: {
5
+ [evt: string]: CustomEvent<any>;
6
+ };
7
+ slots: {};
8
+ };
9
+ export declare type RevisionsProps = typeof __propDef.props;
10
+ export declare type RevisionsEvents = typeof __propDef.events;
11
+ export declare type RevisionsSlots = typeof __propDef.slots;
12
+ export default class Revisions extends SvelteComponentTyped<RevisionsProps, RevisionsEvents, RevisionsSlots> {
13
+ }
14
+ export {};
@@ -0,0 +1,108 @@
1
+ <script>import Header from "./Header.svelte";
2
+ import Outline from './Outline.svelte';
3
+ import Page from './Page.svelte';
4
+ import Link from "../Link.svelte";
5
+ import Chapter from '../../models/book/Chapter';
6
+ import ChapterIDs from '../../models/book/ChapterID';
7
+ import { onMount } from "svelte";
8
+ import { getBase, getEdition } from "./Contexts";
9
+ let edition = getEdition();
10
+ let base = getBase();
11
+ let query = "";
12
+ let input = null;
13
+ // Focus the query box when loaded
14
+ onMount(() => { if (input)
15
+ input.focus(); });
16
+ // Don't allow spaces
17
+ function handleKeyDown(event) {
18
+ if (event.key === " ") {
19
+ event.preventDefault();
20
+ }
21
+ }
22
+ let results = [];
23
+ $: {
24
+ // Reset the results
25
+ results = [];
26
+ const lowerQuery = query.toLowerCase();
27
+ // Go through all the chapter indexes and find matches.
28
+ if (query.length > 2)
29
+ for (const chapter of $edition.getChapters()) {
30
+ let index = chapter.getIndex();
31
+ // No index yet? Skip this chapter.
32
+ if (index) {
33
+ // Build a DOM to render matches.
34
+ const chapterMatches = [];
35
+ // What are all of the words in the index that match the query?
36
+ for (const word of Object.keys(index)) {
37
+ if (query.length > 0 && word.indexOf(lowerQuery) >= 0) {
38
+ if (index) {
39
+ let matches = index[word];
40
+ matches.forEach((match) => {
41
+ chapterMatches.push(match);
42
+ });
43
+ }
44
+ }
45
+ }
46
+ if (chapterMatches.length > 0) {
47
+ results.push(chapter);
48
+ chapterMatches.forEach((match, index) => {
49
+ // Only highlight the part of the word that matches.
50
+ const start = match.match.toLowerCase().indexOf(lowerQuery);
51
+ results.push({
52
+ link: `${base}/${chapter.getChapterID()}?word=${match.match.toLowerCase()}&number=${index}`,
53
+ left: match.left + match.match.substring(0, start),
54
+ match: match.match.substring(start, start + query.length),
55
+ right: match.match.substring(start + query.length) + match.right
56
+ });
57
+ });
58
+ }
59
+ }
60
+ }
61
+ }
62
+ </script>
63
+
64
+ <Page title={`${$edition.getTitle()} - Search`}>
65
+ <Header
66
+ label="Search title"
67
+ getImage={() => $edition.getImage(ChapterIDs.SearchID)}
68
+ setImage={(embed) => $edition.setImage(ChapterIDs.SearchID, embed)}
69
+ header="Search"
70
+ tags={$edition.getTags()}
71
+ >
72
+ <Outline
73
+ slot="outline"
74
+ previous={$edition.getPreviousChapterID(ChapterIDs.SearchID)}
75
+ next={$edition.getNextChapterID(ChapterIDs.SearchID)}
76
+ />
77
+ </Header>
78
+
79
+ <p>Type a word—just a single word—and we'll show its occurrences in this book:</p>
80
+
81
+ <p>
82
+ <input
83
+ type="text"
84
+ name="query"
85
+ placeholder={"search for a word"}
86
+ on:keydown={handleKeyDown}
87
+ bind:this={input}
88
+ bind:value={query}
89
+ />
90
+ </p>
91
+
92
+ {#if query !== "" }
93
+ {#if query.length < 3 }
94
+ <p>Keep typing...</p>
95
+ {:else if results.length === 0 }
96
+ <p>No occurrence of <em>{query}</em>.</p>
97
+ {:else}
98
+ <p>Found {results.filter(result => !(result instanceof Chapter)).length} occurrences of <em>{query}</em>...</p>
99
+ {#each results as result }
100
+ {#if result instanceof Chapter }
101
+ <h2 class="bookish-header" id={"header-" + result.getChapterID()}>Chapter{#if $edition.getChapterNumber(result.getChapterID()) !== undefined}&nbsp;{$edition.getChapterNumber(result.getChapterID())}{/if} - {result.getTitle()}</h2>
102
+ {:else}
103
+ <p><Link to={result.link}>...{result.left}<span class="bookish-content-highlight">{result.match}</span>{result.right}...</Link></p>
104
+ {/if}
105
+ {/each}
106
+ {/if}
107
+ {/if}
108
+ </Page>
@@ -0,0 +1,14 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {};
4
+ events: {
5
+ [evt: string]: CustomEvent<any>;
6
+ };
7
+ slots: {};
8
+ };
9
+ export declare type SearchProps = typeof __propDef.props;
10
+ export declare type SearchEvents = typeof __propDef.events;
11
+ export declare type SearchSlots = typeof __propDef.slots;
12
+ export default class Search extends SvelteComponentTyped<SearchProps, SearchEvents, SearchSlots> {
13
+ }
14
+ export {};
@@ -0,0 +1,49 @@
1
+ <script>import { BookSaveStatus } from "../../models/book/Edition";
2
+ import { onMount } from "svelte";
3
+ export let book;
4
+ export let edition;
5
+ let status = BookSaveStatus.Saved;
6
+ function handleBookChange(newStatus) {
7
+ status = newStatus;
8
+ }
9
+ // Listen to book and chapter changes.
10
+ onMount(() => {
11
+ book?.addListener(status => handleBookChange(status));
12
+ edition.addListener((status) => handleBookChange(status));
13
+ return () => {
14
+ book?.removeListener(handleBookChange);
15
+ edition.removeListener(handleBookChange);
16
+ };
17
+ });
18
+ </script>
19
+
20
+ <div class={`bookish-editor-status ${status === BookSaveStatus.Saving ? "bookish-editor-status-saving" : status === BookSaveStatus.Error ? "bookish-editor-status-error" : ""}`}>
21
+ {
22
+ status === BookSaveStatus.Changed ? "\u270E Editing" :
23
+ status === BookSaveStatus.Saving ? "\u2026 Saving" :
24
+ status === BookSaveStatus.Saved ? "\u2713 Saved" :
25
+ status === BookSaveStatus.Error ? "\u2715 Couldn't save." :
26
+ ""
27
+ }
28
+ </div>
29
+
30
+ <style>
31
+ .bookish-editor-status {
32
+ position: fixed;
33
+ top: var(--bookish-app-chrome-spacing);
34
+ right: var(--bookish-app-chrome-spacing);
35
+ z-index: 3;
36
+ color: var(--bookish-muted-color);
37
+ font-family: var(--bookish-header-font-family);
38
+ font-size: var(--bookish-small-font-size);
39
+ }
40
+
41
+ .bookish-editor-status-error {
42
+ color: var(--bookish-app-error-color);
43
+ animation: failure 100ms infinite;
44
+ }
45
+
46
+ .bookish-editor-status-saving {
47
+ animation: waiting 100ms infinite;
48
+ }
49
+ </style>
@@ -0,0 +1,19 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import type Book from "../../models/book/Book";
3
+ import type Edition from "../../models/book/Edition";
4
+ declare const __propDef: {
5
+ props: {
6
+ book: Book | undefined;
7
+ edition: Edition;
8
+ };
9
+ events: {
10
+ [evt: string]: CustomEvent<any>;
11
+ };
12
+ slots: {};
13
+ };
14
+ export declare type StatusProps = typeof __propDef.props;
15
+ export declare type StatusEvents = typeof __propDef.events;
16
+ export declare type StatusSlots = typeof __propDef.slots;
17
+ export default class Status extends SvelteComponentTyped<StatusProps, StatusEvents, StatusSlots> {
18
+ }
19
+ export {};
@@ -0,0 +1,30 @@
1
+ <script>import TextEditor from "../editor/TextEditor.svelte";
2
+ import { subdomainIsAvailable } from "../../models/Firestore";
3
+ import { getBook } from "./Contexts";
4
+ let book = getBook();
5
+ const invalidNames = ["email", "login", "confirm", "read", "write"];
6
+ </script>
7
+
8
+ <span class="bookish-muted">
9
+ <TextEditor
10
+ startText={book.getSubdomain() ?? ""}
11
+ label="Book domain editor"
12
+ save={
13
+ // Save the new domain
14
+ async domain => {
15
+ const available = await subdomainIsAvailable(domain, book);
16
+ if(available)
17
+ book.setSubdomain(domain);
18
+ else throw Error("Domain isn't available");
19
+ }
20
+ }
21
+ placeholder="URL name"
22
+ valid={newDomain =>
23
+ // If not the empty string, must be a valid URL subdomain, and none of the existing routes.
24
+ invalidNames.includes(newDomain) || (newDomain.length > 0 && !/^[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?$/.test(newDomain)) ? `Book domains must be fewer than 63 characters, made of symbols a-z, A-Z, and 0-9, and not one of ${invalidNames.join(", ")}.` :
25
+ undefined
26
+ }
27
+ saveOnExit={true}
28
+ />
29
+ <br/>
30
+ </span>
@@ -0,0 +1,14 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {};
4
+ events: {
5
+ [evt: string]: CustomEvent<any>;
6
+ };
7
+ slots: {};
8
+ };
9
+ export declare type SubdomainEditorProps = typeof __propDef.props;
10
+ export declare type SubdomainEditorEvents = typeof __propDef.events;
11
+ export declare type SubdomainEditorSlots = typeof __propDef.slots;
12
+ export default class SubdomainEditor extends SvelteComponentTyped<SubdomainEditorProps, SubdomainEditorEvents, SubdomainEditorSlots> {
13
+ }
14
+ export {};