bookish-press 0.4.1 → 0.4.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/components/Auth.svelte +19 -14
- package/components/Auth.svelte.d.ts +4 -4
- package/components/Authentication.d.ts +2 -2
- package/components/BookPreview.svelte +77 -59
- package/components/BookPreview.svelte.d.ts +5 -5
- package/components/External.svelte +1 -1
- package/components/External.svelte.d.ts +3 -3
- package/components/Link.svelte +49 -3
- package/components/Link.svelte.d.ts +3 -4
- package/components/app/BookList.svelte +19 -0
- package/components/app/BookList.svelte.d.ts +18 -0
- package/components/app/Button.svelte +49 -0
- package/components/app/Button.svelte.d.ts +22 -0
- package/components/app/Feedback.svelte +45 -0
- package/components/app/Feedback.svelte.d.ts +18 -0
- package/components/app/Head.svelte +12 -0
- package/components/app/Head.svelte.d.ts +27 -0
- package/components/app/Large.svelte +8 -0
- package/components/app/Large.svelte.d.ts +27 -0
- package/components/app/Lead.svelte +12 -0
- package/components/app/Lead.svelte.d.ts +27 -0
- package/components/app/Link.svelte +24 -0
- package/components/app/Link.svelte.d.ts +20 -0
- package/components/app/Options.svelte +24 -0
- package/components/app/Options.svelte.d.ts +19 -0
- package/components/app/Paragraph.svelte +19 -0
- package/components/app/Paragraph.svelte.d.ts +18 -0
- package/components/app/Table.svelte +32 -0
- package/components/app/Table.svelte.d.ts +27 -0
- package/components/app/TextInput.svelte +37 -0
- package/components/app/TextInput.svelte.d.ts +22 -0
- package/components/app/Writing.svelte +13 -0
- package/components/app/Writing.svelte.d.ts +27 -0
- package/components/chapter/Atom.svelte +20 -6
- package/components/chapter/Atom.svelte.d.ts +3 -3
- package/components/chapter/Block.svelte +23 -20
- package/components/chapter/Block.svelte.d.ts +4 -4
- package/components/chapter/Callout.svelte +38 -7
- package/components/chapter/Callout.svelte.d.ts +4 -4
- package/components/chapter/CaptionedCode.svelte +66 -23
- package/components/chapter/CaptionedCode.svelte.d.ts +4 -4
- package/components/chapter/ChapterBody.svelte +61 -9
- package/components/chapter/ChapterBody.svelte.d.ts +4 -4
- package/components/chapter/Citations.svelte +86 -20
- package/components/chapter/Citations.svelte.d.ts +4 -4
- package/components/chapter/Code.svelte +152 -21
- package/components/chapter/Code.svelte.d.ts +3 -3
- package/components/chapter/Comment.svelte +38 -16
- package/components/chapter/Comment.svelte.d.ts +3 -3
- package/components/chapter/Definition.svelte +52 -18
- package/components/chapter/Definition.svelte.d.ts +5 -8
- package/components/chapter/Embed.svelte +154 -66
- package/components/chapter/Embed.svelte.d.ts +5 -4
- package/components/chapter/ErrorMessage.svelte +7 -2
- package/components/chapter/ErrorMessage.svelte.d.ts +4 -4
- package/components/chapter/ExtendedPrism.d.ts +2 -0
- package/components/chapter/ExtendedPrism.js +69 -0
- package/components/chapter/Figure.svelte +90 -0
- package/components/chapter/Figure.svelte.d.ts +24 -0
- package/components/chapter/Footnote.svelte +75 -12
- package/components/chapter/Footnote.svelte.d.ts +4 -4
- package/components/chapter/Format.svelte +60 -37
- package/components/chapter/Format.svelte.d.ts +4 -4
- package/components/chapter/InlineCode.svelte +15 -5
- package/components/chapter/InlineCode.svelte.d.ts +4 -4
- package/components/chapter/Label.svelte +37 -8
- package/components/chapter/Label.svelte.d.ts +4 -4
- package/components/chapter/Link.svelte +23 -18
- package/components/chapter/Link.svelte.d.ts +4 -4
- package/components/chapter/List.svelte +75 -8
- package/components/chapter/List.svelte.d.ts +4 -4
- package/components/chapter/Marginal.svelte +169 -27
- package/components/chapter/Marginal.svelte.d.ts +6 -3
- package/components/chapter/Paragraph.svelte +74 -6
- package/components/chapter/Paragraph.svelte.d.ts +4 -4
- package/components/chapter/Positioned.svelte +33 -0
- package/components/chapter/Positioned.svelte.d.ts +19 -0
- package/components/chapter/Problem.svelte +15 -0
- package/components/chapter/Problem.svelte.d.ts +27 -0
- package/components/chapter/Python.svelte +68 -21
- package/components/chapter/Python.svelte.d.ts +4 -4
- package/components/chapter/Quote.svelte +64 -11
- package/components/chapter/Quote.svelte.d.ts +4 -4
- package/components/chapter/Rule.svelte +12 -1
- package/components/chapter/Rule.svelte.d.ts +4 -4
- package/components/chapter/Table.svelte +36 -25
- package/components/chapter/Table.svelte.d.ts +4 -4
- package/components/chapter/Text.svelte +61 -36
- package/components/chapter/Text.svelte.d.ts +5 -4
- package/components/editor/BookishEditor.svelte +343 -237
- package/components/editor/BookishEditor.svelte.d.ts +5 -5
- package/components/editor/CalloutEditor.svelte +5 -5
- package/components/editor/CalloutEditor.svelte.d.ts +4 -4
- package/components/editor/CaptionedCodeEditor.svelte +16 -12
- package/components/editor/CaptionedCodeEditor.svelte.d.ts +4 -4
- package/components/editor/CaretContext.d.ts +48 -16
- package/components/editor/CaretState.d.ts +16 -44
- package/components/editor/CaretUtilities.d.ts +2 -2
- package/components/editor/CaretView.svelte +80 -0
- package/components/editor/CaretView.svelte.d.ts +24 -0
- package/components/editor/CitationsEditor.svelte +36 -25
- package/components/editor/CitationsEditor.svelte.d.ts +4 -4
- package/components/editor/Clipboard.d.ts +2 -2
- package/components/editor/Command.d.ts +13 -12
- package/components/editor/Commands.d.ts +1 -1
- package/components/editor/Commands.js +1114 -571
- package/components/editor/ConfirmButton.svelte +18 -12
- package/components/editor/ConfirmButton.svelte.d.ts +5 -4
- package/components/editor/DefinitionEditor.svelte +29 -21
- package/components/editor/DefinitionEditor.svelte.d.ts +4 -4
- package/components/editor/EmbedEditor.svelte +93 -43
- package/components/editor/EmbedEditor.svelte.d.ts +3 -3
- package/components/editor/Icon.svelte +17 -0
- package/components/editor/Icon.svelte.d.ts +16 -0
- package/components/editor/ImageChooser.svelte +53 -34
- package/components/editor/ImageChooser.svelte.d.ts +3 -3
- package/components/editor/InlineCodeEditor.svelte +7 -4
- package/components/editor/InlineCodeEditor.svelte.d.ts +4 -4
- package/components/editor/LabelEditor.svelte +20 -11
- package/components/editor/LabelEditor.svelte.d.ts +4 -4
- package/components/editor/LanguageEditor.svelte +10 -7
- package/components/editor/LanguageEditor.svelte.d.ts +3 -3
- package/components/editor/LinkEditor.svelte +64 -39
- package/components/editor/LinkEditor.svelte.d.ts +4 -4
- package/components/editor/Note.svelte +3 -3
- package/components/editor/Note.svelte.d.ts +6 -2
- package/components/editor/PositionEditor.svelte +9 -6
- package/components/editor/PositionEditor.svelte.d.ts +4 -4
- package/components/editor/QuoteEditor.svelte +7 -2
- package/components/editor/QuoteEditor.svelte.d.ts +4 -4
- package/components/editor/Switch.svelte +55 -28
- package/components/editor/Switch.svelte.d.ts +4 -4
- package/components/editor/TableEditor.svelte +10 -0
- package/components/editor/TableEditor.svelte.d.ts +17 -0
- package/components/editor/TextEditor.svelte +83 -45
- package/components/editor/TextEditor.svelte.d.ts +5 -4
- package/components/editor/Toggle.svelte +11 -8
- package/components/editor/Toggle.svelte.d.ts +4 -4
- package/components/editor/Toolbar.svelte +192 -144
- package/components/editor/Toolbar.svelte.d.ts +5 -8
- package/components/editor/ToolbarGroup.svelte +18 -23
- package/components/editor/ToolbarGroup.svelte.d.ts +3 -4
- package/components/editor/ToolbarSpacer.svelte +8 -1
- package/components/editor/ToolbarSpacer.svelte.d.ts +6 -2
- package/components/editor/URLEditor.svelte +6 -8
- package/components/editor/URLEditor.svelte.d.ts +3 -3
- package/components/editor/UndoState.d.ts +3 -3
- package/components/editor/icons/annotate.svg +1 -0
- package/components/editor/icons/block.svg +1 -0
- package/components/editor/icons/bold.svg +1 -0
- package/components/editor/icons/bullets.svg +1 -0
- package/components/editor/icons/callout.svg +1 -0
- package/components/editor/icons/citation.svg +8 -0
- package/components/editor/icons/clear.svg +1 -0
- package/components/editor/icons/clipboard.svg +1 -0
- package/components/editor/icons/code.svg +1 -0
- package/components/editor/icons/columnafter.svg +1 -0
- package/components/editor/icons/columnbefore.svg +1 -0
- package/components/editor/icons/comment.svg +1 -0
- package/components/editor/icons/copy.svg +1 -0
- package/components/editor/icons/cut.svg +1 -0
- package/components/editor/icons/define.svg +7 -0
- package/components/editor/icons/deletecolumn.svg +1 -0
- package/components/editor/icons/deleterow.svg +1 -0
- package/components/editor/icons/footnote.svg +8 -0
- package/components/editor/icons/header1.svg +7 -0
- package/components/editor/icons/header2.svg +7 -0
- package/components/editor/icons/header3.svg +7 -0
- package/components/editor/icons/home.svg +1 -0
- package/components/editor/icons/indent.svg +1 -0
- package/components/editor/icons/italic.svg +1 -0
- package/components/editor/icons/label.svg +1 -0
- package/components/editor/icons/left.svg +1 -0
- package/components/editor/icons/level.svg +1 -0
- package/components/editor/icons/link.svg +1 -0
- package/components/editor/icons/list.svg +1 -0
- package/components/editor/icons/media.svg +1 -0
- package/components/editor/icons/middle.svg +1 -0
- package/components/editor/icons/numbers.svg +10 -0
- package/components/editor/icons/paragraph.svg +1 -0
- package/components/editor/icons/paste.svg +10 -0
- package/components/editor/icons/quote.svg +1 -0
- package/components/editor/icons/redo.svg +1 -0
- package/components/editor/icons/right.svg +1 -0
- package/components/editor/icons/rowabove.svg +1 -0
- package/components/editor/icons/rowbelow.svg +1 -0
- package/components/editor/icons/rule.svg +1 -0
- package/components/editor/icons/sub.svg +1 -0
- package/components/editor/icons/super.svg +1 -0
- package/components/editor/icons/table.svg +1 -0
- package/components/editor/icons/text.svg +1 -0
- package/components/editor/icons/time.svg +1 -0
- package/components/editor/icons/undo.svg +1 -0
- package/components/editor/icons/unindent.svg +1 -0
- package/components/editor/icons/unlink.svg +1 -0
- package/components/page/Acknowledgements.svelte +31 -22
- package/components/page/Acknowledgements.svelte.d.ts +4 -4
- package/components/page/Authors.svelte +34 -14
- package/components/page/Authors.svelte.d.ts +6 -6
- package/components/page/BulkReferenceEditor.svelte +53 -22
- package/components/page/BulkReferenceEditor.svelte.d.ts +4 -4
- package/components/page/Chapter.svelte +196 -141
- package/components/page/Chapter.svelte.d.ts +3 -3
- package/components/page/ChapterContext.d.ts +4 -4
- package/components/page/ChapterNumber.svelte +9 -0
- package/components/page/ChapterNumber.svelte.d.ts +27 -0
- package/components/page/ChapterTitle.svelte +16 -0
- package/components/page/ChapterTitle.svelte.d.ts +18 -0
- package/components/page/Contexts.d.ts +31 -20
- package/components/page/Contexts.js +47 -17
- package/components/page/DefinitionView.svelte +115 -86
- package/components/page/DefinitionView.svelte.d.ts +3 -3
- package/components/page/Description.svelte +27 -18
- package/components/page/Description.svelte.d.ts +4 -4
- package/components/page/Edition.svelte +127 -75
- package/components/page/Edition.svelte.d.ts +4 -4
- package/components/page/Editions.svelte +158 -0
- package/components/page/Editions.svelte.d.ts +14 -0
- package/components/page/Glossary.svelte +57 -48
- package/components/page/Glossary.svelte.d.ts +4 -4
- package/components/page/Header.svelte +129 -44
- package/components/page/Header.svelte.d.ts +6 -6
- package/components/page/Index.svelte +114 -80
- package/components/page/Index.svelte.d.ts +4 -4
- package/components/page/Instructions.svelte +18 -16
- package/components/page/Instructions.svelte.d.ts +4 -4
- package/components/page/License.svelte +29 -21
- package/components/page/License.svelte.d.ts +4 -4
- package/components/page/Loading.svelte +102 -12
- package/components/page/Loading.svelte.d.ts +6 -2
- package/components/page/Media.svelte +77 -51
- package/components/page/Media.svelte.d.ts +4 -4
- package/components/page/MediaPreview.svelte +26 -8
- package/components/page/MediaPreview.svelte.d.ts +3 -3
- package/components/page/Muted.svelte +10 -0
- package/components/page/Muted.svelte.d.ts +27 -0
- package/components/page/Outline.svelte +279 -59
- package/components/page/Outline.svelte.d.ts +3 -3
- package/components/page/Page.svelte +40 -9
- package/components/page/Page.svelte.d.ts +3 -3
- package/components/page/PageHeader.svelte +14 -0
- package/components/page/PageHeader.svelte.d.ts +18 -0
- package/components/page/PageParagraph.svelte +18 -0
- package/components/page/PageParagraph.svelte.d.ts +27 -0
- package/components/page/PossibleChapter.svelte +7 -7
- package/components/page/PossibleChapter.svelte.d.ts +4 -4
- package/components/page/PossibleReference.svelte +6 -11
- package/components/page/PossibleReference.svelte.d.ts +6 -7
- package/components/page/Print.svelte +27 -3
- package/components/page/Print.svelte.d.ts +4 -4
- package/components/page/Reference.svelte +256 -113
- package/components/page/Reference.svelte.d.ts +5 -5
- package/components/page/References.svelte +39 -47
- package/components/page/References.svelte.d.ts +4 -4
- package/components/page/Rows.svelte +54 -0
- package/components/page/Rows.svelte.d.ts +27 -0
- package/components/page/Search.svelte +86 -63
- package/components/page/Search.svelte.d.ts +4 -4
- package/components/page/Status.svelte +43 -35
- package/components/page/Status.svelte.d.ts +4 -9
- package/components/page/SubdomainEditor.svelte +40 -27
- package/components/page/SubdomainEditor.svelte.d.ts +4 -4
- package/components/page/TableOfContents.svelte +225 -190
- package/components/page/TableOfContents.svelte.d.ts +4 -4
- package/components/page/TableOfContentsImage.svelte +8 -8
- package/components/page/TableOfContentsImage.svelte.d.ts +3 -3
- package/components/page/TableOfContentsRow.svelte +96 -33
- package/components/page/TableOfContentsRow.svelte.d.ts +4 -4
- package/components/page/ThemeEditor.svelte +174 -39
- package/components/page/ThemeEditor.svelte.d.ts +4 -4
- package/components/page/ThemeEditorPreview.svelte +35 -23
- package/components/page/ThemeEditorPreview.svelte.d.ts +5 -5
- package/components/page/ThemeSetEditor.svelte +15 -13
- package/components/page/ThemeSetEditor.svelte.d.ts +4 -4
- package/components/page/ThemeVariableEditor.svelte +24 -15
- package/components/page/ThemeVariableEditor.svelte.d.ts +3 -3
- package/components/page/Title.svelte +12 -0
- package/components/page/Title.svelte.d.ts +27 -0
- package/components/page/Unknown.svelte +25 -21
- package/components/page/Unknown.svelte.d.ts +4 -4
- package/components/page/margins.js +50 -33
- package/index.d.ts +14 -0
- package/index.js +14 -0
- package/models/CRUD.d.ts +17 -0
- package/models/CRUD.js +207 -0
- package/models/Firebase.d.ts +1 -0
- package/models/Firebase.js +21 -15
- package/models/book/Book.d.ts +26 -30
- package/models/book/Book.js +120 -113
- package/models/book/BookMedia.d.ts +3 -3
- package/models/book/BookMedia.js +22 -16
- package/models/book/BookSaveStatus.d.ts +7 -0
- package/models/book/BookSaveStatus.js +8 -0
- package/models/book/Chapter.d.ts +46 -39
- package/models/book/Chapter.js +180 -198
- package/models/book/ChapterID.js +7 -7
- package/models/book/Definition.d.ts +1 -1
- package/models/book/Edition.d.ts +62 -60
- package/models/book/Edition.js +385 -303
- package/models/book/Reference.d.ts +24 -0
- package/models/book/Reference.js +78 -0
- package/models/book/Schema.d.ts +169 -0
- package/models/book/Schema.js +114 -0
- package/models/book/Theme.d.ts +44 -37
- package/models/book/Theme.js +452 -52
- package/models/book/ThemeColors.d.ts +1 -1
- package/models/book/Words.d.ts +2 -0
- package/models/book/Words.js +110 -0
- package/models/chapter/AtomNode.d.ts +4 -4
- package/models/chapter/AtomNode.js +20 -13
- package/models/chapter/BlockNode.d.ts +9 -10
- package/models/chapter/BlockNode.js +32 -13
- package/models/chapter/BlocksNode.d.ts +10 -10
- package/models/chapter/BlocksNode.js +315 -120
- package/models/chapter/BlocksNode.test.js +494 -228
- package/models/chapter/Bookkeeping.d.ts +1 -1
- package/models/chapter/CalloutNode.d.ts +3 -3
- package/models/chapter/CalloutNode.js +34 -12
- package/models/chapter/Caret.d.ts +9 -7
- package/models/chapter/Caret.js +11 -6
- package/models/chapter/ChapterNode.d.ts +11 -11
- package/models/chapter/ChapterNode.js +70 -33
- package/models/chapter/CitationsNode.d.ts +3 -3
- package/models/chapter/CitationsNode.js +31 -12
- package/models/chapter/CodeNode.d.ts +11 -6
- package/models/chapter/CodeNode.js +143 -34
- package/models/chapter/CommentNode.d.ts +5 -5
- package/models/chapter/CommentNode.js +29 -13
- package/models/chapter/DefinitionNode.d.ts +2 -2
- package/models/chapter/DefinitionNode.js +15 -7
- package/models/chapter/Edit.d.ts +3 -3
- package/models/chapter/EmbedNode.d.ts +9 -5
- package/models/chapter/EmbedNode.js +108 -35
- package/models/chapter/ErrorNode.d.ts +2 -2
- package/models/chapter/ErrorNode.js +34 -12
- package/models/chapter/FootnoteNode.d.ts +5 -5
- package/models/chapter/FootnoteNode.js +34 -16
- package/models/chapter/FormatNode.d.ts +10 -10
- package/models/chapter/FormatNode.js +237 -106
- package/models/chapter/FormatNode.test.js +87 -45
- package/models/chapter/InlineCodeNode.d.ts +2 -2
- package/models/chapter/InlineCodeNode.js +22 -9
- package/models/chapter/LabelNode.d.ts +4 -4
- package/models/chapter/LabelNode.js +31 -13
- package/models/chapter/LinkNode.d.ts +2 -2
- package/models/chapter/LinkNode.js +21 -9
- package/models/chapter/ListNode.d.ts +8 -8
- package/models/chapter/ListNode.js +99 -38
- package/models/chapter/ListNode.test.js +29 -24
- package/models/chapter/MetadataNode.d.ts +3 -3
- package/models/chapter/MetadataNode.js +13 -5
- package/models/chapter/Node.d.ts +5 -3
- package/models/chapter/Node.js +76 -29
- package/models/chapter/Node.test.js +20 -18
- package/models/chapter/ParagraphNode.d.ts +6 -6
- package/models/chapter/ParagraphNode.js +84 -29
- package/models/chapter/ParagraphNode.test.js +22 -13
- package/models/chapter/Parser.d.ts +25 -25
- package/models/chapter/Parser.js +201 -189
- package/models/chapter/Parser.test.js +16 -16
- package/models/chapter/Position.d.ts +1 -1
- package/models/chapter/QuoteNode.d.ts +6 -6
- package/models/chapter/QuoteNode.js +61 -23
- package/models/chapter/RootNode.d.ts +4 -4
- package/models/chapter/RuleNode.d.ts +2 -2
- package/models/chapter/RuleNode.js +31 -11
- package/models/chapter/TableNode.d.ts +8 -6
- package/models/chapter/TableNode.js +89 -34
- package/models/chapter/TableNode.test.js +22 -24
- package/models/chapter/TextNode.d.ts +6 -6
- package/models/chapter/TextNode.js +72 -32
- package/models/chapter/TextNode.test.js +4 -4
- package/models/loadEdition.d.ts +1 -1
- package/models/loadEdition.js +10 -6
- package/package.json +104 -25
- package/util/getSubdomain.js +8 -6
- package/util/isMobile.js +1 -1
- package/util/mineReference.d.ts +3 -2
- package/util/mineReference.js +67 -29
- package/util/scrollToEyeLevel.js +6 -1
- package/components/chapter/renderPosition.d.ts +0 -3
- package/components/chapter/renderPosition.js +0 -4
- package/components/editor/ToolbarIcon.svelte +0 -22
- package/components/editor/ToolbarIcon.svelte.d.ts +0 -16
- package/components/page/Alert.svelte +0 -11
- package/components/page/Alert.svelte.d.ts +0 -23
- package/components/page/Revisions.svelte +0 -124
- package/components/page/Revisions.svelte.d.ts +0 -14
- package/models/BookLoader.d.ts +0 -2
- package/models/BookLoader.js +0 -67
- package/models/Firestore.d.ts +0 -22
- package/models/Firestore.js +0 -194
- package/models/chapter/ReferenceNode.d.ts +0 -29
- package/models/chapter/ReferenceNode.js +0 -48
|
@@ -1,37 +1,89 @@
|
|
|
1
|
-
import CalloutNode from
|
|
2
|
-
import CitationsNode from
|
|
3
|
-
import CodeNode from
|
|
4
|
-
import CommentNode from
|
|
5
|
-
import DefinitionNode from
|
|
6
|
-
import EmbedNode from
|
|
7
|
-
import FootnoteNode from
|
|
8
|
-
import FormatNode from
|
|
9
|
-
import InlineCodeNode from
|
|
10
|
-
import LabelNode from
|
|
11
|
-
import LinkNode from
|
|
12
|
-
import ListNode from
|
|
13
|
-
import ParagraphNode from
|
|
14
|
-
import QuoteNode from
|
|
15
|
-
import RuleNode from
|
|
16
|
-
import TableNode from
|
|
17
|
-
import TextNode from
|
|
18
|
-
import AtomNode from
|
|
19
|
-
import BlocksNode from
|
|
20
|
-
|
|
1
|
+
import CalloutNode from '../../models/chapter/CalloutNode';
|
|
2
|
+
import CitationsNode from '../../models/chapter/CitationsNode';
|
|
3
|
+
import CodeNode from '../../models/chapter/CodeNode';
|
|
4
|
+
import CommentNode from '../../models/chapter/CommentNode';
|
|
5
|
+
import DefinitionNode from '../../models/chapter/DefinitionNode';
|
|
6
|
+
import EmbedNode from '../../models/chapter/EmbedNode';
|
|
7
|
+
import FootnoteNode from '../../models/chapter/FootnoteNode';
|
|
8
|
+
import FormatNode from '../../models/chapter/FormatNode';
|
|
9
|
+
import InlineCodeNode from '../../models/chapter/InlineCodeNode';
|
|
10
|
+
import LabelNode from '../../models/chapter/LabelNode';
|
|
11
|
+
import LinkNode from '../../models/chapter/LinkNode';
|
|
12
|
+
import ListNode from '../../models/chapter/ListNode';
|
|
13
|
+
import ParagraphNode from '../../models/chapter/ParagraphNode';
|
|
14
|
+
import QuoteNode from '../../models/chapter/QuoteNode';
|
|
15
|
+
import RuleNode from '../../models/chapter/RuleNode';
|
|
16
|
+
import TableNode from '../../models/chapter/TableNode';
|
|
17
|
+
import TextNode from '../../models/chapter/TextNode';
|
|
18
|
+
import AtomNode from '../../models/chapter/AtomNode';
|
|
19
|
+
import BlocksNode from '../../models/chapter/BlocksNode';
|
|
20
|
+
import BoldIcon from './icons/bold.svg?raw';
|
|
21
|
+
import BulletsIcon from './icons/bullets.svg?raw';
|
|
22
|
+
import CalloutIcon from './icons/callout.svg?raw';
|
|
23
|
+
import CitationIcon from './icons/citation.svg?raw';
|
|
24
|
+
import ClearIcon from './icons/clear.svg?raw';
|
|
25
|
+
import CodeIcon from './icons/code.svg?raw';
|
|
26
|
+
import ColumnAfterIcon from './icons/columnafter.svg?raw';
|
|
27
|
+
import ColumnBeforeIcon from './icons/columnbefore.svg?raw';
|
|
28
|
+
import CommentIcon from './icons/comment.svg?raw';
|
|
29
|
+
import CopyIcon from './icons/copy.svg?raw';
|
|
30
|
+
import CutIcon from './icons/cut.svg?raw';
|
|
31
|
+
import DefineIcon from './icons/define.svg?raw';
|
|
32
|
+
import DeleteColumnIcon from './icons/deletecolumn.svg?raw';
|
|
33
|
+
import DeleteRowIcon from './icons/deleterow.svg?raw';
|
|
34
|
+
import FootnoteIcon from './icons/footnote.svg?raw';
|
|
35
|
+
import Header1Icon from './icons/header1.svg?raw';
|
|
36
|
+
import Header2Icon from './icons/header2.svg?raw';
|
|
37
|
+
import Header3Icon from './icons/header3.svg?raw';
|
|
38
|
+
import IndentIcon from './icons/indent.svg?raw';
|
|
39
|
+
import ItalicIcon from './icons/italic.svg?raw';
|
|
40
|
+
import LabelIcon from './icons/label.svg?raw';
|
|
41
|
+
import LinkIcon from './icons/link.svg?raw';
|
|
42
|
+
import MediaIcon from './icons/media.svg?raw';
|
|
43
|
+
import NumbersIcon from './icons/numbers.svg?raw';
|
|
44
|
+
import ParagraphIcon from './icons/paragraph.svg?raw';
|
|
45
|
+
import PasteIcon from './icons/paste.svg?raw';
|
|
46
|
+
import QuoteIcon from './icons/quote.svg?raw';
|
|
47
|
+
import RedoIcon from './icons/redo.svg?raw';
|
|
48
|
+
import RowAboveIcon from './icons/rowabove.svg?raw';
|
|
49
|
+
import RowBelowIcon from './icons/rowbelow.svg?raw';
|
|
50
|
+
import RuleIcon from './icons/rule.svg?raw';
|
|
51
|
+
import SubscriptIcon from './icons/sub.svg?raw';
|
|
52
|
+
import SuperscriptIcon from './icons/super.svg?raw';
|
|
53
|
+
import TableIcon from './icons/table.svg?raw';
|
|
54
|
+
import UndoIcon from './icons/undo.svg?raw';
|
|
55
|
+
import UnindentIcon from './icons/unindent.svg?raw';
|
|
56
|
+
/**
|
|
57
|
+
* Icons:
|
|
58
|
+
* From: https://www.streamlinehq.com/icons/streamline-mini-line
|
|
59
|
+
* All use CSS currentColor
|
|
60
|
+
* No background
|
|
61
|
+
* SVG
|
|
62
|
+
* 48 px
|
|
63
|
+
* stroke width 1
|
|
64
|
+
* */
|
|
21
65
|
function insertTableRowColumn(context, table, format, row, before) {
|
|
22
66
|
const location = table.locate(format);
|
|
23
67
|
if (location === undefined)
|
|
24
68
|
return;
|
|
25
|
-
return rootWithNode(context, table, row
|
|
69
|
+
return rootWithNode(context, table, row
|
|
70
|
+
? table.withNewRow(location.row + (before ? 0 : 1))
|
|
71
|
+
: table.withNewColumn(location.column + (before ? 0 : 1)), (t) => t.getCell(location.row + (row && !before ? 1 : 0), location.column + (!row && !before ? 1 : 0)).getFirstCaret());
|
|
26
72
|
}
|
|
27
73
|
function deleteTableRowColumn(context, table, format, row) {
|
|
28
74
|
const location = table.locate(format);
|
|
29
75
|
if (location === undefined)
|
|
30
76
|
return;
|
|
31
|
-
return rootWithNode(context, table, row
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
77
|
+
return rootWithNode(context, table, row
|
|
78
|
+
? table.withoutRow(location.row)
|
|
79
|
+
: table.withoutColumn(location.column), (t) => {
|
|
80
|
+
return (row
|
|
81
|
+
? t.getCell(location.row === table.getRowCount()
|
|
82
|
+
? location.row - 1
|
|
83
|
+
: location.row, location.column)
|
|
84
|
+
: t.getCell(location.row, location.column === table.getColumnCount()
|
|
85
|
+
? location.column - 1
|
|
86
|
+
: location.column))?.getFirstCaret();
|
|
35
87
|
});
|
|
36
88
|
}
|
|
37
89
|
// A helper function that encapsulates boilerplate for replacing a node in a root and updating a caret.
|
|
@@ -48,245 +100,496 @@ function rootWithNode(context, original, replacement, caret) {
|
|
|
48
100
|
if (caret !== undefined && newCaret === undefined)
|
|
49
101
|
return;
|
|
50
102
|
// Return the edit
|
|
51
|
-
return {
|
|
103
|
+
return {
|
|
104
|
+
root: newRoot,
|
|
105
|
+
range: newCaret !== undefined
|
|
106
|
+
? { start: newCaret, end: newCaret }
|
|
107
|
+
: context.range,
|
|
108
|
+
};
|
|
52
109
|
}
|
|
53
110
|
// An ordered list of command specifications for keyboard and mouse input.
|
|
54
111
|
const commands = [
|
|
55
112
|
{
|
|
56
|
-
|
|
57
|
-
description:
|
|
58
|
-
category:
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
|
|
102
|
-
description:
|
|
103
|
-
category:
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
+
icon: RowAboveIcon,
|
|
114
|
+
description: 'insert row above',
|
|
115
|
+
category: 'table',
|
|
116
|
+
mutates: true,
|
|
117
|
+
control: false,
|
|
118
|
+
alt: true,
|
|
119
|
+
shift: false,
|
|
120
|
+
key: 'ArrowUp',
|
|
121
|
+
visible: (context) => context.table !== undefined,
|
|
122
|
+
active: (context) => context.table !== undefined && context.format !== undefined,
|
|
123
|
+
handler: (context) => context.table !== undefined && context.format !== undefined
|
|
124
|
+
? insertTableRowColumn(context, context.table, context.format, true, true)
|
|
125
|
+
: undefined,
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
icon: RowBelowIcon,
|
|
129
|
+
description: 'insert row below',
|
|
130
|
+
category: 'table',
|
|
131
|
+
mutates: true,
|
|
132
|
+
control: false,
|
|
133
|
+
alt: true,
|
|
134
|
+
shift: false,
|
|
135
|
+
key: 'ArrowDown',
|
|
136
|
+
visible: (context) => context.table !== undefined,
|
|
137
|
+
active: (context) => context.table !== undefined && context.format !== undefined,
|
|
138
|
+
handler: (context) => context.table !== undefined && context.format !== undefined
|
|
139
|
+
? insertTableRowColumn(context, context.table, context.format, true, false)
|
|
140
|
+
: undefined,
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
icon: ColumnAfterIcon,
|
|
144
|
+
description: 'insert column after',
|
|
145
|
+
category: 'table',
|
|
146
|
+
mutates: true,
|
|
147
|
+
control: false,
|
|
148
|
+
alt: true,
|
|
149
|
+
shift: false,
|
|
150
|
+
key: 'ArrowRight',
|
|
151
|
+
visible: (context) => context.table !== undefined,
|
|
152
|
+
active: (context) => context.table !== undefined && context.format !== undefined,
|
|
153
|
+
handler: (context) => context.table !== undefined && context.format !== undefined
|
|
154
|
+
? insertTableRowColumn(context, context.table, context.format, false, false)
|
|
155
|
+
: undefined,
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
icon: ColumnBeforeIcon,
|
|
159
|
+
description: 'insert column before',
|
|
160
|
+
category: 'table',
|
|
161
|
+
mutates: true,
|
|
162
|
+
control: false,
|
|
163
|
+
alt: true,
|
|
164
|
+
shift: false,
|
|
165
|
+
key: 'ArrowLeft',
|
|
166
|
+
visible: (context) => context.table !== undefined,
|
|
167
|
+
active: (context) => context.table !== undefined && context.format !== undefined,
|
|
168
|
+
handler: (context) => context.table !== undefined && context.format !== undefined
|
|
169
|
+
? insertTableRowColumn(context, context.table, context.format, false, true)
|
|
170
|
+
: undefined,
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
icon: DeleteRowIcon,
|
|
174
|
+
description: 'delete row',
|
|
175
|
+
category: 'table',
|
|
176
|
+
mutates: true,
|
|
177
|
+
control: false,
|
|
178
|
+
alt: true,
|
|
179
|
+
shift: false,
|
|
180
|
+
key: 'Backspace',
|
|
181
|
+
visible: (context) => context.table !== undefined,
|
|
182
|
+
active: (context) => context.format !== undefined &&
|
|
183
|
+
context.table !== undefined &&
|
|
184
|
+
context.table.getRowCount() > 1,
|
|
185
|
+
handler: (context) => context.format !== undefined && context.table !== undefined
|
|
186
|
+
? deleteTableRowColumn(context, context.table, context.format, true)
|
|
187
|
+
: undefined,
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
icon: DeleteColumnIcon,
|
|
191
|
+
description: 'delete column',
|
|
192
|
+
category: 'table',
|
|
193
|
+
mutates: true,
|
|
194
|
+
control: false,
|
|
195
|
+
alt: true,
|
|
196
|
+
shift: true,
|
|
197
|
+
key: 'Backspace',
|
|
198
|
+
visible: (context) => context.table !== undefined,
|
|
199
|
+
active: (context) => context.format !== undefined &&
|
|
200
|
+
context.table !== undefined &&
|
|
201
|
+
context.table.getColumnCount() > 1,
|
|
202
|
+
handler: (context) => context.format !== undefined && context.table !== undefined
|
|
203
|
+
? deleteTableRowColumn(context, context.table, context.format, false)
|
|
204
|
+
: undefined,
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
icon: '➡️',
|
|
208
|
+
description: 'next paragraph',
|
|
209
|
+
category: 'navigation',
|
|
210
|
+
mutates: false,
|
|
211
|
+
control: false,
|
|
212
|
+
alt: false,
|
|
213
|
+
shift: false,
|
|
214
|
+
key: 'Tab',
|
|
215
|
+
visible: () => false,
|
|
216
|
+
active: (context) => context.format !== undefined,
|
|
217
|
+
handler: (context) => {
|
|
218
|
+
if (context.format) {
|
|
219
|
+
let caret = context.root
|
|
220
|
+
.getNodeAfter(context.format, (node) => node instanceof FormatNode)
|
|
221
|
+
?.getFirstCaret();
|
|
222
|
+
if (caret)
|
|
223
|
+
return {
|
|
224
|
+
root: context.root,
|
|
225
|
+
range: { start: caret, end: caret },
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
icon: '←',
|
|
232
|
+
description: 'previous paragraph',
|
|
233
|
+
category: 'navigation',
|
|
234
|
+
mutates: false,
|
|
235
|
+
control: false,
|
|
236
|
+
alt: false,
|
|
237
|
+
shift: true,
|
|
238
|
+
key: 'Tab',
|
|
113
239
|
visible: () => false,
|
|
114
|
-
active: context => context.
|
|
115
|
-
|
|
116
|
-
|
|
240
|
+
active: (context) => context.format !== undefined,
|
|
241
|
+
// If we're in a table, find the previous cell.
|
|
242
|
+
handler: (context) => {
|
|
243
|
+
if (context.format) {
|
|
244
|
+
let caret = context.root
|
|
245
|
+
.getNodeBefore(context.format, (node) => node instanceof FormatNode)
|
|
246
|
+
?.getFirstCaret();
|
|
247
|
+
if (caret)
|
|
248
|
+
return {
|
|
249
|
+
root: context.root,
|
|
250
|
+
range: { start: caret, end: caret },
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
icon: '←',
|
|
257
|
+
description: 'move to previous character',
|
|
258
|
+
category: 'navigation',
|
|
259
|
+
mutates: false,
|
|
260
|
+
control: false,
|
|
261
|
+
alt: false,
|
|
262
|
+
shift: false,
|
|
263
|
+
key: 'ArrowLeft',
|
|
264
|
+
visible: () => false,
|
|
265
|
+
active: (context) => context.endIsTextOrAtom,
|
|
266
|
+
handler: (context) => {
|
|
267
|
+
if (context.end.node instanceof TextNode ||
|
|
268
|
+
context.end.node instanceof AtomNode ||
|
|
269
|
+
context.end.node instanceof EmbedNode) {
|
|
117
270
|
const nextCaret = context.root.getAdjacentCaret(context.end, false);
|
|
118
271
|
const sortedRange = context.root.sortRange(context.range);
|
|
119
|
-
return {
|
|
272
|
+
return {
|
|
273
|
+
root: context.root,
|
|
274
|
+
range: nextCaret === undefined
|
|
275
|
+
? {
|
|
276
|
+
start: sortedRange.start,
|
|
277
|
+
end: sortedRange.start,
|
|
278
|
+
}
|
|
279
|
+
: { start: nextCaret, end: nextCaret },
|
|
280
|
+
};
|
|
120
281
|
}
|
|
121
|
-
}
|
|
282
|
+
},
|
|
122
283
|
},
|
|
123
284
|
{
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
285
|
+
icon: '← word',
|
|
286
|
+
description: 'move to previous word',
|
|
287
|
+
category: 'navigation',
|
|
288
|
+
mutates: false,
|
|
289
|
+
control: false,
|
|
290
|
+
alt: true,
|
|
291
|
+
shift: false,
|
|
292
|
+
key: 'ArrowLeft',
|
|
127
293
|
visible: false,
|
|
128
|
-
active: context => context.endIsTextOrAtom,
|
|
129
|
-
handler: context => {
|
|
130
|
-
if (context.end.node instanceof TextNode ||
|
|
294
|
+
active: (context) => context.endIsTextOrAtom,
|
|
295
|
+
handler: (context) => {
|
|
296
|
+
if (context.end.node instanceof TextNode ||
|
|
297
|
+
context.end.node instanceof AtomNode ||
|
|
298
|
+
context.end.node instanceof EmbedNode) {
|
|
131
299
|
const previous = context.end.node.previousWord(context.root, context.end.index);
|
|
132
|
-
return {
|
|
300
|
+
return {
|
|
301
|
+
root: context.root,
|
|
302
|
+
range: { start: previous, end: previous },
|
|
303
|
+
};
|
|
133
304
|
}
|
|
134
|
-
}
|
|
305
|
+
},
|
|
135
306
|
},
|
|
136
307
|
{
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
308
|
+
icon: '← paragraph',
|
|
309
|
+
description: 'move to paragraph start',
|
|
310
|
+
category: 'navigation',
|
|
311
|
+
mutates: false,
|
|
312
|
+
control: true,
|
|
313
|
+
alt: false,
|
|
314
|
+
shift: false,
|
|
315
|
+
key: 'ArrowLeft',
|
|
140
316
|
visible: false,
|
|
141
|
-
active: context => context.format !== undefined,
|
|
142
|
-
handler: context => {
|
|
317
|
+
active: (context) => context.format !== undefined,
|
|
318
|
+
handler: (context) => {
|
|
143
319
|
if (context.format !== undefined) {
|
|
144
320
|
const first = context.format.getFirstTextNode();
|
|
145
|
-
return {
|
|
321
|
+
return {
|
|
322
|
+
root: context.root,
|
|
323
|
+
range: {
|
|
324
|
+
start: { node: first, index: 0 },
|
|
325
|
+
end: { node: first, index: 0 },
|
|
326
|
+
},
|
|
327
|
+
};
|
|
146
328
|
}
|
|
147
|
-
}
|
|
329
|
+
},
|
|
148
330
|
},
|
|
149
331
|
{
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
332
|
+
icon: '← select',
|
|
333
|
+
description: 'expand selection to previous character',
|
|
334
|
+
category: 'selection',
|
|
335
|
+
mutates: false,
|
|
336
|
+
control: false,
|
|
337
|
+
alt: false,
|
|
338
|
+
shift: true,
|
|
339
|
+
key: 'ArrowLeft',
|
|
153
340
|
visible: false,
|
|
154
|
-
active: context => context.endIsTextOrAtom,
|
|
155
|
-
handler: context => {
|
|
156
|
-
if (context.end.node instanceof TextNode ||
|
|
341
|
+
active: (context) => context.endIsTextOrAtom,
|
|
342
|
+
handler: (context) => {
|
|
343
|
+
if (context.end.node instanceof TextNode ||
|
|
344
|
+
context.end.node instanceof AtomNode ||
|
|
345
|
+
context.end.node instanceof EmbedNode) {
|
|
157
346
|
const previous = context.root.getAdjacentCaret(context.end, false);
|
|
158
347
|
if (previous === undefined)
|
|
159
348
|
return;
|
|
160
|
-
return {
|
|
349
|
+
return {
|
|
350
|
+
root: context.root,
|
|
351
|
+
range: { start: context.start, end: previous },
|
|
352
|
+
};
|
|
161
353
|
}
|
|
162
|
-
}
|
|
354
|
+
},
|
|
163
355
|
},
|
|
164
356
|
{
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
357
|
+
icon: 'select ← word',
|
|
358
|
+
description: 'expand selection to previous word',
|
|
359
|
+
category: 'selection',
|
|
360
|
+
mutates: false,
|
|
361
|
+
control: false,
|
|
362
|
+
alt: true,
|
|
363
|
+
shift: true,
|
|
364
|
+
key: 'ArrowLeft',
|
|
168
365
|
visible: false,
|
|
169
|
-
active: context => context.endIsTextOrAtom,
|
|
170
|
-
handler: context => {
|
|
171
|
-
if (context.end.node instanceof TextNode ||
|
|
366
|
+
active: (context) => context.endIsTextOrAtom,
|
|
367
|
+
handler: (context) => {
|
|
368
|
+
if (context.end.node instanceof TextNode ||
|
|
369
|
+
context.end.node instanceof AtomNode ||
|
|
370
|
+
context.end.node instanceof EmbedNode) {
|
|
172
371
|
const previous = context.end.node.previousWord(context.root, context.end.index);
|
|
173
|
-
return {
|
|
372
|
+
return {
|
|
373
|
+
root: context.root,
|
|
374
|
+
range: { start: context.start, end: previous },
|
|
375
|
+
};
|
|
174
376
|
}
|
|
175
|
-
}
|
|
377
|
+
},
|
|
176
378
|
},
|
|
177
379
|
{
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
380
|
+
icon: 'select start',
|
|
381
|
+
description: 'expand selection to start',
|
|
382
|
+
category: 'selection',
|
|
383
|
+
mutates: false,
|
|
384
|
+
control: true,
|
|
385
|
+
alt: false,
|
|
386
|
+
shift: true,
|
|
387
|
+
key: 'ArrowLeft',
|
|
181
388
|
visible: false,
|
|
182
|
-
active: context => context.format !== undefined,
|
|
183
|
-
handler: context => {
|
|
389
|
+
active: (context) => context.format !== undefined,
|
|
390
|
+
handler: (context) => {
|
|
184
391
|
if (context.format !== undefined) {
|
|
185
392
|
const first = context.format.getFirstTextNode();
|
|
186
|
-
return {
|
|
393
|
+
return {
|
|
394
|
+
root: context.root,
|
|
395
|
+
range: {
|
|
396
|
+
start: context.start,
|
|
397
|
+
end: { node: first, index: 0 },
|
|
398
|
+
},
|
|
399
|
+
};
|
|
187
400
|
}
|
|
188
|
-
}
|
|
401
|
+
},
|
|
189
402
|
},
|
|
190
403
|
{
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
404
|
+
icon: '→',
|
|
405
|
+
description: 'move to next character',
|
|
406
|
+
category: 'navigation',
|
|
407
|
+
mutates: false,
|
|
408
|
+
control: false,
|
|
409
|
+
alt: false,
|
|
410
|
+
shift: false,
|
|
411
|
+
key: 'ArrowRight',
|
|
194
412
|
visible: false,
|
|
195
|
-
active: context => context.endIsTextOrAtom,
|
|
196
|
-
handler: context => {
|
|
197
|
-
if (context.end.node instanceof TextNode ||
|
|
413
|
+
active: (context) => context.endIsTextOrAtom,
|
|
414
|
+
handler: (context) => {
|
|
415
|
+
if (context.end.node instanceof TextNode ||
|
|
416
|
+
context.end.node instanceof AtomNode ||
|
|
417
|
+
context.end.node instanceof EmbedNode) {
|
|
198
418
|
const nextCaret = context.root.getAdjacentCaret(context.end, true);
|
|
199
419
|
const sortedRange = context.root.sortRange(context.range);
|
|
200
420
|
// If there is no next caret, move the caret to the largest of the current start and end.
|
|
201
|
-
return {
|
|
421
|
+
return {
|
|
422
|
+
root: context.root,
|
|
423
|
+
range: nextCaret === undefined
|
|
424
|
+
? { start: sortedRange.end, end: sortedRange.end }
|
|
425
|
+
: { start: nextCaret, end: nextCaret },
|
|
426
|
+
};
|
|
202
427
|
}
|
|
203
|
-
}
|
|
428
|
+
},
|
|
204
429
|
},
|
|
205
430
|
{
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
431
|
+
icon: '→ word',
|
|
432
|
+
description: 'move to next word',
|
|
433
|
+
category: 'navigation',
|
|
434
|
+
mutates: false,
|
|
435
|
+
control: false,
|
|
436
|
+
alt: true,
|
|
437
|
+
shift: false,
|
|
438
|
+
key: 'ArrowRight',
|
|
209
439
|
visible: false,
|
|
210
|
-
active: context => context.endIsTextOrAtom,
|
|
211
|
-
handler: context => {
|
|
212
|
-
if (context.end.node instanceof TextNode ||
|
|
440
|
+
active: (context) => context.endIsTextOrAtom,
|
|
441
|
+
handler: (context) => {
|
|
442
|
+
if (context.end.node instanceof TextNode ||
|
|
443
|
+
context.end.node instanceof AtomNode ||
|
|
444
|
+
context.end.node instanceof EmbedNode) {
|
|
213
445
|
const next = context.end.node.nextWord(context.root, context.end.index);
|
|
214
|
-
return {
|
|
446
|
+
return {
|
|
447
|
+
root: context.root,
|
|
448
|
+
range: { start: next, end: next },
|
|
449
|
+
};
|
|
215
450
|
}
|
|
216
|
-
}
|
|
451
|
+
},
|
|
217
452
|
},
|
|
218
453
|
{
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
454
|
+
icon: '→ end',
|
|
455
|
+
description: 'move to paragraph end',
|
|
456
|
+
category: 'navigation',
|
|
457
|
+
mutates: false,
|
|
458
|
+
control: true,
|
|
459
|
+
alt: false,
|
|
460
|
+
shift: false,
|
|
461
|
+
key: 'ArrowRight',
|
|
222
462
|
visible: false,
|
|
223
|
-
active: context => context.format !== undefined,
|
|
224
|
-
handler: context => {
|
|
463
|
+
active: (context) => context.format !== undefined,
|
|
464
|
+
handler: (context) => {
|
|
225
465
|
if (context.format !== undefined) {
|
|
226
466
|
const last = context.format.getLastTextNode();
|
|
227
467
|
const caret = { node: last, index: last.getLength() };
|
|
228
|
-
return {
|
|
468
|
+
return {
|
|
469
|
+
root: context.root,
|
|
470
|
+
range: { start: caret, end: caret },
|
|
471
|
+
};
|
|
229
472
|
}
|
|
230
|
-
}
|
|
473
|
+
},
|
|
231
474
|
},
|
|
232
475
|
{
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
476
|
+
icon: 'select →',
|
|
477
|
+
description: 'expand selection to next character',
|
|
478
|
+
category: 'selection',
|
|
479
|
+
mutates: false,
|
|
480
|
+
control: false,
|
|
481
|
+
alt: false,
|
|
482
|
+
shift: true,
|
|
483
|
+
key: 'ArrowRight',
|
|
236
484
|
visible: false,
|
|
237
|
-
active: context => context.endIsTextOrAtom,
|
|
238
|
-
handler: context => {
|
|
239
|
-
if (context.end.node instanceof TextNode ||
|
|
485
|
+
active: (context) => context.endIsTextOrAtom,
|
|
486
|
+
handler: (context) => {
|
|
487
|
+
if (context.end.node instanceof TextNode ||
|
|
488
|
+
context.end.node instanceof AtomNode ||
|
|
489
|
+
context.end.node instanceof EmbedNode) {
|
|
240
490
|
const next = context.root.getAdjacentCaret(context.end, true);
|
|
241
491
|
if (next === undefined)
|
|
242
492
|
return;
|
|
243
|
-
return {
|
|
493
|
+
return {
|
|
494
|
+
root: context.root,
|
|
495
|
+
range: { start: context.start, end: next },
|
|
496
|
+
};
|
|
244
497
|
}
|
|
245
|
-
}
|
|
498
|
+
},
|
|
246
499
|
},
|
|
247
500
|
{
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
501
|
+
icon: 'select → word',
|
|
502
|
+
description: 'expand selection to next word',
|
|
503
|
+
category: 'selection',
|
|
504
|
+
mutates: false,
|
|
505
|
+
control: false,
|
|
506
|
+
alt: true,
|
|
507
|
+
shift: true,
|
|
508
|
+
key: 'ArrowRight',
|
|
251
509
|
visible: false,
|
|
252
|
-
active: context => context.endIsTextOrAtom,
|
|
253
|
-
handler: context => {
|
|
254
|
-
if (context.end.node instanceof TextNode ||
|
|
510
|
+
active: (context) => context.endIsTextOrAtom,
|
|
511
|
+
handler: (context) => {
|
|
512
|
+
if (context.end.node instanceof TextNode ||
|
|
513
|
+
context.end.node instanceof AtomNode ||
|
|
514
|
+
context.end.node instanceof EmbedNode) {
|
|
255
515
|
const previous = context.end.node.nextWord(context.root, context.end.index);
|
|
256
|
-
return {
|
|
516
|
+
return {
|
|
517
|
+
root: context.root,
|
|
518
|
+
range: { start: context.start, end: previous },
|
|
519
|
+
};
|
|
257
520
|
}
|
|
258
|
-
}
|
|
521
|
+
},
|
|
259
522
|
},
|
|
260
523
|
{
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
524
|
+
icon: 'select → end',
|
|
525
|
+
description: 'expand selection to end',
|
|
526
|
+
category: 'selection',
|
|
527
|
+
mutates: false,
|
|
528
|
+
control: true,
|
|
529
|
+
alt: false,
|
|
530
|
+
shift: true,
|
|
531
|
+
key: 'ArrowRight',
|
|
264
532
|
visible: false,
|
|
265
|
-
active: context => context.format !== undefined,
|
|
266
|
-
handler: context => {
|
|
533
|
+
active: (context) => context.format !== undefined,
|
|
534
|
+
handler: (context) => {
|
|
267
535
|
if (context.format !== undefined) {
|
|
268
536
|
const last = context.format.getLastTextNode();
|
|
269
|
-
return {
|
|
537
|
+
return {
|
|
538
|
+
root: context.root,
|
|
539
|
+
range: {
|
|
540
|
+
start: context.start,
|
|
541
|
+
end: { node: last, index: last.getLength() },
|
|
542
|
+
},
|
|
543
|
+
};
|
|
270
544
|
}
|
|
271
|
-
}
|
|
545
|
+
},
|
|
272
546
|
},
|
|
273
547
|
{
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
548
|
+
icon: 'select all',
|
|
549
|
+
description: 'expand selection to all',
|
|
550
|
+
category: 'selection',
|
|
551
|
+
mutates: false,
|
|
552
|
+
control: true,
|
|
553
|
+
alt: false,
|
|
554
|
+
shift: false,
|
|
555
|
+
key: 'a',
|
|
277
556
|
visible: false,
|
|
278
557
|
active: () => true,
|
|
279
|
-
handler: context => {
|
|
558
|
+
handler: (context) => {
|
|
280
559
|
// If in a footnote, expand to the footnote.
|
|
281
560
|
if (context.atom) {
|
|
282
561
|
const format = context.atom.getMeta();
|
|
283
|
-
return {
|
|
562
|
+
return {
|
|
563
|
+
root: context.root,
|
|
564
|
+
range: {
|
|
565
|
+
start: format.getFirstCaret(),
|
|
566
|
+
end: format.getLastCaret(),
|
|
567
|
+
},
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
// If in a code node, expand to the code.
|
|
571
|
+
else if (context.block instanceof CodeNode &&
|
|
572
|
+
context.range.start.node === context.block.getCodeNode()) {
|
|
573
|
+
const code = context.block.getCodeNode();
|
|
574
|
+
return {
|
|
575
|
+
root: context.root,
|
|
576
|
+
range: {
|
|
577
|
+
start: { node: code, index: 0 },
|
|
578
|
+
end: { node: code, index: code.getLength() },
|
|
579
|
+
},
|
|
580
|
+
};
|
|
284
581
|
}
|
|
285
|
-
// If
|
|
286
|
-
else if (context.paragraph === undefined &&
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
582
|
+
// If in a non paragraph block, expand to the format of whatever format we're in.
|
|
583
|
+
else if (context.paragraph === undefined &&
|
|
584
|
+
context.block &&
|
|
585
|
+
context.format) {
|
|
586
|
+
return {
|
|
587
|
+
root: context.root,
|
|
588
|
+
range: {
|
|
589
|
+
start: context.format.getFirstCaret(),
|
|
590
|
+
end: context.format.getLastCaret(),
|
|
591
|
+
},
|
|
592
|
+
};
|
|
290
593
|
}
|
|
291
594
|
else {
|
|
292
595
|
// Find the first and last caret of the entire chapter.
|
|
@@ -296,64 +599,98 @@ const commands = [
|
|
|
296
599
|
root: context.root,
|
|
297
600
|
range: {
|
|
298
601
|
start: { node: text[0], index: 0 },
|
|
299
|
-
end: {
|
|
300
|
-
|
|
602
|
+
end: {
|
|
603
|
+
node: text[text.length - 1],
|
|
604
|
+
index: text[text.length - 1].getLength(),
|
|
605
|
+
},
|
|
606
|
+
},
|
|
301
607
|
};
|
|
302
608
|
}
|
|
303
609
|
}
|
|
304
|
-
}
|
|
610
|
+
},
|
|
305
611
|
},
|
|
306
612
|
{
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
613
|
+
icon: '↑ line',
|
|
614
|
+
description: 'move up one line',
|
|
615
|
+
category: 'navigation',
|
|
616
|
+
mutates: false,
|
|
617
|
+
control: false,
|
|
618
|
+
alt: false,
|
|
619
|
+
shift: false,
|
|
620
|
+
key: 'ArrowUp',
|
|
310
621
|
visible: false,
|
|
311
|
-
active: context => context.startIsTextOrAtom,
|
|
622
|
+
active: (context) => context.startIsTextOrAtom,
|
|
312
623
|
handler: (context, utilities) => {
|
|
313
624
|
const above = utilities.getCaretOnLine(context.start, false);
|
|
314
625
|
return { root: context.root, range: { start: above, end: above } };
|
|
315
|
-
}
|
|
626
|
+
},
|
|
316
627
|
},
|
|
317
628
|
{
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
629
|
+
icon: 'select ↑ line',
|
|
630
|
+
description: 'move selection up one line',
|
|
631
|
+
category: 'selection',
|
|
632
|
+
mutates: false,
|
|
633
|
+
control: false,
|
|
634
|
+
alt: false,
|
|
635
|
+
shift: true,
|
|
636
|
+
key: 'ArrowUp',
|
|
321
637
|
visible: false,
|
|
322
|
-
active: context => context.startIsTextOrAtom,
|
|
638
|
+
active: (context) => context.startIsTextOrAtom,
|
|
323
639
|
handler: (context, utilities) => {
|
|
324
640
|
const above = utilities.getCaretOnLine(context.end, false);
|
|
325
|
-
return {
|
|
326
|
-
|
|
641
|
+
return {
|
|
642
|
+
root: context.root,
|
|
643
|
+
range: { start: context.start, end: above },
|
|
644
|
+
};
|
|
645
|
+
},
|
|
327
646
|
},
|
|
328
647
|
{
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
648
|
+
icon: 'select ↓ line',
|
|
649
|
+
description: 'move up down line',
|
|
650
|
+
category: 'navigation',
|
|
651
|
+
mutates: false,
|
|
652
|
+
control: false,
|
|
653
|
+
alt: false,
|
|
654
|
+
shift: false,
|
|
655
|
+
key: 'ArrowDown',
|
|
332
656
|
visible: false,
|
|
333
|
-
active: context => context.startIsTextOrAtom,
|
|
657
|
+
active: (context) => context.startIsTextOrAtom,
|
|
334
658
|
handler: (context, utilities) => {
|
|
335
659
|
const below = utilities.getCaretOnLine(context.start, true);
|
|
336
660
|
return { root: context.root, range: { start: below, end: below } };
|
|
337
|
-
}
|
|
661
|
+
},
|
|
338
662
|
},
|
|
339
663
|
{
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
664
|
+
icon: 'select ↓ line',
|
|
665
|
+
description: 'move selection down one line',
|
|
666
|
+
category: 'selection',
|
|
667
|
+
mutates: false,
|
|
668
|
+
control: false,
|
|
669
|
+
alt: false,
|
|
670
|
+
shift: true,
|
|
671
|
+
key: 'ArrowDown',
|
|
343
672
|
visible: false,
|
|
344
|
-
active: context => context.startIsTextOrAtom,
|
|
673
|
+
active: (context) => context.startIsTextOrAtom,
|
|
345
674
|
handler: (context, utilities) => {
|
|
346
675
|
const below = utilities.getCaretOnLine(context.end, true);
|
|
347
|
-
return {
|
|
348
|
-
|
|
676
|
+
return {
|
|
677
|
+
root: context.root,
|
|
678
|
+
range: { start: context.start, end: below },
|
|
679
|
+
};
|
|
680
|
+
},
|
|
349
681
|
},
|
|
350
682
|
{
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
683
|
+
icon: 'delete ←',
|
|
684
|
+
description: 'delete previous character',
|
|
685
|
+
category: 'text',
|
|
686
|
+
mutates: false,
|
|
687
|
+
control: false,
|
|
688
|
+
alt: false,
|
|
689
|
+
shift: false,
|
|
690
|
+
key: 'Backspace',
|
|
354
691
|
visible: false,
|
|
355
692
|
active: true,
|
|
356
|
-
handler: context => {
|
|
693
|
+
handler: (context) => {
|
|
357
694
|
if (context.root === undefined)
|
|
358
695
|
return;
|
|
359
696
|
if (context.isSelection) {
|
|
@@ -368,15 +705,20 @@ const commands = [
|
|
|
368
705
|
return;
|
|
369
706
|
return rootWithNode(context, context.root, edit.root, () => edit.range.start);
|
|
370
707
|
}
|
|
371
|
-
}
|
|
708
|
+
},
|
|
372
709
|
},
|
|
373
710
|
{
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
711
|
+
icon: 'delete →',
|
|
712
|
+
description: 'delete next character',
|
|
713
|
+
category: 'text',
|
|
714
|
+
mutates: true,
|
|
715
|
+
control: false,
|
|
716
|
+
alt: false,
|
|
717
|
+
shift: false,
|
|
718
|
+
key: 'Delete',
|
|
377
719
|
visible: false,
|
|
378
720
|
active: true,
|
|
379
|
-
handler: context => {
|
|
721
|
+
handler: (context) => {
|
|
380
722
|
if (context.root === undefined)
|
|
381
723
|
return;
|
|
382
724
|
if (context.isSelection) {
|
|
@@ -391,36 +733,53 @@ const commands = [
|
|
|
391
733
|
return;
|
|
392
734
|
return rootWithNode(context, context.root, edit.root, () => edit.range.start);
|
|
393
735
|
}
|
|
394
|
-
}
|
|
736
|
+
},
|
|
395
737
|
},
|
|
396
738
|
{
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
739
|
+
icon: 'new line',
|
|
740
|
+
description: 'insert code newline',
|
|
741
|
+
category: 'text',
|
|
742
|
+
mutates: true,
|
|
743
|
+
control: false,
|
|
744
|
+
alt: false,
|
|
745
|
+
shift: false,
|
|
746
|
+
key: 'Enter',
|
|
400
747
|
visible: false,
|
|
401
|
-
active: context => context.code !== undefined,
|
|
402
|
-
handler: context => {
|
|
748
|
+
active: (context) => context.code !== undefined,
|
|
749
|
+
handler: (context) => {
|
|
403
750
|
if (context.code?.getCodeNode() !== context.start.node)
|
|
404
751
|
return;
|
|
405
|
-
const newText = context.start.node.withCharacterAt(
|
|
752
|
+
const newText = context.start.node.withCharacterAt('\n', context.start.index);
|
|
406
753
|
if (newText === undefined)
|
|
407
754
|
return;
|
|
408
|
-
return rootWithNode(context, context.start.node, newText, text => {
|
|
409
|
-
|
|
755
|
+
return rootWithNode(context, context.start.node, newText, (text) => {
|
|
756
|
+
return { node: text, index: context.start.index + 1 };
|
|
757
|
+
});
|
|
758
|
+
},
|
|
410
759
|
},
|
|
411
760
|
{
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
761
|
+
icon: 'split list',
|
|
762
|
+
description: 'split list item',
|
|
763
|
+
category: 'list',
|
|
764
|
+
mutates: true,
|
|
765
|
+
control: false,
|
|
766
|
+
alt: false,
|
|
767
|
+
shift: false,
|
|
768
|
+
key: 'Enter',
|
|
415
769
|
visible: false,
|
|
416
|
-
active: context => context.list !== undefined,
|
|
417
|
-
handler: context => {
|
|
770
|
+
active: (context) => context.list !== undefined,
|
|
771
|
+
handler: (context) => {
|
|
418
772
|
if (context.list === undefined)
|
|
419
773
|
return;
|
|
420
774
|
const lastItem = context.list.getLastItem();
|
|
421
775
|
const lastCaret = lastItem?.getLastCaret();
|
|
422
776
|
// If we're at the last item in the list and it's empty, then add a
|
|
423
|
-
if (lastItem !== undefined &&
|
|
777
|
+
if (lastItem !== undefined &&
|
|
778
|
+
lastCaret !== undefined &&
|
|
779
|
+
lastCaret.node instanceof TextNode &&
|
|
780
|
+
lastCaret.node.getLength() === 0 &&
|
|
781
|
+
lastCaret.node === context.end.node &&
|
|
782
|
+
lastCaret.index === context.end.index) {
|
|
424
783
|
const listParent = context.list.getParent(context.root);
|
|
425
784
|
if (listParent instanceof ListNode) {
|
|
426
785
|
const newSublist = context.list.withoutItem(lastItem);
|
|
@@ -438,14 +797,16 @@ const commands = [
|
|
|
438
797
|
const listWithoutItem = context.list.withoutItem(lastItem);
|
|
439
798
|
if (listWithoutItem === undefined)
|
|
440
799
|
return;
|
|
441
|
-
const newBlocks = listParent
|
|
800
|
+
const newBlocks = listParent
|
|
801
|
+
.withChildReplaced(context.list, listWithoutItem)
|
|
802
|
+
?.withBlockInsertedAfter(listWithoutItem, new ParagraphNode(0, lastItem));
|
|
442
803
|
if (newBlocks === undefined)
|
|
443
804
|
return;
|
|
444
805
|
return rootWithNode(context, listParent, newBlocks, () => lastCaret);
|
|
445
806
|
}
|
|
446
807
|
}
|
|
447
808
|
else
|
|
448
|
-
return rootWithNode(context, context.list, context.list?.withItemSplit(context.range.start), newList => {
|
|
809
|
+
return rootWithNode(context, context.list, context.list?.withItemSplit(context.range.start), (newList) => {
|
|
449
810
|
const index = context.list?.getItemContaining(context.range.start);
|
|
450
811
|
if (index === undefined)
|
|
451
812
|
return;
|
|
@@ -454,374 +815,528 @@ const commands = [
|
|
|
454
815
|
return;
|
|
455
816
|
return item.getFirstCaret();
|
|
456
817
|
});
|
|
457
|
-
}
|
|
818
|
+
},
|
|
458
819
|
},
|
|
459
820
|
{
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
821
|
+
icon: 'split paragraph',
|
|
822
|
+
description: 'split paragraph',
|
|
823
|
+
category: 'text',
|
|
824
|
+
mutates: true,
|
|
825
|
+
control: false,
|
|
826
|
+
alt: false,
|
|
827
|
+
shift: false,
|
|
828
|
+
key: 'Enter',
|
|
463
829
|
visible: false,
|
|
464
|
-
active: context => context.atom === undefined && context.blocks !== undefined,
|
|
465
|
-
handler: context => {
|
|
830
|
+
active: (context) => context.atom === undefined && context.blocks !== undefined,
|
|
831
|
+
handler: (context) => {
|
|
466
832
|
const edit = context.blocks?.withSelectionSplit(context.range);
|
|
467
833
|
if (edit === undefined)
|
|
468
834
|
return;
|
|
469
835
|
return rootWithNode(context, context.blocks, edit.root, () => edit.range.start);
|
|
470
|
-
}
|
|
471
|
-
},
|
|
472
|
-
{
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
control: false,
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
836
|
+
},
|
|
837
|
+
},
|
|
838
|
+
{
|
|
839
|
+
icon: IndentIcon,
|
|
840
|
+
description: 'indent list item',
|
|
841
|
+
category: 'list',
|
|
842
|
+
mutates: true,
|
|
843
|
+
control: false,
|
|
844
|
+
alt: false,
|
|
845
|
+
shift: false,
|
|
846
|
+
key: 'Tab',
|
|
847
|
+
visible: (context) => context.list !== undefined,
|
|
848
|
+
active: (context) => context.list !== undefined,
|
|
849
|
+
handler: (context) => rootWithNode(context, context.blocks, context.blocks?.withListsIndented(context.range, true)),
|
|
850
|
+
},
|
|
851
|
+
{
|
|
852
|
+
icon: UnindentIcon,
|
|
853
|
+
description: 'unindent list item',
|
|
854
|
+
mutates: true,
|
|
855
|
+
category: 'list',
|
|
856
|
+
control: false,
|
|
857
|
+
alt: false,
|
|
858
|
+
shift: true,
|
|
859
|
+
key: 'Tab',
|
|
860
|
+
visible: (context) => context.list !== undefined,
|
|
861
|
+
active: (context) => context.list !== undefined &&
|
|
862
|
+
context.list.isInside(context.root, ListNode),
|
|
863
|
+
handler: (context) => rootWithNode(context, context.blocks, context.blocks?.withListsIndented(context.range, false)),
|
|
864
|
+
},
|
|
865
|
+
{
|
|
866
|
+
icon: ClearIcon,
|
|
867
|
+
description: 'clear formatting',
|
|
868
|
+
mutates: true,
|
|
869
|
+
category: 'text',
|
|
870
|
+
control: true,
|
|
871
|
+
alt: false,
|
|
872
|
+
shift: false,
|
|
873
|
+
key: '0',
|
|
498
874
|
visible: true,
|
|
499
|
-
active: context => context.startIsText || context.endIsText,
|
|
500
|
-
handler: context => context.root.withRangeFormatted(context.range,
|
|
875
|
+
active: (context) => context.startIsText || context.endIsText,
|
|
876
|
+
handler: (context) => context.root.withRangeFormatted(context.range, ''),
|
|
501
877
|
},
|
|
502
878
|
{
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
control: true,
|
|
879
|
+
icon: BoldIcon,
|
|
880
|
+
description: 'bold',
|
|
881
|
+
category: 'text',
|
|
882
|
+
mutates: true,
|
|
883
|
+
control: true,
|
|
884
|
+
alt: false,
|
|
885
|
+
shift: false,
|
|
886
|
+
key: 'b',
|
|
508
887
|
visible: true,
|
|
509
|
-
active: context => context.startIsText || context.endIsText,
|
|
510
|
-
handler: context => context.root.withRangeFormatted(context.range,
|
|
888
|
+
active: (context) => context.startIsText || context.endIsText,
|
|
889
|
+
handler: (context) => context.root.withRangeFormatted(context.range, '*'),
|
|
511
890
|
},
|
|
512
891
|
{
|
|
513
|
-
description:
|
|
514
|
-
icon:
|
|
515
|
-
category:
|
|
516
|
-
|
|
892
|
+
description: 'italic',
|
|
893
|
+
icon: ItalicIcon,
|
|
894
|
+
category: 'text',
|
|
895
|
+
mutates: true,
|
|
896
|
+
control: true,
|
|
897
|
+
alt: false,
|
|
898
|
+
shift: false,
|
|
899
|
+
key: 'i',
|
|
517
900
|
visible: true,
|
|
518
|
-
active: context => context.startIsText || context.endIsText,
|
|
519
|
-
handler: context => context.root.withRangeFormatted(context.range,
|
|
901
|
+
active: (context) => context.startIsText || context.endIsText,
|
|
902
|
+
handler: (context) => context.root.withRangeFormatted(context.range, '_'),
|
|
520
903
|
},
|
|
521
904
|
{
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
control: true,
|
|
905
|
+
icon: SubscriptIcon,
|
|
906
|
+
description: 'subscript',
|
|
907
|
+
category: 'text',
|
|
908
|
+
mutates: true,
|
|
909
|
+
control: true,
|
|
910
|
+
alt: false,
|
|
911
|
+
shift: false,
|
|
912
|
+
key: ',',
|
|
527
913
|
visible: true,
|
|
528
|
-
active: context => context.startIsText || context.endIsText,
|
|
529
|
-
handler: context => context.root.withRangeFormatted(context.range,
|
|
914
|
+
active: (context) => context.startIsText || context.endIsText,
|
|
915
|
+
handler: (context) => context.root.withRangeFormatted(context.range, 'v'),
|
|
530
916
|
},
|
|
531
917
|
{
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
control: true,
|
|
918
|
+
icon: SuperscriptIcon,
|
|
919
|
+
description: 'superscript',
|
|
920
|
+
category: 'text',
|
|
921
|
+
mutates: true,
|
|
922
|
+
control: true,
|
|
923
|
+
alt: false,
|
|
924
|
+
shift: false,
|
|
925
|
+
key: '.',
|
|
537
926
|
visible: true,
|
|
538
|
-
active: context => context.startIsText || context.endIsText,
|
|
539
|
-
handler: context => context.root.withRangeFormatted(context.range,
|
|
927
|
+
active: (context) => context.startIsText || context.endIsText,
|
|
928
|
+
handler: (context) => context.root.withRangeFormatted(context.range, '^'),
|
|
540
929
|
},
|
|
541
930
|
{
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
control: true,
|
|
931
|
+
icon: CodeIcon,
|
|
932
|
+
description: 'toggle code',
|
|
933
|
+
category: 'annotation',
|
|
934
|
+
mutates: true,
|
|
935
|
+
control: true,
|
|
936
|
+
alt: false,
|
|
937
|
+
shift: false,
|
|
938
|
+
key: 'e',
|
|
547
939
|
visible: true,
|
|
548
|
-
active: context => context.startIsText || context.endIsText,
|
|
549
|
-
handler: context => context.meta instanceof InlineCodeNode
|
|
550
|
-
rootWithNode(context, context.format, context.format?.withSegmentReplaced(context.meta, context.meta.getText()))
|
|
551
|
-
context.root.withSegmentAtSelection(context.range, text => new InlineCodeNode(new TextNode(text)))
|
|
940
|
+
active: (context) => context.startIsText || context.endIsText,
|
|
941
|
+
handler: (context) => context.meta instanceof InlineCodeNode
|
|
942
|
+
? rootWithNode(context, context.format, context.format?.withSegmentReplaced(context.meta, context.meta.getText()))
|
|
943
|
+
: context.root.withSegmentAtSelection(context.range, (text) => new InlineCodeNode(new TextNode(text))),
|
|
552
944
|
},
|
|
553
945
|
{
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
control: true,
|
|
946
|
+
icon: LinkIcon,
|
|
947
|
+
description: 'toggle link',
|
|
948
|
+
category: 'annotation',
|
|
949
|
+
mutates: true,
|
|
950
|
+
control: true,
|
|
951
|
+
alt: false,
|
|
952
|
+
shift: false,
|
|
953
|
+
key: 'k',
|
|
559
954
|
visible: true,
|
|
560
|
-
active: context => (context.atom === undefined && context.meta === undefined) ||
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
context.
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
},
|
|
585
|
-
{
|
|
586
|
-
|
|
587
|
-
description:
|
|
588
|
-
category:
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
955
|
+
active: (context) => (context.atom === undefined && context.meta === undefined) ||
|
|
956
|
+
context.meta instanceof LinkNode,
|
|
957
|
+
handler: (context) => context.meta instanceof LinkNode
|
|
958
|
+
? rootWithNode(context, context.format, context.format?.withSegmentReplaced(context.meta, context.meta.getText()))
|
|
959
|
+
: context.root.withSegmentAtSelection(context.range, (text) => new LinkNode(new TextNode(text))),
|
|
960
|
+
},
|
|
961
|
+
{
|
|
962
|
+
icon: DefineIcon,
|
|
963
|
+
description: 'toggle definition',
|
|
964
|
+
category: 'annotation',
|
|
965
|
+
mutates: true,
|
|
966
|
+
control: true,
|
|
967
|
+
alt: false,
|
|
968
|
+
shift: false,
|
|
969
|
+
key: 'd',
|
|
970
|
+
visible: (context) => context.chapter &&
|
|
971
|
+
context.atom === undefined &&
|
|
972
|
+
context.meta === undefined,
|
|
973
|
+
active: (context) => context.chapter &&
|
|
974
|
+
context.atom === undefined &&
|
|
975
|
+
context.meta === undefined,
|
|
976
|
+
handler: (context) => context.meta instanceof DefinitionNode
|
|
977
|
+
? rootWithNode(context, context.format, context.format?.withSegmentReplaced(context.meta, context.meta.getText()))
|
|
978
|
+
: context.root.withSegmentAtSelection(context.range, (text) => new DefinitionNode(new TextNode(text))),
|
|
979
|
+
},
|
|
980
|
+
{
|
|
981
|
+
icon: FootnoteIcon,
|
|
982
|
+
description: 'insert footnote',
|
|
983
|
+
category: 'annotation',
|
|
984
|
+
mutates: true,
|
|
985
|
+
control: true,
|
|
986
|
+
alt: false,
|
|
987
|
+
shift: false,
|
|
988
|
+
key: 'f',
|
|
989
|
+
visible: (context) => context.chapter &&
|
|
990
|
+
context.atom === undefined &&
|
|
991
|
+
context.meta === undefined,
|
|
992
|
+
active: (context) => context.chapter &&
|
|
993
|
+
context.atom === undefined &&
|
|
994
|
+
context.meta === undefined,
|
|
995
|
+
handler: (context) => context.root.withSegmentAtSelection(context.range, (text) => new FootnoteNode(new FormatNode('', [new TextNode(text)]))),
|
|
996
|
+
},
|
|
997
|
+
{
|
|
998
|
+
icon: CitationIcon,
|
|
999
|
+
description: 'insert citations',
|
|
1000
|
+
category: 'annotation',
|
|
1001
|
+
mutates: true,
|
|
1002
|
+
control: true,
|
|
1003
|
+
alt: false,
|
|
1004
|
+
shift: false,
|
|
1005
|
+
key: 'o',
|
|
1006
|
+
visible: (context) => context.chapter &&
|
|
1007
|
+
context.atom === undefined &&
|
|
1008
|
+
context.meta === undefined,
|
|
1009
|
+
active: (context) => context.chapter &&
|
|
1010
|
+
context.atom === undefined &&
|
|
1011
|
+
context.meta === undefined,
|
|
1012
|
+
handler: (context) => context.root.withSegmentAtSelection(context.range, () => new CitationsNode([])),
|
|
1013
|
+
},
|
|
1014
|
+
{
|
|
1015
|
+
icon: LabelIcon,
|
|
1016
|
+
description: 'insert label',
|
|
1017
|
+
category: 'annotation',
|
|
1018
|
+
mutates: true,
|
|
1019
|
+
control: true,
|
|
1020
|
+
alt: false,
|
|
1021
|
+
shift: false,
|
|
1022
|
+
key: 'l',
|
|
1023
|
+
visible: (context) => context.chapter &&
|
|
1024
|
+
context.atom === undefined &&
|
|
1025
|
+
context.meta === undefined,
|
|
1026
|
+
active: (context) => context.chapter &&
|
|
1027
|
+
context.atom === undefined &&
|
|
1028
|
+
context.meta === undefined,
|
|
1029
|
+
handler: (context) => context.root.withSegmentAtSelection(context.range, () => new LabelNode('')),
|
|
1030
|
+
},
|
|
1031
|
+
{
|
|
1032
|
+
icon: CommentIcon,
|
|
1033
|
+
description: 'insert comment',
|
|
1034
|
+
category: 'annotation',
|
|
1035
|
+
mutates: true,
|
|
1036
|
+
control: true,
|
|
1037
|
+
alt: false,
|
|
1038
|
+
shift: false,
|
|
1039
|
+
key: "'",
|
|
1040
|
+
visible: (context) => context.chapter &&
|
|
1041
|
+
context.atom === undefined &&
|
|
1042
|
+
context.meta === undefined,
|
|
1043
|
+
active: (context) => context.chapter &&
|
|
1044
|
+
context.atom === undefined &&
|
|
1045
|
+
context.meta === undefined,
|
|
1046
|
+
handler: (context) => context.root.withSegmentAtSelection(context.range, (text) => new CommentNode(new FormatNode('', [new TextNode(text)]))),
|
|
1047
|
+
},
|
|
1048
|
+
{
|
|
1049
|
+
icon: ParagraphIcon,
|
|
1050
|
+
description: 'format as paragraph',
|
|
1051
|
+
category: 'level',
|
|
1052
|
+
mutates: true,
|
|
1053
|
+
control: true,
|
|
1054
|
+
alt: true,
|
|
1055
|
+
shift: false,
|
|
1056
|
+
code: 'Digit0',
|
|
1057
|
+
visible: (context) => context.paragraph !== undefined &&
|
|
1058
|
+
context.paragraph.getLevel() !== 0,
|
|
1059
|
+
active: (context) => context.paragraph !== undefined &&
|
|
1060
|
+
context.paragraph.getLevel() !== 0,
|
|
1061
|
+
handler: (context) => {
|
|
622
1062
|
if (context.paragraph === undefined)
|
|
623
1063
|
return;
|
|
624
1064
|
return rootWithNode(context, context.paragraph, context.paragraph.withLevel(0));
|
|
625
|
-
}
|
|
626
|
-
},
|
|
627
|
-
{
|
|
628
|
-
|
|
629
|
-
description:
|
|
630
|
-
category:
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
visible: context => context.paragraph !== undefined,
|
|
651
|
-
active: context => context.paragraph !== undefined &&
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
1065
|
+
},
|
|
1066
|
+
},
|
|
1067
|
+
{
|
|
1068
|
+
icon: Header1Icon,
|
|
1069
|
+
description: 'format as 1st level header',
|
|
1070
|
+
category: 'level',
|
|
1071
|
+
mutates: true,
|
|
1072
|
+
control: true,
|
|
1073
|
+
alt: true,
|
|
1074
|
+
shift: false,
|
|
1075
|
+
code: 'Digit1',
|
|
1076
|
+
visible: (context) => context.paragraph !== undefined,
|
|
1077
|
+
active: (context) => context.paragraph !== undefined &&
|
|
1078
|
+
context.paragraph.getLevel() !== 1,
|
|
1079
|
+
handler: (context) => rootWithNode(context, context.paragraph, context.paragraph?.withLevel(1)),
|
|
1080
|
+
},
|
|
1081
|
+
{
|
|
1082
|
+
icon: Header2Icon,
|
|
1083
|
+
description: 'format as 2nd level header',
|
|
1084
|
+
category: 'level',
|
|
1085
|
+
mutates: true,
|
|
1086
|
+
control: true,
|
|
1087
|
+
alt: true,
|
|
1088
|
+
shift: false,
|
|
1089
|
+
code: 'Digit2',
|
|
1090
|
+
visible: (context) => context.paragraph !== undefined,
|
|
1091
|
+
active: (context) => context.paragraph !== undefined &&
|
|
1092
|
+
context.paragraph.getLevel() !== 2,
|
|
1093
|
+
handler: (context) => rootWithNode(context, context.paragraph, context.paragraph?.withLevel(2)),
|
|
1094
|
+
},
|
|
1095
|
+
{
|
|
1096
|
+
icon: Header3Icon,
|
|
1097
|
+
description: 'format as 3rd level header',
|
|
1098
|
+
category: 'level',
|
|
1099
|
+
mutates: true,
|
|
1100
|
+
control: true,
|
|
1101
|
+
alt: true,
|
|
1102
|
+
shift: false,
|
|
1103
|
+
code: 'Digit3',
|
|
1104
|
+
visible: (context) => context.paragraph !== undefined,
|
|
1105
|
+
active: (context) => context.paragraph !== undefined &&
|
|
1106
|
+
context.paragraph.getLevel() !== 3,
|
|
1107
|
+
handler: (context) => rootWithNode(context, context.paragraph, context.paragraph?.withLevel(3)),
|
|
1108
|
+
},
|
|
1109
|
+
{
|
|
1110
|
+
icon: RuleIcon,
|
|
1111
|
+
description: 'insert horizontal rule',
|
|
1112
|
+
category: 'block',
|
|
1113
|
+
mutates: true,
|
|
1114
|
+
control: true,
|
|
1115
|
+
alt: false,
|
|
1116
|
+
shift: false,
|
|
1117
|
+
key: 'u',
|
|
1118
|
+
visible: (context) => context.paragraph !== undefined,
|
|
1119
|
+
active: (context) => context.paragraph !== undefined && context.atParagraphStart,
|
|
1120
|
+
handler: (context) => context.paragraph
|
|
1121
|
+
? rootWithNode(context, context.blocks, context.blocks?.withBlockInsertedBefore(context.paragraph, new RuleNode()))
|
|
1122
|
+
: undefined,
|
|
1123
|
+
},
|
|
1124
|
+
{
|
|
1125
|
+
icon: CalloutIcon,
|
|
1126
|
+
description: 'insert callout',
|
|
1127
|
+
category: 'block',
|
|
1128
|
+
mutates: true,
|
|
1129
|
+
control: true,
|
|
1130
|
+
alt: false,
|
|
1131
|
+
shift: true,
|
|
1132
|
+
key: '-',
|
|
1133
|
+
visible: (context) => context.paragraph !== undefined,
|
|
1134
|
+
active: (context) => context.paragraph !== undefined && context.atParagraphStart,
|
|
1135
|
+
handler: (context) => {
|
|
671
1136
|
// If the caret is in a paragraph in a blocks node, insert a callout before the current paragraph.
|
|
672
1137
|
if (context.blocks && context.paragraph) {
|
|
673
1138
|
// Make a new callout node with an empty paragraph, insert it before the paragraph the caret is in, and place the caret inside the empty paragraph.
|
|
674
1139
|
const newParagraph = new ParagraphNode();
|
|
675
1140
|
return rootWithNode(context, context.blocks, context.blocks.withBlockInsertedBefore(context.paragraph, new CalloutNode([newParagraph])), () => newParagraph.getFirstCaret());
|
|
676
1141
|
}
|
|
677
|
-
}
|
|
1142
|
+
},
|
|
678
1143
|
},
|
|
679
1144
|
{
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
control: true,
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
1145
|
+
icon: QuoteIcon,
|
|
1146
|
+
description: 'insert quote',
|
|
1147
|
+
category: 'block',
|
|
1148
|
+
mutates: true,
|
|
1149
|
+
control: true,
|
|
1150
|
+
alt: false,
|
|
1151
|
+
shift: true,
|
|
1152
|
+
key: "'",
|
|
1153
|
+
visible: (context) => context.paragraph !== undefined,
|
|
1154
|
+
active: (context) => context.paragraph !== undefined && context.atParagraphStart,
|
|
1155
|
+
handler: (context) => {
|
|
688
1156
|
if (context.blocks && context.paragraph) {
|
|
689
1157
|
// Make a new quote and place the caret inside the quote's first empty paragraph.
|
|
690
1158
|
const newParagraph = new ParagraphNode();
|
|
691
1159
|
return rootWithNode(context, context.blocks, context.blocks.withBlockInsertedBefore(context.paragraph, new QuoteNode([newParagraph])), () => newParagraph.getFirstCaret());
|
|
692
1160
|
}
|
|
693
|
-
}
|
|
1161
|
+
},
|
|
694
1162
|
},
|
|
695
1163
|
{
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
control: true,
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
1164
|
+
icon: CodeIcon,
|
|
1165
|
+
description: 'insert code',
|
|
1166
|
+
category: 'block',
|
|
1167
|
+
mutates: true,
|
|
1168
|
+
control: true,
|
|
1169
|
+
alt: false,
|
|
1170
|
+
shift: true,
|
|
1171
|
+
key: 's',
|
|
1172
|
+
visible: (context) => context.paragraph !== undefined,
|
|
1173
|
+
active: (context) => context.paragraph !== undefined && context.atParagraphStart,
|
|
1174
|
+
handler: (context) => {
|
|
704
1175
|
if (context.blocks && context.paragraph) {
|
|
705
|
-
const newCode = new CodeNode(new TextNode(),
|
|
706
|
-
return rootWithNode(context, context.blocks, context.blocks.withBlockInsertedBefore(context.paragraph, newCode), () => {
|
|
1176
|
+
const newCode = new CodeNode(new TextNode(), 'plaintext', '|');
|
|
1177
|
+
return rootWithNode(context, context.blocks, context.blocks.withBlockInsertedBefore(context.paragraph, newCode), () => {
|
|
1178
|
+
return { node: newCode.getCodeNode(), index: 0 };
|
|
1179
|
+
});
|
|
707
1180
|
}
|
|
708
|
-
}
|
|
1181
|
+
},
|
|
709
1182
|
},
|
|
710
1183
|
{
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
control: true,
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
1184
|
+
icon: MediaIcon,
|
|
1185
|
+
description: 'insert image or video',
|
|
1186
|
+
category: 'block',
|
|
1187
|
+
mutates: true,
|
|
1188
|
+
control: true,
|
|
1189
|
+
alt: false,
|
|
1190
|
+
shift: true,
|
|
1191
|
+
key: 'i',
|
|
1192
|
+
visible: (context) => context.paragraph !== undefined,
|
|
1193
|
+
active: (context) => context.paragraph !== undefined && context.atParagraphStart,
|
|
1194
|
+
handler: (context) => {
|
|
719
1195
|
if (context.blocks && context.paragraph) {
|
|
720
1196
|
// Place the caret inside the code's code node.
|
|
721
|
-
const newEmbed = new EmbedNode(
|
|
1197
|
+
const newEmbed = new EmbedNode('', '');
|
|
722
1198
|
return rootWithNode(context, context.blocks, context.blocks.withBlockInsertedBefore(context.paragraph, newEmbed), () => newEmbed.getCaption().getFirstCaret());
|
|
723
1199
|
}
|
|
724
|
-
}
|
|
1200
|
+
},
|
|
725
1201
|
},
|
|
726
1202
|
{
|
|
727
|
-
|
|
728
|
-
description:
|
|
729
|
-
category:
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
1203
|
+
icon: TableIcon,
|
|
1204
|
+
description: 'insert table',
|
|
1205
|
+
category: 'block',
|
|
1206
|
+
mutates: true,
|
|
1207
|
+
control: true,
|
|
1208
|
+
alt: false,
|
|
1209
|
+
shift: false,
|
|
1210
|
+
key: '[',
|
|
1211
|
+
visible: (context) => context.paragraph !== undefined,
|
|
1212
|
+
active: (context) => context.paragraph !== undefined && context.atParagraphStart,
|
|
1213
|
+
handler: (context) => {
|
|
734
1214
|
if (context.blocks && context.paragraph) {
|
|
735
1215
|
// Create a 3x3 of table rows and columns
|
|
736
1216
|
// Return a caret corresponding to the first cell.
|
|
737
1217
|
const newRows = [[], [], []];
|
|
738
1218
|
for (let r = 0; r < Math.max(1, 3); r++) {
|
|
739
1219
|
for (let c = 0; c < Math.max(1, 3); c++)
|
|
740
|
-
newRows[r].push(new FormatNode(
|
|
1220
|
+
newRows[r].push(new FormatNode('', [new TextNode()]));
|
|
741
1221
|
}
|
|
742
|
-
const newTable = new TableNode(newRows,
|
|
743
|
-
return rootWithNode(context, context.blocks, context.blocks.withBlockInsertedBefore(context.paragraph, newTable), () => {
|
|
1222
|
+
const newTable = new TableNode(newRows, '|', new FormatNode('', [new TextNode()]));
|
|
1223
|
+
return rootWithNode(context, context.blocks, context.blocks.withBlockInsertedBefore(context.paragraph, newTable), () => {
|
|
1224
|
+
return {
|
|
1225
|
+
node: newTable.getRows()[0][0].getTextNodes()[0],
|
|
1226
|
+
index: 0,
|
|
1227
|
+
};
|
|
1228
|
+
});
|
|
744
1229
|
}
|
|
745
|
-
}
|
|
746
|
-
},
|
|
747
|
-
{
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
control: true,
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
icon:
|
|
790
|
-
description:
|
|
791
|
-
category:
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
1230
|
+
},
|
|
1231
|
+
},
|
|
1232
|
+
{
|
|
1233
|
+
icon: BulletsIcon,
|
|
1234
|
+
description: 'convert paragraph to bulleted list item',
|
|
1235
|
+
category: 'list',
|
|
1236
|
+
mutates: true,
|
|
1237
|
+
control: true,
|
|
1238
|
+
alt: false,
|
|
1239
|
+
shift: true,
|
|
1240
|
+
key: '7',
|
|
1241
|
+
visible: (context) => context.paragraph !== undefined && context.list === undefined,
|
|
1242
|
+
active: (context) => context.paragraph !== undefined && context.list === undefined,
|
|
1243
|
+
handler: (context) => rootWithNode(context, context.blocks, context.blocks?.withParagraphsAsLists(context.range, false)),
|
|
1244
|
+
},
|
|
1245
|
+
{
|
|
1246
|
+
icon: NumbersIcon,
|
|
1247
|
+
description: 'convert paragraph to numbered list item',
|
|
1248
|
+
category: 'list',
|
|
1249
|
+
mutates: true,
|
|
1250
|
+
control: true,
|
|
1251
|
+
alt: false,
|
|
1252
|
+
shift: true,
|
|
1253
|
+
key: '8',
|
|
1254
|
+
visible: (context) => context.paragraph !== undefined && context.list === undefined,
|
|
1255
|
+
active: (context) => context.paragraph !== undefined && context.list === undefined,
|
|
1256
|
+
handler: (context) => rootWithNode(context, context.blocks, context.blocks?.withParagraphsAsLists(context.range, true)),
|
|
1257
|
+
},
|
|
1258
|
+
{
|
|
1259
|
+
icon: BulletsIcon,
|
|
1260
|
+
description: 'convert numbered list item to bulleted',
|
|
1261
|
+
category: 'list',
|
|
1262
|
+
mutates: true,
|
|
1263
|
+
control: true,
|
|
1264
|
+
alt: false,
|
|
1265
|
+
shift: true,
|
|
1266
|
+
key: '7',
|
|
1267
|
+
visible: (context) => context.list !== undefined && context.list.isNumbered(),
|
|
1268
|
+
active: (context) => context.list !== undefined && context.list.isNumbered(),
|
|
1269
|
+
handler: (context) => context.list
|
|
1270
|
+
? rootWithNode(context, context.blocks, context.blocks?.withListAsStyle(context.list, false))
|
|
1271
|
+
: undefined,
|
|
1272
|
+
},
|
|
1273
|
+
{
|
|
1274
|
+
icon: NumbersIcon,
|
|
1275
|
+
description: 'convert bulleted list item to numbered',
|
|
1276
|
+
category: 'list',
|
|
1277
|
+
mutates: true,
|
|
1278
|
+
control: true,
|
|
1279
|
+
alt: false,
|
|
1280
|
+
shift: true,
|
|
1281
|
+
key: '8',
|
|
1282
|
+
visible: (context) => context.list !== undefined && !context.list.isNumbered(),
|
|
1283
|
+
active: (context) => context.list !== undefined && !context.list.isNumbered(),
|
|
1284
|
+
handler: (context) => context.list
|
|
1285
|
+
? rootWithNode(context, context.blocks, context.blocks?.withListAsStyle(context.list, true))
|
|
1286
|
+
: undefined,
|
|
1287
|
+
},
|
|
1288
|
+
{
|
|
1289
|
+
icon: ParagraphIcon,
|
|
1290
|
+
description: 'convert bulleted list item to paragraph',
|
|
1291
|
+
category: 'list',
|
|
1292
|
+
mutates: true,
|
|
1293
|
+
control: true,
|
|
1294
|
+
alt: false,
|
|
1295
|
+
shift: true,
|
|
1296
|
+
key: ['7', '8'],
|
|
1297
|
+
visible: (context) => context.list !== undefined,
|
|
1298
|
+
active: (context) => context.list !== undefined,
|
|
1299
|
+
handler: (context) => rootWithNode(context, context.blocks, context.blocks?.withListsAsParagraphs(context.range)),
|
|
1300
|
+
},
|
|
1301
|
+
{
|
|
1302
|
+
icon: UndoIcon,
|
|
1303
|
+
description: 'undo the last command',
|
|
1304
|
+
category: 'history',
|
|
1305
|
+
mutates: false,
|
|
1306
|
+
control: true,
|
|
1307
|
+
alt: false,
|
|
1308
|
+
shift: false,
|
|
1309
|
+
key: 'z',
|
|
803
1310
|
visible: true,
|
|
804
|
-
active: context => context.undoStack.length > 0 &&
|
|
805
|
-
|
|
1311
|
+
active: (context) => context.undoStack.length > 0 &&
|
|
1312
|
+
context.undoPosition < context.undoStack.length - 1,
|
|
1313
|
+
handler: (context) => context.undo(),
|
|
806
1314
|
},
|
|
807
1315
|
{
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
control: true,
|
|
1316
|
+
icon: RedoIcon,
|
|
1317
|
+
description: 'redo the most recently undone command',
|
|
1318
|
+
category: 'history',
|
|
1319
|
+
mutates: false,
|
|
1320
|
+
control: true,
|
|
1321
|
+
alt: false,
|
|
1322
|
+
shift: false,
|
|
1323
|
+
key: 'y',
|
|
813
1324
|
visible: true,
|
|
814
|
-
active: context => context.undoPosition > 0,
|
|
815
|
-
handler: context => context.redo()
|
|
1325
|
+
active: (context) => context.undoPosition > 0,
|
|
1326
|
+
handler: (context) => context.redo(),
|
|
816
1327
|
},
|
|
817
1328
|
{
|
|
818
|
-
|
|
819
|
-
description:
|
|
820
|
-
category:
|
|
821
|
-
|
|
1329
|
+
icon: CutIcon,
|
|
1330
|
+
description: 'delete the selected content and copy it to the clipboard',
|
|
1331
|
+
category: 'clipboard',
|
|
1332
|
+
mutates: true,
|
|
1333
|
+
control: true,
|
|
1334
|
+
alt: false,
|
|
1335
|
+
shift: false,
|
|
1336
|
+
key: 'x',
|
|
822
1337
|
visible: true,
|
|
823
|
-
active: context => context.root !== undefined && context.isSelection,
|
|
824
|
-
handler: context => {
|
|
1338
|
+
active: (context) => context.root !== undefined && context.isSelection,
|
|
1339
|
+
handler: (context) => {
|
|
825
1340
|
if (context.root === undefined)
|
|
826
1341
|
return;
|
|
827
1342
|
// Save the copied content to the clipboard
|
|
@@ -831,16 +1346,20 @@ const commands = [
|
|
|
831
1346
|
return;
|
|
832
1347
|
context.handleCopy(copy);
|
|
833
1348
|
return rootWithNode(context, context.root, edit.root, () => edit.range.start);
|
|
834
|
-
}
|
|
1349
|
+
},
|
|
835
1350
|
},
|
|
836
1351
|
{
|
|
837
|
-
|
|
838
|
-
description:
|
|
839
|
-
category:
|
|
840
|
-
|
|
1352
|
+
icon: CopyIcon,
|
|
1353
|
+
description: 'copy the selected content to the clipboard',
|
|
1354
|
+
category: 'clipboard',
|
|
1355
|
+
mutates: false,
|
|
1356
|
+
control: true,
|
|
1357
|
+
alt: false,
|
|
1358
|
+
shift: false,
|
|
1359
|
+
key: 'c',
|
|
841
1360
|
visible: true,
|
|
842
|
-
active: context => context.isSelection,
|
|
843
|
-
handler: context => {
|
|
1361
|
+
active: (context) => context.isSelection,
|
|
1362
|
+
handler: (context) => {
|
|
844
1363
|
if (context.root === undefined)
|
|
845
1364
|
return;
|
|
846
1365
|
// Save the copied content to the clipboard
|
|
@@ -848,52 +1367,70 @@ const commands = [
|
|
|
848
1367
|
if (copy !== undefined)
|
|
849
1368
|
context.handleCopy(copy);
|
|
850
1369
|
return undefined;
|
|
851
|
-
}
|
|
1370
|
+
},
|
|
852
1371
|
},
|
|
853
1372
|
{
|
|
854
|
-
|
|
855
|
-
description:
|
|
856
|
-
category:
|
|
857
|
-
|
|
1373
|
+
icon: PasteIcon,
|
|
1374
|
+
description: 'paste the content from the clipboard',
|
|
1375
|
+
category: 'clipboard',
|
|
1376
|
+
mutates: false,
|
|
1377
|
+
control: true,
|
|
1378
|
+
alt: false,
|
|
1379
|
+
shift: false,
|
|
1380
|
+
key: 'v',
|
|
858
1381
|
visible: true,
|
|
859
1382
|
active: () => true,
|
|
860
|
-
handler: context => {
|
|
1383
|
+
handler: (context) => {
|
|
861
1384
|
if (context.root === undefined)
|
|
862
1385
|
return undefined;
|
|
863
1386
|
// See if there's something on the clipboard.
|
|
864
1387
|
if (navigator.clipboard) {
|
|
865
|
-
navigator.clipboard.read()
|
|
866
|
-
.then((items) => {
|
|
1388
|
+
navigator.clipboard.read().then((items) => {
|
|
867
1389
|
// If there's nothing, paste whatever is on the editor clipboard, if there is something.
|
|
868
1390
|
if (items.length === 0 && context.clipboard !== undefined)
|
|
869
1391
|
context.handlePaste(context, context.clipboard, true);
|
|
870
1392
|
else {
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
1393
|
+
// See if there's data we can handle. Just look at the first.
|
|
1394
|
+
const item = items[0];
|
|
1395
|
+
// If there's something, try pasting that.
|
|
1396
|
+
if (item) {
|
|
1397
|
+
async function gatherClipboard() {
|
|
1398
|
+
// Eventually we should add HTML support.
|
|
1399
|
+
const contents = {
|
|
1400
|
+
plain: undefined,
|
|
1401
|
+
};
|
|
1402
|
+
try {
|
|
1403
|
+
{
|
|
1404
|
+
const blob = await item.getType('text/plain');
|
|
1405
|
+
const text = await blob.text();
|
|
1406
|
+
contents.plain = text;
|
|
1407
|
+
}
|
|
1408
|
+
context.handlePaste(context, contents, true);
|
|
1409
|
+
}
|
|
1410
|
+
catch (err) { }
|
|
880
1411
|
}
|
|
1412
|
+
gatherClipboard();
|
|
881
1413
|
}
|
|
1414
|
+
// Otherwise, try pasting what's on the app clipboard.
|
|
1415
|
+
else if (context.clipboard !== undefined)
|
|
1416
|
+
return context.handlePaste(context, context.clipboard, false);
|
|
882
1417
|
}
|
|
883
1418
|
});
|
|
884
1419
|
}
|
|
885
|
-
//
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
}
|
|
889
|
-
return undefined;
|
|
890
|
-
}
|
|
1420
|
+
// Return the current caret to avoid unhandled command feedback.
|
|
1421
|
+
return { root: context.root, range: context.range };
|
|
1422
|
+
},
|
|
891
1423
|
},
|
|
892
1424
|
{
|
|
893
|
-
|
|
894
|
-
description:
|
|
895
|
-
category:
|
|
896
|
-
|
|
1425
|
+
icon: 'insert symbol',
|
|
1426
|
+
description: 'insert character',
|
|
1427
|
+
category: 'text',
|
|
1428
|
+
press: true,
|
|
1429
|
+
mutates: true,
|
|
1430
|
+
control: undefined,
|
|
1431
|
+
alt: undefined,
|
|
1432
|
+
shift: undefined,
|
|
1433
|
+
key: (key) => key.length === 1,
|
|
897
1434
|
visible: false,
|
|
898
1435
|
active: (context, key) => context && key !== undefined && key.length === 1,
|
|
899
1436
|
handler: (context, utilities, key) => {
|
|
@@ -910,7 +1447,8 @@ const commands = [
|
|
|
910
1447
|
// If there's a selection, remove it before inserting, and insert at the caret returned.
|
|
911
1448
|
if (context.isSelection) {
|
|
912
1449
|
if (context.code) {
|
|
913
|
-
if (context.code.getCodeNode() ===
|
|
1450
|
+
if (context.code.getCodeNode() ===
|
|
1451
|
+
sortedRange.start.node) {
|
|
914
1452
|
const newText = insertionPoint.node.withoutRange(sortedRange);
|
|
915
1453
|
if (newText === undefined)
|
|
916
1454
|
return;
|
|
@@ -918,7 +1456,10 @@ const commands = [
|
|
|
918
1456
|
if (edit === undefined)
|
|
919
1457
|
return;
|
|
920
1458
|
newRoot = edit;
|
|
921
|
-
insertionPoint = {
|
|
1459
|
+
insertionPoint = {
|
|
1460
|
+
node: newText,
|
|
1461
|
+
index: sortedRange.start.index,
|
|
1462
|
+
};
|
|
922
1463
|
}
|
|
923
1464
|
}
|
|
924
1465
|
else {
|
|
@@ -943,9 +1484,11 @@ const commands = [
|
|
|
943
1484
|
if (newRoot === undefined)
|
|
944
1485
|
return;
|
|
945
1486
|
// Update the chapter
|
|
946
|
-
return rootWithNode(context, context.root, newRoot, () => {
|
|
1487
|
+
return rootWithNode(context, context.root, newRoot, () => {
|
|
1488
|
+
return { node: newText, index: insertionPoint.index + 1 };
|
|
1489
|
+
});
|
|
947
1490
|
}
|
|
948
|
-
}
|
|
949
|
-
}
|
|
1491
|
+
},
|
|
1492
|
+
},
|
|
950
1493
|
];
|
|
951
1494
|
export default commands;
|