Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: content node for yfm note #161

Merged
merged 1 commit into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 83 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"tslib": "^2.3.1"
},
"devDependencies": {
"@diplodoc/transform": "4.2.1",
"@diplodoc/transform": "4.5.0",
"@gravity-ui/components": "2.0.0",
"@gravity-ui/eslint-config": "1.0.2",
"@gravity-ui/prettier-config": "1.0.1",
Expand Down Expand Up @@ -111,7 +111,7 @@
"typescript": "^4.5.2"
},
"peerDependencies": {
"@diplodoc/transform": "^4.0.0",
"@diplodoc/transform": "^4.5.0",
"@gravity-ui/components": "^2.0.0",
"@gravity-ui/uikit": "^5.0.0",
"lodash": "^4.17.20",
Expand Down
25 changes: 17 additions & 8 deletions src/extensions/yfm/YfmNote/YfmNote.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const {schema, parser, serializer} = new ExtensionsManager({
.use(ImageSpecs),
}).buildDeps();

const {doc, p, i, bq, img, note, noteTitle} = builders(schema, {
const {doc, p, i, bq, img, note, noteTitle, noteContent} = builders(schema, {
doc: {nodeType: BaseNode.Doc},
p: {nodeType: BaseNode.Paragraph},
i: {markType: italicMarkName},
Expand All @@ -37,7 +37,8 @@ const {doc, p, i, bq, img, note, noteTitle} = builders(schema, {
[NoteAttrs.Class]: 'yfm-note yfm-accent-info',
},
noteTitle: {nodeType: NoteNode.NoteTitle},
}) as PMTestBuilderResult<'doc' | 'p' | 'bq' | 'img' | 'note' | 'noteTitle', 'i'>;
noteContent: {nodeType: NoteNode.NoteContent},
}) as PMTestBuilderResult<'doc' | 'p' | 'bq' | 'img' | 'note' | 'noteTitle' | 'noteContent', 'i'>;

const {same} = createMarkupChecker({parser, serializer});

Expand All @@ -53,7 +54,10 @@ note content 2
{% endnote %}
`.trim();

same(markup, doc(note(noteTitle('note title'), p('note content'), p('note content 2'))));
same(
markup,
doc(note(noteTitle('note title'), noteContent(p('note content'), p('note content 2')))),
);
});

it('should parse nested yfm-notes', () => {
Expand All @@ -71,7 +75,12 @@ note content

same(
markup,
doc(note(noteTitle('note title'), note(noteTitle('note title 2'), p('note content')))),
doc(
note(
noteTitle('note title'),
noteContent(note(noteTitle('note title 2'), noteContent(p('note content')))),
),
),
);
});

Expand All @@ -84,7 +93,7 @@ note content
> {% endnote %}
`.trim();

same(markup, doc(bq(note(noteTitle('note title'), p('note content')))));
same(markup, doc(bq(note(noteTitle('note title'), noteContent(p('note content'))))));
});

