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

Test: Move the merge block handler to the actions file and unit test it #769

Merged
merged 2 commits into from
May 16, 2017

Conversation

youknowriad
Copy link
Contributor

@youknowriad youknowriad commented May 11, 2017

I'm planning to work on the "forward merge", before this, I've moved the mergeBlocks action creator into actions.js and unit test it.

Side note: We start having action creators that take "dispatch" as a parameter and others that return actions, we should probably decide to include thunks or an alternative soon.

Edit: The last commit adds forward deletion and should close #506

@youknowriad youknowriad added the Framework Issues related to broader framework topics, especially as it relates to javascript label May 11, 2017
@youknowriad youknowriad self-assigned this May 11, 2017
@youknowriad youknowriad requested a review from aduth May 11, 2017 10:53
this.onChange();
this.props.onMerge( this.editor.getContent() );
this.props.onMerge( forward );
Copy link
Member

@aduth aduth May 12, 2017

Choose a reason for hiding this comment

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

I really don't like the idea of Editable assuming a context with the editor's store, but it sure would be nice if onMerge here were the connected dispatch, wouldn't it? 😄 Since it means blocks wouldn't need to pass this through at all.

Copy link
Contributor Author

@youknowriad youknowriad May 12, 2017

Choose a reason for hiding this comment

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

Yes, but it's not that simple. Imagine a block having multiple editables. So the merge of the last one would probably merge its content with the previous one (or do nothing) but the merge of the first editable would actually trigger the merge with the previous block.

It could be way simpler if it's one block = one editable, but that's not the case. Could we provide more "metadata" on how the block uses the editable in this case and fallback to one editable mergeable with the previous block if this metadata is not provided? I don't know but that's something we should think about.

example:

edit() {
  return (
    <div>
       <Editable value={ attributes.content } mergeWithPrevious />
       <Editable onMerge={ mergeWithAttribute( 'content' ) } />
       <Editable noMerge />
    </div>
  );
}

Copy link
Member

Choose a reason for hiding this comment

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

Imagine a block having multiple editables.

Ah, that's a good point. I hadn't considered this.

Could we provide more "metadata" on how the block uses the editable

Interesting idea. I think at the point where we're saying a block implementer needs to be concerned with merge behavior (and it's fairly obvious they do), I'm not as much concerned about accepting and applying the onMerge prop handling anymore.

It could be slightly more optimized if Editable were able to handle this by hints, but I'm not sure a clean way we can connect the Editable to the editor's store without tying it directly to the editor (not so great).

Copy link
Member

Choose a reason for hiding this comment

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

To your points here, do you think it's obvious to the block implementer what's happening when they pass mergeBlocks to an editable, specifically in merging with a previous block, next block, or between editables of the same block?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think this should be well documented. It's not obvious at all for now but I don't have any alternative. We should enhance our block API documentation once it's more stable.

Copy link
Member

Choose a reason for hiding this comment

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

cc @mtias since we'd chatted about this topic today. Maybe for the sake of simplicity we don't allow complex merging within a block, and try to make editor smarter about knowing how to handle Editables. It's a very fuzzy desire, but maybe traversing returned element to find first or last editable to decide how to merge into previous or next. @mtias indicated some desire to avoid merging and transforms being responsibility of block at all, which sounds nice; difficult to pull off 😄 But I think it'd be fair to make some compromises about what merging can be performed if it helps simplify.

I don't think this needs to be settled here; in fact, mergeBlocks could very well be compatible with this future desire. Just a matter of using context to communicate directly between VisualEditorBlock and Editable to avoid block needing to handle directly.

Copy link
Member

Choose a reason for hiding this comment

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

I missed this comment @aduth. Let's create an issue for this so we don't lose sight of it.

Copy link
Member

Choose a reason for hiding this comment

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

I missed this comment @aduth. Let's create an issue for this so we don't lose sight of it.

See #878

@aduth
Copy link
Member

aduth commented May 15, 2017

Side note: We start having action creators that take "dispatch" as a parameter and others that return actions, we should probably decide to include thunks or an alternative soon.

Related: #691

Do you have any opinions on this? I've actually been leaning toward thunks a bit; even if I personally dislike their data "impurity", it's hard to argue that they're not simple to use, which could be a big win for what's already a complicated setup.

I'll plan to do a proper review of the changes here shortly.

@youknowriad
Copy link
Contributor Author

@aduth I have a personal preference for generators, redux-saga is a bit complex though, so I use a personal library in general https://github.com/youknowriad/redux-rungen. But this is a lot to handle I think, requires a certain mastery of generators. Thus, I'm also leaning towards thunks to avoid having a steep learning curve.

Copy link
Member

@aduth aduth left a comment

Choose a reason for hiding this comment

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

This looks good 👍

@@ -41,3 +57,42 @@ export function savePost( dispatch, postId, edits ) {
} );
} );
}

export function mergeBlocks( dispatch, blockA, blockB ) {
Copy link
Member

Choose a reason for hiding this comment

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

Similar to what we did with concatChildren, I wonder if this needs to be necessarily limited to merging two blocks (unless it becomes much more complex).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes not as easy as concatChildren, because merging blocks could produce several blocks, merging only the first paragraph. I'm thinking we could do this recursively, but I don't see much value to support this for now.

@youknowriad youknowriad merged commit 4a89530 into master May 16, 2017
@mtias mtias deleted the test/merge-block-action branch May 16, 2017 09:40
@BE-Webdesign
Copy link
Contributor

Do you have any opinions on this? I've actually been leaning toward thunks a bit; even if I personally dislike their data "impurity", it's hard to argue that they're not simple to use, which could be a big win for what's already a complicated setup.
I'll plan to do a proper review of the changes here shortly.

I can see refx being more valuable than thunks. Thunks can pin you into a corner when you want to have dispatched actions trigger other side effects, rather than having whole new action creators added to the codebase. By using a refx-esque approach you can incrementally build complexity on top of the action flow already happening. When auto drafting is implemented, that would be somewhat tricky to do in thunks, but pretty easy to manage with refx. The downside is that it might be more hidden as to what is actually happening when using a library like refx, as the flow of actions is no longer hard coupled to the action creators' functions. Even considering that, I think refx is the right choice, as it will be more flexible and easy to use and maybe the code can document that refx side effects are occurring. If a developer is new to Redux, thunks and refx will both be foreign, so trying to pick a simple to use solution won't provide much benefit to them in my opinion. Even though thunks are more commonplace (probably who knows), I think refx is a better choice and is equally simple to use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Framework Issues related to broader framework topics, especially as it relates to javascript
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Blocks: Handle forward deletion merge
4 participants