Closed deeg closed 1 year ago
The Quill implementation of the Delta format has a lot of weird edge cases that are specific to the Quill editor. I don't expect them to be fully compatible. That's why in the y-quill editor binding, I do some sanity transformations before I apply Deltas to the Yjs document.
Here is an edge case that Yjs handles differently than Quill:
// assume you have a `ytext` with the rich-text content "a*b*" (b is bold).
ytext.applyDelta([{ retain: 1 }, { insert: 'X' }])
// Then both "a*Xb*" and "aX*b*" are valid outcomes because you didn't specify any formatting attributes in the delta.
// However, the below approach should always yield the same result
ytext.applyDelta([retain: 1}, {insert: 'X', attributes: {}}]) // specify that X shouldn't have attributes.
So I suggest you try setting empty attributes specifically, so they don't get inherited.
@dmonad , thanks for the quick response!
The Quill implementation of the Delta format has a lot of weird edge cases that are specific to the Quill editor. I don't expect them to be fully compatible. That's why in the y-quill editor binding, I do some sanity transformations before I apply Deltas to the Yjs document.
We are following all of the same formatting that you are doing int he y-quill
binding.
The issue seems to be with this delta
const addingList = [
{
"retain": 12
},
{
"delete": 2
},
{
"retain": 1,
"attributes": {
// Clear table line attribute
"table-cell-line": null,
// Add list attribute in place of table-cell-line
"list": {
"rowspan": "1",
"colspan": "1",
"row": "row-pflz90",
"cell": "cell-20b0j9",
"list": "bullet"
}
}
}
]
It doesn't like that table-cell-line
attribute is null. If I split this delta up into two events, it works as expected:
Delta 1:
[ {
'retain': 12,
attributes: {}
},
{
'delete': 2,
attributes: {}
}]
Delta 2:
[{
'retain': 12,
attributes: {}
},
{
'retain': 1,
'attributes': {
'table-cell-line': null,
'list': {
'rowspan': '1',
'colspan': '1',
'row': 'row-pflz90',
'cell': 'cell-20b0j9',
'list': 'bullet'
}
}
}]
So I suggest you try setting empty attributes specifically, so they don't get inherited.
I tried this, but it doesn't seem to fix the problem.
Do you have any other suggestions on how to ensure we always get the same end state with yDoc and Delta formats?
FYI: Setting an attribute to null should remove the attribute. I'm not sure if that is still the case in the Quill Delta format.
If you set up some minimal reproduction case (in code), I'd have a look at it. Since the above Delta is huge with presumably a lot of edge-cases, I haven't run it yet.
@dmonad I will make a smaller example and send that too.
All of the original code is linked at the bottom in a Zip file and can be easily run.
Delta does remove the attribute correctly with null, and it still says it should work that way according to their docs.
YJS does handle it okay sometimes, but not in the case of this specific delta.
@dmonad here is a smaller example with a table with two cells.
If you unzip and run npm i
you should be able to run the example.
I have also included JSON files of the different outputs to easily inspect them.
Please let me know if you would like me to provide anything else!
Seems like potentially related: https://github.com/yjs/yjs/issues/302
Hi @deeg,
Thanks for the debugging case. This should be fixed in the latest release!
Checklist
Describe the bug
Applying delta operations to a yText document ends up with a different final state than if applying those same delta operations to a Delta object directly outside of YJS.
To Reproduce
-
characters and adds a list into the table cellExpected behavior
With a plain Delta object this returns the following end state
Notice how at the end the operation with the
list
attribute does not have anytable-cell-line
. There is also notable-cell-line
below the operation withlist
attribute.End state with YJS
Notice how at the end the operation with the
list
attribute also hastable-cell-line
attribute. There are alsotable-cell-line
attributes below that operation when there should not be.Diff between the two end states
Environment Information
Code sample: yjs-playground.zip
Huly®: YJS-335