@lblod/ember-rdfa-editor-lblod-plugins 19.3.1 → 20.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +3 -0
- package/CHANGELOG.md +14 -0
- package/addon/components/besluit-topic-plugin/besluit-topic-toolbar-dropdown.ts +8 -10
- package/addon/components/besluit-type-plugin/toolbar-dropdown.ts +4 -20
- package/addon/components/decision-plugin/decision-plugin-card.gts +231 -0
- package/addon/components/decision-plugin/insert-article.gts +81 -0
- package/addon/components/hover-tooltip.gts +68 -0
- package/addon/components/prosemirror-editor.hbs +15 -0
- package/addon/components/prosemirror-editor.ts +98 -0
- package/addon/components/roadsign-regulation-plugin/roadsign-regulation-card.ts +16 -19
- package/addon/components/roadsign-regulation-plugin/roadsigns-modal.ts +23 -3
- package/addon/components/structure-plugin/_private/control-card.gts +192 -0
- package/addon/components/structure-plugin/_private/structure.gts +159 -0
- package/addon/plugins/besluit-topic-plugin/utils/helpers.ts +19 -10
- package/addon/plugins/decision-plugin/commands/insert-article-command.ts +82 -0
- package/addon/plugins/decision-plugin/commands/insert-article-container.ts +33 -35
- package/addon/plugins/decision-plugin/commands/insert-description.ts +31 -28
- package/addon/plugins/decision-plugin/commands/insert-motivation.ts +106 -106
- package/addon/plugins/decision-plugin/commands/insert-title.ts +30 -28
- package/addon/plugins/decision-plugin/utils/build-article-structure.ts +44 -0
- package/addon/plugins/roadsign-regulation-plugin/index.ts +1 -0
- package/addon/plugins/structure-plugin/move-structure.ts +120 -0
- package/addon/plugins/structure-plugin/node.ts +148 -0
- package/addon/plugins/structure-plugin/recalculate-structure-numbers.ts +28 -0
- package/addon/utils/find-insertion-pos-in-node.ts +21 -0
- package/addon/utils/nested-prosemirror.ts +111 -0
- package/app/styles/structure-plugin.scss +53 -0
- package/declarations/addon/components/besluit-topic-plugin/besluit-topic-toolbar-dropdown.d.ts +2 -1
- package/declarations/addon/components/besluit-type-plugin/toolbar-dropdown.d.ts +1 -2
- package/declarations/addon/components/decision-plugin/decision-plugin-card.d.ts +20 -11
- package/declarations/addon/components/decision-plugin/insert-article.d.ts +23 -0
- package/declarations/addon/components/hover-tooltip.d.ts +26 -9
- package/declarations/addon/components/prosemirror-editor.d.ts +23 -0
- package/declarations/addon/components/roadsign-regulation-plugin/roadsigns-modal.d.ts +6 -0
- package/declarations/addon/components/structure-plugin/_private/control-card.d.ts +22 -0
- package/declarations/addon/components/structure-plugin/_private/structure.d.ts +32 -0
- package/declarations/addon/plugins/besluit-topic-plugin/utils/helpers.d.ts +2 -2
- package/declarations/addon/plugins/decision-plugin/commands/insert-article-command.d.ts +8 -0
- package/declarations/addon/plugins/decision-plugin/commands/insert-article-container.d.ts +4 -2
- package/declarations/addon/plugins/decision-plugin/commands/insert-description.d.ts +3 -2
- package/declarations/addon/plugins/decision-plugin/commands/insert-motivation.d.ts +3 -2
- package/declarations/addon/plugins/decision-plugin/commands/insert-title.d.ts +3 -2
- package/declarations/addon/plugins/decision-plugin/utils/build-article-structure.d.ts +2 -0
- package/declarations/addon/plugins/roadsign-regulation-plugin/index.d.ts +1 -0
- package/declarations/addon/plugins/structure-plugin/move-structure.d.ts +2 -0
- package/declarations/addon/plugins/structure-plugin/node.d.ts +4 -0
- package/declarations/addon/plugins/structure-plugin/recalculate-structure-numbers.d.ts +3 -0
- package/declarations/addon/utils/find-insertion-pos-in-node.d.ts +3 -0
- package/declarations/addon/utils/nested-prosemirror.d.ts +23 -0
- package/package.json +10 -5
- package/pnpm-lock.yaml +73 -14
- package/translations/en-US.yaml +9 -0
- package/translations/nl-BE.yaml +10 -3
- package/types/ember-power-select/components/power-select.d.ts +3 -3
- package/addon/components/decision-plugin/decision-plugin-card.hbs +0 -55
- package/addon/components/decision-plugin/decision-plugin-card.ts +0 -71
- package/addon/components/hover-tooltip.hbs +0 -12
- package/addon/components/hover-tooltip.ts +0 -41
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
} from '@lblod/ember-rdfa-editor';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { findInsertionPosInAncestorOfType } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/find-insertion-pos-in-ancestor-of-type';
|
|
1
|
+
import { EditorState, Transaction } from '@lblod/ember-rdfa-editor';
|
|
2
|
+
import { NodeWithPos } from '@curvenote/prosemirror-utils';
|
|
3
|
+
import { v4 as uuid } from 'uuid';
|
|
4
|
+
import { addPropertyToNode } from '@lblod/ember-rdfa-editor/utils/rdfa-utils';
|
|
5
|
+
import { ELI } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
|
|
6
|
+
import { SayDataFactory } from '@lblod/ember-rdfa-editor/core/say-data-factory';
|
|
7
|
+
import { transactionCombinator } from '@lblod/ember-rdfa-editor/utils/transaction-utils';
|
|
9
8
|
|
|
10
9
|
interface InsertDescriptionArgs {
|
|
11
10
|
placeholderText: string;
|
|
12
|
-
|
|
11
|
+
decisionLocation: NodeWithPos;
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
export default function insertDescription({
|
|
16
15
|
placeholderText,
|
|
17
|
-
|
|
16
|
+
decisionLocation,
|
|
18
17
|
}: InsertDescriptionArgs) {
|
|
19
18
|
return function (state: EditorState, dispatch?: (tr: Transaction) => void) {
|
|
20
|
-
const {
|
|
19
|
+
const { schema } = state;
|
|
20
|
+
const descriptionId = uuid();
|
|
21
21
|
const nodeToInsert = schema.node(
|
|
22
|
-
'
|
|
23
|
-
{},
|
|
22
|
+
'block_rdfa',
|
|
23
|
+
{ rdfaNodeType: 'literal', __rdfaId: descriptionId },
|
|
24
24
|
schema.node(
|
|
25
25
|
'paragraph',
|
|
26
26
|
null,
|
|
@@ -29,23 +29,26 @@ export default function insertDescription({
|
|
|
29
29
|
}),
|
|
30
30
|
),
|
|
31
31
|
);
|
|
32
|
-
const insertionPos = findInsertionPosInAncestorOfType(
|
|
33
|
-
selection,
|
|
34
|
-
schema.nodes.besluit,
|
|
35
|
-
nodeToInsert,
|
|
36
|
-
);
|
|
37
|
-
if (isNone(insertionPos)) {
|
|
38
|
-
return false;
|
|
39
|
-
}
|
|
40
32
|
const tr = state.tr;
|
|
41
33
|
|
|
42
|
-
tr.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
tr
|
|
48
|
-
|
|
34
|
+
tr.replaceSelectionWith(nodeToInsert);
|
|
35
|
+
|
|
36
|
+
const factory = new SayDataFactory();
|
|
37
|
+
const { transaction: newTr, result } = transactionCombinator<boolean>(
|
|
38
|
+
state,
|
|
39
|
+
tr,
|
|
40
|
+
)([
|
|
41
|
+
addPropertyToNode({
|
|
42
|
+
resource: decisionLocation.node.attrs.subject,
|
|
43
|
+
property: {
|
|
44
|
+
predicate: ELI('description').full,
|
|
45
|
+
object: factory.literalNode(descriptionId),
|
|
46
|
+
},
|
|
47
|
+
}),
|
|
48
|
+
]);
|
|
49
|
+
if (dispatch && result.every((ok) => ok)) {
|
|
50
|
+
// newTr.setSelection(NodeSelection.create(newTr.doc, insertionPos + 2));
|
|
51
|
+
dispatch(newTr.scrollIntoView());
|
|
49
52
|
}
|
|
50
53
|
return true;
|
|
51
54
|
};
|
|
@@ -1,135 +1,135 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Command,
|
|
3
|
-
EditorState,
|
|
4
|
-
NodeSelection,
|
|
5
|
-
Transaction,
|
|
6
|
-
} from '@lblod/ember-rdfa-editor';
|
|
7
|
-
import { isNone } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
|
|
8
|
-
import { transactionCompliesWithShapes } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/validation/utils/transaction-complies-with-shapes';
|
|
9
|
-
import { findInsertionPosInAncestorOfType } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/find-insertion-pos-in-ancestor-of-type';
|
|
1
|
+
import { Command, EditorState, Transaction } from '@lblod/ember-rdfa-editor';
|
|
10
2
|
import IntlService from 'ember-intl/services/intl';
|
|
11
3
|
import { getTranslationFunction } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/translation';
|
|
4
|
+
import { BESLUIT } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
|
|
5
|
+
import { NodeWithPos } from '@curvenote/prosemirror-utils';
|
|
6
|
+
import { v4 as uuid } from 'uuid';
|
|
7
|
+
import { addPropertyToNode } from '@lblod/ember-rdfa-editor/utils/_private/rdfa-utils';
|
|
8
|
+
import { SayDataFactory } from '@lblod/ember-rdfa-editor/core/say-data-factory';
|
|
9
|
+
import { transactionCombinator } from '@lblod/ember-rdfa-editor/utils/transaction-utils';
|
|
12
10
|
|
|
13
11
|
interface InsertMotivationArgs {
|
|
14
12
|
intl: IntlService;
|
|
15
|
-
|
|
13
|
+
decisionLocation: NodeWithPos;
|
|
16
14
|
}
|
|
17
15
|
|
|
18
16
|
export default function insertMotivation({
|
|
19
17
|
intl,
|
|
20
|
-
|
|
18
|
+
decisionLocation,
|
|
21
19
|
}: InsertMotivationArgs): Command {
|
|
22
20
|
return function (state: EditorState, dispatch?: (tr: Transaction) => void) {
|
|
23
21
|
const translationWithDocLang = getTranslationFunction(state);
|
|
24
|
-
const {
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
22
|
+
const { schema } = state;
|
|
23
|
+
const decisionNode = decisionLocation;
|
|
24
|
+
const motivationId = uuid();
|
|
25
|
+
const nodeToInsert = schema.node(
|
|
26
|
+
'block_rdfa',
|
|
27
|
+
{ rdfaNodeType: 'literal', __rdfaId: motivationId },
|
|
28
|
+
[
|
|
29
|
+
schema.node(
|
|
30
|
+
'paragraph',
|
|
31
|
+
null,
|
|
32
|
+
schema.node('placeholder', {
|
|
33
|
+
placeholderText: translationWithDocLang(
|
|
34
|
+
'besluit-plugin.placeholder.government-body',
|
|
35
|
+
intl.t('besluit-plugin.placeholder.government-body'),
|
|
36
|
+
),
|
|
37
|
+
}),
|
|
38
|
+
),
|
|
39
|
+
schema.node(
|
|
40
|
+
'heading',
|
|
41
|
+
{
|
|
42
|
+
level: 5,
|
|
43
|
+
},
|
|
44
|
+
[schema.text(intl.t('besluit-plugin.text.authority'))],
|
|
45
|
+
),
|
|
46
|
+
schema.node('bullet_list', null, [
|
|
47
|
+
schema.node('list_item', null, [
|
|
48
|
+
schema.node('paragraph', null, [
|
|
49
|
+
schema.node('placeholder', {
|
|
50
|
+
placeholderText: translationWithDocLang(
|
|
51
|
+
'besluit-plugin.placeholder.legal-jurisdiction',
|
|
52
|
+
intl.t('besluit-plugin.placeholder.legal-jurisdiction'),
|
|
53
|
+
),
|
|
54
|
+
}),
|
|
55
|
+
]),
|
|
52
56
|
]),
|
|
53
57
|
]),
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
intl.t('besluit-plugin.text.legal-context'),
|
|
65
|
-
),
|
|
66
|
-
),
|
|
67
|
-
],
|
|
68
|
-
),
|
|
69
|
-
schema.node('bullet_list', null, [
|
|
70
|
-
schema.node('list_item', null, [
|
|
71
|
-
schema.node('paragraph', null, [
|
|
72
|
-
schema.node('placeholder', {
|
|
73
|
-
placeholderText: translationWithDocLang(
|
|
74
|
-
'besluit-plugin.placeholder.insert-legal-context',
|
|
75
|
-
intl.t('besluit-plugin.placeholder.insert-legal-context'),
|
|
58
|
+
schema.node(
|
|
59
|
+
'heading',
|
|
60
|
+
{
|
|
61
|
+
level: 5,
|
|
62
|
+
},
|
|
63
|
+
[
|
|
64
|
+
schema.text(
|
|
65
|
+
translationWithDocLang(
|
|
66
|
+
'besluit-plugin.text.legal-context',
|
|
67
|
+
intl.t('besluit-plugin.text.legal-context'),
|
|
76
68
|
),
|
|
77
|
-
|
|
69
|
+
),
|
|
70
|
+
],
|
|
71
|
+
),
|
|
72
|
+
schema.node('bullet_list', null, [
|
|
73
|
+
schema.node('list_item', null, [
|
|
74
|
+
schema.node('paragraph', null, [
|
|
75
|
+
schema.node('placeholder', {
|
|
76
|
+
placeholderText: translationWithDocLang(
|
|
77
|
+
'besluit-plugin.placeholder.insert-legal-context',
|
|
78
|
+
intl.t('besluit-plugin.placeholder.insert-legal-context'),
|
|
79
|
+
),
|
|
80
|
+
}),
|
|
81
|
+
]),
|
|
78
82
|
]),
|
|
79
83
|
]),
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
intl.t('besluit-plugin.text.factual-context'),
|
|
91
|
-
),
|
|
92
|
-
),
|
|
93
|
-
],
|
|
94
|
-
),
|
|
95
|
-
schema.node('bullet_list', null, [
|
|
96
|
-
schema.node('list_item', null, [
|
|
97
|
-
schema.node('paragraph', null, [
|
|
98
|
-
schema.node('placeholder', {
|
|
99
|
-
placeholderText: translationWithDocLang(
|
|
100
|
-
'besluit-plugin.placeholder.insert-factual-context',
|
|
101
|
-
intl.t('besluit-plugin.placeholder.insert-factual-context'),
|
|
84
|
+
schema.node(
|
|
85
|
+
'heading',
|
|
86
|
+
{
|
|
87
|
+
level: 5,
|
|
88
|
+
},
|
|
89
|
+
[
|
|
90
|
+
schema.text(
|
|
91
|
+
translationWithDocLang(
|
|
92
|
+
'besluit-plugin.text.factual-context',
|
|
93
|
+
intl.t('besluit-plugin.text.factual-context'),
|
|
102
94
|
),
|
|
103
|
-
|
|
95
|
+
),
|
|
96
|
+
],
|
|
97
|
+
),
|
|
98
|
+
schema.node('bullet_list', null, [
|
|
99
|
+
schema.node('list_item', null, [
|
|
100
|
+
schema.node('paragraph', null, [
|
|
101
|
+
schema.node('placeholder', {
|
|
102
|
+
placeholderText: translationWithDocLang(
|
|
103
|
+
'besluit-plugin.placeholder.insert-factual-context',
|
|
104
|
+
intl.t('besluit-plugin.placeholder.insert-factual-context'),
|
|
105
|
+
),
|
|
106
|
+
}),
|
|
107
|
+
]),
|
|
104
108
|
]),
|
|
105
109
|
]),
|
|
106
|
-
]
|
|
107
|
-
]);
|
|
108
|
-
// how the offset between the insertion point and the point where the cursor should end up
|
|
109
|
-
const cursorOffset = 2;
|
|
110
|
-
|
|
111
|
-
const insertionPos = findInsertionPosInAncestorOfType(
|
|
112
|
-
selection,
|
|
113
|
-
schema.nodes.besluit,
|
|
114
|
-
nodeToInsert,
|
|
110
|
+
],
|
|
115
111
|
);
|
|
116
|
-
if (isNone(insertionPos)) {
|
|
117
|
-
return false;
|
|
118
|
-
}
|
|
119
112
|
const tr = state.tr;
|
|
113
|
+
tr.replaceSelectionWith(nodeToInsert);
|
|
114
|
+
const factory = new SayDataFactory();
|
|
120
115
|
|
|
121
|
-
|
|
122
|
-
|
|
116
|
+
const { transaction: newTr, result } = transactionCombinator<boolean>(
|
|
117
|
+
state,
|
|
118
|
+
tr,
|
|
119
|
+
)([
|
|
120
|
+
addPropertyToNode({
|
|
121
|
+
resource: decisionNode.node.attrs.subject,
|
|
122
|
+
property: {
|
|
123
|
+
predicate: BESLUIT('motivering').full,
|
|
124
|
+
object: factory.literalNode(motivationId),
|
|
125
|
+
},
|
|
126
|
+
}),
|
|
127
|
+
]);
|
|
128
|
+
if (result.some((success) => !success)) {
|
|
123
129
|
return false;
|
|
124
130
|
}
|
|
125
131
|
if (dispatch) {
|
|
126
|
-
|
|
127
|
-
// const targetPos = tr.doc.resolve(insertionPos + cursorOffset + 1);
|
|
128
|
-
// TODO figure out why I cant just set a nodeSelection here
|
|
129
|
-
tr.setSelection(
|
|
130
|
-
new NodeSelection(tr.doc.resolve(selectionPos.posAtIndex(0))),
|
|
131
|
-
);
|
|
132
|
-
dispatch(tr);
|
|
132
|
+
dispatch(newTr);
|
|
133
133
|
}
|
|
134
134
|
return true;
|
|
135
135
|
};
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
} from '@lblod/ember-rdfa-editor';
|
|
7
|
-
import {
|
|
8
|
-
import { findInsertionPosInAncestorOfType } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/find-insertion-pos-in-ancestor-of-type';
|
|
1
|
+
import { EditorState, Transaction } from '@lblod/ember-rdfa-editor';
|
|
2
|
+
import { NodeWithPos } from '@curvenote/prosemirror-utils';
|
|
3
|
+
import { v4 as uuid } from 'uuid';
|
|
4
|
+
import { addPropertyToNode } from '@lblod/ember-rdfa-editor/utils/rdfa-utils';
|
|
5
|
+
import { ELI } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
|
|
6
|
+
import { SayDataFactory } from '@lblod/ember-rdfa-editor/core/say-data-factory';
|
|
7
|
+
import { transactionCombinator } from '@lblod/ember-rdfa-editor/utils/transaction-utils';
|
|
9
8
|
|
|
10
9
|
interface InsertTitleArgs {
|
|
11
10
|
placeholderText: string;
|
|
12
|
-
|
|
11
|
+
decisionLocation: NodeWithPos;
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
export default function insertTitle({
|
|
16
15
|
placeholderText,
|
|
17
|
-
|
|
16
|
+
decisionLocation,
|
|
18
17
|
}: InsertTitleArgs) {
|
|
19
18
|
return function (state: EditorState, dispatch?: (tr: Transaction) => void) {
|
|
20
|
-
const {
|
|
19
|
+
const { schema } = state;
|
|
20
|
+
const titleId = uuid();
|
|
21
21
|
const nodeToInsert = schema.node(
|
|
22
|
-
'
|
|
23
|
-
{},
|
|
22
|
+
'block_rdfa',
|
|
23
|
+
{ rdfaNodeType: 'literal', __rdfaId: titleId },
|
|
24
24
|
schema.node(
|
|
25
25
|
'paragraph',
|
|
26
26
|
null,
|
|
@@ -30,23 +30,25 @@ export default function insertTitle({
|
|
|
30
30
|
),
|
|
31
31
|
);
|
|
32
32
|
|
|
33
|
-
const insertionPos = findInsertionPosInAncestorOfType(
|
|
34
|
-
selection,
|
|
35
|
-
schema.nodes.besluit,
|
|
36
|
-
nodeToInsert,
|
|
37
|
-
);
|
|
38
|
-
if (isNone(insertionPos)) {
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
33
|
const tr = state.tr;
|
|
42
|
-
tr.
|
|
34
|
+
tr.replaceSelectionWith(nodeToInsert);
|
|
43
35
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
36
|
+
const factory = new SayDataFactory();
|
|
37
|
+
const { transaction: newTr, result } = transactionCombinator<boolean>(
|
|
38
|
+
state,
|
|
39
|
+
tr,
|
|
40
|
+
)([
|
|
41
|
+
addPropertyToNode({
|
|
42
|
+
resource: decisionLocation.node.attrs.subject,
|
|
43
|
+
property: {
|
|
44
|
+
predicate: ELI('title').full,
|
|
45
|
+
object: factory.literalNode(titleId),
|
|
46
|
+
},
|
|
47
|
+
}),
|
|
48
|
+
]);
|
|
49
|
+
if (dispatch && result.every((ok) => ok)) {
|
|
50
|
+
// newTr.setSelection(NodeSelection.create(newTr.doc, insertionPos + 2));
|
|
51
|
+
dispatch(newTr.scrollIntoView());
|
|
50
52
|
}
|
|
51
53
|
return true;
|
|
52
54
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Schema } from '@lblod/ember-rdfa-editor';
|
|
2
|
+
import {
|
|
3
|
+
BESLUIT,
|
|
4
|
+
RDF,
|
|
5
|
+
} from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
|
|
6
|
+
import { OutgoingTriple } from '@lblod/ember-rdfa-editor/core/rdfa-processor';
|
|
7
|
+
import { SayDataFactory } from '@lblod/ember-rdfa-editor/core/say-data-factory';
|
|
8
|
+
import { v4 as uuid } from 'uuid';
|
|
9
|
+
|
|
10
|
+
export function buildArticleStructure(
|
|
11
|
+
schema: Schema,
|
|
12
|
+
uriGenerator?: () => string,
|
|
13
|
+
) {
|
|
14
|
+
let articleResource: string;
|
|
15
|
+
if (uriGenerator) {
|
|
16
|
+
articleResource = uriGenerator();
|
|
17
|
+
} else {
|
|
18
|
+
const articleId = uuid();
|
|
19
|
+
articleResource = `http://data.lblod.info/artikels/--ref-uuid4-${articleId}`;
|
|
20
|
+
}
|
|
21
|
+
const factory = new SayDataFactory();
|
|
22
|
+
return schema.node(
|
|
23
|
+
'structure',
|
|
24
|
+
{
|
|
25
|
+
rdfaNodeType: 'resource',
|
|
26
|
+
properties: [
|
|
27
|
+
{
|
|
28
|
+
predicate: RDF('type').full,
|
|
29
|
+
object: factory.namedNode(BESLUIT('Artikel').full),
|
|
30
|
+
},
|
|
31
|
+
] satisfies OutgoingTriple[],
|
|
32
|
+
hasTitle: true,
|
|
33
|
+
title: '',
|
|
34
|
+
structureName: 'Artikel',
|
|
35
|
+
headerTag: 'h5',
|
|
36
|
+
subject: articleResource,
|
|
37
|
+
},
|
|
38
|
+
schema.node(
|
|
39
|
+
'paragraph',
|
|
40
|
+
{},
|
|
41
|
+
schema.node('placeholder', { placeholderText: 'Voeg inhoud artikel in' }),
|
|
42
|
+
),
|
|
43
|
+
);
|
|
44
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Command,
|
|
3
|
+
PNode,
|
|
4
|
+
ResolvedPos,
|
|
5
|
+
TextSelection,
|
|
6
|
+
} from '@lblod/ember-rdfa-editor';
|
|
7
|
+
import { findAncestorOfType } from '../article-structure-plugin/utils/structure';
|
|
8
|
+
import {
|
|
9
|
+
findNodePosDown,
|
|
10
|
+
findNodePosUp,
|
|
11
|
+
} from '@lblod/ember-rdfa-editor/utils/position-utils';
|
|
12
|
+
import {
|
|
13
|
+
isNone,
|
|
14
|
+
unwrap,
|
|
15
|
+
} from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
|
|
16
|
+
import { recalculateNumbers } from './recalculate-structure-numbers';
|
|
17
|
+
import { transactionCombinator } from '@lblod/ember-rdfa-editor/utils/transaction-utils';
|
|
18
|
+
|
|
19
|
+
export function moveStructure(direction: 'up' | 'down'): Command {
|
|
20
|
+
return (state, dispatch) => {
|
|
21
|
+
const { doc, selection, schema } = state;
|
|
22
|
+
const structure = findAncestorOfType(selection, schema.nodes['structure']);
|
|
23
|
+
if (!structure) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
const { pos, node } = structure;
|
|
27
|
+
const currentPos = node.attrs['number'];
|
|
28
|
+
if (direction === 'up') {
|
|
29
|
+
if (currentPos <= 1) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
const previousStructurePos =
|
|
33
|
+
findNodePosUp(doc, pos, ($pos: ResolvedPos) => {
|
|
34
|
+
const node = $pos.nodeAfter;
|
|
35
|
+
if (node) {
|
|
36
|
+
return node.type.name === 'structure';
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
}).next().value ?? null;
|
|
40
|
+
if (isNone(previousStructurePos)) {
|
|
41
|
+
return false;
|
|
42
|
+
} else {
|
|
43
|
+
if (dispatch) {
|
|
44
|
+
const transaction = state.tr;
|
|
45
|
+
// we are moving the structure up, so if we delete it first, it won't affect the positions
|
|
46
|
+
// before it
|
|
47
|
+
transaction.delete(pos, pos + node.nodeSize);
|
|
48
|
+
|
|
49
|
+
// previousStructurePos is the position right BEFORE the previous structure,
|
|
50
|
+
// so inserting there is correct
|
|
51
|
+
transaction.insert(previousStructurePos, node);
|
|
52
|
+
// after updating we have to recalculate the numbers
|
|
53
|
+
const { transaction: newTr } = transactionCombinator(
|
|
54
|
+
state,
|
|
55
|
+
transaction,
|
|
56
|
+
)([recalculateNumbers]);
|
|
57
|
+
|
|
58
|
+
// previousStructurePos should now point to the position right before our moved structure
|
|
59
|
+
// so we can simply add 1 to get the first position inside of it, and for the end
|
|
60
|
+
// we add the nodesize and subtract one
|
|
61
|
+
newTr.setSelection(
|
|
62
|
+
TextSelection.create(
|
|
63
|
+
newTr.doc,
|
|
64
|
+
previousStructurePos + 1,
|
|
65
|
+
previousStructurePos + node.nodeSize - 1,
|
|
66
|
+
),
|
|
67
|
+
);
|
|
68
|
+
dispatch(newTr);
|
|
69
|
+
}
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
// findNodePosUp and findNodePosDown have a different interface (historic reasons)
|
|
74
|
+
const nextStructureParentPos =
|
|
75
|
+
findNodePosDown(
|
|
76
|
+
doc,
|
|
77
|
+
doc.resolve(pos + node.nodeSize),
|
|
78
|
+
(parent: PNode) => {
|
|
79
|
+
return parent.type.name === 'structure';
|
|
80
|
+
},
|
|
81
|
+
).next().value ?? null;
|
|
82
|
+
if (isNone(nextStructureParentPos)) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
// findNodePosDown has a weird quirk where it can only find positions IN nodes
|
|
86
|
+
// cause the filter function only receives the position's parent
|
|
87
|
+
// so we need to step back one here (or make a way more complicated filter)
|
|
88
|
+
const nextStructurePos = nextStructureParentPos - 1;
|
|
89
|
+
if (dispatch) {
|
|
90
|
+
const transaction = state.tr;
|
|
91
|
+
const $structurePos = doc.resolve(nextStructurePos);
|
|
92
|
+
const nextStructureNode = unwrap($structurePos.nodeAfter);
|
|
93
|
+
|
|
94
|
+
transaction.delete(pos, pos + node.nodeSize);
|
|
95
|
+
const insertPos = transaction.mapping.map(
|
|
96
|
+
nextStructurePos + nextStructureNode.nodeSize,
|
|
97
|
+
);
|
|
98
|
+
transaction.insert(insertPos, node);
|
|
99
|
+
|
|
100
|
+
const { transaction: newTr } = transactionCombinator(
|
|
101
|
+
state,
|
|
102
|
+
transaction,
|
|
103
|
+
)([recalculateNumbers]);
|
|
104
|
+
|
|
105
|
+
// since we've deleted something before the insert position, we have to map
|
|
106
|
+
// the positions through the transaction to find the moved node's new position
|
|
107
|
+
newTr.setSelection(
|
|
108
|
+
TextSelection.create(
|
|
109
|
+
newTr.doc,
|
|
110
|
+
insertPos + 1,
|
|
111
|
+
insertPos + node.nodeSize - 1,
|
|
112
|
+
),
|
|
113
|
+
);
|
|
114
|
+
dispatch(newTr);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|