@limetech/lime-elements 37.44.3 → 37.45.1

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.
Files changed (34) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js +143 -17
  3. package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js.map +1 -1
  4. package/dist/cjs/limel-text-editor.cjs.entry.js.map +1 -1
  5. package/dist/collection/components/text-editor/prosemirror-adapter/menu/menu-commands.js +81 -10
  6. package/dist/collection/components/text-editor/prosemirror-adapter/menu/menu-commands.js.map +1 -1
  7. package/dist/collection/components/text-editor/prosemirror-adapter/menu/menu-items.js +27 -0
  8. package/dist/collection/components/text-editor/prosemirror-adapter/menu/menu-items.js.map +1 -1
  9. package/dist/collection/components/text-editor/prosemirror-adapter/menu/menu-schema-extender.js +12 -0
  10. package/dist/collection/components/text-editor/prosemirror-adapter/menu/menu-schema-extender.js.map +1 -0
  11. package/dist/collection/components/text-editor/prosemirror-adapter/menu/types.js +3 -0
  12. package/dist/collection/components/text-editor/prosemirror-adapter/menu/types.js.map +1 -1
  13. package/dist/collection/components/text-editor/prosemirror-adapter/prosemirror-adapter.js +16 -7
  14. package/dist/collection/components/text-editor/prosemirror-adapter/prosemirror-adapter.js.map +1 -1
  15. package/dist/collection/components/text-editor/text-editor.js +1 -1
  16. package/dist/collection/components/text-editor/text-editor.js.map +1 -1
  17. package/dist/collection/components/text-editor/utils/markdown-converter.js +8 -2
  18. package/dist/collection/components/text-editor/utils/markdown-converter.js.map +1 -1
  19. package/dist/collection/util/get-attributes.js +27 -0
  20. package/dist/collection/util/get-attributes.js.map +1 -0
  21. package/dist/esm/limel-prosemirror-adapter.entry.js +143 -17
  22. package/dist/esm/limel-prosemirror-adapter.entry.js.map +1 -1
  23. package/dist/esm/limel-text-editor.entry.js.map +1 -1
  24. package/dist/lime-elements/lime-elements.esm.js +1 -1
  25. package/dist/lime-elements/{p-50a34fa3.entry.js → p-3ae3b23e.entry.js} +2 -2
  26. package/dist/lime-elements/p-3ae3b23e.entry.js.map +1 -0
  27. package/dist/lime-elements/p-c5f96fcd.entry.js.map +1 -1
  28. package/dist/types/components/text-editor/prosemirror-adapter/menu/menu-commands.d.ts +9 -6
  29. package/dist/types/components/text-editor/prosemirror-adapter/menu/menu-items.d.ts +3 -0
  30. package/dist/types/components/text-editor/prosemirror-adapter/menu/menu-schema-extender.d.ts +3 -0
  31. package/dist/types/components/text-editor/prosemirror-adapter/prosemirror-adapter.d.ts +1 -0
  32. package/dist/types/util/get-attributes.d.ts +15 -0
  33. package/package.json +1 -1
  34. package/dist/lime-elements/p-50a34fa3.entry.js.map +0 -1
