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) { 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
} }

View File

@ -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(' &nbsp; ') .append(' &nbsp; ')
.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
}; };
} }

View File

@ -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}`);

View File

@ -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;
} }

View File

@ -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)
); );
} }
} }

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; 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;
} }