mirror of
				https://github.com/go-gitea/gitea
				synced 2025-10-31 03:18:24 +00:00 
			
		
		
		
	Fix EasyMDE toolbar (#24489)
Fixes https://github.com/go-gitea/gitea/issues/24486 The "clean block" button is gone because I could not find a matching octicon. Order of buttons is roughly equal to textarea. <img width="824" alt="Screenshot 2023-05-02 at 21 10 00" src="https://user-images.githubusercontent.com/115237/235762593-ceccb260-e665-4932-ac8a-ef6fe8406a3c.png"> --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
		| @@ -8,7 +8,7 @@ import {handleGlobalEnterQuickSubmit} from './QuickSubmit.js'; | ||||
| import {emojiString} from '../emoji.js'; | ||||
| import {renderPreviewPanelContent} from '../repo-editor.js'; | ||||
| import {matchEmoji, matchMention} from '../../utils/match.js'; | ||||
| import {svg} from '../../svg.js'; | ||||
| import {easyMDEToolbarActions} from './EasyMDEToolbarActions.js'; | ||||
|  | ||||
| let elementIdCounter = 0; | ||||
|  | ||||
| @@ -206,66 +206,20 @@ class ComboMarkdownEditor { | ||||
|  | ||||
|   prepareEasyMDEToolbarActions() { | ||||
|     this.easyMDEToolbarDefault = [ | ||||
|       'bold', 'italic', 'strikethrough', '|', 'heading-1', 'heading-2', 'heading-3', 'heading-bigger', 'heading-smaller', '|', | ||||
|       'code', 'quote', '|', 'gitea-checkbox-empty', 'gitea-checkbox-checked', '|', | ||||
|       'unordered-list', 'ordered-list', '|', 'link', 'image', 'table', 'horizontal-rule', '|', 'clean-block', '|', | ||||
|       'gitea-switch-to-textarea', | ||||
|       'bold', 'italic', 'strikethrough', '|', 'heading-1', 'heading-2', 'heading-3', | ||||
|       'heading-bigger', 'heading-smaller', '|', 'code', 'quote', '|', 'gitea-checkbox-empty', | ||||
|       'gitea-checkbox-checked', '|', 'unordered-list', 'ordered-list', '|', 'link', 'image', | ||||
|       'table', 'horizontal-rule', '|', 'gitea-switch-to-textarea', | ||||
|     ]; | ||||
|  | ||||
|     this.easyMDEToolbarActions = { | ||||
|       'gitea-checkbox-empty': { | ||||
|         action(e) { | ||||
|           const cm = e.codemirror; | ||||
|           cm.replaceSelection(`\n- [ ] ${cm.getSelection()}`); | ||||
|           cm.focus(); | ||||
|         }, | ||||
|         icon: svg('gitea-empty-checkbox'), | ||||
|         title: 'Add Checkbox (empty)', | ||||
|       }, | ||||
|       'gitea-checkbox-checked': { | ||||
|         action(e) { | ||||
|           const cm = e.codemirror; | ||||
|           cm.replaceSelection(`\n- [x] ${cm.getSelection()}`); | ||||
|           cm.focus(); | ||||
|         }, | ||||
|         icon: svg('octicon-checkbox'), | ||||
|         title: 'Add Checkbox (checked)', | ||||
|       }, | ||||
|       'gitea-switch-to-textarea': { | ||||
|         action: () => { | ||||
|           this.userPreferredEditor = 'textarea'; | ||||
|           this.switchToTextarea(); | ||||
|         }, | ||||
|         icon: svg('octicon-file'), | ||||
|         title: 'Revert to simple textarea', | ||||
|       }, | ||||
|       'gitea-code-inline': { | ||||
|         action(e) { | ||||
|           const cm = e.codemirror; | ||||
|           const selection = cm.getSelection(); | ||||
|           cm.replaceSelection(`\`${selection}\``); | ||||
|           if (!selection) { | ||||
|             const cursorPos = cm.getCursor(); | ||||
|             cm.setCursor(cursorPos.line, cursorPos.ch - 1); | ||||
|           } | ||||
|           cm.focus(); | ||||
|         }, | ||||
|         icon: svg('octicon-chevron-right'), | ||||
|         title: 'Add Inline Code', | ||||
|       } | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   parseEasyMDEToolbar(actions) { | ||||
|   parseEasyMDEToolbar(EasyMDE, actions) { | ||||
|     this.easyMDEToolbarActions = this.easyMDEToolbarActions || easyMDEToolbarActions(EasyMDE, this); | ||||
|     const processed = []; | ||||
|     for (const action of actions) { | ||||
|       if (action.startsWith('gitea-')) { | ||||
|         const giteaAction = this.easyMDEToolbarActions[action]; | ||||
|         if (!giteaAction) throw new Error(`Unknown EasyMDE toolbar action ${action}`); | ||||
|         processed.push(giteaAction); | ||||
|       } else { | ||||
|         processed.push(action); | ||||
|       } | ||||
|       const actionButton = this.easyMDEToolbarActions[action]; | ||||
|       if (!actionButton) throw new Error(`Unknown EasyMDE toolbar action ${action}`); | ||||
|       processed.push(actionButton); | ||||
|     } | ||||
|     return processed; | ||||
|   } | ||||
| @@ -293,7 +247,7 @@ class ComboMarkdownEditor { | ||||
|       nativeSpellcheck: true, | ||||
|       ...this.options.easyMDEOptions, | ||||
|     }; | ||||
|     easyMDEOpt.toolbar = this.parseEasyMDEToolbar(easyMDEOpt.toolbar ?? this.easyMDEToolbarDefault); | ||||
|     easyMDEOpt.toolbar = this.parseEasyMDEToolbar(EasyMDE, easyMDEOpt.toolbar ?? this.easyMDEToolbarDefault); | ||||
|  | ||||
|     this.easyMDE = new EasyMDE(easyMDEOpt); | ||||
|     this.easyMDE.codemirror.on('change', (...args) => {this.options?.onContentChanged?.(this, ...args)}); | ||||
|   | ||||
							
								
								
									
										152
									
								
								web_src/js/features/comp/EasyMDEToolbarActions.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								web_src/js/features/comp/EasyMDEToolbarActions.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,152 @@ | ||||
| import {svg} from '../../svg.js'; | ||||
|  | ||||
| export function easyMDEToolbarActions(EasyMDE, editor) { | ||||
|   const actions = { | ||||
|     '|': '|', | ||||
|     'heading-1': { | ||||
|       action: EasyMDE.toggleHeading1, | ||||
|       icon: svg('octicon-heading'), | ||||
|       title: 'Heading 1', | ||||
|     }, | ||||
|     'heading-2': { | ||||
|       action: EasyMDE.toggleHeading2, | ||||
|       icon: svg('octicon-heading'), | ||||
|       title: 'Heading 2', | ||||
|     }, | ||||
|     'heading-3': { | ||||
|       action: EasyMDE.toggleHeading3, | ||||
|       icon: svg('octicon-heading'), | ||||
|       title: 'Heading 3', | ||||
|     }, | ||||
|     'heading-smaller': { | ||||
|       action: EasyMDE.toggleHeadingSmaller, | ||||
|       icon: svg('octicon-heading'), | ||||
|       title: 'Decrease Heading', | ||||
|     }, | ||||
|     'heading-bigger': { | ||||
|       action: EasyMDE.toggleHeadingBigger, | ||||
|       icon: svg('octicon-heading'), | ||||
|       title: 'Increase Heading', | ||||
|     }, | ||||
|     'bold': { | ||||
|       action: EasyMDE.toggleBold, | ||||
|       icon: svg('octicon-bold'), | ||||
|       title: 'Bold', | ||||
|     }, | ||||
|     'italic': { | ||||
|       action: EasyMDE.toggleItalic, | ||||
|       icon: svg('octicon-italic'), | ||||
|       title: 'Italic', | ||||
|     }, | ||||
|     'strikethrough': { | ||||
|       action: EasyMDE.toggleStrikethrough, | ||||
|       icon: svg('octicon-strikethrough'), | ||||
|       title: 'Strikethrough', | ||||
|     }, | ||||
|     'quote': { | ||||
|       action: EasyMDE.toggleBlockquote, | ||||
|       icon: svg('octicon-quote'), | ||||
|       title: 'Quote', | ||||
|     }, | ||||
|     'code': { | ||||
|       action: EasyMDE.toggleCodeBlock, | ||||
|       icon: svg('octicon-code'), | ||||
|       title: 'Code', | ||||
|     }, | ||||
|     'link': { | ||||
|       action: EasyMDE.drawLink, | ||||
|       icon: svg('octicon-link'), | ||||
|       title: 'Link', | ||||
|     }, | ||||
|     'unordered-list': { | ||||
|       action: EasyMDE.toggleUnorderedList, | ||||
|       icon: svg('octicon-list-unordered'), | ||||
|       title: 'Unordered List', | ||||
|     }, | ||||
|     'ordered-list': { | ||||
|       action: EasyMDE.toggleOrderedList, | ||||
|       icon: svg('octicon-list-ordered'), | ||||
|       title: 'Ordered List', | ||||
|     }, | ||||
|     'image': { | ||||
|       action: EasyMDE.drawImage, | ||||
|       icon: svg('octicon-image'), | ||||
|       title: 'Image', | ||||
|     }, | ||||
|     'table': { | ||||
|       action: EasyMDE.drawTable, | ||||
|       icon: svg('octicon-table'), | ||||
|       title: 'Table', | ||||
|     }, | ||||
|     'horizontal-rule': { | ||||
|       action: EasyMDE.drawHorizontalRule, | ||||
|       icon: svg('octicon-horizontal-rule'), | ||||
|       title: 'Horizontal Rule', | ||||
|     }, | ||||
|     'preview': { | ||||
|       action: EasyMDE.togglePreview, | ||||
|       icon: svg('octicon-eye'), | ||||
|       title: 'Preview', | ||||
|     }, | ||||
|     'fullscreen': { | ||||
|       action: EasyMDE.toggleFullScreen, | ||||
|       icon: svg('octicon-screen-full'), | ||||
|       title: 'Fullscreen', | ||||
|     }, | ||||
|     'side-by-side': { | ||||
|       action: EasyMDE.toggleSideBySide, | ||||
|       icon: svg('octicon-columns'), | ||||
|       title: 'Side by Side', | ||||
|     }, | ||||
|  | ||||
|     // gitea's custom actions | ||||
|     'gitea-checkbox-empty': { | ||||
|       action(e) { | ||||
|         const cm = e.codemirror; | ||||
|         cm.replaceSelection(`\n- [ ] ${cm.getSelection()}`); | ||||
|         cm.focus(); | ||||
|       }, | ||||
|       icon: svg('gitea-empty-checkbox'), | ||||
|       title: 'Add Checkbox (empty)', | ||||
|     }, | ||||
|     'gitea-checkbox-checked': { | ||||
|       action(e) { | ||||
|         const cm = e.codemirror; | ||||
|         cm.replaceSelection(`\n- [x] ${cm.getSelection()}`); | ||||
|         cm.focus(); | ||||
|       }, | ||||
|       icon: svg('octicon-checkbox'), | ||||
|       title: 'Add Checkbox (checked)', | ||||
|     }, | ||||
|     'gitea-switch-to-textarea': { | ||||
|       action: () => { | ||||
|         editor.userPreferredEditor = 'textarea'; | ||||
|         editor.switchToTextarea(); | ||||
|       }, | ||||
|       icon: svg('octicon-arrow-switch'), | ||||
|       title: 'Revert to simple textarea', | ||||
|     }, | ||||
|     'gitea-code-inline': { | ||||
|       action(e) { | ||||
|         const cm = e.codemirror; | ||||
|         const selection = cm.getSelection(); | ||||
|         cm.replaceSelection(`\`${selection}\``); | ||||
|         if (!selection) { | ||||
|           const cursorPos = cm.getCursor(); | ||||
|           cm.setCursor(cursorPos.line, cursorPos.ch - 1); | ||||
|         } | ||||
|         cm.focus(); | ||||
|       }, | ||||
|       icon: svg('octicon-chevron-right'), | ||||
|       title: 'Add Inline Code', | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   for (const [key, value] of Object.entries(actions)) { | ||||
|     if (typeof value !== 'string') { | ||||
|       value.name = key; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return actions; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user