got rid of .renderTo(), tab caching widgets use hidden marker element

This commit is contained in:
zadam 2020-01-19 15:36:42 +01:00
parent 6de4914ea6
commit 416d733510
11 changed files with 59 additions and 79 deletions

View File

@ -24,6 +24,11 @@ import RowFlexContainer from "../widgets/row_flex_container.js";
import StandardTopWidget from "../widgets/standard_top_widget.js"; import StandardTopWidget from "../widgets/standard_top_widget.js";
import treeCache from "./tree_cache.js"; import treeCache from "./tree_cache.js";
import treeUtils from "./tree_utils.js"; import treeUtils from "./tree_utils.js";
import NotePathsWidget from "../widgets/note_paths.js";
import RunScriptButtonsWidget from "../widgets/run_script_buttons.js";
import ProtectedNoteSwitchWidget from "../widgets/protected_note_switch.js";
import NoteTypeWidget from "../widgets/note_type.js";
import NoteActionsWidget from "../widgets/note_actions.js";
class AppContext { class AppContext {
constructor() { constructor() {
@ -51,7 +56,7 @@ class AppContext {
const $topPane = $("#top-pane"); const $topPane = $("#top-pane");
for (const widget of topPaneWidgets) { for (const widget of topPaneWidgets) {
widget.renderTo($topPane); $topPane.append(widget.render());
} }
const $leftPane = $("#left-pane"); const $leftPane = $("#left-pane");
@ -66,19 +71,26 @@ class AppContext {
]; ];
for (const widget of leftPaneWidgets) { for (const widget of leftPaneWidgets) {
widget.renderTo($leftPane); $leftPane.append(widget.render());
} }
const $centerPane = $("#center-pane"); const $centerPane = $("#center-pane");
const centerPaneWidgets = [ const centerPaneWidgets = [
new TabCachingWidget(this, () => new NoteTitleWidget(this)), new RowFlexContainer(this, [
new TabCachingWidget(this, () => new NotePathsWidget(this)),
new NoteTitleWidget(this),
new RunScriptButtonsWidget(this),
new ProtectedNoteSwitchWidget(this),
new NoteTypeWidget(this),
new NoteActionsWidget(this)
]),
new TabCachingWidget(this, () => new PromotedAttributesWidget(this)), new TabCachingWidget(this, () => new PromotedAttributesWidget(this)),
new TabCachingWidget(this, () => new NoteDetailWidget(this)) new TabCachingWidget(this, () => new NoteDetailWidget(this))
]; ];
for (const widget of centerPaneWidgets) { for (const widget of centerPaneWidgets) {
widget.renderTo($centerPane); $centerPane.append(widget.render());
} }
const $rightPane = $("#right-pane"); const $rightPane = $("#right-pane");
@ -93,7 +105,7 @@ class AppContext {
]; ];
for (const widget of rightPaneWidgets) { for (const widget of rightPaneWidgets) {
widget.renderTo($rightPane); $rightPane.append(widget.render());
} }
this.widgets = [ this.widgets = [

View File

@ -1,12 +1,6 @@
import Component from "./component.js"; import Component from "./component.js";
class BasicWidget extends Component { class BasicWidget extends Component {
renderTo($parent) {
this.$parent = $parent;
$parent.append(this.render());
}
render() { render() {
return this.doRender(); return this.doRender();
} }

View File

@ -92,7 +92,7 @@ export default class NoteDetailWidget extends TabAwareWidget {
this.typeWidgets[this.type] = new clazz.default(this.appContext); this.typeWidgets[this.type] = new clazz.default(this.appContext);
this.children.push(this.typeWidgets[this.type]); this.children.push(this.typeWidgets[this.type]);
this.typeWidgets[this.type].renderTo(this.$widget); this.$widget.append(this.typeWidgets[this.type].render());
this.typeWidgets[this.type].eventReceived('setTabContext', {tabContext: this.tabContext}); this.typeWidgets[this.type].eventReceived('setTabContext', {tabContext: this.tabContext});
} }

View File

@ -30,9 +30,7 @@ export default class NotePathsWidget extends TabAwareWidget {
return this.$widget; return this.$widget;
} }
async refreshWithNote() { async refreshWithNote(note, notePath) {
const {note, notePath} = this.tabContext;
if (note.noteId === 'root') { if (note.noteId === 'root') {
// root doesn't have any parent, but it's still technically 1 path // root doesn't have any parent, but it's still technically 1 path

View File

@ -12,12 +12,8 @@ import ProtectedNoteSwitchWidget from "./protected_note_switch.js";
import RunScriptButtonsWidget from "./run_script_buttons.js"; import RunScriptButtonsWidget from "./run_script_buttons.js";
const TPL = ` const TPL = `
<div class="note-title-row"> <div>
<style> <style>
.note-title-row {
display: flex;
}
.note-title { .note-title {
margin-left: 15px; margin-left: 15px;
margin-right: 10px; margin-right: 10px;
@ -34,28 +30,8 @@ const TPL = `
export default class NoteTitleWidget extends TabAwareWidget { export default class NoteTitleWidget extends TabAwareWidget {
doRender() { doRender() {
this.$widget = $(TPL); this.$widget = $(TPL);
this.$noteTitle = this.$widget.find(".note-title"); this.$noteTitle = this.$widget.find(".note-title");
this.$savedIndicator = this.$widget.find(".saved-indicator");
this.runScriptButtons = new RunScriptButtonsWidget(this.appContext);
this.$widget.append(this.runScriptButtons.render());
this.protectedNoteSwitch = new ProtectedNoteSwitchWidget(this.appContext);
this.$widget.append(this.protectedNoteSwitch.render());
this.noteType = new NoteTypeWidget(this.appContext);
this.$widget.append(this.noteType.render());
this.noteActions = new NoteActionsWidget(this.appContext);
this.$widget.append(this.noteActions.render());
this.notePaths = new NotePathsWidget(this.appContext);
this.$widget.prepend(this.notePaths.render());
this.children.push(this.noteType, this.notePaths);
this.$noteTitle.on('input', () => { this.$noteTitle.on('input', () => {
if (!this.note) { if (!this.note) {
return; return;
@ -84,17 +60,11 @@ export default class NoteTitleWidget extends TabAwareWidget {
return this.$widget; return this.$widget;
} }
async refreshWithNote() { async refreshWithNote(note) {
const note = this.tabContext.note;
this.$noteTitle.val(note.title); this.$noteTitle.val(note.title);
if (note.isProtected && !protectedSessionHolder.isProtectedSessionAvailable()) { if (note.isProtected && !protectedSessionHolder.isProtectedSessionAvailable()) {
this.$noteTitle.prop("readonly", true); this.$noteTitle.prop("readonly", true);
} }
} }
noteSavedListener() {
this.$savedIndicator.fadeIn();
}
} }

View File

@ -42,20 +42,15 @@ export default class NoteTypeWidget extends TabAwareWidget {
this.$noteTypeDropdown = this.$widget.find(".note-type-dropdown"); this.$noteTypeDropdown = this.$widget.find(".note-type-dropdown");
this.$noteTypeButton = this.$widget.find(".note-type-button"); this.$noteTypeButton = this.$widget.find(".note-type-button");
this.$noteTypeDesc = this.$widget.find(".note-type-desc"); this.$noteTypeDesc = this.$widget.find(".note-type-desc");
this.$executeScriptButton = this.$widget.find(".execute-script-button");
this.$renderButton = this.$widget.find('.render-button');
return this.$widget; return this.$widget;
} }
async refreshWithNote() { async refreshWithNote(note) {
this.$noteTypeButton.prop("disabled", this.$noteTypeButton.prop("disabled",
() => ["file", "image", "search"].includes(this.tabContext.note.type)); () => ["file", "image", "search"].includes(note.type));
this.$noteTypeDesc.text(await this.findTypeTitle(this.tabContext.note.type, this.tabContext.note.mime)); this.$noteTypeDesc.text(await this.findTypeTitle(note.type, note.mime));
this.$executeScriptButton.toggle(this.tabContext.note.mime.startsWith('application/javascript'));
this.$renderButton.toggle(this.tabContext.note.type === 'render');
} }
/** actual body is rendered lazily on note-type button click */ /** actual body is rendered lazily on note-type button click */

View File

@ -1,4 +1,6 @@
import BasicWidget from "./basic_widget.js"; import BasicWidget from "./basic_widget.js";
import protectedSessionService from "../services/protected_session.js";
import protectedSessionHolder from "../services/protected_session_holder.js";
const TPL = ` const TPL = `
<div class="btn-group btn-group-xs"> <div class="btn-group btn-group-xs">
@ -17,6 +19,19 @@ export default class ProtectedNoteSwitchWidget extends BasicWidget {
doRender() { doRender() {
this.$widget = $(TPL); this.$widget = $(TPL);
this.$protectButton = this.$widget.find(".protect-button");
this.$protectButton.on('click', protectedSessionService.protectNoteAndSendToServer);
this.$unprotectButton = this.$widget.find(".unprotect-button");
this.$unprotectButton.on('click', protectedSessionService.unprotectNoteAndSendToServer);
return this.$widget; return this.$widget;
} }
refreshWithNote(note) {
this.$protectButton.toggleClass("active", note.isProtected);
this.$protectButton.prop("disabled", note.isProtected);
this.$unprotectButton.toggleClass("active", !note.isProtected);
this.$unprotectButton.prop("disabled", !note.isProtected || !protectedSessionHolder.isProtectedSessionAvailable());
}
} }

View File

@ -4,13 +4,13 @@ export default class RowFlexContainer extends BasicWidget {
constructor(appContext, widgets) { constructor(appContext, widgets) {
super(appContext); super(appContext);
this.childWidgets = widgets; this.children = widgets;
} }
render() { render() {
this.$widget = $(`<div style="display: flex; flex-direction: row;">`); this.$widget = $(`<div style="display: flex; flex-direction: row;">`);
for (const widget of this.childWidgets) { for (const widget of this.children) {
this.$widget.append(widget.render()); this.$widget.append(widget.render());
} }

View File

@ -3,31 +3,28 @@ import protectedSessionService from "../services/protected_session.js";
import protectedSessionHolder from "../services/protected_session_holder.js"; import protectedSessionHolder from "../services/protected_session_holder.js";
const TPL = ` const TPL = `
<button class="btn btn-sm icon-button bx bx-play-circle render-button" <div>
<button class="btn btn-sm icon-button bx bx-play-circle render-button"
style="display: none; margin-right: 10px;" style="display: none; margin-right: 10px;"
title="Render"></button> title="Render"></button>
<button class="btn btn-sm icon-button bx bx-play-circle execute-script-button" <button class="btn btn-sm icon-button bx bx-play-circle execute-script-button"
style="display: none; margin-right: 10px;" style="display: none; margin-right: 10px;"
title="Execute (Ctrl+Enter)"></button>`; title="Execute (Ctrl+Enter)"></button>
</div>`;
export default class RunScriptButtonsWidget extends TabAwareWidget { export default class RunScriptButtonsWidget extends TabAwareWidget {
doRender() { doRender() {
this.$widget = $(TPL); this.$widget = $(TPL);
this.$protectButton = this.$widget.find(".protect-button"); this.$renderButton = this.$widget.find('.render-button');
this.$protectButton.on('click', protectedSessionService.protectNoteAndSendToServer); this.$executeScriptButton = this.$widget.find('.execute-script-button');
this.$unprotectButton = this.$widget.find(".unprotect-button");
this.$unprotectButton.on('click', protectedSessionService.unprotectNoteAndSendToServer);
return this.$widget; return this.$widget;
} }
refreshWithNote(note) { refreshWithNote(note) {
this.$protectButton.toggleClass("active", note.isProtected); this.$renderButton.toggle(note.type === 'render');
this.$protectButton.prop("disabled", note.isProtected); this.$executeScriptButton.toggle(note.mime.startsWith('application/javascript'));
this.$unprotectButton.toggleClass("active", !note.isProtected);
this.$unprotectButton.prop("disabled", !note.isProtected || !protectedSessionHolder.isProtectedSessionAvailable());
} }
} }

View File

@ -25,7 +25,7 @@ export default class TabAwareWidget extends BasicWidget {
refresh() { refresh() {
if (this.tabContext && this.tabContext.note) { if (this.tabContext && this.tabContext.note) {
this.toggle(true); this.toggle(true);
this.refreshWithNote(this.tabContext.note); this.refreshWithNote(this.tabContext.note, this.tabContext.notePath);
} }
else { else {
this.toggle(false); this.toggle(false);

View File

@ -5,13 +5,12 @@ export default class TabCachingWidget extends TabAwareWidget {
super(appContext); super(appContext);
this.widgetFactory = widgetFactory; this.widgetFactory = widgetFactory;
/** @type {JQuery} */
this.$parent = null;
this.widgets = {}; this.widgets = {};
} }
renderTo($parent) { doRender() {
this.$parent = $parent; this.$widget = $(`<div class="marker" style="display: none;">`);
return this.$widget;
} }
activeTabChangedListener() { activeTabChangedListener() {
@ -26,7 +25,7 @@ export default class TabCachingWidget extends TabAwareWidget {
if (!widget) { if (!widget) {
widget = this.widgets[this.tabContext.tabId] = this.widgetFactory(); widget = this.widgets[this.tabContext.tabId] = this.widgetFactory();
this.children.push(widget); this.children.push(widget);
widget.renderTo(this.$parent); this.$widget.after(widget.render());
widget.eventReceived('setTabContext', {tabContext: this.tabContext}); widget.eventReceived('setTabContext', {tabContext: this.tabContext});
} }