bookish-press 0.4.47 → 0.4.49
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/components/Auth.svelte +55 -0
- package/components/Auth.svelte.d.ts +16 -0
- package/{src/lib/components/Authentication.ts → components/Authentication.d.ts} +0 -2
- package/components/Authentication.js +1 -0
- package/{src/lib/components → components}/BookPreview.svelte +22 -27
- package/components/BookPreview.svelte.d.ts +18 -0
- package/{src/lib/components → components}/External.svelte +1 -2
- package/components/External.svelte.d.ts +18 -0
- package/components/Link.svelte +51 -0
- package/components/Link.svelte.d.ts +18 -0
- package/{src/lib/components → components}/app/BookList.svelte +3 -6
- package/components/app/BookList.svelte.d.ts +18 -0
- package/{src/lib/components → components}/app/Button.svelte +4 -5
- package/components/app/Button.svelte.d.ts +22 -0
- package/{src/lib/components → components}/app/Feedback.svelte +7 -11
- package/components/app/Feedback.svelte.d.ts +18 -0
- package/{src/lib/components → components}/app/Head.svelte +1 -2
- package/components/app/Head.svelte.d.ts +18 -0
- package/{src/lib/components → components}/app/Large.svelte +0 -0
- package/components/app/Large.svelte.d.ts +27 -0
- package/{src/lib/components → components}/app/Lead.svelte +0 -0
- package/components/app/Lead.svelte.d.ts +27 -0
- package/{src/lib/components → components}/app/Link.svelte +3 -4
- package/components/app/Link.svelte.d.ts +20 -0
- package/{src/lib/components → components}/app/Options.svelte +4 -5
- package/components/app/Options.svelte.d.ts +19 -0
- package/{src/lib/components → components}/app/Paragraph.svelte +1 -2
- package/components/app/Paragraph.svelte.d.ts +18 -0
- package/{src/lib/components → components}/app/Section.svelte +0 -0
- package/components/app/Section.svelte.d.ts +27 -0
- package/{src/lib/components → components}/app/Table.svelte +0 -0
- package/components/app/Table.svelte.d.ts +27 -0
- package/{src/lib/components → components}/app/TextInput.svelte +9 -12
- package/components/app/TextInput.svelte.d.ts +22 -0
- package/{src/lib/components → components}/chapter/Atom.svelte +12 -18
- package/components/chapter/Atom.svelte.d.ts +19 -0
- package/components/chapter/Block.svelte +37 -0
- package/components/chapter/Block.svelte.d.ts +17 -0
- package/{src/lib/components → components}/chapter/Callout.svelte +3 -6
- package/components/chapter/Callout.svelte.d.ts +17 -0
- package/{src/lib/components → components}/chapter/CaptionedCode.svelte +13 -21
- package/components/chapter/CaptionedCode.svelte.d.ts +17 -0
- package/{src/lib/components → components}/chapter/ChapterBody.svelte +9 -13
- package/components/chapter/ChapterBody.svelte.d.ts +19 -0
- package/{src/lib/components → components}/chapter/Citations.svelte +33 -34
- package/components/chapter/Citations.svelte.d.ts +17 -0
- package/{src/lib/components → components}/chapter/Code.svelte +60 -64
- package/components/chapter/Code.svelte.d.ts +22 -0
- package/{src/lib/components → components}/chapter/Comment.svelte +18 -30
- package/components/chapter/Comment.svelte.d.ts +17 -0
- package/{src/lib/components → components}/chapter/Definition.svelte +17 -23
- package/components/chapter/Definition.svelte.d.ts +17 -0
- package/{src/lib/components → components}/chapter/Embed.svelte +77 -97
- package/components/chapter/Embed.svelte.d.ts +20 -0
- package/components/chapter/ErrorMessage.svelte +9 -0
- package/components/chapter/ErrorMessage.svelte.d.ts +17 -0
- package/components/chapter/ExtendedPrism.d.ts +2 -0
- package/{src/lib/components → components}/chapter/ExtendedPrism.js +0 -0
- package/{src/lib/components → components}/chapter/Figure.svelte +26 -34
- package/components/chapter/Figure.svelte.d.ts +24 -0
- package/{src/lib/components → components}/chapter/Footnote.svelte +20 -32
- package/components/chapter/Footnote.svelte.d.ts +19 -0
- package/{src/lib/components → components}/chapter/Format.svelte +34 -39
- package/components/chapter/Format.svelte.d.ts +19 -0
- package/{src/lib/components → components}/chapter/InlineCode.svelte +5 -9
- package/components/chapter/InlineCode.svelte.d.ts +17 -0
- package/{src/lib/components → components}/chapter/Label.svelte +14 -23
- package/components/chapter/Label.svelte.d.ts +17 -0
- package/{src/lib/components → components}/chapter/Link.svelte +21 -27
- package/components/chapter/Link.svelte.d.ts +17 -0
- package/{src/lib/components → components}/chapter/List.svelte +3 -5
- package/components/chapter/List.svelte.d.ts +17 -0
- package/{src/lib/components → components}/chapter/Marginal.svelte +41 -54
- package/components/chapter/Marginal.svelte.d.ts +22 -0
- package/{src/lib/components → components}/chapter/Paragraph.svelte +20 -25
- package/components/chapter/Paragraph.svelte.d.ts +18 -0
- package/{src/lib/components → components}/chapter/Positioned.svelte +1 -4
- package/components/chapter/Positioned.svelte.d.ts +19 -0
- package/{src/lib/components → components}/chapter/Problem.svelte +0 -0
- package/components/chapter/Problem.svelte.d.ts +27 -0
- package/components/chapter/Python.svelte +128 -0
- package/components/chapter/Python.svelte.d.ts +18 -0
- package/{src/lib/components → components}/chapter/Quote.svelte +19 -13
- package/components/chapter/Quote.svelte.d.ts +17 -0
- package/{src/lib/components → components}/chapter/Rule.svelte +1 -4
- package/components/chapter/Rule.svelte.d.ts +17 -0
- package/{src/lib/components → components}/chapter/Table.svelte +7 -11
- package/components/chapter/Table.svelte.d.ts +17 -0
- package/components/chapter/Text.svelte +87 -0
- package/components/chapter/Text.svelte.d.ts +18 -0
- package/components/editor/BookishEditor.svelte +884 -0
- package/components/editor/BookishEditor.svelte.d.ts +25 -0
- package/components/editor/CalloutEditor.svelte +10 -0
- package/components/editor/CalloutEditor.svelte.d.ts +17 -0
- package/{src/lib/components → components}/editor/CaptionedCodeEditor.svelte +6 -10
- package/components/editor/CaptionedCodeEditor.svelte.d.ts +17 -0
- package/components/editor/CaretContext.d.ts +50 -0
- package/components/editor/CaretContext.js +1 -0
- package/{src/lib/components/editor/CaretState.ts → components/editor/CaretState.d.ts} +7 -6
- package/components/editor/CaretState.js +1 -0
- package/{src/lib/components/editor/CaretUtilities.ts → components/editor/CaretUtilities.d.ts} +0 -1
- package/components/editor/CaretUtilities.js +1 -0
- package/{src/lib/components → components}/editor/CaretView.svelte +20 -25
- package/components/editor/CaretView.svelte.d.ts +25 -0
- package/components/editor/CitationsEditor.svelte +53 -0
- package/components/editor/CitationsEditor.svelte.d.ts +17 -0
- package/{src/lib/components/editor/Clipboard.ts → components/editor/Clipboard.d.ts} +1 -2
- package/components/editor/Clipboard.js +1 -0
- package/{src/lib/components/editor/Command.ts → components/editor/Command.d.ts} +2 -8
- package/components/editor/Command.js +1 -0
- package/components/editor/Commands.d.ts +3 -0
- package/{src/lib/components/editor/Commands.ts → components/editor/Commands.js} +315 -730
- package/components/editor/ConfirmButton.svelte +49 -0
- package/components/editor/ConfirmButton.svelte.d.ts +19 -0
- package/components/editor/DefinitionEditor.svelte +36 -0
- package/components/editor/DefinitionEditor.svelte.d.ts +17 -0
- package/components/editor/EmbedEditor.svelte +137 -0
- package/components/editor/EmbedEditor.svelte.d.ts +17 -0
- package/{src/lib/components → components}/editor/Icon.svelte +1 -2
- package/components/editor/Icon.svelte.d.ts +16 -0
- package/{src/lib/components → components}/editor/ImageChooser.svelte +19 -24
- package/components/editor/ImageChooser.svelte.d.ts +18 -0
- package/components/editor/InlineCodeEditor.svelte +12 -0
- package/components/editor/InlineCodeEditor.svelte.d.ts +17 -0
- package/{src/lib/components → components}/editor/LabelEditor.svelte +9 -14
- package/components/editor/LabelEditor.svelte.d.ts +17 -0
- package/{src/lib/components → components}/editor/LanguageEditor.svelte +5 -8
- package/components/editor/LanguageEditor.svelte.d.ts +17 -0
- package/components/editor/LinkEditor.svelte +100 -0
- package/components/editor/LinkEditor.svelte.d.ts +17 -0
- package/{src/lib/components → components}/editor/Note.svelte +0 -0
- package/components/editor/Note.svelte.d.ts +27 -0
- package/{src/lib/components → components}/editor/Permissions.svelte +36 -43
- package/components/editor/Permissions.svelte.d.ts +20 -0
- package/components/editor/PositionEditor.svelte +17 -0
- package/components/editor/PositionEditor.svelte.d.ts +18 -0
- package/components/editor/QuoteEditor.svelte +10 -0
- package/components/editor/QuoteEditor.svelte.d.ts +17 -0
- package/{src/lib/components → components}/editor/Switch.svelte +11 -14
- package/components/editor/Switch.svelte.d.ts +20 -0
- package/components/editor/TableEditor.svelte +10 -0
- package/components/editor/TableEditor.svelte.d.ts +17 -0
- package/{src/lib/components → components}/editor/TextEditor.svelte +89 -101
- package/components/editor/TextEditor.svelte.d.ts +24 -0
- package/components/editor/Toggle.svelte +41 -0
- package/components/editor/Toggle.svelte.d.ts +19 -0
- package/components/editor/Toolbar.svelte +249 -0
- package/components/editor/Toolbar.svelte.d.ts +17 -0
- package/{src/lib/components → components}/editor/ToolbarGroup.svelte +3 -5
- package/components/editor/ToolbarGroup.svelte.d.ts +18 -0
- package/{src/lib/components → components}/editor/ToolbarSpacer.svelte +0 -0
- package/components/editor/ToolbarSpacer.svelte.d.ts +23 -0
- package/components/editor/URLEditor.svelte +13 -0
- package/components/editor/URLEditor.svelte.d.ts +18 -0
- package/{src/lib/components/editor/UndoState.ts → components/editor/UndoState.d.ts} +2 -3
- package/components/editor/UndoState.js +1 -0
- package/{src/lib/components → components}/editor/icons/annotate.svg +0 -0
- package/{src/lib/components → components}/editor/icons/block.svg +0 -0
- package/{src/lib/components → components}/editor/icons/bold.svg +0 -0
- package/{src/lib/components → components}/editor/icons/bullets.svg +0 -0
- package/{src/lib/components → components}/editor/icons/callout.svg +0 -0
- package/{src/lib/components → components}/editor/icons/citation.svg +0 -0
- package/{src/lib/components → components}/editor/icons/clear.svg +0 -0
- package/{src/lib/components → components}/editor/icons/clipboard.svg +0 -0
- package/{src/lib/components → components}/editor/icons/code.svg +0 -0
- package/{src/lib/components → components}/editor/icons/columnafter.svg +0 -0
- package/{src/lib/components → components}/editor/icons/columnbefore.svg +0 -0
- package/{src/lib/components → components}/editor/icons/comment.svg +0 -0
- package/{src/lib/components → components}/editor/icons/copy.svg +0 -0
- package/{src/lib/components → components}/editor/icons/cut.svg +0 -0
- package/{src/lib/components → components}/editor/icons/define.svg +0 -0
- package/{src/lib/components → components}/editor/icons/deletecolumn.svg +0 -0
- package/{src/lib/components → components}/editor/icons/deleterow.svg +0 -0
- package/{src/lib/components → components}/editor/icons/footnote.svg +0 -0
- package/{src/lib/components → components}/editor/icons/header1.svg +0 -0
- package/{src/lib/components → components}/editor/icons/header2.svg +0 -0
- package/{src/lib/components → components}/editor/icons/header3.svg +0 -0
- package/{src/lib/components → components}/editor/icons/home.svg +0 -0
- package/{src/lib/components → components}/editor/icons/indent.svg +0 -0
- package/{src/lib/components → components}/editor/icons/italic.svg +0 -0
- package/{src/lib/components → components}/editor/icons/label.svg +0 -0
- package/{src/lib/components → components}/editor/icons/left.svg +0 -0
- package/{src/lib/components → components}/editor/icons/level.svg +0 -0
- package/{src/lib/components → components}/editor/icons/link.svg +0 -0
- package/{src/lib/components → components}/editor/icons/list.svg +0 -0
- package/{src/lib/components → components}/editor/icons/media.svg +0 -0
- package/{src/lib/components → components}/editor/icons/middle.svg +0 -0
- package/{src/lib/components → components}/editor/icons/numbers.svg +0 -0
- package/{src/lib/components → components}/editor/icons/paragraph.svg +0 -0
- package/{src/lib/components → components}/editor/icons/paste.svg +0 -0
- package/{src/lib/components → components}/editor/icons/quote.svg +0 -0
- package/{src/lib/components → components}/editor/icons/redo.svg +0 -0
- package/{src/lib/components → components}/editor/icons/right.svg +0 -0
- package/{src/lib/components → components}/editor/icons/rowabove.svg +0 -0
- package/{src/lib/components → components}/editor/icons/rowbelow.svg +0 -0
- package/{src/lib/components → components}/editor/icons/rule.svg +0 -0
- package/{src/lib/components → components}/editor/icons/sub.svg +0 -0
- package/{src/lib/components → components}/editor/icons/super.svg +0 -0
- package/{src/lib/components → components}/editor/icons/table.svg +0 -0
- package/{src/lib/components → components}/editor/icons/text.svg +0 -0
- package/{src/lib/components → components}/editor/icons/time.svg +0 -0
- package/{src/lib/components → components}/editor/icons/undo.svg +0 -0
- package/{src/lib/components → components}/editor/icons/unindent.svg +0 -0
- package/{src/lib/components → components}/editor/icons/unlink.svg +0 -0
- package/{src/lib/components → components}/page/Acknowledgements.svelte +10 -19
- package/components/page/Acknowledgements.svelte.d.ts +14 -0
- package/components/page/Authors.svelte +85 -0
- package/components/page/Authors.svelte.d.ts +21 -0
- package/components/page/BookLoader.svelte +59 -0
- package/components/page/BookLoader.svelte.d.ts +16 -0
- package/components/page/BulkReferenceEditor.svelte +63 -0
- package/components/page/BulkReferenceEditor.svelte.d.ts +14 -0
- package/components/page/Chapter.svelte +393 -0
- package/components/page/Chapter.svelte.d.ts +18 -0
- package/components/page/ChapterContext.d.ts +10 -0
- package/components/page/ChapterContext.js +1 -0
- package/{src/lib/components → components}/page/ChapterNumber.svelte +0 -0
- package/components/page/ChapterNumber.svelte.d.ts +27 -0
- package/{src/lib/components → components}/page/ChapterTitle.svelte +2 -4
- package/components/page/ChapterTitle.svelte.d.ts +18 -0
- package/components/page/Contexts.d.ts +47 -0
- package/components/page/Contexts.js +133 -0
- package/{src/lib/components → components}/page/DefinitionView.svelte +38 -53
- package/components/page/DefinitionView.svelte.d.ts +18 -0
- package/{src/lib/components → components}/page/Description.svelte +7 -15
- package/components/page/Description.svelte.d.ts +14 -0
- package/components/page/Edition.svelte +161 -0
- package/components/page/Edition.svelte.d.ts +20 -0
- package/components/page/EditionLoader.svelte +99 -0
- package/components/page/EditionLoader.svelte.d.ts +18 -0
- package/{src/lib/components → components}/page/Editions.svelte +18 -22
- package/components/page/Editions.svelte.d.ts +14 -0
- package/{src/lib/components → components}/page/Glossary.svelte +28 -33
- package/components/page/Glossary.svelte.d.ts +14 -0
- package/{src/lib/components → components}/page/Header.svelte +52 -59
- package/components/page/Header.svelte.d.ts +29 -0
- package/{src/lib/components → components}/page/Index.svelte +47 -50
- package/components/page/Index.svelte.d.ts +14 -0
- package/{src/lib/components → components}/page/Instructions.svelte +1 -2
- package/components/page/Instructions.svelte.d.ts +18 -0
- package/{src/lib/components → components}/page/License.svelte +9 -17
- package/components/page/License.svelte.d.ts +14 -0
- package/{src/lib/components → components}/page/Loading.svelte +0 -0
- package/components/page/Loading.svelte.d.ts +23 -0
- package/{src/lib/components → components}/page/Media.svelte +27 -44
- package/components/page/Media.svelte.d.ts +14 -0
- package/{src/lib/components → components}/page/MediaPreview.svelte +2 -3
- package/components/page/MediaPreview.svelte.d.ts +19 -0
- package/{src/lib/components → components}/page/Muted.svelte +0 -0
- package/components/page/Muted.svelte.d.ts +27 -0
- package/{src/lib/components → components}/page/Outline.svelte +110 -140
- package/components/page/Outline.svelte.d.ts +19 -0
- package/components/page/Page.svelte +84 -0
- package/components/page/Page.svelte.d.ts +19 -0
- package/{src/lib/components → components}/page/PageHeader.svelte +1 -2
- package/components/page/PageHeader.svelte.d.ts +18 -0
- package/{src/lib/components → components}/page/PageParagraph.svelte +0 -0
- package/components/page/PageParagraph.svelte.d.ts +27 -0
- package/components/page/PossibleChapter.svelte +14 -0
- package/components/page/PossibleChapter.svelte.d.ts +14 -0
- package/components/page/PossibleReference.svelte +11 -0
- package/components/page/PossibleReference.svelte.d.ts +18 -0
- package/{src/lib/components → components}/page/Print.svelte +3 -5
- package/components/page/Print.svelte.d.ts +14 -0
- package/{src/lib/components → components}/page/Publish.svelte +52 -59
- package/components/page/Publish.svelte.d.ts +14 -0
- package/{src/lib/components → components}/page/Reference.svelte +30 -39
- package/components/page/Reference.svelte.d.ts +17 -0
- package/{src/lib/components → components}/page/References.svelte +14 -18
- package/components/page/References.svelte.d.ts +14 -0
- package/{src/lib/components → components}/page/Rows.svelte +0 -0
- package/components/page/Rows.svelte.d.ts +27 -0
- package/components/page/Search.svelte +133 -0
- package/components/page/Search.svelte.d.ts +14 -0
- package/{src/lib/components → components}/page/Status.svelte +3 -5
- package/components/page/Status.svelte.d.ts +14 -0
- package/{src/lib/components → components}/page/SubdomainEditor.svelte +13 -16
- package/components/page/SubdomainEditor.svelte.d.ts +14 -0
- package/{src/lib/components → components}/page/TableOfContents.svelte +68 -79
- package/components/page/TableOfContents.svelte.d.ts +14 -0
- package/components/page/TableOfContentsImage.svelte +18 -0
- package/components/page/TableOfContentsImage.svelte.d.ts +16 -0
- package/{src/lib/components → components}/page/TableOfContentsRow.svelte +24 -34
- package/components/page/TableOfContentsRow.svelte.d.ts +24 -0
- package/{src/lib/components → components}/page/ThemeEditor.svelte +33 -44
- package/components/page/ThemeEditor.svelte.d.ts +14 -0
- package/{src/lib/components → components}/page/ThemeEditorPreview.svelte +12 -21
- package/components/page/ThemeEditorPreview.svelte.d.ts +17 -0
- package/components/page/ThemeSetEditor.svelte +19 -0
- package/components/page/ThemeSetEditor.svelte.d.ts +18 -0
- package/{src/lib/components → components}/page/ThemeVariableEditor.svelte +14 -18
- package/components/page/ThemeVariableEditor.svelte.d.ts +18 -0
- package/{src/lib/components → components}/page/Title.svelte +0 -0
- package/components/page/Title.svelte.d.ts +27 -0
- package/{src/lib/components → components}/page/Unknown.svelte +8 -10
- package/components/page/Unknown.svelte.d.ts +16 -0
- package/components/page/margins.d.ts +2 -0
- package/{src/lib/components/page/margins.ts → components/page/margins.js} +46 -79
- package/index.d.ts +15 -0
- package/{src/lib/index.js → index.js} +0 -0
- package/models/CRUD.d.ts +27 -0
- package/models/CRUD.js +262 -0
- package/models/Firebase.d.ts +5 -0
- package/{src/lib/models/Firebase.ts → models/Firebase.js} +16 -26
- package/models/book/Book.d.ts +61 -0
- package/models/book/Book.js +135 -0
- package/models/book/BookMedia.d.ts +23 -0
- package/models/book/BookMedia.js +108 -0
- package/models/book/BookSaveStatus.d.ts +7 -0
- package/models/book/BookSaveStatus.js +8 -0
- package/models/book/Chapter.d.ts +81 -0
- package/models/book/Chapter.js +212 -0
- package/models/book/ChapterID.d.ts +10 -0
- package/{src/lib/models/book/ChapterID.ts → models/book/ChapterID.js} +0 -1
- package/models/book/Definition.d.ts +6 -0
- package/models/book/Definition.js +1 -0
- package/models/book/Edition.d.ts +139 -0
- package/models/book/Edition.js +620 -0
- package/models/book/Reference.d.ts +24 -0
- package/models/book/Reference.js +78 -0
- package/models/book/Schema.d.ts +174 -0
- package/{src/lib/models/book/Schema.ts → models/book/Schema.js} +0 -1
- package/models/book/Theme.d.ts +113 -0
- package/{src/lib/models/book/Theme.ts → models/book/Theme.js} +6 -110
- package/{src/lib/models/book/ThemeColors.ts → models/book/ThemeColors.d.ts} +0 -6
- package/models/book/ThemeColors.js +1 -0
- package/models/book/Words.d.ts +2 -0
- package/{src/lib/models/book/Words.ts → models/book/Words.js} +0 -1
- package/models/chapter/AtomNode.d.ts +18 -0
- package/{src/lib/models/chapter/AtomNode.ts → models/chapter/AtomNode.js} +10 -30
- package/models/chapter/BlockNode.d.ts +20 -0
- package/{src/lib/models/chapter/BlockNode.ts → models/chapter/BlockNode.js} +47 -80
- package/models/chapter/BlocksNode.d.ts +50 -0
- package/{src/lib/models/chapter/BlocksNode.ts → models/chapter/BlocksNode.js} +359 -571
- package/models/chapter/BlocksNode.test.d.ts +1 -0
- package/models/chapter/BlocksNode.test.js +568 -0
- package/{src/lib/models/chapter/Bookkeeping.ts → models/chapter/Bookkeeping.d.ts} +0 -0
- package/models/chapter/Bookkeeping.js +1 -0
- package/models/chapter/CalloutNode.d.ts +17 -0
- package/models/chapter/CalloutNode.js +58 -0
- package/models/chapter/Caret.d.ts +23 -0
- package/{src/lib/models/chapter/Caret.ts → models/chapter/Caret.js} +26 -50
- package/models/chapter/ChapterNode.d.ts +34 -0
- package/models/chapter/ChapterNode.js +117 -0
- package/models/chapter/CitationsNode.d.ts +16 -0
- package/{src/lib/models/chapter/CitationsNode.ts → models/chapter/CitationsNode.js} +10 -17
- package/models/chapter/CodeNode.d.ts +35 -0
- package/{src/lib/models/chapter/CodeNode.ts → models/chapter/CodeNode.js} +62 -125
- package/models/chapter/CommentNode.d.ts +18 -0
- package/models/chapter/CommentNode.js +48 -0
- package/models/chapter/DefinitionNode.d.ts +12 -0
- package/{src/lib/models/chapter/DefinitionNode.ts → models/chapter/DefinitionNode.js} +8 -14
- package/models/chapter/Edit.d.ts +7 -0
- package/models/chapter/Edit.js +1 -0
- package/models/chapter/EmbedNode.d.ts +45 -0
- package/models/chapter/EmbedNode.js +168 -0
- package/models/chapter/ErrorNode.d.ts +17 -0
- package/{src/lib/models/chapter/ErrorNode.ts → models/chapter/ErrorNode.js} +8 -15
- package/models/chapter/FootnoteNode.d.ts +18 -0
- package/models/chapter/FootnoteNode.js +47 -0
- package/models/chapter/FormatNode.d.ts +60 -0
- package/{src/lib/models/chapter/FormatNode.ts → models/chapter/FormatNode.js} +262 -443
- package/models/chapter/FormatNode.test.d.ts +1 -0
- package/models/chapter/FormatNode.test.js +96 -0
- package/models/chapter/InlineCodeNode.d.ts +12 -0
- package/{src/lib/models/chapter/InlineCodeNode.ts → models/chapter/InlineCodeNode.js} +9 -17
- package/models/chapter/LabelNode.d.ts +17 -0
- package/{src/lib/models/chapter/LabelNode.ts → models/chapter/LabelNode.js} +10 -26
- package/models/chapter/LinkNode.d.ts +12 -0
- package/{src/lib/models/chapter/LinkNode.ts → models/chapter/LinkNode.js} +7 -12
- package/models/chapter/ListNode.d.ts +51 -0
- package/{src/lib/models/chapter/ListNode.ts → models/chapter/ListNode.js} +200 -277
- package/models/chapter/ListNode.test.d.ts +1 -0
- package/{src/lib/models/chapter/ListNode.test.ts → models/chapter/ListNode.test.js} +20 -57
- package/models/chapter/MetadataNode.d.ts +17 -0
- package/models/chapter/MetadataNode.js +32 -0
- package/models/chapter/Node.d.ts +38 -0
- package/{src/lib/models/chapter/Node.ts → models/chapter/Node.js} +71 -155
- package/models/chapter/Node.test.d.ts +1 -0
- package/{src/lib/models → models}/chapter/Node.test.js +0 -0
- package/models/chapter/ParagraphNode.d.ts +33 -0
- package/{src/lib/models/chapter/ParagraphNode.ts → models/chapter/ParagraphNode.js} +58 -95
- package/models/chapter/ParagraphNode.test.d.ts +1 -0
- package/models/chapter/ParagraphNode.test.js +30 -0
- package/models/chapter/Parser.d.ts +75 -0
- package/{src/lib/models/chapter/Parser.ts → models/chapter/Parser.js} +184 -369
- package/models/chapter/Parser.test.d.ts +1 -0
- package/{src/lib/models/chapter/Parser.test.ts → models/chapter/Parser.test.js} +0 -7
- package/{src/lib/models/chapter/Position.ts → models/chapter/Position.d.ts} +0 -0
- package/models/chapter/Position.js +1 -0
- package/models/chapter/QuoteNode.d.ts +25 -0
- package/models/chapter/QuoteNode.js +99 -0
- package/{src/lib/models/chapter/RootNode.ts → models/chapter/RootNode.d.ts} +0 -2
- package/models/chapter/RootNode.js +1 -0
- package/models/chapter/RuleNode.d.ts +15 -0
- package/{src/lib/models/chapter/RuleNode.ts → models/chapter/RuleNode.js} +6 -9
- package/models/chapter/TableNode.d.ts +37 -0
- package/{src/lib/models/chapter/TableNode.ts → models/chapter/TableNode.js} +82 -141
- package/models/chapter/TableNode.test.d.ts +1 -0
- package/{src/lib/models/chapter/TableNode.test.ts → models/chapter/TableNode.test.js} +10 -27
- package/models/chapter/TextNode.d.ts +36 -0
- package/{src/lib/models/chapter/TextNode.ts → models/chapter/TextNode.js} +65 -117
- package/models/chapter/TextNode.test.d.ts +1 -0
- package/{src/lib/models/chapter/TextNode.test.ts → models/chapter/TextNode.test.js} +0 -2
- package/package.json +270 -53
- package/util/getSubdomain.d.ts +3 -0
- package/{src/lib/util/getSubdomain.ts → util/getSubdomain.js} +8 -14
- package/util/isMobile.d.ts +2 -0
- package/{src/lib/util/isMobile.ts → util/isMobile.js} +0 -1
- package/util/mineReference.d.ts +4 -0
- package/{src/lib/util/mineReference.ts → util/mineReference.js} +25 -45
- package/util/scrollToEyeLevel.d.ts +2 -0
- package/{src/lib/util/scrollToEyeLevel.ts → util/scrollToEyeLevel.js} +2 -4
- package/.env.example +0 -8
- package/.firebaserc +0 -8
- package/.prettierignore +0 -8
- package/.prettierrc.json +0 -5
- package/_update-notifier-last-checked +0 -0
- package/firebase.json +0 -46
- package/firestore.indexes.json +0 -4
- package/firestore.rules +0 -59
- package/functions/.eslintrc.js +0 -28
- package/functions/package-lock.json +0 -12595
- package/functions/package.json +0 -43
- package/functions/src/index.ts +0 -345
- package/functions/tsconfig.dev.json +0 -3
- package/functions/tsconfig.json +0 -15
- package/scripts/claims.cjs +0 -99
- package/src/app.d.ts +0 -9
- package/src/app.html +0 -24
- package/src/lib/components/Auth.svelte +0 -65
- package/src/lib/components/Link.svelte +0 -58
- package/src/lib/components/chapter/Block.svelte +0 -42
- package/src/lib/components/chapter/ErrorMessage.svelte +0 -12
- package/src/lib/components/chapter/Python.svelte +0 -144
- package/src/lib/components/chapter/Text.svelte +0 -109
- package/src/lib/components/editor/BookishEditor.svelte +0 -1101
- package/src/lib/components/editor/CalloutEditor.svelte +0 -14
- package/src/lib/components/editor/CaretContext.ts +0 -55
- package/src/lib/components/editor/CitationsEditor.svelte +0 -64
- package/src/lib/components/editor/ConfirmButton.svelte +0 -51
- package/src/lib/components/editor/DefinitionEditor.svelte +0 -44
- package/src/lib/components/editor/EmbedEditor.svelte +0 -152
- package/src/lib/components/editor/InlineCodeEditor.svelte +0 -16
- package/src/lib/components/editor/LinkEditor.svelte +0 -110
- package/src/lib/components/editor/PositionEditor.svelte +0 -21
- package/src/lib/components/editor/QuoteEditor.svelte +0 -14
- package/src/lib/components/editor/TableEditor.svelte +0 -14
- package/src/lib/components/editor/Toggle.svelte +0 -47
- package/src/lib/components/editor/Toolbar.svelte +0 -297
- package/src/lib/components/editor/URLEditor.svelte +0 -15
- package/src/lib/components/page/Authors.svelte +0 -92
- package/src/lib/components/page/BookLoader.svelte +0 -77
- package/src/lib/components/page/BulkReferenceEditor.svelte +0 -86
- package/src/lib/components/page/Chapter.svelte +0 -449
- package/src/lib/components/page/ChapterContext.ts +0 -13
- package/src/lib/components/page/Contexts.ts +0 -176
- package/src/lib/components/page/Edition.svelte +0 -189
- package/src/lib/components/page/EditionLoader.svelte +0 -123
- package/src/lib/components/page/Page.svelte +0 -94
- package/src/lib/components/page/PossibleChapter.svelte +0 -16
- package/src/lib/components/page/PossibleReference.svelte +0 -14
- package/src/lib/components/page/Search.svelte +0 -153
- package/src/lib/components/page/TableOfContentsImage.svelte +0 -22
- package/src/lib/components/page/ThemeSetEditor.svelte +0 -21
- package/src/lib/models/CRUD.ts +0 -469
- package/src/lib/models/book/Book.ts +0 -283
- package/src/lib/models/book/BookMedia.ts +0 -182
- package/src/lib/models/book/BookSaveStatus.ts +0 -8
- package/src/lib/models/book/Chapter.ts +0 -462
- package/src/lib/models/book/Definition.ts +0 -2
- package/src/lib/models/book/Edition.ts +0 -1216
- package/src/lib/models/book/Reference.ts +0 -171
- package/src/lib/models/chapter/BlocksNode.test.ts +0 -867
- package/src/lib/models/chapter/CalloutNode.ts +0 -79
- package/src/lib/models/chapter/ChapterNode.ts +0 -169
- package/src/lib/models/chapter/CommentNode.ts +0 -61
- package/src/lib/models/chapter/Edit.ts +0 -6
- package/src/lib/models/chapter/EmbedNode.ts +0 -257
- package/src/lib/models/chapter/FootnoteNode.ts +0 -59
- package/src/lib/models/chapter/FormatNode.test.ts +0 -137
- package/src/lib/models/chapter/MetadataNode.ts +0 -44
- package/src/lib/models/chapter/ParagraphNode.test.ts +0 -54
- package/src/lib/models/chapter/QuoteNode.ts +0 -135
- package/src/params/edition.ts +0 -3
- package/src/routes/+error.svelte +0 -12
- package/src/routes/+layout.svelte +0 -241
- package/src/routes/+page.svelte +0 -43
- package/src/routes/Footer.svelte +0 -0
- package/src/routes/Header.svelte +0 -112
- package/src/routes/[bookid]/+layout.svelte +0 -5
- package/src/routes/[bookid]/[[editionid=edition]]/+error.svelte +0 -14
- package/src/routes/[bookid]/[[editionid=edition]]/+layout.svelte +0 -7
- package/src/routes/[bookid]/[[editionid=edition]]/+page.svelte +0 -5
- package/src/routes/[bookid]/[[editionid=edition]]/[chapterid]/+page.svelte +0 -5
- package/src/routes/[bookid]/[[editionid=edition]]/glossary/+page.svelte +0 -5
- package/src/routes/[bookid]/[[editionid=edition]]/index/[[letter]]/+page.svelte +0 -5
- package/src/routes/[bookid]/[[editionid=edition]]/media/+page.svelte +0 -5
- package/src/routes/[bookid]/[[editionid=edition]]/print/+page.svelte +0 -5
- package/src/routes/[bookid]/[[editionid=edition]]/references/+page.svelte +0 -5
- package/src/routes/[bookid]/[[editionid=edition]]/search/+page.svelte +0 -5
- package/src/routes/[bookid]/editions/+page.svelte +0 -20
- package/src/routes/about/+page.svelte +0 -102
- package/src/routes/confirm/+page.svelte +0 -62
- package/src/routes/email/+page.svelte +0 -99
- package/src/routes/login/+page.svelte +0 -66
- package/src/routes/read/+page.svelte +0 -38
- package/src/routes/write/+error.svelte +0 -10
- package/src/routes/write/+layout.svelte +0 -11
- package/src/routes/write/+page.svelte +0 -114
- package/src/routes/write/[bookid]/+layout.svelte +0 -5
- package/src/routes/write/[bookid]/[[editionid=edition]]/+layout.svelte +0 -7
- package/src/routes/write/[bookid]/[[editionid=edition]]/+page.svelte +0 -5
- package/src/routes/write/[bookid]/[[editionid=edition]]/[chapterid]/+page.svelte +0 -5
- package/src/routes/write/[bookid]/[[editionid=edition]]/glossary/+page.svelte +0 -5
- package/src/routes/write/[bookid]/[[editionid=edition]]/index/[[letter]]/+page.svelte +0 -5
- package/src/routes/write/[bookid]/[[editionid=edition]]/media/+page.svelte +0 -5
- package/src/routes/write/[bookid]/[[editionid=edition]]/print/+page.svelte +0 -5
- package/src/routes/write/[bookid]/[[editionid=edition]]/references/+page.svelte +0 -5
- package/src/routes/write/[bookid]/[[editionid=edition]]/search/+page.svelte +0 -5
- package/src/routes/write/[bookid]/[[editionid=edition]]/theme/+page.svelte +0 -5
- package/src/routes/write/[bookid]/[[editionid=edition]]/unknown/+page.svelte +0 -5
- package/src/routes/write/[bookid]/editions/+page.svelte +0 -20
- package/src/vite-env.d.ts +0 -1
- package/static/icons/favicon.png +0 -0
- package/static/icons/icon.png +0 -0
- package/static/icons/ios-icon.png +0 -0
- package/storage.rules +0 -9
- package/svelte.config.js +0 -19
- package/tsconfig.json +0 -18
- package/tsconfig.node.json +0 -9
- package/vite.config.ts +0 -8
- package/vite.reader.config.ts +0 -32
|
@@ -1,48 +1,24 @@
|
|
|
1
1
|
import Node from './Node';
|
|
2
|
-
import type ErrorNode from './ErrorNode';
|
|
3
2
|
import TextNode from './TextNode';
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
caretRangeToIndexRange,
|
|
7
|
-
caretToIndex,
|
|
8
|
-
indexToCaret,
|
|
9
|
-
type CaretRange,
|
|
10
|
-
} from './Caret';
|
|
3
|
+
import { caretRangeToIndexRange, caretToIndex, indexToCaret, } from './Caret';
|
|
11
4
|
import MetadataNode from './MetadataNode';
|
|
12
5
|
import AtomNode from './AtomNode';
|
|
13
|
-
import type Edit from './Edit';
|
|
14
|
-
|
|
15
|
-
export type Format = '' | '*' | '_' | '^' | 'v';
|
|
16
|
-
export type FormatNodeSegmentType =
|
|
17
|
-
| FormatNode
|
|
18
|
-
| TextNode
|
|
19
|
-
| ErrorNode
|
|
20
|
-
| MetadataNode<any>
|
|
21
|
-
| AtomNode<any>;
|
|
22
|
-
|
|
23
6
|
export default class FormatNode extends Node {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
constructor(format: Format, segments: FormatNodeSegmentType[]) {
|
|
7
|
+
#format;
|
|
8
|
+
#segments;
|
|
9
|
+
constructor(format, segments) {
|
|
28
10
|
super();
|
|
29
|
-
|
|
30
11
|
this.#format = format;
|
|
31
12
|
// Remove consecutive empty text nodes.
|
|
32
13
|
this.#segments = segments.filter((item, position, list) => {
|
|
33
|
-
if (
|
|
34
|
-
position === 0 ||
|
|
14
|
+
if (position === 0 ||
|
|
35
15
|
!(item instanceof TextNode) ||
|
|
36
|
-
item.getLength() > 0
|
|
37
|
-
)
|
|
16
|
+
item.getLength() > 0)
|
|
38
17
|
return true;
|
|
39
18
|
const previous = list[position - 1];
|
|
40
|
-
return !(
|
|
41
|
-
previous instanceof TextNode && previous.getLength() === 0
|
|
42
|
-
);
|
|
19
|
+
return !(previous instanceof TextNode && previous.getLength() === 0);
|
|
43
20
|
});
|
|
44
21
|
}
|
|
45
|
-
|
|
46
22
|
getType() {
|
|
47
23
|
return 'formatted';
|
|
48
24
|
}
|
|
@@ -56,130 +32,100 @@ export default class FormatNode extends Node {
|
|
|
56
32
|
return this.#segments.length === 0;
|
|
57
33
|
}
|
|
58
34
|
isEmptyText() {
|
|
59
|
-
return (
|
|
60
|
-
this.#segments.length === 1 &&
|
|
35
|
+
return (this.#segments.length === 1 &&
|
|
61
36
|
this.#segments[0] instanceof TextNode &&
|
|
62
|
-
this.#segments[0].getText() === ''
|
|
63
|
-
);
|
|
37
|
+
this.#segments[0].getText() === '');
|
|
64
38
|
}
|
|
65
39
|
getLength() {
|
|
66
40
|
return this.#segments.length;
|
|
67
41
|
}
|
|
68
|
-
getParentOf(node
|
|
42
|
+
getParentOf(node) {
|
|
69
43
|
return this.#segments
|
|
70
44
|
.map((b) => (b === node ? this : b.getParentOf(node)))
|
|
71
45
|
.find((b) => b !== undefined);
|
|
72
46
|
}
|
|
73
|
-
|
|
74
|
-
toText(): string {
|
|
47
|
+
toText() {
|
|
75
48
|
return this.#segments.map((segment) => segment.toText()).join(' ');
|
|
76
49
|
}
|
|
77
|
-
toHTML()
|
|
50
|
+
toHTML() {
|
|
78
51
|
const format = this.#format;
|
|
79
52
|
const segments = this.#segments.map((s) => s.toHTML()).join('');
|
|
80
|
-
if (format === '*')
|
|
81
|
-
|
|
82
|
-
else if (format === '
|
|
83
|
-
|
|
84
|
-
else
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
53
|
+
if (format === '*')
|
|
54
|
+
return `<strong>${segments}</strong>`;
|
|
55
|
+
else if (format === '_')
|
|
56
|
+
return `<em>${segments}</em>`;
|
|
57
|
+
else if (format === '^')
|
|
58
|
+
return `<sup>${segments}</sup>`;
|
|
59
|
+
else if (format === 'v')
|
|
60
|
+
return `<sub>${segments}</sub>`;
|
|
61
|
+
else
|
|
62
|
+
return segments;
|
|
63
|
+
}
|
|
64
|
+
toBookdown() {
|
|
65
|
+
return ((this.#format === 'v' ? '^v' : this.#format) +
|
|
90
66
|
this.#segments
|
|
91
|
-
.map((s) =>
|
|
92
|
-
s instanceof AtomNode ? s.toBookdown(this) : s.toBookdown()
|
|
93
|
-
)
|
|
67
|
+
.map((s) => s instanceof AtomNode ? s.toBookdown(this) : s.toBookdown())
|
|
94
68
|
.join('') +
|
|
95
|
-
(this.#format === 'v' ? '^' : this.#format)
|
|
96
|
-
);
|
|
69
|
+
(this.#format === 'v' ? '^' : this.#format));
|
|
97
70
|
}
|
|
98
|
-
|
|
99
71
|
getChildren() {
|
|
100
72
|
return this.#segments;
|
|
101
73
|
}
|
|
102
|
-
|
|
103
|
-
getFirstTextNode(): TextNode {
|
|
74
|
+
getFirstTextNode() {
|
|
104
75
|
const text = this.getTextNodes();
|
|
105
76
|
return text[0];
|
|
106
77
|
}
|
|
107
|
-
|
|
108
|
-
getLastTextNode(): TextNode {
|
|
78
|
+
getLastTextNode() {
|
|
109
79
|
const text = this.getTextNodes();
|
|
110
80
|
return text[text.length - 1];
|
|
111
81
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
return new FormatNode(
|
|
115
|
-
this.#format,
|
|
116
|
-
this.#segments.map((s) => s.copy())
|
|
117
|
-
) as this;
|
|
82
|
+
copy() {
|
|
83
|
+
return new FormatNode(this.#format, this.#segments.map((s) => s.copy()));
|
|
118
84
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return this.getNodes().filter(
|
|
122
|
-
(n) => n instanceof TextNode
|
|
123
|
-
) as TextNode[];
|
|
85
|
+
getTextNodes() {
|
|
86
|
+
return this.getNodes().filter((n) => n instanceof TextNode);
|
|
124
87
|
}
|
|
125
|
-
|
|
126
88
|
// Get all text or atom nodes in this format, except for any inside an atom node,
|
|
127
89
|
// as this is used for navigation and editing, and they should be isolated from that.
|
|
128
|
-
getTextAndAtomNodes()
|
|
129
|
-
return this.getNodes().filter(
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
getAdjacentTextOrAtom(
|
|
135
|
-
node: TextNode | AtomNode<any>,
|
|
136
|
-
next: boolean
|
|
137
|
-
): TextNode | AtomNode<any> | undefined {
|
|
90
|
+
getTextAndAtomNodes() {
|
|
91
|
+
return this.getNodes().filter((n) => n instanceof TextNode || n instanceof AtomNode);
|
|
92
|
+
}
|
|
93
|
+
getAdjacentTextOrAtom(node, next) {
|
|
138
94
|
// Find all of the text and atom nodes not in atom nodes in this node.
|
|
139
95
|
const text = this.getTextAndAtomNodes().filter((n) => {
|
|
140
96
|
const atomAncestor = n.getClosestParentOfType(this, AtomNode);
|
|
141
|
-
return (
|
|
142
|
-
atomAncestor === undefined ||
|
|
97
|
+
return (atomAncestor === undefined ||
|
|
143
98
|
(atomAncestor instanceof AtomNode &&
|
|
144
|
-
atomAncestor.getMeta() === this)
|
|
145
|
-
);
|
|
99
|
+
atomAncestor.getMeta() === this));
|
|
146
100
|
});
|
|
147
101
|
const index = text.indexOf(node);
|
|
148
102
|
return index === undefined
|
|
149
103
|
? undefined
|
|
150
104
|
: next
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
getNextTextOrAtom(
|
|
160
|
-
node: TextNode | AtomNode<any>
|
|
161
|
-
): TextNode | AtomNode<any> | undefined {
|
|
105
|
+
? index >= 0 && index < text.length - 1
|
|
106
|
+
? text[index + 1]
|
|
107
|
+
: undefined
|
|
108
|
+
: index > 0 && index <= text.length
|
|
109
|
+
? text[index - 1]
|
|
110
|
+
: undefined;
|
|
111
|
+
}
|
|
112
|
+
getNextTextOrAtom(node) {
|
|
162
113
|
return this.getAdjacentTextOrAtom(node, true);
|
|
163
114
|
}
|
|
164
|
-
|
|
165
|
-
getPreviousTextOrAtom(
|
|
166
|
-
node: TextNode | AtomNode<any>
|
|
167
|
-
): TextNode | AtomNode<any> | undefined {
|
|
115
|
+
getPreviousTextOrAtom(node) {
|
|
168
116
|
return this.getAdjacentTextOrAtom(node, false);
|
|
169
117
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
!(caret.node instanceof TextNode) &&
|
|
174
|
-
!(caret.node instanceof AtomNode)
|
|
175
|
-
)
|
|
118
|
+
getAdjacentCaret(caret, next) {
|
|
119
|
+
if (!(caret.node instanceof TextNode) &&
|
|
120
|
+
!(caret.node instanceof AtomNode))
|
|
176
121
|
return;
|
|
177
122
|
// Is there an adjascent caret in the current text node? If so, return it.
|
|
178
123
|
if (caret.node instanceof TextNode) {
|
|
179
124
|
const adjacentText = next
|
|
180
125
|
? caret.node.getNextCaret(caret.index)
|
|
181
126
|
: caret.node.getPreviousCaret(caret.index);
|
|
182
|
-
if (adjacentText !== undefined)
|
|
127
|
+
if (adjacentText !== undefined)
|
|
128
|
+
return adjacentText;
|
|
183
129
|
}
|
|
184
130
|
// If there's not, is there an adjacent caret in the sequence of text and atom nodes?
|
|
185
131
|
const adjacentNode = this.getAdjacentTextOrAtom(caret.node, next);
|
|
@@ -195,30 +141,29 @@ export default class FormatNode extends Node {
|
|
|
195
141
|
: 1
|
|
196
142
|
: 0
|
|
197
143
|
: adjacentNode instanceof TextNode
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
144
|
+
? adjacentNode.isEmpty()
|
|
145
|
+
? 0
|
|
146
|
+
: adjacentNode.getLength() - 1
|
|
147
|
+
: 0,
|
|
202
148
|
};
|
|
203
149
|
}
|
|
204
150
|
// Otherwise, there is no adjascent caret.
|
|
205
151
|
return undefined;
|
|
206
152
|
}
|
|
207
|
-
|
|
208
|
-
getFirstCaret(): Caret | undefined {
|
|
153
|
+
getFirstCaret() {
|
|
209
154
|
const text = this.getTextNodes();
|
|
210
|
-
if (text.length === 0)
|
|
155
|
+
if (text.length === 0)
|
|
156
|
+
return undefined;
|
|
211
157
|
return { node: this.getTextNodes()[0], index: 0 };
|
|
212
158
|
}
|
|
213
|
-
|
|
214
|
-
getLastCaret(): Caret | undefined {
|
|
159
|
+
getLastCaret() {
|
|
215
160
|
const text = this.getTextNodes();
|
|
216
|
-
if (text.length === 0)
|
|
161
|
+
if (text.length === 0)
|
|
162
|
+
return undefined;
|
|
217
163
|
const last = text[text.length - 1];
|
|
218
164
|
return { node: last, index: last.getLength() };
|
|
219
165
|
}
|
|
220
|
-
|
|
221
|
-
getSelection(): CaretRange {
|
|
166
|
+
getSelection() {
|
|
222
167
|
const first = this.getFirstTextNode();
|
|
223
168
|
const last = this.getLastTextNode();
|
|
224
169
|
return {
|
|
@@ -226,159 +171,117 @@ export default class FormatNode extends Node {
|
|
|
226
171
|
end: { node: last, index: last.getLength() },
|
|
227
172
|
};
|
|
228
173
|
}
|
|
229
|
-
|
|
230
|
-
getIndexOfTextNode(node: TextNode): number | undefined {
|
|
174
|
+
getIndexOfTextNode(node) {
|
|
231
175
|
const text = this.getTextNodes();
|
|
232
176
|
return text.indexOf(node);
|
|
233
177
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
!(range.start.node instanceof TextNode) ||
|
|
238
|
-
!(range.end.node instanceof TextNode)
|
|
239
|
-
)
|
|
178
|
+
getSelectedText(range) {
|
|
179
|
+
if (!(range.start.node instanceof TextNode) ||
|
|
180
|
+
!(range.end.node instanceof TextNode))
|
|
240
181
|
return undefined;
|
|
241
|
-
|
|
242
182
|
const start = this.getIndexOfTextNode(range.start.node);
|
|
243
183
|
const end = this.getIndexOfTextNode(range.end.node);
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
184
|
+
if (start === undefined || end === undefined)
|
|
185
|
+
return undefined;
|
|
247
186
|
return this.getTextNodes()
|
|
248
187
|
.map((current, index) => {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
188
|
+
return current === range.start.node
|
|
189
|
+
? current === range.end.node
|
|
190
|
+
? current
|
|
191
|
+
.getText()
|
|
192
|
+
.substring(range.start.index, range.end.index)
|
|
193
|
+
: current.getText().substring(range.start.index)
|
|
194
|
+
: index > start && index < end
|
|
256
195
|
? current.getText()
|
|
257
196
|
: current === range.end.node
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
197
|
+
? current.getText().substring(0, range.end.index)
|
|
198
|
+
: '';
|
|
199
|
+
})
|
|
261
200
|
.join('');
|
|
262
201
|
}
|
|
263
|
-
|
|
264
202
|
withTextIfEmpty() {
|
|
265
203
|
return this.isEmpty() ? this.withSegmentAppended(new TextNode()) : this;
|
|
266
204
|
}
|
|
267
|
-
|
|
268
|
-
withSegmentPrepended(segment: FormatNodeSegmentType): FormatNode {
|
|
205
|
+
withSegmentPrepended(segment) {
|
|
269
206
|
return new FormatNode(this.#format, [segment, ...this.#segments]);
|
|
270
207
|
}
|
|
271
|
-
|
|
272
|
-
withSegmentAppended(segment: FormatNodeSegmentType): FormatNode {
|
|
208
|
+
withSegmentAppended(segment) {
|
|
273
209
|
return new FormatNode(this.#format, [...this.#segments, segment]);
|
|
274
210
|
}
|
|
275
|
-
|
|
276
|
-
withSegmentReplaced(
|
|
277
|
-
segment: FormatNodeSegmentType,
|
|
278
|
-
replacement: FormatNodeSegmentType
|
|
279
|
-
): this | undefined {
|
|
211
|
+
withSegmentReplaced(segment, replacement) {
|
|
280
212
|
const index = this.#segments.indexOf(segment);
|
|
281
|
-
if (index < 0)
|
|
282
|
-
|
|
213
|
+
if (index < 0)
|
|
214
|
+
return undefined;
|
|
283
215
|
const segments = this.#segments.slice();
|
|
284
216
|
segments[index] = replacement;
|
|
285
|
-
|
|
286
|
-
return new FormatNode(this.#format, segments) as this;
|
|
217
|
+
return new FormatNode(this.#format, segments);
|
|
287
218
|
}
|
|
288
|
-
|
|
289
|
-
withoutSegment(segment: FormatNodeSegmentType): this | undefined {
|
|
219
|
+
withoutSegment(segment) {
|
|
290
220
|
const index = this.#segments.indexOf(segment);
|
|
291
|
-
if (index < 0)
|
|
221
|
+
if (index < 0)
|
|
222
|
+
return undefined;
|
|
292
223
|
const newSegments = this.#segments.slice();
|
|
293
224
|
newSegments.splice(index, 1);
|
|
294
|
-
return new FormatNode(this.#format, newSegments)
|
|
225
|
+
return new FormatNode(this.#format, newSegments);
|
|
295
226
|
}
|
|
296
|
-
|
|
297
|
-
withChildReplaced(
|
|
298
|
-
node: FormatNodeSegmentType,
|
|
299
|
-
replacement: FormatNodeSegmentType | undefined
|
|
300
|
-
) {
|
|
227
|
+
withChildReplaced(node, replacement) {
|
|
301
228
|
return replacement === undefined
|
|
302
|
-
?
|
|
303
|
-
:
|
|
229
|
+
? this.withoutSegment(node)
|
|
230
|
+
: this.withSegmentReplaced(node, replacement);
|
|
304
231
|
}
|
|
305
|
-
|
|
306
232
|
// Creates two formatted nodes that split this node at the given caret location.
|
|
307
|
-
split(caret
|
|
233
|
+
split(caret) {
|
|
308
234
|
// We can only copy if
|
|
309
235
|
// ... this has a parent.
|
|
310
236
|
// ... the given caret is in this formatted node.
|
|
311
237
|
// ... the caret is on a text node.
|
|
312
238
|
if (!(caret.node instanceof TextNode) || !this.contains(caret.node))
|
|
313
239
|
return undefined;
|
|
314
|
-
|
|
315
240
|
const firstCaret = this.getFirstCaret();
|
|
316
241
|
const lastCaret = this.getLastCaret();
|
|
317
242
|
if (firstCaret === undefined || lastCaret === undefined)
|
|
318
243
|
return undefined;
|
|
319
|
-
|
|
320
244
|
// Delete everything after in the first, everything before in the second.
|
|
321
245
|
const first = this.withoutRange({ start: caret, end: lastCaret });
|
|
322
246
|
const second = this.withoutRange({ start: firstCaret, end: caret });
|
|
323
|
-
|
|
324
|
-
|
|
247
|
+
if (first !== undefined && second !== undefined)
|
|
248
|
+
return [first, second];
|
|
325
249
|
}
|
|
326
|
-
|
|
327
|
-
withoutRange(range: CaretRange): FormatNode | undefined {
|
|
250
|
+
withoutRange(range) {
|
|
328
251
|
return this.withFormat(range, undefined);
|
|
329
252
|
}
|
|
330
|
-
|
|
331
253
|
// This function takes the given range, and if it's within the bounds of this FormatNode,
|
|
332
254
|
// produces a new FormatNode that either formats the given range with the given format or deletes the range if the format is undefined.
|
|
333
255
|
// It's approach is to scan through every text, meta, and atom node build a new format based on the requested format.
|
|
334
|
-
withFormat(
|
|
335
|
-
range: CaretRange,
|
|
336
|
-
format: Format | undefined
|
|
337
|
-
): FormatNode | undefined {
|
|
256
|
+
withFormat(range, format) {
|
|
338
257
|
// This only transforms ranges that start and end with text/atom nodes in this format node.
|
|
339
|
-
if (
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
range.
|
|
343
|
-
)
|
|
344
|
-
!(
|
|
345
|
-
range.end.node instanceof TextNode ||
|
|
346
|
-
range.end.node instanceof AtomNode
|
|
347
|
-
) ||
|
|
348
|
-
!(this.contains(range.start.node) && this.contains(range.end.node))
|
|
349
|
-
)
|
|
258
|
+
if (!(range.start.node instanceof TextNode ||
|
|
259
|
+
range.start.node instanceof AtomNode) ||
|
|
260
|
+
!(range.end.node instanceof TextNode ||
|
|
261
|
+
range.end.node instanceof AtomNode) ||
|
|
262
|
+
!(this.contains(range.start.node) && this.contains(range.end.node)))
|
|
350
263
|
return;
|
|
351
|
-
|
|
352
264
|
const sortedRange = this.sortRange(range);
|
|
353
|
-
|
|
354
265
|
// Remember the text positions so we can return a new range in the new tree.
|
|
355
266
|
const selectionStartIndex = caretToIndex(this, sortedRange.start);
|
|
356
267
|
const selectionEndIndex = caretToIndex(this, sortedRange.end);
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
selectionStartIndex === undefined ||
|
|
360
|
-
selectionEndIndex === undefined
|
|
361
|
-
)
|
|
268
|
+
if (selectionStartIndex === undefined ||
|
|
269
|
+
selectionEndIndex === undefined)
|
|
362
270
|
return;
|
|
363
|
-
|
|
364
271
|
// Remember if the selection is zero width.
|
|
365
272
|
let zeroWidthSelection = selectionStartIndex === selectionEndIndex;
|
|
366
|
-
|
|
367
273
|
// Find all of the content in the node, except for format nodes and decendants of atom nodes that have format nodes,
|
|
368
274
|
// to construct a new format tree with the old content.
|
|
369
|
-
const everythingButFormats = this.getNodes().filter(
|
|
370
|
-
(n) => !(n instanceof FormatNode)
|
|
371
|
-
);
|
|
372
|
-
|
|
275
|
+
const everythingButFormats = this.getNodes().filter((n) => !(n instanceof FormatNode));
|
|
373
276
|
// Check if all of the selected content has the requested format so we can toggle it if so.
|
|
374
277
|
let checkIndex = 0; // This tracks the current location in our scan.
|
|
375
278
|
let editingEmptyNode = false; // This remembers the special case of the caret being inside an empty text node.
|
|
376
279
|
let alreadyApplied = false; // We assume it's not applied until proven otherwise.
|
|
377
280
|
let nodeCount = 0;
|
|
378
281
|
let nodesWithFormat = 0;
|
|
379
|
-
|
|
380
282
|
// It's already applied if we're deleting (in which case this doesn't apply).
|
|
381
|
-
if (format === undefined)
|
|
283
|
+
if (format === undefined)
|
|
284
|
+
alreadyApplied = true;
|
|
382
285
|
// Otherwise, formatting is already applied if all of the non-format nodes already have this format.
|
|
383
286
|
// We need to know this so we can toggle the format off.
|
|
384
287
|
else {
|
|
@@ -391,10 +294,8 @@ export default class FormatNode extends Node {
|
|
|
391
294
|
}
|
|
392
295
|
// If this node is empty but contains a zero-width selection, remember it, since this is the only node for which formats are relevant.
|
|
393
296
|
else if (node.getText().length === 0) {
|
|
394
|
-
if (
|
|
395
|
-
|
|
396
|
-
zeroWidthSelection
|
|
397
|
-
) {
|
|
297
|
+
if (checkIndex === selectionStartIndex &&
|
|
298
|
+
zeroWidthSelection) {
|
|
398
299
|
editingEmptyNode = true;
|
|
399
300
|
alreadyApplied = parent
|
|
400
301
|
.getFormats(this)
|
|
@@ -407,46 +308,41 @@ export default class FormatNode extends Node {
|
|
|
407
308
|
const parentIsFormatted = parent
|
|
408
309
|
.getFormats(this)
|
|
409
310
|
.includes(format);
|
|
410
|
-
const selectionContainsNode =
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
1) ||
|
|
311
|
+
const selectionContainsNode = (selectionStartIndex > checkIndex &&
|
|
312
|
+
selectionStartIndex <
|
|
313
|
+
checkIndex +
|
|
314
|
+
node.getCaretPositionCount() -
|
|
315
|
+
1) ||
|
|
416
316
|
(selectionEndIndex > checkIndex &&
|
|
417
317
|
selectionEndIndex <
|
|
418
318
|
checkIndex +
|
|
419
319
|
node.getCaretPositionCount() -
|
|
420
320
|
1);
|
|
421
|
-
const nodeContainsSelection =
|
|
422
|
-
selectionStartIndex >= checkIndex &&
|
|
321
|
+
const nodeContainsSelection = selectionStartIndex >= checkIndex &&
|
|
423
322
|
selectionEndIndex <=
|
|
424
323
|
checkIndex + node.getCaretPositionCount();
|
|
425
324
|
checkIndex += node.getCaretPositionCount();
|
|
426
325
|
if (nodeContainsSelection || selectionContainsNode) {
|
|
427
326
|
nodeCount++;
|
|
428
|
-
if (parentIsFormatted)
|
|
327
|
+
if (parentIsFormatted)
|
|
328
|
+
nodesWithFormat++;
|
|
429
329
|
}
|
|
430
330
|
}
|
|
431
331
|
}
|
|
432
332
|
// Treat all non-text as containing the requested format.
|
|
433
|
-
else
|
|
333
|
+
else
|
|
334
|
+
return true;
|
|
434
335
|
});
|
|
435
336
|
if (nodeCount > 0 && nodesWithFormat === nodeCount)
|
|
436
337
|
alreadyApplied = true;
|
|
437
338
|
}
|
|
438
|
-
|
|
439
339
|
// Reformat everything. The strategy is to step through each character, atom node, and metadata node in this format node
|
|
440
340
|
// and create a new series of formats that preserve existing formatting while applying new formatting to the selection.
|
|
441
|
-
let newFormats:
|
|
442
|
-
format: Format;
|
|
443
|
-
segments: FormatNodeSegmentType[];
|
|
444
|
-
}[] = [{ format: '', segments: [] }]; // A stack of formats we're constructing.
|
|
341
|
+
let newFormats = [{ format: '', segments: [] }]; // A stack of formats we're constructing.
|
|
445
342
|
let textIndex = 0;
|
|
446
343
|
let currentText = ''; // The current text we've accumulated, inserted before each format change and at the end.
|
|
447
344
|
let formattingEmptyNode = false;
|
|
448
345
|
let emptyNode = undefined;
|
|
449
|
-
|
|
450
346
|
function saveText() {
|
|
451
347
|
// If there's some text, update the current format with the current text, then reset it.
|
|
452
348
|
if (currentText.length > 0) {
|
|
@@ -454,60 +350,45 @@ export default class FormatNode extends Node {
|
|
|
454
350
|
currentText = '';
|
|
455
351
|
}
|
|
456
352
|
}
|
|
457
|
-
|
|
458
353
|
function inRange() {
|
|
459
|
-
return (
|
|
460
|
-
selectionStartIndex !== undefined &&
|
|
354
|
+
return (selectionStartIndex !== undefined &&
|
|
461
355
|
selectionEndIndex !== undefined &&
|
|
462
356
|
textIndex >= selectionStartIndex &&
|
|
463
|
-
textIndex < selectionEndIndex
|
|
464
|
-
);
|
|
357
|
+
textIndex < selectionEndIndex);
|
|
465
358
|
}
|
|
466
|
-
|
|
467
359
|
function getFormats() {
|
|
468
360
|
// We don't include non-formatted text in the list of formats applied.
|
|
469
361
|
return newFormats.map((f) => f.format).filter((f) => f !== '');
|
|
470
362
|
}
|
|
471
|
-
|
|
472
363
|
function finishFormat() {
|
|
473
364
|
const formatSpec = newFormats[0];
|
|
474
365
|
newFormats.shift();
|
|
475
366
|
// Keep the new format clean by only adding the format node if it's not empty, or if it's a zero width selection.
|
|
476
|
-
if (
|
|
477
|
-
|
|
478
|
-
(
|
|
479
|
-
)
|
|
480
|
-
newFormats[0].segments.push(
|
|
481
|
-
new FormatNode(formatSpec.format, formatSpec.segments)
|
|
482
|
-
);
|
|
367
|
+
if (formatSpec.segments.length > 0 ||
|
|
368
|
+
(zeroWidthSelection && textIndex === selectionStartIndex))
|
|
369
|
+
newFormats[0].segments.push(new FormatNode(formatSpec.format, formatSpec.segments));
|
|
483
370
|
}
|
|
484
|
-
|
|
485
371
|
everythingButFormats.forEach((node) => {
|
|
486
372
|
const parent = this.getParentOf(node);
|
|
487
373
|
if (node instanceof TextNode) {
|
|
488
374
|
// If this is a text node in an atom node we're not formatting the atom node's format, then just
|
|
489
375
|
// account for it's length, but do nothing else.
|
|
490
|
-
const atomAncestor = node.getClosestParentOfType(
|
|
491
|
-
|
|
492
|
-
AtomNode
|
|
493
|
-
);
|
|
494
|
-
if (
|
|
495
|
-
atomAncestor instanceof AtomNode &&
|
|
376
|
+
const atomAncestor = node.getClosestParentOfType(this, AtomNode);
|
|
377
|
+
if (atomAncestor instanceof AtomNode &&
|
|
496
378
|
atomAncestor.getMeta() !== this &&
|
|
497
|
-
atomAncestor.getMeta() instanceof FormatNode
|
|
498
|
-
) {
|
|
379
|
+
atomAncestor.getMeta() instanceof FormatNode) {
|
|
499
380
|
textIndex += node.getCaretPositionCount();
|
|
500
|
-
}
|
|
381
|
+
}
|
|
382
|
+
else if (parent instanceof FormatNode) {
|
|
501
383
|
// Remember we found an empty node so that we don't insert an extra one later.
|
|
502
384
|
if (node.getText().length === 0) {
|
|
503
|
-
if (
|
|
504
|
-
|
|
505
|
-
zeroWidthSelection
|
|
506
|
-
) {
|
|
385
|
+
if (textIndex === selectionStartIndex &&
|
|
386
|
+
zeroWidthSelection) {
|
|
507
387
|
formattingEmptyNode = true;
|
|
508
388
|
textIndex++;
|
|
509
389
|
}
|
|
510
|
-
}
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
511
392
|
// Process each character in the node, including the very last position.
|
|
512
393
|
for (let i = 0; i <= node.getText().length; i++) {
|
|
513
394
|
// Determine the desired format for this character. Start with the current formats
|
|
@@ -517,31 +398,22 @@ export default class FormatNode extends Node {
|
|
|
517
398
|
let desiredFormats = formatter
|
|
518
399
|
? formatter.getFormats(this)
|
|
519
400
|
: [];
|
|
520
|
-
if (
|
|
521
|
-
format !== undefined &&
|
|
401
|
+
if (format !== undefined &&
|
|
522
402
|
((textIndex === selectionStartIndex &&
|
|
523
403
|
zeroWidthSelection) ||
|
|
524
|
-
inRange())
|
|
525
|
-
) {
|
|
404
|
+
inRange())) {
|
|
526
405
|
// Remove all formatting if we were asked to.
|
|
527
|
-
if (format === '')
|
|
406
|
+
if (format === '')
|
|
407
|
+
desiredFormats = [];
|
|
528
408
|
// Apply the formatting if it's not already applied.
|
|
529
|
-
else if (
|
|
530
|
-
!
|
|
531
|
-
!desiredFormats.includes(format)
|
|
532
|
-
)
|
|
409
|
+
else if (!alreadyApplied &&
|
|
410
|
+
!desiredFormats.includes(format))
|
|
533
411
|
desiredFormats.push(format);
|
|
534
412
|
// Remove the formatting if it's already applied in the selection.
|
|
535
|
-
else if (
|
|
536
|
-
|
|
537
|
-
desiredFormats.
|
|
538
|
-
)
|
|
539
|
-
desiredFormats.splice(
|
|
540
|
-
desiredFormats.indexOf(format),
|
|
541
|
-
1
|
|
542
|
-
);
|
|
413
|
+
else if (alreadyApplied &&
|
|
414
|
+
desiredFormats.includes(format))
|
|
415
|
+
desiredFormats.splice(desiredFormats.indexOf(format), 1);
|
|
543
416
|
}
|
|
544
|
-
|
|
545
417
|
// Remove undesired formats.
|
|
546
418
|
getFormats().forEach((activeFormat) => {
|
|
547
419
|
// If the current format is not in the desired list, close the text
|
|
@@ -549,22 +421,16 @@ export default class FormatNode extends Node {
|
|
|
549
421
|
if (!desiredFormats.includes(activeFormat)) {
|
|
550
422
|
// Save any text that we've accumulated.
|
|
551
423
|
saveText();
|
|
552
|
-
|
|
553
424
|
// Not sure this loop is necessary; we should always remove in the order we added.
|
|
554
|
-
while (
|
|
555
|
-
newFormats[0].format !== activeFormat
|
|
556
|
-
)
|
|
425
|
+
while (newFormats[0].format !== activeFormat)
|
|
557
426
|
finishFormat();
|
|
558
427
|
// Do it one more time to close out the undesired format.
|
|
559
428
|
finishFormat();
|
|
560
|
-
|
|
561
429
|
// If we have unformatted something at a zero-width range, create empty format node, add a text node in it and remember it so
|
|
562
430
|
// we can place the caret in it.
|
|
563
|
-
if (
|
|
564
|
-
!formattingEmptyNode &&
|
|
431
|
+
if (!formattingEmptyNode &&
|
|
565
432
|
textIndex === selectionStartIndex &&
|
|
566
|
-
zeroWidthSelection
|
|
567
|
-
) {
|
|
433
|
+
zeroWidthSelection) {
|
|
568
434
|
// Remember the node for later, so we can place the caret in it.
|
|
569
435
|
emptyNode = new TextNode();
|
|
570
436
|
// Append the empty node to the current format.
|
|
@@ -577,7 +443,6 @@ export default class FormatNode extends Node {
|
|
|
577
443
|
}
|
|
578
444
|
}
|
|
579
445
|
});
|
|
580
|
-
|
|
581
446
|
// Ensure the desired formats.
|
|
582
447
|
desiredFormats.forEach((desiredFormat) => {
|
|
583
448
|
// If the current format does not yet include the desired format,
|
|
@@ -585,27 +450,22 @@ export default class FormatNode extends Node {
|
|
|
585
450
|
if (!getFormats().includes(desiredFormat)) {
|
|
586
451
|
// Save any text that we've accumulated in the curent format.
|
|
587
452
|
saveText();
|
|
588
|
-
|
|
589
453
|
// Add a new format onto the stack to start adding to.
|
|
590
454
|
newFormats.unshift({
|
|
591
455
|
format: desiredFormat,
|
|
592
456
|
segments: [],
|
|
593
457
|
});
|
|
594
|
-
|
|
595
458
|
// If we inserted an empty format node, add a text node in it and remember it so
|
|
596
459
|
// we can place the caret in it.
|
|
597
|
-
if (
|
|
598
|
-
!formattingEmptyNode &&
|
|
460
|
+
if (!formattingEmptyNode &&
|
|
599
461
|
textIndex === selectionStartIndex &&
|
|
600
|
-
zeroWidthSelection
|
|
601
|
-
) {
|
|
462
|
+
zeroWidthSelection) {
|
|
602
463
|
emptyNode = new TextNode();
|
|
603
464
|
newFormats[0].segments.push(emptyNode);
|
|
604
465
|
finishFormat();
|
|
605
466
|
}
|
|
606
467
|
}
|
|
607
468
|
});
|
|
608
|
-
|
|
609
469
|
// If there's a format we're applying, or we're outside the deletion range, append the current character.
|
|
610
470
|
// We don't do this if we're checking the very last index of the node, since there is no character after it.
|
|
611
471
|
if (i < node.getLength()) {
|
|
@@ -621,20 +481,16 @@ export default class FormatNode extends Node {
|
|
|
621
481
|
else if (parent instanceof MetadataNode) {
|
|
622
482
|
// Save whatever text came before it.
|
|
623
483
|
saveText();
|
|
624
|
-
|
|
625
484
|
// Process each character in the node if we're formatting, and if we're deleting, skip anything in range of deletion.
|
|
626
485
|
for (let i = 0; i < node.getText().length; i++) {
|
|
627
486
|
if (format !== undefined || !inRange())
|
|
628
487
|
currentText += node.getText().charAt(i);
|
|
629
488
|
textIndex++;
|
|
630
489
|
}
|
|
631
|
-
|
|
632
490
|
// Duplicate the MetadataNode but with new text. Erase the MetadataNode if the text is empty
|
|
633
491
|
// by simply not adding one to this new format. Then, erase the text, since it was added in the metadata node.
|
|
634
492
|
if (currentText.length > 0) {
|
|
635
|
-
newFormats[0].segments.push(
|
|
636
|
-
parent.withText(new TextNode(currentText))
|
|
637
|
-
);
|
|
493
|
+
newFormats[0].segments.push(parent.withText(new TextNode(currentText)));
|
|
638
494
|
currentText = '';
|
|
639
495
|
}
|
|
640
496
|
}
|
|
@@ -644,52 +500,35 @@ export default class FormatNode extends Node {
|
|
|
644
500
|
else if (node instanceof AtomNode) {
|
|
645
501
|
// Before adding the atom, create a text node and reset the accumulator.
|
|
646
502
|
saveText();
|
|
647
|
-
|
|
648
503
|
// Add the atom immediately after, unless it's in the deletion range.
|
|
649
504
|
// We include the start index since AtomNode's text index is on the left.
|
|
650
|
-
if (
|
|
651
|
-
format !== undefined ||
|
|
505
|
+
if (format !== undefined ||
|
|
652
506
|
textIndex < selectionStartIndex ||
|
|
653
|
-
textIndex > selectionEndIndex
|
|
654
|
-
) {
|
|
507
|
+
textIndex > selectionEndIndex) {
|
|
655
508
|
// Does the atom node have a format? Format it!
|
|
656
509
|
let newAtom = node;
|
|
657
510
|
const atomMeta = node.getMeta();
|
|
658
511
|
if (atomMeta instanceof FormatNode) {
|
|
659
|
-
if (
|
|
660
|
-
atomMeta.contains(range.
|
|
661
|
-
atomMeta.
|
|
662
|
-
) {
|
|
663
|
-
const newFormat = atomMeta.withFormat(
|
|
664
|
-
range,
|
|
665
|
-
format
|
|
666
|
-
);
|
|
512
|
+
if (atomMeta.contains(range.start.node) &&
|
|
513
|
+
atomMeta.contains(range.end.node)) {
|
|
514
|
+
const newFormat = atomMeta.withFormat(range, format);
|
|
667
515
|
newAtom = node.withMeta(newFormat);
|
|
668
516
|
}
|
|
669
517
|
}
|
|
670
518
|
// Add the formatted atom if there is one.
|
|
671
|
-
newFormats[0].segments.push(
|
|
672
|
-
newAtom !== undefined ? newAtom : node
|
|
673
|
-
);
|
|
519
|
+
newFormats[0].segments.push(newAtom !== undefined ? newAtom : node);
|
|
674
520
|
}
|
|
675
|
-
|
|
676
521
|
// Increment the text index; atoms count for one character.
|
|
677
522
|
textIndex++;
|
|
678
523
|
}
|
|
679
524
|
});
|
|
680
|
-
|
|
681
525
|
// Save any remaining text that we've accumulated.
|
|
682
526
|
saveText();
|
|
683
|
-
|
|
684
527
|
// Keep finishing formats until we get to the original we created.
|
|
685
|
-
while (newFormats.length > 1)
|
|
686
|
-
|
|
528
|
+
while (newFormats.length > 1)
|
|
529
|
+
finishFormat();
|
|
687
530
|
// Create the final format.
|
|
688
|
-
let newFormat = new FormatNode(
|
|
689
|
-
newFormats[0].format,
|
|
690
|
-
newFormats[0].segments
|
|
691
|
-
);
|
|
692
|
-
|
|
531
|
+
let newFormat = new FormatNode(newFormats[0].format, newFormats[0].segments);
|
|
693
532
|
// If after all that, it's empty, make sure there's one empty text node to type in.
|
|
694
533
|
if (newFormat.getTextAndAtomNodes().length === 0)
|
|
695
534
|
newFormat = new FormatNode('', [new TextNode()]);
|
|
@@ -697,230 +536,210 @@ export default class FormatNode extends Node {
|
|
|
697
536
|
else {
|
|
698
537
|
if (newFormat.#segments[0] instanceof AtomNode)
|
|
699
538
|
newFormat = newFormat.withSegmentPrepended(new TextNode());
|
|
700
|
-
if (
|
|
701
|
-
|
|
702
|
-
AtomNode
|
|
703
|
-
)
|
|
539
|
+
if (newFormat.#segments[newFormat.getLength() - 1] instanceof
|
|
540
|
+
AtomNode)
|
|
704
541
|
newFormat = newFormat.withSegmentAppended(new TextNode());
|
|
705
542
|
}
|
|
706
|
-
|
|
707
543
|
return newFormat;
|
|
708
544
|
}
|
|
709
|
-
|
|
710
|
-
withRangeFormatted(range: CaretRange, format: Format | undefined): Edit {
|
|
545
|
+
withRangeFormatted(range, format) {
|
|
711
546
|
// Convert the range to text indices.
|
|
712
547
|
const text = caretRangeToIndexRange(this, range);
|
|
713
|
-
if (text === undefined)
|
|
548
|
+
if (text === undefined)
|
|
549
|
+
return;
|
|
714
550
|
const newFormat = this.withFormat(range, format);
|
|
715
|
-
if (newFormat === undefined)
|
|
551
|
+
if (newFormat === undefined)
|
|
552
|
+
return;
|
|
716
553
|
const newStart = indexToCaret(newFormat, text.start);
|
|
717
|
-
const newEnd =
|
|
718
|
-
|
|
719
|
-
|
|
554
|
+
const newEnd = format === undefined ? newStart : indexToCaret(newFormat, text.end);
|
|
555
|
+
if (newStart === undefined || newEnd === undefined)
|
|
556
|
+
return;
|
|
720
557
|
return { root: newFormat, range: { start: newStart, end: newEnd } };
|
|
721
558
|
}
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
const formats: Format[] = [];
|
|
559
|
+
getFormats(root) {
|
|
560
|
+
let format = this;
|
|
561
|
+
const formats = [];
|
|
726
562
|
while (format instanceof FormatNode) {
|
|
727
|
-
if (format.#format !== '')
|
|
563
|
+
if (format.#format !== '')
|
|
564
|
+
formats.push(format.#format);
|
|
728
565
|
format = format.getParent(root);
|
|
729
566
|
}
|
|
730
567
|
return formats;
|
|
731
568
|
}
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
caret: Caret
|
|
736
|
-
): FormatNode | undefined {
|
|
737
|
-
if (!(caret.node instanceof TextNode)) return;
|
|
738
|
-
|
|
569
|
+
withSegmentAt(segment, caret) {
|
|
570
|
+
if (!(caret.node instanceof TextNode))
|
|
571
|
+
return;
|
|
739
572
|
// Verify that the caret's node is a segment in this node.
|
|
740
573
|
const index = this.#segments.indexOf(caret.node);
|
|
741
|
-
if (index < 0)
|
|
742
|
-
|
|
574
|
+
if (index < 0)
|
|
575
|
+
return;
|
|
743
576
|
// Splice the text node.
|
|
744
|
-
const left = new TextNode(
|
|
745
|
-
caret.node.getText().substring(0, caret.index)
|
|
746
|
-
);
|
|
577
|
+
const left = new TextNode(caret.node.getText().substring(0, caret.index));
|
|
747
578
|
const right = new TextNode(caret.node.getText().substring(caret.index));
|
|
748
|
-
|
|
749
579
|
// Insert the new left, right and middle
|
|
750
580
|
const newSegments = this.#segments.slice();
|
|
751
581
|
newSegments.splice(index, 1, left, segment, right);
|
|
752
582
|
return new FormatNode(this.#format, newSegments);
|
|
753
583
|
}
|
|
754
|
-
|
|
755
|
-
withSegmentAtSelection(
|
|
756
|
-
range: CaretRange,
|
|
757
|
-
nodeCreator: (text: string) => FormatNodeSegmentType
|
|
758
|
-
): Edit {
|
|
584
|
+
withSegmentAtSelection(range, nodeCreator) {
|
|
759
585
|
// If there's a selection, grab it's text and then remove the text and update the root and text being edited.
|
|
760
586
|
let selectedText = this.getSelectedText(range);
|
|
761
|
-
let newFormat
|
|
587
|
+
let newFormat = this;
|
|
762
588
|
const sortedRange = this.sortRange(range);
|
|
763
589
|
let caret = sortedRange.start;
|
|
764
|
-
if (
|
|
765
|
-
sortedRange.start.
|
|
766
|
-
sortedRange.start.index !== sortedRange.end.index
|
|
767
|
-
) {
|
|
590
|
+
if (sortedRange.start.node !== sortedRange.end.node ||
|
|
591
|
+
sortedRange.start.index !== sortedRange.end.index) {
|
|
768
592
|
// Try to remove the selected text. Bail on fail.
|
|
769
593
|
const textIndex = caretToIndex(this, sortedRange.start);
|
|
770
|
-
if (textIndex === undefined)
|
|
594
|
+
if (textIndex === undefined)
|
|
595
|
+
return;
|
|
771
596
|
newFormat = this.withoutRange(sortedRange);
|
|
772
|
-
if (newFormat === undefined)
|
|
597
|
+
if (newFormat === undefined)
|
|
598
|
+
return;
|
|
773
599
|
const newCaret = indexToCaret(newFormat, textIndex);
|
|
774
|
-
if (newCaret === undefined)
|
|
600
|
+
if (newCaret === undefined)
|
|
601
|
+
return;
|
|
775
602
|
caret = newCaret;
|
|
776
603
|
}
|
|
777
|
-
|
|
778
604
|
// Create and insert the into the formatted node.
|
|
779
|
-
const newNode = nodeCreator.call(
|
|
780
|
-
undefined,
|
|
781
|
-
selectedText ? selectedText : ''
|
|
782
|
-
);
|
|
605
|
+
const newNode = nodeCreator.call(undefined, selectedText ? selectedText : '');
|
|
783
606
|
const revisedFormat = newFormat.withSegmentAt(newNode, caret);
|
|
784
|
-
if (revisedFormat === undefined)
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
607
|
+
if (revisedFormat === undefined)
|
|
608
|
+
return;
|
|
609
|
+
const newCaret = newNode instanceof AtomNode
|
|
610
|
+
? newNode.getDefaultCaret()
|
|
611
|
+
: newNode instanceof FormatNode
|
|
789
612
|
? newNode.getFirstCaret()
|
|
790
613
|
: newNode instanceof MetadataNode
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
614
|
+
? { node: newNode.getText(), index: 0 }
|
|
615
|
+
: newNode instanceof TextNode
|
|
616
|
+
? { node: newNode, index: 0 }
|
|
617
|
+
: undefined;
|
|
618
|
+
if (newCaret === undefined)
|
|
619
|
+
return;
|
|
797
620
|
return {
|
|
798
621
|
root: revisedFormat,
|
|
799
622
|
range: { start: newCaret, end: newCaret },
|
|
800
623
|
};
|
|
801
624
|
}
|
|
802
|
-
|
|
803
|
-
withoutContentBefore(caret: Caret): FormatNode | undefined {
|
|
625
|
+
withoutContentBefore(caret) {
|
|
804
626
|
return this.withContentAt(caret, false);
|
|
805
627
|
}
|
|
806
|
-
|
|
807
|
-
withoutContentAfter(caret: Caret): FormatNode | undefined {
|
|
628
|
+
withoutContentAfter(caret) {
|
|
808
629
|
return this.withContentAt(caret, true);
|
|
809
630
|
}
|
|
810
|
-
|
|
811
|
-
withContentAt(caret: Caret, before: boolean): FormatNode | undefined {
|
|
631
|
+
withContentAt(caret, before) {
|
|
812
632
|
let range = undefined;
|
|
813
633
|
if (before) {
|
|
814
634
|
const lastCaret = this.getLastCaret();
|
|
815
|
-
if (lastCaret === undefined)
|
|
635
|
+
if (lastCaret === undefined)
|
|
636
|
+
return;
|
|
816
637
|
range = { start: caret, end: lastCaret };
|
|
817
|
-
}
|
|
638
|
+
}
|
|
639
|
+
else {
|
|
818
640
|
const firstCaret = this.getFirstCaret();
|
|
819
|
-
if (firstCaret === undefined)
|
|
641
|
+
if (firstCaret === undefined)
|
|
642
|
+
return;
|
|
820
643
|
range = { start: firstCaret, end: caret };
|
|
821
644
|
}
|
|
822
645
|
return this.withoutRange(range);
|
|
823
646
|
}
|
|
824
|
-
|
|
825
|
-
withContentInRange(range: CaretRange): this | undefined {
|
|
647
|
+
withContentInRange(range) {
|
|
826
648
|
const containsStart = this.contains(range.start.node);
|
|
827
649
|
const containsEnd = this.contains(range.end.node);
|
|
828
|
-
if (!containsStart && !containsEnd)
|
|
650
|
+
if (!containsStart && !containsEnd)
|
|
651
|
+
return this.copy();
|
|
829
652
|
const startCaret = containsStart ? range.start : this.getFirstCaret();
|
|
830
653
|
const endCaret = containsEnd ? range.end : this.getLastCaret();
|
|
831
|
-
if (startCaret === undefined || endCaret === undefined)
|
|
654
|
+
if (startCaret === undefined || endCaret === undefined)
|
|
655
|
+
return;
|
|
832
656
|
const startIndex = caretToIndex(this, startCaret);
|
|
833
657
|
const endIndex = caretToIndex(this, endCaret);
|
|
834
|
-
if (startIndex === undefined || endIndex === undefined)
|
|
658
|
+
if (startIndex === undefined || endIndex === undefined)
|
|
659
|
+
return;
|
|
835
660
|
const withoutBefore = this.withoutContentBefore(startCaret);
|
|
836
|
-
if (withoutBefore === undefined)
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
withSegmentsAppended(format: FormatNode): FormatNode {
|
|
661
|
+
if (withoutBefore === undefined)
|
|
662
|
+
return;
|
|
663
|
+
const revisedEndCaret = indexToCaret(withoutBefore, endIndex - startIndex);
|
|
664
|
+
if (revisedEndCaret === undefined)
|
|
665
|
+
return;
|
|
666
|
+
return withoutBefore.withoutContentAfter(revisedEndCaret);
|
|
667
|
+
}
|
|
668
|
+
withSegmentsAppended(format) {
|
|
846
669
|
return new FormatNode(this.#format, [
|
|
847
670
|
...this.#segments,
|
|
848
671
|
...format.getSegments(),
|
|
849
672
|
]);
|
|
850
673
|
}
|
|
851
|
-
|
|
852
|
-
withoutAdjacentContent(caret: Caret, next: boolean): Edit | undefined {
|
|
674
|
+
withoutAdjacentContent(caret, next) {
|
|
853
675
|
return this.withoutCharacter(caret, next);
|
|
854
676
|
}
|
|
855
|
-
|
|
856
|
-
withoutCharacter(caret: Caret, next: boolean): Edit | undefined {
|
|
677
|
+
withoutCharacter(caret, next) {
|
|
857
678
|
// Confirm that this caret is in this format.
|
|
858
|
-
if (!this.contains(caret.node))
|
|
679
|
+
if (!this.contains(caret.node))
|
|
680
|
+
return;
|
|
859
681
|
// Is there an adjascent caret? Return nothing if not.
|
|
860
682
|
const adjacentCaret = this.getAdjacentCaret(caret, next);
|
|
861
|
-
if (adjacentCaret === undefined)
|
|
862
|
-
|
|
683
|
+
if (adjacentCaret === undefined)
|
|
684
|
+
return;
|
|
863
685
|
// Handle each case differently
|
|
864
686
|
if (caret.node instanceof AtomNode) {
|
|
865
687
|
const newFormat = this.withNodeReplaced(caret.node, undefined);
|
|
866
|
-
if (newFormat === undefined)
|
|
688
|
+
if (newFormat === undefined)
|
|
689
|
+
return;
|
|
867
690
|
return {
|
|
868
691
|
root: newFormat,
|
|
869
692
|
range: { start: adjacentCaret, end: adjacentCaret },
|
|
870
693
|
};
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
if (newFormat === undefined) return;
|
|
694
|
+
}
|
|
695
|
+
else if (adjacentCaret.node instanceof AtomNode) {
|
|
696
|
+
const newFormat = this.withNodeReplaced(adjacentCaret.node, undefined);
|
|
697
|
+
if (newFormat === undefined)
|
|
698
|
+
return;
|
|
877
699
|
return { root: newFormat, range: { start: caret, end: caret } };
|
|
878
|
-
}
|
|
700
|
+
}
|
|
701
|
+
else {
|
|
879
702
|
// If next, keep the caret in place, otherwise go to the adjacent caret position.
|
|
880
703
|
const textIndex = caretToIndex(this, next ? caret : adjacentCaret);
|
|
881
|
-
if (textIndex === undefined)
|
|
704
|
+
if (textIndex === undefined)
|
|
705
|
+
return;
|
|
882
706
|
// If there is one, try removing everything between this and the adjascent caret.
|
|
883
707
|
const newFormat = this.withoutRange({
|
|
884
708
|
start: caret,
|
|
885
709
|
end: adjacentCaret,
|
|
886
710
|
});
|
|
887
|
-
if (newFormat === undefined)
|
|
711
|
+
if (newFormat === undefined)
|
|
712
|
+
return;
|
|
888
713
|
const newCaret = indexToCaret(newFormat, textIndex);
|
|
889
|
-
if (newCaret === undefined)
|
|
714
|
+
if (newCaret === undefined)
|
|
715
|
+
return;
|
|
890
716
|
return {
|
|
891
717
|
root: newFormat,
|
|
892
718
|
range: { start: newCaret, end: newCaret },
|
|
893
719
|
};
|
|
894
720
|
}
|
|
895
721
|
}
|
|
896
|
-
|
|
897
|
-
withNodeInserted(caret: Caret, node: Node): Edit {
|
|
722
|
+
withNodeInserted(caret, node) {
|
|
898
723
|
// The caret node has to be one of the nodes in this format to insert.
|
|
899
|
-
const index = this.#segments.indexOf(
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
if (index < 0) return;
|
|
724
|
+
const index = this.#segments.indexOf(caret.node);
|
|
725
|
+
if (index < 0)
|
|
726
|
+
return;
|
|
903
727
|
// The inserted node has to be a segment type.
|
|
904
|
-
if (
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
node instanceof MetadataNode ||
|
|
909
|
-
node instanceof AtomNode
|
|
910
|
-
)
|
|
911
|
-
)
|
|
728
|
+
if (!(node instanceof FormatNode ||
|
|
729
|
+
node instanceof TextNode ||
|
|
730
|
+
node instanceof MetadataNode ||
|
|
731
|
+
node instanceof AtomNode))
|
|
912
732
|
return;
|
|
913
|
-
|
|
914
733
|
const newFormat = this.withSegmentAt(node, caret);
|
|
915
|
-
const newCaret =
|
|
916
|
-
node
|
|
917
|
-
|
|
918
|
-
: node instanceof FormatNode
|
|
734
|
+
const newCaret = node instanceof AtomNode
|
|
735
|
+
? node.getDefaultCaret()
|
|
736
|
+
: node instanceof FormatNode
|
|
919
737
|
? node.getLastCaret()
|
|
920
738
|
: node instanceof MetadataNode
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
if (newFormat === undefined || newCaret === undefined)
|
|
739
|
+
? { node: node.getText(), index: node.getText().getLength() }
|
|
740
|
+
: { node: node, index: node.getLength() };
|
|
741
|
+
if (newFormat === undefined || newCaret === undefined)
|
|
742
|
+
return;
|
|
924
743
|
return { root: newFormat, range: { start: newCaret, end: newCaret } };
|
|
925
744
|
}
|
|
926
745
|
}
|