markupeditor 0.9.50 → 0.9.52
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/dist/markup-editor.js +226 -164
- package/package.json +1 -1
- package/styles/markup.css +12 -0
package/dist/markup-editor.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const sheet$4 = new CSSStyleSheet();sheet$4.replaceSync("/**\n The CSS here was adapted from the ProseMirror example.\n The adaptations mainly consisted of removing styling when it interfered with\n markup.css in some way. These changes were commented-out and moved to the end of\n this file. Top-level Prosemirror styling was brought to the top of the file.\n Styling from search.css in prosemirror-search were added and modified.\n */\n\n .ProseMirror {\n position: relative;\n padding: 4px 8px 4px 8px;\n line-height: 1.2;\n outline: none;\n word-wrap: break-word;\n white-space: pre-wrap;\n white-space: break-spaces;\n font-variant-ligatures: none;\n }\n \n .ProseMirror pre {\n white-space: pre-wrap;\n }\n \n .ProseMirror li {\n position: relative;\n }\n \n .ProseMirror-hideselection *::selection { background: transparent; }\n .ProseMirror-hideselection *::-moz-selection { background: transparent; }\n .ProseMirror-hideselection { caret-color: transparent; }\n \n /* See https://github.com/ProseMirror/prosemirror/issues/1421#issuecomment-1759320191 */\n .ProseMirror [draggable][contenteditable=false] { user-select: text }\n \n .ProseMirror-selectednode {\n outline: 2px solid #8cf;\n }\n \n /* Make sure li selections wrap around markers */\n \n li.ProseMirror-selectednode {\n outline: none;\n }\n \n li.ProseMirror-selectednode:after {\n content: \"\";\n position: absolute;\n left: -32px;\n right: -2px; top: -2px; bottom: -2px;\n border: 2px solid #8cf;\n pointer-events: none;\n }\n \n /* Protect against generic img rules */\n \n img.ProseMirror-separator {\n display: inline !important;\n border: none !important;\n margin: 0 !important;\n }\n .ProseMirror-textblock-dropdown {\n min-width: 3em;\n }\n \n .ProseMirror-icon svg {\n fill: currentColor;\n height: 1em;\n }\n \n .ProseMirror-icon span {\n vertical-align: text-top;\n }\n .ProseMirror-gapcursor {\n display: none;\n pointer-events: none;\n position: absolute;\n }\n \n .ProseMirror-gapcursor:after {\n content: \"\";\n display: block;\n position: absolute;\n top: -2px;\n width: 20px;\n border-top: 1px solid black;\n animation: ProseMirror-cursor-blink 1.1s steps(2, start) infinite;\n }\n \n @keyframes ProseMirror-cursor-blink {\n to {\n visibility: hidden;\n }\n }\n \n .ProseMirror-focused .ProseMirror-gapcursor {\n display: block;\n }\n \n .ProseMirror-prompt {\n background: white;\n padding: 5px 10px 5px 15px;\n border: 1px solid silver;\n position: fixed;\n border-radius: 3px;\n z-index: 11;\n box-shadow: -.5px 2px 5px rgba(0, 0, 0, .2);\n }\n \n .ProseMirror-prompt h5 {\n margin: 0;\n font-weight: normal;\n font-size: 100%;\n color: #444;\n }\n \n .ProseMirror-prompt input[type=\"text\"],\n .ProseMirror-prompt textarea {\n background: #eee;\n border: none;\n outline: none;\n }\n \n .ProseMirror-prompt input[type=\"text\"] {\n padding: 0 4px;\n }\n \n .ProseMirror-prompt-close {\n position: absolute;\n left: 2px; top: 1px;\n color: #666;\n border: none; background: transparent; padding: 0;\n }\n \n .ProseMirror-prompt-close:after {\n content: \"✕\";\n font-size: 12px;\n }\n \n .ProseMirror-invalid {\n background: #ffc;\n border: 1px solid #cc7;\n border-radius: 4px;\n padding: 5px 10px;\n position: absolute;\n min-width: 10em;\n }\n \n .ProseMirror-prompt-buttons {\n margin-top: 5px;\n /* display: none; */\n }\n \n /*\n \n #editor, .editor {\n border-radius: 4px;\n border: 2px solid rgba(0, 0, 0, 0.2);\n }\n \n .ProseMirror-example-setup-style hr {\n padding: 2px 10px;\n border: none;\n margin: 1em 0;\n }\n \n .ProseMirror-example-setup-style hr:after {\n content: \"\";\n display: block;\n height: 1px;\n background-color: silver;\n line-height: 2px;\n }\n \n .ProseMirror ul, .ProseMirror ol {\n padding-left: 30px;\n }\n \n .ProseMirror blockquote {\n padding-left: 1em;\n border-left: 3px solid #eee;\n margin-left: 0; margin-right: 0;\n }\n \n .ProseMirror-example-setup-style img {\n cursor: default;\n }\n \n .ProseMirror p { margin-bottom: 1em }\n */\n ");
|
|
2
2
|
|
|
3
|
-
const sheet$3 = new CSSStyleSheet();sheet$3.replaceSync("#editor, .editor {\n font-family: system-ui, sans-serif;\n background: white;\n color: black;\n background-clip: padding-box;\n margin: -8px; /* Set so that the .ProseMirror padding starts from edges */\n --padBottom: 0; /* MU.padBottom() sets this value in px based on fullHeight */\n padding-block: 0 var(--padBottom);\n overflow-x: clip;\n overflow-y: scroll;\n height: 100vh;\n padding-right: 12px;\n}\n@media (prefers-color-scheme: dark) {\n #editor, .editor {\n background: black;\n color: white;\n }\n}\n\nbody {\n font-family: system-ui, sans-serif;\n}\n\na {\n color: blue;\n text-decoration: none;\n}\n@media (prefers-color-scheme: dark) {\n a {\n color: #4183c4;\n }\n}\n\na:hover {\n text-decoration: underline;\n}\n\np, pre {\n font-size: 1.0rem;\n}\n\np, ul, ol, dl, table, pre {\n margin: 0 0 15px;\n}\n\nul, ol {\n padding-left: 30px;\n}\n\nh1 {\n font-size: 2.5rem;\n}\n\nh2 {\n font-size: 2.0rem;\n}\n\nh3 {\n font-size: 1.5rem;\n}\n\nh4 {\n font-size: 1.2rem;\n}\n\nh5 {\n font-size: 1.0rem;\n}\n\nh6 {\n font-size: .83rem;\n}\n\nh1, h2, h3, h4, h5, h6 {\n font-weight: bold;\n margin: 0 0 10px 0;\n}\n\nh1 + p, h2 + p, h3 + p {\n margin-top: 10px;\n}\n\ntable {\n table-layout: fixed;\n border-collapse: collapse;\n width: 100%;\n}\n\ntable th, table td {\n padding: 4px;\n}\n\ntable th {\n font-weight: normal; /* The default is bold, but we want to use paragraph styles and formatting */\n}\n\n/* Make the styling compact inside of a table */\ntable p, table h1, table h2, table h3, table h4, table h5, table h6 {\n margin: 0;\n}\n\n/* Table bordering options */\n.bordered-table-none {\n border: none;\n}\n\n.bordered-table-outer, .bordered-table-header, .bordered-table-cell {\n border: 1px solid #DDD;\n}\n\n.bordered-table-header th { /* border th not thead to refresh properly */\n border: 1px solid #DDD;\n}\n\n.bordered-table-cell th, .bordered-table-cell td {\n border: 1px solid #DDD;\n}\n\n/* Default table bordering is same as .bordered-table-cell but is only used when not specified */\ntable:not(.bordered-table-none, .bordered-table-outer, .bordered-table-header, .bordered-table-cell) {\n border: 1px solid #DDD;\n}\n\ntable:not(.bordered-table-none, .bordered-table-outer, .bordered-table-header, .bordered-table-cell) td {\n border: 1px solid #DDD;\n}\n\ntable:not(.bordered-table-none, .bordered-table-outer, .bordered-table-header, .bordered-table-cell) th {\n border: 1px solid #DDD;\n}\n\nli p {\n margin: 0px 0;\n}\n\nli > ul, li > ol {\n margin-bottom: 0;\n}\n\nli > h1, li > h2, li > h3, li > h4, li > h5, li > h6 {\n margin-bottom: 0;\n}\n\nblockquote {\n margin-right: 0px; /* Because nested blockquotes just keep getting narrower */\n}\n\ncode {\n overflow-x: scroll;\n display: block;\n background-color: #F8F8F8;\n border-radius: 3px;\n font-family: 'SF Mono', SFMono-Regular, ui-monospace, 'DejaVu Sans Mono', Menlo, Consolas, monospace;\n white-space: pre;\n}\n@media (prefers-color-scheme: dark) {\n code {\n background-color: #808080;\n }\n}\n\np code, h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {\n display: inline;\n}\n\n.resize-container {\n position: relative;\n display: inline-block;\n margin: 0;\n}\n\nimg {\n max-width: 100%;\n height: auto;\n}\n\n/* Provide a slightly darkened or lightened overlay while search is active */\n.searching {\n background-color: rgba(0, 0, 0, 0.10);\n}\n@media (prefers-color-scheme: dark) {\n .searching {\n background: rgba(255, 255, 255, 0.10);\n }\n}\n\n.resize-container img {\n display: block;\n outline: 1px black dashed;\n outline-offset: 4px;\n outline-width: 1px;\n}\n@media (prefers-color-scheme: dark) {\n .resize-container img {\n outline: 1px white dashed;\n }\n}\n\n.resize-handle-nw,\n.resize-handle-ne,\n.resize-handle-sw,\n.resize-handle-se {\n position: absolute;\n display: block;\n width: 6px;\n height: 6px;\n outline: 1px black solid;\n background: white;\n z-index: 999;\n}\n@media (prefers-color-scheme: dark) {\n .resize-handle-nw,\n .resize-handle-ne,\n .resize-handle-sw,\n .resize-handle-se {\n outline: 1px white solid;\n background: black;\n }\n}\n\n/* A transparent child for each resize-handle that expands the clickable area */\n.resize-handle-nw:after,\n.resize-handle-ne:after,\n.resize-handle-sw:after,\n.resize-handle-se:after {\n content: \"\";\n position: absolute;\n left: -5px;\n top: -5px;\n width: 16px;\n height: 16px;\n}\n\n/* The *-resize cursors do not work, at least in MacCatalyst.\n * Still specifying them below. They default to a pointer instead\n */\n.resize-handle-nw {\n cursor: nw-resize;\n top: -8px;\n left: -7px;\n}\n\n.resize-handle-ne {\n cursor: ne-resize;\n top: -8px;\n right: -7px;\n}\n\n.resize-handle-sw {\n cursor: sw-resize;\n bottom: -8px;\n left: -7px;\n}\n\n.resize-handle-se {\n cursor: se-resize;\n bottom: -8px;\n right: -7px;\n}\n\n.placeholder[placeholder]:before {\n content: attr(placeholder);\n position: absolute;\n color: #ccc;\n}\n\n/* Scoped to :has() rather than styling pre unconditionally, since a code_block's\n <pre> should only become a positioning context when it's actually carrying the\n language tab (highlightCode on, block selected) — not for every code block. */\npre:has(.Markup-code-language-tab) {\n position: relative;\n}\n\n.Markup-code-language-tab {\n position: absolute;\n bottom: 100%;\n right: 0;\n font-size: 0.75rem;\n padding: 2px 6px;\n border: none;\n border-radius: 4px 4px 0 0;\n cursor: pointer;\n opacity: 0.6;\n color: white;\n background: var(--Markup-accent-color, blue);\n}\n\n.Markup-code-language-tab:hover {\n opacity: 0.9;\n}\n\n/* Applied (setup/index.js, CodeView.hasRoomAbove) when the code_block is too close to\n the top of the view for the tab to fit above it — attach to the bottom instead. */\n.Markup-code-language-tab-below {\n bottom: auto;\n top: 100%;\n border-radius: 0 0 4px 4px;\n}\n\n/* Matches .Markup-menuitem-active's selected-button color scheme. */\n@media (prefers-color-scheme: dark) {\n .Markup-code-language-tab {\n background: var(--Markup-accent-color, lightblue);\n color: black;\n }\n}\n\n/* Classes set by prosemirror-search module, modified for MarkupEditor */\n/* Note the dark and light mode are the same */\n\n.ProseMirror-search-match {\n background-color: yellow;\n color: black;\n}\n\n.ProseMirror-active-search-match {\n background-color: orange;\n color: black;\n outline: 1px orangered solid;\n z-index: 2;\n}");
|
|
3
|
+
const sheet$3 = new CSSStyleSheet();sheet$3.replaceSync("#editor, .editor {\n font-family: system-ui, sans-serif;\n background: white;\n color: black;\n background-clip: padding-box;\n margin: -8px; /* Set so that the .ProseMirror padding starts from edges */\n --padBottom: 0; /* MU.padBottom() sets this value in px based on fullHeight */\n padding-block: 0 var(--padBottom);\n overflow-x: clip;\n overflow-y: scroll;\n height: 100vh;\n padding-right: 12px;\n}\n@media (prefers-color-scheme: dark) {\n #editor, .editor {\n background: black;\n color: white;\n }\n}\n\nbody {\n font-family: system-ui, sans-serif;\n}\n\na {\n color: blue;\n text-decoration: none;\n}\n@media (prefers-color-scheme: dark) {\n a {\n color: #4183c4;\n }\n}\n\na:hover {\n text-decoration: underline;\n}\n\np, pre {\n font-size: 1.0rem;\n}\n\np, ul, ol, dl, table, pre {\n margin: 0 0 15px;\n}\n\nul, ol {\n padding-left: 30px;\n}\n\nh1 {\n font-size: 2.5rem;\n}\n\nh2 {\n font-size: 2.0rem;\n}\n\nh3 {\n font-size: 1.5rem;\n}\n\nh4 {\n font-size: 1.2rem;\n}\n\nh5 {\n font-size: 1.0rem;\n}\n\nh6 {\n font-size: .83rem;\n}\n\nh1, h2, h3, h4, h5, h6 {\n font-weight: bold;\n margin: 0 0 10px 0;\n}\n\nh1 + p, h2 + p, h3 + p {\n margin-top: 10px;\n}\n\ntable {\n table-layout: fixed;\n border-collapse: collapse;\n width: 100%;\n}\n\ntable th, table td {\n padding: 4px;\n}\n\ntable th {\n font-weight: normal; /* The default is bold, but we want to use paragraph styles and formatting */\n}\n\n/* Make the styling compact inside of a table */\ntable p, table h1, table h2, table h3, table h4, table h5, table h6 {\n margin: 0;\n}\n\n/* Table bordering options */\n.bordered-table-none {\n border: none;\n}\n\n.bordered-table-outer, .bordered-table-header, .bordered-table-cell {\n border: 1px solid #DDD;\n}\n\n.bordered-table-header th { /* border th not thead to refresh properly */\n border: 1px solid #DDD;\n}\n\n.bordered-table-cell th, .bordered-table-cell td {\n border: 1px solid #DDD;\n}\n\n/* Default table bordering is same as .bordered-table-cell but is only used when not specified */\ntable:not(.bordered-table-none, .bordered-table-outer, .bordered-table-header, .bordered-table-cell) {\n border: 1px solid #DDD;\n}\n\ntable:not(.bordered-table-none, .bordered-table-outer, .bordered-table-header, .bordered-table-cell) td {\n border: 1px solid #DDD;\n}\n\ntable:not(.bordered-table-none, .bordered-table-outer, .bordered-table-header, .bordered-table-cell) th {\n border: 1px solid #DDD;\n}\n\nli p {\n margin: 0px 0;\n}\n\nli > ul, li > ol {\n margin-bottom: 0;\n}\n\nli > h1, li > h2, li > h3, li > h4, li > h5, li > h6 {\n margin-bottom: 0;\n}\n\nblockquote {\n margin-right: 0px; /* Because nested blockquotes just keep getting narrower */\n}\n\ncode {\n overflow-x: scroll;\n display: block;\n background-color: #F8F8F8;\n border-radius: 3px;\n font-family: 'SF Mono', SFMono-Regular, ui-monospace, 'DejaVu Sans Mono', Menlo, Consolas, monospace;\n white-space: pre;\n}\n@media (prefers-color-scheme: dark) {\n code {\n background-color: #808080;\n }\n}\n\np code, h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {\n display: inline;\n}\n\n/* Text that Return will turn into a code block, styled like inline code. */\n.code-fence-pending {\n background-color: #F8F8F8;\n border-radius: 3px;\n font-family: 'SF Mono', SFMono-Regular, ui-monospace, 'DejaVu Sans Mono', Menlo, Consolas, monospace;\n}\n@media (prefers-color-scheme: dark) {\n .code-fence-pending {\n background-color: #808080;\n }\n}\n\n.resize-container {\n position: relative;\n display: inline-block;\n margin: 0;\n}\n\nimg {\n max-width: 100%;\n height: auto;\n}\n\n/* Provide a slightly darkened or lightened overlay while search is active */\n.searching {\n background-color: rgba(0, 0, 0, 0.10);\n}\n@media (prefers-color-scheme: dark) {\n .searching {\n background: rgba(255, 255, 255, 0.10);\n }\n}\n\n.resize-container img {\n display: block;\n outline: 1px black dashed;\n outline-offset: 4px;\n outline-width: 1px;\n}\n@media (prefers-color-scheme: dark) {\n .resize-container img {\n outline: 1px white dashed;\n }\n}\n\n.resize-handle-nw,\n.resize-handle-ne,\n.resize-handle-sw,\n.resize-handle-se {\n position: absolute;\n display: block;\n width: 6px;\n height: 6px;\n outline: 1px black solid;\n background: white;\n z-index: 999;\n}\n@media (prefers-color-scheme: dark) {\n .resize-handle-nw,\n .resize-handle-ne,\n .resize-handle-sw,\n .resize-handle-se {\n outline: 1px white solid;\n background: black;\n }\n}\n\n/* A transparent child for each resize-handle that expands the clickable area */\n.resize-handle-nw:after,\n.resize-handle-ne:after,\n.resize-handle-sw:after,\n.resize-handle-se:after {\n content: \"\";\n position: absolute;\n left: -5px;\n top: -5px;\n width: 16px;\n height: 16px;\n}\n\n/* The *-resize cursors do not work, at least in MacCatalyst.\n * Still specifying them below. They default to a pointer instead\n */\n.resize-handle-nw {\n cursor: nw-resize;\n top: -8px;\n left: -7px;\n}\n\n.resize-handle-ne {\n cursor: ne-resize;\n top: -8px;\n right: -7px;\n}\n\n.resize-handle-sw {\n cursor: sw-resize;\n bottom: -8px;\n left: -7px;\n}\n\n.resize-handle-se {\n cursor: se-resize;\n bottom: -8px;\n right: -7px;\n}\n\n.placeholder[placeholder]:before {\n content: attr(placeholder);\n position: absolute;\n color: #ccc;\n}\n\n/* Scoped to :has() rather than styling pre unconditionally, since a code_block's\n <pre> should only become a positioning context when it's actually carrying the\n language tab (highlightCode on, block selected) — not for every code block. */\npre:has(.Markup-code-language-tab) {\n position: relative;\n}\n\n.Markup-code-language-tab {\n position: absolute;\n bottom: 100%;\n right: 0;\n font-size: 0.75rem;\n padding: 2px 6px;\n border: none;\n border-radius: 4px 4px 0 0;\n cursor: pointer;\n opacity: 0.6;\n color: white;\n background: var(--Markup-accent-color, blue);\n}\n\n.Markup-code-language-tab:hover {\n opacity: 0.9;\n}\n\n/* Applied (setup/index.js, CodeView.hasRoomAbove) when the code_block is too close to\n the top of the view for the tab to fit above it — attach to the bottom instead. */\n.Markup-code-language-tab-below {\n bottom: auto;\n top: 100%;\n border-radius: 0 0 4px 4px;\n}\n\n/* Matches .Markup-menuitem-active's selected-button color scheme. */\n@media (prefers-color-scheme: dark) {\n .Markup-code-language-tab {\n background: var(--Markup-accent-color, lightblue);\n color: black;\n }\n}\n\n/* Classes set by prosemirror-search module, modified for MarkupEditor */\n/* Note the dark and light mode are the same */\n\n.ProseMirror-search-match {\n background-color: yellow;\n color: black;\n}\n\n.ProseMirror-active-search-match {\n background-color: orange;\n color: black;\n outline: 1px orangered solid;\n z-index: 2;\n}");
|
|
4
4
|
|
|
5
5
|
const sheet$2 = new CSSStyleSheet();sheet$2.replaceSync("/* Spacing at the top */\n/* Note that toolbar-overlay below is also set to these values */\n\n.Markup-searchbar-showing {\n height: 38px;\n top: 76px;\n}\n\n/* The wrapper lets us automatically embed a toolbar and scroll under it */\n.Markup-toolbar-wrapper {\n margin-right: -12px; /* Prevent side scroll even when menu fits */\n height: inherit;\n overflow-y: scroll;\n position: relative; \n}\n\n/* We add Markup-prompt-showing to the wrapper to prevent scroll, and remove it when done */\n.Markup-prompt-showing {\n overflow-y: hidden;\n}\n\n/* Z-indexes in one place */\n\n.body-content { \n z-index: 1; \n}\n\n.Markup-prompt-overlay { \n z-index: 2; \n}\n\n.Markup-prompt, .Markup-selection {\n z-index: 3;\n}\n\n.Markup-searchbar {\n z-index: 4;\n}\n\n.Markup-toolbar, .Markup-toolbar-more {\n z-index: 5;\n}\n\n.Markup-toolbar-overlay { \n z-index: 6; \n}\n\n.Markup-menu-dropdown-menu {\n z-index: 7;\n}\n\n/* Toolbar, menu item, and dropdown styling */\n\n.Markup-toolbar {\n display: inline-flex;\n position: sticky;\n overflow: visible;\n width: 100%;\n font-size: var(--Markup-button-font-size, 24px);\n vertical-align: middle;\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n top: 0;\n max-height: calc(var(--Markup-button-size, 28px) + 10px);\n padding: 2px 8px;\n color: var(--Markup-accent-color, blue);\n background: var(--Markup-toolbar-bg, rgba(250, 249, 246, 0.95));\n border-bottom: 1px solid var(--Markup-border-color, lightgray);\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n@media (prefers-color-scheme: dark) {\n .Markup-toolbar {\n color: var(--Markup-accent-color, lightblue);\n background: var(--Markup-toolbar-bg, rgba(40, 40, 43, 0.9));\n border-bottom: 1px solid var(--Markup-border-color, gray);\n }\n}\n\n.Markup-toolbar-hidden {\n display: none;\n}\n\n.Markup-menuitem {\n display: inline-block;\n flex-shrink: 0; /* Otherwise, the drop-downs with icons shrink */\n overflow-y: visible;\n vertical-align: middle;\n min-width: var(--Markup-button-size, 28px);\n height: var(--Markup-button-size, 28px);\n cursor: pointer;\n margin-right: 4px;\n border-radius: 4px;\n color: var(--Markup-accent-color, blue);\n border: 1px solid var(--Markup-accent-color, blue);\n background: var(--Markup-button-bg, white);\n fill: var(--Markup-accent-color, blue);\n}\n@media (prefers-color-scheme: dark) {\n .Markup-menuitem {\n color: var(--Markup-accent-color, lightblue);\n border: 1px solid var(--Markup-accent-color, lightblue);\n /* border: 1px solid #4183c4; */\n background: var(--Markup-button-bg, black);\n fill: var(--Markup-accent-color, lightblue);\n }\n}\n\n.Markup-menuitem-active {\n fill: white;\n color: white;\n background: var(--Markup-accent-color, blue);\n}\n@media (prefers-color-scheme: dark) {\n .Markup-menuitem-active {\n fill: black;\n color: black;\n background: var(--Markup-accent-color, lightblue);\n }\n}\n\n.Markup-menuitem-disabled {\n cursor: default;\n opacity: .3;\n}\n@media (prefers-color-scheme: dark) {\n .Markup-menuitem-disabled {\n opacity: .6;\n }\n}\n\n.Markup-icon {\n display: inline-block;\n width: var(--Markup-button-size, 28px);\n height: var(--Markup-button-size, 28px);\n border: 0;\n}\n\n.Markup-icon span {\n vertical-align: middle;\n}\n\n.Markup-icon svg {\n width: var(--Markup-button-font-size, 24px);\n height: var(--Markup-button-font-size, 24px);\n padding: 2px;\n border: 0;\n fill: inherit;\n}\n\n.Markup-menuseparator {\n display: inline-block;\n vertical-align: middle;\n height: var(--Markup-button-size, 28px);\n border-right: 1px solid var(--Markup-border-color, lightgray);\n margin-right: 4px;\n}\n@media (prefers-color-scheme: dark) {\n .Markup-menuseparator {\n border-right: 1px solid var(--Markup-border-color, gray);\n }\n}\n\n.Markup-menu-disabled .Markup-icon {\n cursor: default;\n}\n\n.Markup-menu-dropdown, .Markup-menu-dropdown-menu {\n background: inherit;\n text-align: left;\n white-space: nowrap;\n}\n\n.Markup-menu-dropdown span {\n vertical-align: middle;\n}\n\n.Markup-menu-dropdown-icon span {\n vertical-align: middle;\n}\n\n.Markup-menu-dropdown-wrap {\n display: flex;\n justify-content: space-between;\n padding: 0 4px;\n height: inherit;\n border-radius: 4px;\n background: inherit;\n}\n\n.Markup-menu-dropdown-icon-wrap {\n display: flex;\n justify-content: space-between;\n padding-right: 4px;\n width: 1.8em;\n height: inherit;\n border-radius: 4px;\n background: inherit;\n}\n\n.Markup-menu-dropdown-icon-wrap-noindicator {\n display: inline-flex;\n padding-right: 4px;\n width: 1em;\n height: inherit;\n border-radius: 4px;\n background: inherit;\n}\n\n/* For the paragraph style dropdown with a label, make the font smaller */\n.Markup-menu-dropdown {\n display: flex;\n justify-content: space-between;\n align-items: center;\n box-sizing: border-box;\n font-size: 0.8em;\n width: inherit;\n height: inherit;\n background: inherit;\n position: absolute;\n}\n\n/* But for the indicator, bump size up to match the icon-style dropdown */\n.Markup-menu-dropdown .Markup-menu-dropdown-indicator {\n font-size: 1.25em;\n}\n\n.Markup-menu-dropdown-icon {\n display: inline-flex;\n justify-content: space-between;\n font-size: inherit;\n width: inherit;\n cursor: pointer;\n position: absolute;\n}\n\n.Markup-menu-dropdown-indicator {\n opacity: .6;\n}\n\n.Markup-tooltip .Markup-menu {\n width: -webkit-fit-content;\n width: fit-content;\n white-space: pre;\n}\n\n.Markup-menu-dropdown-menu, .Markup-menu-submenu {\n position: absolute;\n background: inherit;\n padding: 2px;\n background: inherit;\n border: 1px solid var(--Markup-border-color, gray);\n}\n@media (prefers-color-scheme: dark) {\n .Markup-menu-dropdown-menu, .Markup-menu-submenu {\n border: 1px solid var(--Markup-border-color, lightgray);\n }\n}\n\n.Markup-menu-dropdown-menu {\n margin-top: calc(1em + 6px);\n min-width: 4em;\n}\n\n.Markup-menu-dropdown-item {\n cursor: pointer;\n padding: 2px 8px 2px 4px;\n}\n\n.Markup-menu-dropdown-separator {\n border-top: 1px solid var(--Markup-border-color, lightgray);\n margin: 4px 0;\n}\n@media (prefers-color-scheme: dark) {\n .Markup-menu-dropdown-separator {\n border-top: 1px solid var(--Markup-border-color, gray);\n }\n}\n\n/* Used to overlfow and ellipsis-truncate text in Dropdown menu items */\n.Markup-menuitem-clipped {\n white-space: nowrap; /* Required for text-overflow */\n overflow-x: hidden; /* Required for text-overflow */\n max-width: 30em;\n text-overflow: ellipsis;\n}\n\n.Markup-menu-dropdown-item:hover, .Markup-menu-submenu-wrap:hover {\n background: var(--Markup-hover-bg, #f2f2f2);\n}\n@media (prefers-color-scheme: dark) {\n .Markup-menu-dropdown-item:hover, .Markup-menu-submenu-wrap:hover {\n background: var(--Markup-hover-bg, rgb(80, 80, 80));\n }\n}\n\n.Markup-menu-dropdown-item p, \n.Markup-menu-dropdown-item h1, \n.Markup-menu-dropdown-item h2, \n.Markup-menu-dropdown-item h3, \n.Markup-menu-dropdown-item h4, \n.Markup-menu-dropdown-item h5, \n.Markup-menu-dropdown-item h6, \n.Markup-menu-dropdown-item pre {\n padding: 0;\n margin: 0;\n min-height: 24px;\n}\n\n.Markup-stylelabel {\n display: flex;\n justify-content: space-between;\n align-items: center;\n white-space: pre;\n width: 100%;\n}\n\n.Markup-stylelabel-keymap {\n display: flex;\n justify-content: flex-end;\n font-size: 1.0rem;\n font-weight: normal;\n color: gray;\n}\n\n.Markup-menu-submenu-wrap:hover .Markup-menu-submenu, .Markup-menu-submenu-wrap-active .Markup-menu-submenu {\n display: block;\n}\n\n.Markup-menu-submenu-wrap {\n position: relative;\n margin-right: -4px;\n background: inherit;\n}\n\n.Markup-menu-submenu {\n display: none;\n min-width: 4em;\n left: 100%;\n top: -5px;\n max-height: 80vh;\n overflow-y: auto;\n /* background cannot be inherited because of hover highlighting in dropdown */\n background: var(--Markup-button-bg, white);\n}\n@media (prefers-color-scheme: dark) {\n .Markup-menu-submenu {\n /* background cannot be inherited because of hover highlighting in dropdown */\n background: var(--Markup-button-bg, black);\n }\n}\n\n.Markup-menu-submenu-label:after {\n content: \"\";\n border-top: 4px solid transparent;\n border-bottom: 4px solid transparent;\n border-left: 4px solid currentColor;\n opacity: .6;\n position: absolute;\n right: 4px;\n top: calc(50% - 4px);\n}\n\n.Markup-selection {\n position: absolute;\n border: 1px solid var(--Markup-accent-color, blue);\n background: transparent;\n}\n@media (prefers-color-scheme: dark) {\n .Markup-selection {\n border: 1px solid var(--Markup-accent-color, lightblue);\n }\n}\n\n/* Toolbar-more styling */\n\n.Markup-toolbar-more {\n display: inline-flex;\n position: sticky;\n overflow: visible;\n width: 100%;\n font-size: var(--Markup-button-font-size, 24px);\n vertical-align: middle;\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n top: calc(var(--Markup-button-size, 28px) + 7px);\n max-height: calc(var(--Markup-button-size, 28px) + 10px);\n padding: 2px 8px;\n color: var(--Markup-accent-color, blue);\n background: var(--Markup-toolbar-bg, rgba(250, 249, 246, 0.95));\n border-bottom: 1px solid var(--Markup-border-color, lightgray);\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n@media (prefers-color-scheme: dark) {\n .Markup-toolbar-more {\n color: var(--Markup-accent-color, lightblue);\n background: var(--Markup-toolbar-bg, rgba(40, 40, 43, 0.9));\n border-bottom: 1px solid var(--Markup-border-color, gray);\n }\n}\n\n/* Searchbar styling */\n\n.Markup-searchbar {\n display: inline-block;\n font-size: var(--Markup-button-font-size, 24px);\n vertical-align: middle;\n position: sticky;\n top: calc(var(--Markup-button-size, 28px) + 7px);\n width: 100%;\n line-height: calc(var(--Markup-button-size, 28px) + 2px);\n height: calc(var(--Markup-button-size, 28px) + 9px);;\n color: var(--Markup-accent-color, blue);\n background: var(--Markup-toolbar-bg, rgba(250, 249, 246, 0.95));\n border-bottom: 1px solid var(--Markup-border-color, lightgray);\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n overflow: hidden;\n}\n@media (prefers-color-scheme: dark) {\n .Markup-searchbar {\n color: var(--Markup-accent-color, lightblue);\n background: var(--Markup-toolbar-bg, rgba(40, 40, 43, 0.9));\n border-bottom: 1px solid var(--Markup-border-color, gray);\n }\n}\n\n.Markup-searchbar input {\n appearance: none; /* Otherwise, in Safari/WebKit, the height is small and fixed */\n position: relative;\n font-size: calc(var(--Markup-button-font-size, 24px) - 6px); \n line-height: calc(var(--Markup-button-size, 28px) + 2px);\n line-height: calc(var(--Markup-button-size, 28px) + 2px);\n width: calc(100% - (3 * (var(--Markup-button-size, 28px) + 12px)) - 8px); /* Three buttons plus spacing and margin */\n margin: 0 8px;\n padding: 0 4px;\n outline: none;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n border: 1px solid lightgray;\n border-radius: 6px;\n}\n@media (prefers-color-scheme: dark) {\n .Markup-searchbar input {\n color: rgb(250, 249, 246);\n background: rgb(40, 40, 43);\n border: 1px solid gray;\n }\n}\n\n.Markup-searchbar .Markup-searchbar-status {\n position: absolute;\n display: flex;\n justify-content: flex-end;\n align-items: center;\n white-space: nowrap;\n font-size: calc(0.5 * var(--Markup-button-font-size, 24px));\n overflow-x: visible;\n height: var(--Markup-button-size, 28px);\n top: 5px;\n left: calc(100% - (4 * (var(--Markup-button-size, 28px) + 12px))); /* Four buttons plus spacing and margin */\n width: 1px;\n color: gray;\n user-select: none;\n}\n\n/* Dialog/prompt styling for insert/edit actions */\n\n.Markup-prompt-overlay {\n\tposition: fixed;\n\ttop: 0;\n\tleft: 0;\n\twidth: 100%;\n\theight: 100%;\n\tbackground-color: rgba(0, 0, 0, 0.2);\n}\n@media (prefers-color-scheme: dark) {\n .Markup-prompt-overlay {\n background-color: rgba(255, 255, 255, 0.2);\n }\n}\n\n.Markup-toolbar-overlay {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\twidth: 100%;\n\tbackground-color: rgba(0, 0, 0, 0.1);\n}\n@media (prefers-color-scheme: dark) {\n .Markup-toolbar-overlay {\n background-color: rgba(255, 255, 255, 0.1);\n }\n}\n\n.Markup-toolbar-overlay.Markup-searchbar-hidden {\n height: calc(var(--Markup-button-size, 28px) + 8px);\n}\n\n.Markup-toolbar-overlay.Markup-searchbar-showing {\n height: calc((var(--Markup-button-size, 28px) + 8px) * 2);\n}\n\n.Markup-prompt {\n margin: 0;\n font-size: 18px;\n background: white;\n padding: 8px;\n border: 1px solid silver;\n position: absolute;\n border-radius: 3px;\n box-shadow: -.5px 2px 5px rgba(0, 0, 0, 0.2);\n}\n@media (prefers-color-scheme: dark) {\n .Markup-prompt {\n background: black;\n box-shadow: -.5px 2px 5px rgba(255, 255, 255, 0.8);\n }\n}\n\n.Markup-prompt-link {\n height: calc(68px + var(--Markup-button-size, 28px)); /* 96 px by default */\n width: 300px;\n}\n\n.Markup-prompt-image {\n height: calc(102px + var(--Markup-button-size, 28px)); /* 130 px by default */\n width: 300px;\n}\n\n.Markup-prompt-language {\n height: calc(68px + var(--Markup-button-size, 28px)); /* 96 px by default */\n width: 300px;\n}\n\n.Markup-prompt img {\n display: inline-block;\n vertical-align: middle;\n min-width: var(--Markup-button-size, 28px);\n height: var(--Markup-button-size, 28px);\n margin-right: 4px;\n}\n\n.Markup-prompt p {\n margin: 0 0 4px 0;\n font-weight: normal;\n color: black;\n}\n@media (prefers-color-scheme: dark) {\n .Markup-prompt p {\n color: white;\n }\n}\n\n.Markup-prompt input[type=\"text\"] {\n font-size: 100%;\n line-height: 28px;\n margin-top: 2px;\n padding: 1px 4px;\n width: 100%;\n appearance: none;\n background: #eee;\n outline: none;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n border: 1px solid lightgray;\n border-radius: 6px;\n}\n@media (prefers-color-scheme: dark) {\n .Markup-prompt input[type=\"text\"] {\n color: rgb(250, 249, 246);\n background: rgb(40, 40, 43);\n border: 1px solid gray;\n }\n}\n\n.Markup-prompt input.invalid {\n color: red;\n}\n@media (prefers-color-scheme: dark) {\n .Markup-prompt input.invalid {\n color: pink;\n }\n}\n\n.Markup-prompt-buttons {\n display: flex;\n vertical-align: middle;\n justify-content: space-between;\n justify-items: center;\n line-height: var(--Markup-button-size, 28px);\n height: var(--Markup-button-size, 28px);\n margin-top: 8px;\n margin-bottom: 8px;\n}\n\n.Markup-prompt-buttongroup {\n flex-shrink: 0;\n}\n\n.Markup-prompt-buttons img {\n aspect-ratio: auto;\n height: auto;\n object-fit: contain;\n}\n\n.Markup-prompt-buttons .Markup-menuitem {\n display: inline-flex;\n padding-right: 4px;\n padding-left: 4px;\n}\n\n/* The buttongroup contains OK and Cancel menuitems on the right */\n.Markup-prompt-buttongroup .Markup-menuitem {\n margin-right: 0;\n margin-left: 4px;\n}\n\n/* .Markup-menu-tablesizer is a specialized submenu */\n.Markup-menu-tablesizer {\n display: none;\n grid-template-columns: repeat(4, 1fr);\n grid-auto-rows: 18px;\n row-gap: 1px;\n column-gap: 1px;\n padding: 0;\n left: 100%;\n top: -5px;\n /* background cannot be inherited because of hover highlighting in dropdown */\n background: var(--Markup-button-bg, white);\n}\n@media (prefers-color-scheme: dark) {\n .Markup-menu-tablesizer {\n /* background cannot be inherited because of hover highlighting in dropdown */\n background: var(--Markup-button-bg, black);\n }\n}\n\n.Markup-menu-submenu-wrap:hover .Markup-menu-tablesizer, .Markup-menu-submenu-wrap-active .Markup-menu-tablesizer {\n display: grid;\n}\n\n.Markup-menu-dropdown-menu, .Markup-menu-tablesizer {\n position: absolute;\n background: inherit;\n padding: 2px;\n background: inherit;\n border: 1px solid var(--Markup-border-color, gray);\n}\n@media (prefers-color-scheme: dark) {\n .Markup-menu-dropdown-menu, .Markup-menu-submenu {\n border: 1px solid var(--Markup-border-color, lightgray);\n }\n}\n\n.Markup-menu-tablesizer .Markup-menu-dropdown-item {\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n border: 1px solid var(--Markup-accent-color, blue);\n width: 18px;\n height: 18px;\n padding: 0;\n font-size: 13px;\n}\n@media (prefers-color-scheme: dark) {\n .Markup-menu-tablesizer .Markup-menu-dropdown-item {\n border: 1px solid var(--Markup-accent-color, lightblue);\n }\n}\n\n.Markup-menu-tablesizer .Markup-menuitem-active {\n height: 13px;\n padding-top: 3px;\n fill: black;\n color: black;\n background: var(--Markup-accent-color, blue);\n}\n@media (prefers-color-scheme: dark) {\n .Markup-menu-tablesizer .Markup-menuitem-active {\n fill: black;\n color: black;\n background: var(--Markup-accent-color, lightblue);\n }\n}");
|
|
6
6
|
|
|
@@ -16577,6 +16577,14 @@ function mustPreserveItems(state) {
|
|
|
16577
16577
|
}
|
|
16578
16578
|
return cachedPreserveItems;
|
|
16579
16579
|
}
|
|
16580
|
+
/**
|
|
16581
|
+
Set a flag on the given transaction that will prevent further steps
|
|
16582
|
+
from being appended to an existing history event (so that they
|
|
16583
|
+
require a separate undo command to undo).
|
|
16584
|
+
*/
|
|
16585
|
+
function closeHistory(tr) {
|
|
16586
|
+
return tr.setMeta(closeHistoryKey, true);
|
|
16587
|
+
}
|
|
16580
16588
|
const historyKey = new PluginKey("history");
|
|
16581
16589
|
const closeHistoryKey = new PluginKey("closeHistory");
|
|
16582
16590
|
/**
|
|
@@ -41508,6 +41516,211 @@ function textblockTypeInputRule(regexp, nodeType, getAttrs = null) {
|
|
|
41508
41516
|
});
|
|
41509
41517
|
}
|
|
41510
41518
|
|
|
41519
|
+
/* eslint no-cond-assign: 0 */
|
|
41520
|
+
|
|
41521
|
+
// : (NodeType) → InputRule
|
|
41522
|
+
// Given a blockquote node type, returns an input rule that turns `"> "`
|
|
41523
|
+
// at the start of a textblock into a blockquote.
|
|
41524
|
+
function blockQuoteRule(nodeType) {
|
|
41525
|
+
return wrappingInputRule(/^\s*>\s$/, nodeType)
|
|
41526
|
+
}
|
|
41527
|
+
|
|
41528
|
+
// : (NodeType) → InputRule
|
|
41529
|
+
// Given a list node type, returns an input rule that turns a number
|
|
41530
|
+
// followed by a dot at the start of a textblock into an ordered list.
|
|
41531
|
+
function orderedListRule(nodeType) {
|
|
41532
|
+
return wrappingInputRule(/^(\d+)\.\s$/, nodeType, match => ({order: +match[1]}),
|
|
41533
|
+
(match, node) => node.childCount + node.attrs.order == +match[1])
|
|
41534
|
+
}
|
|
41535
|
+
|
|
41536
|
+
// : (NodeType) → InputRule
|
|
41537
|
+
// Given a list node type, returns an input rule that turns a bullet
|
|
41538
|
+
// (dash, plush, or asterisk) at the start of a textblock into a
|
|
41539
|
+
// bullet list.
|
|
41540
|
+
function bulletListRule(nodeType) {
|
|
41541
|
+
return wrappingInputRule(/^\s*([-+*])\s$/, nodeType)
|
|
41542
|
+
}
|
|
41543
|
+
|
|
41544
|
+
// : (EditorState, Schema, Object) → ?{$from: ResolvedPos, language: ?string}
|
|
41545
|
+
// Returns the paragraph position and language when the selection is a cursor
|
|
41546
|
+
// at the end of a paragraph that holds only three backticks and an optional
|
|
41547
|
+
// language name, as plain text. Returns null otherwise, including when
|
|
41548
|
+
// markdownShorthand is off.
|
|
41549
|
+
function pendingCodeFence(state, schema, config) {
|
|
41550
|
+
if (!schema.nodes.code_block || config.behavior?.markdownShorthand === false) return null
|
|
41551
|
+
const { $from, empty } = state.selection;
|
|
41552
|
+
const paragraph = $from.parent;
|
|
41553
|
+
if (!empty || paragraph.type !== schema.nodes.paragraph || $from.parentOffset !== paragraph.content.size) return null
|
|
41554
|
+
if (!paragraph.children.every(child => child.isText && child.marks.length === 0)) return null
|
|
41555
|
+
const match = /^```([\w+#.-]*)$/.exec(paragraph.textContent);
|
|
41556
|
+
return match ? { $from, language: match[1] || null } : null
|
|
41557
|
+
}
|
|
41558
|
+
|
|
41559
|
+
// : (Schema, Object) → Command
|
|
41560
|
+
// Returns a command, meant to be chained after the Enter key's other
|
|
41561
|
+
// handlers, that turns a paragraph holding only three backticks and an
|
|
41562
|
+
// optional language name, with the cursor at its end, into an empty code
|
|
41563
|
+
// block with that language. The block is created empty, so typing after it
|
|
41564
|
+
// starts on the first line. It does nothing when markdownShorthand is off.
|
|
41565
|
+
function codeFenceCommand(schema, config = {}) {
|
|
41566
|
+
return (state, dispatch) => {
|
|
41567
|
+
const pending = pendingCodeFence(state, schema, config);
|
|
41568
|
+
if (!pending) return false
|
|
41569
|
+
if (dispatch) {
|
|
41570
|
+
const { $from, language } = pending;
|
|
41571
|
+
const tr = state.tr.delete($from.start(), $from.end());
|
|
41572
|
+
tr.setNodeMarkup($from.before(), schema.nodes.code_block, { language });
|
|
41573
|
+
dispatch(closeHistory(tr).scrollIntoView());
|
|
41574
|
+
}
|
|
41575
|
+
return true
|
|
41576
|
+
}
|
|
41577
|
+
}
|
|
41578
|
+
|
|
41579
|
+
// : (Schema, Object) → Plugin
|
|
41580
|
+
// Returns a plugin that styles the text of a pending code fence like inline
|
|
41581
|
+
// code while Return would turn it into a code block. It only decorates the
|
|
41582
|
+
// view; the document is not changed.
|
|
41583
|
+
function codeFenceHintPlugin(schema, config = {}) {
|
|
41584
|
+
return new Plugin({
|
|
41585
|
+
props: {
|
|
41586
|
+
decorations(state) {
|
|
41587
|
+
const pending = pendingCodeFence(state, schema, config);
|
|
41588
|
+
if (!pending) return null
|
|
41589
|
+
const { $from } = pending;
|
|
41590
|
+
return DecorationSet.create(state.doc, [Decoration.inline($from.start(), $from.end(), { class: "code-fence-pending" })])
|
|
41591
|
+
}
|
|
41592
|
+
}
|
|
41593
|
+
})
|
|
41594
|
+
}
|
|
41595
|
+
|
|
41596
|
+
// : (NodeType, number) → InputRule
|
|
41597
|
+
// Given a node type and a maximum level, creates an input rule that
|
|
41598
|
+
// turns up to that number of `#` characters followed by a space at
|
|
41599
|
+
// the start of a textblock into a heading whose level corresponds to
|
|
41600
|
+
// the number of `#` signs.
|
|
41601
|
+
function headingRule(nodeType, maxLevel) {
|
|
41602
|
+
return textblockTypeInputRule(new RegExp("^(#{1," + maxLevel + "})\\s$"),
|
|
41603
|
+
nodeType, match => ({level: match[1].length}))
|
|
41604
|
+
}
|
|
41605
|
+
|
|
41606
|
+
// : (RegExp, MarkType, number, number) → InputRule
|
|
41607
|
+
// Given a regexp matching a markdown emphasis pattern ending at the
|
|
41608
|
+
// cursor, a mark type, and the lengths of the opening and closing
|
|
41609
|
+
// delimiters, returns an input rule that deletes only the
|
|
41610
|
+
// delimiters -- never the content between them -- and applies the
|
|
41611
|
+
// mark over the untouched range. This preserves any marks (links,
|
|
41612
|
+
// nested emphasis, etc.) already present in the converted range
|
|
41613
|
+
// instead of flattening it to plain text.
|
|
41614
|
+
//
|
|
41615
|
+
// prosemirror-inputrules invokes this handler from handleTextInput,
|
|
41616
|
+
// before the browser's pending keystroke has actually been applied
|
|
41617
|
+
// to the document -- match[0] (built from existing text plus the
|
|
41618
|
+
// not-yet-inserted text) can therefore be longer than end - start.
|
|
41619
|
+
// That trailing slice is inserted first so the full matched range
|
|
41620
|
+
// genuinely exists in the document before the delimiter surgery
|
|
41621
|
+
// below operates on it. Suppressed when the cursor already sits
|
|
41622
|
+
// inside a code mark, since markdown shorthand characters are meant
|
|
41623
|
+
// to stay literal there. Clears the mark from stored marks afterward
|
|
41624
|
+
// so text typed immediately after the conversion does not inherit
|
|
41625
|
+
// it.
|
|
41626
|
+
//
|
|
41627
|
+
// The leading delimiter is deleted before the trailing one, so the
|
|
41628
|
+
// transaction's last content-shifting step is the trailing-delimiter
|
|
41629
|
+
// delete, ending at the cursor -- prosemirror-history's grouping
|
|
41630
|
+
// heuristic only looks at that step's range when deciding whether
|
|
41631
|
+
// the next keystroke belongs to the same undo group (addMark's own
|
|
41632
|
+
// step contributes no range there), so ending at the cursor is what
|
|
41633
|
+
// keeps immediately-following typing (e.g. "**foo**bar") merged with
|
|
41634
|
+
// the conversion into a single undo.
|
|
41635
|
+
function markInputRule(regexp, markType, openLen, closeLen) {
|
|
41636
|
+
return new InputRule(regexp, (state, match, start, end) => {
|
|
41637
|
+
const codeType = state.schema.marks.code;
|
|
41638
|
+
if (codeType && state.doc.resolve(start).marks().some(mark => mark.type === codeType)) return null
|
|
41639
|
+
const tr = state.tr;
|
|
41640
|
+
const fullEnd = start + match[0].length;
|
|
41641
|
+
if (fullEnd > end) tr.insertText(match[0].slice(end - start), end);
|
|
41642
|
+
tr.delete(start, start + openLen);
|
|
41643
|
+
const closeStart = fullEnd - openLen - closeLen;
|
|
41644
|
+
tr.delete(closeStart, closeStart + closeLen);
|
|
41645
|
+
tr.addMark(start, closeStart, markType.create());
|
|
41646
|
+
tr.removeStoredMark(markType);
|
|
41647
|
+
return tr
|
|
41648
|
+
})
|
|
41649
|
+
}
|
|
41650
|
+
|
|
41651
|
+
// : (MarkType) → InputRule
|
|
41652
|
+
// Given the strong mark type, returns an input rule that converts
|
|
41653
|
+
// `**text**` at the cursor into bold.
|
|
41654
|
+
function strongRule(markType) {
|
|
41655
|
+
return markInputRule(/\*\*([^*\s](?:[^*]*[^*\s])?)\*\*$/, markType, 2, 2)
|
|
41656
|
+
}
|
|
41657
|
+
|
|
41658
|
+
// : (MarkType) → InputRule
|
|
41659
|
+
// Given the em mark type, returns an input rule that converts
|
|
41660
|
+
// `*text*` at the cursor into italic. The negative lookbehind on the
|
|
41661
|
+
// opening `*` defers matching until a preceding, still-unconsumed
|
|
41662
|
+
// `*` is no longer in the way, so this rule does not fire on a
|
|
41663
|
+
// partially typed `**text**` before bold's closing marker
|
|
41664
|
+
// completes.
|
|
41665
|
+
function emStarRule(markType) {
|
|
41666
|
+
return markInputRule(/(?<!\*)\*([^*\s](?:[^*]*[^*\s])?)\*$/, markType, 1, 1)
|
|
41667
|
+
}
|
|
41668
|
+
|
|
41669
|
+
// : (MarkType) → InputRule
|
|
41670
|
+
// Given the em mark type, returns an input rule that converts
|
|
41671
|
+
// `_text_` at the cursor into italic. The negative lookbehind on the
|
|
41672
|
+
// opening `_` blocks intraword underscores (`\w` includes `_`), per
|
|
41673
|
+
// CommonMark's flanking rule for `_` emphasis -- unlike `*`, `_`
|
|
41674
|
+
// emphasis must not fire inside a word, so identifiers like
|
|
41675
|
+
// `snake_case_name` stay literal.
|
|
41676
|
+
function emUnderscoreRule(markType) {
|
|
41677
|
+
return markInputRule(/(?<!\w)_([^_\s](?:[^_]*[^_\s])?)_$/, markType, 1, 1)
|
|
41678
|
+
}
|
|
41679
|
+
|
|
41680
|
+
// : (MarkType) → InputRule
|
|
41681
|
+
// Given the code mark type, returns an input rule that converts a
|
|
41682
|
+
// backtick-delimited `text` at the cursor into inline code.
|
|
41683
|
+
function codeRule(markType) {
|
|
41684
|
+
return markInputRule(/(?<!`)`([^`\s](?:[^`]*[^`\s])?)`$/, markType, 1, 1)
|
|
41685
|
+
}
|
|
41686
|
+
|
|
41687
|
+
// : (MarkType) → InputRule
|
|
41688
|
+
// Given the s (strikethrough) mark type, returns an input rule that
|
|
41689
|
+
// converts `~~text~~` at the cursor into strikethrough. No
|
|
41690
|
+
// self-referential lookbehind, matching strongRule -- both are
|
|
41691
|
+
// double-delimiter patterns with no single-character sibling rule to
|
|
41692
|
+
// defer against, unlike emStarRule's genuine need to defer to bold.
|
|
41693
|
+
function strikethroughRule(markType) {
|
|
41694
|
+
return markInputRule(/~~([^~\s](?:[^~]*[^~\s])?)~~$/, markType, 2, 2)
|
|
41695
|
+
}
|
|
41696
|
+
|
|
41697
|
+
// : (Schema, object) → Plugin
|
|
41698
|
+
// A set of input rules for creating the basic block quotes, lists,
|
|
41699
|
+
// heading, and markdown formatting shorthand (bold,
|
|
41700
|
+
// italic, inline code, strikethrough). All nine rules are gated
|
|
41701
|
+
// together by config.behavior.markdownShorthand. config defaults to
|
|
41702
|
+
// {}, so markdownShorthand defaults to enabled (only an explicit
|
|
41703
|
+
// `false` turns it off) when buildInputRules is called without a
|
|
41704
|
+
// config, matching BehaviorConfig's default.
|
|
41705
|
+
function buildInputRules(schema, config = {}) {
|
|
41706
|
+
let rules = [], type;
|
|
41707
|
+
const markdownShorthand = config.behavior?.markdownShorthand !== false;
|
|
41708
|
+
if (markdownShorthand) {
|
|
41709
|
+
if (type = schema.nodes.blockquote) rules.push(blockQuoteRule(type));
|
|
41710
|
+
if (type = schema.nodes.ordered_list) rules.push(orderedListRule(type));
|
|
41711
|
+
if (type = schema.nodes.bullet_list) rules.push(bulletListRule(type));
|
|
41712
|
+
if (type = schema.nodes.heading) rules.push(headingRule(type, 6));
|
|
41713
|
+
if (type = schema.marks.strong) rules.push(strongRule(type));
|
|
41714
|
+
if (type = schema.marks.em) {
|
|
41715
|
+
rules.push(emStarRule(type));
|
|
41716
|
+
rules.push(emUnderscoreRule(type));
|
|
41717
|
+
}
|
|
41718
|
+
if (type = schema.marks.code) rules.push(codeRule(type));
|
|
41719
|
+
if (type = schema.marks.s) rules.push(strikethroughRule(type));
|
|
41720
|
+
}
|
|
41721
|
+
return inputRules({rules})
|
|
41722
|
+
}
|
|
41723
|
+
|
|
41511
41724
|
/**
|
|
41512
41725
|
* Return a map of Commands that will be invoked when key combos are pressed.
|
|
41513
41726
|
*
|
|
@@ -41539,7 +41752,7 @@ function buildKeymap(config, schema) {
|
|
|
41539
41752
|
// the handleEnter with splitListItem that is bound to Enter here, it always executes,
|
|
41540
41753
|
// but splitListItem will also execute, as will anything else beyond it in the chain
|
|
41541
41754
|
// if splitListItem returns false (i.e., it doesn't really split the list).
|
|
41542
|
-
bind("Enter", chainCommands(handleEnter, splitListItem(schema.nodes.list_item)));
|
|
41755
|
+
bind("Enter", chainCommands(handleEnter, codeFenceCommand(schema, config), splitListItem(schema.nodes.list_item)));
|
|
41543
41756
|
// The MarkupEditor handles Shift-Enter as searchBackward when search is active.
|
|
41544
41757
|
bind("Shift-Enter", handleShiftEnter);
|
|
41545
41758
|
// The MarkupEditor needs to be notified of state changes on Delete, like Backspace
|
|
@@ -41714,167 +41927,6 @@ class ToolbarView {
|
|
|
41714
41927
|
|
|
41715
41928
|
}
|
|
41716
41929
|
|
|
41717
|
-
/* eslint no-cond-assign: 0 */
|
|
41718
|
-
|
|
41719
|
-
// : (NodeType) → InputRule
|
|
41720
|
-
// Given a blockquote node type, returns an input rule that turns `"> "`
|
|
41721
|
-
// at the start of a textblock into a blockquote.
|
|
41722
|
-
function blockQuoteRule(nodeType) {
|
|
41723
|
-
return wrappingInputRule(/^\s*>\s$/, nodeType)
|
|
41724
|
-
}
|
|
41725
|
-
|
|
41726
|
-
// : (NodeType) → InputRule
|
|
41727
|
-
// Given a list node type, returns an input rule that turns a number
|
|
41728
|
-
// followed by a dot at the start of a textblock into an ordered list.
|
|
41729
|
-
function orderedListRule(nodeType) {
|
|
41730
|
-
return wrappingInputRule(/^(\d+)\.\s$/, nodeType, match => ({order: +match[1]}),
|
|
41731
|
-
(match, node) => node.childCount + node.attrs.order == +match[1])
|
|
41732
|
-
}
|
|
41733
|
-
|
|
41734
|
-
// : (NodeType) → InputRule
|
|
41735
|
-
// Given a list node type, returns an input rule that turns a bullet
|
|
41736
|
-
// (dash, plush, or asterisk) at the start of a textblock into a
|
|
41737
|
-
// bullet list.
|
|
41738
|
-
function bulletListRule(nodeType) {
|
|
41739
|
-
return wrappingInputRule(/^\s*([-+*])\s$/, nodeType)
|
|
41740
|
-
}
|
|
41741
|
-
|
|
41742
|
-
// : (NodeType) → InputRule
|
|
41743
|
-
// Given a code block node type, returns an input rule that turns a
|
|
41744
|
-
// textblock starting with three backticks into a code block.
|
|
41745
|
-
function codeBlockRule(nodeType) {
|
|
41746
|
-
return textblockTypeInputRule(/^```$/, nodeType)
|
|
41747
|
-
}
|
|
41748
|
-
|
|
41749
|
-
// : (NodeType, number) → InputRule
|
|
41750
|
-
// Given a node type and a maximum level, creates an input rule that
|
|
41751
|
-
// turns up to that number of `#` characters followed by a space at
|
|
41752
|
-
// the start of a textblock into a heading whose level corresponds to
|
|
41753
|
-
// the number of `#` signs.
|
|
41754
|
-
function headingRule(nodeType, maxLevel) {
|
|
41755
|
-
return textblockTypeInputRule(new RegExp("^(#{1," + maxLevel + "})\\s$"),
|
|
41756
|
-
nodeType, match => ({level: match[1].length}))
|
|
41757
|
-
}
|
|
41758
|
-
|
|
41759
|
-
// : (RegExp, MarkType, number, number) → InputRule
|
|
41760
|
-
// Given a regexp matching a markdown emphasis pattern ending at the
|
|
41761
|
-
// cursor, a mark type, and the lengths of the opening and closing
|
|
41762
|
-
// delimiters, returns an input rule that deletes only the
|
|
41763
|
-
// delimiters -- never the content between them -- and applies the
|
|
41764
|
-
// mark over the untouched range. This preserves any marks (links,
|
|
41765
|
-
// nested emphasis, etc.) already present in the converted range
|
|
41766
|
-
// instead of flattening it to plain text.
|
|
41767
|
-
//
|
|
41768
|
-
// prosemirror-inputrules invokes this handler from handleTextInput,
|
|
41769
|
-
// before the browser's pending keystroke has actually been applied
|
|
41770
|
-
// to the document -- match[0] (built from existing text plus the
|
|
41771
|
-
// not-yet-inserted text) can therefore be longer than end - start.
|
|
41772
|
-
// That trailing slice is inserted first so the full matched range
|
|
41773
|
-
// genuinely exists in the document before the delimiter surgery
|
|
41774
|
-
// below operates on it. Suppressed when the cursor already sits
|
|
41775
|
-
// inside a code mark, since markdown shorthand characters are meant
|
|
41776
|
-
// to stay literal there. Clears the mark from stored marks afterward
|
|
41777
|
-
// so text typed immediately after the conversion does not inherit
|
|
41778
|
-
// it.
|
|
41779
|
-
//
|
|
41780
|
-
// The leading delimiter is deleted before the trailing one, so the
|
|
41781
|
-
// transaction's last content-shifting step is the trailing-delimiter
|
|
41782
|
-
// delete, ending at the cursor -- prosemirror-history's grouping
|
|
41783
|
-
// heuristic only looks at that step's range when deciding whether
|
|
41784
|
-
// the next keystroke belongs to the same undo group (addMark's own
|
|
41785
|
-
// step contributes no range there), so ending at the cursor is what
|
|
41786
|
-
// keeps immediately-following typing (e.g. "**foo**bar") merged with
|
|
41787
|
-
// the conversion into a single undo.
|
|
41788
|
-
function markInputRule(regexp, markType, openLen, closeLen) {
|
|
41789
|
-
return new InputRule(regexp, (state, match, start, end) => {
|
|
41790
|
-
const codeType = state.schema.marks.code;
|
|
41791
|
-
if (codeType && state.doc.resolve(start).marks().some(mark => mark.type === codeType)) return null
|
|
41792
|
-
const tr = state.tr;
|
|
41793
|
-
const fullEnd = start + match[0].length;
|
|
41794
|
-
if (fullEnd > end) tr.insertText(match[0].slice(end - start), end);
|
|
41795
|
-
tr.delete(start, start + openLen);
|
|
41796
|
-
const closeStart = fullEnd - openLen - closeLen;
|
|
41797
|
-
tr.delete(closeStart, closeStart + closeLen);
|
|
41798
|
-
tr.addMark(start, closeStart, markType.create());
|
|
41799
|
-
tr.removeStoredMark(markType);
|
|
41800
|
-
return tr
|
|
41801
|
-
})
|
|
41802
|
-
}
|
|
41803
|
-
|
|
41804
|
-
// : (MarkType) → InputRule
|
|
41805
|
-
// Given the strong mark type, returns an input rule that converts
|
|
41806
|
-
// `**text**` at the cursor into bold.
|
|
41807
|
-
function strongRule(markType) {
|
|
41808
|
-
return markInputRule(/\*\*([^*\s](?:[^*]*[^*\s])?)\*\*$/, markType, 2, 2)
|
|
41809
|
-
}
|
|
41810
|
-
|
|
41811
|
-
// : (MarkType) → InputRule
|
|
41812
|
-
// Given the em mark type, returns an input rule that converts
|
|
41813
|
-
// `*text*` at the cursor into italic. The negative lookbehind on the
|
|
41814
|
-
// opening `*` defers matching until a preceding, still-unconsumed
|
|
41815
|
-
// `*` is no longer in the way, so this rule does not fire on a
|
|
41816
|
-
// partially typed `**text**` before bold's closing marker
|
|
41817
|
-
// completes.
|
|
41818
|
-
function emStarRule(markType) {
|
|
41819
|
-
return markInputRule(/(?<!\*)\*([^*\s](?:[^*]*[^*\s])?)\*$/, markType, 1, 1)
|
|
41820
|
-
}
|
|
41821
|
-
|
|
41822
|
-
// : (MarkType) → InputRule
|
|
41823
|
-
// Given the em mark type, returns an input rule that converts
|
|
41824
|
-
// `_text_` at the cursor into italic. The negative lookbehind on the
|
|
41825
|
-
// opening `_` blocks intraword underscores (`\w` includes `_`), per
|
|
41826
|
-
// CommonMark's flanking rule for `_` emphasis -- unlike `*`, `_`
|
|
41827
|
-
// emphasis must not fire inside a word, so identifiers like
|
|
41828
|
-
// `snake_case_name` stay literal.
|
|
41829
|
-
function emUnderscoreRule(markType) {
|
|
41830
|
-
return markInputRule(/(?<!\w)_([^_\s](?:[^_]*[^_\s])?)_$/, markType, 1, 1)
|
|
41831
|
-
}
|
|
41832
|
-
|
|
41833
|
-
// : (MarkType) → InputRule
|
|
41834
|
-
// Given the code mark type, returns an input rule that converts a
|
|
41835
|
-
// backtick-delimited `text` at the cursor into inline code.
|
|
41836
|
-
function codeRule(markType) {
|
|
41837
|
-
return markInputRule(/(?<!`)`([^`\s](?:[^`]*[^`\s])?)`$/, markType, 1, 1)
|
|
41838
|
-
}
|
|
41839
|
-
|
|
41840
|
-
// : (MarkType) → InputRule
|
|
41841
|
-
// Given the s (strikethrough) mark type, returns an input rule that
|
|
41842
|
-
// converts `~~text~~` at the cursor into strikethrough. No
|
|
41843
|
-
// self-referential lookbehind, matching strongRule -- both are
|
|
41844
|
-
// double-delimiter patterns with no single-character sibling rule to
|
|
41845
|
-
// defer against, unlike emStarRule's genuine need to defer to bold.
|
|
41846
|
-
function strikethroughRule(markType) {
|
|
41847
|
-
return markInputRule(/~~([^~\s](?:[^~]*[^~\s])?)~~$/, markType, 2, 2)
|
|
41848
|
-
}
|
|
41849
|
-
|
|
41850
|
-
// : (Schema, object) → Plugin
|
|
41851
|
-
// A set of input rules for creating the basic block quotes, lists,
|
|
41852
|
-
// code blocks, heading, and markdown formatting shorthand (bold,
|
|
41853
|
-
// italic, inline code, strikethrough). All ten rules are gated
|
|
41854
|
-
// together by config.behavior.markdownShorthand. config defaults to
|
|
41855
|
-
// {}, so markdownShorthand defaults to enabled (only an explicit
|
|
41856
|
-
// `false` turns it off) when buildInputRules is called without a
|
|
41857
|
-
// config, matching BehaviorConfig's default.
|
|
41858
|
-
function buildInputRules(schema, config = {}) {
|
|
41859
|
-
let rules = [], type;
|
|
41860
|
-
const markdownShorthand = config.behavior?.markdownShorthand !== false;
|
|
41861
|
-
if (markdownShorthand) {
|
|
41862
|
-
if (type = schema.nodes.blockquote) rules.push(blockQuoteRule(type));
|
|
41863
|
-
if (type = schema.nodes.ordered_list) rules.push(orderedListRule(type));
|
|
41864
|
-
if (type = schema.nodes.bullet_list) rules.push(bulletListRule(type));
|
|
41865
|
-
if (type = schema.nodes.code_block) rules.push(codeBlockRule(type));
|
|
41866
|
-
if (type = schema.nodes.heading) rules.push(headingRule(type, 6));
|
|
41867
|
-
if (type = schema.marks.strong) rules.push(strongRule(type));
|
|
41868
|
-
if (type = schema.marks.em) {
|
|
41869
|
-
rules.push(emStarRule(type));
|
|
41870
|
-
rules.push(emUnderscoreRule(type));
|
|
41871
|
-
}
|
|
41872
|
-
if (type = schema.marks.code) rules.push(codeRule(type));
|
|
41873
|
-
if (type = schema.marks.s) rules.push(strikethroughRule(type));
|
|
41874
|
-
}
|
|
41875
|
-
return inputRules({rules})
|
|
41876
|
-
}
|
|
41877
|
-
|
|
41878
41930
|
/**
|
|
41879
41931
|
* The tablePlugin handles decorations that add CSS styling
|
|
41880
41932
|
* for table borders.
|
|
@@ -41992,7 +42044,16 @@ const codeHighlightPlugin = new Plugin({
|
|
|
41992
42044
|
}
|
|
41993
42045
|
},
|
|
41994
42046
|
props: {
|
|
41995
|
-
|
|
42047
|
+
// The code_block holding the selection is left unhighlighted. Highlighting
|
|
42048
|
+
// wraps the text in spans that are rebuilt as it changes, which breaks the
|
|
42049
|
+
// system's inline predictions while typing. The block is highlighted again
|
|
42050
|
+
// when the selection leaves it.
|
|
42051
|
+
decorations(state) {
|
|
42052
|
+
const {decorations} = codeHighlightPlugin.getState(state);
|
|
42053
|
+
const editing = codeBlockAtSelection(state);
|
|
42054
|
+
if (!editing) return decorations
|
|
42055
|
+
return decorations.remove(decorations.find(editing.pos, editing.pos + editing.node.nodeSize))
|
|
42056
|
+
}
|
|
41996
42057
|
}
|
|
41997
42058
|
});
|
|
41998
42059
|
|
|
@@ -42153,6 +42214,7 @@ function markupSetup(config, schema) {
|
|
|
42153
42214
|
setPrefix('Markup');
|
|
42154
42215
|
let plugins = [
|
|
42155
42216
|
buildInputRules(schema, config),
|
|
42217
|
+
codeFenceHintPlugin(schema, config),
|
|
42156
42218
|
keymap(buildKeymap(config, schema)),
|
|
42157
42219
|
keymap(baseKeymap),
|
|
42158
42220
|
dropCursor(),
|
package/package.json
CHANGED
package/styles/markup.css
CHANGED
|
@@ -164,6 +164,18 @@ p code, h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
|
|
|
164
164
|
display: inline;
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
+
/* Text that Return will turn into a code block, styled like inline code. */
|
|
168
|
+
.code-fence-pending {
|
|
169
|
+
background-color: #F8F8F8;
|
|
170
|
+
border-radius: 3px;
|
|
171
|
+
font-family: 'SF Mono', SFMono-Regular, ui-monospace, 'DejaVu Sans Mono', Menlo, Consolas, monospace;
|
|
172
|
+
}
|
|
173
|
+
@media (prefers-color-scheme: dark) {
|
|
174
|
+
.code-fence-pending {
|
|
175
|
+
background-color: #808080;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
167
179
|
.resize-container {
|
|
168
180
|
position: relative;
|
|
169
181
|
display: inline-block;
|