it('should parse yfm-note with inline markup in note title', () => {
Expand All @@ -96,7 +105,7 @@ note content
{% endnote %}
`.trim();

same(markup, doc(note(noteTitle(i('note italic title')), p('note content'))));
same(markup, doc(note(noteTitle(i('note italic title')), noteContent(p('note content')))));
});

it('should parse yfm-note with inline node in note title', () => {
Expand All @@ -118,7 +127,7 @@ note content
[ImageAttr.Alt]: 'img',
}),
),
p('note content'),
noteContent(p('note content')),
),
),
);
Expand All @@ -132,7 +141,7 @@ note content
'<p class="yfm-note-title">YfmNote title</p>' +
'<p>YfmNote content</p>' +
'</div></div>',
doc(note(noteTitle('YfmNote title'), p('YfmNote content'))),
doc(note(noteTitle('YfmNote title'), noteContent(p('YfmNote content')))),
);
});
});
1 change: 1 addition & 0 deletions src/extensions/yfm/YfmNote/YfmNoteSpecs/const.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export enum NoteNode {
Note = 'yfm_note',
NoteTitle = 'yfm_note_title',
NoteContent = 'yfm_note_content',
}

export enum NoteAttrs {
Expand Down
1 change: 1 addition & 0 deletions src/extensions/yfm/YfmNote/YfmNoteSpecs/fromYfm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export const fromYfm: Record<NoteNode, ParserToken> = {
getAttrs: (token) => (token.attrs ? Object.fromEntries(token.attrs) : {}),
},
[NoteNode.NoteTitle]: {name: NoteNode.NoteTitle, type: 'block'},
[NoteNode.NoteContent]: {name: NoteNode.NoteContent, type: 'block'},
};
7 changes: 7 additions & 0 deletions src/extensions/yfm/YfmNote/YfmNoteSpecs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,12 @@ export const YfmNoteSpecs: ExtensionAuto<YfmNoteSpecsOptions> = (builder, opts)
fromYfm: {
tokenSpec: fromYfm[NoteNode.NoteTitle],
},
}))
.addNode(NoteNode.NoteContent, () => ({
spec: spec[NoteNode.NoteContent],
toYfm: toYfm[NoteNode.NoteContent],
fromYfm: {
tokenSpec: fromYfm[NoteNode.NoteContent],
},
}));
};
23 changes: 22 additions & 1 deletion src/extensions/yfm/YfmNote/YfmNoteSpecs/spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {NoteAttrs, NoteNode} from './const';
import {PlaceholderOptions} from '../../../../utils/placeholder';

const DEFAULT_TITLE_PLACEHOLDER = 'Note';
const DEFAULT_CONTENT_PLACEHOLDER = 'Note content';

export const getSpec = (
opts?: YfmNoteSpecsOptions,
Expand All @@ -14,7 +15,7 @@ export const getSpec = (
[NoteAttrs.Class]: {default: 'yfm-note yfm-accent-info'},
[NoteAttrs.Type]: {default: 'info'},
},
content: `${NoteNode.NoteTitle} block+`,
content: `${NoteNode.NoteTitle} ${NoteNode.NoteContent}`,
group: 'block yfm-note',
parseDOM: [
{
Expand Down Expand Up @@ -57,4 +58,24 @@ export const getSpec = (
},
complex: 'leaf',
},
[NoteNode.NoteContent]: {
content: '(block | paragraph)+',
group: 'block yfm-note',
parseDOM: [
{
tag: 'div.yfm-note-content',
priority: 100,
},
],
toDOM() {
return ['div', {class: 'yfm-note-content'}, 0];
},
selectable: false,
allowSelection: false,
placeholder: {
content: placeholder?.[NoteNode.NoteContent] ?? DEFAULT_CONTENT_PLACEHOLDER,
alwaysVisible: true,
},
complex: 'leaf',
},
});
6 changes: 6 additions & 0 deletions src/extensions/yfm/YfmNote/YfmNoteSpecs/toYfm.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {isNodeEmpty} from '../../../../utils/nodes';
import type {SerializerNodeToken} from '../../../../core';
import {getPlaceholderContent} from '../../../../utils/placeholder';
import {NoteAttrs, NoteNode} from './const';
Expand All @@ -23,4 +24,9 @@ export const toYfm: Record<NoteNode, SerializerNodeToken> = {
state.write('\n');
state.closeBlock();
},

[NoteNode.NoteContent]: (state, node) => {
if (!isNodeEmpty(node)) state.renderInline(node);
else state.write(getPlaceholderContent(node) + '\n\n');
},
};
1 change: 1 addition & 0 deletions src/extensions/yfm/YfmNote/YfmNoteSpecs/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ import {NoteNode} from './const';

export const noteType = nodeTypeFactory(NoteNode.Note);
export const noteTitleType = nodeTypeFactory(NoteNode.NoteTitle);
export const noteContentType = nodeTypeFactory(NoteNode.NoteContent);
7 changes: 5 additions & 2 deletions src/extensions/yfm/YfmNote/actions/toYfmNote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {Command, EditorState} from 'prosemirror-state';
import {findParentNodeOfType, hasParentNodeOfType} from 'prosemirror-utils';
import type {ActionSpec} from '../../../../core';
import {NoteAttrs} from '../const';
import {noteTitleType, noteType} from '../utils';
import {noteContentType, noteTitleType, noteType} from '../utils';

export function isInsideYfmNote(state: EditorState) {
return hasParentNodeOfType(noteType(state.schema))(state.selection);
Expand All @@ -17,7 +17,10 @@ const createYfmNoteNode = (schema: Schema) => (type: YfmNoteType, content: Node
[NoteAttrs.Class]: `yfm-note yfm-accent-${type}`,
[NoteAttrs.Type]: type,
},
[noteTitleType(schema).createAndFill()!].concat(content),
[
noteTitleType(schema).createAndFill()!,
noteContentType(schema).createAndFill({}, content)!,
],
);
};

Expand Down
Loading