Skip to content

Commit

Permalink
fix(extension-events): fix marks matching for hover event (#1981)
Browse files Browse the repository at this point in the history
  • Loading branch information
ocavue committed Jan 15, 2023
1 parent af1c212 commit 8307249
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/beige-jokes-juggle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@remirror/extension-events': patch
---

This patch fixes an issue where `EventsExtension` cannot get the marks with [`inclusive`](https://prosemirror.net/docs/ref/#model.MarkSpec.inclusive) set to `false` for a `hover` event.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { jest } from '@jest/globals';
import { fireEvent } from '@testing-library/dom';
import { extensionValidityTest, renderEditor } from 'jest-remirror';
import { LinkExtension } from 'remirror/extensions';

import { ContextMenuEventHandlerState, EventsExtension, HoverEventHandlerState } from '../';

Expand Down Expand Up @@ -100,26 +101,58 @@ describe('events', () => {
it('responds to editor `hover` events', () => {
const eventsExtension = new EventsExtension();
const hoverHandler: any = jest.fn((_: MouseEvent, __: HoverEventHandlerState) => true);
const editor = renderEditor([eventsExtension]);
const editor = renderEditor([eventsExtension, new LinkExtension()]);
const { doc, p } = editor.nodes;
const { link } = editor.attributeMarks;
eventsExtension.addHandler('hover', hoverHandler);

editor.add(doc(p('first')));
fireEvent.mouseOver(editor.dom.querySelector('p') as Element);
editor.add(
doc(p('paragraph 1'), p('paragraph 2', link({ href: 'https://example.com' })('link'))),
);

const paragraphElement = editor.dom.querySelector('p') as Element;
expect(paragraphElement.textContent).toBe('paragraph 1');

fireEvent.mouseOver(paragraphElement);

expect(hoverHandler).toHaveBeenCalledTimes(1);
expect(hoverHandler.mock.calls[0]?.[0]).toBeInstanceOf(Event);
expect(hoverHandler.mock.calls[0]?.[1]).not.toHaveProperty('event');
expect(hoverHandler.mock.calls[0]?.[1]?.getNode).toBeFunction();
expect(hoverHandler.mock.calls[0]?.[1]).toHaveProperty('hovering', true);
expect(hoverHandler.mock.calls[0]?.[1]?.marks).toHaveLength(0);

fireEvent.mouseOut(editor.dom.querySelector('p') as Element);
fireEvent.mouseOut(paragraphElement);

expect(hoverHandler).toHaveBeenCalledTimes(2);
expect(hoverHandler.mock.calls[1]?.[0]).toBeInstanceOf(Event);
expect(hoverHandler.mock.calls[1]?.[1]).not.toHaveProperty('event');
expect(hoverHandler.mock.calls[1]?.[1]?.getNode).toBeFunction();
expect(hoverHandler.mock.calls[1]?.[1]).toHaveProperty('hovering', false);
expect(hoverHandler.mock.calls[1]?.[1]?.marks).toHaveLength(0);

const linkElement = editor.dom.querySelector('a') as Element;
expect(linkElement.attributes.getNamedItem('href')?.value).toBe('https://example.com');

fireEvent.mouseOver(linkElement);

expect(hoverHandler).toHaveBeenCalledTimes(3);
expect(hoverHandler.mock.calls[2]?.[0]).toBeInstanceOf(Event);
expect(hoverHandler.mock.calls[2]?.[1]).not.toHaveProperty('event');
expect(hoverHandler.mock.calls[2]?.[1]?.getNode).toBeFunction();
expect(hoverHandler.mock.calls[2]?.[1]).toHaveProperty('hovering', true);
expect(hoverHandler.mock.calls[2]?.[1]?.marks).toHaveLength(1);
expect(hoverHandler.mock.calls[2]?.[1]?.marks[0].mark.type.name).toBe('link');

fireEvent.mouseOut(linkElement);

expect(hoverHandler).toHaveBeenCalledTimes(4);
expect(hoverHandler.mock.calls[3]?.[0]).toBeInstanceOf(Event);
expect(hoverHandler.mock.calls[3]?.[1]).not.toHaveProperty('event');
expect(hoverHandler.mock.calls[3]?.[1]?.getNode).toBeFunction();
expect(hoverHandler.mock.calls[3]?.[1]).toHaveProperty('hovering', false);
expect(hoverHandler.mock.calls[3]?.[1]?.marks).toHaveLength(1);
expect(hoverHandler.mock.calls[3]?.[1]?.marks[0].mark.type.name).toBe('link');
});

it('responds to editor `contextmenu` events', () => {
Expand Down
6 changes: 3 additions & 3 deletions packages/remirror__extension-events/src/events-extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ export class EventsExtension extends PlainExtension<EventsOptions> {
// The marks wrapping the captured position.
const marks: GetMarkRange[] = [];

const { inside } = eventPosition;
const { inside, pos } = eventPosition;

// This handle the case when the context menu click has no corresponding
// nodes or marks because it's outside of any editor content.
Expand All @@ -538,7 +538,7 @@ export class EventsExtension extends PlainExtension<EventsOptions> {
}

// Retrieve the resolved position from the current state.
const $pos = view.state.doc.resolve(inside);
const $pos = view.state.doc.resolve(pos);

// The depth of the current node (which is a direct match)
const currentNodeDepth = $pos.depth + 1;
Expand All @@ -552,7 +552,7 @@ export class EventsExtension extends PlainExtension<EventsOptions> {
}

// Populate the marks.
for (const { type } of $pos.marks()) {
for (const { type } of $pos.marksAcross($pos) ?? []) {
const range = getMarkRange($pos, type);

if (range) {
Expand Down

1 comment on commit 8307249

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

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

🎉 Published on https://remirror.io as production
🚀 Deployed on https://63c41ad3b5ccdf6b7f47c0fd--remirror.netlify.app

Please sign in to comment.