Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

modularize yDocToProsemirrorJSON to Y.XmlText and Y.XmlElement #64

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

BrianHung
Copy link
Contributor

@BrianHung BrianHung commented Aug 17, 2021

Motivation for this PR is to separate out Y.XmlFragment from Y.XmlElement in the scenario of using a custom top-level document with type, attrs, and marks defined.

Related:
https://discuss.yjs.dev/t/y-prosemirror-ydoctoprosemirrorjson-root-node-type-is-always-doc/642
#48

sync-plugin still needs to be refactored to allow for XmlElement to be a top-level document, and #63 is related because the new YXmlElementToProsemirrorJSON method assumes node-level marks are stored as an array in type.getAttribute('marks). Also in #63, node-level marks are serialized using toJSON() which is pretty convenient for this PR as well.

Copy link
Member

@dmonad dmonad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @BrianHung,

thanks for working on this. I will give this PR another review if you leave the existing API functional. Unless there is a good reason, we can't change the arguments or the names of the functions without breaking existing code.

@@ -469,8 +469,7 @@ const createTextNodesFromYText = (text, schema, mapping, snapshot, prevSnapshot,
const nodes = []
const deltas = text.toDelta(snapshot, prevSnapshot, computeYChange)
try {
for (let i = 0; i < deltas.length; i++) {
const delta = deltas[i]
for (const delta in deltas) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use for-in loops for arrays as they fail to transpile in old typescript versions. I deliberately only use normal for loops.

src/lib.js Outdated
const items = ydoc.getXmlFragment(xmlFragment).toArray()
return {
type: 'doc',
content: items.map(typeToProseMirrorJSON).flat()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .flat() method is a fairly recent addition to EcmaScript. Please use import { flatten } from 'lib0/array' instead.

@SamDuvall
Copy link

@BrianHung, @dmonad, I don't think yDocToProsemirrorJSON is the correct signature to convert a Y.XmlFragment to JSON. In my mind, a Y.XmlFragment is an array of Nodes, not a Node with type 'doc'.

See my PR here: #53

@BrianHung
Copy link
Contributor Author

I don't think yDocToProsemirrorJSON is the correct signature to convert a Y.XmlFragment to JSON. In my mind, a Y.XmlFragment is an array of Nodes, not a Node with type 'doc'.

@SamDuvall I agree with both of your points about separating yDoc from Y.XmlFragment. YXmlFragmentToProsemirrorJSON is pretty simple with the newly modularized functions -- just needed that serialize function to be outside of it -- so I've added that as well.

@BrianHung BrianHung force-pushed the modularize-yDocToProsemirrorJSON branch from fc36506 to ce9d0d3 Compare August 17, 2021 19:33
@BrianHung BrianHung requested a review from dmonad August 17, 2021 19:37
@dmonad
Copy link
Member

dmonad commented Aug 18, 2021

Thanks to @BrianHung and @SamDuvall we now have two competing implementations 🤔

#53
#64

After reviewing this I think you are right that we should change the signature. I would be fine with making another major release for this feature. Could you both please communicate and come up with a solution that works for both of you. I'll merge the version that you both reviewed and agree with. Thanks!

@SamDuvall
Copy link

This PR has everything I need for converting Y.Xml* to JSON. I am happy to abandon #53 and then create a new PR that focuses on JSON to X.XmlFragment.

@BrianHung
Copy link
Contributor Author

we should change the signature

To clarify, this would mean in essence deprecating yDocToProsemirrorJSON in favor of the other two utility methods YXmlFragmentToProsemirrorJSON and YXmlElementToProsemirrorJSON?

Because if we change the signature of yDocToProsemirrorJSON to return "an array of Nodes" as Sam suggested, that would be equivalent to YXmlFragmentToProsemirrorJSON.

In my view, deprecating yDocToProsemirrorJSON would be good because it'd force the end user to explicitly work with YXMLFragment or YXMLElement instead of that being abstracted behind Y.Doc and a field.

Those using the new API but want the old abstraction of yDocToProsemirrorJSON can easily migrate by:

// Previously
let json = yDocToProsemirrorJSON(ydoc)

// Now
let xmlFragment = ydoc.getXmlFragment('prosemirror')
let json = {type: 'doc', content: YXmlFragmentToProsemirrorJSON(xmlFragment)}

@SamDuvall
Copy link

If we're doing a major version bump, then I agree with @BrianHung's proposal to just delete yDocToProsemirrorJSON, so long as there is a clear explanation in the release notes.

@dmonad, if we did a major version bump, would you be okay with taking #34 as-is or would you still like a PR that is backwards-compatible? I'm coming across some issues with annotations/comment/suggestions that would benefit greatly from marks of the same type (e.g. comment) being allowed.

Copy link
Contributor

@flaviouk flaviouk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be a great addition!

I also need to be able to set prosemirror content json to a YFragment, I believe updateYFragment does this, but I'm curious if we should create a separate PR for that:
#53

@EricHasegawa
Copy link

Any updates here? Having the same issue needing overlapping nodes with different attributes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants