/* DokuWiki MoaiEditor Layout_desktop.js file Version : 0.5 (May 5, 2026) Author : MoaiTools License : GPL 3 (http://www.gnu.org/licenses/gpl.html) */ /* Desktop layout class ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ This class handles the desktop layout. Layout ‾‾‾‾‾‾ body -- #moaied__wrapper -- Semitransparent overlay #moaied__tplsidebar -- Container for editor (and optionally the template sidebar as well) #moaied__editor -- Container for the editor itself ┌─ #moaied__wrapper ┌─ #moaied__editor │ │ ┌──┴──┏━━━━━━┓┏━━━━━━━━━━━━━━━━━━┴━━━━━━┓─────┐ │/ / /┃ ┃┃ ┃/ / /│ │/ / /┃ ┃┃ ┃/ / /│ │/ / /┃ ┃┃ ┃/ / /│ │/ / /┃ ┃┃ ┃/ / /│ │/ / /┃ ┃┃ ┃/ / /│ │/ / /┃ ┃┃ ┃/ / /│ │/ / /┃ ┃┃ ┃/ / /│ │/ / /┃ ┃┃ ┃/ / /│ │/ / /┃ ┃┃ ┃/ / /│ │/ / /┃ ┃┃ ┃/ / /│ └─────┗━━━┬━━┛┗━━━━━━━━━━━━━━━━━━━━━━━━━┛─────┘ │ └─ #moaied__tplsidebar (the template's sidebar) */ MoaiEditor.LayoutDesktop = class { constructor(layout) { // Arguments this.layout = layout; // Settings this.settings = { default: { show_edit_summary:false, show_optional_buttons:false} }; // Variables this.show_edit_summary = this.settings.default.show_edit_summary; this.show_optional_buttons = this.settings.default.show_optional_buttons; } // ──────────────────────────────────── deactivate () { // Remove the right sidebar from the panes container this.sidebar.remove(); // Unhide all buttons const buttons = document.querySelectorAll(".moaied-button"); for (let button of buttons) button.classList.remove('moaied-display-none'); // Remove editor padding this.layout.editor.style.paddingLeft = ''; this.layout.editor.style.paddingRight = ''; // Unhide edit summary this.show_edit_summary = true; this.setEditSummaryVisibility(); } // ──────────────────────────────────── activate () { // Handles const editor = this.layout.editor; const elements = this.layout.elements; // Editor layout this.row1 = moaiEditor.createHTML('
'); // Page location, MoaiEditor buttons this.row2 = moaiEditor.createHTML('
'); // Toolbar buttons, edit-summary input fields this.paneswrapper = moaiEditor.createHTML('
'); // This div allows us to scroll the panes horizontally in single pane view this.footer = moaiEditor.createHTML(''); // Footer row editor.appendChild(this.row1); editor.appendChild(this.layout.msgarea); editor.appendChild(this.row2); editor.appendChild(this.paneswrapper); editor.appendChild(this.footer); editor.appendChild(this.layout.indicatorScrolling); this.paneswrapper.appendChild(this.layout.panes); // Setup Dokuwiki page-tools (currently we are not showing it but someone might want it back in the future) //this.setupPageTools(); // ──────────────── Row 1 ──────────────────── // Left, center and right this.topleft = moaiEditor.createHTML('
'); // Back button and document id this.toc = moaiEditor.toc.container; // Table of contents this.toc.classList.remove('phone'); this.buttons = moaiEditor.createHTML('
'); // Editor buttons this.row1.appendChild(this.topleft); this.row1.appendChild(this.toc); this.row1.appendChild(this.buttons); // Back button this.topleft.appendChild(moaiEditor.buttons.back.handle); // Page id this.topleft.appendChild(this.layout.pageid); // Editor buttons var names = [ 'preview', 'livepreview', 'partialpreview', 'autoscroll', 'sep', 'divider_moveleft', 'divider_moveright', 'panes', 'sep', 'settings', 'fullwidth', 'enabled', 'sep', 'save', 'cancel', ]; this.layout.addButtons (this.buttons, names); // ──────────────── Row 2 ──────────────────── // Left and right this.row2left = moaiEditor.createHTML('
'); this.row2right = moaiEditor.createHTML('
'); this.row2.appendChild(this.row2left); this.row2.appendChild(this.row2right); // Default Dokuwiki toolbar this.toolbar = elements.toolbar; this.row2left.appendChild(this.toolbar); // Edit summary this.row2right.appendChild(this.layout.summary); // ──────────────── Side ──────────────────── // Sidebar buttons this.btn_options = this.layout.createSidebarButton ('options', 'More options', this.toggleButtonsVisibility.bind(this) ); this.btn_scrollhrz = this.layout.createSidebarButton ('arrowhrz', 'Toggle preview', this.toggleHorizontalScroll.bind(this) ); this.btn_editsummary = this.layout.createSidebarButton ('summary', 'Edit summary', this.toggleEditSummaryVisibility.bind(this) ); // Sidebar this.sidebar = moaiEditor.createHTML('
'); // Sidebar with buttons (on the right) this.row2.appendChild(this.sidebar); this.sidebar.appendChild(this.btn_options); this.sidebar.appendChild(this.btn_scrollhrz); this.sidebar.appendChild(this.btn_editsummary); this.sidebar.appendChild(this.layout.btn_editor); this.sidebar.appendChild(this.layout.btn_linewrap); this.sidebar.appendChild(this.layout.btn_fullscreen); this.sidebar.appendChild(this.layout.btn_scrolltop); this.sidebar.appendChild(this.layout.btn_scrollbottom); // Bottom right container (for logo, codemirror menu, etc) this.footer.appendChild(this.layout.bottomRight); // ──────────────── Footer ──────────────────── // Footer this.footerLeft = moaiEditor.createHTML(''); this.docinfo = moaiEditor.createHTML('
 
'); this.footer.appendChild(this.footerLeft); this.footer.appendChild(this.docinfo); // Docinfo (will not exist when creating a document) const data = JSINFO.plugin_moaieditor.docinfo; if (data !== null) { const path = ''+data.labelPath+':  '+data.path+''; const mod = ''+data.labelMod+'  '+data.time+'  '+data.by+''; this.docinfo.innerHTML = path + '  ·  ' + mod; } // ────────────────── Hints ───────────────────── this.hint_scrollhrz_btn = new MoaiEditor.Hint('arrow-right', 'Click me', this.btn_scrollhrz, 40, 2); this.hint_scrollhrz_bar = new MoaiEditor.Hint('arrow-corner-left-down', 'Drag the scroll bar', this.footer, 200, 52); // ────────────── Other things ────────────────── this.updatePanesLayout(); // Update the panes layout (side-by-side, top-bottom, single-pane) this.setButtonsVisibility(); // Hide or show the optional buttons at the top this.setEditSummaryVisibility(); // Hide or show the edit summary input fields moaiEditor.buttons.updateDivider(); // Update the panel divider position } // ──────────────────────────────────── onClickPanesBtn() { const mode = moaiEditor.buttons.panes.mode; // Show or hide hints this.hint_scrollhrz_btn.disable(); this.hint_scrollhrz_bar.disable(); if (mode == 'single') { this.hint_scrollhrz_btn.start(); this.hint_scrollhrz_bar.start(); } // Update the layout this.updatePanesLayout(); } // ──────────────────────────────────── updatePanesLayout() { // Handles const mode = moaiEditor.buttons.panes.mode; const wrapper = document.body.querySelector('#moaied__panes_wrapper'); const panes = document.body.querySelector('#moaied__panes'); const btn_moveleft = moaiEditor.buttons.divider_moveleft; const btn_moveright = moaiEditor.buttons.divider_moveright; // Set single or dual pane layout if (wrapper) { wrapper.classList.remove('moaied-single-pane'); if (mode == 'single') wrapper.classList.add('moaied-single-pane'); } // In dual pane layout, adjust the orientation of the panes (side-by-side, top-bottom) by controlling 'flex-direction' if (panes) { panes.classList.remove('column'); if (mode == 'column') panes.classList.add('column'); } // Update the icons of the divider adjustment buttons (to show the correct layout) if (mode != 'single') { btn_moveleft.mode = mode; btn_moveright.mode = mode; } // In single pane layout btn_moveleft.handle.classList.remove('moaied-display-none-secondary'); btn_moveright.handle.classList.remove('moaied-display-none-secondary'); this.btn_scrollhrz.classList.add('moaied-display-none'); if (mode == 'single') { // Hide the divider adjustment buttons (as they are not needed) btn_moveleft.handle.classList.add('moaied-display-none-secondary'); btn_moveright.handle.classList.add('moaied-display-none-secondary'); // Show the horizontal scroll toggle button (to toggle between editor and preview panes) this.btn_scrollhrz.classList.remove('moaied-display-none'); } // Set the maximum width depending on user settings and full-width button const userSettings = JSINFO.plugin_moaieditor; var maxwidth; if (mode == 'row') maxwidth = userSettings.editor_width_side_by_side; if (mode == 'column') maxwidth = userSettings.editor_width_top_bottom; if (mode == 'single') maxwidth = userSettings.editor_width_single_pane; if (moaiEditor.buttons.fullwidth.mode == 'on') maxwidth = 'none'; this.layout.editor.style.maxWidth = maxwidth; //console.warn(JSINFO.plugin_moaieditor); } // ──────────────────────────────────── toggleHorizontalScroll() { // Toggle between editor and preview pane in single pane layout mode (horizontal scroll) const scroll = this.paneswrapper.scrollLeft; const maxScroll = moaiEditor.scroll.tools.getMaxScrollX (this.paneswrapper); const threshold = maxScroll / 2; if (scroll > threshold) this.paneswrapper.scrollLeft = 0; else this.paneswrapper.scrollLeft = maxScroll+10; } // ──────────────────────────────────── toggleButtonsVisibility() { // Show or hide additional buttons at the top of the editor (blue and green buttons) this.show_optional_buttons = !this.show_optional_buttons; this.setButtonsVisibility(); } setButtonsVisibility() { // Hide or show the optional buttons at the top of the editor const show = this.show_optional_buttons; var element; var names = [ 'livepreview', 'partialpreview', 'autoscroll', 'settings', /*'enabled', 3*/ ]; for (let name of names) { if (typeof name === 'string') element = moaiEditor.buttons[name].handle; else element = document.getElementById('moaied__sep_'+name); if (show) element.classList.remove('moaied-display-none'); else element.classList.add('moaied-display-none'); } } // ──────────────────────────────────── toggleEditSummaryVisibility() { // Show or hide the edit-summary input fields (because many users don't use this feature) this.show_edit_summary = !this.show_edit_summary; this.setEditSummaryVisibility(); } setEditSummaryVisibility() { const summary = this.layout.summary; if (this.show_edit_summary) summary.classList.remove('moaied-display-none'); else summary.classList.add('moaied-display-none'); } // ──────────────────────────────────── onWindowResize() { this.adjustPaddings(); } // ──────────────────────────────────── adjustPaddings() { // var w = window.innerWidth; var h = window.innerHeight; // Horizontal padding var left = 10; var right = 40; if (w > 1200) { let extra = (w-1200)/40; left += extra; right += extra*.65; } this.layout.editor.style.paddingLeft = left + 'px'; this.layout.editor.style.paddingRight = right + 'px'; } }; // End Class