mirror of
https://github.com/zadam/trilium.git
synced 2025-11-02 03:16:11 +01:00
tabs wip
This commit is contained in:
@@ -3,93 +3,98 @@ import noteDetailService from './note_detail.js';
|
||||
import treeService from './tree.js';
|
||||
import attributeService from "./attributes.js";
|
||||
|
||||
const $component = $('#note-detail-text');
|
||||
class NoteDetailText {
|
||||
/**
|
||||
* @param {NoteContext} ctx
|
||||
*/
|
||||
constructor(ctx) {
|
||||
this.$component = ctx.$noteTab.find('.note-detail-text');
|
||||
this.textEditor = null;
|
||||
|
||||
let textEditor = null;
|
||||
this.$component.on("dblclick", "img", e => {
|
||||
const $img = $(e.target);
|
||||
const src = $img.prop("src");
|
||||
|
||||
async function show() {
|
||||
if (!textEditor) {
|
||||
await libraryLoader.requireLibrary(libraryLoader.CKEDITOR);
|
||||
const match = src.match(/\/api\/images\/([A-Za-z0-9]+)\//);
|
||||
|
||||
// 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();
|
||||
if (match) {
|
||||
const noteId = match[1];
|
||||
|
||||
// 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], {
|
||||
placeholder: "Type the content of your note here ..."
|
||||
});
|
||||
treeService.activateNote(noteId);
|
||||
}
|
||||
else {
|
||||
window.open(src, '_blank');
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onNoteChange(noteDetailService.noteChanged);
|
||||
async show() {
|
||||
if (!this.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.
|
||||
this.$component.show();
|
||||
|
||||
// textEditor might have been initialized during previous await so checking again
|
||||
// looks like double initialization can freeze CKEditor pretty badly
|
||||
if (!this.textEditor) {
|
||||
this.textEditor = await BalloonEditor.create(this.$component[0], {
|
||||
placeholder: "Type the content of your note here ..."
|
||||
});
|
||||
|
||||
this.onNoteChange(noteDetailService.noteChanged);
|
||||
}
|
||||
}
|
||||
|
||||
this.textEditor.isReadOnly = await isReadOnly();
|
||||
|
||||
this.$component.show();
|
||||
|
||||
this.textEditor.setData(noteDetailService.getActiveNote().content);
|
||||
}
|
||||
|
||||
getContent() {
|
||||
let content = this.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 isReadOnly() {
|
||||
const attributes = await attributeService.getAttributes();
|
||||
|
||||
return attributes.some(attr => attr.type === 'label' && attr.name === 'readOnly');
|
||||
}
|
||||
|
||||
focus() {
|
||||
this.$component.focus();
|
||||
}
|
||||
|
||||
getEditor() {
|
||||
return this.textEditor;
|
||||
}
|
||||
|
||||
onNoteChange(func) {
|
||||
this.textEditor.model.document.on('change:data', func);
|
||||
}
|
||||
|
||||
|
||||
cleanup() {
|
||||
if (this.textEditor) {
|
||||
this.textEditor.setData('');
|
||||
}
|
||||
}
|
||||
|
||||
textEditor.isReadOnly = await isReadOnly();
|
||||
|
||||
$component.show();
|
||||
|
||||
textEditor.setData(noteDetailService.getActiveNote().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 = '';
|
||||
scrollToTop() {
|
||||
this.$component.scrollTop(0);
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
export default NoteDetailText
|
||||
Reference in New Issue
Block a user