unification of tooltip and note list renderers

This commit is contained in:
zadam 2020-12-03 22:54:24 +01:00
parent bc520edd19
commit a1fb84f14d
6 changed files with 76 additions and 66 deletions

View File

@ -63,7 +63,7 @@ async function createNoteLink(noteId) {
}
async function renderAttributes(attributes, renderIsInheritable) {
const $container = $("<span>");
const $container = $('<span class="rendered-note-attributes">');
for (let i = 0; i < attributes.length; i++) {
const attribute = attributes[i];
@ -79,7 +79,19 @@ async function renderAttributes(attributes, renderIsInheritable) {
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 {
renderAttribute,
renderAttributes
renderAttributes,
renderNormalAttributes
}

View File

@ -4,38 +4,42 @@ import protectedSessionService from "./protected_session.js";
import protectedSessionHolder from "./protected_session_holder.js";
import libraryLoader from "./library_loader.js";
import openService from "./open.js";
import treeCache from "./tree_cache.js";
async function getRenderedContent(note, options = {}) {
options = Object.assign({
trim: false
trim: false,
tooltip: false
}, options);
const type = getRenderingType(note);
let $rendered;
const $renderedContent = $('<div class="rendered-note-content">');
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);
renderMathInElement($rendered[0], {});
renderMathInElement($renderedContent[0], {});
}
}
else if (type === 'code') {
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') {
$rendered = $("<img>")
.attr("src", `api/images/${note.noteId}/${note.title}`)
.css("max-width", "100%");
$renderedContent.append(
$("<img>")
.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 $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
$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') {
const $pdfPreview = $('<iframe class="pdf-preview" style="width: 100%; flex-grow: 100;"></iframe>');
$pdfPreview.attr("src", openService.getUrlForDownload("api/notes/" + note.noteId + "/open"));
$rendered.append($pdfPreview);
$content.append($pdfPreview);
}
$rendered.append(
$content.append(
$("<div>")
.append($downloadButton)
.append(' &nbsp; ')
.append($openButton)
);
$renderedContent.append($content);
}
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>`)
.on('click', protectedSessionService.enterProtectedSession);
$rendered = $("<div>")
.append("<div>This note is protected and to access it you need to enter password.</div>")
.append("<br/>")
.append($button);
$renderedContent.append(
$("<div>")
.append("<div>This note is protected and to access it you need to enter password.</div>")
.append("<br/>")
.append($button)
);
}
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 {
renderedContent: $rendered,
$renderedContent,
type
};
}

View File

@ -2,6 +2,7 @@ import linkService from "./link.js";
import noteContentRenderer from "./note_content_renderer.js";
import treeCache from "./tree_cache.js";
import attributeService from "./attributes.js";
import attributeRenderer from "./attribute_renderer.js";
const TPL = `
<div class="note-list">
@ -56,6 +57,14 @@ const TPL = `
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 {
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) {
const $expander = $('<span class="note-expander bx bx-chevron-right"></span>');
const {$renderedAttributes} = await attributeRenderer.renderNormalAttributes(note);
const $card = $('<div class="note-book-card">')
.attr('data-note-id', note.noteId)
.append(
$('<h5 class="note-book-title">')
.append($expander)
.append(await linkService.createNoteLink(note.noteId, {showTooltip: false}))
.append($renderedAttributes)
);
$expander.on('click', () => this.toggleContent($card, note, !$card.hasClass("expanded")));
@ -288,11 +299,11 @@ class NoteListRenderer {
const $content = $('<div class="note-book-content">');
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
});
$content.append(renderedContent);
$content.append($renderedContent);
$content.addClass("type-" + type);
} catch (e) {
console.log(`Caught error while rendering note ${note.noteId} of type ${note.type}: ${e.message}, stack: ${e.stack}`);

View File

@ -3,7 +3,7 @@ import linkService from "./link.js";
import treeCache from "./tree_cache.js";
import utils from "./utils.js";
import attributeRenderer from "./attribute_renderer.js";
import libraryLoader from "./library_loader.js";
import noteContentRenderer from "./note_content_renderer.js";
function setupGlobalTooltip() {
$(document).on("mouseenter", "a", mouseEnterHandler);
@ -45,9 +45,7 @@ async function mouseEnterHandler() {
const noteId = treeService.getNoteIdFromNotePath(notePath);
const note = await treeCache.getNote(noteId);
const noteComplement = await treeCache.getNoteComplement(noteId);
const content = await renderTooltip(note, noteComplement);
const content = await renderTooltip(note);
if (utils.isHtmlEmpty(content)) {
return;
@ -79,7 +77,7 @@ function mouseLeaveHandler() {
$(this).tooltip('dispose');
}
async function renderTooltip(note, noteComplement) {
async function renderTooltip(note) {
if (note.isDeleted) {
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');
const attributes = note.getAttributes()
.filter(attr => !attr.isDefinition());
const {$renderedAttributes} = await attributeRenderer.renderNormalAttributes(note);
if (attributes.length > 0) {
content += '<div class="tooltip-attributes"><strong>Attributes: </strong> '
+ (await attributeRenderer.renderAttributes(attributes)).html()
+ '</div>'
}
const {$renderedContent} = await noteContentRenderer.getRenderedContent(note, {
tooltip: true,
trim: true
});
if (note.type === 'text' && !utils.isHtmlEmpty(noteComplement.content)) {
const $content = $('<div class="ck-content">').append(noteComplement.content);
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
content = content
+ $renderedAttributes[0].outerHTML
+ $renderedContent[0].outerHTML;
return content;
}

View File

@ -36,11 +36,11 @@ export default class AbstractTextTypeWidget extends TypeWidget {
.append($link)
);
const {renderedContent, type} = await noteContentRenderer.getRenderedContent(note);
const {$renderedContent, type} = await noteContentRenderer.getRenderedContent(note);
$el.append(
$(`<div class="include-note-content type-${type}">`)
.append(renderedContent)
.append($renderedContent)
);
}
}

View File

@ -411,7 +411,7 @@ table.promoted-attributes-in-tooltip td, table.promoted-attributes-in-tooltip th
box-shadow: 10px 10px 93px -25px #aaaaaa;
}
.tooltip-attributes {
.rendered-note-attributes {
color: var(--muted-text-color);
margin-bottom: 7px;
}