They've always been called extensions, not sure why the folder was plugins. Part of ongoing spring cleaning
76 lines
2.1 KiB
TypeScript
76 lines
2.1 KiB
TypeScript
import { Plugin } from "prosemirror-state";
|
|
import { findBlockNodes } from "prosemirror-utils";
|
|
import { Decoration, DecorationSet } from "prosemirror-view";
|
|
import Storage from "../../utils/Storage";
|
|
import Extension from "../lib/Extension";
|
|
import { headingToPersistenceKey } from "../lib/headingToSlug";
|
|
import findCollapsedNodes from "../queries/findCollapsedNodes";
|
|
|
|
export default class Folding extends Extension {
|
|
get name() {
|
|
return "folding";
|
|
}
|
|
|
|
get plugins() {
|
|
let loaded = false;
|
|
|
|
return [
|
|
new Plugin({
|
|
view: (view) => {
|
|
loaded = false;
|
|
view.dispatch(view.state.tr.setMeta("folding", { loaded: true }));
|
|
return {};
|
|
},
|
|
appendTransaction: (transactions, oldState, newState) => {
|
|
if (loaded) {
|
|
return;
|
|
}
|
|
if (
|
|
!transactions.some((transaction) => transaction.getMeta("folding"))
|
|
) {
|
|
return;
|
|
}
|
|
|
|
let modified = false;
|
|
const tr = newState.tr;
|
|
const blocks = findBlockNodes(newState.doc);
|
|
|
|
for (const block of blocks) {
|
|
if (block.node.type.name === "heading") {
|
|
const persistKey = headingToPersistenceKey(
|
|
block.node,
|
|
this.editor.props.id
|
|
);
|
|
const persistedState = Storage.get(persistKey);
|
|
|
|
if (persistedState === "collapsed") {
|
|
tr.setNodeMarkup(block.pos, undefined, {
|
|
...block.node.attrs,
|
|
collapsed: true,
|
|
});
|
|
modified = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
loaded = true;
|
|
return modified ? tr : null;
|
|
},
|
|
props: {
|
|
decorations: (state) => {
|
|
const { doc } = state;
|
|
const decorations: Decoration[] = findCollapsedNodes(doc).map(
|
|
(block) =>
|
|
Decoration.node(block.pos, block.pos + block.node.nodeSize, {
|
|
class: "folded-content",
|
|
})
|
|
);
|
|
|
|
return DecorationSet.create(doc, decorations);
|
|
},
|
|
},
|
|
}),
|
|
];
|
|
}
|
|
}
|