BookStackApp / BookStack

A platform to create documentation/wiki content built with PHP & Laravel
https://www.bookstackapp.com/
MIT License
14.99k stars 1.88k forks source link

Markdown editor: hide and/or resize the preview pane #2215

Closed marcvef closed 1 year ago

marcvef commented 4 years ago

Describe the feature you'd like I love the markdown mode. The preview pane while editing the markdown source pane is a nice touch. However, most of the time markdown is already readable enough that a preview pane is not necessary. I don't mind having it enabled when BookStack can use the full monitor screen size, but if I put the browser page on only the left/right half of the screen, the preview pane is quite obstructive because the source pane is only covering 1/4 of the screen.

It would be nice to have a button to simply disable the preview pane letting the source pane use 100% of the available screen width. Or even better yet, allow a slider between the panes to dynamically adjust the width of both to the point were either one can be completely hidden to view the other pane at 100% width.

I have been able to simply modify the DOM to achieve hiding the preview pane by deleting the preview pane node and adjusting the source pane width from 50% to 100%.

Describe the benefits this feature would bring to BookStack users Such a feature would benefit people with one monitor (such as laptops) who use BookStack on one half of the screen and another type of content on the other, e.g., to write notes while reading a PDF.

abulgatz commented 3 years ago

+1

In the meantime, here are two options:

UserStyle using Stylus that you can enable/disable to hide the preview pane:

#markdown-editor .markdown-editor-wrap {
    display: none;
}
#markdown-editor .markdown-editor-wrap.active {
    display: flex;
    width: 100%;
    max-width: 100%;
}

UserScript using Tampermonkey that allows resizing the two panes:

// ==UserScript==
// @name         BookStack Resize Markdown Panes
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Allow resizing of the two panes in Mardown editing modes
// @author       Adam Bulgatz
// @match        https://YOURDOMAIN.com/*
// @icon         https://www.google.com/s2/favicons?domain=YOURDOMAIN.com
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    const panes = document.getElementsByClassName("markdown-editor-wrap")

    for (let i = 0; i < panes.length; i++) {
        panes[i].style.width = "inherit";
        panes[i].style.maxWidth = "inherit";
    }

    const leftSide = panes[0];
    const rightSide = panes[1];

    leftSide.style.borderRight = "none";
    rightSide.style.borderLeft = "none";

    const resizer = document.createElement("div");
    resizer.className = "resizer";
    resizer.id = "dragMe";
    resizer.style.backgroundColor = "#ccc";
    resizer.style.cursor = "col-resize";
    resizer.style.height = "100%";
    resizer.style.width = "4px";

    rightSide.parentNode.insertBefore(resizer, rightSide)

    // From: https://htmldom.dev/create-resizable-split-views/

    // Query the element
    // const resizer = document.getElementById('dragMe');
    // const leftSide = resizer.previousElementSibling;
    // const rightSide = resizer.nextElementSibling;

    // The current position of mouse
    let x = 0;
    let y = 0;
    let leftWidth = 0;

    // Handle the mousedown event
    // that's triggered when user drags the resizer
    const mouseDownHandler = function(e) {
        // Get the current mouse position
        x = e.clientX;
        y = e.clientY;
        leftWidth = leftSide.getBoundingClientRect().width;

        // Attach the listeners to `document`
        document.addEventListener('mousemove', mouseMoveHandler);
        document.addEventListener('mouseup', mouseUpHandler);
    };

    const mouseMoveHandler = function(e) {
        // How far the mouse has been moved
        const dx = e.clientX - x;
        const dy = e.clientY - y;

        const newLeftWidth = (leftWidth + dx) * 100 / resizer.parentNode.getBoundingClientRect().width;
        const newRightWidth = 100 - newLeftWidth;
        leftSide.style.maxWidth = `calc(${newLeftWidth}% - 4px)`;
        rightSide.style.maxWidth = `calc(${newRightWidth}% - 4px)`;

        resizer.style.cursor = 'col-resize';
        document.body.style.cursor = 'col-resize';

        leftSide.style.userSelect = 'none';
        leftSide.style.pointerEvents = 'none';

        rightSide.style.userSelect = 'none';
        rightSide.style.pointerEvents = 'none';
    };

    const mouseUpHandler = function() {
        document.body.style.removeProperty('cursor');

        leftSide.style.removeProperty('user-select');
        leftSide.style.removeProperty('pointer-events');

        rightSide.style.removeProperty('user-select');
        rightSide.style.removeProperty('pointer-events');

        // Remove the handlers of `mousemove` and `mouseup`
        document.removeEventListener('mousemove', mouseMoveHandler);
        document.removeEventListener('mouseup', mouseUpHandler);
    };

    // Attach the handler
    resizer.addEventListener('mousedown', mouseDownHandler);
})();
noeltaillardat commented 3 years ago

Hi @abulgatz, The tips seems nice, however I can't see how I might be able to use it in my Bookstack instance (until now, I added little css styling & js scripts in the Custom HTML Head Content section of the Bookstack Settings... which can't be used for such dom manipulations). How did you use/implement this on your own Bookstack installation?

jacdyb commented 2 years ago

Hello, I fully agree, that would be a great to have a button to enable / disable preview. Resizing panes would be also great, but not so essential I think. @abulgatz, thanks for sharing your solution. I will try to test this if I will have some spare time :)

zachallaun commented 2 years ago

Would also love to be able to toggle the preview pane!

@ssddanbrown I’d be happy to take a crack at contributing this feature. Would you mind pointing me in the right direction for modifying the markdown editing view and any gotchas you might foresee? My plan would be:

Possible enhancement:

ssddanbrown commented 2 years ago

@zachallaun 👋

The preview is already collapsible, since this is handled for mobile mode. Hopefully should be able to just build on that. For a minor option such as this, I think using Browser LocalStorage to store the preference would be enough, especially as it may be device-dependent.

Let me know if you do proceed with this, and I'll assign you. I'm aiming to do some significant work to the markdown editor component, for upgrading CodeMirror, in the next release which would probably conflict but I can schedule around if needed, Might just mean I'd be chasing this up if taken on but not complete after a couple of weeks.

zachallaun commented 2 years ago

Thanks for getting back to me so quickly, @ssddanbrown! Don't assign me just yet as I don't want to be a blocker on any of the work you're doing until I can firmly commit. I'll look through the resources you linked later today and will get back to you!

ssddanbrown commented 1 year ago

From the changes in #3875 and 31c28be57a53bc543e34bdf113ecd64e8ee11ed1, there is now an editor control to toggle the display of the preview window. It is also possible drag the center divider to resize the panes to a maximum 80/20% split.

These changes will be part of the next feature release.