Create a new detached LoroText (not attached to any LoroDoc).
The edits on a detached container will not be persisted. To attach the container to the document, please insert it into an attached container.
Readonly
idGet the container id of the text.
Readonly
lengthGet the length of text (utf-16 length).
Change the state of this text by delta.
If a delta item is insert
, it should include all the attributes of the inserted text.
Loro's rich text CRDT may make the inserted text inherit some styles when you use
insert
method directly. However, when you use applyDelta
if some attributes are
inherited from CRDT but not included in the delta, they will be removed.
Another special property of applyDelta
is if you format an attribute for ranges out of
the text length, Loro will insert new lines to fill the gap first. It's useful when you
build the binding between Loro and rich text editors like Quill, which might assume there
is always a newline at the end of the text implicitly.
const doc = new LoroDoc();
const text = doc.getText("text");
doc.configTextStyle({bold: {expand: "after"}});
text.insert(0, "Hello World!");
text.mark({ start: 0, end: 5 }, "bold", true);
const delta = text.toDelta();
const text2 = doc.getText("text2");
text2.applyDelta(delta);
expect(text2.toDelta()).toStrictEqual(delta);
Get the attached container associated with this.
Returns an attached Container
that is equal to this or created by this; otherwise, it returns undefined
.
Get the cursor position at the given pos.
When expressing the position of a cursor, using "index" can be unstable because the cursor's position may change due to other deletions and insertions, requiring updates with each edit. To stably represent a position or range within a list structure, we can utilize the ID of each item/character on List CRDT or Text CRDT for expression.
Loro optimizes State metadata by not storing the IDs of deleted elements. This approach complicates tracking cursors since they rely on these IDs. The solution recalculates position by replaying relevant history to update cursors accurately. To minimize the performance impact of history replay, the system updates cursor info to reference only the IDs of currently present elements, thereby reducing the need for replay.
Optional
side: SideGet the editor of the text at the given position.
Get the shallow value of the text. This equals to text.toString()
.
Whether the container is attached to a LoroDoc.
If it's detached, the operations on the container will not be persisted.
Check if the container is deleted
Iterate each text span(internal storage unit)
The callback function will be called for each span in the text.
If the callback returns false
, the iteration will stop.
Limitation: you cannot access or alter the doc state when iterating (this is for performance consideration).
If you need to access or alter the doc state, please use toString
instead.
"Text"
Mark a range of text with a key and a value (utf-16 index).
You should call
configTextStyle
before usingmark
andunmark
.
You can use it to create a highlight, make a range of text bold, or add a link to a range of text.
Note: this is not suitable for unmergeable annotations like comments.
Get the parent container.
undefined
.Push a string to the end of the text.
Delete and return the string at the given range and insert a string at the same position (utf-16 index).
Get the text in Delta format.
The returned value will include the rich text information.
import { LoroDoc } from "loro-crdt";
const doc = new LoroDoc();
const text = doc.getText("text");
doc.configTextStyle({bold: {expand: "after"}});
text.insert(0, "Hello World!");
text.mark({ start: 0, end: 5 }, "bold", true);
console.log(text.toDelta()); // [ { insert: 'Hello', attributes: { bold: true } } ]
Get the JSON representation of the text.
Convert the text to a string
Unmark a range of text with a key and a value (utf-16 index).
You should call
configTextStyle
before usingmark
andunmark
.
You can use it to remove highlights, bolds or links
Update the current text to the target text.
It will calculate the minimal difference and apply it to the current text. It uses Myers' diff algorithm to compute the optimal difference.
This could take a long time for large texts (e.g. > 50_000 characters).
In that case, you should use updateByLine
instead.
Optional
options: TextUpdateOptionsUpdate the current text based on the provided text. This update calculation is line-based, which will be more efficient but less precise.
Optional
options: TextUpdateOptions
The handler of a text container. It supports rich text CRDT.
Learn more at https://loro.dev/docs/tutorial/text