Open krassowski opened 1 year ago
Link to the code mentioned above: https://github.com/jupyterlab/lumino/blob/133d8725f4dd2c3a56b10d917f1a7b116ff17ce8/packages/widgets/src/menu.ts#L316
Somehow related for the discussion: https://github.com/jupyterlab/lumino/issues/180
During the team call an issue of serialisation of commands (e.g. in command-linker
in JupyterLab) was raised. If we just pass events as-is, it would potentially limit some functionality for use cases where commands are sent via JSON (or loaded from file); while for the use-case of retrieving context menu event this is not a new limitation, we could consider declaring a custom IEvent
interface which would wrap the event and potentially expose some additional information, e.g. exposing a subset of event.target
DOM node as a serialisable object. This could be:
interface INodeData {
boundingBox: {x: number; y: number; height: number; width: number};
htmlString: string;
selector: string;
classNames: readonly string[];
}
interface IEvent {
target?: INodeData
// other common event data
}
boundingBox
this is essential for some commands but might be too expensive to generate for every event and it may be best avoided (though if event is generated by browser after layout it should not be that expensive... the problem is if we were to trigger forced style calculation because something changed in the DOM since the event was fired)htmlString
could be retrieved using standard XMLSerializer.serializeToString()
but:
<body>
leading to potential performance/memory issuesselector
: there is a number of algorithms generating unique selectors see 1, 2, 3; these are all cheap because they traverse DOM tree upwards; this could be later used by the command to retrieve the target node cheaply:
TextNode
(but I am not sure here)classNames
it is a common use case to check if target has some className, so we could include it:
thoughts? CC @afshin
Problem
A number of commands, e.g. in jupterlab extensions (especially editor integrations such as spellchecker or LSP), need to know the node they were triggered on. Currently JupyterLab implements a custom caching logic that holds the most recent pointer event that triggered the context menu forever (until another context menu gets opened). This leads to a memory leak.
Proposed Solution
We could reserve a special argument in the args of commands for the event the command was triggered by (if any). Since most events contain a
target
property this would solve a major headache of extension developers.This would mean that calls to
CommandRegistry.execute
would need to be adjusted to pass the event on. Conceptually this could be something like:but in practice we would probably want to adjust the signature of
execute
to avoid repetition of this operation. We would also want to make similar adjustments inisEnabled
and similar methods.Additional context