@atlaskit/editor-plugin-base
Version:
Base plugin for @atlaskit/editor-core
77 lines • 3.04 kB
JavaScript
import { lazyNodeViewDecorationPluginKey } from '@atlaskit/editor-common/lazy-node-view';
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
var LAZY_NODE_VIEW_DECORATION_CLASS = '__lazy-node-view-decoration__';
/**
* Plugin is used to force re-render NodeViews for a specific node type
* when LazyNodeView finishes loading the real NodeView.
*
* This is achieved by applying a decoration to a node.
*
* It's a blessed way that Marijn suggested multiple times in ProseMirror Discuss:
* – https://discuss.prosemirror.net/t/force-nodes-of-specific-type-to-re-render/2480
*/
export function createLazyNodeViewDecorationPlugin() {
return new SafePlugin({
key: lazyNodeViewDecorationPluginKey,
state: {
init: function init() {
return {
decorations: DecorationSet.empty,
nodeTypes: []
};
},
apply: function apply(tr, _oldState, newState) {
var actionPayload = tr.getMeta(lazyNodeViewDecorationPluginKey);
var pluginState = lazyNodeViewDecorationPluginKey.getState(newState);
if ((actionPayload === null || actionPayload === void 0 ? void 0 : actionPayload.type) === 'add' && actionPayload.nodeTypes.size) {
var decorations = [];
tr.doc.nodesBetween(0, tr.doc.nodeSize - 2, function (node, pos) {
if (actionPayload.nodeTypes.has(node.type.name)) {
decorations.push(Decoration.node(pos, pos + node.nodeSize, {
class: LAZY_NODE_VIEW_DECORATION_CLASS
}));
}
});
return {
decorations: DecorationSet.create(tr.doc, decorations)
};
}
if ((actionPayload === null || actionPayload === void 0 ? void 0 : actionPayload.type) === 'clear') {
return {
decorations: DecorationSet.empty
};
}
if (tr.docChanged) {
return {
decorations: pluginState === null || pluginState === void 0 ? void 0 : pluginState.decorations.map(tr.mapping, tr.doc)
};
}
return pluginState;
}
},
props: {
decorations: function decorations(state) {
var _lazyNodeViewDecorati;
return (_lazyNodeViewDecorati = lazyNodeViewDecorationPluginKey.getState(state)) === null || _lazyNodeViewDecorati === void 0 ? void 0 : _lazyNodeViewDecorati.decorations;
}
},
view: function view(editorView) {
return {
update: function update() {
/**
* After view update can clean up decorations...
*/
var pluginState = lazyNodeViewDecorationPluginKey.getState(editorView.state);
if (pluginState.decorations !== DecorationSet.empty) {
var tr = editorView.state.tr;
tr.setMeta(lazyNodeViewDecorationPluginKey, {
type: 'clear'
});
editorView.dispatch(tr);
}
}
};
}
});
}