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

"newEntity" event not triggered when inserting entity by formatting content model #2852

Closed
ndjonbor opened this issue Oct 30, 2024 · 7 comments

Comments

@ndjonbor
Copy link

ndjonbor commented Oct 30, 2024

Describe the bug
The "newEntity" operation is supposed to notify plugins when new entity DOM nodes are added to the editor. However, when formatting the content model with entities, no "newEntity" notifications are sent, even though new entity DOM nodes are indeed added. Other entity operation notifications, such as "click" and "removeFromEnd", work as expected.

To Reproduce

  1. Call IEditor.formatContentModel with content that includes an entity, resulting in the addition of a new entity DOM node.
  2. Observe from EditorPlugin.onPluginEvent that the "newEntity" operation does not occur.

Expected behavior
The "newEntity" operation should be triggered when formatting the content model, as new entity DOM nodes are added.

Screenshots
None

Device Information

  • OS: Win10
  • Browser chrome
  • Version 9.11.0

Additional context
I need to rehydrate entities when loading previously stored HTML. I managed to achieve this by manually triggering EntityOperationEvent with the "newEntity" operation using the onNodeCreated callback for IEditor.formatContentModel. However, I'm unsure if this approach is correct. Any advice would be appreciated. Here’s how I’m currently formatting the content model when fetching HTML from our backend:

// this method is called when loading HTML from backend, previously exported from the editor
private replaceEditorContent(editor: IEditor, content: string) {
  const newModel = createModelFromHtml(content);
  editor.formatContentModel(
    currentModel => {
      currentModel.blocks = newModel.blocks;
      return true;
    },
    {
      // workaround is here
      onNodeCreated: onExistingAutotextNodeCreated(editor)
    }
  );
}

// this is where "newEntity" is manually triggered for each new entity DOM node
export const onExistingAutotextNodeCreated =
  (editor: IEditor): OnNodeCreated =>
  (_model, node) => {
    if (!isEntityElement(node)) {
      return;
    }
    const entityFormat = parseEntityFormat(node as HTMLElement);
    const isAutotextEntity = isAutotextEntityType(entityFormat.entityType);
    if (!isAutotextEntity) {
      return;
    }

    editor.triggerEvent('entityOperation', {
      entity: {
        id: entityFormat.id!,
        type: entityFormat.entityType!,
        wrapper: node as HTMLElement,
        isReadonly: entityFormat.isReadonly!
      },
      operation: 'newEntity'
    });
  };
@ndjonbor ndjonbor changed the title EntityOperationEvent with operation "newEntity" does not fire when formatting content model EntityOperationEvent with operation "newEntity" is not triggered when formatting content model Oct 30, 2024
@ndjonbor ndjonbor changed the title EntityOperationEvent with operation "newEntity" is not triggered when formatting content model "newEntity" event not triggered when inserting entity by formatting content model Oct 30, 2024
@JiuqingSong
Copy link
Collaborator

@ndjonbor Please provide a minimum repro of "content" so we can try end to end repro.

Thanks.

@ndjonbor
Copy link
Author

ndjonbor commented Oct 30, 2024

@JiuqingSong

No prob, here you go. Btw, this is also what the content looks like when exporting the editor HTML for saving to our backend.

const exampleContent = '<div style="margin-left: 0; font-family: Arial"><span class="_Entity _EType_SpecTitle _EId_SpecTitle _EReadonly_1" style="color: inherit"></span></div>';

After inserting the content, the DOM looks like this: (I excluded the editor container div here)

<div style="margin-left: 0px; font-family: Arial">
  <span class="entityDelimiterBefore" style="font-size: 10pt"></span
  ><span
    style=""
    class="_Entity _EType_SpecTitle _EId_SpecTitle _EReadonly_1"
    contenteditable="false"
    >[00 Title]</span
  ><span class="entityDelimiterAfter" style="font-size: 10pt"></span>
</div>

@JiuqingSong
Copy link
Collaborator

Got it.

For now, we don't do auto detection of new entity from formatContentModel API to improve performance. And we assume in your code you can know if there is new entity is inserted. Then you can leverage the context parameter of formatContentModel callback and set your new entity into the newEntities array, then entityOperation event will be triggered.

I have built a sample here: https://codepen.io/jiuqingsong/pen/zYgjXVX

Just click the "Test" button, you should get a dialog showing the new entity Id:

Image

@ndjonbor
Copy link
Author

ndjonbor commented Nov 1, 2024

@JiuqingSong

For now, we don't do auto detection of new entity from formatContentModel API to improve performance.

Gotcha, that's reasonable.

And we assume in your code you can know if there is new entity is inserted. Then you can leverage the context parameter of formatContentModel callback and set your new entity into the newEntities array, then entityOperation event will be triggered.

Aha, using the context is something I wasn't even aware of. Doing it that way will be a bit cleaner, and work just fine 👍 Thanks for looking into it, and for the sample!

EDIT:
I'm closing this, since there are no plans to change current behavior, and I can confirm the suggested solution works nicely.

@ndjonbor ndjonbor closed this as completed Nov 1, 2024
@JiuqingSong
Copy link
Collaborator

Maybe we can add a parameter to allow auto detecting of new entities, then you don't need to do that manually.

@JiuqingSong
Copy link
Collaborator

#2855

@ndjonbor
Copy link
Author

ndjonbor commented Nov 1, 2024

Yes, I did have to adjust a little bit in order to detect new inline entities within list elements, for example. Given the use case of entity lifecycles and hydration/dehydration, I think something like that would be useful. 👍

I'm subscribed to the new issue you linked, keeping my eyes peeled

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

No branches or pull requests

2 participants