merge main into develop

This commit is contained in:
bdbch 2024-04-06 01:37:57 +02:00
commit 7213843951
150 changed files with 3301 additions and 536 deletions

View File

@ -31,7 +31,7 @@ jobs:
node-version: ${{ matrix.node-version }}
- name: Load cached dependencies
uses: actions/cache@v3.3.2
uses: actions/cache@v4.0.2
id: cache
with:
path: |
@ -140,7 +140,7 @@ jobs:
node-version: ${{ matrix.node-version }}
- name: Load cached dependencies
uses: actions/cache@v3.3.2
uses: actions/cache@v4.0.2
id: cache
with:
path: |

View File

@ -3,6 +3,41 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
### Bug Fixes
* Disallow only whitespace between markdown shortcuts delimiters ([#4866](https://github.com/ueberdosis/tiptap/issues/4866)) ([aa029fe](https://github.com/ueberdosis/tiptap/commit/aa029fe2242aeadc38555b2832df6ae1614c7d1d))
* **extension-link:** Avoid auto-linking partial text for invalid TLDs ([#4865](https://github.com/ueberdosis/tiptap/issues/4865)) ([4474d05](https://github.com/ueberdosis/tiptap/commit/4474d056daf9280ebb10b31f98bb000e953132e5))
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
### Bug Fixes
* mark nocookie youtube url as valid when parsing html ([#4883](https://github.com/ueberdosis/tiptap/issues/4883)) ([099e10d](https://github.com/ueberdosis/tiptap/commit/099e10df923d851dd866354e9abca331d995b65c))
* typecheck drag and clipboard events for testing environments ([bbee9a3](https://github.com/ueberdosis/tiptap/commit/bbee9a3c3090fa40bf366591682b42a3f6ec5f91))
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
### Bug Fixes
* fix test path ([21aa96d](https://github.com/ueberdosis/tiptap/commit/21aa96dee8deab1f439b7f655b8ed266a516a4cd))
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)

View File

@ -3,6 +3,33 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package tiptap-demos
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package tiptap-demos
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
### Bug Fixes
* fix test path ([21aa96d](https://github.com/ueberdosis/tiptap/commit/21aa96dee8deab1f439b7f655b8ed266a516a4cd))
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package tiptap-demos

View File

@ -1,12 +1,12 @@
{
"name": "tiptap-demos",
"version": "2.2.2",
"version": "2.2.5",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "tiptap-demos",
"version": "2.2.2",
"version": "2.2.5",
"dependencies": {
"@hocuspocus/provider": "^2.9.0",
"@lexical/react": "^0.11.1",

View File

@ -1,6 +1,6 @@
{
"name": "tiptap-demos",
"version": "2.2.2",
"version": "2.2.5",
"private": true,
"scripts": {
"start": "vite --host",

View File

@ -59,7 +59,7 @@ editor.commands.unsetStrike()
## Keyboard shortcuts
| Command | Windows/Linux | macOS |
| -------------- | ------------------------------- | --------------------------- |
| toggleStrike() | `Control` `Shift` `X` | `Cmd` `Shift` `X` |
| toggleStrike() | `Control` `Shift` `S` | `Cmd` `Shift` `S` |
## Source code
[packages/extension-strike/](https://github.com/ueberdosis/tiptap/blob/main/packages/extension-strike/)

View File

@ -67,6 +67,16 @@ Mention.configure({
}
})
```
### deleteTriggerWithBackspace
Toggle whether the suggestion character(s) should also be deleted on deletion of a mention node. Default is `false`.
```js
Mention.configure({
deleteTriggerWithBackspace: true
})
```
### suggestion
[Read more](/api/utilities/suggestion)

View File

@ -59,7 +59,7 @@ Default: `() => ({})`
### findSuggestionMatch
Optional param to replace the built-in regex matching of editor content that triggers a suggestion.
See [the
source](https://github.com/estrattonbailey/tiptap/blob/develop/packages/suggestion/src/findSuggestionMatch.ts#L18)
source](https://github.com/ueberdosis/tiptap/blob/main/packages/suggestion/src/findSuggestionMatch.ts#L18)
for more detail.
Default: `findSuggestionMatch(config: Trigger): SuggestionMatch`

View File

@ -0,0 +1,156 @@
---
tableOfContents: true
---
# Authentication and authorization in Collaboration
## Authentication in Collaboration
After setting up a collaborative editor in the installation guide, it's crucial to address authentication for longer-term use. The temporary JWT provided by Collaboration is only suitable for brief testing sessions.
### **Understanding JWT**
JWT, or JSON Web Token, is a compact, URL-safe means of representing claims to be transferred between two parties. The information in a JWT is digitally signed using a cryptographic algorithm to ensure that the claims cannot be altered after the token is issued. This digital signature makes the JWT a reliable vehicle for secure information exchange in web applications, providing a method to authenticate and exchange information.
### **Creating static JWT for testing**
For testing purposes, you might not want to set up a complete backend system to generate JWTs. In such cases, using online tools like http://jwtbuilder.jamiekurtz.com/ can be a quick workaround. These tools allow you to create a JWT by inputting the necessary payload and signing it with a secret key.
When using these tools, ensure that the "Key" field is replaced with the secret key from your [Collaboration settings](https://collab.tiptap.dev/apps/settings) page. You dont need to change any other information.
Remember, this approach is only recommended for testing due to security risks associated with exposing your secret key.
### **Generating JWTs for production environments**
For production-level applications, generating JWTs on the server side is a necessity to maintain security. Exposing your secret key in client-side code would compromise the security of your application. Heres an enhanced example using NodeJS for creating JWTs server-side:
```bash
npm install jsonwebtoken
```
```typescript
import jsonwebtoken from 'jsonwebtoken'
const payload = {
// The payload contains claims like the user ID, which can be used to identify the user and their permissions.
userId: 'user123'
}
// The 'sign' method creates the JWT, with the payload and your secret key as inputs.
const jwt = jsonwebtoken.sign(payload, 'your_secret_key_here')
// The resulting JWT is used for authentication in API requests, ensuring secure access.
// Important: Never expose your secret key in client-side code!
```
This JWT should be incorporated into API requests within the **`token`** field of your authentication provider, safeguarding user sessions and data access.
To fully integrate JWT into your application, consider setting up a dedicated server or API endpoint, such as **`GET /getCollabToken`**. This endpoint would dynamically generate JWTs based on a secret stored securely on the server and user-specific information, like document access permissions.
This setup not only enhances security but also provides a scalable solution for managing user sessions and permissions in your collaborative application.
Ensure the secret key is stored as an environment variable on the server, or define it directly in the server code. Avoid sending it from the client side.
A full server / API example is available [here](https://github.com/ueberdosis/tiptap-collab-replit/tree/main/src).
## **Authorization in Collaboration**
Setting up the right access controls is important for keeping your documents secure and workflows smooth in Tiptap Collaboration.
This part of the guide walks you through how to use JSON Web Tokens (JWTs) to fine-tune who gets to see and edit what. Whether you need to give someone full access, restrict them to certain documents, or block access entirely, we've got you covered with minimalistic examples.
### Allowing Full Access to Every Document
Omitting the `allowedDocumentNames` property from the JWT payload grants the user access to all documents. This is useful for users who need unrestricted access.
```typescript
import jsonwebtoken from 'jsonwebtoken';
const data = {};
const jwt = jsonwebtoken.sign(data, 'your_secret');
```
### **Limiting Access to Specific Documents**
To restrict a user's access to specific documents, include those document names in the `allowedDocumentNames` array within the JWT payload. This ensures the user can only access the listed documents.
```typescript
import jsonwebtoken from 'jsonwebtoken';
const data = {
allowedDocumentNames: ['user-specific-document-1', 'user-specific-document-2'],
};
const jwt = jsonwebtoken.sign(data, 'your_secret');
```
### Blocking Access to All Documents
To prohibit a user from accessing any documents, provide an empty array for `allowedDocumentNames` in the JWT payload. This effectively blocks access to all documents.
```typescript
import jsonwebtoken from 'jsonwebtoken';
const data = {
allowedDocumentNames: [],
};
const jwt = jsonwebtoken.sign(data, 'your_secret');
```
## Setting Read-Only Access
The `readonlyDocumentNames` property in your JWT setup plays a crucial role when you need to allow users to view documents without the ability to edit them. This feature is particularly useful in scenarios where you want to share information with team members for review or reference purposes but need to maintain the integrity of the original document.
By specifying document names in the `readonlyDocumentNames` array, you grant users read-only access to those documents. Users can open and read the documents, but any attempts to modify the content will be restricted. This ensures that sensitive or critical information remains unchanged while still being accessible for necessary personnel.
In this example, we grant read-only access to two documents, `annual-report-2024` and `policy-document-v3`. Users with this JWT can view these documents but cannot make any edits.
```typescript
import jsonwebtoken from 'jsonwebtoken';
const data = {
readonlyDocumentNames: ['annual-report-2024', 'policy-document-v3'],
};
const jwt = jsonwebtoken.sign(data, 'your_secret');
```
Incorporating the `readonlyDocumentNames` property into your JWT strategy enhances document security by ensuring that only authorized edits are made, preserving the integrity of your critical documents.
## Utilizing Wildcards for Flexible Document Access
Wildcards in JWTs offer a dynamic way to manage document access, allowing for broader permissions within specific criteria without listing each document individually. This method is particularly useful in scenarios where documents are grouped by certain attributes, such as projects, teams, or roles.
### Managing Project-Specific Documents
For teams working on multiple projects, it's essential to ensure that members have access only to the documents relevant to their current projects. By using project identifiers with wildcards, you can streamline access management.
```typescript
import jsonwebtoken from 'jsonwebtoken';
const data = {
allowedDocumentNames: ['project-alpha/*', 'project-beta/*'],
};
const jwt = jsonwebtoken.sign(data, 'your_secret');
```
In this example, users will have access to all documents under 'project-alpha' and 'project-beta', making it easier to manage permissions as new documents are added to these projects.
### Facilitating Role-Based Access Control
Role-based access control (RBAC) is a common requirement in many systems, where access needs to be granted based on the user's role within the organization. Wildcards allow for easy mapping of roles to document access patterns.
```typescript
import jsonwebtoken from 'jsonwebtoken';
const data = {
allowedDocumentNames: ['editors/*', 'contributors/*'],
};
const jwt = jsonwebtoken.sign(data, 'your_secret');
```
Here, users assigned as 'editors' or 'contributors' can access documents prefixed with their respective roles. This setup simplifies the process of updating access rights as roles change or new roles are added.

View File

@ -0,0 +1,68 @@
# What is Awareness in Collaboration
Awareness in Tiptap Collaboration, powered by Yjs, is helping you share real-time info on users' activities within a collaborative space. This can include details like user presence, cursor positions, and custom user states.
At its core, awareness utilizes its own Conflict-Free Replicated Data Type (CRDT) to ensure that this shared meta-information remains consistent and immediate across all users, without maintaining a historical record of these states.
You can read more about Awareness in the [Yjs documentation on awareness](https://docs.yjs.dev/getting-started/adding-awareness).
### Understanding provider events for awareness
Awareness updates trigger specific [provider events](https://tiptap.dev/docs/editor/collaboration/events) to develop interactive features based on user actions and presence:
- `awarenessUpdate`: This event signals that a user is active. It triggers without actual state changes, serving as a 'heartbeat' to inform others the user is in the document.
- `awarenessChange`: This event alerts you to any additions, updates, or deletions in the awareness state, reflecting both your local changes and those from remote users.
These events serve as hooks for integrating custom Awareness features.
## Integrating Basic Awareness
With your [collaborative environment](https://tiptap.dev/docs/editor/collaboration/install) set up, you're all set to integrate Awareness, which is natively supported by the Collaboration Provider.
To kick things off, update the Awareness state with any relevant information. For this guide, we'll use a user's name, cursor color, and mouse position as examples.
### Setting the awareness field
Let's assign a name, color, and mouse position to the user. This is just an example; feel free to use any data relevant to your application.
```typescript
// Set the awareness field for the current user
provider.setAwarenessField("user", {
// Share any information you like
name: "Kevin James",
color: "#ffcc00",
});
```
### Listening for changes
Set up an event listener to track changes in the Awareness states across all connected users:
```typescript
// Listen for updates to the states of all users
provider.on("awarenessChange", ({ states }) => {
console.log(states);
});
```
You can now view these updates in your browser's console as you move on to the next step.
### Tracking mouse movement
Next, we'll add an event listener to our app to track mouse movements and update the awareness' information accordingly.
```typescript
document.addEventListener("mousemove", (event) => {
// Share any information you like
provider.setAwarenessField("user", {
name: "Kevin James",
color: "#ffcc00",
mouseX: event.clientX,
mouseY: event.clientY,
});
});
```
Check your browser's console to see the stream of events as users move their mice.
### Next Steps
With basic Awareness in place, consider enhancing your setup with the [Collaboration Cursor](https://tiptap.dev/docs/editor/api/extensions/collaboration-cursor) extension. This extension adds cursor positions, text selections, and personalized details (such as names and colors) of all participating users to your editor.

View File

@ -0,0 +1,181 @@
# Backend Document Manipulation
Backend Document Manipulation allows developers to programmatically modify documents stored on the Collaboration server (On premises and Cloud).
This feature provides flexibility in document management, enabling updates through JSON, which is a simpler alternative to using Yjs methods directly.
The feature is fully compliant with Version history, and allows to track changes from users, as well as the Backend Document Manipulation feature.
:::warning Subscription required
This feature requires a valid Business or Enterprise subscription and a running [Tiptap Cloud instance](https://collab.tiptap.dev/).
:::
### Use Cases
Backend Document Manipulation enables a variety of use cases, such as:
- Live translation of document content.
- Server-side components, like executing an SQL query and displaying results.
- Automatic typo and grammar corrections.
- Version history integration and conflict-free merging of concurrent edits.
This powerful feature set allows for extensive customization and automation of document handling on the Tiptap platform, catering to a wide range of collaborative editing scenarios.
## Update Document
To update an existing document on the Collaboration server, you can use the `PATCH` method with the following API endpoint:
```bash
PATCH /api/documents/:identifier?format=:format
```
This endpoint accepts a Yjs update message and applies it to the specified document. The `format` query parameter specifies the format of the update and can be one of the following:
- `binary`: Directly using Yjs's `Y.encodeStateAsUpdate` method.
- `base64`: The binary state encoded as a Base64 string.
- `json`: Updates the document using JSON format (with some caveats, see below).
Upon successful update, the server will return HTTP status `204`. If the document does not exist, it will return `404`, and if the payload is invalid or the update cannot be applied, it will return `422`.
Example `curl` command to update a document:
```bash
curl --location --request PATCH 'https://YOUR_APP_ID.collab.tiptap.cloud/api/documents/DOCUMENT_NAME' \\
--header 'Authorization: YOUR_SECRET_FROM_SETTINGS_AREA' \\
--data '@yjsUpdate.binary.txt'
```
### Update via JSON
When updating via JSON, the server computes the difference between the current document state and the provided JSON, then internally calculates the required Yjs update to reach the target state.
To ensure precise updates, especially for node-specific changes, it is recommended to use the `nodeAttributeName` and `nodeAttributeValue` parameters. These can be generated by Tiptap's [UniqueID Extension](https://tiptap.dev/docs/editor/api/extensions/unique-id) or a custom implementation.
- `nodeAttributeName`: Configured as `attributeName` in the UniqueID extension.
- `nodeAttributeValue`: The unique value generated for the node to be updated.
From version 3.3.0 onwards, you can use `?mode=append` to append nodes to the document's JSON representation without altering existing content.
Omitting these parameters may result in overwriting any updates made between fetching the document and issuing the update call.
Here is an example of how to update a document using JSON:
```typescript
// Define the document name, secret, and application ID
const docName = ''
const secret = ''
const appId = '';
// Construct the base URL
const url = `https://${appId}.collab.tiptap.dev`
// Fetch the current document's JSON representation
const docJson = await axios.get(`${url}/api/documents/${docName}?format=json`, {
headers: {
Authorization: secret
},
})
// Extract the document's JSON content
const tiptapJson = docJson.data
const nodes = tiptapJson.content
// Find and log specific nodes using their unique identifiers
const query = nodes.find(n => n.attrs?.identifier === 'fe5c0789-85d9-4877-a2c3-bccf5d874866').content[0].text
const resultTable = nodes.find(n => n.attrs?.identifier === '246368b6-0746-4ca1-a16f-8d964aff4041')
console.log(`Query: ${query}`)
console.log(JSON.stringify(resultTable.content))
// Append new content to the result table node
resultTable.content.push({
// New table row content here
{
"type": "tableRow",
"content": [
{
"type": "tableCell",
"attrs": {
"colspan": 1,
"rowspan": 1
},
"content": [
{
"type": "paragraph",
"attrs": {
"textAlign": "left"
},
"content": [
{
"type": "text",
"text": "Jan"
}
]
}
]
},
{
"type": "tableCell",
"attrs": {
"colspan": 1,
"rowspan": 1
},
"content": [
{
"type": "paragraph",
"attrs": {
"textAlign": "left"
},
"content": [
{
"type": "text",
"text": "Thurau"
}
]
}
]
},
{
"type": "tableCell",
"attrs": {
"colspan": 1,
"rowspan": 1
},
"content": [
{
"type": "paragraph",
"attrs": {
"textAlign": "left"
},
"content": [
{
"type": "text",
"text": "jan@janthurau.de"
}
]
}
]
}
]
}
})
// Send the updated JSON back to the server to apply the changes
await axios.patch(`${url}/api/documents/${docName}?format=json`, tiptapJson, {
headers: {
Authorization: secret
}
})
```
## Create Document
To seed a new document on the Tiptap Collab server, use the `POST` method with the following endpoint:
```bash
POST /api/documents/:identifier?format=:format
```
The server will return HTTP status `204` for successful creation, `409` if the document already exists (you must delete it first to overwrite), and `422` if the action failed.
The `format` parameter accepts the same values as the update endpoint (`binary`, `base64`, or `json`).

View File

@ -0,0 +1,80 @@
# Runtime Configuration for Collaboration
This documentation provides a comprehensive guide to configuring collaboration settings at runtime in your application. These settings allow for flexible management of your collaboration environment without the need to restart your application.
## Collaboration Settings Overview**
Several `key` settings can be adjusted dynamically:
- **secret**: The secret key for JWT tokens, auto-generated upon first launch.
- **api_secret**: The secret for API calls, used in the Authorization header and auto-generated at first boot.
- **webhook_url**: Optional webhook URL for receiving callbacks.
- **authentication_disabled**: Toggle for enabling/disabling authentication (1 for disabled, 0 for enabled, with the default being 0).
- **name**: Optional instance name.
## Managing Settings via API
The collaboration platform offers a straightforward API for managing these settings:
### Creating or Overwriting Settings
To add or update settings, utilize the following API call:
```bash
curl --location --request PUT 'https://YOUR_APP_ID.collab.tiptap.cloud/api/admin/settings/:key' \
--header 'Authorization: YOUR_SECRET_FROM_SETTINGS_AREA'
```
*Replace `:key` with the setting key you wish to update.*
### Listing Current Settings
Retrieve a list of all current settings with this API request:
```bash
curl --location 'https://YOUR_APP_ID.collab.tiptap.cloud/api/admin/settings' \
--header 'Authorization: YOUR_SECRET_FROM_SETTINGS_AREA'
```
### Retrieving a Specific Setting
To fetch the value of a particular setting, use:
```bash
curl --location 'https://YOUR_APP_ID.collab.tiptap.cloud/api/admin/settings/:key' \
--header 'Authorization: YOUR_SECRET_FROM_SETTINGS_AREA'
```
### Updating a Specific Setting
Similar to creating settings, updating is done via:
```bash
curl --location --request PUT 'https://YOUR_APP_ID.collab.tiptap.cloud/api/admin/settings/:key' \
--header 'Authorization: YOUR_SECRET_FROM_SETTINGS_AREA'
```
### Deleting a Setting
To remove a setting, the following API call is used:
```bash
curl --location --request DELETE 'https://YOUR_APP_ID.collab.tiptap.cloud/api/admin/settings/:key' \
--header 'Authorization: YOUR_SECRET_FROM_SETTINGS_AREA'
```
## Server Performance Metrics
Gain insights into server performance and document statistics through the `/api/statistics` endpoint, providing data on total documents, peak concurrent connections, total connections over the last 30 days, and lifetime connection counts.
```bash
curl --location 'https://YOUR_APP_ID.collab.tiptap.cloud/api/statistics' \
--header 'Authorization: YOUR_SECRET_FROM_SETTINGS_AREA'
```
*Note: The total number of connections of the last 30 days and the lifetime connection count are presented as strings due to their representation as BIGINT internally.*
This dedicated documentation page aims to clarify the process of adjusting runtime settings for collaboration, ensuring developers can effectively manage their collaborative environments.

View File

@ -2,22 +2,25 @@
tableOfContents: true
---
# Management API
# Document Management API
In addition to the websocket protocol, each Tiptap Collab app comes with a REST API for managing
your documents. It's exposed directly from your Tiptap Collab app, so it's available at your custom
URL:
The Collaboration Management API provides a suite of RESTful endpoints for managing documents. This API facilitates document creation, listing, retrieval, updates, and deletion, along with the ability to duplicate documents for efficient content management.
Explore the [Postman Collection](https://www.postman.com/docking-module-explorer-14290287/workspace/tiptap-collaboration-public/collection/33042171-cc186a66-df41-4df8-9c6e-e91b20deffe5?action=share&creator=32651125) for a hands-on experience, allowing you to experiment with the REST API's capabilities.
## Accessing the Management API
The REST API is exposed directly from your Collaboration app, available at your custom URL:
`https://YOUR_APP_ID.collab.tiptap.cloud/`
Authentication is done using an API secret which you can find in
the [settings](https://collab.tiptap.dev/) of your Tiptap Collab app. The secret must be sent as
the [settings](https://collab.tiptap.dev/) of your Collaboration app. The secret must be sent as
an `Authorization` header.
If your document identifier contains a slash (`/`), just make sure to encode it as `%2F`, e.g.
using `encodeURIComponent`.
## Documents
## Document Operations
### Create Document
@ -167,73 +170,3 @@ await axios.post('https://YOUR_APP_ID.collab.tiptap.cloud/api/documents/somedoc-
},
})
```
## Settings
TiptapCollab has a few settings that can be configured at runtime (no restart needed):
| Key | Type | Editable | Description |
|-------------------------|--------|----------|------------------------------------------------------------------------------------------------------|
| secret | string | Yes | The secret used to sign JWT tokens ; auto-generated on first boot. |
| api_secret | string | Yes | The secret that is sent in API calls (as the `Authorization` header) ; auto-generated on first boot. |
| webhook_url | string | Yes | The webhook URL ; optional |
| authentication_disabled | string | Yes | Whether authentication is disabled. Must be 1 or 0 ; optional (default = 0) |
| name | string | Yes | The name of the instance ; optional |
### Create setting
If you want to create or overwrite settings, this is the API for it.
```bash
curl --location --request PUT 'https://YOUR_APP_ID.collab.tiptap.cloud/api/admin/settings/:key' \
--header 'Authorization: YOUR_SECRET_FROM_SETTINGS_AREA'
```
### List settings
All current settings can be retrieved with the GET /api/admin/settings call.
```bash
curl --location 'https://YOUR_APP_ID.collab.tiptap.cloud/api/admin/settings' \
--header 'Authorization: YOUR_SECRET_FROM_SETTINGS_AREA'
```
### Get setting
If you want to get a setting value, this is the API for it.
```bash
curl --location 'https://YOUR_APP_ID.collab.tiptap.cloud/api/admin/settings/:key' \
--header 'Authorization: YOUR_SECRET_FROM_SETTINGS_AREA'
```
### Update setting
If you want to create or overwrite settings, this is the API for it.
```bash
curl --location --request PUT 'https://YOUR_APP_ID.collab.tiptap.cloud/api/admin/settings/:key' \
--header 'Authorization: YOUR_SECRET_FROM_SETTINGS_AREA'
```
### Delete setting
If you want to delete settings, this is the API for it.
```bash
curl --location --request DELETE 'https://YOUR_APP_ID.collab.tiptap.cloud/api/admin/settings/:key' \
--header 'Authorization: YOUR_SECRET_FROM_SETTINGS_AREA'
```
## Get server statistics
You can get a few server statistics using the /api/statistics endpoint. We currently export the
total number of documents, the maximum concurrent connections (last 30 days), the total number of
connections (last 30 days) and the lifetime connection count.
Not that the last two values are exported as string, as they are internally a BIGINT.
```bash
curl --location 'https://YOUR_APP_ID.collab.tiptap.cloud/api/statistics' \
--header 'Authorization: YOUR_SECRET_FROM_SETTINGS_AREA'
```

View File

@ -0,0 +1,115 @@
---
tableOfContents: true
---
# What are provider events?
Events in Collaboration providers allow you to respond to various states and changes, such as successful connections or authentication updates. You can attach event listeners during the provider's initialization or add them later based on your application's needs.
## Key Events and their uses
| Event | Description |
| --- | --- |
| open | Triggered when the WebSocket connection is established. |
| connect | Occurs when the provider successfully connects to the server. |
| authenticated | Indicates successful client authentication. |
| authenticationFailed | Fires when client authentication fails. |
| status | Reflects changes in connection status. |
| message | Captures incoming messages. |
| outgoingMessage | Signals when a message is about to be sent. |
| synced | Marks the initial successful sync of the Y.js document. |
| close | Triggered when the WebSocket connection closes. |
| disconnect | Occurs upon provider disconnection. |
| destroy | Signifies the impending destruction of the provider. |
| awarenessUpdate | Tracks updates in user awareness information. |
| awarenessChange | Indicates changes in the awareness state. |
| stateless | When the stateless message was received. |
## Configuring Event Listeners
To ensure immediate event tracking, you can pass event listeners directly to the provider's constructor. This method guarantees that listeners are active from the start.
```typescript
const provider = new TiptapCollabProvider({
appId: '', // Use for cloud setups, replace with baseUrl in case of on-prem
name: "example-document", // Document identifier
token: '', // Your authentication JWT token
document: ydoc,
onOpen() {
console.log("WebSocket connection opened.");
},
onConnect() {
console.log("Connected to the server.");
},
// See below for all event listeners...
});
```
### Dynamic Event Binding
For scenarios where you need to add or remove listeners post-initialization, the provider allows for dynamic binding and unbinding of event handlers
**Binding Event Listeners**
```typescript
const provider = new TiptapCollabProvider({
// …
});
provider.on("synced", () => {
console.log("Document synced.");
});
```
**Unbinding Event Listeners**
```typescript
const onMessage = () => {
console.log("New message received.");
};
// Binding
provider.on("message", onMessage);
// Unbinding
provider.off("message", onMessage);
```
## Use cases for event handling
### Real-time Connection Status
Utilize `onConnect` and `onDisconnect` to provide users with real-time connection status feedback, enhancing the user experience.
```tsx
provider.on("connect", () => {
showStatus("Connected");
});
provider.on("disconnect", () => {
showStatus("Disconnected");
});
```
### Document Sync Status
The `synced` event can be used to alert users when the document is fully synced initially, ensuring they start working with the latest version.
```tsx
provider.on("synced", () => {
alert("Document initialized");
});
```
### Handling Authentication Issues
Use `authenticationFailed` to catch authentication errors and prompt users to reauthenticate, maintaining secure access.
```tsx
provider.on("authenticationFailed", ({ reason }) => {
console.error("Authentication failed:", reason);
requestUserReauthentication();
});
```

View File

@ -1,65 +0,0 @@
## Getting Started
### Installation
First you need to install `@hocuspocus/provider` at least in version `2.0.0`.
```bash
npm install @hocuspocus/provider
```
### Basic Usage
Tiptap Collab makes your application collaborative by synchronizing a Yjs document between connected users using websockets. If you're already using Yjs in your application, it's as easy as this:
```typescript
import { TiptapCollabProvider } from '@hocuspocus/provider'
import * as Y from 'yjs'
const provider = new TiptapCollabProvider({
appId: 'your_app_id', // get this at collab.tiptap.dev
name: 'your_document_name', // e.g. a uuid uuidv4();
token: 'your_JWT', // see "Authentication" below
document: new Y.Doc() // pass your existing doc, or leave this out and use provider.document
});
```
### Upgrade From Hocuspocus
If you are upgrading from our self-hosted collaboration backend called Hocuspocus, all you need to do is replace `HocuspocusProvider` with the new `TiptapCollabProvider`. The API is the same, it's just a wrapper that handles the hostname to your Tiptap Collab app and authentication.
## Example
[![Cloud Documents](https://tiptap.dev/images/docs/server/cloud/tiptapcollab-demo.png)](https://tiptap.dev/images/docs/server/cloud/tiptapcollab-demo.png)
We have created a simple client / server setup using replit that you can review and fork here:
[Github](https://github.com/janthurau/TiptapCollab) or [Replit Demo](https://replit.com/@ueberdosis/TiptapCollab?v=1)
The example loads multiple documents over the same websocket (multiplexing), and shows how to implement per-document authentication using JWT.
More tutorials can be found in our [Tutorials section](/tutorials).
## Authentication
Authentication is done using [JSON Web Token (JWT)](https://en.wikipedia.org/wiki/JSON_Web_Token). There are many libraries available to generate a valid token.
### JWT Generation
To generate a JWT in the browser, you can use [http://jwtbuilder.jamiekurtz.com/](http://jwtbuilder.jamiekurtz.com/). You can leave all the fields as default, just replace the "Key" at the bottom with the secret from your [settings](https://collab.tiptap.dev/apps/settings).
In Node.js, you can generate a JWT like this:
```typescript
import jsonwebtoken from 'jsonwebtoken'
const data = {
// Use this list to limit the number of documents that can be accessed by this client.
// An empty array means no access at all.
// Not sending this property means access to all documents.
// We are supporting a wildcard at the end of the string (only there).
allowedDocumentNames: ['document-1', 'document-2', 'my-user-uuid/*', 'my-organization-uuid/*']
}
// This JWT should be sent in the `token` field of the provider. Never expose 'your_secret' to a frontend!
const jwt = jsonwebtoken.sign(data, 'your_secret')

View File

@ -0,0 +1 @@
# Getting Started

View File

@ -0,0 +1,234 @@
---
tableOfContents: true
---
# Install Collaboration
This guide will get you started with collaborative editing in the Tiptap Editor. If you're already using Tiptap Editor, feel free to skip ahead to the "Adding Collaboration" section.
### Installing Tiptap Editor
If Tiptap Editor isn't installed yet, run the following command in your CLI for either React or Vue to install the basic editor and necessary extensions for this example:
```bash
npm install @tiptap/extension-document @tiptap/extension-paragraph @tiptap/extension-text @tiptap/react
```
Once installed, you can get your Tiptap Editor up and running with this basic setup. Just add the following code snippets to your project:
https://embed.tiptap.dev/preview/Examples/Minimal
## Adding Collaboration
To introduce team collaboration features into your Tiptap Editor, integrate the Yjs library and Editor Collaboration extension into your frontend. This setup uses Y.Doc, a shared document model, rather than just handling plain text.
Afterwards we will connect Y.Doc to the TiptapCollabProvider to synchronize user interactions.
### Integrating Yjs and the Collaboration Extension
Add the Editor Collaboration extension and Yjs library to your frontend:
```bash
npm install @tiptap/extension-collaboration yjs
```
Then, update your index.jsx to include these new imports:
```typescript
import './styles.scss'
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import { EditorContent, useEditor } from '@tiptap/react'
import React from 'react'
import Collaboration from '@tiptap/extension-collaboration'
import * as Y from 'yjs'
export default () => {
const doc = new Y.Doc() // Initialize Y.Doc for shared editing
const editor = useEditor({
extensions: [
Document,
Paragraph,
Text,
Collaboration.configure({
document: doc // Configure Y.Doc for collaboration
})
],
content: `
<p>
This is a radically reduced version of tiptap. It has support for a document, with paragraphs and text. Thats it. Its probably too much for real minimalists though.
</p>
<p>
The paragraph extension is not really required, but you need at least one node. Sure, that node can be something different.
</p>
`,
})
return (
<EditorContent editor={editor} />
)
}
```
Your editor is now prepared for collaborative editing!
### Connecting to the Collaboration Server
For collaborative functionality, install the `@hocuspocus/provider` package:
```bash
npm install @hocuspocus/provider
```
Next, configure the Hocuspocus provider in your index.jsx file with your server details:
- **name**: Serves as the document identifier for synchronization.
- **appID**: Found in your [Cloud account](https://cloud.tiptap.dev/apps) after you started your app. For on-premises setups replace `appID` with `baseUrl`.
- **token**: Use the JWT from your [Cloud interface](https://cloud.tiptap.dev/apps/settings) for testing, but generate your own JWT for production.
Incorporate the following code to complete the setup:
```typescript
import './styles.scss'
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import { EditorContent, useEditor } from '@tiptap/react'
import React from 'react'
import Collaboration from '@tiptap/extension-collaboration'
import * as Y from 'yjs'
// Importing the provider and useEffect
import {useEffect} from 'react'
import { TiptapCollabProvider } from '@hocuspocus/provider'
export default () => {
const doc = new Y.Doc()
const editor = useEditor({
extensions: [
Document,
Paragraph,
Text,
Collaboration.configure({
document: doc,
}),
],
content: `
<p>
This is a radically reduced version of tiptap. It has support for a document, with paragraphs and text. Thats it. Its probably too much for real minimalists though.
</p>
<p>
The paragraph extension is not really required, but you need at least one node. Sure, that node can be something different.
</p>
`,
})
// Connect to your Collaboration server
useEffect(() => {
const provider = new TiptapCollabProvider({
name: "document.name", // Unique document identifier for syncing. This is your document name.
appId: '7j9y6m10', // Your Cloud Dashboard AppID or `baseURL` for on-premises
token: 'notoken', // Your JWT token
document: doc,
})
})
return (
<EditorContent editor={editor} />
)
}
```
After following these steps, you should be able to open two different browsers and connect to the same document simultaneously through separate WebSocket connections.
For a clear test of the collaboration features, using two different browsers is recommended to guarantee unique websocket connections.
### Initializing Content Properly
Upon implementing collaboration in your Tiptap Editor, you might notice that the initial content is repeatedly added each time the editor loads. To prevent this, use the `.setContent()` method to set the initial content only once.
```typescript
import './styles.scss'
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import { EditorContent, useEditor } from '@tiptap/react'
import React from 'react'
import * as Y from 'yjs'
import Collaboration from '@tiptap/extension-collaboration'
import {useEffect} from 'react'
import { TiptapCollabProvider } from '@hocuspocus/provider'
export default () => {
const doc = new Y.Doc()
const editor = useEditor({
extensions: [
Document,
Paragraph,
Text,
Collaboration.configure({
document: doc
})
],
// Remove the automatic content addition on editor initialization.
})
useEffect(() => {
const provider = new TiptapCollabProvider({
name: "document.name", // Unique document identifier for syncing. This is your document name.
appId: '7j9y6m10', // Your Cloud Dashboard AppID or `baseURL` for on-premises
token: 'notoken', // Your JWT token
document: doc,
// The onSynced callback ensures initial content is set only once using editor.setContent(), preventing repetitive content loading on editor syncs.
onSynced() {
if( !doc.getMap('config').get('initialContentLoaded') && editor ){
doc.getMap('config').set('initialContentLoaded', true);
editor.commands.setContent(`
<p>
This is a radically reduced version of tiptap. It has support for a document, with paragraphs and text. Thats it. Its probably too much for real minimalists though.
</p>
<p>
The paragraph extension is not really required, but you need at least one node. Sure, that node can be something different.
</p>
`)
}
}
})
})
return (
<EditorContent editor={editor} />
)
}
```
This ensures the initial content is set only once. To test with new initial content, create a new document by changing the `name` parameter (e.g., from `document.name` to `document.name2`).
## Disabling Default Undo/Redo
If you're integrating collaboration into an editor **other than the one provided in this demo**, you may need to disable the default history function of your Editor. This is necessary to avoid conflicts with the collaborative history management: You wouldn't want to revert someone else's changes.
This action is only required if your project includes the Tiptap [StarterKit](https://tiptap.dev/docs/editor/api/extensions/starter-kit) or [History](https://tiptap.dev/docs/editor/api/extensions/history) extension.
```typescript
const editor = useEditor({
extensions: [
StarterKit.configure({
history: false, // Disables default history to use Collaboration's history management
}),
```
Following this guide will set up a basic, yet functional collaborative Tiptap Editor, synchronized through either the Collaboration Cloud or an on-premises backend.

View File

@ -0,0 +1,65 @@
---
tableOfContents: true
---
# What is Tiptap Collaboration?
Tiptap Collaboration turns standard text editors into collaborative platforms, enabling simultaneous editing similar to Google Docs or Notion. Built on our open source Hocuspocus WebSocket backend, it facilitates real-time and asynchronous updates through WebSocket technology, with Y.js ensuring consistent synchronization of changes.
Built for performance and scalability, Tiptap Collaboration is tested by hundreds of thousands of users every day. Enhancing the robust Hocuspocus foundation, Tiptap Collaboration introduces more performance, scalability, and security.
It integrates functionalities such as commenting, document version history, and secure authentication, suitable for both cloud services and personal servers.
### Core features
- Real-time and offline change merging without conflicts.
- Compatible with various editors: Tiptap, Slate, Quill, Monaco, ProseMirror.
- Supports multiplexing for handling multiple documents over one WebSocket connection.
- Integrates with webhooks for change notifications.
- Scales efficiently with Redis for high user volumes.
- Built with TypeScript for type safety and scalability.
Tiptap Collaboration serves as a foundational technology, enabling a suite of advanced features including webhook events, document version control, backend document manipulation, comments and more.
## Where your documents are stored
If you're using our on-premises solutions, you can choose where to store your documents in your own infrastructure. However, for users of our Collaboration Cloud service, we've partnered with Hetzner, renowned for their dependable cloud infrastructure, to guarantee stable and efficient performance, especially during periods of heavy traffic and collaborative activities.
Your document storage location depends on your subscription plan:
- Entry Plan: Your documents are stored in GDPR-compliant data centers in Europe, ensuring your data's privacy and security.
- Business Plan: You have the option to store your documents in data centers on the US East or West Coast, or in Europe, according to your preference.
- Enterprise Plan: Choose dedicated cloud storage in your preferred location, or opt for on-premises storage to manage your documents yourself.
Regardless of your plan, you have the flexibility to create your own backups of all documents and associated information using our document management API.
## About Y.js
Y.js is a library that enables real-time, conflict-free merging of changes made by multiple users. It stands out for its high performance among Conflict-Free Replicated Data Types (CRDTs), offering significant efficiency advantages over similar technologies.
As a CRDT, Y.js ensures that the sequence of changes does not impact the final state of the document, similar to how Git operates with commits. This guarantees that all copies of the data remain consistent across different environments.
The technology supports the development of highly responsive real-time applications, enabling collaborative features in existing software, managing synchronization states, and catering to offline-first scenarios with easy data integration upon reconnection.
### Y.js Document Compatibility
Y.js uses a special Y.doc binary format to work efficiently, but you don't need to worry about changing how you create documents in Tiptap Editor. You can keep using common formats like JSON or HTML, and the Collaboration server will take care of converting them for use with Y.js.
Thanks to Y.js's binary format, it handles data quickly and keeps everything in sync. If you need the binary format, you can get the Y.doc through the document management API. However, you have the option to retrieve your documents in the more familiar JSON or HTML formats. While direct markup output isn't provided, you can achieve it by converting from HTML, offering versatility in how you handle document formats.
## Migrate from Hocuspocus or Collaboration Cloud
Migrating your application from Hocuspocus to either an on-premises solution or the Tiptap Collaboration Cloud involves a simple switch from the `HocuspocusProvider` to the `TiptapCollabProvider`, or the other way around.
This doesn't require any other updates to your setup, and the way you interact with the API won't change as well. The `TiptapCollabProvider` acts as a go-between, managing how your application connects to the server and handles login details.
This migration approach is also applicable when migrating from the Tiptap Collaboration Cloud to an on-premises configuration.
## Schema management
Tiptap enforces strict schema adherence, discarding any elements not defined in the active schema. This can cause issues when clients using different schema versions concurrently edit a document.
For instance, imagine adding a task list feature in an update. Users on the previous schema won't see these task lists, and any added by a user on the new schema will disappear from their view due to schema discrepancies. This occurs because Tiptap synchronizes changes across clients, removing unrecognized elements based on the older schema.
To mitigate these issues, consider the following strategies:
1. Require clients to update their application to match the new schema upon deployment.
2. Monitor schema versions and restrict editing access for clients using outdated versions.

View File

@ -0,0 +1,73 @@
# Naming documents with unique identifiers
This guide outlines best practices for naming documents and organizing content within a single document, to help you define your own document structure.
For a comprehensive understanding of how to choose document names, you should review our [authorization guide](https://tiptap.dev/docs/editor/collaboration/authenticate#authorization-in-collaboration), as document naming plays a crucial role in access control as well.
## Structuring document names
Tiptap Collaboration uses document names to facilitate collaborative sessions, they serve as unique identifiers that link users to the same document. In theory it could be any string.
While the following example uses an entity's name combined with a unique ID, typical for CMS applications, you're free to adopt any naming convention that suits your application's requirements.
New documents are automatically generated as needed; you only need to provide a string identifier to the provider.
```typescript
const documentName = "article.123";
```
This naming format allows you to separate out the key details easily:
```typescript
const documentName = "article.123";
// Splitting the document name into separate parts
const [entityType, entityID] = documentName.split(".");
console.log(entityType); // Output: "article"
console.log(entityID); // Output: "123"
```
## Managing nested documents with fragments
Yjs's fragments are ideal for handling complex documents with distinct sections. This might be relevant in case you want to nest your documents, like for example a blog post with separate `title` and `content` parts.
With fragments, you can use one Y.Doc instance (e.g. one document) and use different editors for its distinct sections.
For example, in this blog post setup:
```typescript
const ydoc = new Y.Doc();
// Title editor
const titleEditor = new Editor({
extensions: [
Collaboration.configure({
document: this.ydoc,
field: "title",
}),
],
})
// Content editor
const bodyEditor = new Editor({
extensions: [
Collaboration.configure({
document: this.ydoc,
field: "content",
}),
],
})
```
For complex setups with nested fragments, you can directly use a raw Y.js fragment, bypassing the `document` and `field` settings.
```typescript
// a raw Y.js fragment
Collaboration.configure({
fragment: ydoc.getXmlFragment('custom'),
})
```
To fully grasp how document naming influences access control in Tiptap Collaboration, it's essential to consult our [authorization guide](https://tiptap.dev/docs/editor/collaboration/authenticate#authorization-in-collaboration).

View File

@ -0,0 +1,36 @@
# Adding offline support to your editor
Easily add offline functionality to your collaborative editor by using the [Y IndexedDB](https://docs.yjs.dev/ecosystem/database-provider/y-indexeddb) extension. This tool from the Y.js ecosystem enhances your editor with offline data storage and sync capabilities.
## Integrating offline support
Begin by adding the Y IndexedDB adapter to your project:
```bash
npm install y-indexeddb
```
Connect Y Indexeddb with a Y document to store it locally.
```typescript
import { Editor } from '@tiptap/core'
import Collaboration from '@tiptap/extension-collaboration'
import * as Y from 'yjs'
import { IndexeddbPersistence } from 'y-indexeddb'
const ydoc = new Y.Doc()
// Set up IndexedDB for local storage of the Y document
new IndexeddbPersistence('example-document', ydoc)
const editor = new Editor({
extensions: [
// Other extensions...
Collaboration.configure({
document: ydoc,
}),
],
});
```
The IndexedDB adapter ensures that every change to your document is stored locally in the browser. This means your work is saved even if you close the tab, lose your internet connection, or edit offline. When you're back online, it automatically syncs these changes.

View File

@ -0,0 +1,226 @@
---
tableOfContents: true
---
# Install Collaboration
This guide will get you started with collaborative editing in the Tiptap Editor. If you're already using Tiptap Editor, feel free to skip ahead to the "Adding Collaboration" section.
### Installing Tiptap Editor
If Tiptap Editor isn't installed yet, run the following command in your CLI for either React or Vue to install the basic editor and necessary extensions for this example:
```bash
npm install @tiptap/extension-document @tiptap/extension-paragraph @tiptap/extension-text @tiptap/react
```
Once installed, you can get your Tiptap Editor up and running with this basic setup. Just add the following code snippets to your project:
https://embed.tiptap.dev/preview/Examples/Minimal
## Adding Collaboration
To introduce team collaboration features into your Tiptap Editor, integrate the Yjs library and Editor Collaboration extension into your frontend. This setup uses Y.Doc, a shared document model, rather than just handling plain text.
Afterwards we will connect Y.Doc to the TiptapCollabProvider to synchronize user interactions.
### Integrating Yjs and the Collaboration Extension
Add the Editor Collaboration extension and Yjs library to your frontend:
```bash
npm install @tiptap/extension-collaboration yjs
```
Then, update your index.jsx to include these new imports:
```typescript
import './styles.scss'
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import { EditorContent, useEditor } from '@tiptap/react'
import Collaboration from '@tiptap/extension-collaboration'
import * as Y from 'yjs'
export default () => {
const doc = new Y.Doc() // Initialize Y.Doc for shared editing
const editor = useEditor({
extensions: [
Document,
Paragraph,
Text,
Collaboration.configure({
document: doc // Configure Y.Doc for collaboration
})
],
content: `
<p>
This is a radically reduced version of tiptap. It has support for a document, with paragraphs and text. Thats it. Its probably too much for real minimalists though.
</p>
<p>
The paragraph extension is not really required, but you need at least one node. Sure, that node can be something different.
</p>
`,
})
return (
<EditorContent editor={editor} />
)
}
```
Your editor is now prepared for collaborative editing!
### Connecting to the Collaboration Server
For collaborative functionality, install the `@hocuspocus/provider` package:
```bash
npm install @hocuspocus/provider
```
Next, configure the Hocuspocus provider in your index.jsx file with your server details:
- **name**: Serves as the document identifier for synchronization.
- **appID**: Found in your [Cloud account](https://cloud.tiptap.dev/apps) after you started your app. For on-premises setups replace `appID` with `baseUrl`.
- **token**: Use the JWT from your [Cloud interface](https://cloud.tiptap.dev/apps/settings) for testing, but generate your own JWT for production.
Incorporate the following code to complete the setup:
```typescript
import './styles.scss'
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import { EditorContent, useEditor } from '@tiptap/react'
import * as Y from 'yjs'
import Collaboration from '@tiptap/extension-collaboration'
// Importing the provider
import { TiptapCollabProvider } from '@hocuspocus/provider'
export default () => {
const doc = new Y.Doc()
// Connect to your Collaboration server
const provider = new TiptapCollabProvider({
name: "document.name", // Unique document identifier for syncing. This is your document name.
appId: '7j9y6m10', // Your Cloud Dashboard AppID or `baseURL` for on-premises
token: 'notoken', // Your JWT token
document: doc,
})
const editor = useEditor({
extensions: [
Document,
Paragraph,
Text,
Collaboration.configure({
document: doc,
}),
],
content: `
<p>
This is a radically reduced version of tiptap. It has support for a document, with paragraphs and text. Thats it. Its probably too much for real minimalists though.
</p>
<p>
The paragraph extension is not really required, but you need at least one node. Sure, that node can be something different.
</p>
`,
})
return (
<EditorContent editor={editor} />
)
}
```
After following these steps, you should be able to open two different browsers and connect to the same document simultaneously through separate WebSocket connections.
For a clear test of the collaboration features, using two different browsers is recommended to guarantee unique websocket connections.
### Initializing Content Properly
Upon implementing collaboration in your Tiptap Editor, you might notice that the initial content is repeatedly added each time the editor loads. To prevent this, use the `.setContent()` method to set the initial content only once.
```typescript
import './styles.scss'
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import { EditorContent, useEditor } from '@tiptap/react'
import * as Y from 'yjs'
import Collaboration from '@tiptap/extension-collaboration'
import { TiptapCollabProvider } from '@hocuspocus/provider'
export default () => {
const doc = new Y.Doc()
const provider = new TiptapCollabProvider({
name: "document.name", // Unique document identifier for syncing. This is your document name.
appId: '7j9y6m10', // Your Cloud Dashboard AppID or `baseURL` for on-premises
token: 'notoken', // Your JWT token
document: doc,
// The onSynced callback ensures initial content is set only once using editor.setContent(), preventing repetitive content insertion on editor syncs.
onSynced() {
if( !doc.getMap('config').get('initialContentLoaded') && editor ){
doc.getMap('config').set('initialContentLoaded', true);
editor.commands.setContent(`
<p>
This is a radically reduced version of tiptap. It has support for a document, with paragraphs and text. Thats it. Its probably too much for real minimalists though.
</p>
<p>
The paragraph extension is not really required, but you need at least one node. Sure, that node can be something different.
</p>
`)
}
}
})
const editor = useEditor({
extensions: [
Document,
Paragraph,
Text,
Collaboration.configure({
document: doc
}),
],
// Remove the automatic content addition on editor initialization.
})
return (
<EditorContent editor={editor} />
)
}
```
This ensures the initial content is set only once. To test with new initial content, create a new document by changing the `name` parameter (e.g., from `document.name` to `document.name2`).
## Disabling Default Undo/Redo
If you're integrating collaboration into an editor **other than the one provided in this demo**, you may need to disable the default history function of your Editor. This is necessary to avoid conflicts with the collaborative history management: You wouldn't want to revert someone else's changes.
This action is only required if your project includes the Tiptap [StarterKit](https://tiptap.dev/docs/editor/api/extensions/starter-kit) or [History](https://tiptap.dev/docs/editor/api/extensions/history) extension.
```typescript
const editor = useEditor({
extensions: [
StarterKit.configure({
history: false, // Disables default history to use Collaboration's history management
}),
```
Following this guide will set up a basic, yet functional collaborative Tiptap Editor, synchronized through either the Collaboration Cloud or an on-premises backend.

View File

@ -1,9 +0,0 @@
# Collaboration
Implementing real-time collaboration is quite hard. With Tiptap Collab we build a solution that does it in minutes. To see it in action check out our [live demo](https://tiptap.dev/editor).
Tiptap Collab is our managed cloud solution of [Hocuspocus](https://tiptap.dev/hocuspocus/introduction). It makes it a easy to add real-time collaboration to any application. If you already have an application using Tiptap Editor, it's even easier to add collaboration.
:::warning Pro Feature
To get started, you need a Tiptap Pro account. [Log in](https://tiptap.dev/login) or [sign up](https://tiptap.dev/register) for free.
:::

View File

@ -0,0 +1,65 @@
---
tableOfContents: true
---
# What is Tiptap Collaboration?
Tiptap Collaboration turns standard text editors into collaborative platforms, enabling simultaneous editing similar to Google Docs or Notion. Built on our open source Hocuspocus WebSocket backend, it facilitates real-time and asynchronous updates through WebSocket technology, with Y.js ensuring consistent synchronization of changes.
Built for performance and scalability, Tiptap Collaboration is tested by hundreds of thousands of users every day. Enhancing the robust Hocuspocus foundation, Tiptap Collaboration introduces more performance, scalability, and security.
It integrates functionalities such as commenting, document version history, and secure authentication, suitable for both cloud services and personal servers.
### Core features
- Real-time and offline change merging without conflicts.
- Compatible with various editors: Tiptap, Slate, Quill, Monaco, ProseMirror.
- Supports multiplexing for handling multiple documents over one WebSocket connection.
- Integrates with webhooks for change notifications.
- Scales efficiently with Redis for high user volumes.
- Built with TypeScript for type safety and scalability.
Tiptap Collaboration serves as a foundational technology, enabling a suite of advanced features including webhook events, document version control, backend document manipulation, comments and more.
## Where your documents are stored
If you're using our on-premises solutions, you can choose where to store your documents in your own infrastructure. However, for users of our Collaboration Cloud service, we've partnered with Hetzner, renowned for their dependable cloud infrastructure, to guarantee stable and efficient performance, especially during periods of heavy traffic and collaborative activities.
Your document storage location depends on your subscription plan:
- Entry Plan: Your documents are stored in GDPR-compliant data centers in Europe, ensuring your data's privacy and security.
- Business Plan: You have the option to store your documents in data centers on the US East or West Coast, or in Europe, according to your preference.
- Enterprise Plan: Choose dedicated cloud storage in your preferred location, or opt for on-premises storage to manage your documents yourself.
Regardless of your plan, you have the flexibility to create your own backups of all documents and associated information using our document management API.
## About Y.js
Y.js is a library that enables real-time, conflict-free merging of changes made by multiple users. It stands out for its high performance among Conflict-Free Replicated Data Types (CRDTs), offering significant efficiency advantages over similar technologies.
As a CRDT, Y.js ensures that the sequence of changes does not impact the final state of the document, similar to how Git operates with commits. This guarantees that all copies of the data remain consistent across different environments.
The technology supports the development of highly responsive real-time applications, enabling collaborative features in existing software, managing synchronization states, and catering to offline-first scenarios with easy data integration upon reconnection.
### Y.js Document Compatibility
Y.js uses a special Y.doc binary format to work efficiently, but you don't need to worry about changing how you create documents in Tiptap Editor. You can keep using common formats like JSON or HTML, and the Collaboration server will take care of converting them for use with Y.js.
Thanks to Y.js's binary format, it handles data quickly and keeps everything in sync. If you need the binary format, you can get the Y.doc through the document management API. However, you have the option to retrieve your documents in the more familiar JSON or HTML formats. While direct markup output isn't provided, you can achieve it by converting from HTML, offering versatility in how you handle document formats.
## Migrate from Hocuspocus or Collaboration Cloud
Migrating your application from Hocuspocus to either an on-premises solution or the Tiptap Collaboration Cloud involves a simple switch from the `HocuspocusProvider` to the `TiptapCollabProvider`, or the other way around.
This doesn't require any other updates to your setup, and the way you interact with the API won't change as well. The `TiptapCollabProvider` acts as a go-between, managing how your application connects to the server and handles login details.
This migration approach is also applicable when migrating from the Tiptap Collaboration Cloud to an on-premises configuration.
## Schema management
Tiptap enforces strict schema adherence, discarding any elements not defined in the active schema. This can cause issues when clients using different schema versions concurrently edit a document.
For instance, imagine adding a task list feature in an update. Users on the previous schema won't see these task lists, and any added by a user on the new schema will disappear from their view due to schema discrepancies. This occurs because Tiptap synchronizes changes across clients, removing unrecognized elements based on the older schema.
To mitigate these issues, consider the following strategies:
1. Require clients to update their application to match the new schema upon deployment.
2. Monitor schema versions and restrict editing access for clients using outdated versions.

View File

@ -0,0 +1,63 @@
# What is the Collaboration Provider
Together with the Collaboration backend, Providers act as the backbone for real-time collaborative editing. They establish and manage the communication channels between different users, ensuring that updates and changes to documents are synchronized across all participants.
Providers help handle the complexities of real-time data exchange, including conflict resolution, network reliability, and user presence awareness. The Hocuspocus provider, specifically designed for Tiptap Collaboration, brings advanced features tailored for collaborative environments, including WebSocket message authentication, debug modes, and flexible connection strategies.
## Setting up a basic configuration
First you need to install the provider package in your project with
```bash
npm install @hocuspocus/provider
```
For a basic setup, you need to connect to the Collaboration backend. This involves specifying the document's name, your app's ID (for cloud setups), or the base URL (for on-premises solutions), along with your JWT. Depending on your framework, register a callback to the Collaboration backend, such as `useEffect()` in React or `onMounted()` in Vue.
```typescript
const doc = new Y.Doc()
useEffect(() => {
const provider = new TiptapCollabProvider({
name: note.id, // Document identifier
appId: 'YOUR_APP_ID', // replace with YOUR_APP_ID from Cloud dashboard
token: 'YOUR_JWT', // Authentication token
document: doc,
})
```
## Configuring an advanced provider
Tiptap Collaboration's advanced provider settings offer deep customization for enhanced collaboration. Below, explore a comprehensive list of parameters, practical use cases, and key concepts like "awareness" explained in detail.
| Setting | Description | Default Value |
| --- | --- | --- |
| appId | App ID for Collaboration Cloud setups. | '' |
| baseUrl | URL for connecting to on-premises servers, used as an alternative to appId for on-prem setups. | '' |
| name | The name of the document. | '' |
| document | The Y.js document instance; defaults to creating a new one. | new Y.Doc() |
| token | Authentication token for secure connections. Works with strings, functions and Promises. | '' |
| awareness | Manages user presence information, by default attached to the passed Y.js document. | new Awareness() |
| connect | Whether to connect to the server after initialization. | true |
| preserveConnection | Whether to preserve the websocket connection after closing the provider. | true |
| broadcast | Enables syncing across browser tabs. | true |
| forceSyncInterval | Interval for forced server sync (in ms). | false |
| quiet | Suppresses warning outputs. | false |
| WebSocketPolyfill | WebSocket implementation for Node.js environments. For example ws. | WebSocket |
### Optimizing Reconnection Timings
The providers reconnection settings are preset for optimal performance in production settings, ensuring reliability and efficiency. If you need to tweak these settings for specific scenarios, our delay configurations offer flexibility.
Adjust initial delays, apply exponential backoff, or set maximum wait times to fine-tune your application's reconnection behavior, balancing responsiveness with server efficiency.
| Setting | Description | Default Value |
| --- | --- | --- |
| delay | Base delay between reconnection attempts, in milliseconds. | 1000 |
| factor | Multiplier for delay, increasing it exponentially after each attempt. | 2 |
| initialDelay | Time before the first reconnection attempt, in milliseconds. Ideally immediate. | 0 |
| maxAttempts | Maximum number of reconnection attempts. 0 means unlimited. | 0 |
| jitter | When jitter is enabled, it adds variability to the reconnection delay by selecting a random value within the range of minDelay and the delay calculated for the current attempt. | true |
| minDelay | Minimum delay when jitter is enabled, ensuring a random delay isn't too short. This property has no effect if jitter is disabled. | 1000 |
| maxDelay | The maxDelay setting caps the delay during reconnection attempts. When using the exponential backoff (factor), you can specify 0 for maxDelay to remove this upper limit, allowing the delay to increase indefinitely. | 30000 |
| timeout | Sets a limit, in milliseconds, for how long to wait for a reconnection attempt before giving up. If this timeout is reached, subsequent attempts are halted. | 0 |
| messageReconnectTimeout | Defines the duration in milliseconds to await a server message before terminating the connection. If no message is received within this period, the connection is automatically closed. | 30000 |

View File

@ -291,6 +291,9 @@
link: /api/extensions/bubble-menu
- title: CharacterCount
link: /api/extensions/character-count
- title: Comments
link: /api/extensions/comments
type: beta
- title: Collaboration
link: /api/extensions/collaboration
- title: CollaborationCursor
@ -333,7 +336,8 @@
link: /api/extensions/unique-id
type: pro
- title: Utilities
link: /api/utilities
link: /api/utilities/
redirect: /api/utilities/html
items:
- title: HTML
link: /api/utilities/html
@ -341,7 +345,6 @@
link: /api/utilities/suggestion
- title: Tiptap for PHP
link: /api/utilities/tiptap-php
type: new
- title: Keyboard shortcuts
link: /api/keyboard-shortcuts
- title: Schema
@ -383,26 +386,60 @@
- title: Upgrade Editor to v2
link: /overview/upgrade-guide
- title: Comments
type: beta
items:
- title: Overview
link: /comments/overview
- title: Getting started
link: /comments/getting-started
- title: Managing threads
link: /comments/managing-threads
- title: Styling threads
link: /comments/styling-threads
- title: Editor API
link: /comments/api
- title: REST API
link: /comments/rest-api
- title: Webhook
link: /comments/webhook
- title: Configuration
link: /comments/configuration
- title: Collaboration
items:
- title: Getting started
link: /collaboration/introduction
items:
- title: Introduction
link: /collaboration/introduction
- title: Getting started
link: /collaboration/getting-started
- title: Management API
link: /collaboration/management-api
- title: Overview
link: /collaboration/overview
- title: Install
link: /collaboration/install
- title: Authenticate
link: /collaboration/authenticate
- title: Provider
link: /collaboration/provider
- title: Events
link: /collaboration/events
- title: Awareness
link: /collaboration/awareness
- title: Configure
link: /collaboration/configure
- title: Document API
link: /collaboration/document-api
- title: Document Manipulation
link: /collaboration/backend-document-manipulation
type: beta
- title: Webhook
link: /collaboration/webhook
- title: Guides
link: /collaboration/guides
items:
- title: Simple collaboration app
link: /collaboration/guides/simple-collaboration-app
- title: JWT Authentication
link: /collaboration/guides/jwt-authentication
- title: Naming documents
link: /collaboration/guides/naming-documents
- title: Offline support
link: /collaboration/guides/offline-support
- title: Simple collaboration app
link: /collaboration/guides/simple-collaboration-app
- title: Content AI
items:

View File

@ -10,5 +10,5 @@
},
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"useNx": true,
"version": "2.2.2"
"version": "2.2.5"
}

314
package-lock.json generated
View File

@ -52,7 +52,7 @@
},
"demos": {
"name": "tiptap-demos",
"version": "2.2.2",
"version": "2.2.5",
"dependencies": {
"@hocuspocus/provider": "^2.9.0",
"@lexical/react": "^0.11.1",
@ -19035,10 +19035,10 @@
},
"packages/core": {
"name": "@tiptap/core",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/pm": "^2.2.2"
"@tiptap/pm": "^2.2.5"
},
"funding": {
"type": "github",
@ -19050,10 +19050,10 @@
},
"packages/extension-blockquote": {
"name": "@tiptap/extension-blockquote",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19065,10 +19065,10 @@
},
"packages/extension-bold": {
"name": "@tiptap/extension-bold",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19080,14 +19080,14 @@
},
"packages/extension-bubble-menu": {
"name": "@tiptap/extension-bubble-menu",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"dependencies": {
"tippy.js": "^6.3.7"
},
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"funding": {
"type": "github",
@ -19100,10 +19100,10 @@
},
"packages/extension-bullet-list": {
"name": "@tiptap/extension-bullet-list",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19115,11 +19115,11 @@
},
"packages/extension-character-count": {
"name": "@tiptap/extension-character-count",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"funding": {
"type": "github",
@ -19132,10 +19132,10 @@
},
"packages/extension-code": {
"name": "@tiptap/extension-code",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19147,11 +19147,11 @@
},
"packages/extension-code-block": {
"name": "@tiptap/extension-code-block",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"funding": {
"type": "github",
@ -19164,12 +19164,12 @@
},
"packages/extension-code-block-lowlight": {
"name": "@tiptap/extension-code-block-lowlight",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/extension-code-block": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/extension-code-block": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"funding": {
"type": "github",
@ -19183,11 +19183,11 @@
},
"packages/extension-collaboration": {
"name": "@tiptap/extension-collaboration",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2",
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5",
"y-prosemirror": "^1.2.1"
},
"funding": {
@ -19202,10 +19202,10 @@
},
"packages/extension-collaboration-cursor": {
"name": "@tiptap/extension-collaboration-cursor",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/core": "^2.2.5",
"y-prosemirror": "^1.2.1"
},
"funding": {
@ -19219,11 +19219,11 @@
},
"packages/extension-color": {
"name": "@tiptap/extension-color",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/extension-text-style": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/extension-text-style": "^2.2.5"
},
"funding": {
"type": "github",
@ -19236,10 +19236,10 @@
},
"packages/extension-document": {
"name": "@tiptap/extension-document",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19251,11 +19251,11 @@
},
"packages/extension-dropcursor": {
"name": "@tiptap/extension-dropcursor",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"funding": {
"type": "github",
@ -19268,14 +19268,14 @@
},
"packages/extension-floating-menu": {
"name": "@tiptap/extension-floating-menu",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"dependencies": {
"tippy.js": "^6.3.7"
},
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"funding": {
"type": "github",
@ -19288,11 +19288,11 @@
},
"packages/extension-focus": {
"name": "@tiptap/extension-focus",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"funding": {
"type": "github",
@ -19305,11 +19305,11 @@
},
"packages/extension-font-family": {
"name": "@tiptap/extension-font-family",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/extension-text-style": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/extension-text-style": "^2.2.5"
},
"funding": {
"type": "github",
@ -19322,11 +19322,11 @@
},
"packages/extension-gapcursor": {
"name": "@tiptap/extension-gapcursor",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"funding": {
"type": "github",
@ -19339,10 +19339,10 @@
},
"packages/extension-hard-break": {
"name": "@tiptap/extension-hard-break",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19354,10 +19354,10 @@
},
"packages/extension-heading": {
"name": "@tiptap/extension-heading",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19369,10 +19369,10 @@
},
"packages/extension-highlight": {
"name": "@tiptap/extension-highlight",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19384,11 +19384,11 @@
},
"packages/extension-history": {
"name": "@tiptap/extension-history",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"funding": {
"type": "github",
@ -19401,11 +19401,11 @@
},
"packages/extension-horizontal-rule": {
"name": "@tiptap/extension-horizontal-rule",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"funding": {
"type": "github",
@ -19418,10 +19418,10 @@
},
"packages/extension-image": {
"name": "@tiptap/extension-image",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19433,10 +19433,10 @@
},
"packages/extension-italic": {
"name": "@tiptap/extension-italic",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19448,14 +19448,14 @@
},
"packages/extension-link": {
"name": "@tiptap/extension-link",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"dependencies": {
"linkifyjs": "^4.1.0"
},
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"funding": {
"type": "github",
@ -19468,10 +19468,10 @@
},
"packages/extension-list-item": {
"name": "@tiptap/extension-list-item",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19483,10 +19483,10 @@
},
"packages/extension-list-keymap": {
"name": "@tiptap/extension-list-keymap",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19498,12 +19498,12 @@
},
"packages/extension-mention": {
"name": "@tiptap/extension-mention",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2",
"@tiptap/suggestion": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5",
"@tiptap/suggestion": "^2.2.5"
},
"funding": {
"type": "github",
@ -19517,10 +19517,10 @@
},
"packages/extension-ordered-list": {
"name": "@tiptap/extension-ordered-list",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19532,10 +19532,10 @@
},
"packages/extension-paragraph": {
"name": "@tiptap/extension-paragraph",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19547,11 +19547,11 @@
},
"packages/extension-placeholder": {
"name": "@tiptap/extension-placeholder",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"funding": {
"type": "github",
@ -19564,10 +19564,10 @@
},
"packages/extension-strike": {
"name": "@tiptap/extension-strike",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19579,10 +19579,10 @@
},
"packages/extension-subscript": {
"name": "@tiptap/extension-subscript",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19594,10 +19594,10 @@
},
"packages/extension-superscript": {
"name": "@tiptap/extension-superscript",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19609,11 +19609,11 @@
},
"packages/extension-table": {
"name": "@tiptap/extension-table",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"funding": {
"type": "github",
@ -19626,10 +19626,10 @@
},
"packages/extension-table-cell": {
"name": "@tiptap/extension-table-cell",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19641,10 +19641,10 @@
},
"packages/extension-table-header": {
"name": "@tiptap/extension-table-header",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19656,10 +19656,10 @@
},
"packages/extension-table-row": {
"name": "@tiptap/extension-table-row",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19671,11 +19671,11 @@
},
"packages/extension-task-item": {
"name": "@tiptap/extension-task-item",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"funding": {
"type": "github",
@ -19688,10 +19688,10 @@
},
"packages/extension-task-list": {
"name": "@tiptap/extension-task-list",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19703,10 +19703,10 @@
},
"packages/extension-text": {
"name": "@tiptap/extension-text",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19718,10 +19718,10 @@
},
"packages/extension-text-align": {
"name": "@tiptap/extension-text-align",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19733,10 +19733,10 @@
},
"packages/extension-text-style": {
"name": "@tiptap/extension-text-style",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19748,10 +19748,10 @@
},
"packages/extension-typography": {
"name": "@tiptap/extension-typography",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19763,10 +19763,10 @@
},
"packages/extension-underline": {
"name": "@tiptap/extension-underline",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19778,10 +19778,10 @@
},
"packages/extension-youtube": {
"name": "@tiptap/extension-youtube",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"funding": {
"type": "github",
@ -19793,14 +19793,14 @@
},
"packages/html": {
"name": "@tiptap/html",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"dependencies": {
"zeed-dom": "^0.10.9"
},
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"funding": {
"type": "github",
@ -19813,7 +19813,7 @@
},
"packages/pm": {
"name": "@tiptap/pm",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"dependencies": {
"prosemirror-changeset": "^2.2.1",
@ -19842,15 +19842,15 @@
},
"packages/react": {
"name": "@tiptap/react",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"dependencies": {
"@tiptap/extension-bubble-menu": "^2.2.2",
"@tiptap/extension-floating-menu": "^2.2.2"
"@tiptap/extension-bubble-menu": "^2.2.5",
"@tiptap/extension-floating-menu": "^2.2.5"
},
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2",
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5",
"@types/react": "^18.2.14",
"@types/react-dom": "^18.2.6",
"react": "^18.0.0",
@ -19869,28 +19869,28 @@
},
"packages/starter-kit": {
"name": "@tiptap/starter-kit",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"dependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/extension-blockquote": "^2.2.2",
"@tiptap/extension-bold": "^2.2.2",
"@tiptap/extension-bullet-list": "^2.2.2",
"@tiptap/extension-code": "^2.2.2",
"@tiptap/extension-code-block": "^2.2.2",
"@tiptap/extension-document": "^2.2.2",
"@tiptap/extension-dropcursor": "^2.2.2",
"@tiptap/extension-gapcursor": "^2.2.2",
"@tiptap/extension-hard-break": "^2.2.2",
"@tiptap/extension-heading": "^2.2.2",
"@tiptap/extension-history": "^2.2.2",
"@tiptap/extension-horizontal-rule": "^2.2.2",
"@tiptap/extension-italic": "^2.2.2",
"@tiptap/extension-list-item": "^2.2.2",
"@tiptap/extension-ordered-list": "^2.2.2",
"@tiptap/extension-paragraph": "^2.2.2",
"@tiptap/extension-strike": "^2.2.2",
"@tiptap/extension-text": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/extension-blockquote": "^2.2.5",
"@tiptap/extension-bold": "^2.2.5",
"@tiptap/extension-bullet-list": "^2.2.5",
"@tiptap/extension-code": "^2.2.5",
"@tiptap/extension-code-block": "^2.2.5",
"@tiptap/extension-document": "^2.2.5",
"@tiptap/extension-dropcursor": "^2.2.5",
"@tiptap/extension-gapcursor": "^2.2.5",
"@tiptap/extension-hard-break": "^2.2.5",
"@tiptap/extension-heading": "^2.2.5",
"@tiptap/extension-history": "^2.2.5",
"@tiptap/extension-horizontal-rule": "^2.2.5",
"@tiptap/extension-italic": "^2.2.5",
"@tiptap/extension-list-item": "^2.2.5",
"@tiptap/extension-ordered-list": "^2.2.5",
"@tiptap/extension-paragraph": "^2.2.5",
"@tiptap/extension-strike": "^2.2.5",
"@tiptap/extension-text": "^2.2.5"
},
"funding": {
"type": "github",
@ -19899,11 +19899,11 @@
},
"packages/suggestion": {
"name": "@tiptap/suggestion",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"funding": {
"type": "github",
@ -19916,16 +19916,16 @@
},
"packages/vue-2": {
"name": "@tiptap/vue-2",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"dependencies": {
"@tiptap/extension-bubble-menu": "^2.2.2",
"@tiptap/extension-floating-menu": "^2.2.2",
"@tiptap/extension-bubble-menu": "^2.2.5",
"@tiptap/extension-floating-menu": "^2.2.5",
"vue-ts-types": "^1.6.0"
},
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2",
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5",
"vue": "^2.6.0"
},
"funding": {
@ -19945,15 +19945,15 @@
},
"packages/vue-3": {
"name": "@tiptap/vue-3",
"version": "2.2.2",
"version": "2.2.5",
"license": "MIT",
"dependencies": {
"@tiptap/extension-bubble-menu": "^2.2.2",
"@tiptap/extension-floating-menu": "^2.2.2"
"@tiptap/extension-bubble-menu": "^2.2.5",
"@tiptap/extension-floating-menu": "^2.2.5"
},
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2",
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5",
"vue": "^3.0.0"
},
"funding": {

View File

@ -3,6 +3,33 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/core
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
### Bug Fixes
* typecheck drag and clipboard events for testing environments ([bbee9a3](https://github.com/ueberdosis/tiptap/commit/bbee9a3c3090fa40bf366591682b42a3f6ec5f91))
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/core
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/core

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/core",
"description": "headless rich text editor",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -32,7 +32,7 @@
"dist"
],
"devDependencies": {
"@tiptap/pm": "^2.2.2"
"@tiptap/pm": "^2.2.5"
},
"peerDependencies": {
"@tiptap/pm": "^2.0.0"

View File

@ -21,7 +21,7 @@ export type PasteRuleMatch = {
data?: Record<string, any>
}
export type PasteRuleFinder = RegExp | ((text: string, event?: ClipboardEvent) => PasteRuleMatch[] | null | undefined)
export type PasteRuleFinder = RegExp | ((text: string, event?: ClipboardEvent | null) => PasteRuleMatch[] | null | undefined)
export class PasteRule {
find: PasteRuleFinder
@ -33,8 +33,8 @@ export class PasteRule {
commands: SingleCommands
chain: () => ChainedCommands
can: () => CanCommands
pasteEvent: ClipboardEvent
dropEvent: DragEvent
pasteEvent: ClipboardEvent | null
dropEvent: DragEvent | null
}) => void | null
constructor(config: {
@ -43,9 +43,9 @@ export class PasteRule {
can: () => CanCommands
chain: () => ChainedCommands
commands: SingleCommands
dropEvent: DragEvent
dropEvent: DragEvent | null
match: ExtendedRegExpMatchArray
pasteEvent: ClipboardEvent
pasteEvent: ClipboardEvent | null
range: Range
state: EditorState
}) => void | null
@ -58,7 +58,7 @@ export class PasteRule {
const pasteRuleMatcherHandler = (
text: string,
find: PasteRuleFinder,
event?: ClipboardEvent,
event?: ClipboardEvent | null,
): ExtendedRegExpMatchArray[] => {
if (isRegExp(find)) {
return [...text.matchAll(find)]
@ -97,8 +97,8 @@ function run(config: {
from: number
to: number
rule: PasteRule
pasteEvent: ClipboardEvent
dropEvent: DragEvent
pasteEvent: ClipboardEvent | null
dropEvent: DragEvent | null
}): boolean {
const {
editor, state, from, to, rule, pasteEvent, dropEvent,
@ -164,8 +164,8 @@ export function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }):
let dragSourceElement: Element | null = null
let isPastedFromProseMirror = false
let isDroppedFromProseMirror = false
let pasteEvent = new ClipboardEvent('paste')
let dropEvent = new DragEvent('drop')
let pasteEvent = typeof ClipboardEvent !== 'undefined' ? new ClipboardEvent('paste') : null
let dropEvent = typeof DragEvent !== 'undefined' ? new DragEvent('drop') : null
const plugins = rules.map(rule => {
return new Plugin({
@ -247,8 +247,8 @@ export function pasteRulesPlugin(props: { editor: Editor; rules: PasteRule[] }):
return
}
dropEvent = new DragEvent('drop')
pasteEvent = new ClipboardEvent('paste')
dropEvent = typeof DragEvent !== 'undefined' ? new DragEvent('drop') : null
pasteEvent = typeof ClipboardEvent !== 'undefined' ? new ClipboardEvent('paste') : null
return tr
},

View File

@ -18,7 +18,7 @@ export const Keymap = Extension.create({
const { selection, doc } = tr
const { empty, $anchor } = selection
const { pos, parent } = $anchor
const $parentPos = $anchor.parent.isTextblock ? tr.doc.resolve(pos - 1) : $anchor
const $parentPos = $anchor.parent.isTextblock && pos > 0 ? tr.doc.resolve(pos - 1) : $anchor
const parentIsIsolating = $parentPos.parent.type.spec.isolating
const parentPos = $anchor.pos - $anchor.parentOffset

View File

@ -33,7 +33,11 @@ export function getTextBetween(
range,
})
}
} else if (node.isText) {
// do not descend into child nodes when there exists a serializer
return false
}
if (node.isText) {
text += node?.text?.slice(Math.max(from, pos) - pos, to - pos) // eslint-disable-line
separated = false
} else if (node.isBlock && !separated) {

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-blockquote
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-blockquote
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-blockquote
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-blockquote

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-blockquote",
"description": "blockquote extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,7 +29,7 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0"

View File

@ -3,6 +3,33 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
### Bug Fixes
* Disallow only whitespace between markdown shortcuts delimiters ([#4866](https://github.com/ueberdosis/tiptap/issues/4866)) ([aa029fe](https://github.com/ueberdosis/tiptap/commit/aa029fe2242aeadc38555b2832df6ae1614c7d1d))
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-bold
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-bold
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-bold

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-bold",
"description": "bold extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,7 +29,7 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0"

View File

@ -28,10 +28,10 @@ declare module '@tiptap/core' {
}
}
export const starInputRegex = /(?:^|\s)((?:\*\*)((?:[^*]+))(?:\*\*))$/
export const starPasteRegex = /(?:^|\s)((?:\*\*)((?:[^*]+))(?:\*\*))/g
export const underscoreInputRegex = /(?:^|\s)((?:__)((?:[^__]+))(?:__))$/
export const underscorePasteRegex = /(?:^|\s)((?:__)((?:[^__]+))(?:__))/g
export const starInputRegex = /(?:^|\s)(\*\*(?!\s+\*\*)((?:[^*]+))\*\*(?!\s+\*\*))$/
export const starPasteRegex = /(?:^|\s)(\*\*(?!\s+\*\*)((?:[^*]+))\*\*(?!\s+\*\*))/g
export const underscoreInputRegex = /(?:^|\s)(__(?!\s+__)((?:[^_]+))__(?!\s+__))$/
export const underscorePasteRegex = /(?:^|\s)(__(?!\s+__)((?:[^_]+))__(?!\s+__))/g
export const Bold = Mark.create<BoldOptions>({
name: 'bold',

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-bubble-menu
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-bubble-menu
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-bubble-menu
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-bubble-menu

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-bubble-menu",
"description": "bubble-menu extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -38,8 +38,8 @@
},
"sideEffects": false,
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0",

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-bullet-list
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-bullet-list
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-bullet-list
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-bullet-list

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-bullet-list",
"description": "bullet list extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,7 +29,7 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0"

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-character-count
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-character-count
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-character-count
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-character-count

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-character-count",
"description": "font family extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,8 +29,8 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0",

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-code-block-lowlight
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-code-block-lowlight
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-code-block-lowlight
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-code-block-lowlight

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-code-block-lowlight",
"description": "code block extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,9 +29,9 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/extension-code-block": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/extension-code-block": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0",

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-code-block
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-code-block
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-code-block
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-code-block

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-code-block",
"description": "code block extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,8 +29,8 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0",

View File

@ -3,6 +3,33 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
### Bug Fixes
* Disallow only whitespace between markdown shortcuts delimiters ([#4866](https://github.com/ueberdosis/tiptap/issues/4866)) ([aa029fe](https://github.com/ueberdosis/tiptap/commit/aa029fe2242aeadc38555b2832df6ae1614c7d1d))
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-code
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-code
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-code

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-code",
"description": "code extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,7 +29,7 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0"

View File

@ -28,8 +28,8 @@ declare module '@tiptap/core' {
}
}
export const inputRegex = /(?:^|\s)((?:`)((?:[^`]+))(?:`))$/
export const pasteRegex = /(?:^|\s)((?:`)((?:[^`]+))(?:`))/g
export const inputRegex = /(?:^|\s)(`(?!\s+`)((?:[^`]+))`(?!\s+`))$/
export const pasteRegex = /(?:^|\s)(`(?!\s+`)((?:[^`]+))`(?!\s+`))/g
export const Code = Mark.create<CodeOptions>({
name: 'code',

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-collaboration-cursor
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-collaboration-cursor
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-collaboration-cursor
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-collaboration-cursor

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-collaboration-cursor",
"description": "collaboration cursor extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,7 +29,7 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/core": "^2.2.5",
"y-prosemirror": "^1.2.1"
},
"peerDependencies": {

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-collaboration
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-collaboration
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-collaboration
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-collaboration

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-collaboration",
"description": "collaboration extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,8 +29,8 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2",
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5",
"y-prosemirror": "^1.2.1"
},
"peerDependencies": {

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-color
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-color
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-color
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-color

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-color",
"description": "text color extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,8 +29,8 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/extension-text-style": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/extension-text-style": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0",

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-document
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-document
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-document
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-document

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-document",
"description": "document extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,7 +29,7 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0"

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-dropcursor
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-dropcursor
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-dropcursor
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-dropcursor

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-dropcursor",
"description": "dropcursor extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,8 +29,8 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0",

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-floating-menu
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-floating-menu
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-floating-menu
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-floating-menu

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-floating-menu",
"description": "floating-menu extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,8 +29,8 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0",

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-focus
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-focus
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-focus
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-focus

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-focus",
"description": "focus extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,8 +29,8 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0",

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-font-family
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-font-family
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-font-family
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-font-family

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-font-family",
"description": "font family extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,8 +29,8 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/extension-text-style": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/extension-text-style": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0",

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-gapcursor
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-gapcursor
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-gapcursor
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-gapcursor

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-gapcursor",
"description": "gapcursor extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,8 +29,8 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0",

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-hard-break
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-hard-break
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-hard-break
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-hard-break

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-hard-break",
"description": "hard break extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,7 +29,7 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0"

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-heading
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-heading
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-heading
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-heading

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-heading",
"description": "heading extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,7 +29,7 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0"

View File

@ -3,6 +3,33 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
### Bug Fixes
* Disallow only whitespace between markdown shortcuts delimiters ([#4866](https://github.com/ueberdosis/tiptap/issues/4866)) ([aa029fe](https://github.com/ueberdosis/tiptap/commit/aa029fe2242aeadc38555b2832df6ae1614c7d1d))
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-highlight
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-highlight
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-highlight

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-highlight",
"description": "highlight extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,7 +29,7 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0"

View File

@ -29,8 +29,8 @@ declare module '@tiptap/core' {
}
}
export const inputRegex = /(?:^|\s)((?:==)((?:[^~=]+))(?:==))$/
export const pasteRegex = /(?:^|\s)((?:==)((?:[^~=]+))(?:==))/g
export const inputRegex = /(?:^|\s)(==(?!\s+==)((?:[^=]+))==(?!\s+==))$/
export const pasteRegex = /(?:^|\s)(==(?!\s+==)((?:[^=]+))==(?!\s+==))/g
export const Highlight = Mark.create<HighlightOptions>({
name: 'highlight',

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-history
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-history
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-history
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-history

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-history",
"description": "history extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,8 +29,8 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0",

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-horizontal-rule
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-horizontal-rule
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-horizontal-rule
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-horizontal-rule

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-horizontal-rule",
"description": "horizontal rule extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,8 +29,8 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0",

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-image
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-image
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-image
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-image

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-image",
"description": "image extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,7 +29,7 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0"

View File

@ -3,6 +3,33 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
### Bug Fixes
* Disallow only whitespace between markdown shortcuts delimiters ([#4866](https://github.com/ueberdosis/tiptap/issues/4866)) ([aa029fe](https://github.com/ueberdosis/tiptap/commit/aa029fe2242aeadc38555b2832df6ae1614c7d1d))
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-italic
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-italic
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-italic

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-italic",
"description": "italic extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,7 +29,7 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0"

View File

@ -28,10 +28,10 @@ declare module '@tiptap/core' {
}
}
export const starInputRegex = /(?:^|\s)((?:\*)((?:[^*]+))(?:\*))$/
export const starPasteRegex = /(?:^|\s)((?:\*)((?:[^*]+))(?:\*))/g
export const underscoreInputRegex = /(?:^|\s)((?:_)((?:[^_]+))(?:_))$/
export const underscorePasteRegex = /(?:^|\s)((?:_)((?:[^_]+))(?:_))/g
export const starInputRegex = /(?:^|\s)(\*(?!\s+\*)((?:[^*]+))\*(?!\s+\*))$/
export const starPasteRegex = /(?:^|\s)(\*(?!\s+\*)((?:[^*]+))\*(?!\s+\*))/g
export const underscoreInputRegex = /(?:^|\s)(_(?!\s+_)((?:[^_]+))_(?!\s+_))$/
export const underscorePasteRegex = /(?:^|\s)(_(?!\s+_)((?:[^_]+))_(?!\s+_))/g
export const Italic = Mark.create<ItalicOptions>({
name: 'italic',

View File

@ -3,6 +3,33 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
### Bug Fixes
* **extension-link:** Avoid auto-linking partial text for invalid TLDs ([#4865](https://github.com/ueberdosis/tiptap/issues/4865)) ([4474d05](https://github.com/ueberdosis/tiptap/commit/4474d056daf9280ebb10b31f98bb000e953132e5))
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-link
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-link
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-link

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-link",
"description": "link extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -32,8 +32,8 @@
"linkifyjs": "^4.1.0"
},
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0",

View File

@ -7,7 +7,29 @@ import {
} from '@tiptap/core'
import { MarkType } from '@tiptap/pm/model'
import { Plugin, PluginKey } from '@tiptap/pm/state'
import { find } from 'linkifyjs'
import { MultiToken, tokenize } from 'linkifyjs'
/**
* Check if the provided tokens form a valid link structure, which can either be a single link token
* or a link token surrounded by parentheses or square brackets.
*
* This ensures that only complete and valid text is hyperlinked, preventing cases where a valid
* top-level domain (TLD) is immediately followed by an invalid character, like a number. For
* example, with the `find` method from Linkify, entering `example.com1` would result in
* `example.com` being linked and the trailing `1` left as plain text. By using the `tokenize`
* method, we can perform more comprehensive validation on the input text.
*/
function isValidLinkStructure(tokens: Array<ReturnType<MultiToken['toObject']>>) {
if (tokens.length === 1) {
return tokens[0].isLink
}
if (tokens.length === 3 && tokens[1].isLink) {
return ['()', '[]'].includes(tokens[0].value + tokens[2].value)
}
return false
}
type AutolinkOptions = {
type: MarkType
@ -77,7 +99,13 @@ export function autolink(options: AutolinkOptions): Plugin {
return false
}
find(lastWordBeforeSpace)
const linksBeforeSpace = tokenize(lastWordBeforeSpace).map(t => t.toObject())
if (!isValidLinkStructure(linksBeforeSpace)) {
return false
}
linksBeforeSpace
.filter(link => link.isLink)
// Calculate link position.
.map(link => ({

View File

@ -162,28 +162,9 @@ export const Link = Mark.create<LinkOptions>({
addPasteRules() {
return [
markPasteRule({
find: (text, event) => {
const html = event?.clipboardData?.getData('text/html')
find: text => {
const foundLinks: PasteRuleMatch[] = []
if (html) {
const dom = new DOMParser().parseFromString(html, 'text/html')
const anchors = dom.querySelectorAll('a')
if (anchors.length) {
[...anchors].forEach(anchor => (foundLinks.push({
text: anchor.innerText,
data: {
href: anchor.getAttribute('href'),
},
// get the index of the anchor inside the text
// and add the length of the anchor text
index: dom.body.innerText.indexOf(anchor.innerText) + anchor.innerText.length,
})))
}
}
if (text) {
const links = find(text).filter(item => item.isLink)

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-list-item
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-list-item
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-list-item
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-list-item

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-list-item",
"description": "list item extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,7 +29,7 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0"

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-list-keymap
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-list-keymap
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-list-keymap
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-list-keymap

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-list-keymap",
"description": "list keymap extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,7 +29,7 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0"

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-mention
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-mention
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-mention
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-mention

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-mention",
"description": "mention extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,9 +29,9 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2",
"@tiptap/pm": "^2.2.2",
"@tiptap/suggestion": "^2.2.2"
"@tiptap/core": "^2.2.5",
"@tiptap/pm": "^2.2.5",
"@tiptap/suggestion": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0",

View File

@ -9,6 +9,7 @@ export type MentionOptions = {
renderLabel?: (props: { options: MentionOptions; node: ProseMirrorNode }) => string
renderText: (props: { options: MentionOptions; node: ProseMirrorNode }) => string
renderHTML: (props: { options: MentionOptions; node: ProseMirrorNode }) => DOMOutputSpec
deleteTriggerWithBackspace: boolean
suggestion: Omit<SuggestionOptions, 'editor'>
}
@ -23,6 +24,7 @@ export const Mention = Node.create<MentionOptions>({
renderText({ options, node }) {
return `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`
},
deleteTriggerWithBackspace: false,
renderHTML({ options, node }) {
return [
'span',
@ -177,7 +179,11 @@ export const Mention = Node.create<MentionOptions>({
state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {
if (node.type.name === this.name) {
isMention = true
tr.insertText(this.options.suggestion.char || '', pos, pos + node.nodeSize)
tr.insertText(
this.options.deleteTriggerWithBackspace ? '' : this.options.suggestion.char || '',
pos,
pos + node.nodeSize,
)
return false
}

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-ordered-list
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-ordered-list
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-ordered-list
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-ordered-list

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-ordered-list",
"description": "ordered list extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,7 +29,7 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0"

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-paragraph
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-paragraph
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-paragraph
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-paragraph

View File

@ -1,7 +1,7 @@
{
"name": "@tiptap/extension-paragraph",
"description": "paragraph extension for tiptap",
"version": "2.2.2",
"version": "2.2.5",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
@ -29,7 +29,7 @@
"dist"
],
"devDependencies": {
"@tiptap/core": "^2.2.2"
"@tiptap/core": "^2.2.5"
},
"peerDependencies": {
"@tiptap/core": "^2.0.0"

View File

@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.2.5](https://github.com/ueberdosis/tiptap/compare/v2.2.4...v2.2.5) (2024-04-05)
**Note:** Version bump only for package @tiptap/extension-placeholder
## [2.2.4](https://github.com/ueberdosis/tiptap/compare/v2.2.3...v2.2.4) (2024-02-23)
**Note:** Version bump only for package @tiptap/extension-placeholder
## [2.2.3](https://github.com/ueberdosis/tiptap/compare/v2.2.2...v2.2.3) (2024-02-15)
**Note:** Version bump only for package @tiptap/extension-placeholder
## [2.2.2](https://github.com/ueberdosis/tiptap/compare/v2.2.1...v2.2.2) (2024-02-07)
**Note:** Version bump only for package @tiptap/extension-placeholder

Some files were not shown because too many files have changed in this diff Show More