render notes in book

This commit is contained in:
zadam 2019-10-05 10:55:29 +02:00
parent 5892b5b851
commit 7c54ba63ce
8 changed files with 87 additions and 42 deletions

View File

@ -8,8 +8,8 @@ async function getAndExecuteBundle(noteId, originEntity = null) {
return await executeBundle(bundle, originEntity); return await executeBundle(bundle, originEntity);
} }
async function executeBundle(bundle, originEntity, tabContext) { async function executeBundle(bundle, originEntity, tabContext, $container) {
const apiContext = await ScriptContext(bundle.noteId, bundle.allNoteIds, originEntity, tabContext); const apiContext = await ScriptContext(bundle.noteId, bundle.allNoteIds, originEntity, tabContext, $container);
try { try {
return await (function () { return await (function () {

View File

@ -16,9 +16,12 @@ import StandardWidget from '../widgets/standard_widget.js';
* @constructor * @constructor
* @hideconstructor * @hideconstructor
*/ */
function FrontendScriptApi(startNote, currentNote, originEntity = null, tabContext = null) { function FrontendScriptApi(startNote, currentNote, originEntity = null, tabContext = null, $container = null) {
const $pluginButtons = $("#plugin-buttons"); const $pluginButtons = $("#plugin-buttons");
/** @property {jQuery} container of all the rendered script content */
this.$container = $container;
/** @property {object} note where script started executing */ /** @property {object} note where script started executing */
this.startNote = startNote; this.startNote = startNote;
/** @property {object} note where script is currently executing */ /** @property {object} note where script is currently executing */

View File

@ -2,17 +2,36 @@ import server from "./server.js";
import linkService from "./link.js"; import linkService from "./link.js";
import utils from "./utils.js"; import utils from "./utils.js";
import treeCache from "./tree_cache.js"; import treeCache from "./tree_cache.js";
import renderService from "./render.js";
const MIN_ZOOM_LEVEL = 1; const MIN_ZOOM_LEVEL = 1;
const MAX_ZOOM_LEVEL = 6; const MAX_ZOOM_LEVEL = 6;
const ZOOMS = { const ZOOMS = {
1: 100, 1: {
2: 49, width: "100%",
3: 32, height: "100%"
4: 24, },
5: 19, 2: {
6: 16 width: "49%",
height: "350px"
},
3: {
width: "32%",
height: "250px"
},
4: {
width: "24%",
height: "200px"
},
5: {
width: "19%",
height: "175px"
},
6: {
width: "16%",
height: "150px"
}
}; };
class NoteDetailBook { class NoteDetailBook {
@ -57,7 +76,8 @@ class NoteDetailBook {
this.$zoomInButton.prop("disabled", zoomLevel === MIN_ZOOM_LEVEL); this.$zoomInButton.prop("disabled", zoomLevel === MIN_ZOOM_LEVEL);
this.$zoomOutButton.prop("disabled", zoomLevel === MAX_ZOOM_LEVEL); this.$zoomOutButton.prop("disabled", zoomLevel === MAX_ZOOM_LEVEL);
this.$content.find('.note-book-card').css("flex-basis", ZOOMS[zoomLevel] + "%"); this.$content.find('.note-book-card').css("flex-basis", ZOOMS[zoomLevel].width);
this.$content.find('.note-book-content').css("max-height", ZOOMS[zoomLevel].height);
} }
async render() { async render() {
@ -70,10 +90,12 @@ class NoteDetailBook {
for (const childNote of await note.getChildNotes()) { for (const childNote of await note.getChildNotes()) {
const $card = $('<div class="note-book-card">') const $card = $('<div class="note-book-card">')
.attr('data-note-id', childNote.noteId) .attr('data-note-id', childNote.noteId)
.css("flex-basis", ZOOMS[this.zoomLevel] + "%") .css("flex-basis", ZOOMS[this.zoomLevel].width)
.addClass("type-" + childNote.type) .addClass("type-" + childNote.type)
.append($('<h5 class="note-book-title">').append(await linkService.createNoteLink(childNote.noteId, null, false))) .append($('<h5 class="note-book-title">').append(await linkService.createNoteLink(childNote.noteId, null, false)))
.append($('<div class="note-book-content">').append(await this.getNoteContent(childNote))); .append($('<div class="note-book-content">')
.css("max-height", ZOOMS[this.zoomLevel].height)
.append(await this.getNoteContent(childNote)));
const childCount = childNote.getChildNoteIds().length; const childCount = childNote.getChildNoteIds().length;
@ -81,8 +103,8 @@ class NoteDetailBook {
const label = `${childCount} child${childCount > 1 ? 'ren' : ''}`; const label = `${childCount} child${childCount > 1 ? 'ren' : ''}`;
$card.append($('<div class="note-book-children">') $card.append($('<div class="note-book-children">')
.append($(`<a class="note-book-open-children-button" href="javascript:">Show ${label}</a>`)) .append($(`<a class="note-book-open-children-button" href="javascript:">+ Show ${label}</a>`))
.append($(`<a class="note-book-hide-children-button" href="javascript:">Hide ${label}</a>`).hide()) .append($(`<a class="note-book-hide-children-button" href="javascript:">- Hide ${label}</a>`).hide())
.append($('<div class="note-book-children-content">')) .append($('<div class="note-book-children-content">'))
); );
} }
@ -145,6 +167,13 @@ class NoteDetailBook {
.append(' &nbsp; ') .append(' &nbsp; ')
.append($openButton); .append($openButton);
} }
else if (note.type === 'render') {
const $el = $('<div>');
await renderService.render(note, $el, this.ctx);
return $el;
}
else { else {
return "<em>Content of this note cannot be displayed in the book format</em>"; return "<em>Content of this note cannot be displayed in the book format</em>";
} }

View File

@ -1,5 +1,4 @@
import bundleService from "./bundle.js"; import renderService from "./render.js";
import server from "./server.js";
class NoteDetailRender { class NoteDetailRender {
/** /**
@ -16,29 +15,10 @@ class NoteDetailRender {
} }
async render() { async render() {
const attributes = await this.ctx.attributes.getAttributes();
const renderNotes = attributes.filter(attr =>
attr.type === 'relation'
&& attr.name === 'renderNote'
&& !!attr.value);
this.$component.show(); this.$component.show();
this.$noteDetailRenderHelp.hide();
this.$noteDetailRenderContent.empty(); await renderService.render(this.ctx.note, this.$noteDetailRenderContent, this.ctx);
this.$noteDetailRenderContent.toggle(renderNotes.length > 0);
this.$noteDetailRenderHelp.toggle(renderNotes.length === 0);
for (const renderNote of renderNotes) {
const bundle = await server.get('script/bundle/' + renderNote.value);
this.$noteDetailRenderContent.append(bundle.html);
const $result = await bundleService.executeBundle(bundle, this.ctx.note, this.ctx);
if ($result) {
this.$noteDetailRenderContent.append($result);
}
}
} }
getContent() {} getContent() {}

View File

@ -0,0 +1,33 @@
import server from "./server.js";
import bundleService from "./bundle.js";
async function render(note, $el, ctx) {
const attributes = await note.getAttributes();
const renderNoteIds = attributes.filter(attr =>
attr.type === 'relation'
&& attr.name === 'renderNote'
&& !!attr.value).map(rel => rel.value);
$el.empty().toggle(renderNoteIds.length > 0);
for (const renderNoteId of renderNoteIds) {
const bundle = await server.get('script/bundle/' + renderNoteId);
const $scriptContainer = $('<div>');
$el.append($scriptContainer);
$scriptContainer.append(bundle.html);
const $result = await bundleService.executeBundle(bundle, note, ctx, $scriptContainer);
if ($result) {
$scriptContainer.append($result);
}
}
return renderNoteIds.length > 0;
}
export default {
render
}

View File

@ -2,7 +2,7 @@ import FrontendScriptApi from './frontend_script_api.js';
import utils from './utils.js'; import utils from './utils.js';
import treeCache from './tree_cache.js'; import treeCache from './tree_cache.js';
async function ScriptContext(startNoteId, allNoteIds, originEntity = null, tabContext = null) { async function ScriptContext(startNoteId, allNoteIds, originEntity = null, tabContext = null, $container = null) {
const modules = {}; const modules = {};
const startNote = await treeCache.getNote(startNoteId); const startNote = await treeCache.getNote(startNoteId);
@ -11,7 +11,7 @@ async function ScriptContext(startNoteId, allNoteIds, originEntity = null, tabCo
return { return {
modules: modules, modules: modules,
notes: utils.toObject(allNotes, note => [note.noteId, note]), notes: utils.toObject(allNotes, note => [note.noteId, note]),
apis: utils.toObject(allNotes, note => [note.noteId, new FrontendScriptApi(startNote, note, originEntity, tabContext)]), apis: utils.toObject(allNotes, note => [note.noteId, new FrontendScriptApi(startNote, note, originEntity, tabContext, $container)]),
require: moduleNoteIds => { require: moduleNoteIds => {
return moduleName => { return moduleName => {
const candidates = allNotes.filter(note => moduleNoteIds.includes(note.noteId)); const candidates = allNotes.filter(note => moduleNoteIds.includes(note.noteId));

View File

@ -848,10 +848,10 @@ a.external:not(.no-arrow):after, a[href^="http://"]:not(.no-arrow):after, a[href
} }
.note-book-content { .note-book-content {
max-height: 250px; overflow: hidden;
} }
.note-book.type-image .note-book-content, .note-book.type-file .note-book-content { .note-book-card.type-image .note-book-content, .note-book-card.type-file .note-book-content {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;

View File

@ -1,5 +1,5 @@
<div class="note-detail-book note-detail-component"> <div class="note-detail-book note-detail-component">
<div class="btn-group floating-button" style="right: 25px; top: 20px;"> <div class="btn-group floating-button" style="right: 10px; top: 20px;">
<button type="button" <button type="button"
class="book-zoom-in btn icon-button jam jam-search-plus" class="book-zoom-in btn icon-button jam jam-search-plus"
title="Zoom In"></button> title="Zoom In"></button>