diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-12-16 21:09:43 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-12-16 21:09:43 +0300 |
commit | 0122d00cac3c058508a2fcb258f12ecfb7bc9055 (patch) | |
tree | b2a0e138ed4113e80588df57b542dc76d5360e2b /app/assets/javascripts/editor | |
parent | f1357e5566b2c1f4f5e7b933b72a2d24431905e9 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/editor')
4 files changed, 158 insertions, 8 deletions
diff --git a/app/assets/javascripts/editor/components/source_editor_toolbar.vue b/app/assets/javascripts/editor/components/source_editor_toolbar.vue index 2c177634bbe..c72145f9d2f 100644 --- a/app/assets/javascripts/editor/components/source_editor_toolbar.vue +++ b/app/assets/javascripts/editor/components/source_editor_toolbar.vue @@ -57,13 +57,12 @@ export default { > <div v-for="group in $options.groups" :key="group"> <gl-button-group v-if="hasGroupItems(group)"> - <template v-for="item in getGroupItems(group)"> - <source-editor-toolbar-button - :key="item.id" - :button="item" - @click="$emit('click', item)" - /> - </template> + <source-editor-toolbar-button + v-for="item in getGroupItems(group)" + :key="item.id" + :button="item" + @click="$emit('click', item)" + /> </gl-button-group> </div> </section> diff --git a/app/assets/javascripts/editor/components/source_editor_toolbar_button.vue b/app/assets/javascripts/editor/components/source_editor_toolbar_button.vue index e440feb5a22..38f586f0773 100644 --- a/app/assets/javascripts/editor/components/source_editor_toolbar_button.vue +++ b/app/assets/javascripts/editor/components/source_editor_toolbar_button.vue @@ -59,6 +59,7 @@ export default { :icon="icon" :title="label" :aria-label="label" + :class="button.class" @click="clickHandler($event)" /> </template> diff --git a/app/assets/javascripts/editor/constants.js b/app/assets/javascripts/editor/constants.js index 83cfdd25757..d0649ecccba 100644 --- a/app/assets/javascripts/editor/constants.js +++ b/app/assets/javascripts/editor/constants.js @@ -1,5 +1,6 @@ +import { MODIFIER_KEY } from '~/constants'; import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants'; -import { s__, __ } from '~/locale'; +import { s__, __, sprintf } from '~/locale'; export const URI_PREFIX = 'gitlab'; export const CONTENT_UPDATE_DEBOUNCE = DEFAULT_DEBOUNCE_AND_THROTTLE_MS; @@ -62,3 +63,104 @@ export const EXTENSION_MARKDOWN_PREVIEW_PANEL_WIDTH = 0.5; // 50% of the width export const EXTENSION_MARKDOWN_PREVIEW_UPDATE_DELAY = 250; // ms export const EXTENSION_MARKDOWN_PREVIEW_LABEL = __('Preview Markdown'); export const EXTENSION_MARKDOWN_HIDE_PREVIEW_LABEL = __('Hide Live Preview'); +export const EXTENSION_MARKDOWN_BUTTONS = [ + { + id: 'bold', + label: sprintf(s__('MarkdownEditor|Add bold text (%{modifierKey}B)'), { + modifierKey: MODIFIER_KEY, + }), + data: { + mdTag: '**', + mdShortcuts: '["mod+b"]', + }, + }, + { + id: 'italic', + label: sprintf(s__('MarkdownEditor|Add italic text (%{modifierKey}I)'), { + modifierKey: MODIFIER_KEY, + }), + data: { + mdTag: '_', + mdShortcuts: '["mod+i"]', + }, + }, + { + id: 'strikethrough', + label: sprintf(s__('MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)'), { + modifierKey: MODIFIER_KEY, + }), + data: { + mdTag: '~~', + mdShortcuts: '["mod+shift+x]', + }, + }, + { + id: 'quote', + label: __('Insert a quote'), + data: { + mdTag: '> ', + mdPrepend: true, + }, + }, + { + id: 'code', + label: __('Insert code'), + data: { + mdTag: '`', + mdBlock: '```', + }, + }, + { + id: 'link', + label: sprintf(s__('MarkdownEditor|Add a link (%{modifier_key}K)'), { + modifierKey: MODIFIER_KEY, + }), + data: { + mdTag: '[{text}](url)', + mdSelect: 'url', + mdShortcuts: '["mod+k"]', + }, + }, + { + id: 'list-bulleted', + label: __('Add a bullet list'), + data: { + mdTag: '- ', + mdPrepend: true, + }, + }, + { + id: 'list-numbered', + label: __('Add a numbered list'), + data: { + mdTag: '1. ', + mdPrepend: true, + }, + }, + { + id: 'list-task', + label: __('Add a checklist'), + data: { + mdTag: '- [ ] ', + mdPrepend: true, + }, + }, + { + id: 'details-block', + label: __('Add a collapsible section'), + data: { + mdTag: '<details><summary>Click to expand</summary>\n{text}\n</details>', + mdPrepend: true, + mdSelect: __('Click to expand'), + }, + }, + { + id: 'table', + label: __('Add a table'), + data: { + /* eslint-disable-next-line @gitlab/require-i18n-strings */ + mdTag: '| header | header |\n| ------ | ------ |\n| | |\n| | |', + mdPrepend: true, + }, + }, +]; diff --git a/app/assets/javascripts/editor/extensions/source_editor_markdown_ext.js b/app/assets/javascripts/editor/extensions/source_editor_markdown_ext.js index a16fe93026e..6105a577996 100644 --- a/app/assets/javascripts/editor/extensions/source_editor_markdown_ext.js +++ b/app/assets/javascripts/editor/extensions/source_editor_markdown_ext.js @@ -1,8 +1,37 @@ +import { insertMarkdownText } from '~/lib/utils/text_markdown'; +import { EDITOR_TOOLBAR_RIGHT_GROUP, EXTENSION_MARKDOWN_BUTTONS } from '../constants'; + export class EditorMarkdownExtension { static get extensionName() { return 'EditorMarkdown'; } + onSetup(instance) { + this.toolbarButtons = []; + if (instance.toolbar) { + this.setupToolbar(instance); + } + } + onBeforeUnuse(instance) { + const ids = this.toolbarButtons.map((item) => item.id); + if (instance.toolbar) { + instance.toolbar.removeItems(ids); + } + } + + setupToolbar(instance) { + this.toolbarButtons = EXTENSION_MARKDOWN_BUTTONS.map((btn) => { + return { + ...btn, + icon: btn.id, + group: EDITOR_TOOLBAR_RIGHT_GROUP, + category: 'tertiary', + onClick: (e) => instance.insertMarkdown(e), + }; + }); + instance.toolbar.addItems(this.toolbarButtons); + } + // eslint-disable-next-line class-methods-use-this provides() { return { @@ -36,6 +65,25 @@ export class EditorMarkdownExtension { pos.lineNumber += dy; instance.setPosition(pos); }, + insertMarkdown: (instance, e) => { + const { + mdTag: tag, + mdBlock: blockTag, + mdPrepend, + mdSelect: select, + } = e.currentTarget.dataset; + + insertMarkdownText({ + tag, + blockTag, + wrap: !mdPrepend, + select, + selected: instance.getSelectedText(), + text: instance.getValue(), + editor: instance, + }); + instance.focus(); + }, /** * Adjust existing selection to select text within the original selection. * - If `selectedText` is not supplied, we fetch selected text with |