bookish-press 0.4.47 → 0.4.48
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 +58 -62
- 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 +5 -9
- 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 +392 -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 +37 -52
- 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 +41 -48
- 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} +5 -109
- 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,33 +1,24 @@
|
|
|
1
|
-
import type Node from './Node';
|
|
2
1
|
import BlockNode from './BlockNode';
|
|
3
2
|
import ListNode from './ListNode';
|
|
4
|
-
import type Caret from './Caret';
|
|
5
|
-
import type { CaretRange } from './Caret';
|
|
6
3
|
import { caretToIndex, indexToCaret } from './Caret';
|
|
7
4
|
import ParagraphNode from './ParagraphNode';
|
|
8
|
-
import type { Format, FormatNodeSegmentType } from './FormatNode';
|
|
9
5
|
import FormatNode from './FormatNode';
|
|
10
6
|
import TextNode from './TextNode';
|
|
11
7
|
import AtomNode from './AtomNode';
|
|
12
|
-
import type Edit from './Edit';
|
|
13
8
|
import CodeNode from './CodeNode';
|
|
14
9
|
import EmbedNode from './EmbedNode';
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
constructor(elements: BlockNode[]) {
|
|
10
|
+
export default class BlocksNode extends BlockNode {
|
|
11
|
+
#blocks;
|
|
12
|
+
constructor(elements) {
|
|
20
13
|
super();
|
|
21
14
|
const adjustedElements = [];
|
|
22
15
|
for (let i = 0; i < elements.length; i++) {
|
|
23
16
|
const block = elements[i];
|
|
24
17
|
const previousBlock = i === 0 ? undefined : elements[i - 1];
|
|
25
18
|
// If this block and the previous one are lists of the same kind, merge them.
|
|
26
|
-
if (
|
|
27
|
-
block instanceof ListNode &&
|
|
19
|
+
if (block instanceof ListNode &&
|
|
28
20
|
previousBlock instanceof ListNode &&
|
|
29
|
-
block.isNumbered() === previousBlock.isNumbered()
|
|
30
|
-
) {
|
|
21
|
+
block.isNumbered() === previousBlock.isNumbered()) {
|
|
31
22
|
adjustedElements[adjustedElements.length - 1] =
|
|
32
23
|
previousBlock.withListAppended(block);
|
|
33
24
|
}
|
|
@@ -37,49 +28,40 @@ export default abstract class BlocksNode extends BlockNode {
|
|
|
37
28
|
// if(!(block instanceof ParagraphNode) && (i === 0 || !(previousBlock instanceof ParagraphNode)))
|
|
38
29
|
// adjustedElements.push(new ParagraphNode());
|
|
39
30
|
// }
|
|
40
|
-
else
|
|
31
|
+
else
|
|
32
|
+
adjustedElements.push(block);
|
|
41
33
|
}
|
|
42
34
|
// Check the last one.
|
|
43
35
|
// if(!(adjustedElements[adjustedElements.length - 1] instanceof ParagraphNode))
|
|
44
36
|
// adjustedElements.push(new ParagraphNode());
|
|
45
|
-
|
|
46
37
|
this.#blocks = adjustedElements;
|
|
47
|
-
|
|
48
38
|
// After all that, always ensure there's at least one empty paragraph block.
|
|
49
|
-
if (this.#blocks.length === 0)
|
|
39
|
+
if (this.#blocks.length === 0)
|
|
40
|
+
this.#blocks.push(new ParagraphNode());
|
|
50
41
|
}
|
|
51
|
-
|
|
52
42
|
getBlocks() {
|
|
53
43
|
return this.#blocks;
|
|
54
44
|
}
|
|
55
45
|
getFormats() {
|
|
56
|
-
return this.getBlocks().reduce(
|
|
57
|
-
(prev: FormatNode[], current) => prev.concat(current.getFormats()),
|
|
58
|
-
[]
|
|
59
|
-
);
|
|
46
|
+
return this.getBlocks().reduce((prev, current) => prev.concat(current.getFormats()), []);
|
|
60
47
|
}
|
|
61
|
-
|
|
62
|
-
getIndexOf(block: BlockNode): number | undefined {
|
|
48
|
+
getIndexOf(block) {
|
|
63
49
|
const index = this.#blocks.indexOf(block);
|
|
64
50
|
return index < 0 ? undefined : index;
|
|
65
51
|
}
|
|
66
|
-
|
|
67
|
-
getBlockBefore(anchor: BlockNode): BlockNode | undefined {
|
|
52
|
+
getBlockBefore(anchor) {
|
|
68
53
|
const index = this.#blocks.indexOf(anchor);
|
|
69
|
-
if (index <= 0)
|
|
54
|
+
if (index <= 0)
|
|
55
|
+
return undefined;
|
|
70
56
|
return this.#blocks[index - 1];
|
|
71
57
|
}
|
|
72
|
-
|
|
73
|
-
getBlockAfter(anchor: BlockNode): BlockNode | undefined {
|
|
58
|
+
getBlockAfter(anchor) {
|
|
74
59
|
const index = this.#blocks.indexOf(anchor);
|
|
75
|
-
if (index < 0 || index > this.#blocks.length - 2)
|
|
60
|
+
if (index < 0 || index > this.#blocks.length - 2)
|
|
61
|
+
return undefined;
|
|
76
62
|
return this.#blocks[index + 1];
|
|
77
63
|
}
|
|
78
|
-
|
|
79
|
-
getBlocksBetween(
|
|
80
|
-
first: BlockNode,
|
|
81
|
-
last: BlockNode
|
|
82
|
-
): BlockNode[] | undefined {
|
|
64
|
+
getBlocksBetween(first, last) {
|
|
83
65
|
const firstIndex = this.getIndexOf(first);
|
|
84
66
|
const lastIndex = this.getIndexOf(last);
|
|
85
67
|
if (firstIndex !== undefined && lastIndex !== undefined) {
|
|
@@ -93,164 +75,133 @@ export default abstract class BlocksNode extends BlockNode {
|
|
|
93
75
|
let inside = false;
|
|
94
76
|
for (let i = 0; i < this.#blocks.length; i++) {
|
|
95
77
|
let block = this.#blocks[i];
|
|
96
|
-
if (block === first)
|
|
97
|
-
|
|
98
|
-
if (
|
|
78
|
+
if (block === first)
|
|
79
|
+
inside = true;
|
|
80
|
+
if (inside)
|
|
81
|
+
blocks.push(block);
|
|
82
|
+
if (block === last)
|
|
83
|
+
break;
|
|
99
84
|
}
|
|
100
85
|
return blocks;
|
|
101
86
|
}
|
|
102
87
|
return undefined;
|
|
103
88
|
}
|
|
104
|
-
|
|
105
|
-
getBlocksInRange(range: CaretRange): BlockNode[] | undefined {
|
|
89
|
+
getBlocksInRange(range) {
|
|
106
90
|
// Find the start and end block the carets reside in. Bail on fail.
|
|
107
91
|
const startBlock = this.getBlockOfCaret(range.start);
|
|
108
|
-
const endBlock =
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
92
|
+
const endBlock = range.end === range.start
|
|
93
|
+
? startBlock
|
|
94
|
+
: this.getBlockOfCaret(range.end);
|
|
95
|
+
if (startBlock === undefined || endBlock === undefined)
|
|
96
|
+
return;
|
|
114
97
|
// Find all of the blocks between the start and end blocks.
|
|
115
98
|
// Start tracking when we hit the start node. Stop tracking when we hit the end node.
|
|
116
|
-
const blocksToEdit
|
|
99
|
+
const blocksToEdit = [];
|
|
117
100
|
let insideSelection = false;
|
|
118
101
|
this.getNodes()
|
|
119
102
|
.filter((n) => n instanceof BlockNode)
|
|
120
103
|
.forEach((node) => {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
104
|
+
if (node === startBlock)
|
|
105
|
+
insideSelection = true;
|
|
106
|
+
if (insideSelection && node instanceof BlockNode)
|
|
107
|
+
blocksToEdit.push(node);
|
|
108
|
+
if (insideSelection && node === endBlock)
|
|
109
|
+
insideSelection = false;
|
|
110
|
+
});
|
|
128
111
|
return blocksToEdit;
|
|
129
112
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
return caret.node.getClosestParentOfType<BlockNode>(this, BlockNode);
|
|
113
|
+
getBlockOfCaret(caret) {
|
|
114
|
+
return caret.node.getClosestParentOfType(this, BlockNode);
|
|
133
115
|
}
|
|
134
|
-
|
|
135
|
-
getParentOf(node: Node): Node | undefined {
|
|
116
|
+
getParentOf(node) {
|
|
136
117
|
return this.#blocks
|
|
137
118
|
.map((b) => (b === node ? this : b.getParentOf(node)))
|
|
138
119
|
.find((b) => b !== undefined);
|
|
139
120
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
return this.getNodes().filter(
|
|
143
|
-
(node) => node instanceof TextNode
|
|
144
|
-
) as TextNode[];
|
|
121
|
+
getTextNodes() {
|
|
122
|
+
return this.getNodes().filter((node) => node instanceof TextNode);
|
|
145
123
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
return this.getNodes().filter(
|
|
149
|
-
(node) => node instanceof AtomNode
|
|
150
|
-
) as AtomNode<any>[];
|
|
124
|
+
getAtomNodes() {
|
|
125
|
+
return this.getNodes().filter((node) => node instanceof AtomNode);
|
|
151
126
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
return this.getNodes().filter(
|
|
155
|
-
(node) => node instanceof TextNode || node instanceof AtomNode
|
|
156
|
-
) as (TextNode | AtomNode<any>)[];
|
|
127
|
+
getTextAndAtomNodes() {
|
|
128
|
+
return this.getNodes().filter((node) => node instanceof TextNode || node instanceof AtomNode);
|
|
157
129
|
}
|
|
158
|
-
|
|
159
|
-
getIndexOfTextNode(node: TextNode): number | undefined {
|
|
130
|
+
getIndexOfTextNode(node) {
|
|
160
131
|
const text = this.getTextNodes();
|
|
161
132
|
return text.indexOf(node);
|
|
162
133
|
}
|
|
163
|
-
|
|
164
|
-
getFirstCaret(): Caret | undefined {
|
|
134
|
+
getFirstCaret() {
|
|
165
135
|
const text = this.getTextNodes();
|
|
166
136
|
return text.length === 0 ? undefined : { node: text[0], index: 0 };
|
|
167
137
|
}
|
|
168
|
-
|
|
169
|
-
getLastCaret(): Caret | undefined {
|
|
138
|
+
getLastCaret() {
|
|
170
139
|
const text = this.getTextNodes();
|
|
171
140
|
return text.length === 0
|
|
172
141
|
? undefined
|
|
173
142
|
: {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
143
|
+
node: text[text.length - 1],
|
|
144
|
+
index: text[text.length - 1].getLength(),
|
|
145
|
+
};
|
|
177
146
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
147
|
+
getAdjacentCaret(caret, next) {
|
|
148
|
+
if (!this.contains(caret.node))
|
|
149
|
+
return;
|
|
182
150
|
// Navigate from code node.
|
|
183
|
-
const code = caret.node.getFarthestParentMatching(
|
|
184
|
-
this,
|
|
185
|
-
(n) => n instanceof CodeNode
|
|
186
|
-
) as CodeNode;
|
|
151
|
+
const code = caret.node.getFarthestParentMatching(this, (n) => n instanceof CodeNode);
|
|
187
152
|
if (code && caret.node === code.getCodeNode()) {
|
|
188
153
|
// Get the adjacent text node.
|
|
189
154
|
const newCaret = next
|
|
190
155
|
? caret.node.getNextCaret(caret.index)
|
|
191
156
|
: caret.node.getPreviousCaret(caret.index);
|
|
192
|
-
if (newCaret !== undefined)
|
|
157
|
+
if (newCaret !== undefined)
|
|
158
|
+
return newCaret;
|
|
193
159
|
// Otherwise, get the adjacent format's first/last caret.
|
|
194
|
-
if (next)
|
|
160
|
+
if (next)
|
|
161
|
+
return code.getCaption().getFirstCaret();
|
|
195
162
|
// If there's no adjacent caret, find the adjacent root format.
|
|
196
|
-
const blocks = this.getNodes().filter(
|
|
197
|
-
(n) => n instanceof BlockNode
|
|
198
|
-
) as BlockNode[];
|
|
163
|
+
const blocks = this.getNodes().filter((n) => n instanceof BlockNode);
|
|
199
164
|
const codeIndex = blocks.indexOf(code);
|
|
200
|
-
if (codeIndex <= 0)
|
|
165
|
+
if (codeIndex <= 0)
|
|
166
|
+
return;
|
|
201
167
|
const adjacentBlock = blocks[codeIndex - 1];
|
|
202
168
|
const adjacentFormats = adjacentBlock.getFormats();
|
|
203
169
|
const adjacentFormat = adjacentFormats[adjacentFormats.length - 1];
|
|
204
170
|
return adjacentFormat.getLastCaret();
|
|
205
171
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
(n) => n instanceof FormatNode
|
|
210
|
-
) as FormatNode;
|
|
211
|
-
if (format === undefined) return;
|
|
212
|
-
|
|
172
|
+
const format = caret.node.getFarthestParentMatching(this, (n) => n instanceof FormatNode);
|
|
173
|
+
if (format === undefined)
|
|
174
|
+
return;
|
|
213
175
|
// Find the format that contains the caret and return the adjacent caret if there is one.
|
|
214
176
|
const adjacentCaretInFormat = format.getAdjacentCaret(caret, next);
|
|
215
|
-
if (adjacentCaretInFormat !== undefined)
|
|
216
|
-
|
|
177
|
+
if (adjacentCaretInFormat !== undefined)
|
|
178
|
+
return adjacentCaretInFormat;
|
|
217
179
|
// If there's no adjacent caret in the root format, find the adjacent format or code.
|
|
218
180
|
const formats = this.getNodes().filter((n) => {
|
|
219
181
|
const parent = n.getParent(this);
|
|
220
|
-
return (
|
|
221
|
-
(n instanceof TextNode && parent instanceof CodeNode) ||
|
|
182
|
+
return ((n instanceof TextNode && parent instanceof CodeNode) ||
|
|
222
183
|
(n instanceof FormatNode &&
|
|
223
184
|
!(parent instanceof AtomNode) &&
|
|
224
|
-
!(parent instanceof FormatNode))
|
|
225
|
-
|
|
226
|
-
}) as (TextNode | FormatNode)[];
|
|
227
|
-
|
|
185
|
+
!(parent instanceof FormatNode)));
|
|
186
|
+
});
|
|
228
187
|
const index = formats.indexOf(format);
|
|
229
|
-
const adjacentFormat =
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
188
|
+
const adjacentFormat = index < 0 || formats.length === 0
|
|
189
|
+
? undefined
|
|
190
|
+
: formats[index + (next ? 1 : -1)];
|
|
191
|
+
if (adjacentFormat === undefined)
|
|
192
|
+
return;
|
|
234
193
|
return next
|
|
235
194
|
? adjacentFormat.getFirstCaret()
|
|
236
195
|
: adjacentFormat.getLastCaret();
|
|
237
196
|
}
|
|
238
|
-
|
|
239
|
-
getSelectedFormatRange(
|
|
240
|
-
format: FormatNode,
|
|
241
|
-
range: CaretRange
|
|
242
|
-
): CaretRange | undefined {
|
|
197
|
+
getSelectedFormatRange(format, range) {
|
|
243
198
|
// Find all of the formats.
|
|
244
|
-
const formats = this.getNodes().filter(
|
|
245
|
-
(n)
|
|
246
|
-
n instanceof FormatNode &&
|
|
247
|
-
!(this.getParentOf(n) instanceof FormatNode)
|
|
248
|
-
) as FormatNode[];
|
|
249
|
-
|
|
199
|
+
const formats = this.getNodes().filter((n) => n instanceof FormatNode &&
|
|
200
|
+
!(this.getParentOf(n) instanceof FormatNode));
|
|
250
201
|
// Find the given format index.
|
|
251
202
|
const formatIndex = formats.indexOf(format);
|
|
252
|
-
if (formatIndex < 0)
|
|
253
|
-
|
|
203
|
+
if (formatIndex < 0)
|
|
204
|
+
return undefined;
|
|
254
205
|
// Find the range start and end formats.
|
|
255
206
|
const startFormat = formats.find((f) => f.contains(range.start.node));
|
|
256
207
|
const endFormat = formats.find((f) => f.contains(range.end.node));
|
|
@@ -258,247 +209,196 @@ export default abstract class BlocksNode extends BlockNode {
|
|
|
258
209
|
return undefined;
|
|
259
210
|
const startIndex = formats.indexOf(startFormat);
|
|
260
211
|
const endIndex = formats.indexOf(endFormat);
|
|
261
|
-
|
|
262
212
|
// No range if out of bounds.
|
|
263
|
-
if (startIndex < 0 || endIndex < 0)
|
|
213
|
+
if (startIndex < 0 || endIndex < 0)
|
|
214
|
+
return undefined;
|
|
264
215
|
if (formatIndex < startIndex || formatIndex > endIndex)
|
|
265
216
|
return undefined;
|
|
266
|
-
|
|
267
217
|
// Choose the portion of the format that is selected.
|
|
268
|
-
const startCaret =
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
if (startCaret === undefined || endCaret === undefined) return;
|
|
218
|
+
const startCaret = formatIndex === startIndex ? range.start : format.getFirstCaret();
|
|
219
|
+
const endCaret = formatIndex === endIndex ? range.end : format.getLastCaret();
|
|
220
|
+
if (startCaret === undefined || endCaret === undefined)
|
|
221
|
+
return;
|
|
273
222
|
return { start: startCaret, end: endCaret };
|
|
274
223
|
}
|
|
275
|
-
|
|
276
|
-
abstract create(blocks: BlockNode[]): BlocksNode;
|
|
277
|
-
|
|
278
|
-
withContentInRange(range: CaretRange): this | undefined {
|
|
224
|
+
withContentInRange(range) {
|
|
279
225
|
const containsStart = this.contains(range.start.node);
|
|
280
226
|
const containsEnd = this.contains(range.end.node);
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
227
|
+
if (!containsStart && !containsEnd)
|
|
228
|
+
return this.copy();
|
|
284
229
|
let foundStart = false;
|
|
285
230
|
let foundEnd = false;
|
|
286
|
-
const newBlocks
|
|
231
|
+
const newBlocks = [];
|
|
287
232
|
for (let i = 0; i < this.#blocks.length; i++) {
|
|
288
|
-
if (this.#blocks[i].contains(range.start.node))
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
((containsEnd && !foundEnd) || !containsEnd)
|
|
292
|
-
) {
|
|
233
|
+
if (this.#blocks[i].contains(range.start.node))
|
|
234
|
+
foundStart = true;
|
|
235
|
+
if (((containsStart && foundStart) || !containsStart) &&
|
|
236
|
+
((containsEnd && !foundEnd) || !containsEnd)) {
|
|
293
237
|
const newBlock = this.#blocks[i].withContentInRange(range);
|
|
294
|
-
if (newBlock === undefined)
|
|
238
|
+
if (newBlock === undefined)
|
|
239
|
+
return;
|
|
295
240
|
newBlocks.push(newBlock);
|
|
296
241
|
}
|
|
297
|
-
if (this.#blocks[i].contains(range.end.node))
|
|
242
|
+
if (this.#blocks[i].contains(range.end.node))
|
|
243
|
+
foundEnd = true;
|
|
298
244
|
}
|
|
299
|
-
|
|
300
|
-
return this.create(newBlocks) as this;
|
|
245
|
+
return this.create(newBlocks);
|
|
301
246
|
}
|
|
302
|
-
|
|
303
|
-
withBlockInserted(
|
|
304
|
-
anchor: BlockNode,
|
|
305
|
-
block: BlockNode,
|
|
306
|
-
before: boolean
|
|
307
|
-
): BlocksNode | undefined {
|
|
247
|
+
withBlockInserted(anchor, block, before) {
|
|
308
248
|
const index = this.#blocks.indexOf(anchor);
|
|
309
|
-
if (index < 0)
|
|
249
|
+
if (index < 0)
|
|
250
|
+
return;
|
|
310
251
|
const newBlocks = this.#blocks.slice();
|
|
311
252
|
newBlocks.splice(index + (before ? 0 : 1), 0, block);
|
|
312
253
|
return this.create(newBlocks);
|
|
313
254
|
}
|
|
314
|
-
|
|
315
|
-
withBlockAppended(block: BlockNode): BlocksNode {
|
|
255
|
+
withBlockAppended(block) {
|
|
316
256
|
let newBlocks = this.#blocks.slice();
|
|
317
257
|
newBlocks.push(block);
|
|
318
258
|
return this.create(newBlocks);
|
|
319
259
|
}
|
|
320
|
-
|
|
321
|
-
withoutBlock(block: BlockNode): BlocksNode {
|
|
260
|
+
withoutBlock(block) {
|
|
322
261
|
return this.create(this.#blocks.filter((n) => n !== block));
|
|
323
262
|
}
|
|
324
|
-
|
|
325
|
-
withBlockInsertedBefore(anchor: BlockNode, block: BlockNode) {
|
|
263
|
+
withBlockInsertedBefore(anchor, block) {
|
|
326
264
|
return this.withBlockInserted(anchor, block, true);
|
|
327
265
|
}
|
|
328
|
-
|
|
329
|
-
withBlockInsertedAfter(anchor: BlockNode, block: BlockNode) {
|
|
266
|
+
withBlockInsertedAfter(anchor, block) {
|
|
330
267
|
return this.withBlockInserted(anchor, block, false);
|
|
331
268
|
}
|
|
332
|
-
|
|
333
|
-
withSelectionSplit(range: CaretRange): Edit {
|
|
269
|
+
withSelectionSplit(range) {
|
|
334
270
|
let caret = range.start;
|
|
335
|
-
let blocks
|
|
336
|
-
|
|
271
|
+
let blocks = this;
|
|
337
272
|
// If there's a selection, remove it before inserting.
|
|
338
|
-
if (
|
|
339
|
-
range.start.
|
|
340
|
-
range.start.index !== range.end.index
|
|
341
|
-
) {
|
|
273
|
+
if (range.start.node !== range.end.node ||
|
|
274
|
+
range.start.index !== range.end.index) {
|
|
342
275
|
const edit = blocks.withoutRange(range);
|
|
343
276
|
if (edit === undefined || !(edit.root instanceof BlocksNode))
|
|
344
277
|
return;
|
|
345
278
|
blocks = edit.root;
|
|
346
279
|
caret = edit.range.start;
|
|
347
280
|
}
|
|
348
|
-
|
|
349
281
|
// Find what block the caret is in.
|
|
350
|
-
const block = caret.node.getClosestParentOfType
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
);
|
|
354
|
-
|
|
355
|
-
if (block === undefined) return;
|
|
356
|
-
|
|
282
|
+
const block = caret.node.getClosestParentOfType(blocks, BlockNode);
|
|
283
|
+
if (block === undefined)
|
|
284
|
+
return;
|
|
357
285
|
// If it's a paragraph, split it.
|
|
358
286
|
if (block instanceof ParagraphNode) {
|
|
359
287
|
const paragraph = block;
|
|
360
288
|
// Split the paragraph in two.
|
|
361
289
|
const split = paragraph.split(caret);
|
|
362
|
-
if (split === undefined)
|
|
290
|
+
if (split === undefined)
|
|
291
|
+
return;
|
|
363
292
|
const [first, last] = split;
|
|
364
293
|
const newCaret = last.getFirstCaret();
|
|
365
|
-
if (newCaret === undefined)
|
|
366
|
-
|
|
294
|
+
if (newCaret === undefined)
|
|
295
|
+
return;
|
|
367
296
|
// Find the paragraph's blocks node.
|
|
368
297
|
const paragraphBlocks = paragraph.getParent(blocks);
|
|
369
|
-
if (!(paragraphBlocks instanceof BlocksNode))
|
|
370
|
-
|
|
298
|
+
if (!(paragraphBlocks instanceof BlocksNode))
|
|
299
|
+
return;
|
|
371
300
|
const newBlocks = paragraphBlocks
|
|
372
301
|
.withBlockInsertedBefore(paragraph, first)
|
|
373
302
|
?.withBlockInsertedAfter(paragraph, last)
|
|
374
303
|
?.withoutBlock(paragraph);
|
|
375
|
-
if (newBlocks === undefined)
|
|
376
|
-
|
|
304
|
+
if (newBlocks === undefined)
|
|
305
|
+
return;
|
|
377
306
|
// Replace the paragraphs blocks in these blocks.
|
|
378
307
|
const newRoot = blocks.withNodeReplaced(paragraphBlocks, newBlocks);
|
|
379
|
-
if (newRoot === undefined)
|
|
380
|
-
|
|
308
|
+
if (newRoot === undefined)
|
|
309
|
+
return;
|
|
381
310
|
return { root: newRoot, range: { start: newCaret, end: newCaret } };
|
|
382
311
|
}
|
|
383
312
|
// If any other kind of block, and an empty paragraph after the block.
|
|
384
313
|
else {
|
|
385
314
|
// Find the paragraph's blocks node.
|
|
386
315
|
const container = block.getParent(blocks);
|
|
387
|
-
if (!(container instanceof BlocksNode))
|
|
388
|
-
|
|
316
|
+
if (!(container instanceof BlocksNode))
|
|
317
|
+
return;
|
|
389
318
|
const newParagraph = new ParagraphNode();
|
|
390
319
|
const newCaret = newParagraph.getFirstCaret();
|
|
391
|
-
if (newCaret === undefined)
|
|
392
|
-
|
|
393
|
-
const newBlocks = container.withBlockInsertedAfter(
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
);
|
|
397
|
-
if (newBlocks === undefined) return;
|
|
398
|
-
|
|
320
|
+
if (newCaret === undefined)
|
|
321
|
+
return;
|
|
322
|
+
const newBlocks = container.withBlockInsertedAfter(block, newParagraph);
|
|
323
|
+
if (newBlocks === undefined)
|
|
324
|
+
return;
|
|
399
325
|
// Replace the paragraphs blocks in these blocks.
|
|
400
326
|
const newRoot = blocks.withNodeReplaced(container, newBlocks);
|
|
401
|
-
if (newRoot === undefined)
|
|
402
|
-
|
|
327
|
+
if (newRoot === undefined)
|
|
328
|
+
return;
|
|
403
329
|
return { root: newRoot, range: { start: newCaret, end: newCaret } };
|
|
404
330
|
}
|
|
405
331
|
}
|
|
406
|
-
|
|
407
|
-
withoutRange(range: CaretRange): Edit {
|
|
332
|
+
withoutRange(range) {
|
|
408
333
|
return this.withRangeFormatted(range, undefined);
|
|
409
334
|
}
|
|
410
|
-
|
|
411
|
-
withoutAtom(atom: AtomNode<any>): Edit {
|
|
335
|
+
withoutAtom(atom) {
|
|
412
336
|
// Find the format that contains the atom.
|
|
413
|
-
const format = atom.getFarthestParentMatching(
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
) as FormatNode | undefined;
|
|
417
|
-
if (format === undefined) return;
|
|
418
|
-
|
|
337
|
+
const format = atom.getFarthestParentMatching(this, (p) => p instanceof FormatNode);
|
|
338
|
+
if (format === undefined)
|
|
339
|
+
return;
|
|
419
340
|
// Find the text or atom node to the left and right of the atom to determine the new caret position.
|
|
420
341
|
const previous = format.getPreviousTextOrAtom(atom);
|
|
421
342
|
const next = format.getNextTextOrAtom(atom);
|
|
422
343
|
const newText = new TextNode();
|
|
423
|
-
|
|
424
344
|
// If the format is otherwise empty, replace the atom with an empty text node
|
|
425
|
-
const newFormat =
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
: format.withoutSegment(atom);
|
|
429
|
-
|
|
345
|
+
const newFormat = previous === undefined && next == undefined
|
|
346
|
+
? format.withSegmentReplaced(atom, newText)
|
|
347
|
+
: format.withoutSegment(atom);
|
|
430
348
|
// New caret is left, or right, or empty text.
|
|
431
349
|
const newCaret = {
|
|
432
350
|
node: previous ? previous : next ? next : newText,
|
|
433
|
-
index:
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
: 0,
|
|
351
|
+
index: previous && previous instanceof TextNode
|
|
352
|
+
? previous.getLength()
|
|
353
|
+
: 0,
|
|
437
354
|
};
|
|
438
|
-
|
|
439
355
|
// No format? Fail.
|
|
440
|
-
if (newFormat === undefined)
|
|
441
|
-
|
|
356
|
+
if (newFormat === undefined)
|
|
357
|
+
return;
|
|
442
358
|
// Create a new chapter with the revised format.
|
|
443
359
|
const newRoot = this.withNodeReplaced(format, newFormat);
|
|
444
|
-
if (newRoot === undefined)
|
|
445
|
-
|
|
360
|
+
if (newRoot === undefined)
|
|
361
|
+
return;
|
|
446
362
|
// Return the edited tree!
|
|
447
363
|
return { root: newRoot, range: { start: newCaret, end: newCaret } };
|
|
448
364
|
}
|
|
449
|
-
|
|
450
|
-
withRangeFormatted(range: CaretRange, format: Format | undefined): Edit {
|
|
365
|
+
withRangeFormatted(range, format) {
|
|
451
366
|
// Only works on text nodes, atom nodes, and metadata nodes.
|
|
452
|
-
if (
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
range.
|
|
456
|
-
) ||
|
|
457
|
-
!(
|
|
458
|
-
range.end.node instanceof TextNode ||
|
|
459
|
-
range.end.node instanceof AtomNode
|
|
460
|
-
)
|
|
461
|
-
)
|
|
367
|
+
if (!(range.start.node instanceof TextNode ||
|
|
368
|
+
range.start.node instanceof AtomNode) ||
|
|
369
|
+
!(range.end.node instanceof TextNode ||
|
|
370
|
+
range.end.node instanceof AtomNode))
|
|
462
371
|
return;
|
|
463
|
-
|
|
464
372
|
// Have we selected a single atom node for removal? Remove it and place the caret in the adjacent word.
|
|
465
|
-
if (
|
|
466
|
-
format === undefined &&
|
|
373
|
+
if (format === undefined &&
|
|
467
374
|
range.start.node instanceof AtomNode &&
|
|
468
375
|
range.end.node instanceof AtomNode &&
|
|
469
|
-
range.start.node === range.end.node
|
|
470
|
-
) {
|
|
376
|
+
range.start.node === range.end.node) {
|
|
471
377
|
return this.withoutAtom(range.start.node);
|
|
472
378
|
}
|
|
473
|
-
|
|
474
379
|
// Preserve the original range, since there are a few cases where we adjust it.
|
|
475
380
|
let adjustedRange = range;
|
|
476
|
-
|
|
477
381
|
// If this a single point in format, and we're clearing formatting, adjust the selection to the whole format.
|
|
478
|
-
if (
|
|
479
|
-
format === '' &&
|
|
382
|
+
if (format === '' &&
|
|
480
383
|
range.start.node === range.end.node &&
|
|
481
|
-
range.start.index === range.end.index
|
|
482
|
-
) {
|
|
384
|
+
range.start.index === range.end.index) {
|
|
483
385
|
const selection = range.start.node
|
|
484
386
|
.getFormatRoot(this)
|
|
485
387
|
?.getSelection();
|
|
486
|
-
if (selection === undefined)
|
|
388
|
+
if (selection === undefined)
|
|
389
|
+
return;
|
|
487
390
|
adjustedRange = selection;
|
|
488
391
|
}
|
|
489
|
-
|
|
490
392
|
// Sort the range if it's out of order, since the algorithm below assumes that it's ordered.
|
|
491
393
|
const sortedRange = this.sortRange(adjustedRange);
|
|
492
|
-
|
|
493
394
|
// Remember the start and end text index so we can map it back after editing.
|
|
494
395
|
const startTextIndex = caretToIndex(this, sortedRange.start);
|
|
495
396
|
const endTextIndex = caretToIndex(this, sortedRange.end);
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
397
|
+
if (startTextIndex === undefined || endTextIndex === undefined)
|
|
398
|
+
return;
|
|
499
399
|
// Ask all of the blocks to format themselves, replacing them as we do.
|
|
500
|
-
let newBlocks
|
|
501
|
-
let formattedBlocks
|
|
400
|
+
let newBlocks = this;
|
|
401
|
+
let formattedBlocks = [];
|
|
502
402
|
let inRange = false;
|
|
503
403
|
for (let i = 0; i < this.#blocks.length; i++) {
|
|
504
404
|
const block = this.#blocks[i];
|
|
@@ -513,321 +413,243 @@ export default abstract class BlocksNode extends BlockNode {
|
|
|
513
413
|
const blockEnd = containsEnd
|
|
514
414
|
? sortedRange.end
|
|
515
415
|
: block.getLastCaret();
|
|
516
|
-
if (blockStart === undefined || blockEnd === undefined)
|
|
517
|
-
|
|
416
|
+
if (blockStart === undefined || blockEnd === undefined)
|
|
417
|
+
return;
|
|
518
418
|
// If we're just going to delete it, then don't bother formatting it.
|
|
519
419
|
if (!containsStart && !containsEnd && format === undefined) {
|
|
520
420
|
newBlocks = newBlocks.withChildReplaced(block, undefined);
|
|
521
|
-
if (newBlocks === undefined)
|
|
421
|
+
if (newBlocks === undefined)
|
|
422
|
+
return;
|
|
522
423
|
}
|
|
523
424
|
// Otherwise, format it.
|
|
524
425
|
else {
|
|
525
|
-
const edit = block.withRangeFormatted(
|
|
526
|
-
{ start: blockStart, end: blockEnd },
|
|
527
|
-
format
|
|
528
|
-
);
|
|
529
|
-
|
|
426
|
+
const edit = block.withRangeFormatted({ start: blockStart, end: blockEnd }, format);
|
|
530
427
|
// If we failed to format it, remove it.
|
|
531
|
-
if (edit === undefined)
|
|
532
|
-
|
|
428
|
+
if (edit === undefined)
|
|
429
|
+
return;
|
|
533
430
|
// If we succeeded in formatting it, replace it, otherwise skip it.
|
|
534
|
-
let newBlock = edit.root
|
|
535
|
-
|
|
431
|
+
let newBlock = edit.root;
|
|
536
432
|
// Finally, if the selection started before a list node, and we were deleting in the middle of some item,
|
|
537
433
|
// convert that item (which should now be the first item in the list) into a paragraph, since it's bullet was deleted, conceptually.
|
|
538
|
-
if (
|
|
539
|
-
!newBlock.isEmpty() &&
|
|
434
|
+
if (!newBlock.isEmpty() &&
|
|
540
435
|
newBlock instanceof ListNode &&
|
|
541
436
|
!containsStart &&
|
|
542
|
-
containsEnd
|
|
543
|
-
) {
|
|
437
|
+
containsEnd) {
|
|
544
438
|
const firstItem = newBlock.getItem(0);
|
|
545
439
|
if (firstItem instanceof FormatNode) {
|
|
546
440
|
// Remove the item from the list.
|
|
547
|
-
const newListWithoutItem =
|
|
548
|
-
|
|
549
|
-
|
|
441
|
+
const newListWithoutItem = newBlock.withoutItem(firstItem);
|
|
442
|
+
if (newListWithoutItem === undefined)
|
|
443
|
+
return;
|
|
550
444
|
newBlock = newListWithoutItem;
|
|
551
|
-
|
|
552
445
|
// Replace the revised list
|
|
553
|
-
const blocksWithList
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
);
|
|
560
|
-
|
|
561
|
-
if (blocksWithList === undefined) return;
|
|
562
|
-
newBlocks = blocksWithList as this;
|
|
446
|
+
const blocksWithList = newBlocks
|
|
447
|
+
.withChildReplaced(block, newBlock)
|
|
448
|
+
?.withBlockInsertedBefore(newBlock, new ParagraphNode(0, firstItem));
|
|
449
|
+
if (blocksWithList === undefined)
|
|
450
|
+
return;
|
|
451
|
+
newBlocks = blocksWithList;
|
|
563
452
|
}
|
|
564
453
|
}
|
|
565
454
|
// Otherwise, just handle the new block in isolation.
|
|
566
455
|
else {
|
|
567
456
|
// Remember non-empty revised blocks so we can merge things after.
|
|
568
|
-
if (!newBlock.isEmpty())
|
|
569
|
-
|
|
457
|
+
if (!newBlock.isEmpty())
|
|
458
|
+
formattedBlocks.push(newBlock);
|
|
570
459
|
// Replace the block, or delete it if it's empty.
|
|
571
|
-
newBlocks = newBlocks.withChildReplaced(
|
|
572
|
-
block,
|
|
573
|
-
newBlock.isEmpty() ? undefined : newBlock
|
|
574
|
-
);
|
|
460
|
+
newBlocks = newBlocks.withChildReplaced(block, newBlock.isEmpty() ? undefined : newBlock);
|
|
575
461
|
}
|
|
576
|
-
|
|
577
462
|
// If we failed to replace it, bail.
|
|
578
|
-
if (newBlocks === undefined)
|
|
463
|
+
if (newBlocks === undefined)
|
|
464
|
+
return;
|
|
579
465
|
}
|
|
580
466
|
}
|
|
581
|
-
if (block.contains(sortedRange.end.node))
|
|
467
|
+
if (block.contains(sortedRange.end.node))
|
|
468
|
+
inRange = false;
|
|
582
469
|
}
|
|
583
|
-
|
|
584
470
|
// If we're deleting and there are two non-empty paragraphs left, merge them.
|
|
585
471
|
if (format === undefined && formattedBlocks.length >= 2) {
|
|
586
472
|
const first = formattedBlocks[0];
|
|
587
473
|
const last = formattedBlocks[formattedBlocks.length - 1];
|
|
588
|
-
if (
|
|
589
|
-
|
|
590
|
-
last instanceof ParagraphNode
|
|
591
|
-
) {
|
|
474
|
+
if (first instanceof ParagraphNode &&
|
|
475
|
+
last instanceof ParagraphNode) {
|
|
592
476
|
// Replace the first paragraph with the second merged.
|
|
593
|
-
newBlocks = newBlocks.withNodeReplaced(
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
first.getFormat().withSegmentsAppended(last.getFormat())
|
|
597
|
-
)
|
|
598
|
-
);
|
|
599
|
-
if (newBlocks === undefined) return;
|
|
477
|
+
newBlocks = newBlocks.withNodeReplaced(first, first.withContent(first.getFormat().withSegmentsAppended(last.getFormat())));
|
|
478
|
+
if (newBlocks === undefined)
|
|
479
|
+
return;
|
|
600
480
|
// Remove the last paragraph.
|
|
601
481
|
newBlocks = newBlocks.withNodeReplaced(last, undefined);
|
|
602
|
-
if (newBlocks === undefined)
|
|
482
|
+
if (newBlocks === undefined)
|
|
483
|
+
return;
|
|
603
484
|
}
|
|
604
485
|
}
|
|
605
|
-
|
|
606
486
|
const startCaret = indexToCaret(newBlocks, startTextIndex);
|
|
607
487
|
// If we deleted, then the end caret should be the same as the start.
|
|
608
|
-
const endCaret =
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
if (startCaret === undefined || endCaret === undefined) return;
|
|
614
|
-
|
|
488
|
+
const endCaret = format === undefined
|
|
489
|
+
? startCaret
|
|
490
|
+
: indexToCaret(newBlocks, endTextIndex);
|
|
491
|
+
if (startCaret === undefined || endCaret === undefined)
|
|
492
|
+
return;
|
|
615
493
|
// Return the new root and the start and end of the range.
|
|
616
494
|
return { root: newBlocks, range: { start: startCaret, end: endCaret } };
|
|
617
495
|
}
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
range: CaretRange,
|
|
621
|
-
nodeCreator: (text: string) => FormatNodeSegmentType
|
|
622
|
-
): Edit {
|
|
623
|
-
let blocks: BlocksNode = this;
|
|
496
|
+
withSegmentAtSelection(range, nodeCreator) {
|
|
497
|
+
let blocks = this;
|
|
624
498
|
let caret = range.start;
|
|
625
|
-
|
|
626
499
|
// Only works at a text node.
|
|
627
|
-
if (!(caret.node instanceof TextNode))
|
|
628
|
-
|
|
500
|
+
if (!(caret.node instanceof TextNode))
|
|
501
|
+
return;
|
|
629
502
|
// Get the nearest FormatNode parent of the selected text. Bail on fail.
|
|
630
|
-
const formatted = caret.node.getClosestParentOfType
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
);
|
|
634
|
-
if (formatted === undefined) return;
|
|
635
|
-
|
|
503
|
+
const formatted = caret.node.getClosestParentOfType(blocks, FormatNode);
|
|
504
|
+
if (formatted === undefined)
|
|
505
|
+
return;
|
|
636
506
|
// Update the format and replace it in the blocks.
|
|
637
507
|
const edit = formatted.withSegmentAtSelection(range, nodeCreator);
|
|
638
|
-
if (edit === undefined || !(edit.root instanceof FormatNode))
|
|
508
|
+
if (edit === undefined || !(edit.root instanceof FormatNode))
|
|
509
|
+
return;
|
|
639
510
|
const newBlocks = blocks.withNodeReplaced(formatted, edit.root);
|
|
640
|
-
if (newBlocks === undefined)
|
|
511
|
+
if (newBlocks === undefined)
|
|
512
|
+
return;
|
|
641
513
|
return { root: newBlocks, range: edit.range };
|
|
642
514
|
}
|
|
643
|
-
|
|
644
|
-
withParagraphsAsLists(
|
|
645
|
-
range: CaretRange,
|
|
646
|
-
numbered: boolean
|
|
647
|
-
): BlocksNode | undefined {
|
|
515
|
+
withParagraphsAsLists(range, numbered) {
|
|
648
516
|
const sortedRange = this.sortRange(range);
|
|
649
517
|
const blocksInRange = this.getBlocksInRange(sortedRange);
|
|
650
|
-
if (blocksInRange === undefined)
|
|
518
|
+
if (blocksInRange === undefined)
|
|
519
|
+
return;
|
|
651
520
|
// Only format if every block selected is a paragraph node. Non-paragraphs can't be in lists.
|
|
652
|
-
if (!blocksInRange.every((b) => b instanceof ParagraphNode))
|
|
653
|
-
|
|
521
|
+
if (!blocksInRange.every((b) => b instanceof ParagraphNode))
|
|
522
|
+
return;
|
|
654
523
|
// Split the blocks into groups with shared parents.
|
|
655
|
-
const sequences
|
|
656
|
-
let previous
|
|
524
|
+
const sequences = [[]];
|
|
525
|
+
let previous = undefined;
|
|
657
526
|
blocksInRange.forEach((block) => {
|
|
658
|
-
if (
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
)
|
|
662
|
-
sequences[sequences.length - 1].push(block as ParagraphNode);
|
|
527
|
+
if (previous === undefined ||
|
|
528
|
+
block.getParent(this) === previous.getParent(this))
|
|
529
|
+
sequences[sequences.length - 1].push(block);
|
|
663
530
|
else {
|
|
664
|
-
sequences.push([block
|
|
531
|
+
sequences.push([block]);
|
|
665
532
|
}
|
|
666
|
-
previous = block
|
|
533
|
+
previous = block;
|
|
667
534
|
});
|
|
668
|
-
|
|
669
535
|
// For each sequence, create a list of all of the paragraphs in it.
|
|
670
|
-
let newBlocks
|
|
536
|
+
let newBlocks = this;
|
|
671
537
|
for (let i = 0; i < sequences.length; i++) {
|
|
672
538
|
const sequence = sequences[i];
|
|
673
539
|
// Make the new list
|
|
674
|
-
const newList = new ListNode(
|
|
675
|
-
sequence.map((p) => p.getFormat()),
|
|
676
|
-
numbered
|
|
677
|
-
);
|
|
540
|
+
const newList = new ListNode(sequence.map((p) => p.getFormat()), numbered);
|
|
678
541
|
// Insert the new list
|
|
679
|
-
const blocksParent
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
let newSequenceBlocks = blocksParent.withBlockInsertedBefore(
|
|
684
|
-
sequence[0],
|
|
685
|
-
newList
|
|
686
|
-
);
|
|
542
|
+
const blocksParent = sequence[0].getParent(newBlocks);
|
|
543
|
+
if (blocksParent === undefined)
|
|
544
|
+
return;
|
|
545
|
+
let newSequenceBlocks = blocksParent.withBlockInsertedBefore(sequence[0], newList);
|
|
687
546
|
// Remove all of the old paragraphs
|
|
688
547
|
for (let j = 0; j < sequence.length; j++) {
|
|
689
|
-
newSequenceBlocks = newSequenceBlocks?.withoutBlock(
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
if (newSequenceBlocks === undefined) return;
|
|
548
|
+
newSequenceBlocks = newSequenceBlocks?.withoutBlock(sequence[j]);
|
|
549
|
+
if (newSequenceBlocks === undefined)
|
|
550
|
+
return;
|
|
693
551
|
}
|
|
694
552
|
// Replace the blocks parent with the new blocks.
|
|
695
|
-
const newRoot = newBlocks.withNodeReplaced(
|
|
696
|
-
blocksParent,
|
|
697
|
-
newSequenceBlocks
|
|
698
|
-
);
|
|
553
|
+
const newRoot = newBlocks.withNodeReplaced(blocksParent, newSequenceBlocks);
|
|
699
554
|
if (newRoot === undefined || !(newRoot instanceof BlocksNode))
|
|
700
555
|
return;
|
|
701
556
|
newBlocks = newRoot;
|
|
702
557
|
}
|
|
703
|
-
|
|
704
558
|
return newBlocks;
|
|
705
559
|
}
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
let newBlocks: BlocksNode = this;
|
|
560
|
+
withListsAsParagraphs(range) {
|
|
561
|
+
let newBlocks = this;
|
|
709
562
|
const sortedRange = this.sortRange(range);
|
|
710
563
|
const blocksInRange = this.getBlocksInRange(sortedRange);
|
|
711
|
-
if (blocksInRange === undefined)
|
|
564
|
+
if (blocksInRange === undefined)
|
|
565
|
+
return;
|
|
712
566
|
// Convert all of the lists into their root lists, since we only convert entire lists, not parts of lists.
|
|
713
567
|
const listsInRange = blocksInRange.filter((l) => l instanceof ListNode);
|
|
714
568
|
const listRootsInRange = [
|
|
715
|
-
...new Set(
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
: l
|
|
724
|
-
)
|
|
725
|
-
.filter((n) => n !== undefined)
|
|
726
|
-
),
|
|
727
|
-
] as ListNode[];
|
|
728
|
-
if (listRootsInRange.length === 0) return undefined;
|
|
729
|
-
|
|
569
|
+
...new Set(listsInRange
|
|
570
|
+
.map((l) => l.getParent(this) instanceof ListNode
|
|
571
|
+
? l.getFarthestParentMatching(this, (m) => m instanceof ListNode)
|
|
572
|
+
: l)
|
|
573
|
+
.filter((n) => n !== undefined)),
|
|
574
|
+
];
|
|
575
|
+
if (listRootsInRange.length === 0)
|
|
576
|
+
return undefined;
|
|
730
577
|
// For each list in the range, convert all items in range to paragraphs.
|
|
731
578
|
for (let i = 0; i < listRootsInRange.length; i++) {
|
|
732
579
|
const list = listRootsInRange[i];
|
|
733
580
|
const paragraphs = list
|
|
734
581
|
.getNodes()
|
|
735
582
|
.filter((n) => n instanceof FormatNode)
|
|
736
|
-
.map(
|
|
737
|
-
(f) => new ParagraphNode(0, f as FormatNode)
|
|
738
|
-
) as ParagraphNode[];
|
|
583
|
+
.map((f) => new ParagraphNode(0, f));
|
|
739
584
|
// Insert in reverse order to keep them in order, since the list is our anchor.
|
|
740
585
|
for (let j = paragraphs.length - 1; j >= 0; j--) {
|
|
741
586
|
const paragraph = paragraphs[j];
|
|
742
|
-
const insertedBlocks = newBlocks.withBlockInsertedAfter(
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
);
|
|
746
|
-
if (insertedBlocks === undefined) return;
|
|
587
|
+
const insertedBlocks = newBlocks.withBlockInsertedAfter(list, paragraph);
|
|
588
|
+
if (insertedBlocks === undefined)
|
|
589
|
+
return;
|
|
747
590
|
newBlocks = insertedBlocks;
|
|
748
591
|
}
|
|
749
592
|
const withoutList = newBlocks.withoutBlock(list);
|
|
750
|
-
if (withoutList === undefined)
|
|
593
|
+
if (withoutList === undefined)
|
|
594
|
+
return;
|
|
751
595
|
newBlocks = withoutList;
|
|
752
596
|
}
|
|
753
|
-
|
|
754
597
|
return newBlocks;
|
|
755
598
|
}
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
range: CaretRange,
|
|
759
|
-
indent: boolean
|
|
760
|
-
): BlocksNode | undefined {
|
|
761
|
-
let newBlocks: BlocksNode = this;
|
|
762
|
-
|
|
599
|
+
withListsIndented(range, indent) {
|
|
600
|
+
let newBlocks = this;
|
|
763
601
|
// Find all of the formats in list nodes in the range and indent them.
|
|
764
|
-
const ancestor = range.start.node.getCommonAncestor(
|
|
765
|
-
newBlocks,
|
|
766
|
-
range.end.node
|
|
767
|
-
);
|
|
602
|
+
const ancestor = range.start.node.getCommonAncestor(newBlocks, range.end.node);
|
|
768
603
|
const nodes = ancestor?.getNodes();
|
|
769
|
-
const formats = nodes?.filter(
|
|
770
|
-
(n)
|
|
771
|
-
n instanceof FormatNode &&
|
|
772
|
-
newBlocks.getParentOf(n) instanceof ListNode
|
|
773
|
-
) as FormatNode[];
|
|
604
|
+
const formats = nodes?.filter((n) => n instanceof FormatNode &&
|
|
605
|
+
newBlocks.getParentOf(n) instanceof ListNode);
|
|
774
606
|
const startIndex = nodes?.indexOf(range.start.node);
|
|
775
607
|
const endIndex = nodes?.indexOf(range.end.node);
|
|
776
|
-
|
|
777
|
-
if (
|
|
778
|
-
formats === undefined ||
|
|
608
|
+
if (formats === undefined ||
|
|
779
609
|
startIndex === undefined ||
|
|
780
|
-
endIndex === undefined
|
|
781
|
-
)
|
|
610
|
+
endIndex === undefined)
|
|
782
611
|
return;
|
|
783
|
-
|
|
784
612
|
// Loop through the formats in the range and indent or dedent them, constructing a new root.
|
|
785
613
|
const first = startIndex < endIndex ? range.start.node : range.end.node;
|
|
786
614
|
const last = startIndex < endIndex ? range.end.node : range.start.node;
|
|
787
615
|
let inside = false;
|
|
788
616
|
for (let i = 0; i < formats.length; i++) {
|
|
789
617
|
const format = formats[i];
|
|
790
|
-
if (first.hasAncestor(newBlocks, format))
|
|
618
|
+
if (first.hasAncestor(newBlocks, format))
|
|
619
|
+
inside = true;
|
|
791
620
|
// If we're in the selection and the format is in a list, restructure it's list to indent/unindent it.
|
|
792
621
|
if (inside) {
|
|
793
622
|
// Find the root list node of the format.
|
|
794
|
-
const list = format.getFarthestParentMatching(
|
|
795
|
-
newBlocks,
|
|
796
|
-
(n) => n instanceof ListNode
|
|
797
|
-
);
|
|
623
|
+
const list = format.getFarthestParentMatching(newBlocks, (n) => n instanceof ListNode);
|
|
798
624
|
if (list instanceof ListNode) {
|
|
799
625
|
const newList = indent
|
|
800
626
|
? list.withItemIndented(format)
|
|
801
627
|
: list.withItemUnindented(format);
|
|
802
|
-
if (newList === undefined)
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
if (blocksWithIndent === undefined) return;
|
|
628
|
+
if (newList === undefined)
|
|
629
|
+
return;
|
|
630
|
+
const blocksWithIndent = newBlocks.withChildReplaced(list, newList);
|
|
631
|
+
if (blocksWithIndent === undefined)
|
|
632
|
+
return;
|
|
808
633
|
newBlocks = blocksWithIndent;
|
|
809
634
|
}
|
|
810
635
|
}
|
|
811
|
-
if (last.hasAncestor(newBlocks, format))
|
|
636
|
+
if (last.hasAncestor(newBlocks, format))
|
|
637
|
+
inside = false;
|
|
812
638
|
}
|
|
813
|
-
|
|
814
639
|
// We shouldn't need to update the range because we haven't modified the text nodes, just their position.
|
|
815
640
|
return newBlocks;
|
|
816
641
|
}
|
|
817
|
-
|
|
818
642
|
// This accounts for adjascent lists that end up with the same style.
|
|
819
|
-
withListAsStyle(list
|
|
643
|
+
withListAsStyle(list, numbered) {
|
|
820
644
|
return this.withNodeReplaced(list, list.withStyle(numbered));
|
|
821
645
|
}
|
|
822
|
-
|
|
823
646
|
// Removes the character before or after the current caret
|
|
824
|
-
withoutAdjacentContent(caret
|
|
647
|
+
withoutAdjacentContent(caret, next) {
|
|
825
648
|
// Confirm that this caret is in this tree. Bail on fail.
|
|
826
|
-
if (!this.contains(caret.node))
|
|
827
|
-
|
|
649
|
+
if (!this.contains(caret.node))
|
|
650
|
+
return;
|
|
828
651
|
// Find the parents of the node.
|
|
829
652
|
const parents = this.getParentsOf(caret.node);
|
|
830
|
-
|
|
831
653
|
// Iterate through the ancestors, seeing if they'd like to handle the request for a deletion.
|
|
832
654
|
while (parents && parents.length > 0) {
|
|
833
655
|
const parent = parents.pop();
|
|
@@ -836,11 +658,9 @@ export default abstract class BlocksNode extends BlockNode {
|
|
|
836
658
|
const editedFormat = parent.withoutCharacter(caret, next);
|
|
837
659
|
// If it failed, let a parent try. Otherwise, just update the format.
|
|
838
660
|
if (editedFormat !== undefined) {
|
|
839
|
-
const newBlocks = this.withNodeReplaced(
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
);
|
|
843
|
-
if (newBlocks === undefined) return;
|
|
661
|
+
const newBlocks = this.withNodeReplaced(parent, editedFormat.root);
|
|
662
|
+
if (newBlocks === undefined)
|
|
663
|
+
return;
|
|
844
664
|
return { root: newBlocks, range: editedFormat.range };
|
|
845
665
|
}
|
|
846
666
|
}
|
|
@@ -853,16 +673,12 @@ export default abstract class BlocksNode extends BlockNode {
|
|
|
853
673
|
index: caret.index + (next ? 1 : -1),
|
|
854
674
|
},
|
|
855
675
|
});
|
|
856
|
-
if (revisedCode === undefined)
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
const newBlocks = this.withNodeReplaced(
|
|
863
|
-
parent,
|
|
864
|
-
revisedCodeNode
|
|
865
|
-
);
|
|
676
|
+
if (revisedCode === undefined)
|
|
677
|
+
return;
|
|
678
|
+
const revisedCodeNode = parent.withChildReplaced(parent.getCodeNode(), revisedCode);
|
|
679
|
+
if (revisedCodeNode === undefined)
|
|
680
|
+
return;
|
|
681
|
+
const newBlocks = this.withNodeReplaced(parent, revisedCodeNode);
|
|
866
682
|
const newCaret = {
|
|
867
683
|
node: revisedCode,
|
|
868
684
|
index: Math.max(0, caret.index + (next ? 0 : -1)),
|
|
@@ -870,38 +686,37 @@ export default abstract class BlocksNode extends BlockNode {
|
|
|
870
686
|
return newBlocks === undefined
|
|
871
687
|
? undefined
|
|
872
688
|
: {
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
689
|
+
root: newBlocks,
|
|
690
|
+
range: { start: newCaret, end: newCaret },
|
|
691
|
+
};
|
|
876
692
|
}
|
|
877
693
|
// If it's a format in the list node, merge with the previous list item
|
|
878
694
|
else if (parent instanceof ListNode) {
|
|
879
695
|
const index = parent.getItemContaining(caret);
|
|
880
|
-
if (index === undefined)
|
|
696
|
+
if (index === undefined)
|
|
697
|
+
break;
|
|
881
698
|
// Merge the item backwards.
|
|
882
699
|
if (parent.getLength() > 1) {
|
|
883
700
|
const edit = parent.withItemMergedBackwards(index);
|
|
884
|
-
if (edit === undefined)
|
|
701
|
+
if (edit === undefined)
|
|
702
|
+
return;
|
|
885
703
|
const [newList, newCaret] = edit;
|
|
886
704
|
const newBlocks = this.withNodeReplaced(parent, newList);
|
|
887
|
-
if (newBlocks === undefined)
|
|
705
|
+
if (newBlocks === undefined)
|
|
706
|
+
return;
|
|
888
707
|
return {
|
|
889
708
|
root: newBlocks,
|
|
890
709
|
range: { start: newCaret, end: newCaret },
|
|
891
710
|
};
|
|
892
711
|
}
|
|
893
712
|
// Convert the remaining list item into a paragraph.
|
|
894
|
-
else if (
|
|
895
|
-
parents.length
|
|
896
|
-
parents[parents.length - 1] instanceof BlocksNode
|
|
897
|
-
) {
|
|
713
|
+
else if (parents.length > 0 &&
|
|
714
|
+
parents[parents.length - 1] instanceof BlocksNode) {
|
|
898
715
|
const item = parent.getItem(0);
|
|
899
|
-
if (!(item instanceof FormatNode))
|
|
716
|
+
if (!(item instanceof FormatNode))
|
|
717
|
+
return;
|
|
900
718
|
const newParagraph = new ParagraphNode(0, item);
|
|
901
|
-
const newBlocks = this.withNodeReplaced(
|
|
902
|
-
parent,
|
|
903
|
-
newParagraph
|
|
904
|
-
);
|
|
719
|
+
const newBlocks = this.withNodeReplaced(parent, newParagraph);
|
|
905
720
|
const newCaret = newParagraph.getFirstCaret();
|
|
906
721
|
if (newBlocks === undefined || newCaret === undefined)
|
|
907
722
|
return;
|
|
@@ -916,49 +731,41 @@ export default abstract class BlocksNode extends BlockNode {
|
|
|
916
731
|
const firstCaret = next
|
|
917
732
|
? parent.getLastCaret()
|
|
918
733
|
: parent.getFirstCaret();
|
|
919
|
-
if (firstCaret === undefined)
|
|
920
|
-
|
|
734
|
+
if (firstCaret === undefined)
|
|
735
|
+
return;
|
|
736
|
+
const blocks = parents[parents.length - 1];
|
|
921
737
|
const adjacentBlock = next
|
|
922
738
|
? blocks.getBlockAfter(parent)
|
|
923
739
|
: blocks.getBlockBefore(parent);
|
|
924
740
|
// Is this the first/last caret of the paragraph and there's an adjascent block? Try deleting something.
|
|
925
|
-
if (
|
|
926
|
-
firstCaret.node === caret.node &&
|
|
741
|
+
if (firstCaret.node === caret.node &&
|
|
927
742
|
firstCaret.index === caret.index &&
|
|
928
|
-
adjacentBlock !== undefined
|
|
929
|
-
) {
|
|
743
|
+
adjacentBlock !== undefined) {
|
|
930
744
|
// If the block adjacent this paragraph is a paragraph, merge the paragraph into the adjacent paragraph.
|
|
931
745
|
if (adjacentBlock instanceof ParagraphNode) {
|
|
932
746
|
const currentCaret = next
|
|
933
747
|
? parent.getLastCaret()
|
|
934
748
|
: adjacentBlock.getLastCaret();
|
|
935
|
-
if (currentCaret === undefined)
|
|
749
|
+
if (currentCaret === undefined)
|
|
750
|
+
return;
|
|
936
751
|
const textIndex = next
|
|
937
752
|
? caretToIndex(parent.getFormat(), currentCaret)
|
|
938
|
-
: caretToIndex(
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
);
|
|
942
|
-
if (textIndex === undefined) return;
|
|
753
|
+
: caretToIndex(adjacentBlock.getFormat(), currentCaret);
|
|
754
|
+
if (textIndex === undefined)
|
|
755
|
+
return;
|
|
943
756
|
const mergedParagraph = next
|
|
944
757
|
? adjacentBlock.withParagraphPrepended(parent)
|
|
945
758
|
: adjacentBlock.withParagraphAppended(parent);
|
|
946
|
-
if (mergedParagraph === undefined)
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
if (newBlocks === undefined) return;
|
|
957
|
-
const newCaret = indexToCaret(
|
|
958
|
-
mergedParagraph.getFormat(),
|
|
959
|
-
textIndex
|
|
960
|
-
);
|
|
961
|
-
if (newCaret === undefined) return;
|
|
759
|
+
if (mergedParagraph === undefined)
|
|
760
|
+
return;
|
|
761
|
+
const newBlocks = this.withNodeReplaced(blocks, blocks
|
|
762
|
+
.withChildReplaced(adjacentBlock, mergedParagraph)
|
|
763
|
+
?.withoutBlock(parent));
|
|
764
|
+
if (newBlocks === undefined)
|
|
765
|
+
return;
|
|
766
|
+
const newCaret = indexToCaret(mergedParagraph.getFormat(), textIndex);
|
|
767
|
+
if (newCaret === undefined)
|
|
768
|
+
return;
|
|
962
769
|
return {
|
|
963
770
|
root: newBlocks,
|
|
964
771
|
range: { start: newCaret, end: newCaret },
|
|
@@ -970,15 +777,14 @@ export default abstract class BlocksNode extends BlockNode {
|
|
|
970
777
|
if (next) {
|
|
971
778
|
const format = adjacentBlock.getFirstItem();
|
|
972
779
|
if (format !== undefined) {
|
|
973
|
-
const newParagraph = parent.withContent(
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
.withSegmentsAppended(format)
|
|
977
|
-
);
|
|
780
|
+
const newParagraph = parent.withContent(parent
|
|
781
|
+
.getFormat()
|
|
782
|
+
.withSegmentsAppended(format));
|
|
978
783
|
const newBlocks = blocks
|
|
979
784
|
.withNodeReplaced(parent, newParagraph)
|
|
980
785
|
?.withNodeReplaced(format, undefined);
|
|
981
|
-
if (newBlocks === undefined)
|
|
786
|
+
if (newBlocks === undefined)
|
|
787
|
+
return;
|
|
982
788
|
return {
|
|
983
789
|
root: newBlocks,
|
|
984
790
|
range: { start: caret, end: caret },
|
|
@@ -990,19 +796,15 @@ export default abstract class BlocksNode extends BlockNode {
|
|
|
990
796
|
else {
|
|
991
797
|
const format = adjacentBlock.getLastItem();
|
|
992
798
|
if (format !== undefined) {
|
|
993
|
-
const newFormat = format.withSegmentAppended(
|
|
994
|
-
parent.getFormat()
|
|
995
|
-
);
|
|
799
|
+
const newFormat = format.withSegmentAppended(parent.getFormat());
|
|
996
800
|
const newBlocks = blocks
|
|
997
801
|
.withNodeReplaced(format, newFormat)
|
|
998
802
|
?.withoutBlock(parent);
|
|
999
803
|
const newCaret = parent
|
|
1000
804
|
.getFormat()
|
|
1001
805
|
.getFirstCaret();
|
|
1002
|
-
if (
|
|
1003
|
-
|
|
1004
|
-
newCaret === undefined
|
|
1005
|
-
)
|
|
806
|
+
if (newBlocks === undefined ||
|
|
807
|
+
newCaret === undefined)
|
|
1006
808
|
return;
|
|
1007
809
|
return {
|
|
1008
810
|
root: newBlocks,
|
|
@@ -1013,62 +815,56 @@ export default abstract class BlocksNode extends BlockNode {
|
|
|
1013
815
|
}
|
|
1014
816
|
// Otherwise, return a root without the previous block, deleting it.
|
|
1015
817
|
else {
|
|
1016
|
-
const newBlocks = this.withNodeReplaced(
|
|
1017
|
-
blocks,
|
|
1018
|
-
blocks.withoutBlock(adjacentBlock)
|
|
1019
|
-
);
|
|
818
|
+
const newBlocks = this.withNodeReplaced(blocks, blocks.withoutBlock(adjacentBlock));
|
|
1020
819
|
return newBlocks === undefined
|
|
1021
820
|
? undefined
|
|
1022
821
|
: {
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
822
|
+
root: newBlocks,
|
|
823
|
+
range: { start: caret, end: caret },
|
|
824
|
+
};
|
|
1026
825
|
}
|
|
1027
826
|
}
|
|
1028
827
|
}
|
|
1029
828
|
}
|
|
1030
829
|
// No parent could handle it. Fail!
|
|
1031
830
|
}
|
|
1032
|
-
|
|
1033
|
-
withNodeInserted(caret: Caret, node: Node): Edit {
|
|
831
|
+
withNodeInserted(caret, node) {
|
|
1034
832
|
// The caret's node must be in this tree.
|
|
1035
|
-
if (!this.contains(caret.node))
|
|
833
|
+
if (!this.contains(caret.node))
|
|
834
|
+
return;
|
|
1036
835
|
// Get the blocks to insert.
|
|
1037
|
-
const blocks =
|
|
1038
|
-
node
|
|
1039
|
-
|
|
1040
|
-
: node instanceof BlockNode
|
|
836
|
+
const blocks = node instanceof BlocksNode
|
|
837
|
+
? node.getBlocks()
|
|
838
|
+
: node instanceof BlockNode
|
|
1041
839
|
? [node]
|
|
1042
840
|
: [];
|
|
1043
841
|
// If there are none, do nothing.
|
|
1044
|
-
if (blocks.length === 0)
|
|
842
|
+
if (blocks.length === 0)
|
|
843
|
+
return;
|
|
1045
844
|
// Find the block in this blocks node that contains the caret.
|
|
1046
845
|
const anchor = this.#blocks.find((b) => b.contains(caret.node));
|
|
1047
|
-
if (anchor === undefined)
|
|
1048
|
-
|
|
846
|
+
if (anchor === undefined)
|
|
847
|
+
return;
|
|
1049
848
|
let lastInsert = anchor;
|
|
1050
|
-
let newBlocks
|
|
849
|
+
let newBlocks = this;
|
|
1051
850
|
while (blocks.length > 0) {
|
|
1052
851
|
// Get the block to insert
|
|
1053
852
|
let newBlock = blocks.shift();
|
|
1054
|
-
if (newBlock === undefined)
|
|
1055
|
-
|
|
853
|
+
if (newBlock === undefined)
|
|
854
|
+
return;
|
|
1056
855
|
// If we're inserting after the anchor and the anchor is a paragraph and the block to insert is a paragraph, merge them.
|
|
1057
|
-
if (
|
|
1058
|
-
lastInsert === anchor &&
|
|
856
|
+
if (lastInsert === anchor &&
|
|
1059
857
|
anchor instanceof ParagraphNode &&
|
|
1060
|
-
newBlock instanceof ParagraphNode
|
|
1061
|
-
) {
|
|
858
|
+
newBlock instanceof ParagraphNode) {
|
|
1062
859
|
newBlock = anchor.withParagraphAppended(newBlock);
|
|
1063
|
-
if (newBlock === undefined)
|
|
860
|
+
if (newBlock === undefined)
|
|
861
|
+
return;
|
|
1064
862
|
newBlocks = newBlocks.withChildReplaced(anchor, newBlock);
|
|
1065
863
|
}
|
|
1066
864
|
// If we're inserting after the anchor and the anchor is a list and the block to insert is a list, merge them.
|
|
1067
|
-
else if (
|
|
1068
|
-
lastInsert === anchor &&
|
|
865
|
+
else if (lastInsert === anchor &&
|
|
1069
866
|
anchor instanceof ListNode &&
|
|
1070
|
-
newBlock instanceof ListNode
|
|
1071
|
-
) {
|
|
867
|
+
newBlock instanceof ListNode) {
|
|
1072
868
|
const edit = anchor.withNodeInserted(caret, newBlock);
|
|
1073
869
|
if (edit === undefined || !(edit.root instanceof BlockNode))
|
|
1074
870
|
return;
|
|
@@ -1077,39 +873,31 @@ export default abstract class BlocksNode extends BlockNode {
|
|
|
1077
873
|
}
|
|
1078
874
|
// Otherwise just insert the block after the last insert, including if it was the anchor block.
|
|
1079
875
|
else {
|
|
1080
|
-
newBlocks = newBlocks.withBlockInsertedAfter(
|
|
1081
|
-
lastInsert,
|
|
1082
|
-
newBlock
|
|
1083
|
-
);
|
|
876
|
+
newBlocks = newBlocks.withBlockInsertedAfter(lastInsert, newBlock);
|
|
1084
877
|
}
|
|
1085
878
|
// Bail on fail.
|
|
1086
|
-
if (newBlocks === undefined)
|
|
879
|
+
if (newBlocks === undefined)
|
|
880
|
+
return;
|
|
1087
881
|
// Remember what we inserted so we can insert after it.
|
|
1088
882
|
lastInsert = newBlock;
|
|
1089
883
|
}
|
|
1090
|
-
|
|
1091
884
|
// Set the caret to the last caret of the last insert, and if there isn't one, insert an empty paragraph so we can.
|
|
1092
885
|
const formats = lastInsert.getFormats();
|
|
1093
886
|
let newCaret = undefined;
|
|
1094
887
|
if (formats.length === 0) {
|
|
1095
|
-
const newParagraph = new ParagraphNode(
|
|
1096
|
-
0,
|
|
1097
|
-
new FormatNode('', [new TextNode()])
|
|
1098
|
-
);
|
|
888
|
+
const newParagraph = new ParagraphNode(0, new FormatNode('', [new TextNode()]));
|
|
1099
889
|
newCaret = newParagraph.getFirstCaret();
|
|
1100
|
-
newBlocks = newBlocks.withBlockInsertedAfter(
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
} else {
|
|
890
|
+
newBlocks = newBlocks.withBlockInsertedAfter(lastInsert, newParagraph);
|
|
891
|
+
if (newCaret === undefined || newBlocks === undefined)
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
894
|
+
else {
|
|
1106
895
|
newCaret = formats[formats.length - 1].getLastCaret();
|
|
1107
|
-
if (newCaret === undefined)
|
|
896
|
+
if (newCaret === undefined)
|
|
897
|
+
return;
|
|
1108
898
|
}
|
|
1109
|
-
|
|
1110
899
|
return { root: newBlocks, range: { start: newCaret, end: newCaret } };
|
|
1111
900
|
}
|
|
1112
|
-
|
|
1113
901
|
toHTML() {
|
|
1114
902
|
return this.#blocks.map((b) => b.toHTML()).join('');
|
|
1115
903
|
}
|