mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
unification of tooltip and note list renderers
This commit is contained in:
parent
bc520edd19
commit
a1fb84f14d
@ -63,7 +63,7 @@ async function createNoteLink(noteId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function renderAttributes(attributes, renderIsInheritable) {
|
async function renderAttributes(attributes, renderIsInheritable) {
|
||||||
const $container = $("<span>");
|
const $container = $('<span class="rendered-note-attributes">');
|
||||||
|
|
||||||
for (let i = 0; i < attributes.length; i++) {
|
for (let i = 0; i < attributes.length; i++) {
|
||||||
const attribute = attributes[i];
|
const attribute = attributes[i];
|
||||||
@ -79,7 +79,19 @@ async function renderAttributes(attributes, renderIsInheritable) {
|
|||||||
return $container;
|
return $container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function renderNormalAttributes(note) {
|
||||||
|
const attrs = note.getAttributes().filter(attr => !attr.isDefinition() && !attr.isAutoLink);
|
||||||
|
|
||||||
|
const $renderedAttributes = await renderAttributes(attrs, false);
|
||||||
|
|
||||||
|
return {
|
||||||
|
count: attrs.length,
|
||||||
|
$renderedAttributes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
renderAttribute,
|
renderAttribute,
|
||||||
renderAttributes
|
renderAttributes,
|
||||||
|
renderNormalAttributes
|
||||||
}
|
}
|
||||||
|
@ -4,38 +4,42 @@ import protectedSessionService from "./protected_session.js";
|
|||||||
import protectedSessionHolder from "./protected_session_holder.js";
|
import protectedSessionHolder from "./protected_session_holder.js";
|
||||||
import libraryLoader from "./library_loader.js";
|
import libraryLoader from "./library_loader.js";
|
||||||
import openService from "./open.js";
|
import openService from "./open.js";
|
||||||
|
import treeCache from "./tree_cache.js";
|
||||||
|
|
||||||
async function getRenderedContent(note, options = {}) {
|
async function getRenderedContent(note, options = {}) {
|
||||||
options = Object.assign({
|
options = Object.assign({
|
||||||
trim: false
|
trim: false,
|
||||||
|
tooltip: false
|
||||||
}, options);
|
}, options);
|
||||||
|
|
||||||
const type = getRenderingType(note);
|
const type = getRenderingType(note);
|
||||||
|
|
||||||
let $rendered;
|
const $renderedContent = $('<div class="rendered-note-content">');
|
||||||
|
|
||||||
if (type === 'text') {
|
if (type === 'text') {
|
||||||
const fullNote = await server.get('notes/' + note.noteId);
|
const noteComplement = await treeCache.getNoteComplement(note.noteId);
|
||||||
|
|
||||||
$rendered = $('<div class="ck-content">').html(trim(fullNote.content, options.trim));
|
$renderedContent.append($('<div class="ck-content">').html(trim(noteComplement.content, options.trim)));
|
||||||
|
|
||||||
if ($rendered.find('span.math-tex').length > 0) {
|
if ($renderedContent.find('span.math-tex').length > 0) {
|
||||||
await libraryLoader.requireLibrary(libraryLoader.KATEX);
|
await libraryLoader.requireLibrary(libraryLoader.KATEX);
|
||||||
|
|
||||||
renderMathInElement($rendered[0], {});
|
renderMathInElement($renderedContent[0], {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type === 'code') {
|
else if (type === 'code') {
|
||||||
const fullNote = await server.get('notes/' + note.noteId);
|
const fullNote = await server.get('notes/' + note.noteId);
|
||||||
|
|
||||||
$rendered = $("<pre>").text(trim(fullNote.content, options.trim));
|
$renderedContent.append($("<pre>").text(trim(fullNote.content, options.trim)));
|
||||||
}
|
}
|
||||||
else if (type === 'image') {
|
else if (type === 'image') {
|
||||||
$rendered = $("<img>")
|
$renderedContent.append(
|
||||||
.attr("src", `api/images/${note.noteId}/${note.title}`)
|
$("<img>")
|
||||||
.css("max-width", "100%");
|
.attr("src", `api/images/${note.noteId}/${note.title}`)
|
||||||
|
.css("max-width", "100%")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else if (type === 'file' || type === 'pdf') {
|
else if (!options.tooltip && (type === 'file' || type === 'pdf')) {
|
||||||
const $downloadButton = $('<button class="file-download btn btn-primary" type="button">Download</button>');
|
const $downloadButton = $('<button class="file-download btn btn-primary" type="button">Download</button>');
|
||||||
const $openButton = $('<button class="file-open btn btn-primary" type="button">Open</button>');
|
const $openButton = $('<button class="file-open btn btn-primary" type="button">Open</button>');
|
||||||
|
|
||||||
@ -45,44 +49,50 @@ async function getRenderedContent(note, options = {}) {
|
|||||||
// open doesn't work for protected notes since it works through browser which isn't in protected session
|
// open doesn't work for protected notes since it works through browser which isn't in protected session
|
||||||
$openButton.toggle(!note.isProtected);
|
$openButton.toggle(!note.isProtected);
|
||||||
|
|
||||||
$rendered = $('<div style="display: flex; flex-direction: column; height: 100%;">');
|
const $content = $('<div style="display: flex; flex-direction: column; height: 100%;">');
|
||||||
|
|
||||||
if (type === 'pdf') {
|
if (type === 'pdf') {
|
||||||
const $pdfPreview = $('<iframe class="pdf-preview" style="width: 100%; flex-grow: 100;"></iframe>');
|
const $pdfPreview = $('<iframe class="pdf-preview" style="width: 100%; flex-grow: 100;"></iframe>');
|
||||||
$pdfPreview.attr("src", openService.getUrlForDownload("api/notes/" + note.noteId + "/open"));
|
$pdfPreview.attr("src", openService.getUrlForDownload("api/notes/" + note.noteId + "/open"));
|
||||||
|
|
||||||
$rendered.append($pdfPreview);
|
$content.append($pdfPreview);
|
||||||
}
|
}
|
||||||
|
|
||||||
$rendered.append(
|
$content.append(
|
||||||
$("<div>")
|
$("<div>")
|
||||||
.append($downloadButton)
|
.append($downloadButton)
|
||||||
.append(' ')
|
.append(' ')
|
||||||
.append($openButton)
|
.append($openButton)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$renderedContent.append($content);
|
||||||
}
|
}
|
||||||
else if (type === 'render') {
|
else if (type === 'render') {
|
||||||
$rendered = $('<div>');
|
const $content = $('<div>');
|
||||||
|
|
||||||
await renderService.render(note, $rendered, this.ctx);
|
await renderService.render(note, $content, this.ctx);
|
||||||
|
|
||||||
|
$renderedContent.append($content);
|
||||||
}
|
}
|
||||||
else if (type === 'protected-session') {
|
else if (!options.tooltip && type === 'protected-session') {
|
||||||
const $button = $(`<button class="btn btn-sm"><span class="bx bx-log-in"></span> Enter protected session</button>`)
|
const $button = $(`<button class="btn btn-sm"><span class="bx bx-log-in"></span> Enter protected session</button>`)
|
||||||
.on('click', protectedSessionService.enterProtectedSession);
|
.on('click', protectedSessionService.enterProtectedSession);
|
||||||
|
|
||||||
$rendered = $("<div>")
|
$renderedContent.append(
|
||||||
.append("<div>This note is protected and to access it you need to enter password.</div>")
|
$("<div>")
|
||||||
.append("<br/>")
|
.append("<div>This note is protected and to access it you need to enter password.</div>")
|
||||||
.append($button);
|
.append("<br/>")
|
||||||
|
.append($button)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$rendered = $("<em>Content of this note cannot be displayed in the book format</em>");
|
$renderedContent.append($("<em>Content of this note cannot be displayed in the book format</em>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
$rendered.addClass(note.getCssClass());
|
$renderedContent.addClass(note.getCssClass());
|
||||||
|
|
||||||
return {
|
return {
|
||||||
renderedContent: $rendered,
|
$renderedContent,
|
||||||
type
|
type
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import linkService from "./link.js";
|
|||||||
import noteContentRenderer from "./note_content_renderer.js";
|
import noteContentRenderer from "./note_content_renderer.js";
|
||||||
import treeCache from "./tree_cache.js";
|
import treeCache from "./tree_cache.js";
|
||||||
import attributeService from "./attributes.js";
|
import attributeService from "./attributes.js";
|
||||||
|
import attributeRenderer from "./attribute_renderer.js";
|
||||||
|
|
||||||
const TPL = `
|
const TPL = `
|
||||||
<div class="note-list">
|
<div class="note-list">
|
||||||
@ -56,6 +57,14 @@ const TPL = `
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.note-book-title .rendered-note-attributes {
|
||||||
|
font-size: medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
.note-book-title .rendered-note-attributes:before {
|
||||||
|
content: "\\00a0\\00a0";
|
||||||
|
}
|
||||||
|
|
||||||
.note-book-card .note-book-card {
|
.note-book-card .note-book-card {
|
||||||
border: 1px solid var(--main-border-color);
|
border: 1px solid var(--main-border-color);
|
||||||
}
|
}
|
||||||
@ -244,16 +253,18 @@ class NoteListRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: we should also render (promoted) attributes
|
|
||||||
async renderNote(note, expand = false) {
|
async renderNote(note, expand = false) {
|
||||||
const $expander = $('<span class="note-expander bx bx-chevron-right"></span>');
|
const $expander = $('<span class="note-expander bx bx-chevron-right"></span>');
|
||||||
|
|
||||||
|
const {$renderedAttributes} = await attributeRenderer.renderNormalAttributes(note);
|
||||||
|
|
||||||
const $card = $('<div class="note-book-card">')
|
const $card = $('<div class="note-book-card">')
|
||||||
.attr('data-note-id', note.noteId)
|
.attr('data-note-id', note.noteId)
|
||||||
.append(
|
.append(
|
||||||
$('<h5 class="note-book-title">')
|
$('<h5 class="note-book-title">')
|
||||||
.append($expander)
|
.append($expander)
|
||||||
.append(await linkService.createNoteLink(note.noteId, {showTooltip: false}))
|
.append(await linkService.createNoteLink(note.noteId, {showTooltip: false}))
|
||||||
|
.append($renderedAttributes)
|
||||||
);
|
);
|
||||||
|
|
||||||
$expander.on('click', () => this.toggleContent($card, note, !$card.hasClass("expanded")));
|
$expander.on('click', () => this.toggleContent($card, note, !$card.hasClass("expanded")));
|
||||||
@ -288,11 +299,11 @@ class NoteListRenderer {
|
|||||||
const $content = $('<div class="note-book-content">');
|
const $content = $('<div class="note-book-content">');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const {renderedContent, type} = await noteContentRenderer.getRenderedContent(note, {
|
const {$renderedContent, type} = await noteContentRenderer.getRenderedContent(note, {
|
||||||
trim: this.viewType === 'grid' // for grid only short content is needed
|
trim: this.viewType === 'grid' // for grid only short content is needed
|
||||||
});
|
});
|
||||||
|
|
||||||
$content.append(renderedContent);
|
$content.append($renderedContent);
|
||||||
$content.addClass("type-" + type);
|
$content.addClass("type-" + type);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(`Caught error while rendering note ${note.noteId} of type ${note.type}: ${e.message}, stack: ${e.stack}`);
|
console.log(`Caught error while rendering note ${note.noteId} of type ${note.type}: ${e.message}, stack: ${e.stack}`);
|
||||||
|
@ -3,7 +3,7 @@ import linkService from "./link.js";
|
|||||||
import treeCache from "./tree_cache.js";
|
import treeCache from "./tree_cache.js";
|
||||||
import utils from "./utils.js";
|
import utils from "./utils.js";
|
||||||
import attributeRenderer from "./attribute_renderer.js";
|
import attributeRenderer from "./attribute_renderer.js";
|
||||||
import libraryLoader from "./library_loader.js";
|
import noteContentRenderer from "./note_content_renderer.js";
|
||||||
|
|
||||||
function setupGlobalTooltip() {
|
function setupGlobalTooltip() {
|
||||||
$(document).on("mouseenter", "a", mouseEnterHandler);
|
$(document).on("mouseenter", "a", mouseEnterHandler);
|
||||||
@ -45,9 +45,7 @@ async function mouseEnterHandler() {
|
|||||||
const noteId = treeService.getNoteIdFromNotePath(notePath);
|
const noteId = treeService.getNoteIdFromNotePath(notePath);
|
||||||
|
|
||||||
const note = await treeCache.getNote(noteId);
|
const note = await treeCache.getNote(noteId);
|
||||||
const noteComplement = await treeCache.getNoteComplement(noteId);
|
const content = await renderTooltip(note);
|
||||||
|
|
||||||
const content = await renderTooltip(note, noteComplement);
|
|
||||||
|
|
||||||
if (utils.isHtmlEmpty(content)) {
|
if (utils.isHtmlEmpty(content)) {
|
||||||
return;
|
return;
|
||||||
@ -79,7 +77,7 @@ function mouseLeaveHandler() {
|
|||||||
$(this).tooltip('dispose');
|
$(this).tooltip('dispose');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function renderTooltip(note, noteComplement) {
|
async function renderTooltip(note) {
|
||||||
if (note.isDeleted) {
|
if (note.isDeleted) {
|
||||||
return '<div>Note has been deleted.</div>';
|
return '<div>Note has been deleted.</div>';
|
||||||
}
|
}
|
||||||
@ -92,37 +90,16 @@ async function renderTooltip(note, noteComplement) {
|
|||||||
|
|
||||||
let content = $("<h5>").text(await treeService.getNotePathTitle(someNotePath)).prop('outerHTML');
|
let content = $("<h5>").text(await treeService.getNotePathTitle(someNotePath)).prop('outerHTML');
|
||||||
|
|
||||||
const attributes = note.getAttributes()
|
const {$renderedAttributes} = await attributeRenderer.renderNormalAttributes(note);
|
||||||
.filter(attr => !attr.isDefinition());
|
|
||||||
|
|
||||||
if (attributes.length > 0) {
|
const {$renderedContent} = await noteContentRenderer.getRenderedContent(note, {
|
||||||
content += '<div class="tooltip-attributes"><strong>Attributes: </strong> '
|
tooltip: true,
|
||||||
+ (await attributeRenderer.renderAttributes(attributes)).html()
|
trim: true
|
||||||
+ '</div>'
|
});
|
||||||
}
|
|
||||||
|
|
||||||
if (note.type === 'text' && !utils.isHtmlEmpty(noteComplement.content)) {
|
content = content
|
||||||
const $content = $('<div class="ck-content">').append(noteComplement.content);
|
+ $renderedAttributes[0].outerHTML
|
||||||
|
+ $renderedContent[0].outerHTML;
|
||||||
if ($content.find('span.math-tex').length > 0) {
|
|
||||||
await libraryLoader.requireLibrary(libraryLoader.KATEX);
|
|
||||||
|
|
||||||
renderMathInElement($content[0], {});
|
|
||||||
}
|
|
||||||
|
|
||||||
content += $content[0].outerHTML;
|
|
||||||
}
|
|
||||||
else if (note.type === 'code' && noteComplement.content && noteComplement.content.trim()) {
|
|
||||||
content += $("<pre>")
|
|
||||||
.text(noteComplement.content)
|
|
||||||
.prop('outerHTML');
|
|
||||||
}
|
|
||||||
else if (note.type === 'image') {
|
|
||||||
content += $("<img>")
|
|
||||||
.prop("src", `api/images/${note.noteId}/${note.title}`)
|
|
||||||
.prop('outerHTML');
|
|
||||||
}
|
|
||||||
// other types of notes don't have tooltip preview
|
|
||||||
|
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
@ -36,11 +36,11 @@ export default class AbstractTextTypeWidget extends TypeWidget {
|
|||||||
.append($link)
|
.append($link)
|
||||||
);
|
);
|
||||||
|
|
||||||
const {renderedContent, type} = await noteContentRenderer.getRenderedContent(note);
|
const {$renderedContent, type} = await noteContentRenderer.getRenderedContent(note);
|
||||||
|
|
||||||
$el.append(
|
$el.append(
|
||||||
$(`<div class="include-note-content type-${type}">`)
|
$(`<div class="include-note-content type-${type}">`)
|
||||||
.append(renderedContent)
|
.append($renderedContent)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -411,7 +411,7 @@ table.promoted-attributes-in-tooltip td, table.promoted-attributes-in-tooltip th
|
|||||||
box-shadow: 10px 10px 93px -25px #aaaaaa;
|
box-shadow: 10px 10px 93px -25px #aaaaaa;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip-attributes {
|
.rendered-note-attributes {
|
||||||
color: var(--muted-text-color);
|
color: var(--muted-text-color);
|
||||||
margin-bottom: 7px;
|
margin-bottom: 7px;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user