Skip to content

Commit

Permalink
feat(YfmCut): add border to editable yfm-cut nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
d3m1d0v committed Feb 15, 2024
1 parent 21fdd74 commit 408cf7e
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/extensions/yfm/YfmCut/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@

.ProseMirror.yfm .yfm-cut {
@include mixins.block-border-hover();

&.yfm-cut-active {
border-color: var(--g-color-line-generic);
}
}
2 changes: 2 additions & 0 deletions src/extensions/yfm/YfmCut/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {createYfmCut, toYfmCut} from './actions/toYfmCut';
import {backToCutTitle, exitFromCutTitle, liftEmptyBlockFromCut, removeCut} from './commands';
import {cutType} from './const';
import {YfmCutTitleNodeView} from './nodeviews/yfm-cut-title';
import {cutActivePlugin} from './plugins/active';
import {cutAutoOpenPlugin} from './plugins/auto-open';

import './index.scss';
Expand Down Expand Up @@ -39,6 +40,7 @@ export const YfmCut: ExtensionAuto<YfmCutOptions> = (builder, opts) => {
});

builder
.addPlugin(cutActivePlugin)
.addPlugin(cutAutoOpenPlugin)
.addAction(cutAction, () => toYfmCut)
.addKeymap(() => ({
Expand Down
65 changes: 65 additions & 0 deletions src/extensions/yfm/YfmCut/plugins/active.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import type {NodeType, ResolvedPos} from 'prosemirror-model';
import {Plugin} from 'prosemirror-state';
import type {NodeWithPos} from 'prosemirror-utils';
import {Decoration, DecorationSet} from 'prosemirror-view';

import {isNodeSelection, isTextSelection} from '../../../../utils/selection';
import {cutType} from '../const';

const YFM_CUT_ACTIVE_CLASSNAME = 'yfm-cut-active';

export const cutActivePlugin = () => {
return new Plugin({
props: {
decorations(state) {
const decos: Decoration[] = [];
const sel = state.selection;
const yfmCutType = cutType(state.schema);

const createDeco = ({pos, node}: NodeWithPos) => {
decos.push(
Decoration.node(pos, pos + node.nodeSize, {
class: YFM_CUT_ACTIVE_CLASSNAME,
}),
);
};

if (isNodeSelection(sel)) {
if (sel.node.type === yfmCutType) createDeco({pos: sel.from, node: sel.node});
findParentNodesOfType(yfmCutType, sel.$from).forEach(createDeco);
} else if (isTextSelection(sel)) {
findParentNodesOfType(yfmCutType, sel.$from).forEach(createDeco);
if (!sel.$from.sameParent(sel.$to)) {
findParentNodesOfType(yfmCutType, sel.$to).forEach(createDeco);
state.doc.nodesBetween(sel.from, sel.to, (node, pos) => {
if (node.type === yfmCutType) createDeco({pos, node});
if (node.isTextblock) return false;
return true;
});
}
} else {
// some other selection
findParentNodesOfType(yfmCutType, sel.$from).forEach(createDeco);
}

return decos.length ? DecorationSet.create(state.doc, decos) : DecorationSet.empty;
},
},
});
};

function findParentNodesOfType(
type: NodeType,
$pos: ResolvedPos,
): (NodeWithPos & {depth: number})[] {
let {depth} = $pos;
const nodes: (NodeWithPos & {depth: number})[] = [];

while (depth >= 0) {
const node = $pos.node(depth);
if (node.type === type) nodes.push({depth, node, pos: $pos.before(depth)});
depth--;
}

return nodes;
}

0 comments on commit 408cf7e

Please sign in to comment.