mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			93 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			93 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import libraryLoader from "./library_loader.js";
 | |
| import noteDetailService from './note_detail.js';
 | |
| import treeService from './tree.js';
 | |
| import attributeService from "./attributes.js";
 | |
| 
 | |
| const $component = $('#note-detail-text');
 | |
| 
 | |
| let textEditor = null;
 | |
| 
 | |
| async function show() {
 | |
|     if (!textEditor) {
 | |
|         await libraryLoader.requireLibrary(libraryLoader.CKEDITOR);
 | |
| 
 | |
|         // CKEditor since version 12 needs the element to be visible before initialization. At the same time
 | |
|         // we want to avoid flicker - i.e. show editor only once everything is ready. That's why we have separate
 | |
|         // display of $component in both branches.
 | |
|         $component.show();
 | |
| 
 | |
|         // textEditor might have been initialized during previous await so checking again
 | |
|         // looks like double initialization can freeze CKEditor pretty badly
 | |
|         if (!textEditor) {
 | |
|             textEditor = await BalloonEditor.create($component[0]);
 | |
| 
 | |
|             onNoteChange(noteDetailService.noteChanged);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     textEditor.isReadOnly = await isReadOnly();
 | |
| 
 | |
|     $component.show();
 | |
| 
 | |
|     textEditor.setData(noteDetailService.getCurrentNote().noteContent.content);
 | |
| }
 | |
| 
 | |
| function getContent() {
 | |
|     let content = textEditor.getData();
 | |
| 
 | |
|     // if content is only tags/whitespace (typically <p> </p>), then just make it empty
 | |
|     // this is important when setting new note to code
 | |
|     if (jQuery(content).text().trim() === '' && !content.includes("<img")) {
 | |
|         content = '';
 | |
|     }
 | |
| 
 | |
|     return content;
 | |
| }
 | |
| 
 | |
| async function isReadOnly() {
 | |
|     const attributes = await attributeService.getAttributes();
 | |
| 
 | |
|     return attributes.some(attr => attr.type === 'label' && attr.name === 'readOnly');
 | |
| }
 | |
| 
 | |
| function focus() {
 | |
|     $component.focus();
 | |
| }
 | |
| 
 | |
| function getEditor() {
 | |
|     return textEditor;
 | |
| }
 | |
| 
 | |
| function onNoteChange(func) {
 | |
|     textEditor.model.document.on('change:data', func);
 | |
| }
 | |
| 
 | |
| $component.on("dblclick", "img", e => {
 | |
|     const $img = $(e.target);
 | |
|     const src = $img.prop("src");
 | |
| 
 | |
|     const match = src.match(/\/api\/images\/([A-Za-z0-9]+)\//);
 | |
| 
 | |
|     if (match) {
 | |
|         const noteId = match[1];
 | |
| 
 | |
|         treeService.activateNote(noteId);
 | |
|     }
 | |
|     else {
 | |
|         window.open(src, '_blank');
 | |
|     }
 | |
| });
 | |
| 
 | |
| export default {
 | |
|     show,
 | |
|     getEditor,
 | |
|     getContent,
 | |
|     focus,
 | |
|     onNoteChange,
 | |
|     cleanup: () => {
 | |
|         if (textEditor) {
 | |
|             textEditor.setData('');
 | |
|         }
 | |
|     },
 | |
|     scrollToTop: () => $component.scrollTop(0)
 | |
| } |