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.
@@ -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
- decorations(state) { return codeHighlightPlugin.getState(state).decorations }
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "markupeditor",
3
- "version": "0.9.50",
3
+ "version": "0.9.52",
4
4
  "description": "A web component and API for WYSIWYG HTML editing.",
5
5
  "keywords": [
6
6
  "wysiwyg",
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;