π Collaborative document editing!
- π Simple focused writing: No distractions, only the formatting you need.
- π Work together: Share and collaborate with friends and colleagues, no matter if they use Nextcloud or not!
- πΎ Open format: Files are saved as Markdown, so you can edit them from any other text app too.
- β Strong foundation: We use π tiptap which is based on π¦ ProseMirror β huge thanks to them!
Nextcloud Text is the default text editor since Nextcloud 17. To start editing just open an existing markdown or plaintext file or create a new one.
The rich workspaces in the file list can be disabled either by the users in the files app settings or globally by the admin with the following occ command:
occ config:app:set text workspace_available --value=0
The app can be configured to open files read-only by default. This setting is globally valid and can be set by the admin with the following command:
occ config:app:set text open_read_only_enabled --value=1
This app requires the main branch of the Viewer app to be installed and enabled. Follow its development setup and then continue here.
- β Clone this app into the
apps
folder of your Nextcloud:git clone https://github.com/nextcloud/text.git
- π©βπ» In the folder of the app, run the command
make
to install dependencies and build the Javascript. - β Enable the app through the app management of your Nextcloud
- π Partytime! Help fix some issues and review pull requests π
To use the advantages of vite serve
with hot module replacement (HMR) and not have to recompile the JS assets after each code change, do the following:
- Configure your webserver to redirect requests to
/apps/text/
to the vite serve server. When using nextcloud-docker-dev, add the following snippet todata/nginx/vhost.d/nextcloud.local
and restart the proxy container. You might have to replace/apps/text/
with e.g./apps-extra/text/
depending on where the text app resides in your dev setup.location /apps/text/ { proxy_pass http://host.docker.internal:5173/apps/text/; # fallback to nextcloud server if vite serve doesn't answer error_page 502 = @fallback; } location @fallback { proxy_pass http://nextcloud.local; }
- Run
npm run serve
to start the vite serve server. If text resides somewhere else than/apps/text
, run e.g.BASE=/apps-extra/text npm run serve
.
Afterwards all changes to the code will apply to the application in your browser automatically thanks to hot module replacement (HMR).
To build the Javascript whenever you make changes, instead of the full make
you can also run npm run build
. Or run npm run watch
to rebuild on every file save.
Currently, this app uses three different kinds of tests:
For testing the backend (PHP) Psalm and PHPUnit are used,
you can run the testcases (placed in tests/
) using the composer scripts psalm
and test:unit
.
For testing the frontend jest is used for unittests, whereas cypress is used for end2end testing.
The unittests are also placed in src/tests/
, the cypress tests are placed in cypress/
.
You can run the tests using the package scripts npm run test
(jest), and respective npm run test:cypress
(cypress).
Please note the cypress tests require a nextcloud server running, the if no running server is detected a docker container will be started,
this requires the current user to be in the docker
group.
Or you might set the CYPRESS_baseUrl
environment variable for a custom nextcloud server.
- The mime type needs to be known by Nextcloud server (see nextcloud/server#24488 for how this can be added)
- Once that is there, please open a pull request to add them to
Lines 35 to 61 in 12df66f
- You can test them like other mime types in cypress/e2e/files.spec.js
In order to load the editor in your app, you'll need to dispatch an event.
use OCA\Text\Event\LoadEditor;
// ...
if (class_exists(LoadEditor::class)) {
$this->eventDispatcher->dispatchTyped(new LoadEditor());
}
Make sure to check if OCA.Text is available as the Text app needs to be enabled. If you want your app to work without Text being installed, you will need to provide an editor fallback on your own.
window.OCA.Text.createEditor({
el: document.getElementById('my-editor-div'),
fileId: 12345,
filePath: '/Readme.md',
}).then((editor) => {
// Once ready you can access the editor instance and call methods like:
editor.setContent('new content') // Beware: this will overwrite the content read from the source file
editor.setReadOnly(true)
editor.insertAtCursor('<h1>Heading</h1>')
// Make sure to destory the editor instance once you remove the dom element
editor.destroy()
})
window.OCA.Text.createEditor({
el: document.getElementById('my-editor-div'),
content: 'initial content',
}).then((editor) => {
// Once ready you can access the editor instance and call methods like:
editor.setContent('new content')
editor.setReadOnly(true)
editor.insertAtCursor('<h1>Heading</h1>')
// Make sure to destory the editor instance once you remove the dom element
editor.destroy()
})