diff --git a/Assets/WebsiteAssets/images/sync_scroll/abst-sync-lp2.png b/Assets/WebsiteAssets/images/sync_scroll/abst-sync-lp2.png new file mode 100644 index 0000000000..2005be9061 Binary files /dev/null and b/Assets/WebsiteAssets/images/sync_scroll/abst-sync-lp2.png differ diff --git a/Assets/WebsiteAssets/images/sync_scroll/abst-wo-sync2.png b/Assets/WebsiteAssets/images/sync_scroll/abst-wo-sync2.png new file mode 100644 index 0000000000..3009a5f83f Binary files /dev/null and b/Assets/WebsiteAssets/images/sync_scroll/abst-wo-sync2.png differ diff --git a/Assets/WebsiteAssets/images/sync_scroll/md-editor-components-pr.png b/Assets/WebsiteAssets/images/sync_scroll/md-editor-components-pr.png new file mode 100644 index 0000000000..5e36ec1d5d Binary files /dev/null and b/Assets/WebsiteAssets/images/sync_scroll/md-editor-components-pr.png differ diff --git a/Assets/WebsiteAssets/images/sync_scroll/trans-e2l-l2v-2.png b/Assets/WebsiteAssets/images/sync_scroll/trans-e2l-l2v-2.png new file mode 100644 index 0000000000..369e7d65ce Binary files /dev/null and b/Assets/WebsiteAssets/images/sync_scroll/trans-e2l-l2v-2.png differ diff --git a/Assets/WebsiteAssets/images/sync_scroll/trans-v2l-l2e-2.png b/Assets/WebsiteAssets/images/sync_scroll/trans-v2l-l2e-2.png new file mode 100644 index 0000000000..574aac8add Binary files /dev/null and b/Assets/WebsiteAssets/images/sync_scroll/trans-v2l-l2e-2.png differ diff --git a/README.md b/README.md index b518695654..13c8fe69c3 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,7 @@ The Web Clipper is a browser extension that allows you to save web pages and scr - [End-to-end encryption spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/e2ee.md) - [Note History spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/history.md) - [Sync Lock spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync_lock.md) + - [Synchronous Scroll spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/sync_scroll.md) - [Plugin Architecture spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/plugins.md) - [Search Sorting spec](https://github.com/laurent22/joplin/blob/dev/readme/spec/search_sorting.md) - [Server: File URL Format](https://github.com/laurent22/joplin/blob/dev/readme/spec/server_file_url_format.md) diff --git a/readme/spec/sync_scroll.md b/readme/spec/sync_scroll.md new file mode 100644 index 0000000000..cd618c63ba --- /dev/null +++ b/readme/spec/sync_scroll.md @@ -0,0 +1,73 @@ +# Synchronous Scroll + +Since Joplin 2.6, the synchronous scroll feature (Sync Scroll) for two-pane Markdown Editor is introduced. This document describes its detail. + +## Motivation + +Joplin has two types of editors, two-pane Markdown Editor and WYSIWYG Editor. Two-pane Markdown Editor consists of an editor pane displaying a Markdown text (Editor) and a viewer pane displaying the rendered Markdown in HTML (Viewer). Both panes have independent scroll bars, and they were linked and controlled by single scroll position expressed as a relative percentage. + +![Abstraction View without Sync Scroll](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/sync_scroll/abst-wo-sync2.png) + +Since the height of a Markdown text line is not always proportional to the height of the corresponding HTML element, displayed contents in Editor and Viewer are often inconsistent. + +To keep the consistency of their displayed contents, both scroll bars needed to be controlled separatedly and synchronously. + +## Feature Specifications + +- Markdown Editor and Viewer scroll synchronously. + - If you scroll Editor, Viewer is scrolled synchronously. The DOM elements corresponding to Markdown lines you are looking at in Editor's viewport are located in Viewer's viewport as possible. + - The same applies in reverse. (Viewer -> Editor) + - During and after any operations, the consistency of scroll positions between Editor and Viewer is kept as possible. + +- Performance requirement: Since scrolling is a basic GUI operation, its overhead should be minimized. + +## Design + +### Abstraction View + +The following figure shows the abstraction view of Sync Scroll. To manage scroll positions, the percent of the line number of a Markdown text data ("percent" in the figure) is used. To handle GUI components and events, "percent" is translated from/to "ePercent" for Editor using translation function E2L() / L2E(). The same is true for Viewer. + +![Abstraction View with Sync Scroll](https://raw.githubusercontent.com/laurent22/joplin/dev/Assets/WebsiteAssets/images/sync_scroll/abst-sync-lp2.png) + +The reasons why "ePercent" is not directly translated from "vPercent" and vice versa are: +- Line-based "percent" is good for maintaining, because it is GUI-independent. Both "ePercent" and "vPercent" depend on GUI components and are affected by many factors such as image loading, window resizing, pane hiding/showing. +- Direct conversion between Editor and Viewer needs both Editor and Viewer are present. If one of them is hidden, the information needed for conversion cannot be acquired. +- Editor and Viewer run in different processes, so separation between them makes things simpler and reduces timing issues. + +### Components and Data Interactions + +The next figure shows the components and data interactions related to Markdown Editor and Sync Scroll. + +First, underlying Markdown Editor is explained. Editor is implemented using [CodeMirror](https://codemirror.net/), and it provides the translation capability between line numbers of Markdown text and their pixel positions in Editor. A Markdown text being edited in Editor is converted to an HTML text using [MarkdownIt](https://github.com/markdown-it/markdown-it), and it is rendered by Viewer, which is implemented using [Electron's `