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

refactor(IText): extract draggable text logic to a delegate #8598

Merged
merged 116 commits into from Jan 20, 2023

Conversation

ShaMan123
Copy link
Contributor

@ShaMan123 ShaMan123 commented Jan 14, 2023

Motivation

making IText logic more scoped and readable
Another step forward typing text

Description

After most of DnD bugs have been fixed in #8534 I have extracted all logic to an external delegate

Changes

The following have been extracted to DraggableTextDelegate:

  • __isDragging => rename to __mouseDownInPlace and exposed as DraggableTextDelegate#isActive and as IText#shouldStartDragging for canvas
  • __dragStartFired
  • __isDraggingOver
  • __dragStartSelection
  • __dragImageDisposer
  • setDragImage
  • onDragStart (alias exposed on iText as well)
  • canDrop (alias exposed on iText as well)
  • dragEnterHandler
  • dragOverHandler
  • dragLeaveHandler
  • dragEndHandler
  • dropHandler

Changes to draggable text logic:

  • types and organizing
  • the call to start the drag lifecycle has been moved to mousedown instead of mousedown:before allowing devs to control the lifecycle 2aadf5d
  • canDrop 8bcc8a6 6fcadb8:
    • !e.defaultPrevented is now part of logic (all calls to canDrop were prefixed with it)
    • targetCanDrop is called intead of canDrop so overriding IText#canDrop will have an affect

Additional:

  • moved __lastSelected to click behavior where it belongs (selected should be moved there as well)
  • consolidated all init handler methods of click mixin into initBehavior

Gist

First merge #8534 => fix-text-dnd...text-dnd-followup

In Action

Copy link
Contributor Author

@ShaMan123 ShaMan123 left a comment

Choose a reason for hiding this comment

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

Changed some minor things the few last commits:
highlighted changes in comments.

and added some more tests

@@ -101,7 +101,7 @@ type TDestroyedCanvas = Omit<
* flag = this.canDrop(opt.e);
* });
* b.canDrop = function(e) {
* !flag && this.callSuper('canDrop', e);
* !flag && this.draggableTextDelegate.canDrop(e);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

should I move this example to DraggableTextDelegate?

* @returns {boolean} determines whether {@link target} should/shouldn't become a drop target
*/
canDrop(e: DragEvent): boolean {
if (this.target.editable && !this.target.__corner && !e.defaultPrevented) {
Copy link
Contributor Author

@ShaMan123 ShaMan123 Jan 16, 2023

Choose a reason for hiding this comment

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

changed:

-    if (this.target.editable && !this.target.__corner) {
+    if (this.target.editable && !this.target.__corner && !e.defaultPrevented) {

Comment on lines +230 to +235
/**
* in order to respect overriding {@link IText#canDrop} we call that instead of calling {@link canDrop} directly
*/
protected targetCanDrop(e: DragEvent) {
return this.target.canDrop(e);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

added

}

dragEnterHandler({ e }: DragEventData) {
const canDrop = this.targetCanDrop(e);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed:
call targetCanDrop instead of canDrop


dragOverHandler(ev: DragEventData) {
const { e } = ev;
const canDrop = this.targetCanDrop(e);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

same

@ShaMan123 ShaMan123 changed the title refactor(): extract draggable text logic to a delegate refactor(IText): extract draggable text logic to a delegate Jan 16, 2023
ShaMan123 added a commit that referenced this pull request Jan 16, 2023
const offset = correction.add(diff).transform(vpt, true);
// prepare instance for drag image snapshot by making all non selected text invisible
const bgc = target.backgroundColor;
const styles = clone(target.styles, true);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

note for merging:
#8600 will cause a merge conflict.
itext_behavior.mixin should be resolved to ours and:

Suggested change
const styles = clone(target.styles, true);
const styles = cloneDeep(target.styles);

Don't forget to adjust imports!

Copy link
Contributor Author

@ShaMan123 ShaMan123 Jan 16, 2023

Choose a reason for hiding this comment

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

And the cumbersome draggableTextDelegate assignment can go away

Comment on lines 35 to 42

// TODO: replace this with a standard assignment when shitty `clone` is removed
Object.defineProperty(this, 'draggableTextDelegate', {
value: new DraggableTextDelegate(this),
configurable: false,
enumerable: false,
writable: true,
});
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this assignment

@asturur
Copy link
Member

asturur commented Jan 19, 2023

Moving to this now.

this.on('mousedown', this.onMouseDown);

// TODO: replace this with a standard assignment when shitty `clone` is removed
Copy link
Member

Choose a reason for hiding this comment

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

i'll truncate this comment before merging up to the appropriate part.

* @public override this method to control whether instance should/shouldn't become a drop target
*/
canDrop(e: DragEvent) {
return this.draggableTextDelegate.canDrop(e);
Copy link
Member

Choose a reason for hiding this comment

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

why we would suggest to overrid the class and not create a custom draggable test delegate?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

both can be done...
I was thinking of your guideline of being able to control dnd with ease, so I felt it is best to have methods on the instance so the dev doesn't need to understand the delegate

@@ -71,6 +71,8 @@ export const isFabricObjectWithDragSupport = (
return (
!!fabricObject &&
typeof (fabricObject as FabricObjectWithDragSupport).onDragStart ===
'function' &&
typeof (fabricObject as FabricObjectWithDragSupport).shouldStartDragging ===
Copy link
Member

Choose a reason for hiding this comment

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

would be there a case in which onDragStart exists but not shouldStartDragging?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no

@asturur
Copy link
Member

asturur commented Jan 20, 2023

This PR is good as it is, but the draggableTextDelegate ( i this a good name ? ) should be somehow optional or we should have an empty one that allow for disabling the feature and not carrying te code around if not wanted.

Probably a matter of an extra class extension and everyone can import text from the preferred export.

@asturur asturur merged commit 3cd9f66 into master Jan 20, 2023
@ShaMan123 ShaMan123 deleted the text-dnd-followup branch February 5, 2023 05:16
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.

None yet

2 participants