@@ -1 +1 @@
1
- {"file":"limel-text-editor.entry.cjs.js","mappings":"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","names":["h","createRandomString","Host"],"sources":["./src/components/text-editor/text-editor.scss?tag=limel-text-editor&encapsulation=shadow","./src/components/text-editor/text-editor.tsx"],"sourcesContent":["@use '../../style/internal/shared_input-select-picker';\n@use '../../style/mixins.scss';\n\n@include shared_input-select-picker.lime-looks-like-input-value;\n.lime-looks-like-input-value {\n padding: var(--limel-text-editor-padding);\n}\n\n* {\n box-sizing: border-box;\n}\n\n:host(limel-text-editor) {\n --limel-text-editor-outline-color: #{shared_input-select-picker.$lime-text-field-outline-color};\n --limel-text-editor-background-color: #{shared_input-select-picker.$background-color-normal};\n --limel-text-editor-label-color: #{shared_input-select-picker.$label-color};\n --limel-text-editor-padding: 0.75rem 1rem;\n position: relative;\n isolation: isolate;\n display: flex;\n flex-direction: column;\n\n width: 100%;\n min-width: 5rem;\n min-height: 5rem;\n height: 100%;\n max-height: 100%;\n}\n\n:host(limel-text-editor:hover) {\n --limel-text-editor-outline-color: #{shared_input-select-picker.$lime-text-field-outline-color--hovered};\n}\n\n:host(limel-text-editor:focus-within) {\n --limel-text-editor-outline-color: #{shared_input-select-picker.$lime-text-field-outline-color--focused};\n}\n\n:host(limel-text-editor[disabled]:not([disabled='false'])) {\n @include shared_input-select-picker.looks-disabled;\n\n limel-prosemirror-adapter {\n pointer-events: none;\n }\n}\n\n:host(limel-text-editor[invalid]:not([invalid='false'])) {\n --limel-text-editor-outline-color: var(--lime-error-text-color);\n}\n\n:host(limel-text-editor[readonly]:not([readonly='false'])) {\n --limel-text-editor-placeholder-top: 0;\n --limel-text-editor-outline-color: transparent;\n\n limel-markdown {\n display: block;\n padding: var(--limel-text-editor-padding);\n }\n}\n\n.notched-outline {\n transition: bottom\n var(--limel-h-l-grid-template-rows-transition-speed, 0.46s)\n cubic-bezier(1, 0.09, 0, 0.89);\n pointer-events: none;\n position: absolute;\n inset: 0;\n bottom: var(--limel-text-editor-notched-outline-bottom, 0);\n\n display: flex;\n background-color: var(--limel-text-editor-background-color);\n}\n\n.leading-outline,\n.notch,\n.trailing-outline {\n transition: border-color 0.2s ease;\n border-width: 1px;\n border-style: solid;\n border-color: var(--limel-text-editor-outline-color);\n}\n\n.leading-outline {\n flex-shrink: 0;\n width: 0.75rem;\n border-right-width: 0;\n border-top-left-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.notch {\n flex-shrink: 0;\n\n position: relative;\n z-index: 2;\n\n border-top-width: 0;\n border-right-width: 0;\n border-left-width: 0;\n\n max-width: calc(100% - 1.5rem);\n}\n\n.trailing-outline {\n flex-grow: 1;\n border-left-width: 0;\n border-top-right-radius: 0.25rem;\n border-bottom-right-radius: 0.25rem;\n}\n\nlabel {\n transform: translateY(-50%);\n\n @include mixins.truncate-text;\n display: block;\n padding: 0 0.25rem;\n\n color: var(--limel-text-editor-label-color);\n font-size: 0.65rem; // `10.4px` similar to MDC's floating label\n letter-spacing: var(--mdc-typography-subtitle1-letter-spacing, 0.009375em);\n\n :host(limel-text-editor[required]) & {\n &::after {\n content: '*';\n }\n }\n}\n\n.placeholder {\n @include mixins.truncate-text;\n pointer-events: none;\n position: absolute;\n top: var(--limel-text-editor-placeholder-top, 2.25rem);\n left: 0;\n right: 0;\n\n padding: var(--limel-text-editor-padding);\n font-style: italic;\n font-size: 0.875rem;\n color: shared_input-select-picker.$input-placeholder-color;\n}\n\nlimel-prosemirror-adapter {\n flex-grow: 1;\n\n min-width: 0;\n min-height: 0;\n height: 100%;\n overflow: hidden auto;\n}\n\n@include mixins.hide-helper-line-when-not-needed(limel-text-editor);\n:host(limel-text-editor.has-helper-text:focus-within),\n:host(limel-text-editor.has-helper-text[invalid]) {\n .notched-outline {\n --limel-text-editor-notched-outline-bottom: 1rem;\n }\n}\n\n:host(limel-text-editor[allow-resize]) {\n limel-prosemirror-adapter {\n resize: vertical;\n }\n}\n","import { Component, Event, EventEmitter, Host, Prop, h } from '@stencil/core';\nimport { FormComponent } from '../form/form.types';\nimport { createRandomString } from 'src/util/random-string';\nimport { Languages } from '../date-picker/date.types';\n/**\n * A rich text editor that offers a rich text editing experience with markdown support,\n * in the sense that you can easily type markdown syntax and see the rendered\n * result as rich text in real-time. For instance, you can type `# Hello, world!`\n * and see it directly turning to a heading 1 (an `<h1>` HTML element).\n *\n * Naturally, you can use standard keyboard hotkeys such as <kbd>Ctrl</kbd> + <kbd>B</kbd>\n * to toggle bold text, <kbd>Ctrl</kbd> + <kbd>I</kbd> to toggle italic text, and so on.\n *\n * @exampleComponent limel-example-text-editor-basic\n * @exampleComponent limel-example-text-editor-as-form-component\n * @exampleComponent limel-example-text-editor-with-markdown\n * @exampleComponent limel-example-text-editor-with-html\n * @exampleComponent limel-example-text-editor-allow-resize\n * @exampleComponent limel-example-text-editor-size\n * @exampleComponent limel-example-text-editor-composite\n * @beta\n * @private\n */\n@Component({\n tag: 'limel-text-editor',\n shadow: true,\n styleUrl: 'text-editor.scss',\n})\nexport class TextEditor implements FormComponent<string> {\n /** The type of content that the editor should handle and emit, defaults to `markdown`\n *\n * Assumed to be set only once, so not reactive to changes\n */\n @Prop()\n public contentType: 'markdown' | 'html' = 'markdown';\n\n /**\n * Defines the language for translations.\n */\n @Prop({ reflect: true })\n public language: Languages = 'en';\n\n /**\n * Set to `true` to disable the field.\n * Use `disabled` to indicate that the field can normally be interacted\n * with, but is currently disabled. This tells the user that if certain\n * requirements are met, the field may become enabled again.\n */\n @Prop({ reflect: true })\n public disabled?: boolean = false;\n\n /**\n * Set to `true` to make the component read-only.\n * Use `readonly` when the field is only there to present the data it holds,\n * and will not become possible for the current user to edit.\n * :::note\n * Consider that it might be better to use `limel-markdown`\n * instead of `limel-text-editor` when the goal is visualizing data.\n * :::\n */\n @Prop({ reflect: true })\n public readonly?: boolean = false;\n\n /**\n * Optional helper text to display below the input field when it has focus\n */\n @Prop({ reflect: true })\n public helperText?: string;\n\n /**\n * The placeholder text shown inside the input field,\n * when the field is empty.\n */\n @Prop({ reflect: true })\n public placeholder?: string;\n\n /**\n * The label of the editor\n */\n @Prop({ reflect: true })\n public label?: string;\n\n /**\n * Set to `true` to indicate that the current value of the editor is\n * invalid.\n */\n @Prop({ reflect: true })\n public invalid?: boolean = false;\n\n /**\n * Description of the text inside the editor as markdown\n */\n @Prop({ reflect: true })\n public value: string;\n\n /**\n * Set to `true` to indicate that the field is required.\n *\n * :::important\n * An empty but required field is not automatically considered invalid.\n * You must make sure to check the validity of the field on your own,\n * and properly handle the `invalid` state.\n * :::\n */\n @Prop({ reflect: true })\n public required?: boolean = false;\n\n /**\n * Set to `true` to allow the user to vertically resize the editor.\n * Set to `false` to disable the resize functionality.\n */\n @Prop({ reflect: true })\n public allowResize: boolean = true;\n\n /**\n * Dispatched when a change is made to the editor\n */\n @Event()\n public change: EventEmitter<string>;\n\n private helperTextId: string;\n private editorId: string;\n\n public constructor() {\n this.helperTextId = createRandomString();\n this.editorId = createRandomString();\n }\n\n public render() {\n return (\n <Host\n class={{\n 'has-helper-text': !!this.helperText,\n }}\n >\n <span class=\"notched-outline\">\n <span class=\"leading-outline\" />\n {this.renderLabel()}\n <span class=\"trailing-outline\" />\n </span>\n {this.renderEditor()}\n </Host>\n );\n }\n\n private renderEditor() {\n if (this.readonly && !this.value) {\n return [\n <span class=\"lime-looks-like-input-value\">–</span>,\n this.renderHelperLine(),\n ];\n }\n\n if (this.readonly) {\n return [\n <limel-markdown\n value={this.value}\n aria-controls={this.helperTextId}\n id={this.editorId}\n />,\n this.renderPlaceholder(),\n this.renderHelperLine(),\n ];\n }\n\n return [\n <limel-prosemirror-adapter\n aria-placeholder={this.placeholder}\n contentType={this.contentType}\n onChange={this.handleChange}\n value={this.value}\n aria-controls={this.helperTextId}\n id={this.editorId}\n tabindex={this.disabled ? -1 : 0}\n aria-disabled={this.disabled}\n language={this.language}\n />,\n this.renderPlaceholder(),\n this.renderHelperLine(),\n ];\n }\n\n private renderLabel() {\n if (!this.label) {\n return;\n }\n\n return (\n <span class=\"notch\">\n <label htmlFor={this.editorId}>{this.label}</label>\n </span>\n );\n }\n\n private renderPlaceholder() {\n if (!this.placeholder || this.value) {\n return;\n }\n\n return (\n <span class=\"placeholder\" aria-hidden=\"true\">\n {this.placeholder}\n </span>\n );\n }\n\n private renderHelperLine = () => {\n if (!this.helperText) {\n return;\n }\n\n return (\n <limel-helper-line\n helperText={this.helperText}\n helperTextId={this.helperTextId}\n invalid={this.isInvalid()}\n />\n );\n };\n\n private isInvalid = () => {\n if (this.readonly) {\n // A readonly field can never be invalid.\n return false;\n }\n\n if (this.invalid) {\n return true;\n }\n };\n\n private handleChange = () => (event: CustomEvent<string>) => {\n event.stopPropagation();\n this.change.emit(event.detail);\n };\n}\n"],"version":3}
1
+ {"file":"limel-text-editor.entry.cjs.js","mappings":"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","names":["h","createRandomString","Host"],"sources":["./src/components/text-editor/text-editor.scss?tag=limel-text-editor&encapsulation=shadow","./src/components/text-editor/text-editor.tsx"],"sourcesContent":["@use '../../style/internal/shared_input-select-picker';\n@use '../../style/mixins.scss';\n\n@include shared_input-select-picker.lime-looks-like-input-value;\n.lime-looks-like-input-value {\n padding: var(--limel-text-editor-padding);\n}\n\n* {\n box-sizing: border-box;\n}\n\n:host(limel-text-editor) {\n --limel-text-editor-outline-color: #{shared_input-select-picker.$lime-text-field-outline-color};\n --limel-text-editor-background-color: #{shared_input-select-picker.$background-color-normal};\n --limel-text-editor-label-color: #{shared_input-select-picker.$label-color};\n --limel-text-editor-padding: 0.75rem 1rem;\n position: relative;\n isolation: isolate;\n display: flex;\n flex-direction: column;\n\n width: 100%;\n min-width: 5rem;\n min-height: 5rem;\n height: 100%;\n max-height: 100%;\n}\n\n:host(limel-text-editor:hover) {\n --limel-text-editor-outline-color: #{shared_input-select-picker.$lime-text-field-outline-color--hovered};\n}\n\n:host(limel-text-editor:focus-within) {\n --limel-text-editor-outline-color: #{shared_input-select-picker.$lime-text-field-outline-color--focused};\n}\n\n:host(limel-text-editor[disabled]:not([disabled='false'])) {\n @include shared_input-select-picker.looks-disabled;\n\n limel-prosemirror-adapter {\n pointer-events: none;\n }\n}\n\n:host(limel-text-editor[invalid]:not([invalid='false'])) {\n --limel-text-editor-outline-color: var(--lime-error-text-color);\n}\n\n:host(limel-text-editor[readonly]:not([readonly='false'])) {\n --limel-text-editor-placeholder-top: 0;\n --limel-text-editor-outline-color: transparent;\n\n limel-markdown {\n display: block;\n padding: var(--limel-text-editor-padding);\n }\n}\n\n.notched-outline {\n transition: bottom\n var(--limel-h-l-grid-template-rows-transition-speed, 0.46s)\n cubic-bezier(1, 0.09, 0, 0.89);\n pointer-events: none;\n position: absolute;\n inset: 0;\n bottom: var(--limel-text-editor-notched-outline-bottom, 0);\n\n display: flex;\n background-color: var(--limel-text-editor-background-color);\n}\n\n.leading-outline,\n.notch,\n.trailing-outline {\n transition: border-color 0.2s ease;\n border-width: 1px;\n border-style: solid;\n border-color: var(--limel-text-editor-outline-color);\n}\n\n.leading-outline {\n flex-shrink: 0;\n width: 0.75rem;\n border-right-width: 0;\n border-top-left-radius: 0.25rem;\n border-bottom-left-radius: 0.25rem;\n}\n\n.notch {\n flex-shrink: 0;\n\n position: relative;\n z-index: 2;\n\n border-top-width: 0;\n border-right-width: 0;\n border-left-width: 0;\n\n max-width: calc(100% - 1.5rem);\n}\n\n.trailing-outline {\n flex-grow: 1;\n border-left-width: 0;\n border-top-right-radius: 0.25rem;\n border-bottom-right-radius: 0.25rem;\n}\n\nlabel {\n transform: translateY(-50%);\n\n @include mixins.truncate-text;\n display: block;\n padding: 0 0.25rem;\n\n color: var(--limel-text-editor-label-color);\n font-size: 0.65rem; // `10.4px` similar to MDC's floating label\n letter-spacing: var(--mdc-typography-subtitle1-letter-spacing, 0.009375em);\n\n :host(limel-text-editor[required]) & {\n &::after {\n content: '*';\n }\n }\n}\n\n.placeholder {\n @include mixins.truncate-text;\n pointer-events: none;\n position: absolute;\n top: var(--limel-text-editor-placeholder-top, 2.25rem);\n left: 0;\n right: 0;\n\n padding: var(--limel-text-editor-padding);\n font-style: italic;\n font-size: 0.875rem;\n color: shared_input-select-picker.$input-placeholder-color;\n}\n\nlimel-prosemirror-adapter {\n flex-grow: 1;\n\n min-width: 0;\n min-height: 0;\n height: 100%;\n overflow: hidden auto;\n}\n\n@include mixins.hide-helper-line-when-not-needed(limel-text-editor);\n:host(limel-text-editor.has-helper-text:focus-within),\n:host(limel-text-editor.has-helper-text[invalid]) {\n .notched-outline {\n --limel-text-editor-notched-outline-bottom: 1rem;\n }\n}\n\n:host(limel-text-editor[allow-resize]) {\n limel-prosemirror-adapter {\n resize: vertical;\n }\n}\n","import { Component, Event, EventEmitter, Host, Prop, h } from '@stencil/core';\nimport { FormComponent } from '../form/form.types';\nimport { Languages } from '../date-picker/date.types';\nimport { createRandomString } from '../../util/random-string';\n/**\n * A rich text editor that offers a rich text editing experience with markdown support,\n * in the sense that you can easily type markdown syntax and see the rendered\n * result as rich text in real-time. For instance, you can type `# Hello, world!`\n * and see it directly turning to a heading 1 (an `<h1>` HTML element).\n *\n * Naturally, you can use standard keyboard hotkeys such as <kbd>Ctrl</kbd> + <kbd>B</kbd>\n * to toggle bold text, <kbd>Ctrl</kbd> + <kbd>I</kbd> to toggle italic text, and so on.\n *\n * @exampleComponent limel-example-text-editor-basic\n * @exampleComponent limel-example-text-editor-as-form-component\n * @exampleComponent limel-example-text-editor-with-markdown\n * @exampleComponent limel-example-text-editor-with-html\n * @exampleComponent limel-example-text-editor-allow-resize\n * @exampleComponent limel-example-text-editor-size\n * @exampleComponent limel-example-text-editor-composite\n * @beta\n * @private\n */\n@Component({\n tag: 'limel-text-editor',\n shadow: true,\n styleUrl: 'text-editor.scss',\n})\nexport class TextEditor implements FormComponent<string> {\n /** The type of content that the editor should handle and emit, defaults to `markdown`\n *\n * Assumed to be set only once, so not reactive to changes\n */\n @Prop()\n public contentType: 'markdown' | 'html' = 'markdown';\n\n /**\n * Defines the language for translations.\n */\n @Prop({ reflect: true })\n public language: Languages = 'en';\n\n /**\n * Set to `true` to disable the field.\n * Use `disabled` to indicate that the field can normally be interacted\n * with, but is currently disabled. This tells the user that if certain\n * requirements are met, the field may become enabled again.\n */\n @Prop({ reflect: true })\n public disabled?: boolean = false;\n\n /**\n * Set to `true` to make the component read-only.\n * Use `readonly` when the field is only there to present the data it holds,\n * and will not become possible for the current user to edit.\n * :::note\n * Consider that it might be better to use `limel-markdown`\n * instead of `limel-text-editor` when the goal is visualizing data.\n * :::\n */\n @Prop({ reflect: true })\n public readonly?: boolean = false;\n\n /**\n * Optional helper text to display below the input field when it has focus\n */\n @Prop({ reflect: true })\n public helperText?: string;\n\n /**\n * The placeholder text shown inside the input field,\n * when the field is empty.\n */\n @Prop({ reflect: true })\n public placeholder?: string;\n\n /**\n * The label of the editor\n */\n @Prop({ reflect: true })\n public label?: string;\n\n /**\n * Set to `true` to indicate that the current value of the editor is\n * invalid.\n */\n @Prop({ reflect: true })\n public invalid?: boolean = false;\n\n /**\n * Description of the text inside the editor as markdown\n */\n @Prop({ reflect: true })\n public value: string;\n\n /**\n * Set to `true` to indicate that the field is required.\n *\n * :::important\n * An empty but required field is not automatically considered invalid.\n * You must make sure to check the validity of the field on your own,\n * and properly handle the `invalid` state.\n * :::\n */\n @Prop({ reflect: true })\n public required?: boolean = false;\n\n /**\n * Set to `true` to allow the user to vertically resize the editor.\n * Set to `false` to disable the resize functionality.\n */\n @Prop({ reflect: true })\n public allowResize: boolean = true;\n\n /**\n * Dispatched when a change is made to the editor\n */\n @Event()\n public change: EventEmitter<string>;\n\n private helperTextId: string;\n private editorId: string;\n\n public constructor() {\n this.helperTextId = createRandomString();\n this.editorId = createRandomString();\n }\n\n public render() {\n return (\n <Host\n class={{\n 'has-helper-text': !!this.helperText,\n }}\n >\n <span class=\"notched-outline\">\n <span class=\"leading-outline\" />\n {this.renderLabel()}\n <span class=\"trailing-outline\" />\n </span>\n {this.renderEditor()}\n </Host>\n );\n }\n\n private renderEditor() {\n if (this.readonly && !this.value) {\n return [\n <span class=\"lime-looks-like-input-value\">–</span>,\n this.renderHelperLine(),\n ];\n }\n\n if (this.readonly) {\n return [\n <limel-markdown\n value={this.value}\n aria-controls={this.helperTextId}\n id={this.editorId}\n />,\n this.renderPlaceholder(),\n this.renderHelperLine(),\n ];\n }\n\n return [\n <limel-prosemirror-adapter\n aria-placeholder={this.placeholder}\n contentType={this.contentType}\n onChange={this.handleChange}\n value={this.value}\n aria-controls={this.helperTextId}\n id={this.editorId}\n tabindex={this.disabled ? -1 : 0}\n aria-disabled={this.disabled}\n language={this.language}\n />,\n this.renderPlaceholder(),\n this.renderHelperLine(),\n ];\n }\n\n private renderLabel() {\n if (!this.label) {\n return;\n }\n\n return (\n <span class=\"notch\">\n <label htmlFor={this.editorId}>{this.label}</label>\n </span>\n );\n }\n\n private renderPlaceholder() {\n if (!this.placeholder || this.value) {\n return;\n }\n\n return (\n <span class=\"placeholder\" aria-hidden=\"true\">\n {this.placeholder}\n </span>\n );\n }\n\n private renderHelperLine = () => {\n if (!this.helperText) {\n return;\n }\n\n return (\n <limel-helper-line\n helperText={this.helperText}\n helperTextId={this.helperTextId}\n invalid={this.isInvalid()}\n />\n );\n };\n\n private isInvalid = () => {\n if (this.readonly) {\n // A readonly field can never be invalid.\n return false;\n }\n\n if (this.invalid) {\n return true;\n }\n };\n\n private handleChange = () => (event: CustomEvent<string>) => {\n event.stopPropagation();\n this.change.emit(event.detail);\n };\n}\n"],"version":3}
@@ -1,5 +1,6 @@
1
1
  import { toggleMark, setBlockType, wrapIn } from 'prosemirror-commands';
2
- import { wrapInList } from 'prosemirror-schema-list';
2
+ import { findWrapping, liftTarget } from 'prosemirror-transform';
3
+ import { TextSelection } from 'prosemirror-state';
3
4
  import { EditorMenuTypes, LevelMapping } from './types';
4
5
  const setActiveMethodForMark = (command, markType) => {
5
6
  command.active = (state) => {
@@ -17,7 +18,7 @@ const setActiveMethodForNode = (command, nodeType, level) => {
17
18
  const { $from } = state.selection;
18
19
  const node = $from.node($from.depth);
19
20
  if (node && node.type.name === nodeType.name) {
20
- if (nodeType.name === 'heading') {
21
+ if (nodeType.name === LevelMapping.Heading && level) {
21
22
  return node.attrs.level === level;
22
23
  }
23
24
  return true;
@@ -62,14 +63,44 @@ const getAttributes = (markName, url) => {
62
63
  const isExternalLink = (url) => {
63
64
  return !url.startsWith(window.location.origin);
64
65
  };
66
+ const toggleBlockType = (schema, type, attrs = {}, wrap = false) => {
67
+ const blockType = schema.nodes[type];
68
+ const paragraphType = schema.nodes.paragraph;
69
+ return (state, dispatch) => {
70
+ const { $from, to } = state.selection;
71
+ if (state.selection instanceof TextSelection &&
72
+ $from.sameParent($from.doc.resolve(to))) {
73
+ if ($from.parent.type === blockType) {
74
+ if (dispatch) {
75
+ dispatch(state.tr.setBlockType($from.pos, to, paragraphType));
76
+ }
77
+ return true;
78
+ }
79
+ else {
80
+ if (wrap) {
81
+ return wrapIn(blockType, attrs)(state, dispatch);
82
+ }
83
+ else {
84
+ return setBlockType(blockType, attrs)(state, dispatch);
85
+ }
86
+ }
87
+ }
88
+ return false;
89
+ };
90
+ };
65
91
  const createSetNodeTypeCommand = (schema, nodeType, level) => {
66
92
  const type = schema.nodes[nodeType];
67
93
  if (!type) {
68
94
  throw new Error(`Node type "${nodeType}" not found in schema`);
69
95
  }
70
96
  let command;
71
- if (nodeType === 'heading' && level) {
72
- command = setBlockType(type, { level: level });
97
+ if (nodeType === LevelMapping.Heading && level) {
98
+ command = toggleBlockType(schema, LevelMapping.Heading, {
99
+ level: level,
100
+ });
101
+ }
102
+ else if (nodeType === EditorMenuTypes.CodeBlock) {
103
+ command = toggleBlockType(schema, EditorMenuTypes.CodeBlock);
73
104
  }
74
105
  else {
75
106
  command = setBlockType(type);
@@ -82,16 +113,50 @@ const createWrapInCommand = (schema, nodeType) => {
82
113
  if (!type) {
83
114
  throw new Error(`Node type "${nodeType}" not found in schema`);
84
115
  }
85
- const command = wrapIn(type);
116
+ let command;
117
+ if (nodeType === EditorMenuTypes.Blockquote) {
118
+ command = toggleBlockType(schema, EditorMenuTypes.Blockquote, {}, true);
119
+ }
120
+ else {
121
+ command = wrapIn(type);
122
+ }
86
123
  setActiveMethodForWrap(command, type);
87
124
  return command;
88
125
  };
126
+ const toggleList = (listType) => {
127
+ return (state, dispatch) => {
128
+ const { $from, $to } = state.selection;
129
+ const range = $from.blockRange($to);
130
+ if (!range) {
131
+ return false;
132
+ }
133
+ const wrapping = range && findWrapping(range, listType);
134
+ if (wrapping) {
135
+ // Wrap the selection in a list
136
+ if (dispatch) {
137
+ dispatch(state.tr.wrap(range, wrapping).scrollIntoView());
138
+ }
139
+ return true;
140
+ }
141
+ else {
142
+ // Check if we are in a list item and lift out of the list
143
+ const liftRange = range && liftTarget(range);
144
+ if (liftRange !== null) {
145
+ if (dispatch) {
146
+ dispatch(state.tr.lift(range, liftRange).scrollIntoView());
147
+ }
148
+ return true;
149
+ }
150
+ return false;
151
+ }
152
+ };
153
+ };
89
154
  const createListCommand = (schema, listType) => {
90
155
  const type = schema.nodes[listType];
91
156
  if (!type) {
92
157
  throw new Error(`List type "${listType}" not found in schema`);
93
158
  }
94
- const command = wrapInList(type);
159
+ const command = toggleList(type);
95
160
  setActiveMethodForWrap(command, type);
96
161
  return command;
97
162
  };
@@ -99,15 +164,18 @@ const commandMapping = {
99
164
  strong: createToggleMarkCommand,
100
165
  em: createToggleMarkCommand,
101
166
  underline: createToggleMarkCommand,
167
+ strikethrough: createToggleMarkCommand,
168
+ code: createToggleMarkCommand,
169
+ link: createToggleMarkCommand,
102
170
  headerlevel1: (schema) => createSetNodeTypeCommand(schema, LevelMapping.Heading, LevelMapping.one),
103
171
  headerlevel2: (schema) => createSetNodeTypeCommand(schema, LevelMapping.Heading, LevelMapping.two),
104
172
  headerlevel3: (schema) => createSetNodeTypeCommand(schema, LevelMapping.Heading, LevelMapping.three),
105
- blockquote: createWrapInCommand,
173
+ blockquote: (schema) => createWrapInCommand(schema, EditorMenuTypes.Blockquote),
106
174
  /* eslint-disable camelcase */
107
- ordered_list: createListCommand,
108
- bullet_list: createListCommand,
175
+ code_block: (schema) => createSetNodeTypeCommand(schema, EditorMenuTypes.CodeBlock),
176
+ ordered_list: (schema) => createListCommand(schema, EditorMenuTypes.OrderedList),
177
+ bullet_list: (schema) => createListCommand(schema, EditorMenuTypes.BulletList),
109
178
  /* eslint-enable camelcase */
110
- link: createToggleMarkCommand,
111
179
  };
112
180
  export class MenuCommandFactory {
113
181
  constructor(schema) {
@@ -127,6 +195,9 @@ export class MenuCommandFactory {
127
195
  'Mod-Shift-1': this.getCommand(EditorMenuTypes.HeaderLevel1),
128
196
  'Mod-Shift-2': this.getCommand(EditorMenuTypes.HeaderLevel2),
129
197
  'Mod-Shift-3': this.getCommand(EditorMenuTypes.HeaderLevel3),
198
+ 'Mod-Shift-X': this.getCommand(EditorMenuTypes.Strikethrough),
199
+ 'Mod-`': this.getCommand(EditorMenuTypes.Code),
200
+ 'Mod-Shift-C': this.getCommand(EditorMenuTypes.CodeBlock),
130
201
  };
131
202
  }
132
203
  }
@@ -1 +1 @@
1
- {"version":3,"file":"menu-commands.js","sourceRoot":"","sources":["../../../../../src/components/text-editor/prosemirror-adapter/menu/menu-commands.ts"],"names":[],"mappings":"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","sourcesContent":["import { toggleMark, setBlockType, wrapIn } from 'prosemirror-commands';\nimport { Schema, MarkType, NodeType, Attrs } from 'prosemirror-model';\nimport { wrapInList } from 'prosemirror-schema-list';\nimport { Command, EditorState } from 'prosemirror-state';\nimport { EditorMenuTypes, LevelMapping } from './types';\n\ntype CommandFunction = (\n schema: Schema,\n mark: EditorMenuTypes,\n url?: string,\n) => Command;\n\ninterface CommandMapping {\n [key: string]: CommandFunction;\n}\n\nexport interface CommandWithActive extends Command {\n active?: (state: EditorState) => boolean;\n}\n\nconst setActiveMethodForMark = (\n command: CommandWithActive,\n markType: MarkType,\n) => {\n command.active = (state) => {\n const { from, $from, to, empty } = state.selection;\n if (empty) {\n return !!markType.isInSet(state.storedMarks || $from.marks());\n } else {\n return state.doc.rangeHasMark(from, to, markType);\n }\n };\n};\n\nconst setActiveMethodForNode = (\n command: CommandWithActive,\n nodeType: NodeType,\n level?: number,\n) => {\n command.active = (state) => {\n const { $from } = state.selection;\n const node = $from.node($from.depth);\n\n if (node && node.type.name === nodeType.name) {\n if (nodeType.name === 'heading') {\n return node.attrs.level === level;\n }\n\n return true;\n }\n\n return false;\n };\n};\n\nconst setActiveMethodForWrap = (\n command: CommandWithActive,\n nodeType: NodeType,\n) => {\n command.active = (state) => {\n const { from, to } = state.selection;\n\n for (let pos = from; pos <= to; pos++) {\n const resolvedPos = state.doc.resolve(pos);\n for (let i = resolvedPos.depth; i > 0; i--) {\n const node = resolvedPos.node(i);\n if (node && node.type.name === nodeType.name) {\n return true;\n }\n }\n }\n\n return false;\n };\n};\n\nconst createToggleMarkCommand = (\n schema: Schema,\n markName: string,\n url?: string,\n): CommandWithActive => {\n const markType: MarkType | undefined = schema.marks[markName];\n if (!markType) {\n throw new Error(`Mark \"${markName}\" not found in schema`);\n }\n\n const attrs = getAttributes(markName, url);\n\n const command: CommandWithActive = toggleMark(markType, attrs);\n setActiveMethodForMark(command, markType);\n\n return command;\n};\n\nconst getAttributes = (markName: string, url: string): Attrs | null => {\n if (markName === EditorMenuTypes.Link && url) {\n return {\n href: url,\n target: isExternalLink(url) ? '_blank' : null,\n };\n }\n\n return undefined;\n};\n\nconst isExternalLink = (url: string): boolean => {\n return !url.startsWith(window.location.origin);\n};\n\nconst createSetNodeTypeCommand = (\n schema: Schema,\n nodeType: string,\n level?: number,\n): CommandWithActive => {\n const type: NodeType | undefined = schema.nodes[nodeType];\n if (!type) {\n throw new Error(`Node type \"${nodeType}\" not found in schema`);\n }\n\n let command: CommandWithActive;\n if (nodeType === 'heading' && level) {\n command = setBlockType(type, { level: level });\n } else {\n command = setBlockType(type);\n }\n\n setActiveMethodForNode(command, type, level);\n\n return command;\n};\n\nconst createWrapInCommand = (\n schema: Schema,\n nodeType: string,\n): CommandWithActive => {\n const type: NodeType | undefined = schema.nodes[nodeType];\n if (!type) {\n throw new Error(`Node type \"${nodeType}\" not found in schema`);\n }\n\n const command: CommandWithActive = wrapIn(type);\n setActiveMethodForWrap(command, type);\n\n return command;\n};\n\nconst createListCommand = (\n schema: Schema,\n listType: string,\n): CommandWithActive => {\n const type: NodeType | undefined = schema.nodes[listType];\n if (!type) {\n throw new Error(`List type \"${listType}\" not found in schema`);\n }\n\n const command: CommandWithActive = wrapInList(type);\n setActiveMethodForWrap(command, type);\n\n return command;\n};\n\nconst commandMapping: CommandMapping = {\n strong: createToggleMarkCommand,\n em: createToggleMarkCommand,\n underline: createToggleMarkCommand,\n headerlevel1: (schema) =>\n createSetNodeTypeCommand(\n schema,\n LevelMapping.Heading,\n LevelMapping.one,\n ),\n headerlevel2: (schema) =>\n createSetNodeTypeCommand(\n schema,\n LevelMapping.Heading,\n LevelMapping.two,\n ),\n headerlevel3: (schema) =>\n createSetNodeTypeCommand(\n schema,\n LevelMapping.Heading,\n LevelMapping.three,\n ),\n blockquote: createWrapInCommand,\n /* eslint-disable camelcase */\n ordered_list: createListCommand,\n bullet_list: createListCommand,\n /* eslint-enable camelcase */\n link: createToggleMarkCommand,\n};\n\nexport class MenuCommandFactory {\n private schema: Schema;\n\n constructor(schema: Schema) {\n this.schema = schema;\n }\n\n public getCommand(mark: EditorMenuTypes, url?: string) {\n const commandFunc = commandMapping[mark];\n if (!commandFunc) {\n throw new Error(`The Mark \"${mark}\" is not supported`);\n }\n\n return commandFunc(this.schema, mark, url);\n }\n\n buildKeymap() {\n return {\n 'Mod-B': this.getCommand(EditorMenuTypes.Bold),\n 'Mod-I': this.getCommand(EditorMenuTypes.Italic),\n 'Mod-Shift-1': this.getCommand(EditorMenuTypes.HeaderLevel1),\n 'Mod-Shift-2': this.getCommand(EditorMenuTypes.HeaderLevel2),\n 'Mod-Shift-3': this.getCommand(EditorMenuTypes.HeaderLevel3),\n };\n }\n}\n"]}
1
+ {"version":3,"file":"menu-commands.js","sourceRoot":"","sources":["../../../../../src/components/text-editor/prosemirror-adapter/menu/menu-commands.ts"],"names":[],"mappings":"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","sourcesContent":["import { toggleMark, setBlockType, wrapIn } from 'prosemirror-commands';\nimport { Schema, MarkType, NodeType, Attrs } from 'prosemirror-model';\nimport { findWrapping, liftTarget } from 'prosemirror-transform';\nimport { Command, EditorState, TextSelection } from 'prosemirror-state';\nimport { EditorMenuTypes, LevelMapping } from './types';\n\ntype CommandFunction = (\n schema: Schema,\n mark: EditorMenuTypes,\n url?: string,\n) => CommandWithActive;\n\ninterface CommandMapping {\n [key: string]: CommandFunction;\n}\n\nexport interface CommandWithActive extends Command {\n active?: (state: EditorState) => boolean;\n}\n\nconst setActiveMethodForMark = (\n command: CommandWithActive,\n markType: MarkType,\n) => {\n command.active = (state) => {\n const { from, $from, to, empty } = state.selection;\n if (empty) {\n return !!markType.isInSet(state.storedMarks || $from.marks());\n } else {\n return state.doc.rangeHasMark(from, to, markType);\n }\n };\n};\n\nconst setActiveMethodForNode = (\n command: CommandWithActive,\n nodeType: NodeType,\n level?: number,\n) => {\n command.active = (state) => {\n const { $from } = state.selection;\n const node = $from.node($from.depth);\n\n if (node && node.type.name === nodeType.name) {\n if (nodeType.name === LevelMapping.Heading && level) {\n return node.attrs.level === level;\n }\n\n return true;\n }\n\n return false;\n };\n};\n\nconst setActiveMethodForWrap = (\n command: CommandWithActive,\n nodeType: NodeType,\n) => {\n command.active = (state) => {\n const { from, to } = state.selection;\n\n for (let pos = from; pos <= to; pos++) {\n const resolvedPos = state.doc.resolve(pos);\n for (let i = resolvedPos.depth; i > 0; i--) {\n const node = resolvedPos.node(i);\n if (node && node.type.name === nodeType.name) {\n return true;\n }\n }\n }\n\n return false;\n };\n};\n\nconst createToggleMarkCommand = (\n schema: Schema,\n markName: string,\n url?: string,\n): CommandWithActive => {\n const markType: MarkType | undefined = schema.marks[markName];\n if (!markType) {\n throw new Error(`Mark \"${markName}\" not found in schema`);\n }\n\n const attrs = getAttributes(markName, url);\n\n const command: CommandWithActive = toggleMark(markType, attrs);\n setActiveMethodForMark(command, markType);\n\n return command;\n};\n\nconst getAttributes = (markName: string, url: string): Attrs | null => {\n if (markName === EditorMenuTypes.Link && url) {\n return {\n href: url,\n target: isExternalLink(url) ? '_blank' : null,\n };\n }\n\n return undefined;\n};\n\nconst isExternalLink = (url: string): boolean => {\n return !url.startsWith(window.location.origin);\n};\n\nconst toggleBlockType = (schema, type, attrs = {}, wrap = false) => {\n const blockType = schema.nodes[type];\n const paragraphType = schema.nodes.paragraph;\n\n return (state, dispatch) => {\n const { $from, to } = state.selection;\n if (\n state.selection instanceof TextSelection &&\n $from.sameParent($from.doc.resolve(to))\n ) {\n if ($from.parent.type === blockType) {\n if (dispatch) {\n dispatch(\n state.tr.setBlockType($from.pos, to, paragraphType),\n );\n }\n\n return true;\n } else {\n if (wrap) {\n return wrapIn(blockType, attrs)(state, dispatch);\n } else {\n return setBlockType(blockType, attrs)(state, dispatch);\n }\n }\n }\n\n return false;\n };\n};\n\nconst createSetNodeTypeCommand = (\n schema: Schema,\n nodeType: string,\n level?: number,\n): CommandWithActive => {\n const type: NodeType | undefined = schema.nodes[nodeType];\n if (!type) {\n throw new Error(`Node type \"${nodeType}\" not found in schema`);\n }\n\n let command: CommandWithActive;\n if (nodeType === LevelMapping.Heading && level) {\n command = toggleBlockType(schema, LevelMapping.Heading, {\n level: level,\n });\n } else if (nodeType === EditorMenuTypes.CodeBlock) {\n command = toggleBlockType(schema, EditorMenuTypes.CodeBlock);\n } else {\n command = setBlockType(type);\n }\n\n setActiveMethodForNode(command, type, level);\n\n return command;\n};\n\nconst createWrapInCommand = (\n schema: Schema,\n nodeType: string,\n): CommandWithActive => {\n const type: NodeType | undefined = schema.nodes[nodeType];\n if (!type) {\n throw new Error(`Node type \"${nodeType}\" not found in schema`);\n }\n\n let command: CommandWithActive;\n if (nodeType === EditorMenuTypes.Blockquote) {\n command = toggleBlockType(schema, EditorMenuTypes.Blockquote, {}, true);\n } else {\n command = wrapIn(type);\n }\n\n setActiveMethodForWrap(command, type);\n\n return command;\n};\n\nconst toggleList = (listType) => {\n return (state, dispatch) => {\n const { $from, $to } = state.selection;\n const range = $from.blockRange($to);\n\n if (!range) {\n return false;\n }\n\n const wrapping = range && findWrapping(range, listType);\n\n if (wrapping) {\n // Wrap the selection in a list\n if (dispatch) {\n dispatch(state.tr.wrap(range, wrapping).scrollIntoView());\n }\n\n return true;\n } else {\n // Check if we are in a list item and lift out of the list\n const liftRange = range && liftTarget(range);\n if (liftRange !== null) {\n if (dispatch) {\n dispatch(state.tr.lift(range, liftRange).scrollIntoView());\n }\n\n return true;\n }\n\n return false;\n }\n };\n};\n\nconst createListCommand = (\n schema: Schema,\n listType: string,\n): CommandWithActive => {\n const type: NodeType | undefined = schema.nodes[listType];\n if (!type) {\n throw new Error(`List type \"${listType}\" not found in schema`);\n }\n\n const command: CommandWithActive = toggleList(type);\n setActiveMethodForWrap(command, type);\n\n return command;\n};\n\nconst commandMapping: CommandMapping = {\n strong: createToggleMarkCommand,\n em: createToggleMarkCommand,\n underline: createToggleMarkCommand,\n strikethrough: createToggleMarkCommand,\n code: createToggleMarkCommand,\n link: createToggleMarkCommand,\n headerlevel1: (schema) =>\n createSetNodeTypeCommand(\n schema,\n LevelMapping.Heading,\n LevelMapping.one,\n ),\n headerlevel2: (schema) =>\n createSetNodeTypeCommand(\n schema,\n LevelMapping.Heading,\n LevelMapping.two,\n ),\n headerlevel3: (schema) =>\n createSetNodeTypeCommand(\n schema,\n LevelMapping.Heading,\n LevelMapping.three,\n ),\n blockquote: (schema) =>\n createWrapInCommand(schema, EditorMenuTypes.Blockquote),\n /* eslint-disable camelcase */\n code_block: (schema) =>\n createSetNodeTypeCommand(schema, EditorMenuTypes.CodeBlock),\n ordered_list: (schema) =>\n createListCommand(schema, EditorMenuTypes.OrderedList),\n bullet_list: (schema) =>\n createListCommand(schema, EditorMenuTypes.BulletList),\n /* eslint-enable camelcase */\n};\n\nexport class MenuCommandFactory {\n private schema: Schema;\n\n constructor(schema: Schema) {\n this.schema = schema;\n }\n\n public getCommand(mark: EditorMenuTypes, url?: string) {\n const commandFunc = commandMapping[mark];\n if (!commandFunc) {\n throw new Error(`The Mark \"${mark}\" is not supported`);\n }\n\n return commandFunc(this.schema, mark, url);\n }\n\n buildKeymap() {\n return {\n 'Mod-B': this.getCommand(EditorMenuTypes.Bold),\n 'Mod-I': this.getCommand(EditorMenuTypes.Italic),\n 'Mod-Shift-1': this.getCommand(EditorMenuTypes.HeaderLevel1),\n 'Mod-Shift-2': this.getCommand(EditorMenuTypes.HeaderLevel2),\n 'Mod-Shift-3': this.getCommand(EditorMenuTypes.HeaderLevel3),\n 'Mod-Shift-X': this.getCommand(EditorMenuTypes.Strikethrough),\n 'Mod-`': this.getCommand(EditorMenuTypes.Code),\n 'Mod-Shift-C': this.getCommand(EditorMenuTypes.CodeBlock),\n };\n }\n}\n"]}
@@ -25,6 +25,30 @@ const textEditorMenuItems = [
25
25
  iconOnly: true,
26
26
  selected: false,
27
27
  },
28
+ {
29
+ value: EditorMenuTypes.Strikethrough,
30
+ text: 'Strikethrough',
31
+ commandText: `${mod} ${shift} X`,
32
+ icon: '-lime-text-strikethrough',
33
+ iconOnly: true,
34
+ selected: false,
35
+ },
36
+ {
37
+ value: EditorMenuTypes.Code,
38
+ text: 'Code',
39
+ commandText: `${mod} \``,
40
+ icon: '-lime-text-code',
41
+ iconOnly: true,
42
+ selected: false,
43
+ },
44
+ {
45
+ value: EditorMenuTypes.CodeBlock,
46
+ text: 'Code Block',
47
+ commandText: `${mod} ${shift} C`,
48
+ icon: '-lime-text-code-block',
49
+ iconOnly: true,
50
+ selected: false,
51
+ },
28
52
  { separator: true },
29
53
  {
30
54
  value: EditorMenuTypes.HeaderLevel1,
@@ -83,8 +107,11 @@ export const menuTranslationIDs = {
83
107
  /* eslint-disable camelcase */
84
108
  bullet_list: 'editor-menu.bulleted-list',
85
109
  ordered_list: 'editor-menu.numbered-list',
110
+ code_block: 'editor-menu.code-block',
86
111
  /* eslint-enable camelcase */
87
112
  blockquote: 'editor-menu.blockquote',
88
113
  link: 'editor-menu.link',
114
+ strikethrough: 'editor-menu.strikethrough',
115
+ code: 'editor-menu.code',
89
116
  };
90
117
  //# sourceMappingURL=menu-items.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"menu-items.js","sourceRoot":"","sources":["../../../../../src/components/text-editor/prosemirror-adapter/menu/menu-items.ts"],"names":[],"mappings":"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","sourcesContent":["import { ActionBarItem } from 'src/components/action-bar/action-bar.types';\nimport { ListSeparator } from 'src/components/list/list-item.types';\nimport { EditorMenuTypes } from './types';\nimport { cloneDeep } from 'lodash-es';\n\nconst getCommandSymbols = (): {\n mod: string;\n option: string;\n shift: string;\n} => {\n const macUserAgent = /Macintosh|MacIntel|MacPPC|Mac68K/;\n if (navigator.userAgent.match(macUserAgent)) {\n return { mod: '⌘', option: '⌥', shift: '⇧' };\n }\n\n return { mod: 'Ctrl', option: 'Alt', shift: 'Shift' };\n};\n\nconst { mod, shift } = getCommandSymbols();\n\nconst textEditorMenuItems: Array<\n ActionBarItem<EditorMenuTypes> | ListSeparator\n> = [\n {\n value: EditorMenuTypes.Bold,\n text: 'Bold',\n commandText: `${mod} B`,\n icon: '-lime-text-bold',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.Italic,\n text: 'Italic',\n commandText: `${mod} I`,\n icon: '-lime-text-italic',\n iconOnly: true,\n selected: false,\n },\n { separator: true },\n {\n value: EditorMenuTypes.HeaderLevel1,\n text: 'Header 1',\n commandText: `${mod} ${shift} 1`,\n icon: '-lime-text-h-heading-1',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.HeaderLevel2,\n text: 'Header 2',\n commandText: `${mod} ${shift} 2`,\n icon: '-lime-text-h-heading-2',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.HeaderLevel3,\n text: 'Header 3',\n commandText: `${mod} ${shift} 3`,\n icon: '-lime-text-h-heading-3',\n iconOnly: true,\n selected: false,\n },\n { separator: true },\n {\n value: EditorMenuTypes.BulletList,\n text: 'Bullet list',\n icon: '-lime-text-bulleted-list',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.OrderedList,\n text: 'Numbered list',\n icon: '-lime-text-ordered-list',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.Blockquote,\n text: 'Blockquote',\n icon: '-lime-text-blockquote',\n iconOnly: true,\n selected: false,\n },\n];\n\nexport const getTextEditorMenuItems = () => cloneDeep(textEditorMenuItems);\n\nexport const menuTranslationIDs = {\n strong: 'editor-menu.bold',\n em: 'editor-menu.italic',\n headerlevel1: 'editor-menu.h1',\n headerlevel2: 'editor-menu.h2',\n headerlevel3: 'editor-menu.h3',\n /* eslint-disable camelcase */\n bullet_list: 'editor-menu.bulleted-list',\n ordered_list: 'editor-menu.numbered-list',\n /* eslint-enable camelcase */\n blockquote: 'editor-menu.blockquote',\n link: 'editor-menu.link',\n};\n\nexport type menuTranslationIDs =\n (typeof menuTranslationIDs)[keyof typeof menuTranslationIDs];\n"]}
1
+ {"version":3,"file":"menu-items.js","sourceRoot":"","sources":["../../../../../src/components/text-editor/prosemirror-adapter/menu/menu-items.ts"],"names":[],"mappings":"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","sourcesContent":["import { ActionBarItem } from 'src/components/action-bar/action-bar.types';\nimport { ListSeparator } from 'src/components/list/list-item.types';\nimport { EditorMenuTypes } from './types';\nimport { cloneDeep } from 'lodash-es';\n\nconst getCommandSymbols = (): {\n mod: string;\n option: string;\n shift: string;\n} => {\n const macUserAgent = /Macintosh|MacIntel|MacPPC|Mac68K/;\n if (navigator.userAgent.match(macUserAgent)) {\n return { mod: '⌘', option: '⌥', shift: '⇧' };\n }\n\n return { mod: 'Ctrl', option: 'Alt', shift: 'Shift' };\n};\n\nconst { mod, shift } = getCommandSymbols();\n\nconst textEditorMenuItems: Array<\n ActionBarItem<EditorMenuTypes> | ListSeparator\n> = [\n {\n value: EditorMenuTypes.Bold,\n text: 'Bold',\n commandText: `${mod} B`,\n icon: '-lime-text-bold',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.Italic,\n text: 'Italic',\n commandText: `${mod} I`,\n icon: '-lime-text-italic',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.Strikethrough,\n text: 'Strikethrough',\n commandText: `${mod} ${shift} X`,\n icon: '-lime-text-strikethrough',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.Code,\n text: 'Code',\n commandText: `${mod} \\``,\n icon: '-lime-text-code',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.CodeBlock,\n text: 'Code Block',\n commandText: `${mod} ${shift} C`,\n icon: '-lime-text-code-block',\n iconOnly: true,\n selected: false,\n },\n { separator: true },\n {\n value: EditorMenuTypes.HeaderLevel1,\n text: 'Header 1',\n commandText: `${mod} ${shift} 1`,\n icon: '-lime-text-h-heading-1',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.HeaderLevel2,\n text: 'Header 2',\n commandText: `${mod} ${shift} 2`,\n icon: '-lime-text-h-heading-2',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.HeaderLevel3,\n text: 'Header 3',\n commandText: `${mod} ${shift} 3`,\n icon: '-lime-text-h-heading-3',\n iconOnly: true,\n selected: false,\n },\n { separator: true },\n {\n value: EditorMenuTypes.BulletList,\n text: 'Bullet list',\n icon: '-lime-text-bulleted-list',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.OrderedList,\n text: 'Numbered list',\n icon: '-lime-text-ordered-list',\n iconOnly: true,\n selected: false,\n },\n {\n value: EditorMenuTypes.Blockquote,\n text: 'Blockquote',\n icon: '-lime-text-blockquote',\n iconOnly: true,\n selected: false,\n },\n];\n\nexport const getTextEditorMenuItems = () => cloneDeep(textEditorMenuItems);\n\nexport const menuTranslationIDs = {\n strong: 'editor-menu.bold',\n em: 'editor-menu.italic',\n headerlevel1: 'editor-menu.h1',\n headerlevel2: 'editor-menu.h2',\n headerlevel3: 'editor-menu.h3',\n /* eslint-disable camelcase */\n bullet_list: 'editor-menu.bulleted-list',\n ordered_list: 'editor-menu.numbered-list',\n code_block: 'editor-menu.code-block',\n /* eslint-enable camelcase */\n blockquote: 'editor-menu.blockquote',\n link: 'editor-menu.link',\n strikethrough: 'editor-menu.strikethrough',\n code: 'editor-menu.code',\n};\n\nexport type menuTranslationIDs =\n (typeof menuTranslationIDs)[keyof typeof menuTranslationIDs];\n"]}
@@ -0,0 +1,12 @@
1
+ export const strikethrough = {
2
+ parseDOM: [
3
+ { tag: 's' },
4
+ { tag: 'del' },
5
+ { tag: 'strike' },
6
+ { style: 'text-decoration=line-through' },
7
+ ],
8
+ toDOM: () => {
9
+ return ['s', 0];
10
+ },
11
+ };
12
+ //# sourceMappingURL=menu-schema-extender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menu-schema-extender.js","sourceRoot":"","sources":["../../../../../src/components/text-editor/prosemirror-adapter/menu/menu-schema-extender.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,aAAa,GAAa;EACnC,QAAQ,EAAE;IACN,EAAE,GAAG,EAAE,GAAG,EAAE;IACZ,EAAE,GAAG,EAAE,KAAK,EAAE;IACd,EAAE,GAAG,EAAE,QAAQ,EAAE;IACjB,EAAE,KAAK,EAAE,8BAA8B,EAAE;GAC5C;EACD,KAAK,EAAE,GAAG,EAAE;IACR,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;EACpB,CAAC;CACJ,CAAC","sourcesContent":["import { MarkSpec } from 'prosemirror-model';\n\nexport const strikethrough: MarkSpec = {\n parseDOM: [\n { tag: 's' },\n { tag: 'del' },\n { tag: 'strike' },\n { style: 'text-decoration=line-through' },\n ],\n toDOM: () => {\n return ['s', 0];\n },\n};\n"]}
@@ -14,6 +14,9 @@ export const EditorMenuTypes = {
14
14
  Link: 'link',
15
15
  OrderedList: 'ordered_list',
16
16
  BulletList: 'bullet_list',
17
+ Strikethrough: 'strikethrough',
18
+ Code: 'code',
19
+ CodeBlock: 'code_block',
17
20
  };
18
21
  /**
19
22
  * `LevelMapping` is used to map string identifiers to numerical header levels.
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/components/text-editor/prosemirror-adapter/menu/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG;EAC3B,IAAI,EAAE,QAAQ;EACd,MAAM,EAAE,IAAI;EACZ,UAAU,EAAE,YAAY;EACxB,YAAY,EAAE,cAAc;EAC5B,YAAY,EAAE,cAAc;EAC5B,YAAY,EAAE,cAAc;EAC5B,IAAI,EAAE,MAAM;EACZ,WAAW,EAAE,cAAc;EAC3B,UAAU,EAAE,aAAa;CAC5B,CAAC;AAKF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;EACxB,OAAO,EAAE,SAAS;EAClB,GAAG,EAAE,CAAC;EACN,GAAG,EAAE,CAAC;EACN,KAAK,EAAE,CAAC;CACX,CAAC","sourcesContent":["/**\n * The `EditorMenuType` type is used to specify the type of menu items that can be added to the editor toolbar.\n * Each one represents a different type to be used for creating the prosemirror commands relevant to the button.\n * The values correspond to the types that can be used with the `prosemirror-commands` library.\n * @beta\n */\n\nexport const EditorMenuTypes = {\n Bold: 'strong',\n Italic: 'em',\n Blockquote: 'blockquote',\n HeaderLevel1: 'headerlevel1',\n HeaderLevel2: 'headerlevel2',\n HeaderLevel3: 'headerlevel3',\n Link: 'link',\n OrderedList: 'ordered_list',\n BulletList: 'bullet_list',\n};\n\nexport type EditorMenuTypes =\n (typeof EditorMenuTypes)[keyof typeof EditorMenuTypes];\n\n/**\n * `LevelMapping` is used to map string identifiers to numerical header levels.\n * It provides a way to represent different levels of headings in ProseMirror commands.\n *\n * The `Heading` identifier is not a valid level and is used to identify the node type.\n * The numerical values are used for creating ProseMirror commands to set the level of a heading node in the editor.\n * @beta\n */\nexport const LevelMapping = {\n Heading: 'heading',\n one: 1,\n two: 2,\n three: 3,\n};\n\nexport type LevelMapping = (typeof LevelMapping)[keyof typeof LevelMapping];\n\nexport type ProseMirrorAdapterElementWithFocus =\n HTMLLimelProsemirrorAdapterElement & {\n setFocus: () => void;\n };\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/components/text-editor/prosemirror-adapter/menu/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG;EAC3B,IAAI,EAAE,QAAQ;EACd,MAAM,EAAE,IAAI;EACZ,UAAU,EAAE,YAAY;EACxB,YAAY,EAAE,cAAc;EAC5B,YAAY,EAAE,cAAc;EAC5B,YAAY,EAAE,cAAc;EAC5B,IAAI,EAAE,MAAM;EACZ,WAAW,EAAE,cAAc;EAC3B,UAAU,EAAE,aAAa;EACzB,aAAa,EAAE,eAAe;EAC9B,IAAI,EAAE,MAAM;EACZ,SAAS,EAAE,YAAY;CAC1B,CAAC;AAKF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;EACxB,OAAO,EAAE,SAAS;EAClB,GAAG,EAAE,CAAC;EACN,GAAG,EAAE,CAAC;EACN,KAAK,EAAE,CAAC;CACX,CAAC","sourcesContent":["/**\n * The `EditorMenuType` type is used to specify the type of menu items that can be added to the editor toolbar.\n * Each one represents a different type to be used for creating the prosemirror commands relevant to the button.\n * The values correspond to the types that can be used with the `prosemirror-commands` library.\n * @beta\n */\n\nexport const EditorMenuTypes = {\n Bold: 'strong',\n Italic: 'em',\n Blockquote: 'blockquote',\n HeaderLevel1: 'headerlevel1',\n HeaderLevel2: 'headerlevel2',\n HeaderLevel3: 'headerlevel3',\n Link: 'link',\n OrderedList: 'ordered_list',\n BulletList: 'bullet_list',\n Strikethrough: 'strikethrough',\n Code: 'code',\n CodeBlock: 'code_block',\n};\n\nexport type EditorMenuTypes =\n (typeof EditorMenuTypes)[keyof typeof EditorMenuTypes];\n\n/**\n * `LevelMapping` is used to map string identifiers to numerical header levels.\n * It provides a way to represent different levels of headings in ProseMirror commands.\n *\n * The `Heading` identifier is not a valid level and is used to identify the node type.\n * The numerical values are used for creating ProseMirror commands to set the level of a heading node in the editor.\n * @beta\n */\nexport const LevelMapping = {\n Heading: 'heading',\n one: 1,\n two: 2,\n three: 3,\n};\n\nexport type LevelMapping = (typeof LevelMapping)[keyof typeof LevelMapping];\n\nexport type ProseMirrorAdapterElementWithFocus =\n HTMLLimelProsemirrorAdapterElement & {\n setFocus: () => void;\n };\n"]}
@@ -13,6 +13,7 @@ import { HTMLConverter } from '../utils/html-converter';
13
13
  import translate from 'src/global/translations';
14
14
  import { isItem } from 'src/components/action-bar/isItem';
15
15
  import { cloneDeep } from 'lodash-es';
16
+ import { strikethrough } from './menu/menu-schema-extender';
16
17
  /**
17
18
  * The ProseMirror adapter offers a rich text editing experience with markdown support.
18
19
  * [Read more...](https://prosemirror.net/)
@@ -110,13 +111,19 @@ export class ProsemirrorAdapter {
110
111
  h("limel-action-bar", { accessibleLabel: "Toolbar", actions: this.actionBarItems, onItemSelected: this.handleActionBarItem }),
111
112
  ];
112
113
  }
114
+ disconnectedCallback() {
115
+ this.view.destroy();
116
+ }
113
117
  setupContentConverter() {
114
- /* eslint-disable multiline-ternary */
115
- this.contentConverter =
116
- this.contentType === 'markdown'
117
- ? new markdownConverter()
118
- : new HTMLConverter();
119
- /* eslint-enable multiline-ternary */
118
+ if (this.contentType === 'markdown') {
119
+ this.contentConverter = new markdownConverter();
120
+ }
121
+ else if (this.contentType === 'html') {
122
+ this.contentConverter = new HTMLConverter();
123
+ }
124
+ else {
125
+ throw new Error(`Unsupported content type: ${this.contentType}. Only 'markdown' and 'html' are supported.`);
126
+ }
120
127
  }
121
128
  async initializeTextEditor() {
122
129
  this.schema = this.initializeSchema();
@@ -133,7 +140,9 @@ export class ProsemirrorAdapter {
133
140
  initializeSchema() {
134
141
  return new Schema({
135
142
  nodes: addListNodes(schema.spec.nodes, 'paragraph block*', 'block'),
136
- marks: schema.spec.marks,
143
+ marks: schema.spec.marks.append({
144
+ strikethrough: strikethrough,
145
+ }),
137
146
  });
138
147
  }
139
148
  async parseInitialContent() {
@@ -1 +1 @@
1
- {"version":3,"file":"prosemirror-adapter.js","sourceRoot":"","sources":["../../../../src/components/text-editor/prosemirror-adapter/prosemirror-adapter.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Element,\n Event,\n EventEmitter,\n Prop,\n State,\n Watch,\n h,\n} from '@stencil/core';\nimport { EditorState, Plugin, PluginKey } from 'prosemirror-state';\nimport { EditorView } from 'prosemirror-view';\nimport { Schema, DOMParser } from 'prosemirror-model';\nimport { schema } from 'prosemirror-schema-basic';\nimport { addListNodes } from 'prosemirror-schema-list';\nimport { exampleSetup } from 'prosemirror-example-setup';\nimport { keymap } from 'prosemirror-keymap';\nimport { ActionBarItem } from 'src/components/action-bar/action-bar.types';\nimport { ListSeparator } from 'src/components/list/list-item.types';\nimport { CommandWithActive, MenuCommandFactory } from './menu/menu-commands';\nimport { menuTranslationIDs, getTextEditorMenuItems } from './menu/menu-items';\nimport { ContentTypeConverter } from '../utils/content-type-converter';\nimport { markdownConverter } from '../utils/markdown-converter';\nimport { HTMLConverter } from '../utils/html-converter';\nimport { EditorMenuTypes } from './menu/types';\nimport translate from 'src/global/translations';\nimport { isItem } from 'src/components/action-bar/isItem';\nimport { cloneDeep } from 'lodash-es';\nimport { Languages } from '../../date-picker/date.types';\n\n/**\n * The ProseMirror adapter offers a rich text editing experience with markdown support.\n * [Read more...](https://prosemirror.net/)\n *\n * @exampleComponent limel-example-prosemirror-adapter-basic\n * @exampleComponent limel-example-prosemirror-adapter-with-custom-menu\n * @beta\n * @private\n */\n@Component({\n tag: 'limel-prosemirror-adapter',\n shadow: true,\n styleUrl: 'prosemirror-adapter.scss',\n})\nexport class ProsemirrorAdapter {\n /**\n * The type of content that the editor should handle and emit, defaults to `markdown`\n *\n * Assumed to be set only once, so not reactive to changes\n */\n @Prop()\n public contentType: 'markdown' | 'html' = 'markdown';\n\n /**\n * The value of the editor, expected to be markdown\n */\n @Prop()\n public value: string;\n\n /**\n * Defines the language for translations.\n */\n @Prop({ reflect: true })\n public language: Languages;\n\n @Element()\n private host: HTMLLimelTextEditorElement;\n\n @State()\n private view: EditorView;\n\n @State()\n private actionBarItems: Array<\n ActionBarItem<EditorMenuTypes> | ListSeparator\n > = [];\n\n private menuCommandFactory: MenuCommandFactory;\n private schema: Schema;\n private contentConverter: ContentTypeConverter;\n\n /**\n * Dispatched when a change is made to the editor\n */\n @Event()\n private change: EventEmitter<string>;\n\n @Watch('value')\n protected watchValue(newValue: string) {\n if (\n !this.view ||\n newValue === this.contentConverter.serialize(this.view, this.schema)\n ) {\n return;\n }\n\n this.updateView(newValue);\n }\n\n public componentWillLoad() {\n this.getActionBarItems();\n this.setupContentConverter();\n }\n\n public componentDidLoad() {\n // Stencil complains loudly about triggering rerenders in\n // componentDidLoad, but we have to, so we're using setTimeout to\n // suppress the warning. /Ads\n setTimeout(() => {\n this.initializeTextEditor();\n }, 0);\n }\n\n public render() {\n return [\n <div id=\"editor\" />,\n <limel-action-bar\n accessibleLabel=\"Toolbar\"\n actions={this.actionBarItems}\n onItemSelected={this.handleActionBarItem}\n />,\n ];\n }\n\n private setupContentConverter() {\n /* eslint-disable multiline-ternary */\n this.contentConverter =\n this.contentType === 'markdown'\n ? new markdownConverter()\n : new HTMLConverter();\n /* eslint-enable multiline-ternary */\n }\n\n private getActionBarItems = () => {\n this.actionBarItems = getTextEditorMenuItems().map(\n this.getTranslatedItem,\n );\n };\n\n private getTranslatedItem = (item) => {\n const newItem = cloneDeep(item);\n\n if (isItem(item)) {\n const translationId = menuTranslationIDs[item.value];\n\n if (translationId) {\n newItem.text = translate.get(translationId, this.language);\n }\n }\n\n return newItem;\n };\n\n private async initializeTextEditor() {\n this.schema = this.initializeSchema();\n const initialDoc = await this.parseInitialContent();\n this.menuCommandFactory = new MenuCommandFactory(this.schema);\n this.view = new EditorView(\n this.host.shadowRoot.querySelector('#editor'),\n {\n state: this.createEditorState(initialDoc),\n dispatchTransaction: this.handleTransaction,\n },\n );\n if (this.value) {\n this.updateView(this.value);\n }\n }\n\n private initializeSchema() {\n return new Schema({\n nodes: addListNodes(schema.spec.nodes, 'paragraph block*', 'block'),\n marks: schema.spec.marks,\n });\n }\n\n private async parseInitialContent() {\n const initialContentElement = document.createElement('div');\n\n if (this.value) {\n initialContentElement.innerHTML =\n await this.contentConverter.parseAsHTML(\n this.value,\n this.schema,\n );\n } else {\n initialContentElement.innerHTML = '<p></p>';\n }\n\n return DOMParser.fromSchema(this.schema).parse(initialContentElement);\n }\n\n private createEditorState(initialDoc) {\n return EditorState.create({\n doc: initialDoc,\n plugins: [\n ...exampleSetup({ schema: this.schema, menuBar: false }),\n keymap(this.menuCommandFactory.buildKeymap()),\n this.createMenuStateTrackingPlugin(this.actionBarItems),\n ],\n });\n }\n\n private async updateView(content: string) {\n const html = await this.contentConverter.parseAsHTML(\n content,\n this.schema,\n );\n const prosemirrorDOMparser = DOMParser.fromSchema(\n this.view.state.schema,\n );\n const domParser = new window.DOMParser();\n const doc = domParser.parseFromString(html, 'text/html');\n const prosemirrorDoc = prosemirrorDOMparser.parse(doc.body);\n const tr = this.view.state.tr;\n tr.replaceWith(0, tr.doc.content.size, prosemirrorDoc.content);\n this.view.dispatch(tr);\n }\n\n private handleTransaction = (transaction) => {\n const newState = this.view.state.apply(transaction);\n this.view.updateState(newState);\n this.change.emit(\n this.contentConverter.serialize(this.view, this.schema),\n );\n };\n\n private handleActionBarItem = (\n event: CustomEvent<ActionBarItem<EditorMenuTypes>>,\n ) => {\n event.preventDefault();\n const { value } = event.detail;\n\n try {\n const command = this.menuCommandFactory.getCommand(value);\n this.dispatchMenuCommand(command);\n } catch (error) {\n throw new Error(`Error executing command: ${error}`);\n }\n };\n\n private dispatchMenuCommand(command) {\n const { state } = this.view;\n const selection = state.selection;\n let transaction = state.tr;\n if (!selection.empty) {\n transaction.setSelection(selection);\n }\n\n command(state, (tr) => {\n transaction = tr;\n });\n this.view.dispatch(transaction);\n this.setFocus();\n }\n\n public setFocus() {\n this.view?.focus();\n }\n\n actionBarPluginKey = new PluginKey('actionBarPlugin');\n\n private updateActionBarItems = (\n actionBarItems: Array<ActionBarItem<EditorMenuTypes> | ListSeparator>,\n view: EditorView,\n ) => {\n const updatedItems = cloneDeep(actionBarItems);\n updatedItems.forEach((item) => {\n if (isItem(item)) {\n const command: CommandWithActive =\n this.menuCommandFactory.getCommand(item.value);\n if (command && command.active) {\n item.selected = command.active(view.state);\n } else {\n item.selected = false;\n }\n }\n });\n this.actionBarItems = updatedItems;\n };\n\n private createMenuStateTrackingPlugin = (\n actionBarItems: Array<ActionBarItem<EditorMenuTypes> | ListSeparator>,\n ) => {\n return new Plugin({\n key: this.actionBarPluginKey,\n view: () => ({\n update: (view) => {\n this.updateActionBarItems(actionBarItems, view);\n },\n }),\n });\n };\n}\n"]}
1
+ {"version":3,"file":"prosemirror-adapter.js","sourceRoot":"","sources":["../../../../src/components/text-editor/prosemirror-adapter/prosemirror-adapter.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Element,\n Event,\n EventEmitter,\n Prop,\n State,\n Watch,\n h,\n} from '@stencil/core';\nimport { EditorState, Plugin, PluginKey } from 'prosemirror-state';\nimport { EditorView } from 'prosemirror-view';\nimport { Schema, DOMParser } from 'prosemirror-model';\nimport { schema } from 'prosemirror-schema-basic';\nimport { addListNodes } from 'prosemirror-schema-list';\nimport { exampleSetup } from 'prosemirror-example-setup';\nimport { keymap } from 'prosemirror-keymap';\nimport { ActionBarItem } from 'src/components/action-bar/action-bar.types';\nimport { ListSeparator } from 'src/components/list/list-item.types';\nimport { CommandWithActive, MenuCommandFactory } from './menu/menu-commands';\nimport { menuTranslationIDs, getTextEditorMenuItems } from './menu/menu-items';\nimport { ContentTypeConverter } from '../utils/content-type-converter';\nimport { markdownConverter } from '../utils/markdown-converter';\nimport { HTMLConverter } from '../utils/html-converter';\nimport { EditorMenuTypes } from './menu/types';\nimport translate from 'src/global/translations';\nimport { isItem } from 'src/components/action-bar/isItem';\nimport { cloneDeep } from 'lodash-es';\nimport { Languages } from '../../date-picker/date.types';\nimport { strikethrough } from './menu/menu-schema-extender';\n\n/**\n * The ProseMirror adapter offers a rich text editing experience with markdown support.\n * [Read more...](https://prosemirror.net/)\n *\n * @exampleComponent limel-example-prosemirror-adapter-basic\n * @exampleComponent limel-example-prosemirror-adapter-with-custom-menu\n * @beta\n * @private\n */\n@Component({\n tag: 'limel-prosemirror-adapter',\n shadow: true,\n styleUrl: 'prosemirror-adapter.scss',\n})\nexport class ProsemirrorAdapter {\n /**\n * The type of content that the editor should handle and emit, defaults to `markdown`\n *\n * Assumed to be set only once, so not reactive to changes\n */\n @Prop()\n public contentType: 'markdown' | 'html' = 'markdown';\n\n /**\n * The value of the editor, expected to be markdown\n */\n @Prop()\n public value: string;\n\n /**\n * Defines the language for translations.\n */\n @Prop({ reflect: true })\n public language: Languages;\n\n @Element()\n private host: HTMLLimelTextEditorElement;\n\n @State()\n private view: EditorView;\n\n @State()\n private actionBarItems: Array<\n ActionBarItem<EditorMenuTypes> | ListSeparator\n > = [];\n\n private menuCommandFactory: MenuCommandFactory;\n private schema: Schema;\n private contentConverter: ContentTypeConverter;\n\n /**\n * Dispatched when a change is made to the editor\n */\n @Event()\n private change: EventEmitter<string>;\n\n @Watch('value')\n protected watchValue(newValue: string) {\n if (\n !this.view ||\n newValue === this.contentConverter.serialize(this.view, this.schema)\n ) {\n return;\n }\n\n this.updateView(newValue);\n }\n\n public componentWillLoad() {\n this.getActionBarItems();\n this.setupContentConverter();\n }\n\n public componentDidLoad() {\n // Stencil complains loudly about triggering rerenders in\n // componentDidLoad, but we have to, so we're using setTimeout to\n // suppress the warning. /Ads\n setTimeout(() => {\n this.initializeTextEditor();\n }, 0);\n }\n\n public render() {\n return [\n <div id=\"editor\" />,\n <limel-action-bar\n accessibleLabel=\"Toolbar\"\n actions={this.actionBarItems}\n onItemSelected={this.handleActionBarItem}\n />,\n ];\n }\n\n public disconnectedCallback() {\n this.view.destroy();\n }\n\n private setupContentConverter() {\n if (this.contentType === 'markdown') {\n this.contentConverter = new markdownConverter();\n } else if (this.contentType === 'html') {\n this.contentConverter = new HTMLConverter();\n } else {\n throw new Error(\n `Unsupported content type: ${this.contentType}. Only 'markdown' and 'html' are supported.`,\n );\n }\n }\n\n private getActionBarItems = () => {\n this.actionBarItems = getTextEditorMenuItems().map(\n this.getTranslatedItem,\n );\n };\n\n private getTranslatedItem = (item) => {\n const newItem = cloneDeep(item);\n\n if (isItem(item)) {\n const translationId = menuTranslationIDs[item.value];\n\n if (translationId) {\n newItem.text = translate.get(translationId, this.language);\n }\n }\n\n return newItem;\n };\n\n private async initializeTextEditor() {\n this.schema = this.initializeSchema();\n const initialDoc = await this.parseInitialContent();\n this.menuCommandFactory = new MenuCommandFactory(this.schema);\n this.view = new EditorView(\n this.host.shadowRoot.querySelector('#editor'),\n {\n state: this.createEditorState(initialDoc),\n dispatchTransaction: this.handleTransaction,\n },\n );\n if (this.value) {\n this.updateView(this.value);\n }\n }\n\n private initializeSchema() {\n return new Schema({\n nodes: addListNodes(schema.spec.nodes, 'paragraph block*', 'block'),\n marks: schema.spec.marks.append({\n strikethrough: strikethrough,\n }),\n });\n }\n\n private async parseInitialContent() {\n const initialContentElement = document.createElement('div');\n\n if (this.value) {\n initialContentElement.innerHTML =\n await this.contentConverter.parseAsHTML(\n this.value,\n this.schema,\n );\n } else {\n initialContentElement.innerHTML = '<p></p>';\n }\n\n return DOMParser.fromSchema(this.schema).parse(initialContentElement);\n }\n\n private createEditorState(initialDoc) {\n return EditorState.create({\n doc: initialDoc,\n plugins: [\n ...exampleSetup({ schema: this.schema, menuBar: false }),\n keymap(this.menuCommandFactory.buildKeymap()),\n this.createMenuStateTrackingPlugin(this.actionBarItems),\n ],\n });\n }\n\n private async updateView(content: string) {\n const html = await this.contentConverter.parseAsHTML(\n content,\n this.schema,\n );\n const prosemirrorDOMparser = DOMParser.fromSchema(\n this.view.state.schema,\n );\n const domParser = new window.DOMParser();\n const doc = domParser.parseFromString(html, 'text/html');\n const prosemirrorDoc = prosemirrorDOMparser.parse(doc.body);\n const tr = this.view.state.tr;\n tr.replaceWith(0, tr.doc.content.size, prosemirrorDoc.content);\n this.view.dispatch(tr);\n }\n\n private handleTransaction = (transaction) => {\n const newState = this.view.state.apply(transaction);\n this.view.updateState(newState);\n this.change.emit(\n this.contentConverter.serialize(this.view, this.schema),\n );\n };\n\n private handleActionBarItem = (\n event: CustomEvent<ActionBarItem<EditorMenuTypes>>,\n ) => {\n event.preventDefault();\n const { value } = event.detail;\n\n try {\n const command = this.menuCommandFactory.getCommand(value);\n this.dispatchMenuCommand(command);\n } catch (error) {\n throw new Error(`Error executing command: ${error}`);\n }\n };\n\n private dispatchMenuCommand(command) {\n const { state } = this.view;\n const selection = state.selection;\n let transaction = state.tr;\n if (!selection.empty) {\n transaction.setSelection(selection);\n }\n\n command(state, (tr) => {\n transaction = tr;\n });\n this.view.dispatch(transaction);\n this.setFocus();\n }\n\n public setFocus() {\n this.view?.focus();\n }\n\n actionBarPluginKey = new PluginKey('actionBarPlugin');\n\n private updateActionBarItems = (\n actionBarItems: Array<ActionBarItem<EditorMenuTypes> | ListSeparator>,\n view: EditorView,\n ) => {\n const updatedItems = cloneDeep(actionBarItems);\n updatedItems.forEach((item) => {\n if (isItem(item)) {\n const command: CommandWithActive =\n this.menuCommandFactory.getCommand(item.value);\n if (command && command.active) {\n item.selected = command.active(view.state);\n } else {\n item.selected = false;\n }\n }\n });\n this.actionBarItems = updatedItems;\n };\n\n private createMenuStateTrackingPlugin = (\n actionBarItems: Array<ActionBarItem<EditorMenuTypes> | ListSeparator>,\n ) => {\n return new Plugin({\n key: this.actionBarPluginKey,\n view: () => ({\n update: (view) => {\n this.updateActionBarItems(actionBarItems, view);\n },\n }),\n });\n };\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { Host, h } from '@stencil/core';
2
- import { createRandomString } from 'src/util/random-string';
2
+ import { createRandomString } from '../../util/random-string';
3
3
  /**
4
4
  * A rich text editor that offers a rich text editing experience with markdown support,
5
5
  * in the sense that you can easily type markdown syntax and see the rendered
@@ -1 +1 @@
1
- {"version":3,"file":"text-editor.js","sourceRoot":"","sources":["../../../src/components/text-editor/text-editor.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Event, EventEmitter, Host, Prop, h } from '@stencil/core';\nimport { FormComponent } from '../form/form.types';\nimport { createRandomString } from 'src/util/random-string';\nimport { Languages } from '../date-picker/date.types';\n/**\n * A rich text editor that offers a rich text editing experience with markdown support,\n * in the sense that you can easily type markdown syntax and see the rendered\n * result as rich text in real-time. For instance, you can type `# Hello, world!`\n * and see it directly turning to a heading 1 (an `<h1>` HTML element).\n *\n * Naturally, you can use standard keyboard hotkeys such as <kbd>Ctrl</kbd> + <kbd>B</kbd>\n * to toggle bold text, <kbd>Ctrl</kbd> + <kbd>I</kbd> to toggle italic text, and so on.\n *\n * @exampleComponent limel-example-text-editor-basic\n * @exampleComponent limel-example-text-editor-as-form-component\n * @exampleComponent limel-example-text-editor-with-markdown\n * @exampleComponent limel-example-text-editor-with-html\n * @exampleComponent limel-example-text-editor-allow-resize\n * @exampleComponent limel-example-text-editor-size\n * @exampleComponent limel-example-text-editor-composite\n * @beta\n * @private\n */\n@Component({\n tag: 'limel-text-editor',\n shadow: true,\n styleUrl: 'text-editor.scss',\n})\nexport class TextEditor implements FormComponent<string> {\n /** The type of content that the editor should handle and emit, defaults to `markdown`\n *\n * Assumed to be set only once, so not reactive to changes\n */\n @Prop()\n public contentType: 'markdown' | 'html' = 'markdown';\n\n /**\n * Defines the language for translations.\n */\n @Prop({ reflect: true })\n public language: Languages = 'en';\n\n /**\n * Set to `true` to disable the field.\n * Use `disabled` to indicate that the field can normally be interacted\n * with, but is currently disabled. This tells the user that if certain\n * requirements are met, the field may become enabled again.\n */\n @Prop({ reflect: true })\n public disabled?: boolean = false;\n\n /**\n * Set to `true` to make the component read-only.\n * Use `readonly` when the field is only there to present the data it holds,\n * and will not become possible for the current user to edit.\n * :::note\n * Consider that it might be better to use `limel-markdown`\n * instead of `limel-text-editor` when the goal is visualizing data.\n * :::\n */\n @Prop({ reflect: true })\n public readonly?: boolean = false;\n\n /**\n * Optional helper text to display below the input field when it has focus\n */\n @Prop({ reflect: true })\n public helperText?: string;\n\n /**\n * The placeholder text shown inside the input field,\n * when the field is empty.\n */\n @Prop({ reflect: true })\n public placeholder?: string;\n\n /**\n * The label of the editor\n */\n @Prop({ reflect: true })\n public label?: string;\n\n /**\n * Set to `true` to indicate that the current value of the editor is\n * invalid.\n */\n @Prop({ reflect: true })\n public invalid?: boolean = false;\n\n /**\n * Description of the text inside the editor as markdown\n */\n @Prop({ reflect: true })\n public value: string;\n\n /**\n * Set to `true` to indicate that the field is required.\n *\n * :::important\n * An empty but required field is not automatically considered invalid.\n * You must make sure to check the validity of the field on your own,\n * and properly handle the `invalid` state.\n * :::\n */\n @Prop({ reflect: true })\n public required?: boolean = false;\n\n /**\n * Set to `true` to allow the user to vertically resize the editor.\n * Set to `false` to disable the resize functionality.\n */\n @Prop({ reflect: true })\n public allowResize: boolean = true;\n\n /**\n * Dispatched when a change is made to the editor\n */\n @Event()\n public change: EventEmitter<string>;\n\n private helperTextId: string;\n private editorId: string;\n\n public constructor() {\n this.helperTextId = createRandomString();\n this.editorId = createRandomString();\n }\n\n public render() {\n return (\n <Host\n class={{\n 'has-helper-text': !!this.helperText,\n }}\n >\n <span class=\"notched-outline\">\n <span class=\"leading-outline\" />\n {this.renderLabel()}\n <span class=\"trailing-outline\" />\n </span>\n {this.renderEditor()}\n </Host>\n );\n }\n\n private renderEditor() {\n if (this.readonly && !this.value) {\n return [\n <span class=\"lime-looks-like-input-value\">–</span>,\n this.renderHelperLine(),\n ];\n }\n\n if (this.readonly) {\n return [\n <limel-markdown\n value={this.value}\n aria-controls={this.helperTextId}\n id={this.editorId}\n />,\n this.renderPlaceholder(),\n this.renderHelperLine(),\n ];\n }\n\n return [\n <limel-prosemirror-adapter\n aria-placeholder={this.placeholder}\n contentType={this.contentType}\n onChange={this.handleChange}\n value={this.value}\n aria-controls={this.helperTextId}\n id={this.editorId}\n tabindex={this.disabled ? -1 : 0}\n aria-disabled={this.disabled}\n language={this.language}\n />,\n this.renderPlaceholder(),\n this.renderHelperLine(),\n ];\n }\n\n private renderLabel() {\n if (!this.label) {\n return;\n }\n\n return (\n <span class=\"notch\">\n <label htmlFor={this.editorId}>{this.label}</label>\n </span>\n );\n }\n\n private renderPlaceholder() {\n if (!this.placeholder || this.value) {\n return;\n }\n\n return (\n <span class=\"placeholder\" aria-hidden=\"true\">\n {this.placeholder}\n </span>\n );\n }\n\n private renderHelperLine = () => {\n if (!this.helperText) {\n return;\n }\n\n return (\n <limel-helper-line\n helperText={this.helperText}\n helperTextId={this.helperTextId}\n invalid={this.isInvalid()}\n />\n );\n };\n\n private isInvalid = () => {\n if (this.readonly) {\n // A readonly field can never be invalid.\n return false;\n }\n\n if (this.invalid) {\n return true;\n }\n };\n\n private handleChange = () => (event: CustomEvent<string>) => {\n event.stopPropagation();\n this.change.emit(event.detail);\n };\n}\n"]}
1
+ {"version":3,"file":"text-editor.js","sourceRoot":"","sources":["../../../src/components/text-editor/text-editor.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Component, Event, EventEmitter, Host, Prop, h } from '@stencil/core';\nimport { FormComponent } from '../form/form.types';\nimport { Languages } from '../date-picker/date.types';\nimport { createRandomString } from '../../util/random-string';\n/**\n * A rich text editor that offers a rich text editing experience with markdown support,\n * in the sense that you can easily type markdown syntax and see the rendered\n * result as rich text in real-time. For instance, you can type `# Hello, world!`\n * and see it directly turning to a heading 1 (an `<h1>` HTML element).\n *\n * Naturally, you can use standard keyboard hotkeys such as <kbd>Ctrl</kbd> + <kbd>B</kbd>\n * to toggle bold text, <kbd>Ctrl</kbd> + <kbd>I</kbd> to toggle italic text, and so on.\n *\n * @exampleComponent limel-example-text-editor-basic\n * @exampleComponent limel-example-text-editor-as-form-component\n * @exampleComponent limel-example-text-editor-with-markdown\n * @exampleComponent limel-example-text-editor-with-html\n * @exampleComponent limel-example-text-editor-allow-resize\n * @exampleComponent limel-example-text-editor-size\n * @exampleComponent limel-example-text-editor-composite\n * @beta\n * @private\n */\n@Component({\n tag: 'limel-text-editor',\n shadow: true,\n styleUrl: 'text-editor.scss',\n})\nexport class TextEditor implements FormComponent<string> {\n /** The type of content that the editor should handle and emit, defaults to `markdown`\n *\n * Assumed to be set only once, so not reactive to changes\n */\n @Prop()\n public contentType: 'markdown' | 'html' = 'markdown';\n\n /**\n * Defines the language for translations.\n */\n @Prop({ reflect: true })\n public language: Languages = 'en';\n\n /**\n * Set to `true` to disable the field.\n * Use `disabled` to indicate that the field can normally be interacted\n * with, but is currently disabled. This tells the user that if certain\n * requirements are met, the field may become enabled again.\n */\n @Prop({ reflect: true })\n public disabled?: boolean = false;\n\n /**\n * Set to `true` to make the component read-only.\n * Use `readonly` when the field is only there to present the data it holds,\n * and will not become possible for the current user to edit.\n * :::note\n * Consider that it might be better to use `limel-markdown`\n * instead of `limel-text-editor` when the goal is visualizing data.\n * :::\n */\n @Prop({ reflect: true })\n public readonly?: boolean = false;\n\n /**\n * Optional helper text to display below the input field when it has focus\n */\n @Prop({ reflect: true })\n public helperText?: string;\n\n /**\n * The placeholder text shown inside the input field,\n * when the field is empty.\n */\n @Prop({ reflect: true })\n public placeholder?: string;\n\n /**\n * The label of the editor\n */\n @Prop({ reflect: true })\n public label?: string;\n\n /**\n * Set to `true` to indicate that the current value of the editor is\n * invalid.\n */\n @Prop({ reflect: true })\n public invalid?: boolean = false;\n\n /**\n * Description of the text inside the editor as markdown\n */\n @Prop({ reflect: true })\n public value: string;\n\n /**\n * Set to `true` to indicate that the field is required.\n *\n * :::important\n * An empty but required field is not automatically considered invalid.\n * You must make sure to check the validity of the field on your own,\n * and properly handle the `invalid` state.\n * :::\n */\n @Prop({ reflect: true })\n public required?: boolean = false;\n\n /**\n * Set to `true` to allow the user to vertically resize the editor.\n * Set to `false` to disable the resize functionality.\n */\n @Prop({ reflect: true })\n public allowResize: boolean = true;\n\n /**\n * Dispatched when a change is made to the editor\n */\n @Event()\n public change: EventEmitter<string>;\n\n private helperTextId: string;\n private editorId: string;\n\n public constructor() {\n this.helperTextId = createRandomString();\n this.editorId = createRandomString();\n }\n\n public render() {\n return (\n <Host\n class={{\n 'has-helper-text': !!this.helperText,\n }}\n >\n <span class=\"notched-outline\">\n <span class=\"leading-outline\" />\n {this.renderLabel()}\n <span class=\"trailing-outline\" />\n </span>\n {this.renderEditor()}\n </Host>\n );\n }\n\n private renderEditor() {\n if (this.readonly && !this.value) {\n return [\n <span class=\"lime-looks-like-input-value\">–</span>,\n this.renderHelperLine(),\n ];\n }\n\n if (this.readonly) {\n return [\n <limel-markdown\n value={this.value}\n aria-controls={this.helperTextId}\n id={this.editorId}\n />,\n this.renderPlaceholder(),\n this.renderHelperLine(),\n ];\n }\n\n return [\n <limel-prosemirror-adapter\n aria-placeholder={this.placeholder}\n contentType={this.contentType}\n onChange={this.handleChange}\n value={this.value}\n aria-controls={this.helperTextId}\n id={this.editorId}\n tabindex={this.disabled ? -1 : 0}\n aria-disabled={this.disabled}\n language={this.language}\n />,\n this.renderPlaceholder(),\n this.renderHelperLine(),\n ];\n }\n\n private renderLabel() {\n if (!this.label) {\n return;\n }\n\n return (\n <span class=\"notch\">\n <label htmlFor={this.editorId}>{this.label}</label>\n </span>\n );\n }\n\n private renderPlaceholder() {\n if (!this.placeholder || this.value) {\n return;\n }\n\n return (\n <span class=\"placeholder\" aria-hidden=\"true\">\n {this.placeholder}\n </span>\n );\n }\n\n private renderHelperLine = () => {\n if (!this.helperText) {\n return;\n }\n\n return (\n <limel-helper-line\n helperText={this.helperText}\n helperTextId={this.helperTextId}\n invalid={this.isInvalid()}\n />\n );\n };\n\n private isInvalid = () => {\n if (this.readonly) {\n // A readonly field can never be invalid.\n return false;\n }\n\n if (this.invalid) {\n return true;\n }\n };\n\n private handleChange = () => (event: CustomEvent<string>) => {\n event.stopPropagation();\n this.change.emit(event.detail);\n };\n}\n"]}
@@ -1,5 +1,11 @@
1
- import { defaultMarkdownSerializer } from 'prosemirror-markdown';
1
+ import { MarkdownSerializer, defaultMarkdownSerializer, } from 'prosemirror-markdown';
2
2
  import { markdownToHTML } from '../../markdown/markdown-parser';
3
+ const customMarkdownSerializer = new MarkdownSerializer(Object.assign({}, defaultMarkdownSerializer.nodes), Object.assign(Object.assign({}, defaultMarkdownSerializer.marks), { strikethrough: {
4
+ open: '~~',
5
+ close: '~~',
6
+ mixable: true,
7
+ expelEnclosingWhitespace: true,
8
+ } }));
3
9
  /**
4
10
  * @private
5
11
  */
@@ -13,7 +19,7 @@ export class markdownConverter {
13
19
  return '';
14
20
  }
15
21
  else {
16
- return defaultMarkdownSerializer.serialize(view.state.doc);
22
+ return customMarkdownSerializer.serialize(view.state.doc);
17
23
  }
18
24
  };
19
25
  }