-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
There should be some way exclude DOM events fired by certain UIElements from default handlers #4600
Comments
Things to remember that not all blame is on The solution is to make some events transparent to CKEditor since we cannot call First thought (looks kinda bad but kinda OK at the same moment): decorate event with some uniqally enough property ( import {
makeEventTransparentForCKEditor
} from '@ckeditor/ckeditor5-utils/dom/transparentevents';
domElement.addEventListener( 'focus', ( ev t) => {
makeEventTransparentForCKEditor( evt );
}, { capture: true } );
// let's say something like this;
makeEventTransparentForCKEditor( evt ) {
evt.__ckEventPreventDefault = true; // or evt[ eventSymbol ] = true;
}; or even: import { hideEventsFromTheEditor } from '@ckeditor/ckeditor5-utils/dom/transparentevents';
hideEventsFromTheEditor( domElement ); The above will add previous listener for all events that are handled by CKEditor ('click', 'mousedown', etc). The editor features will skip such events or maybe event better our |
Related issue: #4465. The workaround posted there may actually be resolving the issues mentioned in this ticket. |
Idea: Use |
I pushed https://github.com/ckeditor/ckeditor5/compare/i/4600 with a prototype and it works just fine. Better than I thought. |
And I found a better workaround than what we had in #4465: [
'click', 'mousedown', 'mouseup', 'mousemove', 'paste', 'cut', 'copy', 'drop', 'focus', 'blur', 'beforeinput', 'keydown', 'keyup'
].forEach( eventName => {
editor.editing.view.document.on( eventName, ( evt, data ) => {
if ( data.domTarget.matches( '[data-cke-ignore-events], [data-cke-ignore-events] *' ) ) {
evt.stop();
}
}, { priority: 999999999 } );
} ); It's still not as reliable as what we can introduce inside observers (e.g. does not cover focus or selection, although, I don't know how important are those), but it seems to work in cases that I tested. |
Did you test it within a React app? |
Yes, I did prototype it with a React app. |
I have a problem with adding support for I thought that it may be a problem with native contentEditable=true/false, but it works fine in https://jsfiddle.net/5d761g4j/. So, there's something that we do differently. Perhaps some listener that I'm not aware of or some styling that's applied in the editor. Unfortunately, this will require more thorough investigation. |
Oh, I think I know the answer. The fix that I did for selectionchange is stupid. Selectionchange's target is always the document. And I've just added code that check whether |
Doh, blocking selection change does not have any effect on this. I also checked that blocking the renderer does not help either. And that we don't style the Finally, I checked that To debug this further, we'd need to start stripping next layers of what CKEditor 5 adds over contentEditable, but this will be extremely time-consuming. For now, |
@Reinmar Did you get a chance to test with |
Regarding the documentation part:
|
…ll not propagate it's events to CKEditor API. Closes #4600.
🎉 |
@Reinmar , I have a div say 'xyz' inside UIElement and both has "data-cke-ignore-events" to be true. I made the div 'xyz' to be contenteditable by using native contenteditable attribute.. But it doesn't work. If I click on the div, focus is going back to editor content. Not able to click and have caret inside the div inside the UIElement. |
Problem
ATM the widget takes over the DOM events like mousedown (also keydown, delete) and processes them as it thinks fit.
I realized when implementing #1509 that this behaviour causes some issues. For instance, because
mousedown
is handled by the widget, I wasn't able to create any dynamic form elements (<select>
) using React inside aUIElement
in the widget. They render, that's alright, but you can't click them, focus etc. because widget wants to handle everything.What I thought was a solution
Unfortunately the problem is not as simple as "remove custom [event] handling when even target is
UIElement
or a descendant" because by doing this, we'd prevent widget selection when anUIElement
is clicked, for instance a media widget usesUIElement
to display the YouTube preview, and we definitely want clicking it to focus the widget.I also tried to attach a native DOM
mousedown
listener on the<select>
I rendered, and stop propagation of the event before it reaches the editable, before CKEditor's widget logick kicks in. I would make sense except that... React uses a single global listener for each event and it heavily depends on the fact that the event does bubble towards the root of the application. Stopping it like that simply breaks React so it's a dead–end.An actual solution
What I guess we need is some API to tell the widget that a particual
HTMLElement
should be excluded from custom event handling.How do we do that?
cc @jodator @Reinmar @mlewand
The text was updated successfully, but these errors were encountered: