mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 18:36:30 +01:00 
			
		
		
		
	feat(math): support multi-line formula editing
This commit is contained in:
		| @@ -110,6 +110,26 @@ export default class MathUI extends Plugin { | ||||
| 			cancel(); | ||||
| 		} ); | ||||
|  | ||||
| 		// Allow pressing Enter to submit changes, and use Shift+Enter to insert a new line | ||||
| 		formView.keystrokes.set('enter', (data, cancel) => { | ||||
| 			if (!data.shiftKey) { | ||||
| 				formView.fire('submit'); | ||||
| 				cancel(); | ||||
| 			} | ||||
| 		}); | ||||
|  | ||||
| 		// Allow the textarea to be resizable | ||||
| 		formView.mathInputView.fieldView.once('render', () => { | ||||
| 			const textarea = formView.mathInputView.fieldView.element; | ||||
| 			if (!textarea) return; | ||||
| 			textarea.focus(); | ||||
| 			Object.assign(textarea.style, { | ||||
| 				resize: 'both', | ||||
| 				height: '100px', | ||||
| 				minWidth: '100%', | ||||
| 			}); | ||||
| 		}); | ||||
|  | ||||
| 		return formView; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -1,16 +1,16 @@ | ||||
| import { ButtonView, createLabeledInputText, FocusCycler, LabelView, LabeledFieldView, submitHandler, SwitchButtonView, View, ViewCollection, type InputTextView, type FocusableView, Locale, FocusTracker, KeystrokeHandler } from 'ckeditor5'; | ||||
| import { ButtonView, createLabeledTextarea, FocusCycler, LabelView, LabeledFieldView, submitHandler, SwitchButtonView, View, ViewCollection, type TextareaView, type FocusableView, Locale, FocusTracker, KeystrokeHandler } from 'ckeditor5'; | ||||
| import { IconCheck, IconCancel } from "@ckeditor/ckeditor5-icons"; | ||||
| import { extractDelimiters, hasDelimiters } from '../utils.js'; | ||||
| import MathView from './mathview.js'; | ||||
| import '../../theme/mathform.css'; | ||||
| import type { KatexOptions } from '../typings-external.js'; | ||||
|  | ||||
| class MathInputView extends LabeledFieldView<InputTextView> { | ||||
| class MathInputView extends LabeledFieldView<TextareaView> { | ||||
| 	public value: null | string = null; | ||||
| 	public isReadOnly = false; | ||||
|  | ||||
| 	constructor( locale: Locale ) { | ||||
| 		super( locale, createLabeledInputText ); | ||||
| 		super( locale, createLabeledTextarea ); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -49,7 +49,7 @@ export default class MathView extends View { | ||||
| 		this.setTemplate( { | ||||
| 			tag: 'div', | ||||
| 			attributes: { | ||||
| 				class: [ 'ck', 'ck-math-preview' ] | ||||
| 				class: [ 'ck', 'ck-math-preview', 'ck-reset_all-excluded' ] | ||||
| 			} | ||||
| 		} ); | ||||
| 	} | ||||
|   | ||||
| @@ -94,7 +94,6 @@ export async function renderEquation( | ||||
| 				el => { | ||||
| 					renderMathJax3( equation, el, display, () => { | ||||
| 						if ( preview ) { | ||||
| 							moveAndScaleElement( element, el ); | ||||
| 							el.style.visibility = 'visible'; | ||||
| 						} | ||||
| 					} ); | ||||
| @@ -115,7 +114,6 @@ export async function renderEquation( | ||||
| 						if ( preview && isMathJaxVersion2( MathJax ) ) { | ||||
| 							// eslint-disable-next-line new-cap | ||||
| 							MathJax.Hub.Queue( () => { | ||||
| 								moveAndScaleElement( element, el ); | ||||
| 								el.style.visibility = 'visible'; | ||||
| 							} ); | ||||
| 						} | ||||
| @@ -139,7 +137,6 @@ export async function renderEquation( | ||||
| 					} ); | ||||
| 				} | ||||
| 				if ( preview ) { | ||||
| 					moveAndScaleElement( element, el ); | ||||
| 					el.style.visibility = 'visible'; | ||||
| 				} | ||||
| 			} | ||||
| @@ -295,47 +292,7 @@ function getPreviewElement( | ||||
| 		previewEl.setAttribute( 'id', previewUid ); | ||||
| 		previewEl.classList.add( ...previewClassName ); | ||||
| 		previewEl.style.visibility = 'hidden'; | ||||
| 		document.body.appendChild( previewEl ); | ||||
|  | ||||
| 		let ticking = false; | ||||
|  | ||||
| 		const renderTransformation = () => { | ||||
| 			if ( !ticking ) { | ||||
| 				window.requestAnimationFrame( () => { | ||||
| 					if ( previewEl ) { | ||||
| 						moveElement( element, previewEl ); | ||||
| 						ticking = false; | ||||
| 					} | ||||
| 				} ); | ||||
|  | ||||
| 				ticking = true; | ||||
| 			} | ||||
| 		}; | ||||
|  | ||||
| 		// Create scroll listener for following | ||||
| 		window.addEventListener( 'resize', renderTransformation ); | ||||
| 		window.addEventListener( 'scroll', renderTransformation ); | ||||
| 		element.appendChild( previewEl ); | ||||
| 	} | ||||
| 	return previewEl; | ||||
| } | ||||
|  | ||||
| function moveAndScaleElement( parent: HTMLElement, child: HTMLElement ) { | ||||
| 	// Move to right place | ||||
| 	moveElement( parent, child ); | ||||
|  | ||||
| 	// Scale parent element same as preview | ||||
| 	const domRect = child.getBoundingClientRect(); | ||||
| 	parent.style.width = domRect.width + 'px'; | ||||
| 	parent.style.height = domRect.height + 'px'; | ||||
| } | ||||
|  | ||||
| function moveElement( parent: HTMLElement, child: HTMLElement ) { | ||||
| 	const domRect = parent.getBoundingClientRect(); | ||||
| 	const left = window.scrollX + domRect.left; | ||||
| 	const top = window.scrollY + domRect.top; | ||||
| 	child.style.position = 'absolute'; | ||||
| 	child.style.left = left + 'px'; | ||||
| 	child.style.top = top + 'px'; | ||||
| 	child.style.zIndex = 'var(--ck-z-panel)'; | ||||
| 	child.style.pointerEvents = 'none'; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user