Skip to content

Commit

Permalink
Desktop: Resolves #176: Added experimental WYSIWYG editor (#2556)
Browse files Browse the repository at this point in the history
* Trying to get TuiEditor to work

* Tests with TinyMCE

* Fixed build

* Improved asset loading

* Added support for Joplin source blocks

* Added support for Joplin source blocks

* Better integration

* Make sure noteDidUpdate event is always dispatched at the right time

* Minor tweaks

* Fixed tests

* Add support for checkboxes

* Minor refactoring

* Added support for file attachments

* Add support for fenced code blocks

* Fix new line issue on code block

* Added support for Fountain scripts

* Refactoring

* Better handling of saving and loading notes

* Fix saving and loading ntoes

* Handle multi-note selection and fixed new note creation issue

* Fixed newline issue in test

* Fixed newline issue in test

* Improve saving and loading

* Improve saving and loading note

* Removed undeeded prop

* Fixed issue when new note being saved is incorrectly reloaded

* Refactoring and improve saving of note when unmounting component

* Fixed TypeScript error

* Small changes

* Improved further handling of saving and loading notes

* Handle provisional notes and fixed various saving and loading bugs

* Adding back support for HTML notes

* Added support for HTML notes

* Better handling of editable nodes

* Preserve image HTML tag when the size is set

* Handle switching between editor when the note has note finished saving

* Handle templates

* Handle templates

* Handle loading note that is being saved

* Handle note being reloaded via sync

* Clean up

* Clean up and improved logging

* Fixed TS error

* Fixed a few issues

* Fixed test

* Logging

* Various improvements

* Add blockquote support

* Moved CWD operation to shim

* Removed deleted files

* Added support for Joplin commands
  • Loading branch information
laurent22 committed Mar 9, 2020
1 parent ab2c8e3 commit 84c3ef1
Show file tree
Hide file tree
Showing 61 changed files with 2,127 additions and 309 deletions.
7 changes: 7 additions & 0 deletions .eslintignore
Expand Up @@ -53,9 +53,16 @@ ReactNativeClient/lib/joplin-renderer/assets/
ReactNativeClient/lib/rnInjectedJs/

# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
ElectronClient/gui/editors/PlainEditor.js
ElectronClient/gui/editors/TinyMCE.js
ElectronClient/gui/MultiNoteActions.js
ElectronClient/gui/NoteContentPropertiesDialog.js
ElectronClient/gui/NoteText2.js
ElectronClient/gui/ResourceScreen.js
ElectronClient/gui/ShareNoteDialog.js
ElectronClient/gui/utils/NoteText.js
ReactNativeClient/lib/AsyncActionQueue.js
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fence.js
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.js
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/sanitize_html.js
ReactNativeClient/lib/JoplinServerApi.js
Expand Down
4 changes: 3 additions & 1 deletion .eslintrc.js
Expand Up @@ -32,6 +32,8 @@ module.exports = {
'browserSupportsPromises_': true,
'chrome': 'readonly',
'browser': 'readonly',

'tinymce': 'readonly',
},
'parserOptions': {
'ecmaVersion': 2018,
Expand All @@ -56,7 +58,7 @@ module.exports = {
// Checks rules of Hooks
"react-hooks/rules-of-hooks": "error",
// Checks effect dependencies
"react-hooks/exhaustive-deps": "error",
"react-hooks/exhaustive-deps": "warn",

// -------------------------------
// Formatting
Expand Down
7 changes: 7 additions & 0 deletions .gitignore
Expand Up @@ -50,9 +50,16 @@ Tools/commit_hook.txt
*.map

# AUTO-GENERATED - EXCLUDED TYPESCRIPT BUILD
ElectronClient/gui/editors/PlainEditor.js
ElectronClient/gui/editors/TinyMCE.js
ElectronClient/gui/MultiNoteActions.js
ElectronClient/gui/NoteContentPropertiesDialog.js
ElectronClient/gui/NoteText2.js
ElectronClient/gui/ResourceScreen.js
ElectronClient/gui/ShareNoteDialog.js
ElectronClient/gui/utils/NoteText.js
ReactNativeClient/lib/AsyncActionQueue.js
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fence.js
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/mermaid.js
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/sanitize_html.js
ReactNativeClient/lib/JoplinServerApi.js
Expand Down
50 changes: 34 additions & 16 deletions CliClient/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion CliClient/package.json
Expand Up @@ -55,7 +55,7 @@
"htmlparser2": "^4.1.0",
"image-data-uri": "^2.0.0",
"image-type": "^3.0.0",
"joplin-turndown": "^4.0.19",
"joplin-turndown": "^4.0.23",
"joplin-turndown-plugin-gfm": "^1.0.12",
"json-stringify-safe": "^5.0.1",
"jssha": "^2.3.0",
Expand Down Expand Up @@ -89,6 +89,7 @@
"query-string": "4.3.4",
"read-chunk": "^2.1.0",
"redux": "^3.7.2",
"relative": "^3.0.2",
"request": "^2.88.0",
"sax": "^1.2.4",
"server-destroy": "^1.0.1",
Expand Down
8 changes: 7 additions & 1 deletion CliClient/tests/HtmlToMd.js
Expand Up @@ -39,7 +39,9 @@ describe('HtmlToMd', function() {
const htmlPath = `${basePath}/${htmlFilename}`;
const mdPath = `${basePath}/${filename(htmlFilename)}.md`;

// if (htmlFilename !== 'table_with_header.html') continue;
// if (htmlFilename !== 'joplin_source_2.html') continue;

// if (htmlFilename.indexOf('image_preserve_size') !== 0) continue;

const htmlToMdOptions = {};

Expand All @@ -51,6 +53,10 @@ describe('HtmlToMd', function() {
htmlToMdOptions.anchorNames = ['first', 'second', 'fourth'];
}

if (htmlFilename.indexOf('image_preserve_size') === 0) {
htmlToMdOptions.preserveImageTagsWithSize = true;
}

const html = await shim.fsDriver().readFile(htmlPath);
let expectedMd = await shim.fsDriver().readFile(mdPath);

Expand Down
8 changes: 8 additions & 0 deletions CliClient/tests/MdToHtml.js
Expand Up @@ -80,4 +80,12 @@ describe('MdToHtml', function() {
}
}));

// it('should write CSS to an external file', asyncTest(async () => {
// const mdToHtml = new MdToHtml({
// fsDriver: shim.fsDriver(),
// tempDir: Setting.value('tempDir'),
// });

// }));

});
1 change: 1 addition & 0 deletions CliClient/tests/html_to_md/image_preserve_size_1.html
@@ -0,0 +1 @@
<img src=":/0415d61cc33e47afa6dde45948c3177a"/>
1 change: 1 addition & 0 deletions CliClient/tests/html_to_md/image_preserve_size_1.md
@@ -0,0 +1 @@
![](:/0415d61cc33e47afa6dde45948c3177a)
1 change: 1 addition & 0 deletions CliClient/tests/html_to_md/image_preserve_size_2.html
@@ -0,0 +1 @@
<img src=":/0415d61cc33e47afa6dde45948c3177a" width="500" height="500">
1 change: 1 addition & 0 deletions CliClient/tests/html_to_md/image_preserve_size_2.md
@@ -0,0 +1 @@
<img src=":/0415d61cc33e47afa6dde45948c3177a" width="500" height="500">
53 changes: 53 additions & 0 deletions CliClient/tests/html_to_md/joplin_checkboxes.html
@@ -0,0 +1,53 @@
<ul>
<li class="md-checkbox joplin-checkbox"><div class="checkbox-wrapper"><input type="checkbox" id="md-checkbox-7" onclick="
try {
if (this.checked) {
this.setAttribute('checked', 'checked');
} else {
this.removeAttribute('checked');
}
ipcProxySendToHost('checkboxclick:checked:0');
const label = document.getElementById(&quot;cb-label-md-checkbox-7&quot;);
label.classList.remove(this.checked ? 'checkbox-label-unchecked' : 'checkbox-label-checked');
label.classList.add(this.checked ? 'checkbox-label-checked' : 'checkbox-label-unchecked');
} catch (error) {
console.warn('Checkbox checked:0 error', error);
}
return true;
" checked="checked"><label id="cb-label-md-checkbox-7" for="md-checkbox-7" class="checkbox-label-checked">one</label></div></li>
<li class="md-checkbox joplin-checkbox"><div class="checkbox-wrapper"><input type="checkbox" id="md-checkbox-8" onclick="
try {
if (this.checked) {
this.setAttribute('checked', 'checked');
} else {
this.removeAttribute('checked');
}
ipcProxySendToHost('checkboxclick:unchecked:1');
const label = document.getElementById(&quot;cb-label-md-checkbox-8&quot;);
label.classList.remove(this.checked ? 'checkbox-label-unchecked' : 'checkbox-label-checked');
label.classList.add(this.checked ? 'checkbox-label-checked' : 'checkbox-label-unchecked');
} catch (error) {
console.warn('Checkbox unchecked:1 error', error);
}
return true;
"><label id="cb-label-md-checkbox-8" for="md-checkbox-8" class="checkbox-label-unchecked">two</label></div></li>
<li class="md-checkbox joplin-checkbox"><div class="checkbox-wrapper"><input type="checkbox" id="md-checkbox-9" onclick="
try {
if (this.checked) {
this.setAttribute('checked', 'checked');
} else {
this.removeAttribute('checked');
}
ipcProxySendToHost('checkboxclick:unchecked:2');
const label = document.getElementById(&quot;cb-label-md-checkbox-9&quot;);
label.classList.remove(this.checked ? 'checkbox-label-unchecked' : 'checkbox-label-checked');
label.classList.add(this.checked ? 'checkbox-label-checked' : 'checkbox-label-unchecked');
} catch (error) {
console.warn('Checkbox unchecked:2 error', error);
}
return true;
"><label id="cb-label-md-checkbox-9" for="md-checkbox-9" class="checkbox-label-unchecked">with <strong>bold</strong> text</label></div></li>
</ul>
3 changes: 3 additions & 0 deletions CliClient/tests/html_to_md/joplin_checkboxes.md
@@ -0,0 +1,3 @@
- [x] one
- [ ] two
- [ ] with **bold** text
1 change: 1 addition & 0 deletions CliClient/tests/html_to_md/joplin_source_1.html
@@ -0,0 +1 @@
<span class="joplin-editable"><pre class="joplin-source" data-joplin-source-open="$" data-joplin-source-close="$">katexcode</pre><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><msubsup><mo>∫</mo><mrow><mo>−</mo><mi mathvariant="normal">∞</mi></mrow><mi mathvariant="normal">∞</mi></msubsup><mover accent="true"><mi>f</mi><mo>^</mo></mover><mo stretchy="false">(</mo><mi>ξ</mi><mo stretchy="false">)</mo><mtext> </mtext><msup><mi>e</mi><mrow><mn>2</mn><mi>π</mi><mi>i</mi><mi>ξ</mi><mi>x</mi></mrow></msup><mtext> </mtext><mi>d</mi><mi>ξ</mi></mrow><annotation encoding="application/x-tex">f(x) = \int_{-\infty}^\infty \hat f(\xi)\,e^{2 \pi i \xi x} \,d\xi </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height: 1em; vertical-align: -0.25em;" data-mce-style="height: 1em; vertical-align: -0.25em;"></span><span class="mord mathdefault" style="margin-right: 0.10764em;" data-mce-style="margin-right: 0.10764em;">f</span><span class="mopen">(</span><span class="mord mathdefault">x</span><span class="mclose">)</span><span class="mspace" style="margin-right: 0.2777777777777778em;" data-mce-style="margin-right: 0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right: 0.2777777777777778em;" data-mce-style="margin-right: 0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height: 2.384573em; vertical-align: -0.970281em;" data-mce-style="height: 2.384573em; vertical-align: -0.970281em;"></span><span class="mop"><span class="mop op-symbol large-op" style="margin-right: 0.44445em; position: relative; top: -0.0011249999999999316em;" data-mce-style="margin-right: 0.44445em; position: relative; top: -0.0011249999999999316em;">∫</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height: 1.414292em;" data-mce-style="height: 1.414292em;"><span style="top: -1.7880500000000001em; margin-left: -0.44445em; margin-right: 0.05em;" data-mce-style="top: -1.7880500000000001em; margin-left: -0.44445em; margin-right: 0.05em;"><span class="pstrut" style="height: 2.7em;" data-mce-style="height: 2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mtight">∞</span></span></span></span><span style="top: -3.8129000000000004em; margin-right: 0.05em;" data-mce-style="top: -3.8129000000000004em; margin-right: 0.05em;"><span class="pstrut" style="height: 2.7em;" data-mce-style="height: 2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">∞</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height: 0.970281em;" data-mce-style="height: 0.970281em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right: 0.16666666666666666em;" data-mce-style="margin-right: 0.16666666666666666em;"></span><span class="mord accent"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height: 0.9578799999999998em;" data-mce-style="height: 0.9578799999999998em;"><span style="top: -3em;" data-mce-style="top: -3em;"><span class="pstrut" style="height: 3em;" data-mce-style="height: 3em;"></span><span class="mord mathdefault" style="margin-right: 0.10764em;" data-mce-style="margin-right: 0.10764em;">f</span></span><span style="top: -3.26344em;" data-mce-style="top: -3.26344em;"><span class="pstrut" style="height: 3em;" data-mce-style="height: 3em;"></span><span class="accent-body" style="left: -0.08332999999999999em;" data-mce-style="left: -0.08332999999999999em;"><span class="mord">^</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height: 0.19444em;" data-mce-style="height: 0.19444em;"><span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathdefault" style="margin-right: 0.04601em;" data-mce-style="margin-right: 0.04601em;">ξ</span><span class="mclose">)</span><span class="mspace" style="margin-right: 0.16666666666666666em;" data-mce-style="margin-right: 0.16666666666666666em;"></span><span class="mord"><span class="mord mathdefault">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height: 0.8991079999999999em;" data-mce-style="height: 0.8991079999999999em;"><span style="top: -3.1130000000000004em; margin-right: 0.05em;" data-mce-style="top: -3.1130000000000004em; margin-right: 0.05em;"><span class="pstrut" style="height: 2.7em;" data-mce-style="height: 2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">2</span><span class="mord mathdefault mtight" style="margin-right: 0.03588em;" data-mce-style="margin-right: 0.03588em;">π</span><span class="mord mathdefault mtight">i</span><span class="mord mathdefault mtight" style="margin-right: 0.04601em;" data-mce-style="margin-right: 0.04601em;">ξ</span><span class="mord mathdefault mtight">x</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right: 0.16666666666666666em;" data-mce-style="margin-right: 0.16666666666666666em;"></span><span class="mord mathdefault">d</span><span class="mord mathdefault" style="margin-right: 0.04601em;" data-mce-style="margin-right: 0.04601em;">ξ</span></span></span></span></span></span>
1 change: 1 addition & 0 deletions CliClient/tests/html_to_md/joplin_source_1.md
@@ -0,0 +1 @@
$katexcode$

0 comments on commit 84c3ef1

Please sign in to comment.