I am writing a Plugin that includes several NodeViews in its props. The plugin also maintains some global state that all of the NodeViews created by this plugin need to know about. Accordingly, each of the callbacks I provide to props.nodeViews
must get the current plugin state before returning a NodeView
.
(below is a simplified example – see also the real code on GitHub)
interface IPluginState { specialNumber:number };
let pluginKey = new PluginKey<IPluginState>("my-plugin");
let pluginSpec:PluginSpec<IPluginState> = {
key: pluginKey,
state: {
init(config, instance){
return { specialNumber: 5 };
},
apply(tr, value, oldState, newState){
let pluginState = mathPluginKey.getState(oldState);
if(pluginState) { /* do something state-dependent */ }
return value;
},
},
props: {
nodeViews: {
"my_nodeview" : function(node: ProseNode, view: EditorView, getPos:boolean|(()=>number)) {
/** @todo is this necessary?
* Docs says that for any function proprs, the current plugin instance
* will be bound to `this`. However, the typings don't reflect this.
*/
let pluginState = pluginKey.getState(view.state);
if(!pluginState){ throw new Error("no plugin found!"); }
// THIS is unbound
console.log(this) // <-- prints `undefined`
// set up NodeView
return new MyNodeView(
node, view, getPos as (() => number),
pluginState.specialNumber
);
}
}
}
};
Question
This solution works, but the dependence on the external pluginKey
seems not ideal, and (without getting into too much detail) is getting in the way as I try to refactor my plugin to be a bit more flexible if users need extra customization. My question is:
When ProseMirror creates a
NodeView
using a function specified in theprops.nodeViews
map of aPlugin
, is there a more elegant way to get the current state of that plugin?
For instance, the documentation for PluginSpec.props
says that
“Props that are functions will be bound to have the plugin instance as their
this
binding.”
However, this seems not to apply to the functions passed to props.nodeViews
, which appear to be unbound (this === undefined
) when called. (I dug through the ProseMirror source a bit to find out where these are actually called, but wasn’t successful in finding the actual call location since the relevant code is split across multiple repositories. Help locating the source would be appreciated!)
Possible Solutions
- Continue using the pluginKey to get the current plugin state, although this is not ideal because of the dependence on a global variable.
- When calling one of the functions specified in
props.nodeViews
, bindthis
to the current plugin instance - (Suggestions Welcome!)
Thanks!