@gravity-ui/markdown-editor 15.36.0 → 15.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -0
- package/build/cjs/core/ExtensionBuilder.d.ts +21 -0
- package/build/cjs/core/ExtensionBuilder.js +306 -4
- package/build/cjs/core/ExtensionBuilder.js.map +1 -1
- package/build/cjs/core/markdown/MarkdownSerializer.d.ts +4 -1
- package/build/cjs/core/markdown/MarkdownSerializer.js +86 -23
- package/build/cjs/core/markdown/MarkdownSerializer.js.map +1 -1
- package/build/cjs/extensions/additional/QuoteLink/QuoteLinkSpecs/index.js +1 -0
- package/build/cjs/extensions/additional/QuoteLink/QuoteLinkSpecs/index.js.map +1 -1
- package/build/cjs/extensions/behavior/Clipboard/clipboard.js +2 -13
- package/build/cjs/extensions/behavior/Clipboard/clipboard.js.map +1 -1
- package/build/cjs/extensions/behavior/Clipboard/selection-content.d.ts +1 -0
- package/build/cjs/extensions/behavior/Clipboard/selection-content.js +35 -0
- package/build/cjs/extensions/behavior/Clipboard/selection-content.js.map +1 -0
- package/build/cjs/extensions/behavior/Selection/commands.d.ts +2 -1
- package/build/cjs/extensions/behavior/Selection/commands.js +47 -1
- package/build/cjs/extensions/behavior/Selection/commands.js.map +1 -1
- package/build/cjs/extensions/behavior/Selection/selection.d.ts +15 -0
- package/build/cjs/extensions/behavior/Selection/selection.js +1 -0
- package/build/cjs/extensions/behavior/Selection/selection.js.map +1 -1
- package/build/cjs/extensions/behavior/SelectionContext/TextSelectionTooltip.d.ts +13 -0
- package/build/cjs/extensions/behavior/SelectionContext/TextSelectionTooltip.js +42 -0
- package/build/cjs/extensions/behavior/SelectionContext/TextSelectionTooltip.js.map +1 -0
- package/build/cjs/extensions/behavior/SelectionContext/index.js +10 -7
- package/build/cjs/extensions/behavior/SelectionContext/index.js.map +1 -1
- package/build/cjs/extensions/behavior/SelectionContext/tooltip.d.ts +11 -15
- package/build/cjs/extensions/behavior/SelectionContext/tooltip.js +24 -56
- package/build/cjs/extensions/behavior/SelectionContext/tooltip.js.map +1 -1
- package/build/cjs/extensions/behavior/SelectionContext/types.d.ts +10 -0
- package/build/cjs/extensions/behavior/SelectionContext/types.js +3 -0
- package/build/cjs/extensions/behavior/SelectionContext/types.js.map +1 -0
- package/build/cjs/extensions/markdown/Blockquote/BlockquoteSpecs/index.js +1 -0
- package/build/cjs/extensions/markdown/Blockquote/BlockquoteSpecs/index.js.map +1 -1
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.d.ts +2 -2
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.js +17 -75
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.js.map +1 -1
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/CodeBlockToolbar.d.ts +14 -0
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/CodeBlockToolbar.js +117 -0
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/CodeBlockToolbar.js.map +1 -0
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/CodeLangSelect.d.ts +9 -0
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/CodeLangSelect.js +22 -0
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/CodeLangSelect.js.map +1 -0
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/index.d.ts +2 -3
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/index.js +5 -93
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/index.js.map +1 -1
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/plugins/codeBlockLangsPlugin.d.ts +23 -0
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/plugins/codeBlockLangsPlugin.js +88 -0
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockHighlight/plugins/codeBlockLangsPlugin.js.map +1 -0
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockSpecs/index.js +24 -34
- package/build/cjs/extensions/markdown/CodeBlock/CodeBlockSpecs/index.js.map +1 -1
- package/build/cjs/extensions/markdown/Deflist/DeflistSpecs/schema.js +2 -0
- package/build/cjs/extensions/markdown/Deflist/DeflistSpecs/schema.js.map +1 -1
- package/build/cjs/extensions/markdown/Heading/HeadingSpecs/const.d.ts +4 -0
- package/build/cjs/extensions/markdown/Heading/HeadingSpecs/const.js +9 -0
- package/build/cjs/extensions/markdown/Heading/HeadingSpecs/const.js.map +1 -0
- package/build/cjs/extensions/markdown/Heading/HeadingSpecs/index.d.ts +3 -5
- package/build/cjs/extensions/markdown/Heading/HeadingSpecs/index.js +22 -25
- package/build/cjs/extensions/markdown/Heading/HeadingSpecs/index.js.map +1 -1
- package/build/cjs/extensions/markdown/Heading/HeadingSpecs/utils.d.ts +7 -0
- package/build/cjs/extensions/markdown/Heading/HeadingSpecs/utils.js +15 -0
- package/build/cjs/extensions/markdown/Heading/HeadingSpecs/utils.js.map +1 -0
- package/build/cjs/extensions/markdown/Heading/actions.d.ts +2 -2
- package/build/cjs/extensions/markdown/Heading/actions.js +3 -4
- package/build/cjs/extensions/markdown/Heading/actions.js.map +1 -1
- package/build/cjs/extensions/markdown/Heading/commands.d.ts +3 -1
- package/build/cjs/extensions/markdown/Heading/commands.js +16 -1
- package/build/cjs/extensions/markdown/Heading/commands.js.map +1 -1
- package/build/cjs/extensions/markdown/Heading/index.js +7 -9
- package/build/cjs/extensions/markdown/Heading/index.js.map +1 -1
- package/build/cjs/extensions/markdown/Lists/index.js +1 -0
- package/build/cjs/extensions/markdown/Lists/index.js.map +1 -1
- package/build/cjs/extensions/markdown/Lists/plugins/CollapseListsPlugin.d.ts +14 -2
- package/build/cjs/extensions/markdown/Lists/plugins/CollapseListsPlugin.js +97 -51
- package/build/cjs/extensions/markdown/Lists/plugins/CollapseListsPlugin.js.map +1 -1
- package/build/cjs/extensions/markdown/Table/TableSpecs/schema.js +1 -0
- package/build/cjs/extensions/markdown/Table/TableSpecs/schema.js.map +1 -1
- package/build/cjs/extensions/yfm/YfmCut/YfmCutSpecs/schema.js +2 -0
- package/build/cjs/extensions/yfm/YfmCut/YfmCutSpecs/schema.js.map +1 -1
- package/build/cjs/extensions/yfm/YfmHeading/YfmHeadingSpecs/const.d.ts +1 -1
- package/build/cjs/extensions/yfm/YfmHeading/YfmHeadingSpecs/const.js +2 -2
- package/build/cjs/extensions/yfm/YfmHeading/YfmHeadingSpecs/const.js.map +1 -1
- package/build/cjs/extensions/yfm/YfmHeading/YfmHeadingSpecs/index.d.ts +3 -7
- package/build/cjs/extensions/yfm/YfmHeading/YfmHeadingSpecs/index.js +72 -90
- package/build/cjs/extensions/yfm/YfmHeading/YfmHeadingSpecs/index.js.map +1 -1
- package/build/cjs/extensions/yfm/YfmHeading/YfmHeadingSpecs/utils.d.ts +3 -0
- package/build/cjs/extensions/yfm/YfmHeading/YfmHeadingSpecs/utils.js +14 -1
- package/build/cjs/extensions/yfm/YfmHeading/YfmHeadingSpecs/utils.js.map +1 -1
- package/build/cjs/extensions/yfm/YfmHeading/actions.js +2 -10
- package/build/cjs/extensions/yfm/YfmHeading/actions.js.map +1 -1
- package/build/cjs/extensions/yfm/YfmHeading/commands.d.ts +1 -4
- package/build/cjs/extensions/yfm/YfmHeading/commands.js +3 -21
- package/build/cjs/extensions/yfm/YfmHeading/commands.js.map +1 -1
- package/build/cjs/extensions/yfm/YfmHeading/index.d.ts +3 -22
- package/build/cjs/extensions/yfm/YfmHeading/index.js +2 -33
- package/build/cjs/extensions/yfm/YfmHeading/index.js.map +1 -1
- package/build/cjs/extensions/yfm/YfmNote/YfmNoteSpecs/schema.js +2 -0
- package/build/cjs/extensions/yfm/YfmNote/YfmNoteSpecs/schema.js.map +1 -1
- package/build/cjs/extensions/yfm/YfmNote/plugins/YfmNoteTooltipPlugin/YfmNoteToolbar.css +20 -0
- package/build/cjs/extensions/yfm/YfmNote/plugins/YfmNoteTooltipPlugin/YfmNoteToolbar.d.ts +9 -0
- package/build/cjs/extensions/yfm/YfmNote/plugins/YfmNoteTooltipPlugin/YfmNoteToolbar.js +77 -0
- package/build/cjs/extensions/yfm/YfmNote/plugins/YfmNoteTooltipPlugin/YfmNoteToolbar.js.map +1 -0
- package/build/cjs/extensions/yfm/YfmNote/plugins/YfmNoteTooltipPlugin/index.d.ts +1 -2
- package/build/cjs/extensions/yfm/YfmNote/plugins/YfmNoteTooltipPlugin/index.js +5 -65
- package/build/cjs/extensions/yfm/YfmNote/plugins/YfmNoteTooltipPlugin/index.js.map +1 -1
- package/build/cjs/extensions/yfm/YfmTable/YfmTableSpecs/schema.js +2 -0
- package/build/cjs/extensions/yfm/YfmTable/YfmTableSpecs/schema.js.map +1 -1
- package/build/cjs/extensions/yfm/YfmTabs/YfmTabsSpecs/schema.js +3 -0
- package/build/cjs/extensions/yfm/YfmTabs/YfmTabsSpecs/schema.js.map +1 -1
- package/build/cjs/plugins/BaseTooltip/index.d.ts +1 -0
- package/build/cjs/plugins/BaseTooltip/index.js +4 -3
- package/build/cjs/plugins/BaseTooltip/index.js.map +1 -1
- package/build/cjs/presets/yfm-specs.js +5 -1
- package/build/cjs/presets/yfm-specs.js.map +1 -1
- package/build/cjs/presets/yfm.js +5 -1
- package/build/cjs/presets/yfm.js.map +1 -1
- package/build/cjs/toolbar/ToolbarGroup.js +4 -3
- package/build/cjs/toolbar/ToolbarGroup.js.map +1 -1
- package/build/cjs/toolbar/types.d.ts +2 -0
- package/build/cjs/toolbar/types.js.map +1 -1
- package/build/cjs/version.js +1 -1
- package/build/cjs/version.js.map +1 -1
- package/build/esm/core/ExtensionBuilder.d.ts +21 -0
- package/build/esm/core/ExtensionBuilder.js +306 -4
- package/build/esm/core/ExtensionBuilder.js.map +1 -1
- package/build/esm/core/markdown/MarkdownSerializer.d.ts +4 -1
- package/build/esm/core/markdown/MarkdownSerializer.js +86 -23
- package/build/esm/core/markdown/MarkdownSerializer.js.map +1 -1
- package/build/esm/extensions/additional/QuoteLink/QuoteLinkSpecs/index.js +1 -0
- package/build/esm/extensions/additional/QuoteLink/QuoteLinkSpecs/index.js.map +1 -1
- package/build/esm/extensions/behavior/Clipboard/clipboard.js +1 -12
- package/build/esm/extensions/behavior/Clipboard/clipboard.js.map +1 -1
- package/build/esm/extensions/behavior/Clipboard/selection-content.d.ts +1 -0
- package/build/esm/extensions/behavior/Clipboard/selection-content.js +32 -0
- package/build/esm/extensions/behavior/Clipboard/selection-content.js.map +1 -0
- package/build/esm/extensions/behavior/Selection/commands.d.ts +2 -1
- package/build/esm/extensions/behavior/Selection/commands.js +47 -2
- package/build/esm/extensions/behavior/Selection/commands.js.map +1 -1
- package/build/esm/extensions/behavior/Selection/selection.d.ts +15 -0
- package/build/esm/extensions/behavior/Selection/selection.js +2 -1
- package/build/esm/extensions/behavior/Selection/selection.js.map +1 -1
- package/build/esm/extensions/behavior/SelectionContext/TextSelectionTooltip.d.ts +13 -0
- package/build/esm/extensions/behavior/SelectionContext/TextSelectionTooltip.js +38 -0
- package/build/esm/extensions/behavior/SelectionContext/TextSelectionTooltip.js.map +1 -0
- package/build/esm/extensions/behavior/SelectionContext/index.js +10 -7
- package/build/esm/extensions/behavior/SelectionContext/index.js.map +1 -1
- package/build/esm/extensions/behavior/SelectionContext/tooltip.d.ts +11 -15
- package/build/esm/extensions/behavior/SelectionContext/tooltip.js +24 -56
- package/build/esm/extensions/behavior/SelectionContext/tooltip.js.map +1 -1
- package/build/esm/extensions/behavior/SelectionContext/types.d.ts +10 -0
- package/build/esm/extensions/behavior/SelectionContext/types.js +2 -0
- package/build/esm/extensions/behavior/SelectionContext/types.js.map +1 -0
- package/build/esm/extensions/markdown/Blockquote/BlockquoteSpecs/index.js +1 -0
- package/build/esm/extensions/markdown/Blockquote/BlockquoteSpecs/index.js.map +1 -1
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.d.ts +2 -2
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.js +17 -75
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/CodeBlockHighlight.js.map +1 -1
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/CodeBlockToolbar.d.ts +14 -0
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/CodeBlockToolbar.js +114 -0
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/CodeBlockToolbar.js.map +1 -0
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/CodeLangSelect.d.ts +9 -0
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/CodeLangSelect.js +19 -0
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/CodeLangSelect.js.map +1 -0
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/index.d.ts +2 -3
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/index.js +6 -94
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/TooltipPlugin/index.js.map +1 -1
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/plugins/codeBlockLangsPlugin.d.ts +23 -0
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/plugins/codeBlockLangsPlugin.js +83 -0
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockHighlight/plugins/codeBlockLangsPlugin.js.map +1 -0
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockSpecs/index.js +24 -34
- package/build/esm/extensions/markdown/CodeBlock/CodeBlockSpecs/index.js.map +1 -1
- package/build/esm/extensions/markdown/Deflist/DeflistSpecs/schema.js +2 -0
- package/build/esm/extensions/markdown/Deflist/DeflistSpecs/schema.js.map +1 -1
- package/build/esm/extensions/markdown/Heading/HeadingSpecs/const.d.ts +4 -0
- package/build/esm/extensions/markdown/Heading/HeadingSpecs/const.js +6 -0
- package/build/esm/extensions/markdown/Heading/HeadingSpecs/const.js.map +1 -0
- package/build/esm/extensions/markdown/Heading/HeadingSpecs/index.d.ts +3 -5
- package/build/esm/extensions/markdown/Heading/HeadingSpecs/index.js +5 -10
- package/build/esm/extensions/markdown/Heading/HeadingSpecs/index.js.map +1 -1
- package/build/esm/extensions/markdown/Heading/HeadingSpecs/utils.d.ts +7 -0
- package/build/esm/extensions/markdown/Heading/HeadingSpecs/utils.js +12 -0
- package/build/esm/extensions/markdown/Heading/HeadingSpecs/utils.js.map +1 -0
- package/build/esm/extensions/markdown/Heading/actions.d.ts +2 -2
- package/build/esm/extensions/markdown/Heading/actions.js +3 -4
- package/build/esm/extensions/markdown/Heading/actions.js.map +1 -1
- package/build/esm/extensions/markdown/Heading/commands.d.ts +3 -1
- package/build/esm/extensions/markdown/Heading/commands.js +15 -1
- package/build/esm/extensions/markdown/Heading/commands.js.map +1 -1
- package/build/esm/extensions/markdown/Heading/index.js +9 -11
- package/build/esm/extensions/markdown/Heading/index.js.map +1 -1
- package/build/esm/extensions/markdown/Lists/index.js +1 -0
- package/build/esm/extensions/markdown/Lists/index.js.map +1 -1
- package/build/esm/extensions/markdown/Lists/plugins/CollapseListsPlugin.d.ts +14 -2
- package/build/esm/extensions/markdown/Lists/plugins/CollapseListsPlugin.js +95 -49
- package/build/esm/extensions/markdown/Lists/plugins/CollapseListsPlugin.js.map +1 -1
- package/build/esm/extensions/markdown/Table/TableSpecs/schema.js +1 -0
- package/build/esm/extensions/markdown/Table/TableSpecs/schema.js.map +1 -1
- package/build/esm/extensions/yfm/YfmCut/YfmCutSpecs/schema.js +2 -0
- package/build/esm/extensions/yfm/YfmCut/YfmCutSpecs/schema.js.map +1 -1
- package/build/esm/extensions/yfm/YfmHeading/YfmHeadingSpecs/const.d.ts +1 -1
- package/build/esm/extensions/yfm/YfmHeading/YfmHeadingSpecs/const.js +3 -3
- package/build/esm/extensions/yfm/YfmHeading/YfmHeadingSpecs/const.js.map +1 -1
- package/build/esm/extensions/yfm/YfmHeading/YfmHeadingSpecs/index.d.ts +3 -7
- package/build/esm/extensions/yfm/YfmHeading/YfmHeadingSpecs/index.js +70 -90
- package/build/esm/extensions/yfm/YfmHeading/YfmHeadingSpecs/index.js.map +1 -1
- package/build/esm/extensions/yfm/YfmHeading/YfmHeadingSpecs/utils.d.ts +3 -0
- package/build/esm/extensions/yfm/YfmHeading/YfmHeadingSpecs/utils.js +11 -0
- package/build/esm/extensions/yfm/YfmHeading/YfmHeadingSpecs/utils.js.map +1 -1
- package/build/esm/extensions/yfm/YfmHeading/actions.js +2 -10
- package/build/esm/extensions/yfm/YfmHeading/actions.js.map +1 -1
- package/build/esm/extensions/yfm/YfmHeading/commands.d.ts +1 -4
- package/build/esm/extensions/yfm/YfmHeading/commands.js +3 -21
- package/build/esm/extensions/yfm/YfmHeading/commands.js.map +1 -1
- package/build/esm/extensions/yfm/YfmHeading/index.d.ts +3 -22
- package/build/esm/extensions/yfm/YfmHeading/index.js +0 -31
- package/build/esm/extensions/yfm/YfmHeading/index.js.map +1 -1
- package/build/esm/extensions/yfm/YfmNote/YfmNoteSpecs/schema.js +2 -0
- package/build/esm/extensions/yfm/YfmNote/YfmNoteSpecs/schema.js.map +1 -1
- package/build/esm/extensions/yfm/YfmNote/plugins/YfmNoteTooltipPlugin/YfmNoteToolbar.css +20 -0
- package/build/esm/extensions/yfm/YfmNote/plugins/YfmNoteTooltipPlugin/YfmNoteToolbar.d.ts +9 -0
- package/build/esm/extensions/yfm/YfmNote/plugins/YfmNoteTooltipPlugin/YfmNoteToolbar.js +74 -0
- package/build/esm/extensions/yfm/YfmNote/plugins/YfmNoteTooltipPlugin/YfmNoteToolbar.js.map +1 -0
- package/build/esm/extensions/yfm/YfmNote/plugins/YfmNoteTooltipPlugin/index.d.ts +1 -2
- package/build/esm/extensions/yfm/YfmNote/plugins/YfmNoteTooltipPlugin/index.js +4 -64
- package/build/esm/extensions/yfm/YfmNote/plugins/YfmNoteTooltipPlugin/index.js.map +1 -1
- package/build/esm/extensions/yfm/YfmTable/YfmTableSpecs/schema.js +2 -0
- package/build/esm/extensions/yfm/YfmTable/YfmTableSpecs/schema.js.map +1 -1
- package/build/esm/extensions/yfm/YfmTabs/YfmTabsSpecs/schema.js +3 -0
- package/build/esm/extensions/yfm/YfmTabs/YfmTabsSpecs/schema.js.map +1 -1
- package/build/esm/plugins/BaseTooltip/index.d.ts +1 -0
- package/build/esm/plugins/BaseTooltip/index.js +4 -3
- package/build/esm/plugins/BaseTooltip/index.js.map +1 -1
- package/build/esm/presets/yfm-specs.js +5 -1
- package/build/esm/presets/yfm-specs.js.map +1 -1
- package/build/esm/presets/yfm.js +5 -1
- package/build/esm/presets/yfm.js.map +1 -1
- package/build/esm/toolbar/ToolbarGroup.js +4 -3
- package/build/esm/toolbar/ToolbarGroup.js.map +1 -1
- package/build/esm/toolbar/types.d.ts +2 -0
- package/build/esm/toolbar/types.js.map +1 -1
- package/build/esm/version.js +1 -1
- package/build/esm/version.js.map +1 -1
- package/build/styles.css +9 -5
- package/package.json +5 -4
- package/build/cjs/extensions/yfm/YfmNote/plugins/YfmNoteTooltipPlugin/index.css +0 -16
- package/build/esm/extensions/yfm/YfmNote/plugins/YfmNoteTooltipPlugin/index.css +0 -16
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selection-content.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/Clipboard/selection-content.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAc;IAC9C,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,iBAAiB,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;IAEvD,IAAI,iBAAiB,IAAI,iBAAiB,KAAK,MAAM,EAAE,CAAC;QACpD,yDAAyD;QACzD,6EAA6E;QAC7E,IAAI,SAAS,GAAG,WAAW,CAAC;QAC5B,KAAK,IAAI,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;gBACjD,SAAS,GAAG,CAAC,CAAC;gBACd,MAAM;YACV,CAAC;QACL,CAAC;QAED,sEAAsE;QACtE,iFAAiF;QACjF,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC;QAC/C,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC/C,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACjD,OAAO,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,WAAW,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,WAAW,EAAE,IAAI,CAAC,CAAC;IAC1F,CAAC;IAED,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;AAC7D,CAAC","sourcesContent":["import type {Selection} from '#pm/state';\n\n/**\n * @internal\n *\n * Like `selection.content()`, but smarter.\n * Copy a structure of complex nodes,\n * e.g. if select part of cut title it creates slice with yfm-cut –> yfm-cut-title -> selected text\n * it works well with simple nodes, but to handle cases as described above, custom logic needed\n */\nexport function getSelectionContent(sel: Selection) {\n const sharedDepth = sel.$from.sharedDepth(sel.$to.pos);\n const sharedNode = sel.$from.node(sharedDepth);\n const sharedNodeComplex = sharedNode.type.spec.complex;\n\n if (sharedNodeComplex && sharedNodeComplex !== 'leaf') {\n // Find the nearest ancestor with complex='root' to avoid\n // wrapping copied content in outer containers (blockquote, table cell, etc.)\n let rootDepth = sharedDepth;\n for (let d = sharedDepth; d >= 0; d--) {\n if (sel.$from.node(d).type.spec.complex === 'root') {\n rootDepth = d;\n break;\n }\n }\n\n // Slice from the parent of the root node so that the root node itself\n // (e.g. bullet_list) is included in the slice, but its outer containers are not.\n const parentDepth = Math.max(0, rootDepth - 1);\n const parentNode = sel.$from.node(parentDepth);\n const parentStart = sel.$from.start(parentDepth);\n return parentNode.slice(sel.$from.pos - parentStart, sel.$to.pos - parentStart, true);\n }\n\n return sel.$from.doc.slice(sel.$from.pos, sel.to, false);\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ResolvedPos } from 'prosemirror-model';
|
|
2
|
-
import type
|
|
2
|
+
import { type Command, type NodeSelection, TextSelection, type Transaction } from 'prosemirror-state';
|
|
3
3
|
import { GapCursorSelection } from "../Cursor/GapCursorSelection.js";
|
|
4
4
|
export type Direction = 'before' | 'after';
|
|
5
5
|
type TextSelectionFinder = (selection: TextSelection, dir: Direction) => ResolvedPos | null;
|
|
@@ -16,4 +16,5 @@ export declare const arrowDown: Command;
|
|
|
16
16
|
export declare const arrowUp: Command;
|
|
17
17
|
export declare const arrowRight: Command;
|
|
18
18
|
export declare const backspace: Command;
|
|
19
|
+
export declare const selectAll: Command;
|
|
19
20
|
export {};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Selection } from 'prosemirror-state';
|
|
2
|
-
import { isCodeBlock } from "../../../utils/nodes.js";
|
|
1
|
+
import { Selection, TextSelection as TextSel, TextSelection, } from 'prosemirror-state';
|
|
2
|
+
import { isCodeBlock, isNodeEmpty } from "../../../utils/nodes.js";
|
|
3
3
|
import { isNodeSelection, isTextSelection } from "../../../utils/selection.js";
|
|
4
4
|
import { GapCursorSelection, isGapCursorSelection } from "../Cursor/GapCursorSelection.js";
|
|
5
|
+
import { hideSelectionMenu } from "../SelectionContext/index.js";
|
|
5
6
|
const isUp = (dir) => dir === 'left' || dir === 'up';
|
|
6
7
|
function isTextblock(node) {
|
|
7
8
|
return node.isTextblock && !isCodeBlock(node);
|
|
@@ -143,4 +144,48 @@ export const backspace = (state, dispatch) => {
|
|
|
143
144
|
}
|
|
144
145
|
return false;
|
|
145
146
|
};
|
|
147
|
+
function hasContentToSelect(node) {
|
|
148
|
+
if (node.isTextblock)
|
|
149
|
+
return node.content.size > 0;
|
|
150
|
+
return !isNodeEmpty(node);
|
|
151
|
+
}
|
|
152
|
+
export const selectAll = (state, dispatch) => {
|
|
153
|
+
const { selection } = state;
|
|
154
|
+
const { $from, $to } = selection;
|
|
155
|
+
const sharedDepth = $from.sharedDepth($to.pos);
|
|
156
|
+
for (let depth = sharedDepth; depth > 0; depth--) {
|
|
157
|
+
const node = $from.node(depth);
|
|
158
|
+
const { spec } = node.type;
|
|
159
|
+
if (spec.selectAll === false)
|
|
160
|
+
continue;
|
|
161
|
+
let mode;
|
|
162
|
+
if (spec.selectAll)
|
|
163
|
+
mode = spec.selectAll;
|
|
164
|
+
else if (node.isTextblock || spec.code)
|
|
165
|
+
mode = 'content';
|
|
166
|
+
else
|
|
167
|
+
continue;
|
|
168
|
+
if (!hasContentToSelect(node))
|
|
169
|
+
continue;
|
|
170
|
+
if (mode === 'node') {
|
|
171
|
+
const selAroundNode = TextSelection.create(state.doc, $from.before(depth), $from.after(depth));
|
|
172
|
+
if (selection.from <= selAroundNode.from && selection.to >= selAroundNode.to)
|
|
173
|
+
continue;
|
|
174
|
+
dispatch?.(hideSelectionMenu(state.tr.setSelection(selAroundNode)));
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
const start = $from.start(depth);
|
|
178
|
+
const end = start + node.content.size;
|
|
179
|
+
const startCursor = Selection.findFrom(state.doc.resolve(start), 1);
|
|
180
|
+
const endCursor = Selection.findFrom(state.doc.resolve(end), -1);
|
|
181
|
+
if (startCursor &&
|
|
182
|
+
endCursor &&
|
|
183
|
+
selection.from <= startCursor.from &&
|
|
184
|
+
selection.to >= endCursor.to)
|
|
185
|
+
continue;
|
|
186
|
+
dispatch?.(state.tr.setSelection(TextSel.create(state.doc, start, end)));
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
return false;
|
|
190
|
+
};
|
|
146
191
|
//# sourceMappingURL=commands.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/Selection/commands.ts"],"names":[],"mappings":"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","sourcesContent":["import type {Node, ResolvedPos} from 'prosemirror-model';\nimport type {Command, NodeSelection, TextSelection, Transaction} from 'prosemirror-state';\nimport {Selection} from 'prosemirror-state';\n\nimport {isCodeBlock} from '../../../utils/nodes';\nimport {isNodeSelection, isTextSelection} from '../../../utils/selection';\nimport {GapCursorSelection, isGapCursorSelection} from '../Cursor/GapCursorSelection';\n\nexport type Direction = 'before' | 'after';\ntype ArrowDirection = 'up' | 'right' | 'down' | 'left';\n\ntype TextSelectionFinder = (selection: TextSelection, dir: Direction) => ResolvedPos | null;\ntype NodeSelectionFinder = (selection: NodeSelection, dir: Direction) => ResolvedPos | null;\ntype GapCursorSelectionFinder = (\n selection: GapCursorSelection,\n dir: Direction,\n) => ResolvedPos | null;\n\ntype GapCursorMeta = {direction: Direction};\n\nconst isUp = (dir: ArrowDirection) => dir === 'left' || dir === 'up';\n\nfunction isTextblock(node: Node): boolean {\n return node.isTextblock && !isCodeBlock(node);\n}\n\nfunction isEdgeTextblock($cursor: ResolvedPos, dir: Direction): boolean {\n const index = $cursor.index($cursor.depth - 1);\n if (dir === 'before') return index === 0;\n if (dir === 'after') return index === $cursor.node($cursor.depth - 1).childCount - 1;\n return false;\n}\n\nexport const findNextFakeParaPosForGapCursorSelection: GapCursorSelectionFinder = ({$pos}, dir) => {\n if ($pos.pos !== $pos.start() && $pos.pos !== $pos.end()) return null;\n return findFakeParaPosClosestToPos($pos, $pos.depth, dir);\n};\n\nexport const findFakeParaPosForNodeSelection: NodeSelectionFinder = (selection, dir) => {\n const selectedNode = selection.node;\n if (selectedNode.isInline || isTextblock(selectedNode)) return null;\n\n const {$from} = selection;\n const index = $from.index();\n const parentNode = $from.parent;\n if (dir === 'before') {\n if (parentNode.firstChild === selectedNode || !isTextblock(parentNode.child(index - 1))) {\n return $from;\n }\n } else if (dir === 'after') {\n if (parentNode.lastChild === selectedNode || !isTextblock(parentNode.child(index + 1))) {\n return selection.$to;\n }\n }\n\n return null;\n};\n\nexport const findFakeParaPosForCodeBlock = ($cursor: ResolvedPos, dir: Direction) => {\n if (!isCodeBlock($cursor.parent)) return null;\n\n let foundPos = -1;\n const index = $cursor.index($cursor.depth - 1);\n const parent = $cursor.node($cursor.depth - 1);\n if (dir === 'before') {\n if (index === 0 || !isTextblock(parent.child(index - 1))) {\n foundPos = $cursor.before();\n }\n } else if (dir === 'after') {\n if (index === parent.childCount - 1 || !isTextblock(parent.child(index + 1))) {\n foundPos = $cursor.after();\n }\n }\n\n return foundPos !== -1 ? $cursor.doc.resolve(foundPos) : null;\n};\n\nexport const findFakeParaPosForTextSelection: TextSelectionFinder = (selection, dir) => {\n const $cursor = dir === 'before' ? selection.$from : selection.$to;\n if ($cursor.parent.isInline) return null;\n\n const $pos = findFakeParaPosForCodeBlock($cursor, dir);\n if ($pos) return $pos;\n\n if (!isEdgeTextblock($cursor, dir)) return null;\n\n return findFakeParaPosClosestToPos($cursor, $cursor.depth - 1, dir);\n};\n\nexport function findFakeParaPosClosestToPos(\n $pos: ResolvedPos,\n depth: number,\n dir: Direction,\n): ResolvedPos | null {\n depth++;\n while (--depth > 0) {\n const node = $pos.node(depth);\n const index = $pos.index(depth - 1);\n const parent = $pos.node(depth - 1);\n\n const isFirstChild = index === 0;\n const isLastChild = index === parent.childCount - 1;\n\n const isComplexChild =\n node.type.spec.complex === 'inner' || node.type.spec.complex === 'leaf';\n\n const disabledGapCursor = parent.type.spec.gapcursor === false;\n\n if (isComplexChild || disabledGapCursor) {\n if (dir === 'before' && isFirstChild) continue;\n if (dir === 'after' && isLastChild) continue;\n return null;\n }\n\n if (dir === 'before') {\n if (isFirstChild || !isTextblock(parent.child(index - 1))) {\n return $pos.doc.resolve($pos.before(depth));\n }\n } else if (dir === 'after') {\n if (isLastChild || !isTextblock(parent.child(index + 1))) {\n return $pos.doc.resolve($pos.after(depth));\n }\n }\n\n return null;\n }\n return null;\n}\n\nconst arrow =\n (dir: ArrowDirection): Command =>\n (state, dispatch, view) => {\n const {selection} = state;\n const direction: Direction = isUp(dir) ? 'before' : 'after';\n let $pos: ResolvedPos | null = null;\n\n if (isGapCursorSelection<GapCursorMeta>(selection)) {\n if (selection.meta?.direction !== direction) {\n return false;\n }\n\n // if gap selection is at start or end of doc\n if (dir === 'up' && selection.pos === 0) return true;\n if (dir === 'down' && selection.pos === state.doc.nodeSize - 2) return true;\n\n $pos = findNextFakeParaPosForGapCursorSelection(selection, direction);\n }\n\n if (isNodeSelection(selection)) {\n $pos = findFakeParaPosForNodeSelection(selection, direction);\n }\n\n if (isTextSelection(selection) && view?.endOfTextblock(dir)) {\n $pos = findFakeParaPosForTextSelection(selection, direction);\n }\n\n if ($pos) {\n dispatch?.(createFakeParagraph(state.tr, $pos, direction).scrollIntoView());\n return true;\n }\n\n return false;\n };\n\nexport function createFakeParagraph(\n tr: Transaction,\n $pos: ResolvedPos,\n direction: Direction,\n): Transaction {\n return tr.setSelection(new GapCursorSelection<GapCursorMeta>($pos, {meta: {direction}}));\n}\n\nexport const arrowLeft = arrow('left');\nexport const arrowDown = arrow('down');\nexport const arrowUp = arrow('up');\nexport const arrowRight = arrow('right');\n\nexport const backspace: Command = (state, dispatch) => {\n const sel = state.selection;\n if (isGapCursorSelection(sel)) {\n const newSel = Selection.findFrom(sel.$pos, -1);\n if (newSel) {\n dispatch?.(state.tr.setSelection(newSel).scrollIntoView());\n return true;\n }\n }\n return false;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/Selection/commands.ts"],"names":[],"mappings":"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","sourcesContent":["import type {Node, ResolvedPos} from 'prosemirror-model';\nimport {\n type Command,\n type NodeSelection,\n Selection,\n TextSelection as TextSel,\n TextSelection,\n type Transaction,\n} from 'prosemirror-state';\n\nimport {isCodeBlock, isNodeEmpty} from '../../../utils/nodes';\nimport {isNodeSelection, isTextSelection} from '../../../utils/selection';\nimport {GapCursorSelection, isGapCursorSelection} from '../Cursor/GapCursorSelection';\nimport {hideSelectionMenu} from '../SelectionContext';\n\nexport type Direction = 'before' | 'after';\ntype ArrowDirection = 'up' | 'right' | 'down' | 'left';\n\ntype TextSelectionFinder = (selection: TextSelection, dir: Direction) => ResolvedPos | null;\ntype NodeSelectionFinder = (selection: NodeSelection, dir: Direction) => ResolvedPos | null;\ntype GapCursorSelectionFinder = (\n selection: GapCursorSelection,\n dir: Direction,\n) => ResolvedPos | null;\n\ntype GapCursorMeta = {direction: Direction};\n\nconst isUp = (dir: ArrowDirection) => dir === 'left' || dir === 'up';\n\nfunction isTextblock(node: Node): boolean {\n return node.isTextblock && !isCodeBlock(node);\n}\n\nfunction isEdgeTextblock($cursor: ResolvedPos, dir: Direction): boolean {\n const index = $cursor.index($cursor.depth - 1);\n if (dir === 'before') return index === 0;\n if (dir === 'after') return index === $cursor.node($cursor.depth - 1).childCount - 1;\n return false;\n}\n\nexport const findNextFakeParaPosForGapCursorSelection: GapCursorSelectionFinder = ({$pos}, dir) => {\n if ($pos.pos !== $pos.start() && $pos.pos !== $pos.end()) return null;\n return findFakeParaPosClosestToPos($pos, $pos.depth, dir);\n};\n\nexport const findFakeParaPosForNodeSelection: NodeSelectionFinder = (selection, dir) => {\n const selectedNode = selection.node;\n if (selectedNode.isInline || isTextblock(selectedNode)) return null;\n\n const {$from} = selection;\n const index = $from.index();\n const parentNode = $from.parent;\n if (dir === 'before') {\n if (parentNode.firstChild === selectedNode || !isTextblock(parentNode.child(index - 1))) {\n return $from;\n }\n } else if (dir === 'after') {\n if (parentNode.lastChild === selectedNode || !isTextblock(parentNode.child(index + 1))) {\n return selection.$to;\n }\n }\n\n return null;\n};\n\nexport const findFakeParaPosForCodeBlock = ($cursor: ResolvedPos, dir: Direction) => {\n if (!isCodeBlock($cursor.parent)) return null;\n\n let foundPos = -1;\n const index = $cursor.index($cursor.depth - 1);\n const parent = $cursor.node($cursor.depth - 1);\n if (dir === 'before') {\n if (index === 0 || !isTextblock(parent.child(index - 1))) {\n foundPos = $cursor.before();\n }\n } else if (dir === 'after') {\n if (index === parent.childCount - 1 || !isTextblock(parent.child(index + 1))) {\n foundPos = $cursor.after();\n }\n }\n\n return foundPos !== -1 ? $cursor.doc.resolve(foundPos) : null;\n};\n\nexport const findFakeParaPosForTextSelection: TextSelectionFinder = (selection, dir) => {\n const $cursor = dir === 'before' ? selection.$from : selection.$to;\n if ($cursor.parent.isInline) return null;\n\n const $pos = findFakeParaPosForCodeBlock($cursor, dir);\n if ($pos) return $pos;\n\n if (!isEdgeTextblock($cursor, dir)) return null;\n\n return findFakeParaPosClosestToPos($cursor, $cursor.depth - 1, dir);\n};\n\nexport function findFakeParaPosClosestToPos(\n $pos: ResolvedPos,\n depth: number,\n dir: Direction,\n): ResolvedPos | null {\n depth++;\n while (--depth > 0) {\n const node = $pos.node(depth);\n const index = $pos.index(depth - 1);\n const parent = $pos.node(depth - 1);\n\n const isFirstChild = index === 0;\n const isLastChild = index === parent.childCount - 1;\n\n const isComplexChild =\n node.type.spec.complex === 'inner' || node.type.spec.complex === 'leaf';\n\n const disabledGapCursor = parent.type.spec.gapcursor === false;\n\n if (isComplexChild || disabledGapCursor) {\n if (dir === 'before' && isFirstChild) continue;\n if (dir === 'after' && isLastChild) continue;\n return null;\n }\n\n if (dir === 'before') {\n if (isFirstChild || !isTextblock(parent.child(index - 1))) {\n return $pos.doc.resolve($pos.before(depth));\n }\n } else if (dir === 'after') {\n if (isLastChild || !isTextblock(parent.child(index + 1))) {\n return $pos.doc.resolve($pos.after(depth));\n }\n }\n\n return null;\n }\n return null;\n}\n\nconst arrow =\n (dir: ArrowDirection): Command =>\n (state, dispatch, view) => {\n const {selection} = state;\n const direction: Direction = isUp(dir) ? 'before' : 'after';\n let $pos: ResolvedPos | null = null;\n\n if (isGapCursorSelection<GapCursorMeta>(selection)) {\n if (selection.meta?.direction !== direction) {\n return false;\n }\n\n // if gap selection is at start or end of doc\n if (dir === 'up' && selection.pos === 0) return true;\n if (dir === 'down' && selection.pos === state.doc.nodeSize - 2) return true;\n\n $pos = findNextFakeParaPosForGapCursorSelection(selection, direction);\n }\n\n if (isNodeSelection(selection)) {\n $pos = findFakeParaPosForNodeSelection(selection, direction);\n }\n\n if (isTextSelection(selection) && view?.endOfTextblock(dir)) {\n $pos = findFakeParaPosForTextSelection(selection, direction);\n }\n\n if ($pos) {\n dispatch?.(createFakeParagraph(state.tr, $pos, direction).scrollIntoView());\n return true;\n }\n\n return false;\n };\n\nexport function createFakeParagraph(\n tr: Transaction,\n $pos: ResolvedPos,\n direction: Direction,\n): Transaction {\n return tr.setSelection(new GapCursorSelection<GapCursorMeta>($pos, {meta: {direction}}));\n}\n\nexport const arrowLeft = arrow('left');\nexport const arrowDown = arrow('down');\nexport const arrowUp = arrow('up');\nexport const arrowRight = arrow('right');\n\nexport const backspace: Command = (state, dispatch) => {\n const sel = state.selection;\n if (isGapCursorSelection(sel)) {\n const newSel = Selection.findFrom(sel.$pos, -1);\n if (newSel) {\n dispatch?.(state.tr.setSelection(newSel).scrollIntoView());\n return true;\n }\n }\n return false;\n};\n\nfunction hasContentToSelect(node: Node): boolean {\n if (node.isTextblock) return node.content.size > 0;\n return !isNodeEmpty(node);\n}\n\nexport const selectAll: Command = (state, dispatch) => {\n const {selection} = state;\n const {$from, $to} = selection;\n const sharedDepth = $from.sharedDepth($to.pos);\n\n for (let depth = sharedDepth; depth > 0; depth--) {\n const node = $from.node(depth);\n const {spec} = node.type;\n\n if (spec.selectAll === false) continue;\n\n let mode: 'content' | 'node';\n if (spec.selectAll) mode = spec.selectAll;\n else if (node.isTextblock || spec.code) mode = 'content';\n else continue;\n\n if (!hasContentToSelect(node)) continue;\n\n if (mode === 'node') {\n const selAroundNode = TextSelection.create(\n state.doc,\n $from.before(depth),\n $from.after(depth),\n );\n\n if (selection.from <= selAroundNode.from && selection.to >= selAroundNode.to) continue;\n\n dispatch?.(hideSelectionMenu(state.tr.setSelection(selAroundNode)));\n return true;\n }\n\n const start = $from.start(depth);\n const end = start + node.content.size;\n\n const startCursor = Selection.findFrom(state.doc.resolve(start), 1);\n const endCursor = Selection.findFrom(state.doc.resolve(end), -1);\n\n if (\n startCursor &&\n endCursor &&\n selection.from <= startCursor.from &&\n selection.to >= endCursor.to\n )\n continue;\n\n dispatch?.(state.tr.setSelection(TextSel.create(state.doc, start, end)));\n return true;\n }\n\n return false;\n};\n"]}
|
|
@@ -3,6 +3,21 @@ import "./selection.css";
|
|
|
3
3
|
export declare const selection: () => Plugin<any>;
|
|
4
4
|
declare module 'prosemirror-model' {
|
|
5
5
|
interface NodeSpec {
|
|
6
|
+
/**
|
|
7
|
+
* Whether clicking directly on this node creates a NodeSelection for it.
|
|
8
|
+
* Typically `true` for root complex nodes (tables, cuts, notes)
|
|
9
|
+
* and `false` for their inner parts and leaf elements.
|
|
10
|
+
*/
|
|
6
11
|
allowSelection?: boolean | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Controls how this node participates in hierarchical select-all (Cmd+A / Ctrl+A).
|
|
14
|
+
* Each press of select-all walks up the node tree and selects the nearest matching ancestor.
|
|
15
|
+
*
|
|
16
|
+
* - `'content'` — select the node's content (TextSelection over inner content range)
|
|
17
|
+
* - `'node'` — select the node itself (NodeSelection)
|
|
18
|
+
* - `false` — skip this node during select-all traversal
|
|
19
|
+
* - `undefined` — default: textblocks and code nodes select their content, others are skipped
|
|
20
|
+
*/
|
|
21
|
+
selectAll?: false | 'node' | 'content' | undefined;
|
|
7
22
|
}
|
|
8
23
|
}
|
|
@@ -4,7 +4,7 @@ import { AllSelection, NodeSelection, Plugin, TextSelection, } from 'prosemirror
|
|
|
4
4
|
import { Decoration, DecorationSet } from 'prosemirror-view';
|
|
5
5
|
import { isSelectableNode } from "../../../utils/nodes.js";
|
|
6
6
|
import { isNodeSelection } from "../../../utils/selection.js";
|
|
7
|
-
import { arrowDown, arrowLeft, arrowRight, arrowUp, backspace } from "./commands.js";
|
|
7
|
+
import { arrowDown, arrowLeft, arrowRight, arrowUp, backspace, selectAll } from "./commands.js";
|
|
8
8
|
import "./selection.css";
|
|
9
9
|
export const selection = () => new Plugin({
|
|
10
10
|
props: {
|
|
@@ -14,6 +14,7 @@ export const selection = () => new Plugin({
|
|
|
14
14
|
ArrowUp: arrowUp,
|
|
15
15
|
ArrowDown: arrowDown,
|
|
16
16
|
Backspace: backspace,
|
|
17
|
+
'Mod-a': selectAll,
|
|
17
18
|
}),
|
|
18
19
|
decorations(state) {
|
|
19
20
|
return getDecorations(state.tr);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/Selection/selection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,gBAAgB,EAAC,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AAElD,OAAO,EACH,YAAY,EAEZ,aAAa,EACb,MAAM,EAEN,aAAa,GAEhB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAC,UAAU,EAAE,aAAa,EAAkB,MAAM,kBAAkB,CAAC;AAE5E,OAAO,EAAC,gBAAgB,EAAC,gCAA6B;AACtD,OAAO,EAAC,eAAe,EAAC,oCAAiC;AAEzD,OAAO,EAAC,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAC,sBAAmB;
|
|
1
|
+
{"version":3,"file":"selection.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/Selection/selection.ts"],"names":[],"mappings":"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","sourcesContent":["import {selectParentNode} from 'prosemirror-commands';\nimport {keydownHandler} from 'prosemirror-keymap';\nimport type {Node} from 'prosemirror-model';\nimport {\n AllSelection,\n type Command,\n NodeSelection,\n Plugin,\n type Selection,\n TextSelection,\n type Transaction,\n} from 'prosemirror-state';\nimport {Decoration, DecorationSet, type EditorView} from 'prosemirror-view';\n\nimport {isSelectableNode} from '../../../utils/nodes';\nimport {isNodeSelection} from '../../../utils/selection';\n\nimport {arrowDown, arrowLeft, arrowRight, arrowUp, backspace, selectAll} from './commands';\n\nimport './selection.scss';\n\nexport const selection = () =>\n new Plugin({\n props: {\n handleKeyDown: keydownHandler({\n ArrowLeft: arrowLeft,\n ArrowRight: arrowRight,\n ArrowUp: arrowUp,\n ArrowDown: arrowDown,\n Backspace: backspace,\n 'Mod-a': selectAll,\n }),\n decorations(state) {\n return getDecorations(state.tr);\n },\n handleClickOn(view, _pos, node, nodePos, _event, direct) {\n if (direct && node.type.spec.allowSelection) {\n return selectNode(nodePos)(view.state, view.dispatch);\n }\n\n return false;\n },\n },\n view(view) {\n reselect(view);\n return {\n update(view) {\n reselect(view);\n },\n };\n },\n });\n\ndeclare module 'prosemirror-model' {\n interface NodeSpec {\n /**\n * Whether clicking directly on this node creates a NodeSelection for it.\n * Typically `true` for root complex nodes (tables, cuts, notes)\n * and `false` for their inner parts and leaf elements.\n */\n allowSelection?: boolean | undefined;\n /**\n * Controls how this node participates in hierarchical select-all (Cmd+A / Ctrl+A).\n * Each press of select-all walks up the node tree and selects the nearest matching ancestor.\n *\n * - `'content'` — select the node's content (TextSelection over inner content range)\n * - `'node'` — select the node itself (NodeSelection)\n * - `false` — skip this node during select-all traversal\n * - `undefined` — default: textblocks and code nodes select their content, others are skipped\n */\n selectAll?: false | 'node' | 'content' | undefined;\n }\n}\n\nconst reselect = (view: EditorView) => {\n const {selection: sel} = view.state;\n if (!sel.empty && isNodeSelection(sel) && !isSelectableNode(sel.node)) {\n return selectParentNode(view.state, view.dispatch);\n }\n return false;\n};\n\nconst selectNode =\n (pos: number): Command =>\n (state, dispatch) => {\n if (dispatch) {\n dispatch(state.tr.setSelection(new NodeSelection(state.doc.resolve(pos))));\n }\n return true;\n };\n\nconst getDecorations = (tr: Transaction): DecorationSet => {\n if (tr.selection instanceof NodeSelection) {\n return DecorationSet.create(tr.doc, [\n Decoration.node(tr.selection.from, tr.selection.to, {\n class: 'pm-node-selected',\n }),\n ]);\n }\n\n if (tr.selection instanceof TextSelection || tr.selection instanceof AllSelection) {\n const decorations = getTopLevelNodesFromSelection(tr.selection, tr.doc).map(\n ({node, pos}) => {\n return Decoration.node(pos, pos + node.nodeSize, {\n class: 'pm-node-selected',\n });\n },\n );\n return DecorationSet.create(tr.doc, decorations);\n }\n return DecorationSet.empty;\n};\n\nconst getTopLevelNodesFromSelection = (selection: Selection, doc: Node) => {\n const nodes: {node: Node; pos: number}[] = [];\n if (selection.from !== selection.to) {\n const {from, to} = selection;\n\n doc.nodesBetween(from, to, (node, pos) => {\n const withinSelection = from <= pos && pos + node.nodeSize <= to;\n\n if (node && !node.isText && node.type.spec.selectable !== false && withinSelection) {\n nodes.push({node, pos});\n\n return false;\n }\n\n return true;\n });\n }\n return nodes;\n};\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type PopupPlacement, type PopupProps } from '@gravity-ui/uikit';
|
|
2
|
+
import type { ActionStorage } from "../../../core/index.js";
|
|
3
|
+
import type { EditorView } from "../../../pm/view.js";
|
|
4
|
+
import { type ToolbarProps } from "../../../toolbar/index.js";
|
|
5
|
+
import type { ContextConfig } from "./types.js";
|
|
6
|
+
export type TextSelectionTooltipProps = Pick<ToolbarProps<ActionStorage>, 'onClick' | 'editor' | 'focus'> & {
|
|
7
|
+
config: ContextConfig;
|
|
8
|
+
editorView: EditorView;
|
|
9
|
+
popupPlacement: PopupPlacement;
|
|
10
|
+
popupAnchor: PopupProps['anchorElement'];
|
|
11
|
+
popupOnOpenChange: PopupProps['onOpenChange'];
|
|
12
|
+
};
|
|
13
|
+
export declare const TextSelectionTooltip: React.FC<TextSelectionTooltipProps>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
3
|
+
import { Popup, sp } from '@gravity-ui/uikit';
|
|
4
|
+
import { isFunction } from "../../../lodash.js";
|
|
5
|
+
import { typedMemo } from "../../../react-utils/memo.js";
|
|
6
|
+
import { Toolbar } from "../../../toolbar/index.js";
|
|
7
|
+
import { ToolbarWrapToContext } from "../../../toolbar/ToolbarRerender.js";
|
|
8
|
+
const ToolbarMemoized = typedMemo(Toolbar);
|
|
9
|
+
const KEY_SEP = '|||';
|
|
10
|
+
export const TextSelectionTooltip = function TextSelectionTooltip({ popupAnchor, popupPlacement, popupOnOpenChange, config, focus, editor, onClick, editorView, }) {
|
|
11
|
+
const [conditionKey, setConditionKey] = useState(() => calcConditionKey(config, editor, editorView));
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
const newKey = calcConditionKey(config, editor, editorView);
|
|
14
|
+
if (conditionKey !== newKey)
|
|
15
|
+
setConditionKey(newKey);
|
|
16
|
+
});
|
|
17
|
+
const toolbarData = useMemo(() => {
|
|
18
|
+
const results = conditionKey.split(KEY_SEP);
|
|
19
|
+
let idx = 0;
|
|
20
|
+
return config
|
|
21
|
+
.map((groupData) => groupData.filter(() => results[idx++] === 'true'))
|
|
22
|
+
.filter((groupData) => Boolean(groupData.length));
|
|
23
|
+
}, [config, conditionKey]);
|
|
24
|
+
return (_jsx(Popup, { open: true, className: sp({ p: '0.5' }), placement: popupPlacement, anchorElement: popupAnchor, onOpenChange: popupOnOpenChange, children: _jsx(ToolbarWrapToContext, { editor: editor, children: _jsx(ToolbarMemoized, { focus: focus, editor: editor, onClick: onClick, data: toolbarData, qa: "g-md-toolbar-selection" }) }) }));
|
|
25
|
+
};
|
|
26
|
+
function calcConditionKey(config, editor, editorView) {
|
|
27
|
+
return config
|
|
28
|
+
.flatMap((groupData) => groupData.map((item) => {
|
|
29
|
+
const { condition } = item;
|
|
30
|
+
if (condition === 'enabled')
|
|
31
|
+
return item.isEnable(editor);
|
|
32
|
+
if (isFunction(condition))
|
|
33
|
+
return condition(editorView.state);
|
|
34
|
+
return true;
|
|
35
|
+
}))
|
|
36
|
+
.join(KEY_SEP);
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=TextSelectionTooltip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TextSelectionTooltip.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/SelectionContext/TextSelectionTooltip.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAC,KAAK,EAAwC,EAAE,EAAC,MAAM,mBAAmB,CAAC;AAIlF,OAAO,EAAC,UAAU,EAAC,2BAAmB;AACtC,OAAO,EAAC,SAAS,EAAC,qCAA6B;AAC/C,OAAO,EAAC,OAAO,EAAsC,kCAAoB;AACzE,OAAO,EAAC,oBAAoB,EAAC,4CAAoC;AAIjE,MAAM,eAAe,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;AAC3C,MAAM,OAAO,GAAG,KAAK,CAAC;AAatB,MAAM,CAAC,MAAM,oBAAoB,GAC7B,SAAS,oBAAoB,CAAC,EAC1B,WAAW,EACX,cAAc,EACd,iBAAiB,EAEjB,MAAM,EACN,KAAK,EACL,MAAM,EACN,OAAO,EACP,UAAU,GACb;IACG,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAClD,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAC/C,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACX,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QAC5D,IAAI,YAAY,KAAK,MAAM;YAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,OAAO,CAA6B,GAAG,EAAE;QACzD,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,OAAO,MAAM;aACR,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM,CAAC,CAAC;aACrE,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1D,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;IAE3B,OAAO,CACH,KAAC,KAAK,IACF,IAAI,QACJ,SAAS,EAAE,EAAE,CAAC,EAAC,CAAC,EAAE,KAAK,EAAC,CAAC,EACzB,SAAS,EAAE,cAAc,EACzB,aAAa,EAAE,WAAW,EAC1B,YAAY,EAAE,iBAAiB,YAE/B,KAAC,oBAAoB,IAAC,MAAM,EAAE,MAAM,YAChC,KAAC,eAAe,IACZ,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,WAAW,EACjB,EAAE,EAAC,wBAAwB,GAC7B,GACiB,GACnB,CACX,CAAC;AACN,CAAC,CAAC;AAEN,SAAS,gBAAgB,CACrB,MAAqB,EACrB,MAAqB,EACrB,UAAsB;IAEtB,OAAO,MAAM;SACR,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CACnB,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACnB,MAAM,EAAC,SAAS,EAAC,GAAG,IAAI,CAAC;QACzB,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC1D,IAAI,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC;IAChB,CAAC,CAAC,CACL;SACA,IAAI,CAAC,OAAO,CAAC,CAAC;AACvB,CAAC","sourcesContent":["import {useEffect, useMemo, useState} from 'react';\n\nimport {Popup, type PopupPlacement, type PopupProps, sp} from '@gravity-ui/uikit';\n\nimport type {ActionStorage} from '#core';\nimport type {EditorView} from '#pm/view';\nimport {isFunction} from 'src/lodash';\nimport {typedMemo} from 'src/react-utils/memo';\nimport {Toolbar, type ToolbarData, type ToolbarProps} from 'src/toolbar';\nimport {ToolbarWrapToContext} from 'src/toolbar/ToolbarRerender';\n\nimport type {ContextConfig} from './types';\n\nconst ToolbarMemoized = typedMemo(Toolbar);\nconst KEY_SEP = '|||';\n\nexport type TextSelectionTooltipProps = Pick<\n ToolbarProps<ActionStorage>,\n 'onClick' | 'editor' | 'focus'\n> & {\n config: ContextConfig;\n editorView: EditorView;\n popupPlacement: PopupPlacement;\n popupAnchor: PopupProps['anchorElement'];\n popupOnOpenChange: PopupProps['onOpenChange'];\n};\n\nexport const TextSelectionTooltip: React.FC<TextSelectionTooltipProps> =\n function TextSelectionTooltip({\n popupAnchor,\n popupPlacement,\n popupOnOpenChange,\n\n config,\n focus,\n editor,\n onClick,\n editorView,\n }) {\n const [conditionKey, setConditionKey] = useState(() =>\n calcConditionKey(config, editor, editorView),\n );\n\n useEffect(() => {\n const newKey = calcConditionKey(config, editor, editorView);\n if (conditionKey !== newKey) setConditionKey(newKey);\n });\n\n const toolbarData = useMemo<ToolbarData<ActionStorage>>(() => {\n const results = conditionKey.split(KEY_SEP);\n let idx = 0;\n return config\n .map((groupData) => groupData.filter(() => results[idx++] === 'true'))\n .filter((groupData) => Boolean(groupData.length));\n }, [config, conditionKey]);\n\n return (\n <Popup\n open\n className={sp({p: '0.5'})}\n placement={popupPlacement}\n anchorElement={popupAnchor}\n onOpenChange={popupOnOpenChange}\n >\n <ToolbarWrapToContext editor={editor}>\n <ToolbarMemoized\n focus={focus}\n editor={editor}\n onClick={onClick}\n data={toolbarData}\n qa=\"g-md-toolbar-selection\"\n />\n </ToolbarWrapToContext>\n </Popup>\n );\n };\n\nfunction calcConditionKey(\n config: ContextConfig,\n editor: ActionStorage,\n editorView: EditorView,\n): string {\n return config\n .flatMap((groupData) =>\n groupData.map((item) => {\n const {condition} = item;\n if (condition === 'enabled') return item.isEnable(editor);\n if (isFunction(condition)) return condition(editorView.state);\n return true;\n }),\n )\n .join(KEY_SEP);\n}\n"]}
|
|
@@ -18,10 +18,17 @@ const pluginKey = new PluginKey('selection-context');
|
|
|
18
18
|
class SelectionTooltip {
|
|
19
19
|
destroyed = false;
|
|
20
20
|
tooltip;
|
|
21
|
+
editorView = null;
|
|
21
22
|
hideTimeoutRef = null;
|
|
22
23
|
_isMousePressed = false;
|
|
23
24
|
constructor(actions, menuConfig, logger, options) {
|
|
24
|
-
this.tooltip = new TooltipView(actions, menuConfig, logger,
|
|
25
|
+
this.tooltip = new TooltipView(actions, menuConfig, logger, {
|
|
26
|
+
...options,
|
|
27
|
+
onPopupOpenChange: (_open, _event, reason) => {
|
|
28
|
+
if (reason !== 'escape-key' && this.editorView)
|
|
29
|
+
this.scheduleTooltipHiding(this.editorView);
|
|
30
|
+
},
|
|
31
|
+
});
|
|
25
32
|
}
|
|
26
33
|
get key() {
|
|
27
34
|
return pluginKey;
|
|
@@ -79,6 +86,7 @@ class SelectionTooltip {
|
|
|
79
86
|
};
|
|
80
87
|
}
|
|
81
88
|
update(view, prevState) {
|
|
89
|
+
this.editorView = view;
|
|
82
90
|
if (this._isMousePressed)
|
|
83
91
|
return;
|
|
84
92
|
this.cancelTooltipHiding();
|
|
@@ -114,12 +122,7 @@ class SelectionTooltip {
|
|
|
114
122
|
this.tooltip.hide(view);
|
|
115
123
|
return;
|
|
116
124
|
}
|
|
117
|
-
this.tooltip.show(view
|
|
118
|
-
onOpenChange: (_open, _event, reason) => {
|
|
119
|
-
if (reason !== 'escape-key')
|
|
120
|
-
this.scheduleTooltipHiding(view);
|
|
121
|
-
},
|
|
122
|
-
});
|
|
125
|
+
this.tooltip.show(view);
|
|
123
126
|
}
|
|
124
127
|
scheduleTooltipHiding(view) {
|
|
125
128
|
this.hideTimeoutRef = setTimeout(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/SelectionContext/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {keydownHandler} from 'prosemirror-keymap';\nimport type {Node} from 'prosemirror-model';\nimport {\n AllSelection,\n type EditorState,\n Plugin,\n PluginKey,\n type PluginSpec,\n type StateField,\n TextSelection,\n type Transaction,\n} from 'prosemirror-state';\n// @ts-ignore // TODO: fix cjs build\nimport {hasParentNode} from 'prosemirror-utils';\nimport type {EditorProps, EditorView} from 'prosemirror-view';\n\nimport type {ActionStorage, ExtensionAuto} from '../../../core';\nimport type {Logger2} from '../../../logger';\nimport {isCodeBlock} from '../../../utils/nodes';\n\nimport {type ContextConfig, TooltipView} from './tooltip';\n\nexport type {\n ContextConfig as SelectionContextConfig,\n ContextGroupItemData as SelectionContextItemData,\n} from './tooltip';\n\nexport type SelectionContextOptions = {\n config?: ContextConfig;\n /**\n * Placement of context popup\n * @default 'bottom'\n */\n placement?: 'top' | 'bottom';\n /**\n * Prevents context popup from overflowing\n * @default false\n */\n flip?: boolean;\n};\n\nexport const SelectionContext: ExtensionAuto<SelectionContextOptions> = (builder, opts) => {\n const {config} = opts;\n if (Array.isArray(config) && config.length > 0) {\n builder.addPlugin(\n ({actions}) => new Plugin(new SelectionTooltip(actions, config, builder.logger, opts)),\n );\n }\n};\n\nconst HideMetaKey = 'hide-selection-menu';\n\nexport const hideSelectionMenu = (tr: Transaction) => {\n return tr.setMeta(HideMetaKey, true);\n};\n\nconst pluginKey = new PluginKey<PluginState>('selection-context');\n\ntype PluginState = {\n disabled: boolean;\n};\n\ntype TinyState = Pick<EditorState, 'doc' | 'selection'>;\n\nclass SelectionTooltip implements PluginSpec<PluginState> {\n private destroyed = false;\n\n private tooltip: TooltipView;\n private hideTimeoutRef: ReturnType<typeof setTimeout> | null = null;\n\n private _isMousePressed = false;\n\n constructor(\n actions: ActionStorage,\n menuConfig: ContextConfig,\n logger: Logger2.ILogger,\n options: SelectionContextOptions,\n ) {\n this.tooltip = new TooltipView(actions, menuConfig, logger, options);\n }\n\n get key(): PluginKey<PluginState> {\n return pluginKey;\n }\n\n get props(): EditorProps {\n return {\n // same as keymap({})\n handleKeyDown: keydownHandler({\n // hide context menu when Esc was pressed\n Escape: (_state, _dispatch, view) => {\n if (this.tooltip.isTooltipOpen) {\n this.tooltip.hide(view!);\n return true;\n }\n return false;\n },\n }),\n handleDOMEvents: {\n mousedown: (view) => {\n const startState: TinyState = {\n doc: view.state.doc,\n selection: view.state.selection,\n };\n this._isMousePressed = true;\n this.cancelTooltipHiding();\n this.tooltip.hide(view);\n\n const onMouseUp = () => {\n if (this.destroyed) return;\n this._isMousePressed = false;\n this.update(view, startState);\n };\n\n document.addEventListener('mouseup', onMouseUp, {once: true});\n },\n },\n };\n }\n\n get state(): StateField<PluginState> {\n return {\n init: () => ({disabled: false}),\n apply(tr) {\n return {disabled: Boolean(tr.getMeta(HideMetaKey))};\n },\n };\n }\n\n view(view: EditorView) {\n this.update(view);\n return {\n update: this.update.bind(this),\n destroy: () => {\n this.destroyed = true;\n this.cancelTooltipHiding();\n this.tooltip.destroy();\n },\n };\n }\n\n private update(view: EditorView, prevState?: TinyState) {\n if (this._isMousePressed) return;\n\n this.cancelTooltipHiding();\n\n const hideFromTr = pluginKey.getState(view.state)?.disabled;\n\n // Don't show tooltip if editor not mounted to the DOM\n if (hideFromTr || !view.dom.parentNode) {\n this.tooltip.hide(view);\n return;\n }\n\n const {state} = view;\n // Don't do anything if the document/selection didn't change\n if (prevState && prevState.doc.eq(state.doc) && prevState.selection.eq(state.selection)) {\n return;\n }\n\n // Don't show tooltip if editor out of focus\n if (!view.hasFocus()) {\n this.tooltip.hide(view);\n return;\n }\n\n const {selection} = state;\n // Hide the tooltip if the selection is empty\n if (\n selection.empty ||\n !(selection instanceof TextSelection || selection instanceof AllSelection)\n ) {\n this.tooltip.hide(view);\n return;\n }\n\n if (\n // Hide tooltip when one side of selection is inside a codeblock\n isCodeBlock(selection.$from.parent) ||\n isCodeBlock(selection.$to.parent) ||\n // or when selection is inside node where context menu is disabled\n hasParentNode((node: Node) => node.type.spec.selectionContext === false)(selection)\n ) {\n this.tooltip.hide(view);\n return;\n }\n\n this.tooltip.show(view, {\n onOpenChange: (_open, _event, reason) => {\n if (reason !== 'escape-key') this.scheduleTooltipHiding(view);\n },\n });\n }\n\n private scheduleTooltipHiding(view: EditorView) {\n this.hideTimeoutRef = setTimeout(() => {\n // hide tooltip if view is out of focus after 30 ms\n if (!view.hasFocus()) {\n this.tooltip.hide(view);\n }\n }, 30);\n }\n\n private cancelTooltipHiding() {\n if (this.hideTimeoutRef !== null) {\n clearTimeout(this.hideTimeoutRef);\n this.hideTimeoutRef = null;\n }\n }\n}\n\ndeclare module 'prosemirror-model' {\n interface NodeSpec {\n /** Set false to disable the selection-context menu within this node */\n selectionContext?: boolean | undefined;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"../../../../../src","sources":["extensions/behavior/SelectionContext/index.ts"],"names":[],"mappings":"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","sourcesContent":["import {keydownHandler} from 'prosemirror-keymap';\nimport type {Node} from 'prosemirror-model';\nimport {\n AllSelection,\n type EditorState,\n Plugin,\n PluginKey,\n type PluginSpec,\n type StateField,\n TextSelection,\n type Transaction,\n} from 'prosemirror-state';\n// @ts-ignore // TODO: fix cjs build\nimport {hasParentNode} from 'prosemirror-utils';\nimport type {EditorProps, EditorView} from 'prosemirror-view';\n\nimport type {ActionStorage, ExtensionAuto} from '../../../core';\nimport type {Logger2} from '../../../logger';\nimport {isCodeBlock} from '../../../utils/nodes';\n\nimport {type ContextConfig, TooltipView} from './tooltip';\n\nexport type {\n ContextConfig as SelectionContextConfig,\n ContextGroupItemData as SelectionContextItemData,\n} from './tooltip';\n\nexport type SelectionContextOptions = {\n config?: ContextConfig;\n /**\n * Placement of context popup\n * @default 'bottom'\n */\n placement?: 'top' | 'bottom';\n /**\n * Prevents context popup from overflowing\n * @default false\n */\n flip?: boolean;\n};\n\nexport const SelectionContext: ExtensionAuto<SelectionContextOptions> = (builder, opts) => {\n const {config} = opts;\n if (Array.isArray(config) && config.length > 0) {\n builder.addPlugin(\n ({actions}) => new Plugin(new SelectionTooltip(actions, config, builder.logger, opts)),\n );\n }\n};\n\nconst HideMetaKey = 'hide-selection-menu';\n\nexport const hideSelectionMenu = (tr: Transaction) => {\n return tr.setMeta(HideMetaKey, true);\n};\n\nconst pluginKey = new PluginKey<PluginState>('selection-context');\n\ntype PluginState = {\n disabled: boolean;\n};\n\ntype TinyState = Pick<EditorState, 'doc' | 'selection'>;\n\nclass SelectionTooltip implements PluginSpec<PluginState> {\n private destroyed = false;\n\n private tooltip: TooltipView;\n private editorView: EditorView | null = null;\n private hideTimeoutRef: ReturnType<typeof setTimeout> | null = null;\n\n private _isMousePressed = false;\n\n constructor(\n actions: ActionStorage,\n menuConfig: ContextConfig,\n logger: Logger2.ILogger,\n options: SelectionContextOptions,\n ) {\n this.tooltip = new TooltipView(actions, menuConfig, logger, {\n ...options,\n onPopupOpenChange: (_open, _event, reason) => {\n if (reason !== 'escape-key' && this.editorView)\n this.scheduleTooltipHiding(this.editorView);\n },\n });\n }\n\n get key(): PluginKey<PluginState> {\n return pluginKey;\n }\n\n get props(): EditorProps {\n return {\n // same as keymap({})\n handleKeyDown: keydownHandler({\n // hide context menu when Esc was pressed\n Escape: (_state, _dispatch, view) => {\n if (this.tooltip.isTooltipOpen) {\n this.tooltip.hide(view!);\n return true;\n }\n return false;\n },\n }),\n handleDOMEvents: {\n mousedown: (view) => {\n const startState: TinyState = {\n doc: view.state.doc,\n selection: view.state.selection,\n };\n this._isMousePressed = true;\n this.cancelTooltipHiding();\n this.tooltip.hide(view);\n\n const onMouseUp = () => {\n if (this.destroyed) return;\n this._isMousePressed = false;\n this.update(view, startState);\n };\n\n document.addEventListener('mouseup', onMouseUp, {once: true});\n },\n },\n };\n }\n\n get state(): StateField<PluginState> {\n return {\n init: () => ({disabled: false}),\n apply(tr) {\n return {disabled: Boolean(tr.getMeta(HideMetaKey))};\n },\n };\n }\n\n view(view: EditorView) {\n this.update(view);\n return {\n update: this.update.bind(this),\n destroy: () => {\n this.destroyed = true;\n this.cancelTooltipHiding();\n this.tooltip.destroy();\n },\n };\n }\n\n private update(view: EditorView, prevState?: TinyState) {\n this.editorView = view;\n\n if (this._isMousePressed) return;\n\n this.cancelTooltipHiding();\n\n const hideFromTr = pluginKey.getState(view.state)?.disabled;\n\n // Don't show tooltip if editor not mounted to the DOM\n if (hideFromTr || !view.dom.parentNode) {\n this.tooltip.hide(view);\n return;\n }\n\n const {state} = view;\n // Don't do anything if the document/selection didn't change\n if (prevState && prevState.doc.eq(state.doc) && prevState.selection.eq(state.selection)) {\n return;\n }\n\n // Don't show tooltip if editor out of focus\n if (!view.hasFocus()) {\n this.tooltip.hide(view);\n return;\n }\n\n const {selection} = state;\n // Hide the tooltip if the selection is empty\n if (\n selection.empty ||\n !(selection instanceof TextSelection || selection instanceof AllSelection)\n ) {\n this.tooltip.hide(view);\n return;\n }\n\n if (\n // Hide tooltip when one side of selection is inside a codeblock\n isCodeBlock(selection.$from.parent) ||\n isCodeBlock(selection.$to.parent) ||\n // or when selection is inside node where context menu is disabled\n hasParentNode((node: Node) => node.type.spec.selectionContext === false)(selection)\n ) {\n this.tooltip.hide(view);\n return;\n }\n\n this.tooltip.show(view);\n }\n\n private scheduleTooltipHiding(view: EditorView) {\n this.hideTimeoutRef = setTimeout(() => {\n // hide tooltip if view is out of focus after 30 ms\n if (!view.hasFocus()) {\n this.tooltip.hide(view);\n }\n }, 30);\n }\n\n private cancelTooltipHiding() {\n if (this.hideTimeoutRef !== null) {\n clearTimeout(this.hideTimeoutRef);\n this.hideTimeoutRef = null;\n }\n }\n}\n\ndeclare module 'prosemirror-model' {\n interface NodeSpec {\n /** Set false to disable the selection-context menu within this node */\n selectionContext?: boolean | undefined;\n }\n}\n"]}
|
|
@@ -1,21 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { EditorState } from 'prosemirror-state';
|
|
1
|
+
import type { PopupProps } from '@gravity-ui/uikit';
|
|
3
2
|
import type { EditorView } from 'prosemirror-view';
|
|
4
3
|
import type { ActionStorage } from "../../../core/index.js";
|
|
5
4
|
import { type Logger2 } from "../../../logger.js";
|
|
6
|
-
import type {
|
|
7
|
-
export type ContextGroupItemData
|
|
8
|
-
condition?: (state: EditorState) => void;
|
|
9
|
-
}) | ((ToolbarSingleItemData<ActionStorage> | ToolbarButtonPopupData<ActionStorage>) & {
|
|
10
|
-
condition?: 'enabled';
|
|
11
|
-
});
|
|
12
|
-
export type ContextGroupData = ContextGroupItemData[];
|
|
13
|
-
export type ContextConfig = ContextGroupData[];
|
|
5
|
+
import type { ContextConfig } from "./types.js";
|
|
6
|
+
export type { ContextGroupItemData, ContextGroupData, ContextConfig } from "./types.js";
|
|
14
7
|
export type TooltipViewParams = {
|
|
15
8
|
/** @default 'bottom' */
|
|
16
9
|
placement?: 'top' | 'bottom';
|
|
17
10
|
/** @default false */
|
|
18
11
|
flip?: boolean;
|
|
12
|
+
onPopupOpenChange: PopupProps['onOpenChange'];
|
|
19
13
|
};
|
|
20
14
|
export declare class TooltipView {
|
|
21
15
|
#private;
|
|
@@ -23,17 +17,19 @@ export declare class TooltipView {
|
|
|
23
17
|
private readonly actions;
|
|
24
18
|
private readonly menuConfig;
|
|
25
19
|
private readonly placement;
|
|
20
|
+
private readonly onPopupOpenChange;
|
|
26
21
|
private view;
|
|
27
|
-
private
|
|
22
|
+
private visible;
|
|
23
|
+
private anchor;
|
|
28
24
|
private _tooltipRenderItem;
|
|
29
25
|
constructor(actions: ActionStorage, menuConfig: ContextConfig, logger: Logger2.ILogger, params: TooltipViewParams);
|
|
30
26
|
get isTooltipOpen(): boolean;
|
|
31
|
-
show(view: EditorView
|
|
27
|
+
show(view: EditorView): void;
|
|
32
28
|
hide(view: EditorView): void;
|
|
33
29
|
destroy(): void;
|
|
34
|
-
private
|
|
35
|
-
private
|
|
30
|
+
private readonly handleFocus;
|
|
31
|
+
private readonly handleClick;
|
|
36
32
|
private renderPopup;
|
|
37
33
|
private get tooltipRenderItem();
|
|
38
|
-
private
|
|
34
|
+
private createVirtualElement;
|
|
39
35
|
}
|
|
@@ -1,100 +1,72 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Popup } from '@gravity-ui/uikit';
|
|
3
|
-
import { isFunction } from "../../../lodash.js";
|
|
4
2
|
import { globalLogger } from "../../../logger.js";
|
|
5
3
|
import { ErrorLoggerBoundary } from "../../../react-utils/ErrorBoundary.js";
|
|
6
|
-
import { Toolbar } from "../../../toolbar/index.js";
|
|
7
4
|
import { getReactRendererFromState } from "../ReactRenderer/index.js";
|
|
8
|
-
|
|
9
|
-
if (!show)
|
|
10
|
-
return null;
|
|
11
|
-
return (_jsx(Popup, { open: true, ...poppupProps, style: { padding: '4px 8px' }, children: _jsx(Toolbar, { ...toolbarProps }) }));
|
|
12
|
-
};
|
|
5
|
+
import { TextSelectionTooltip } from "./TextSelectionTooltip.js";
|
|
13
6
|
export class TooltipView {
|
|
14
7
|
#isTooltipOpen = false;
|
|
15
8
|
logger;
|
|
16
9
|
actions;
|
|
17
10
|
menuConfig;
|
|
18
11
|
placement;
|
|
12
|
+
onPopupOpenChange;
|
|
19
13
|
view;
|
|
20
|
-
|
|
14
|
+
visible = false;
|
|
15
|
+
anchor = undefined;
|
|
21
16
|
_tooltipRenderItem = null;
|
|
22
17
|
constructor(actions, menuConfig, logger, params) {
|
|
23
18
|
this.logger = logger;
|
|
24
19
|
this.actions = actions;
|
|
25
20
|
this.menuConfig = menuConfig;
|
|
26
|
-
const { flip, placement = 'bottom' } = params;
|
|
21
|
+
const { flip, placement = 'bottom', onPopupOpenChange } = params;
|
|
27
22
|
this.placement = flip ? placement : [placement];
|
|
23
|
+
this.onPopupOpenChange = onPopupOpenChange;
|
|
28
24
|
}
|
|
29
25
|
get isTooltipOpen() {
|
|
30
26
|
return this.#isTooltipOpen;
|
|
31
27
|
}
|
|
32
|
-
show(view
|
|
28
|
+
show(view) {
|
|
33
29
|
this.view = view;
|
|
34
30
|
this.#isTooltipOpen = true;
|
|
35
|
-
this.
|
|
36
|
-
|
|
37
|
-
poppupProps: {
|
|
38
|
-
...popupProps,
|
|
39
|
-
...this.calcPosition(view),
|
|
40
|
-
},
|
|
41
|
-
};
|
|
31
|
+
this.visible = true;
|
|
32
|
+
this.anchor ??= this.createVirtualElement(view);
|
|
42
33
|
this.renderPopup();
|
|
43
34
|
}
|
|
44
35
|
hide(view) {
|
|
45
36
|
this.view = view;
|
|
46
37
|
// do not rerender popup if it is already hidden
|
|
47
|
-
if (!this.#isTooltipOpen && !this.
|
|
38
|
+
if (!this.#isTooltipOpen && !this.visible)
|
|
48
39
|
return;
|
|
49
40
|
this.#isTooltipOpen = false;
|
|
50
|
-
this.
|
|
41
|
+
this.visible = false;
|
|
42
|
+
this.anchor = undefined;
|
|
51
43
|
this.renderPopup();
|
|
52
44
|
}
|
|
53
45
|
destroy() {
|
|
54
46
|
this._tooltipRenderItem?.remove();
|
|
55
47
|
this._tooltipRenderItem = null;
|
|
56
48
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
data: this.getFilteredConfig(),
|
|
63
|
-
editor: this.actions,
|
|
64
|
-
onClick: (id) => {
|
|
65
|
-
globalLogger.action({ mode: 'wysiwyg', source: 'context-menu', action: id });
|
|
66
|
-
this.logger.action({ source: 'context-menu', action: id });
|
|
67
|
-
},
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
getFilteredConfig() {
|
|
71
|
-
return this.baseProps.show
|
|
72
|
-
? this.menuConfig
|
|
73
|
-
.map((groupData) => groupData.filter((item) => {
|
|
74
|
-
const { condition } = item;
|
|
75
|
-
if (condition === 'enabled') {
|
|
76
|
-
return item.isEnable(this.actions);
|
|
77
|
-
}
|
|
78
|
-
if (isFunction(condition)) {
|
|
79
|
-
return condition(this.view.state);
|
|
80
|
-
}
|
|
81
|
-
return true;
|
|
82
|
-
}))
|
|
83
|
-
.filter((groupData) => Boolean(groupData.length))
|
|
84
|
-
: [];
|
|
85
|
-
}
|
|
49
|
+
handleFocus = () => this.view.focus();
|
|
50
|
+
handleClick = (id) => {
|
|
51
|
+
globalLogger.action({ mode: 'wysiwyg', source: 'context-menu', action: id });
|
|
52
|
+
this.logger.action({ source: 'context-menu', action: id });
|
|
53
|
+
};
|
|
86
54
|
renderPopup() {
|
|
87
55
|
this.tooltipRenderItem.rerender();
|
|
88
56
|
}
|
|
89
57
|
get tooltipRenderItem() {
|
|
90
58
|
if (!this._tooltipRenderItem) {
|
|
91
59
|
const reactRenderer = getReactRendererFromState(this.view.state);
|
|
92
|
-
this._tooltipRenderItem = reactRenderer.createItem('selection_context', () =>
|
|
60
|
+
this._tooltipRenderItem = reactRenderer.createItem('selection_context', () => {
|
|
61
|
+
if (!this.visible)
|
|
62
|
+
return null;
|
|
63
|
+
return (_jsx(ErrorLoggerBoundary, { children: _jsx(TextSelectionTooltip, { config: this.menuConfig, editor: this.actions, editorView: this.view, focus: this.handleFocus, onClick: this.handleClick, popupPlacement: this.placement, popupAnchor: this.anchor, popupOnOpenChange: this.onPopupOpenChange }) }));
|
|
64
|
+
});
|
|
93
65
|
}
|
|
94
66
|
return this._tooltipRenderItem;
|
|
95
67
|
}
|
|
96
|
-
|
|
97
|
-
|
|
68
|
+
createVirtualElement(view) {
|
|
69
|
+
return {
|
|
98
70
|
getBoundingClientRect() {
|
|
99
71
|
// These are in screen coordinates
|
|
100
72
|
const start = view.coordsAtPos(view.state.selection.from);
|
|
@@ -118,10 +90,6 @@ export class TooltipView {
|
|
|
118
90
|
};
|
|
119
91
|
},
|
|
120
92
|
};
|
|
121
|
-
return {
|
|
122
|
-
placement: this.placement,
|
|
123
|
-
anchorElement: virtualElem,
|
|
124
|
-
};
|
|
125
93
|
}
|
|
126
94
|
}
|
|
127
95
|
//# sourceMappingURL=tooltip.js.map
|