Also rename `initialLoading` in `EditorWrapper` to `contentLoaded`.
This flag is set during the `initialLoading` state change.
It does indicates that the loading happened
Use the past tense to indicate that.
The editor wrapper is now loading in different steps.
The menus will load after the content.
So `content` seems more fitting then `initial`.
Signed-off-by: Max <max@nextcloud.com>
Rendering the menubar and menububble takes a significant amount of time.
First display the content and then render the menus.
Signed-off-by: Max <max@nextcloud.com>
Do not show the spinning wheel unless the file actually changed.
* Resolves#2215.
* Targets: master.
Opening Readme.md in the sidebar triggers a PROPFIND.
We parse its response just like the initial file list load.
Readme.md is part of the response and our handler attempts to open it.
Only set the vm.ready if the file actually changed.
Only a changed file will make the editor load again.
Only then will it set ready to true and stop the spinning wheel.
Signed-off-by: Max <max@nextcloud.com>
See #2018.
Use tiptap TaskList and TaskItem.
Markdown-it happily mixes tasks and bullet points in the same list.
Tiptap lists are strictly separated.
Split bullet and tasks into BulletList and TaskList in markdown-io.
Just like this will turn into three different lists:
* one
- two
+ three
This will now also turn into three different lists
with the middle one being a task list:
* first list
* [ ] todo
* [x] done
* third list
Signed-off-by: Max <max@nextcloud.com>
Cypress tests were failing because they triggered editor.focus on a read only doc.
Focus seems to cause sendable steps - maybe because the current cursor changes.
Prevent this on various levels:
* Do not autofocus read only docs.
* Do not send steps to read only docs.
* Handle server response with 403 without content gracefully when sending steps.
The last originated here:
https://github.com/nextcloud/text/blob/master/lib/Service/ApiService.php#L158
So wither the session was not valid or the document read only.
Not entirely sure what best to do in this situation.
Logging to console.error for now.
Signed-off-by: Max <max@nextcloud.com>
In public shares data did not include a name if i remember correctly.
When the Readme gets created it will trigger a PROPFIND
but that will only look for the Readme itself - not the entire directory.
Also detect that Readme so the view gets updated
and shows the rich workspace when a Readme.md is created.
This covers the main usecase that people click on the empty workspace.
It does not cover creating a localized readme file
or one named README.md or so.
We also did not cover that before - so this seems okay.
Signed-off-by: Max <max@nextcloud.com>
See #2171.
Even though this is meant to improve load times
I did not observe any improvements locally.
I suspect that is because the workspace was loaded in parallel with the PROPFIND anyway.
Experience may differ in production environments obviously.
It is still one request less and the code also seems more clean.
Signed-off-by: Max <max@nextcloud.com>
* Autofix `vue/first-attribute-linebreak`.
* Explicitely import `Store` from `vuex`.
* Allow importing default with the same name as named for tiptap extensions.
This is the way used in tiptap documentation:
`import Document from '@tiptap/extension-document'`
Disable `import/no-named-as-default` - but only for the lines in question.
Signed-off-by: Max <max@nextcloud.com>
Navigating the suggestion list via arrow up/down keys is handled in
javascript, so we have to handle the scrolling in javascript too.
Only scrolls if the new selected item has not visible before.
At ArrowDown, scroll bottom of visible area to lower border of item.
At ArrowUp, scroll top of visible area to upper border of item.
Signed-off-by: Jonas <jonas@freesources.org>
Adds emoji autocompletion by typing `:<search_string>`.
It utilizes the emoji functions from nextcloud-vue[1] and the TipTap
suggestions extension.
[1] https://github.com/nextcloud/nextcloud-vue/pull/1474
Signed-off-by: Jonas <jonas@freesources.org>
* Make list items in ordered lists still show numbers.
* Use the same bullets on second and third level when first level is ol.
Signed-off-by: Max <max@nextcloud.com>
Tiptap v2 changed some defaults for the keyboard shortcuts.
* use new default ctrl+shift+X for strike through.
Old ctrl+d is used to create bookmarks in firefox.
* Keep old ctrl+shift+1 ... ctrl+shift+6 for headings.
No reason to change as far as i can tell.
Also more consistent with lists (ctrl+shift+7/8).
* Change ordered lists to ctrl+shift+7.
New default from tiptap.
This way it comes right after the headings.
Signed-off-by: Max <max@nextcloud.com>
Either handle network errors or the response.
There are three ways to handle errors and responses with axios:
```
axios.post(...).then(...).catch(...)
axios.post(...).catch(...).then(...)
axios.post(...).then(onResponse, onErr)
```
Use the last one.
First one will catch errors triggered by the emits in the happy path
with the network error handling.
Second one will handle the response,
even if errors have been caught.
Signed-off-by: Max <max@nextcloud.com>
Lowlight 2.4.1 was causing failures with jest.
Jest was unhappy with it being an ESM module:
https://github.com/nextcloud/text/runs/5089748945
Do not hand around the lowlight global between EditorFactory and EditorWrapper.
Tiptaps CodeBlockLowLight does not need it anyway.
Signed-off-by: Max <max@nextcloud.com>
Migrate the entire editor to tiptap v2.
Some changes were introduces that go beyond just using the new tiptap API:
*Collaboration*
Port tiptap1 collaboration.
We still want to use our session and sync mechanism.
*Serialization*
Add Markdown extension to handle serialization.
Tiptap config extensions are not automatically added
to the prosemirror schema anymore.
The extension adds the `toMarkdown` config value to the prosemirror schema.
With the new naming scheme tiptap nodes for a number of elements
do not match the prosemirror names.
Camelcase the marks and nodes from `defaultMarkdownSerializer`
so they match the tiptap names.
*Menubar*
* Specify args for isActive function directly rather than setting a function.
* Make use of the editor instance inside the MenuBar component.
* Use the editor rather than slots for command, focused etc.
* disable icons based on editor.can
* Show menubar as long as submenus are open.
When opening a submenu of the menubar
keep track of the open menu even for the image and the remaining action menu.
Also refocus the editor whenever a submenu is closed.
*MenuBubble*
Let tippy handle the positioning
Tippy is really good at positioning the menu bubble.
Remove all our workarounds and let it do its thing.
In order for this to work the content of the MenuBubble
actually needs to live inside the tippy-content.
Tippy bases its calculations on the width of tippy-content.
So if we have the content hanging in a separate div
with absolute positioning
tippy-content will be 0x0 px and not represent the actual width
of the menu bubble.
*Upgrade image node and ImageView.*
Quite a bit of the syntax changed.
We now need a wrapping `<node-view-wrapper>` element.
Pretty good docs at https://tiptap.dev/guide/node-views/vue#render-a-vue-component
We also need to handle the async action.
It will run the action on it's own.
So in `clickIcon()` we need to test if the action returned anything.
Tiptap v1 had inline images.
v2 keeps them outside of paragraphs by default.
Configure Image node to use inline images as markdownit creates inline images right now.
*Trailing Node*
Tiptap v2 does not ship the trailing node extension anymore.
Included the one from the demos and turned it from typescript into javascript.
*Tests*
In order to isolate some problems tests were added.
The tests in Undeline.spec.js were green right from the beginning.
They are not related to the fix and only helped isolate the problem.
Also introduced a cypress test for Lists
that tests the editor
without rendering the page and logging in.
It is very fast and fairly easy to write.
*Refactorings*
* Split marks into separate files.
Signed-off-by: Max <max@nextcloud.com>
This fixes rich workspace loading when moving a Readme.md into a folder
and navigating into that folder.
The file.id stay the same, so no new components are created and RichWorkspace stays in an ready=false state because EditorWrapper never emit a new ready event.
Signed-off-by: Louis Chemineau <louis@chmn.me>
Signed-off-by: Julien Veyssier <eneiluj@posteo.net>
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>