2024-05-03 18:53:07 +03:00
<!--
- SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
2019-05-14 10:41:07 +03:00
# Nextcloud Text
2024-06-16 20:16:43 +03:00
[![REUSE status ](https://api.reuse.software/badge/github.com/nextcloud/text )](https://api.reuse.software/info/github.com/nextcloud/text)
2023-01-16 18:28:51 +03:00
![GitHub Workflow Status ](https://img.shields.io/github/actions/workflow/status/nextcloud/text/node.yml?branch=main )
2019-08-20 13:44:42 +03:00
[![Start contributing ](https://img.shields.io/github/issues/nextcloud/text/good%20first%20issue?color=7057ff&label=Contribute )](https://github.com/nextcloud/text/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22good+first+issue%22)
2019-08-20 13:37:45 +03:00
2019-06-07 18:57:30 +03:00
**📑 Collaborative document editing!**
2019-06-27 12:03:17 +03:00
![](img/screenshots/screenshot1.png)
2019-06-07 18:57:30 +03:00
2021-05-21 15:28:13 +03:00
## Features
2021-05-21 16:05:14 +03:00
- **📝 Simple focused writing:** No distractions, only the formatting you need.
2019-06-07 18:57:30 +03:00
- **🙋 Work together:** Share and collaborate with friends and colleagues, no matter if they use Nextcloud or not!
- **💾 Open format:** Files are saved as [Markdown ](https://en.wikipedia.org/wiki/Markdown ), so you can edit them from any other text app too.
2022-12-18 22:03:25 +03:00
- **✊ Strong foundation:** We use [🐈 tiptap ](https://tiptap.dev ) which is based on [🦉 ProseMirror ](https://prosemirror.net ) – huge thanks to them!
2019-06-07 18:57:30 +03:00
2021-05-21 15:28:13 +03:00
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.
2019-05-14 10:41:07 +03:00
2021-03-09 18:56:22 +03:00
## Configuration
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:
2021-05-21 15:28:13 +03:00
```bash
2021-03-09 18:56:22 +03:00
occ config:app:set text workspace_available --value=0
```
2019-05-14 18:13:23 +03:00
## 🏗 Development setup
2019-05-14 10:41:07 +03:00
2023-10-20 09:25:33 +03:00
This app requires the main branch of the [Viewer app ](https://github.com/nextcloud/viewer ) to be installed and enabled.
Follow its development setup and then continue here.
2019-05-14 10:41:07 +03:00
2019-05-14 18:13:23 +03:00
1. ☁ Clone this app into the `apps` folder of your Nextcloud: `git clone https://github.com/nextcloud/text.git`
2. 👩💻 In the folder of the app, run the command `make` to install dependencies and build the Javascript.
3. ✅ Enable the app through the app management of your Nextcloud
4. 🎉 Partytime! Help fix [some issues ](https://github.com/nextcloud/text/issues ) and [review pull requests ](https://github.com/nextcloud/text/pulls ) 👍
### 🧙 Advanced development stuff
2023-02-01 18:26:05 +03:00
2019-05-14 18:13:23 +03:00
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.
2021-03-09 18:56:22 +03:00
2022-06-01 22:58:06 +03:00
#### 🐞 Testing the app
2023-02-01 18:26:05 +03:00
Currently, this app uses three different kinds of tests:
2022-06-01 22:58:06 +03:00
For testing the backend (PHP) [Psalm ](https://psalm.dev/ ) and [PHPUnit ](https://phpunit.de/ ) are used,
you can run the testcases (placed in `tests/` ) using the composer scripts `psalm` and `test:unit` .
For testing the frontend [jest ](https://jestjs.io/ ) is used for unittests, whereas [cypress ](https://www.cypress.io/ ) is used for end2end testing.
2022-12-08 21:25:36 +03:00
The unittests are also placed in `src/tests/` , the cypress tests are placed in `cypress/` .
2022-06-01 22:58:06 +03:00
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.
2022-12-08 21:25:36 +03:00
Or you might set the `CYPRESS_baseUrl` environment variable for a custom nextcloud server.
#### Adding support for other mime types
- The mime type needs to be known by Nextcloud server (see https://github.com/nextcloud/server/pull/24488 for how this can be added)
- Once that is there, please open a pull request to add them to https://github.com/nextcloud/text/blob/12df66ffdd3d71cc696438e2e4ec60fa17b89a64/src/helpers/mime.js#L35-L61
- You can test them like other mime types in cypress/e2e/files.spec.js
2023-01-28 13:22:44 +03:00
## 🛠️ Integrate text in your app
## Load the editor
In order to load the editor in your app, you'll need to dispatch an event.
```php
2024-06-18 13:46:17 +03:00
use OCA\Text\Event\LoadEditor;
// ...
2023-01-28 13:22:44 +03:00
if (class_exists(LoadEditor::class)) {
$this->eventDispatcher->dispatchTyped(new LoadEditor());
}
```
### Integrate a file editor
2023-02-01 18:26:05 +03:00
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.
2023-01-28 13:22:44 +03:00
2023-02-01 18:26:05 +03:00
```js
2023-01-28 13:22:44 +03:00
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:
2023-02-01 18:26:05 +03:00
editor.setContent('new content') // Beware: this will overwrite the content read from the source file
2023-01-28 13:22:44 +03:00
editor.setReadOnly(true)
editor.insertAtCursor('< h1 > Heading< / h1 > ')
// Make sure to destory the editor instance once you remove the dom element
editor.destroy()
})
```
### Markdown based content editor
2023-02-01 18:26:05 +03:00
```js
2023-01-28 13:22:44 +03:00
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()
})
```