@lblod/ember-rdfa-editor-lblod-plugins 1.0.0-beta.1 → 1.0.0-beta.2
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/CHANGELOG.md +29 -0
- package/addon/components/article-structure-plugin/article-structure-card.hbs +3 -1
- package/addon/components/au-dropdown-pill.hbs +32 -0
- package/addon/components/au-dropdown-pill.ts +65 -0
- package/addon/components/besluit-type-plugin/toolbar-dropdown.ts +19 -12
- package/addon/components/citation-plugin/citation-card.ts +1 -1
- package/addon/components/citation-plugin/citation-insert.ts +1 -1
- package/addon/components/import-snippet-plugin/card.ts +8 -12
- package/addon/components/rdfa-date-plugin/card.hbs +28 -0
- package/addon/components/rdfa-date-plugin/card.ts +72 -38
- package/addon/components/rdfa-date-plugin/date-time-picker.ts +1 -0
- package/addon/components/rdfa-date-plugin/insert.hbs +2 -2
- package/addon/components/rdfa-date-plugin/insert.ts +14 -23
- package/addon/components/roadsign-regulation-plugin/roadsign-regulation-card.ts +24 -25
- package/addon/components/roadsign-regulation-plugin/roadsigns-modal.ts +36 -17
- package/addon/components/standard-template-plugin/template-provider.ts +54 -11
- package/addon/components/{insert-variable-plugin → variable-plugin}/insert-variable-card.hbs +4 -4
- package/addon/components/{insert-variable-plugin → variable-plugin}/insert-variable-card.ts +26 -35
- package/addon/components/{template-variable-plugin → variable-plugin}/template-variable-card.hbs +6 -6
- package/addon/components/variable-plugin/template-variable-card.ts +174 -0
- package/addon/components/variable-plugin/variable.hbs +4 -0
- package/addon/components/variable-plugin/variable.ts +250 -0
- package/addon/plugins/article-structure-plugin/commands/insert-structure.ts +4 -2
- package/addon/plugins/article-structure-plugin/index.ts +1 -1
- package/addon/plugins/article-structure-plugin/structures/article-paragraph.ts +6 -2
- package/addon/plugins/article-structure-plugin/structures/article.ts +1 -1
- package/addon/plugins/article-structure-plugin/structures/chapter.ts +1 -2
- package/addon/plugins/article-structure-plugin/structures/section.ts +1 -1
- package/addon/plugins/article-structure-plugin/structures/subsection.ts +1 -1
- package/addon/plugins/article-structure-plugin/structures/title.ts +1 -2
- package/addon/plugins/citation-plugin/index.ts +184 -113
- package/addon/plugins/rdfa-date-plugin/index.ts +42 -3
- package/addon/plugins/rdfa-date-plugin/nodes/date.ts +127 -0
- package/addon/plugins/rdfa-date-plugin/nodes/index.ts +1 -0
- package/addon/plugins/rdfa-date-plugin/utils.ts +10 -0
- package/addon/plugins/roadsign-regulation-plugin/nodes.ts +107 -0
- package/addon/plugins/standard-template-plugin/index.ts +26 -0
- package/addon/plugins/standard-template-plugin/utils/nodes.ts +366 -0
- package/addon/plugins/{insert-variable-plugin → variable-plugin}/index.ts +6 -1
- package/addon/plugins/variable-plugin/nodes.ts +137 -0
- package/addon/plugins/variable-plugin/utils/constants.ts +107 -0
- package/addon/plugins/{template-variable-plugin → variable-plugin}/utils/fetch-data.ts +41 -0
- package/addon/services/standard-template-plugin.ts +16 -12
- package/addon/utils/changed-descendants.ts +29 -0
- package/addon/utils/constants.ts +11 -0
- package/addon/utils/namespace.ts +42 -7
- package/app/components/au-dropdown-pill.js +1 -0
- package/app/components/{insert-variable-plugin → variable-plugin}/insert-variable-card.js +1 -1
- package/app/components/{template-variable-plugin → variable-plugin}/template-variable-card.js +1 -1
- package/app/components/variable-plugin/variable-edit-modal.js +1 -0
- package/app/components/variable-plugin/variable.js +1 -0
- package/app/styles/date-plugin.scss +17 -0
- package/app/styles/variable-plugin.scss +65 -0
- package/components/au-dropdown-pill.d.ts +19 -0
- package/components/au-native-input.d.ts +1 -1
- package/components/citation-plugin/citation-card.d.ts +1 -1
- package/components/rdfa-date-plugin/card.d.ts +14 -5
- package/components/rdfa-date-plugin/insert.d.ts +1 -2
- package/components/roadsign-regulation-plugin/roadsign-regulation-card.d.ts +1 -0
- package/components/roadsign-regulation-plugin/roadsigns-modal.d.ts +3 -0
- package/components/standard-template-plugin/template-provider.d.ts +6 -1
- package/components/{insert-variable-plugin → variable-plugin}/insert-variable-card.d.ts +3 -4
- package/components/{template-variable-plugin → variable-plugin}/template-variable-card.d.ts +8 -5
- package/components/variable-plugin/variable.d.ts +42 -0
- package/package.json +4 -4
- package/plugins/article-structure-plugin/commands/insert-structure.d.ts +2 -2
- package/plugins/article-structure-plugin/index.d.ts +1 -1
- package/plugins/citation-plugin/index.d.ts +11 -4
- package/plugins/rdfa-date-plugin/index.d.ts +13 -1
- package/plugins/rdfa-date-plugin/nodes/date.d.ts +9 -0
- package/plugins/rdfa-date-plugin/nodes/index.d.ts +1 -0
- package/plugins/rdfa-date-plugin/utils.d.ts +1 -0
- package/plugins/roadsign-regulation-plugin/nodes.d.ts +2 -0
- package/plugins/standard-template-plugin/index.d.ts +12 -0
- package/plugins/standard-template-plugin/utils/nodes.d.ts +12 -0
- package/plugins/{insert-variable-plugin → variable-plugin}/index.d.ts +1 -0
- package/plugins/variable-plugin/nodes.d.ts +2 -0
- package/plugins/variable-plugin/utils/constants.d.ts +9 -0
- package/plugins/{template-variable-plugin → variable-plugin}/utils/fetch-data.d.ts +5 -0
- package/services/standard-template-plugin.d.ts +9 -10
- package/translations/en-US.yaml +4 -3
- package/translations/nl-BE.yaml +5 -4
- package/utils/changed-descendants.d.ts +2 -0
- package/utils/constants.d.ts +5 -0
- package/utils/namespace.d.ts +8 -3
- package/addon/components/template-variable-plugin/template-variable-card.ts +0 -227
- package/addon/plugins/insert-variable-plugin/utils/constants.ts +0 -67
- package/addon/plugins/insert-variable-plugin/utils/fetch-data.ts +0 -41
- package/addon/plugins/rdfa-date-plugin/commands/index.ts +0 -1
- package/addon/plugins/rdfa-date-plugin/commands/modify-date.ts +0 -48
- package/addon/plugins/template-variable-plugin/index.ts +0 -6
- package/addon/plugins/template-variable-plugin/utils/constants.ts +0 -2
- package/plugins/insert-variable-plugin/utils/constants.d.ts +0 -7
- package/plugins/insert-variable-plugin/utils/fetch-data.d.ts +0 -5
- package/plugins/rdfa-date-plugin/commands/index.d.ts +0 -1
- package/plugins/rdfa-date-plugin/commands/modify-date.d.ts +0 -2
- package/plugins/template-variable-plugin/index.d.ts +0 -2
- package/plugins/template-variable-plugin/utils/constants.d.ts +0 -1
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
EditorState,
|
|
7
7
|
} from '@lblod/ember-rdfa-editor';
|
|
8
8
|
import IntlService from 'ember-intl/services/intl';
|
|
9
|
-
import { Transaction } from '
|
|
9
|
+
import { Transaction } from '@lblod/ember-rdfa-editor';
|
|
10
10
|
import { STRUCTURE_SPECS } from './structures';
|
|
11
11
|
|
|
12
12
|
export type SpecName = string;
|
|
@@ -117,8 +117,12 @@ export const article_paragraph: NodeSpec = {
|
|
|
117
117
|
return false;
|
|
118
118
|
},
|
|
119
119
|
getContent: (node, schema) => {
|
|
120
|
-
const content = node.lastChild?.textContent
|
|
121
|
-
|
|
120
|
+
const content = node.lastChild?.textContent;
|
|
121
|
+
if (content) {
|
|
122
|
+
return Fragment.from(schema.text(content));
|
|
123
|
+
} else {
|
|
124
|
+
return Fragment.empty;
|
|
125
|
+
}
|
|
122
126
|
},
|
|
123
127
|
},
|
|
124
128
|
],
|
|
@@ -74,9 +74,8 @@ export const chapterSpec: StructureSpec = {
|
|
|
74
74
|
export const chapter = constructStructureNodeSpec({
|
|
75
75
|
type: SAY('Chapter'),
|
|
76
76
|
content: 'structure_header chapter_body',
|
|
77
|
-
group: 'block',
|
|
78
77
|
});
|
|
79
78
|
|
|
80
79
|
export const chapter_body = constructStructureBodyNodeSpec({
|
|
81
|
-
content: '(section|
|
|
80
|
+
content: '(section|block)+|(article|block)+',
|
|
82
81
|
});
|
|
@@ -74,9 +74,8 @@ export const titleSpec: StructureSpec = {
|
|
|
74
74
|
export const title = constructStructureNodeSpec({
|
|
75
75
|
type: SAY('Title'),
|
|
76
76
|
content: 'structure_header title_body',
|
|
77
|
-
group: 'block',
|
|
78
77
|
});
|
|
79
78
|
|
|
80
79
|
export const title_body = constructStructureBodyNodeSpec({
|
|
81
|
-
content: '(chapter|
|
|
80
|
+
content: '(chapter|block)+|(article|block)+',
|
|
82
81
|
});
|
|
@@ -5,20 +5,17 @@ import {
|
|
|
5
5
|
EditorStateConfig,
|
|
6
6
|
InlineDecorationSpec,
|
|
7
7
|
MarkSpec,
|
|
8
|
+
NodeType,
|
|
8
9
|
PNode,
|
|
9
10
|
ProsePlugin,
|
|
10
11
|
Schema,
|
|
11
12
|
WidgetSpec,
|
|
12
13
|
} from '@lblod/ember-rdfa-editor';
|
|
13
|
-
import {
|
|
14
|
-
datastoreKey,
|
|
15
|
-
ProseStore,
|
|
16
|
-
} from '@lblod/ember-rdfa-editor/plugins/datastore';
|
|
17
14
|
import processMatch, {
|
|
18
15
|
RegexpMatchArrayWithIndices,
|
|
19
16
|
} from './utils/process-match';
|
|
20
|
-
import { expect } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
|
|
21
17
|
import { citation } from './marks/citation';
|
|
18
|
+
import { changedDescendants } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/changed-descendants';
|
|
22
19
|
|
|
23
20
|
const BASIC_MULTIPLANE_CHARACTER = '\u0021-\uFFFF'; // most of the characters used around the world
|
|
24
21
|
|
|
@@ -60,54 +57,6 @@ export interface CitationDecoration extends Decoration {
|
|
|
60
57
|
spec: CitationDecorationSpec;
|
|
61
58
|
}
|
|
62
59
|
|
|
63
|
-
function calculateDecorations(
|
|
64
|
-
schema: CitationSchema,
|
|
65
|
-
doc: PNode,
|
|
66
|
-
activeRanges: [number, number][]
|
|
67
|
-
) {
|
|
68
|
-
const decorations: Decoration[] = [];
|
|
69
|
-
|
|
70
|
-
for (const [start, end] of activeRanges) {
|
|
71
|
-
doc.nodesBetween(start, end, (node: PNode, pos: number): boolean => {
|
|
72
|
-
if (
|
|
73
|
-
node.isText &&
|
|
74
|
-
node.text &&
|
|
75
|
-
!schema.marks.citation.isInSet(node.marks)
|
|
76
|
-
) {
|
|
77
|
-
for (const match of node.text.matchAll(CITATION_REGEX)) {
|
|
78
|
-
const processedMatch = processMatch(
|
|
79
|
-
match as RegexpMatchArrayWithIndices
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
if (processedMatch) {
|
|
83
|
-
const { text, legislationTypeUri, searchTextMatch } =
|
|
84
|
-
processedMatch;
|
|
85
|
-
const { start: matchStart, end: matchEnd } = searchTextMatch;
|
|
86
|
-
const decorationStart = pos + matchStart;
|
|
87
|
-
const decorationEnd = pos + matchEnd;
|
|
88
|
-
decorations.push(
|
|
89
|
-
Decoration.inline(
|
|
90
|
-
decorationStart,
|
|
91
|
-
decorationEnd,
|
|
92
|
-
|
|
93
|
-
{
|
|
94
|
-
'data-editor-highlight': 'true',
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
searchText: text,
|
|
98
|
-
legislationTypeUri,
|
|
99
|
-
}
|
|
100
|
-
)
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
return true;
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
return DecorationSet.create(doc, decorations);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
60
|
interface CitationPluginState {
|
|
112
61
|
highlights: DecorationSet;
|
|
113
62
|
activeRanges: [number, number][];
|
|
@@ -115,63 +64,6 @@ interface CitationPluginState {
|
|
|
115
64
|
|
|
116
65
|
export type CitationPlugin = ProsePlugin<CitationPluginState>;
|
|
117
66
|
|
|
118
|
-
function citationPlugin({
|
|
119
|
-
activeIn = defaultActiveIn,
|
|
120
|
-
}: CitationPluginConfig): CitationPlugin {
|
|
121
|
-
const citation: CitationPlugin = new ProsePlugin({
|
|
122
|
-
state: {
|
|
123
|
-
init(stateConfig: EditorStateConfig, state: EditorState) {
|
|
124
|
-
const { doc, schema } = state;
|
|
125
|
-
const activeRanges = activeIn(
|
|
126
|
-
state,
|
|
127
|
-
expect(
|
|
128
|
-
'the datastore plugin is required for this plugin',
|
|
129
|
-
datastoreKey.getState(state)
|
|
130
|
-
)()
|
|
131
|
-
);
|
|
132
|
-
return {
|
|
133
|
-
highlights: calculateDecorations(schema, doc, activeRanges),
|
|
134
|
-
activeRanges,
|
|
135
|
-
};
|
|
136
|
-
},
|
|
137
|
-
apply(tr, set, oldState, newState) {
|
|
138
|
-
const { doc, schema } = newState;
|
|
139
|
-
const activeRanges = activeIn(
|
|
140
|
-
newState,
|
|
141
|
-
expect(
|
|
142
|
-
'the datastore plugin is required for this plugin',
|
|
143
|
-
datastoreKey.getState(newState)
|
|
144
|
-
)()
|
|
145
|
-
);
|
|
146
|
-
return {
|
|
147
|
-
highlights: calculateDecorations(schema, doc, activeRanges),
|
|
148
|
-
activeRanges,
|
|
149
|
-
};
|
|
150
|
-
},
|
|
151
|
-
},
|
|
152
|
-
props: {
|
|
153
|
-
decorations(state): DecorationSet | undefined {
|
|
154
|
-
return citation.getState(state)?.highlights;
|
|
155
|
-
},
|
|
156
|
-
},
|
|
157
|
-
});
|
|
158
|
-
return citation;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
function defaultActiveIn(
|
|
162
|
-
state: EditorState,
|
|
163
|
-
datastore: ProseStore
|
|
164
|
-
): [number, number][] {
|
|
165
|
-
const result: [number, number][] = [];
|
|
166
|
-
for (const { from, to } of datastore
|
|
167
|
-
.match(null, 'besluit:motivering')
|
|
168
|
-
.asPredicateNodeMapping()
|
|
169
|
-
.nodes()) {
|
|
170
|
-
result.push([from, to]);
|
|
171
|
-
}
|
|
172
|
-
return result;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
67
|
export interface CitationPluginBundle {
|
|
176
68
|
plugin: ProsePlugin<CitationPluginState>;
|
|
177
69
|
widgets: {
|
|
@@ -183,12 +75,31 @@ export interface CitationPluginBundle {
|
|
|
183
75
|
};
|
|
184
76
|
}
|
|
185
77
|
|
|
186
|
-
export interface
|
|
187
|
-
|
|
78
|
+
export interface CitationPluginNodeConfig {
|
|
79
|
+
type: 'nodes';
|
|
80
|
+
regex?: RegExp;
|
|
81
|
+
|
|
82
|
+
activeInNodeTypes(schema: Schema, state: EditorState): Set<NodeType>;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface CitationPluginRangeConfig {
|
|
86
|
+
type: 'ranges';
|
|
87
|
+
regex?: RegExp;
|
|
88
|
+
|
|
89
|
+
activeInRanges(state: EditorState): [number, number][];
|
|
188
90
|
}
|
|
189
91
|
|
|
92
|
+
export type CitationPluginConfig =
|
|
93
|
+
| CitationPluginNodeConfig
|
|
94
|
+
| CitationPluginRangeConfig;
|
|
95
|
+
|
|
190
96
|
export function setupCitationPlugin(
|
|
191
|
-
config: CitationPluginConfig = {
|
|
97
|
+
config: CitationPluginConfig = {
|
|
98
|
+
type: 'nodes',
|
|
99
|
+
activeInNodeTypes(schema): Set<NodeType> {
|
|
100
|
+
return new Set([schema.nodes.doc]);
|
|
101
|
+
},
|
|
102
|
+
}
|
|
192
103
|
): CitationPluginBundle {
|
|
193
104
|
const plugin = citationPlugin(config);
|
|
194
105
|
return {
|
|
@@ -214,3 +125,163 @@ export function setupCitationPlugin(
|
|
|
214
125
|
},
|
|
215
126
|
};
|
|
216
127
|
}
|
|
128
|
+
|
|
129
|
+
function citationPlugin(config: CitationPluginConfig): CitationPlugin {
|
|
130
|
+
const citation: CitationPlugin = new ProsePlugin({
|
|
131
|
+
state: {
|
|
132
|
+
init(stateConfig: EditorStateConfig, state: EditorState) {
|
|
133
|
+
return calculateCitationPluginState(state, config);
|
|
134
|
+
},
|
|
135
|
+
apply(tr, set, oldState, newState) {
|
|
136
|
+
return calculateCitationPluginState(newState, config, oldState);
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
props: {
|
|
140
|
+
decorations(state): DecorationSet | undefined {
|
|
141
|
+
return citation.getState(state)?.highlights;
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
return citation;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function calculateCitationPluginState(
|
|
149
|
+
state: EditorState,
|
|
150
|
+
config: CitationPluginConfig,
|
|
151
|
+
oldState?: EditorState
|
|
152
|
+
) {
|
|
153
|
+
const { doc, schema } = state;
|
|
154
|
+
let activeRanges;
|
|
155
|
+
let highlights;
|
|
156
|
+
if (config.type === 'ranges') {
|
|
157
|
+
activeRanges = config.activeInRanges(state);
|
|
158
|
+
const calculatedDecs = calculateDecorationsInRanges(
|
|
159
|
+
config,
|
|
160
|
+
schema,
|
|
161
|
+
doc,
|
|
162
|
+
activeRanges
|
|
163
|
+
);
|
|
164
|
+
highlights = calculatedDecs.decorations;
|
|
165
|
+
} else {
|
|
166
|
+
const nodes = config.activeInNodeTypes(schema, state);
|
|
167
|
+
const calculatedDecs = calculateDecorationsInNodes(
|
|
168
|
+
config,
|
|
169
|
+
schema,
|
|
170
|
+
nodes,
|
|
171
|
+
doc,
|
|
172
|
+
oldState?.doc
|
|
173
|
+
);
|
|
174
|
+
activeRanges = calculatedDecs.activeRanges;
|
|
175
|
+
highlights = calculatedDecs.decorations;
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
highlights,
|
|
179
|
+
activeRanges,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function calculateDecorationsInNodes(
|
|
184
|
+
config: CitationPluginConfig,
|
|
185
|
+
schema: CitationSchema,
|
|
186
|
+
nodes: Set<NodeType>,
|
|
187
|
+
newDoc: PNode,
|
|
188
|
+
oldDoc?: PNode
|
|
189
|
+
): { decorations: DecorationSet; activeRanges: [number, number][] } {
|
|
190
|
+
const activeRanges: [number, number][] = [];
|
|
191
|
+
const decorations: Decoration[] = [];
|
|
192
|
+
const collector = collectDecorations(decorations, schema, config.regex);
|
|
193
|
+
if (nodes.has(newDoc.type)) {
|
|
194
|
+
oldDoc
|
|
195
|
+
? changedDescendants(oldDoc, newDoc, 0, collector)
|
|
196
|
+
: newDoc.descendants(collector);
|
|
197
|
+
activeRanges.push([0, newDoc.nodeSize]);
|
|
198
|
+
} else {
|
|
199
|
+
oldDoc
|
|
200
|
+
? changedDescendants(
|
|
201
|
+
oldDoc,
|
|
202
|
+
newDoc,
|
|
203
|
+
0,
|
|
204
|
+
|
|
205
|
+
(node, pos) => {
|
|
206
|
+
if (nodes.has(node.type)) {
|
|
207
|
+
node.nodesBetween(0, node.nodeSize - 2, collector, pos + 1);
|
|
208
|
+
activeRanges.push([pos, pos + node.nodeSize]);
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
)
|
|
214
|
+
: newDoc.descendants((node, pos) => {
|
|
215
|
+
if (nodes.has(node.type)) {
|
|
216
|
+
node.nodesBetween(0, node.nodeSize - 2, collector, pos + 1);
|
|
217
|
+
activeRanges.push([pos, pos + node.nodeSize]);
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
return true;
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
return {
|
|
224
|
+
decorations: DecorationSet.create(newDoc, decorations),
|
|
225
|
+
activeRanges,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function calculateDecorationsInRanges(
|
|
230
|
+
config: CitationPluginConfig,
|
|
231
|
+
schema: CitationSchema,
|
|
232
|
+
doc: PNode,
|
|
233
|
+
activeRanges: [number, number][]
|
|
234
|
+
): { decorations: DecorationSet; activeRanges: [number, number][] } {
|
|
235
|
+
const decorations: Decoration[] = [];
|
|
236
|
+
const collector = collectDecorations(decorations, schema, config.regex);
|
|
237
|
+
|
|
238
|
+
for (const [start, end] of activeRanges) {
|
|
239
|
+
doc.nodesBetween(start, end, collector);
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
decorations: DecorationSet.create(doc, decorations),
|
|
243
|
+
activeRanges: activeRanges,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function collectDecorations(
|
|
248
|
+
decorations: Decoration[],
|
|
249
|
+
schema: CitationSchema,
|
|
250
|
+
regex: RegExp = CITATION_REGEX
|
|
251
|
+
) {
|
|
252
|
+
return function (node: PNode, pos: number): boolean {
|
|
253
|
+
if (
|
|
254
|
+
node.isText &&
|
|
255
|
+
node.text &&
|
|
256
|
+
!schema.marks.citation.isInSet(node.marks)
|
|
257
|
+
) {
|
|
258
|
+
for (const match of node.text.matchAll(regex)) {
|
|
259
|
+
const processedMatch = processMatch(
|
|
260
|
+
match as RegexpMatchArrayWithIndices
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
if (processedMatch) {
|
|
264
|
+
const { text, legislationTypeUri, searchTextMatch } = processedMatch;
|
|
265
|
+
const { start: matchStart, end: matchEnd } = searchTextMatch;
|
|
266
|
+
const decorationStart = pos + matchStart;
|
|
267
|
+
const decorationEnd = pos + matchEnd;
|
|
268
|
+
decorations.push(
|
|
269
|
+
Decoration.inline(
|
|
270
|
+
decorationStart,
|
|
271
|
+
decorationEnd,
|
|
272
|
+
|
|
273
|
+
{
|
|
274
|
+
'data-editor-highlight': 'true',
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
searchText: text,
|
|
278
|
+
legislationTypeUri,
|
|
279
|
+
}
|
|
280
|
+
)
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return true;
|
|
286
|
+
};
|
|
287
|
+
}
|
|
@@ -1,11 +1,50 @@
|
|
|
1
1
|
import { WidgetSpec } from '@lblod/ember-rdfa-editor';
|
|
2
2
|
|
|
3
|
-
export const
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
export const defaultDateFormats: DateFormat[] = [
|
|
4
|
+
{
|
|
5
|
+
label: 'Short small Date',
|
|
6
|
+
key: 'short',
|
|
7
|
+
dateFormat: 'dd/MM/yy',
|
|
8
|
+
dateTimeFormat: 'dd/MM/yy HH:mm',
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
label: 'Long Date',
|
|
12
|
+
key: 'long',
|
|
13
|
+
dateFormat: 'EEEE dd MMMM yyyy',
|
|
14
|
+
dateTimeFormat: 'EEEE dd MMMM yyyy at HH:mm',
|
|
15
|
+
},
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
const defaultOptions = {
|
|
19
|
+
formats: defaultDateFormats,
|
|
20
|
+
allowCustomFormat: true,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const rdfaDateCardWidget: (options?: DatePluginOptions) => WidgetSpec = (
|
|
24
|
+
options
|
|
25
|
+
) => {
|
|
26
|
+
return {
|
|
27
|
+
componentName: 'rdfa-date-plugin/card',
|
|
28
|
+
desiredLocation: 'sidebar',
|
|
29
|
+
widgetArgs: {
|
|
30
|
+
options: options ? options : defaultOptions,
|
|
31
|
+
},
|
|
32
|
+
};
|
|
6
33
|
};
|
|
7
34
|
|
|
8
35
|
export const rdfaDateInsertWidget: WidgetSpec = {
|
|
9
36
|
componentName: 'rdfa-date-plugin/insert',
|
|
10
37
|
desiredLocation: 'insertSidebar',
|
|
11
38
|
};
|
|
39
|
+
|
|
40
|
+
export type DateFormat = {
|
|
41
|
+
label: string;
|
|
42
|
+
key: string;
|
|
43
|
+
dateFormat: string;
|
|
44
|
+
dateTimeFormat: string;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
type DatePluginOptions = {
|
|
48
|
+
formats: DateFormat[];
|
|
49
|
+
allowCustomFormat: boolean;
|
|
50
|
+
};
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { NodeSpec } from '@lblod/ember-rdfa-editor';
|
|
2
|
+
import {
|
|
3
|
+
DCT,
|
|
4
|
+
EXT,
|
|
5
|
+
XSD,
|
|
6
|
+
} from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
|
|
7
|
+
import { hasRDFaAttribute } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/namespace';
|
|
8
|
+
import { formatDate } from '../utils';
|
|
9
|
+
|
|
10
|
+
export type DateOptions = {
|
|
11
|
+
placeholder: {
|
|
12
|
+
insertDate: string;
|
|
13
|
+
insertDateTime: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
const date: (options: DateOptions) => NodeSpec = (options) => {
|
|
17
|
+
return {
|
|
18
|
+
group: 'inline',
|
|
19
|
+
inline: true,
|
|
20
|
+
attrs: {
|
|
21
|
+
mappingResource: {
|
|
22
|
+
default: null,
|
|
23
|
+
},
|
|
24
|
+
value: {
|
|
25
|
+
default: null,
|
|
26
|
+
},
|
|
27
|
+
format: {
|
|
28
|
+
default: 'dd/mm/yyyy',
|
|
29
|
+
},
|
|
30
|
+
onlyDate: {
|
|
31
|
+
default: true,
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
selectable: true,
|
|
35
|
+
leafText: (node) => {
|
|
36
|
+
const { value, onlyDate, format } = node.attrs;
|
|
37
|
+
const humanReadableDate = value
|
|
38
|
+
? formatDate(new Date(value), format)
|
|
39
|
+
: onlyDate
|
|
40
|
+
? options.placeholder.insertDate
|
|
41
|
+
: options.placeholder.insertDateTime;
|
|
42
|
+
return humanReadableDate;
|
|
43
|
+
},
|
|
44
|
+
toDOM: (node) => {
|
|
45
|
+
const { value, onlyDate, format, mappingResource } = node.attrs;
|
|
46
|
+
const datatype = onlyDate ? XSD('date') : XSD('dateTime');
|
|
47
|
+
const humanReadableDate = value
|
|
48
|
+
? formatDate(new Date(value), format)
|
|
49
|
+
: onlyDate
|
|
50
|
+
? options.placeholder.insertDate
|
|
51
|
+
: options.placeholder.insertDateTime;
|
|
52
|
+
const dateAttrs = {
|
|
53
|
+
datatype: datatype.prefixed,
|
|
54
|
+
property: EXT('content').prefixed,
|
|
55
|
+
'data-format': format as string,
|
|
56
|
+
...(!!value && { content: value as string }),
|
|
57
|
+
};
|
|
58
|
+
if (mappingResource) {
|
|
59
|
+
return [
|
|
60
|
+
'span',
|
|
61
|
+
{
|
|
62
|
+
resource: mappingResource as string,
|
|
63
|
+
typeof: EXT('Mapping').prefixed,
|
|
64
|
+
class: 'date',
|
|
65
|
+
},
|
|
66
|
+
['span', { property: DCT('type').prefixed, content: 'date' }],
|
|
67
|
+
['span', dateAttrs, humanReadableDate],
|
|
68
|
+
];
|
|
69
|
+
} else {
|
|
70
|
+
return ['span', { class: 'date', ...dateAttrs }, humanReadableDate];
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
parseDOM: [
|
|
74
|
+
{
|
|
75
|
+
tag: 'span',
|
|
76
|
+
getAttrs: (node: HTMLElement) => {
|
|
77
|
+
if (
|
|
78
|
+
hasRDFaAttribute(node, 'datatype', XSD('date')) ||
|
|
79
|
+
hasRDFaAttribute(node, 'datatype', XSD('dateTime'))
|
|
80
|
+
) {
|
|
81
|
+
const onlyDate = hasRDFaAttribute(node, 'datatype', XSD('date'));
|
|
82
|
+
return {
|
|
83
|
+
value: node.getAttribute('content'),
|
|
84
|
+
onlyDate,
|
|
85
|
+
format: node.dataset.format,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return false;
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
tag: 'span',
|
|
93
|
+
getAttrs: (node: HTMLElement) => {
|
|
94
|
+
if (hasRDFaAttribute(node, 'typeof', EXT('Mapping'))) {
|
|
95
|
+
const mappingResource = node.getAttribute('resource');
|
|
96
|
+
if (!mappingResource) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
const variableType = [...node.children]
|
|
100
|
+
.find((el) => hasRDFaAttribute(el, 'property', DCT('type')))
|
|
101
|
+
?.getAttribute('content');
|
|
102
|
+
const datatype = [...node.children]
|
|
103
|
+
.find((el) => hasRDFaAttribute(el, 'property', EXT('content')))
|
|
104
|
+
?.getAttribute('datatype');
|
|
105
|
+
if (variableType === 'date' && datatype) {
|
|
106
|
+
const onlyDate = !![...node.children].find((el) =>
|
|
107
|
+
hasRDFaAttribute(el, 'datatype', XSD('date'))
|
|
108
|
+
);
|
|
109
|
+
const dateNode = [...node.children].find((el) =>
|
|
110
|
+
hasRDFaAttribute(el, 'property', EXT('content'))
|
|
111
|
+
);
|
|
112
|
+
return {
|
|
113
|
+
mappingResource,
|
|
114
|
+
onlyDate,
|
|
115
|
+
value: dateNode?.getAttribute('content'),
|
|
116
|
+
format: dateNode?.getAttribute('data-format'),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return false;
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
export default date;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as date, DateOptions } from './date';
|