@manuscripts/body-editor 3.9.11 → 3.9.13
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/dist/cjs/commands.js +5 -2
- package/dist/cjs/components/keywords/AddKeywordInline.js +12 -1
- package/dist/cjs/components/views/FigureDropdown.js +65 -6
- package/dist/cjs/configs/ManuscriptsEditor.js +1 -1
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/keys/misc.js +2 -1
- package/dist/cjs/keys/title.js +0 -38
- package/dist/cjs/lib/comments.js +1 -0
- package/dist/cjs/lib/context-menu.js +74 -8
- package/dist/cjs/lib/media.js +27 -3
- package/dist/cjs/lib/navigation-utils.js +132 -0
- package/dist/cjs/lib/popper.js +25 -1
- package/dist/cjs/lib/position-menu.js +3 -0
- package/dist/cjs/lib/utils.js +7 -2
- package/dist/cjs/plugins/accessibility_element.js +10 -2
- package/dist/cjs/plugins/add-subtitle.js +8 -2
- package/dist/cjs/plugins/alt-titles.js +6 -1
- package/dist/cjs/plugins/comments.js +27 -15
- package/dist/cjs/plugins/persistent-cursor.js +4 -6
- package/dist/cjs/plugins/section_category.js +42 -9
- package/dist/cjs/plugins/translations.js +49 -13
- package/dist/cjs/versions.js +1 -1
- package/dist/cjs/views/accessibility_element.js +30 -0
- package/dist/cjs/views/alt_title.js +29 -0
- package/dist/cjs/views/alt_titles_section.js +9 -1
- package/dist/cjs/views/attachment.js +1 -1
- package/dist/cjs/views/bibliography_element.js +39 -17
- package/dist/cjs/views/citation.js +1 -0
- package/dist/cjs/views/citation_editable.js +4 -2
- package/dist/cjs/views/contributors.js +23 -2
- package/dist/cjs/views/cross_reference.js +3 -0
- package/dist/cjs/views/editable_block.js +37 -3
- package/dist/cjs/views/embed.js +3 -3
- package/dist/cjs/views/figure_editable.js +1 -1
- package/dist/cjs/views/figure_element.js +3 -0
- package/dist/cjs/views/footnote.js +3 -0
- package/dist/cjs/views/hero_image.js +4 -1
- package/dist/cjs/views/image_element.js +15 -7
- package/dist/cjs/views/inline_footnote.js +3 -0
- package/dist/cjs/views/keyword.js +15 -0
- package/dist/cjs/views/keyword_group.js +38 -0
- package/dist/cjs/views/quote_image_editable.js +1 -0
- package/dist/cjs/views/supplements.js +4 -1
- package/dist/es/commands.js +5 -2
- package/dist/es/components/keywords/AddKeywordInline.js +12 -1
- package/dist/es/components/views/FigureDropdown.js +66 -7
- package/dist/es/configs/ManuscriptsEditor.js +1 -1
- package/dist/es/index.js +1 -0
- package/dist/es/keys/misc.js +2 -1
- package/dist/es/keys/title.js +1 -39
- package/dist/es/lib/comments.js +1 -0
- package/dist/es/lib/context-menu.js +74 -8
- package/dist/es/lib/media.js +27 -3
- package/dist/es/lib/navigation-utils.js +122 -0
- package/dist/es/lib/popper.js +25 -1
- package/dist/es/lib/position-menu.js +3 -0
- package/dist/es/lib/utils.js +7 -2
- package/dist/es/plugins/accessibility_element.js +10 -2
- package/dist/es/plugins/add-subtitle.js +8 -2
- package/dist/es/plugins/alt-titles.js +6 -1
- package/dist/es/plugins/comments.js +27 -15
- package/dist/es/plugins/persistent-cursor.js +4 -6
- package/dist/es/plugins/section_category.js +42 -9
- package/dist/es/plugins/translations.js +49 -13
- package/dist/es/versions.js +1 -1
- package/dist/es/views/accessibility_element.js +30 -0
- package/dist/es/views/alt_title.js +29 -0
- package/dist/es/views/alt_titles_section.js +9 -1
- package/dist/es/views/attachment.js +1 -1
- package/dist/es/views/bibliography_element.js +39 -17
- package/dist/es/views/citation.js +1 -0
- package/dist/es/views/citation_editable.js +4 -2
- package/dist/es/views/contributors.js +23 -2
- package/dist/es/views/cross_reference.js +3 -0
- package/dist/es/views/editable_block.js +37 -3
- package/dist/es/views/embed.js +3 -3
- package/dist/es/views/figure_editable.js +1 -1
- package/dist/es/views/figure_element.js +3 -0
- package/dist/es/views/footnote.js +3 -0
- package/dist/es/views/hero_image.js +4 -1
- package/dist/es/views/image_element.js +15 -7
- package/dist/es/views/inline_footnote.js +3 -0
- package/dist/es/views/keyword.js +15 -0
- package/dist/es/views/keyword_group.js +38 -0
- package/dist/es/views/quote_image_editable.js +1 -0
- package/dist/es/views/supplements.js +4 -1
- package/dist/types/configs/ManuscriptsEditor.d.ts +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/lib/context-menu.d.ts +1 -0
- package/dist/types/lib/media.d.ts +1 -1
- package/dist/types/lib/navigation-utils.d.ts +45 -0
- package/dist/types/lib/popper.d.ts +3 -0
- package/dist/types/lib/utils.d.ts +1 -1
- package/dist/types/versions.d.ts +1 -1
- package/dist/types/views/accessibility_element.d.ts +2 -0
- package/dist/types/views/alt_title.d.ts +2 -0
- package/dist/types/views/bibliography_element.d.ts +3 -0
- package/dist/types/views/citation_editable.d.ts +1 -1
- package/dist/types/views/contributors.d.ts +3 -1
- package/dist/types/views/keyword.d.ts +1 -0
- package/dist/types/views/keyword_group.d.ts +4 -0
- package/package.json +4 -4
- package/styles/AdvancedEditor.css +116 -10
- package/styles/Editor.css +61 -6
- package/styles/popper.css +3 -1
|
@@ -24,6 +24,7 @@ const transform_1 = require("@manuscripts/transform");
|
|
|
24
24
|
const prosemirror_state_1 = require("prosemirror-state");
|
|
25
25
|
const ReferencesEditor_1 = require("../components/references/ReferencesEditor");
|
|
26
26
|
const comments_1 = require("../lib/comments");
|
|
27
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
27
28
|
const doc_1 = require("../lib/doc");
|
|
28
29
|
const dompurify_1 = require("../lib/dompurify");
|
|
29
30
|
const track_changes_utils_1 = require("../lib/track-changes-utils");
|
|
@@ -39,31 +40,50 @@ class BibliographyElementBlockView extends block_view_1.default {
|
|
|
39
40
|
super(...arguments);
|
|
40
41
|
this.stopEvent = () => true;
|
|
41
42
|
this.ignoreMutation = () => true;
|
|
43
|
+
this.handleCommentMarkerInteraction = (marker) => {
|
|
44
|
+
const key = marker.dataset.key;
|
|
45
|
+
const tr = this.view.state.tr;
|
|
46
|
+
(0, comments_2.setCommentSelection)(tr, key, undefined, false);
|
|
47
|
+
this.view.dispatch(tr);
|
|
48
|
+
};
|
|
49
|
+
this.handleBibItemInteraction = (item) => {
|
|
50
|
+
if (!this.props.getCapabilities().seeReferencesButtons) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
this.showContextMenu(item);
|
|
54
|
+
const node = (0, view_1.findChildByID)(this.view, item.id);
|
|
55
|
+
if (node) {
|
|
56
|
+
const tr = this.view.state.tr;
|
|
57
|
+
tr.setSelection(prosemirror_state_1.NodeSelection.create(this.view.state.doc, node.pos));
|
|
58
|
+
this.view.dispatch(tr);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
42
61
|
this.handleClick = (event) => {
|
|
43
62
|
const element = event.target;
|
|
44
63
|
const marker = element.closest('.comment-marker');
|
|
45
64
|
if (marker) {
|
|
46
|
-
|
|
47
|
-
const tr = this.view.state.tr;
|
|
48
|
-
(0, comments_2.setCommentSelection)(tr, key, undefined, false);
|
|
49
|
-
this.view.dispatch(tr);
|
|
65
|
+
this.handleCommentMarkerInteraction(marker);
|
|
50
66
|
return;
|
|
51
67
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
this.showContextMenu(item);
|
|
56
|
-
const node = (0, view_1.findChildByID)(this.view, item.id);
|
|
57
|
-
if (!node) {
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
const view = this.view;
|
|
61
|
-
const tr = view.state.tr;
|
|
62
|
-
tr.setSelection(prosemirror_state_1.NodeSelection.create(view.state.doc, node.pos));
|
|
63
|
-
view.dispatch(tr);
|
|
64
|
-
}
|
|
68
|
+
const item = element.closest('.bib-item');
|
|
69
|
+
if (item) {
|
|
70
|
+
this.handleBibItemInteraction(item);
|
|
65
71
|
}
|
|
66
72
|
};
|
|
73
|
+
this.handleKeyDown = (event) => {
|
|
74
|
+
(0, navigation_utils_1.handleEnterKey)(() => {
|
|
75
|
+
const target = document.activeElement;
|
|
76
|
+
const marker = target?.closest('.comment-marker');
|
|
77
|
+
if (marker) {
|
|
78
|
+
this.handleCommentMarkerInteraction(marker);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const bibItem = target?.closest('.bib-item');
|
|
82
|
+
if (bibItem) {
|
|
83
|
+
this.handleBibItemInteraction(bibItem);
|
|
84
|
+
}
|
|
85
|
+
})(event);
|
|
86
|
+
};
|
|
67
87
|
this.createElement = () => {
|
|
68
88
|
this.container = document.createElement('div');
|
|
69
89
|
this.container.classList.add('block');
|
|
@@ -170,6 +190,7 @@ class BibliographyElementBlockView extends block_view_1.default {
|
|
|
170
190
|
const wrapper = document.createElement('div');
|
|
171
191
|
wrapper.classList.add('contents');
|
|
172
192
|
wrapper.addEventListener('click', this.handleClick);
|
|
193
|
+
wrapper.addEventListener('keydown', this.handleKeyDown);
|
|
173
194
|
const [meta, bibliography] = bib.engine.makeBibliography();
|
|
174
195
|
for (let i = 0; i < bibliography.length; i++) {
|
|
175
196
|
const id = meta.entry_ids[i][0];
|
|
@@ -196,6 +217,7 @@ class BibliographyElementBlockView extends block_view_1.default {
|
|
|
196
217
|
}
|
|
197
218
|
}
|
|
198
219
|
const element = (0, dompurify_1.sanitize)(`<div id="${id}" class="bib-item"><div class="csl-bib-body">${tempDiv.innerHTML}</div></div>`).firstElementChild;
|
|
220
|
+
element.tabIndex = 0;
|
|
199
221
|
const comment = (0, comments_1.createCommentMarker)('div', id);
|
|
200
222
|
element.prepend(comment);
|
|
201
223
|
(0, track_changes_utils_1.addTrackChangesAttributes)(node.attrs, element);
|
|
@@ -27,6 +27,7 @@ const CitationEditor_1 = require("../components/references/CitationEditor");
|
|
|
27
27
|
const CitationViewer_1 = require("../components/references/CitationViewer");
|
|
28
28
|
const comments_1 = require("../lib/comments");
|
|
29
29
|
const crossref_1 = require("../lib/crossref");
|
|
30
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
30
31
|
const track_changes_utils_1 = require("../lib/track-changes-utils");
|
|
31
32
|
const view_1 = require("../lib/view");
|
|
32
33
|
const bibliography_1 = require("../plugins/bibliography");
|
|
@@ -47,12 +48,12 @@ class CitationEditableView extends citation_1.CitationView {
|
|
|
47
48
|
element.classList.contains('comment-icon') ||
|
|
48
49
|
element.parentElement?.classList.contains('comment-icon'));
|
|
49
50
|
};
|
|
50
|
-
this.handleClick = (
|
|
51
|
+
this.handleClick = () => {
|
|
51
52
|
if (!this.can.seeReferencesButtons ||
|
|
52
53
|
this.dom.classList.contains('inconsistency-highlight')) {
|
|
53
54
|
this.showPopper();
|
|
54
55
|
}
|
|
55
|
-
else if (!(0, track_changes_utils_1.isDeleted)(this.node)
|
|
56
|
+
else if (!(0, track_changes_utils_1.isDeleted)(this.node)) {
|
|
56
57
|
const attrs = this.node.attrs;
|
|
57
58
|
if (attrs.rids.length) {
|
|
58
59
|
this.showContextMenu();
|
|
@@ -197,6 +198,7 @@ class CitationEditableView extends citation_1.CitationView {
|
|
|
197
198
|
createDOM() {
|
|
198
199
|
super.createDOM();
|
|
199
200
|
this.dom.addEventListener('mouseup', this.handleClick);
|
|
201
|
+
this.dom.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(() => this.handleClick()));
|
|
200
202
|
}
|
|
201
203
|
insertBibliographyNode(attrs) {
|
|
202
204
|
const { doc, tr } = this.view.state;
|
|
@@ -25,6 +25,7 @@ const prosemirror_state_1 = require("prosemirror-state");
|
|
|
25
25
|
const AuthorsModal_1 = require("../components/authors/AuthorsModal");
|
|
26
26
|
const authors_1 = require("../lib/authors");
|
|
27
27
|
const comments_1 = require("../lib/comments");
|
|
28
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
28
29
|
const track_changes_utils_1 = require("../lib/track-changes-utils");
|
|
29
30
|
const utils_1 = require("../lib/utils");
|
|
30
31
|
const view_1 = require("../lib/view");
|
|
@@ -51,11 +52,26 @@ class ContributorsView extends block_view_1.default {
|
|
|
51
52
|
const can = this.props.getCapabilities();
|
|
52
53
|
if (can.editMetadata) {
|
|
53
54
|
wrapper.addEventListener('click', this.handleClick);
|
|
55
|
+
this.removeKeydownListener = (0, navigation_utils_1.createKeyboardInteraction)({
|
|
56
|
+
container: wrapper,
|
|
57
|
+
navigation: {
|
|
58
|
+
getItems: () => {
|
|
59
|
+
return Array.from(wrapper.querySelectorAll('.contributor'));
|
|
60
|
+
},
|
|
61
|
+
arrowKeys: { forward: 'ArrowRight', backward: 'ArrowLeft' },
|
|
62
|
+
},
|
|
63
|
+
additionalKeys: {
|
|
64
|
+
Enter: (e) => {
|
|
65
|
+
e.preventDefault();
|
|
66
|
+
this.handleClick(e);
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
});
|
|
54
70
|
}
|
|
55
71
|
const authors = affs.contributors;
|
|
56
72
|
authors.sort(authors_1.authorComparator).forEach((author, i) => {
|
|
57
73
|
const jointAuthors = this.isJointFirstAuthor(authors, i);
|
|
58
|
-
wrapper.appendChild(this.buildAuthor(author, jointAuthors));
|
|
74
|
+
wrapper.appendChild(this.buildAuthor(author, jointAuthors, i));
|
|
59
75
|
if (i !== authors.length - 1) {
|
|
60
76
|
const separator = document.createElement('span');
|
|
61
77
|
separator.classList.add('separator');
|
|
@@ -65,13 +81,14 @@ class ContributorsView extends block_view_1.default {
|
|
|
65
81
|
});
|
|
66
82
|
this.container.appendChild(wrapper);
|
|
67
83
|
};
|
|
68
|
-
this.buildAuthor = (attrs, isJointFirstAuthor) => {
|
|
84
|
+
this.buildAuthor = (attrs, isJointFirstAuthor, index) => {
|
|
69
85
|
const state = this.view.state;
|
|
70
86
|
const affs = affiliations_1.affiliationsKey.getState(state)?.indexedAffiliationIds;
|
|
71
87
|
const container = document.createElement('span');
|
|
72
88
|
container.classList.add('contributor');
|
|
73
89
|
container.setAttribute('id', attrs.id);
|
|
74
90
|
container.setAttribute('contenteditable', 'false');
|
|
91
|
+
container.tabIndex = index === 0 ? 0 : -1;
|
|
75
92
|
(0, track_changes_utils_1.addTrackChangesAttributes)(attrs, container);
|
|
76
93
|
const name = (0, authors_1.authorLabel)(attrs);
|
|
77
94
|
container.innerHTML =
|
|
@@ -275,6 +292,10 @@ class ContributorsView extends block_view_1.default {
|
|
|
275
292
|
note.classList.add('contributor-note');
|
|
276
293
|
return note;
|
|
277
294
|
}
|
|
295
|
+
destroy() {
|
|
296
|
+
this.removeKeydownListener?.();
|
|
297
|
+
super.destroy();
|
|
298
|
+
}
|
|
278
299
|
}
|
|
279
300
|
exports.ContributorsView = ContributorsView;
|
|
280
301
|
exports.default = (0, creators_1.createNodeView)(ContributorsView);
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.CrossReferenceView = void 0;
|
|
19
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
19
20
|
const objects_1 = require("../plugins/objects");
|
|
20
21
|
const base_node_view_1 = require("./base_node_view");
|
|
21
22
|
const creators_1 = require("./creators");
|
|
@@ -40,6 +41,8 @@ class CrossReferenceView extends base_node_view_1.BaseNodeView {
|
|
|
40
41
|
this.createDOM = () => {
|
|
41
42
|
this.dom = document.createElement('span');
|
|
42
43
|
this.dom.className = 'cross-reference';
|
|
44
|
+
this.dom.tabIndex = 0;
|
|
45
|
+
this.dom.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(() => this.handleClick()));
|
|
43
46
|
};
|
|
44
47
|
}
|
|
45
48
|
updateContents() {
|
|
@@ -19,6 +19,7 @@ exports.EditableBlock = void 0;
|
|
|
19
19
|
const transform_1 = require("@manuscripts/transform");
|
|
20
20
|
const context_menu_1 = require("../lib/context-menu");
|
|
21
21
|
const utils_1 = require("../lib/utils");
|
|
22
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
22
23
|
const EditableBlock = (Base) => {
|
|
23
24
|
return class extends Base {
|
|
24
25
|
constructor() {
|
|
@@ -28,7 +29,12 @@ const EditableBlock = (Base) => {
|
|
|
28
29
|
};
|
|
29
30
|
}
|
|
30
31
|
gutterButtons() {
|
|
31
|
-
|
|
32
|
+
const buttons = [this.createAddButton(), this.createEditButton()].filter(utils_1.isNotNull);
|
|
33
|
+
buttons.forEach((btn) => (btn.tabIndex = -1));
|
|
34
|
+
if (buttons.length > 0) {
|
|
35
|
+
buttons[0].tabIndex = 0;
|
|
36
|
+
}
|
|
37
|
+
return buttons;
|
|
32
38
|
}
|
|
33
39
|
actionGutterButtons() {
|
|
34
40
|
return [];
|
|
@@ -56,10 +62,24 @@ const EditableBlock = (Base) => {
|
|
|
56
62
|
button.setAttribute('role', 'button');
|
|
57
63
|
button.setAttribute('aria-label', `Add an element below`);
|
|
58
64
|
button.setAttribute('data-balloon-pos', 'down-left');
|
|
59
|
-
|
|
65
|
+
const handleClick = (event) => {
|
|
60
66
|
event.preventDefault();
|
|
61
67
|
const menu = this.createMenu();
|
|
62
68
|
menu.showAddMenu(event.currentTarget);
|
|
69
|
+
};
|
|
70
|
+
button.addEventListener('mousedown', handleClick);
|
|
71
|
+
(0, navigation_utils_1.createKeyboardInteraction)({
|
|
72
|
+
container: button,
|
|
73
|
+
additionalKeys: {
|
|
74
|
+
Enter: handleClick,
|
|
75
|
+
ArrowRight: () => {
|
|
76
|
+
const parent = button.parentElement;
|
|
77
|
+
const editButton = parent?.querySelector('.edit-block');
|
|
78
|
+
if (editButton) {
|
|
79
|
+
editButton.focus();
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
},
|
|
63
83
|
});
|
|
64
84
|
return button;
|
|
65
85
|
}
|
|
@@ -72,10 +92,24 @@ const EditableBlock = (Base) => {
|
|
|
72
92
|
button.setAttribute('role', 'button');
|
|
73
93
|
button.setAttribute('aria-label', 'Open menu');
|
|
74
94
|
button.setAttribute('data-balloon-pos', 'down-left');
|
|
75
|
-
|
|
95
|
+
const handleClick = (event) => {
|
|
76
96
|
event.preventDefault();
|
|
77
97
|
const menu = this.createMenu();
|
|
78
98
|
menu.showEditMenu(event.currentTarget);
|
|
99
|
+
};
|
|
100
|
+
button.addEventListener('mousedown', handleClick);
|
|
101
|
+
(0, navigation_utils_1.createKeyboardInteraction)({
|
|
102
|
+
container: button,
|
|
103
|
+
additionalKeys: {
|
|
104
|
+
Enter: handleClick,
|
|
105
|
+
ArrowLeft: () => {
|
|
106
|
+
const parent = button.parentElement;
|
|
107
|
+
const addButton = parent?.querySelector('.add-block');
|
|
108
|
+
if (addButton) {
|
|
109
|
+
addButton.focus();
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
},
|
|
79
113
|
});
|
|
80
114
|
return button;
|
|
81
115
|
}
|
package/dist/cjs/views/embed.js
CHANGED
|
@@ -164,7 +164,7 @@ class EmbedView extends block_view_1.default {
|
|
|
164
164
|
const href = this.node.attrs.href;
|
|
165
165
|
let object;
|
|
166
166
|
if (!href) {
|
|
167
|
-
object = (0, media_1.createMediaPlaceholder)(media_1.MediaType.Media, this.view, this.getPos);
|
|
167
|
+
object = (0, media_1.createMediaPlaceholder)(media_1.MediaType.Media, this.view, this.getPos, this.props);
|
|
168
168
|
}
|
|
169
169
|
else if (this.isUploadedFile()) {
|
|
170
170
|
const files = this.props.getFiles();
|
|
@@ -178,14 +178,14 @@ class EmbedView extends block_view_1.default {
|
|
|
178
178
|
: (0, media_1.createUnsupportedFormat)(file.name, this.props.getCapabilities().editArticle);
|
|
179
179
|
}
|
|
180
180
|
else {
|
|
181
|
-
object = (0, media_1.createMediaPlaceholder)(media_1.MediaType.Media, this.view, this.getPos);
|
|
181
|
+
object = (0, media_1.createMediaPlaceholder)(media_1.MediaType.Media, this.view, this.getPos, this.props);
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
else if (this.isEmbedLink()) {
|
|
185
185
|
object = await this.createEmbedPreview();
|
|
186
186
|
}
|
|
187
187
|
else {
|
|
188
|
-
object = (0, media_1.createMediaPlaceholder)(media_1.MediaType.Media, this.view, this.getPos);
|
|
188
|
+
object = (0, media_1.createMediaPlaceholder)(media_1.MediaType.Media, this.view, this.getPos, this.props);
|
|
189
189
|
}
|
|
190
190
|
const can = this.props.getCapabilities();
|
|
191
191
|
if (can.uploadFile && object.classList.contains('placeholder')) {
|
|
@@ -52,7 +52,7 @@ class FigureEditableView extends figure_1.FigureView {
|
|
|
52
52
|
return img;
|
|
53
53
|
};
|
|
54
54
|
this.createPlaceholder = () => {
|
|
55
|
-
return (0, media_1.createMediaPlaceholder)(media_1.MediaType.Figure);
|
|
55
|
+
return (0, media_1.createMediaPlaceholder)(media_1.MediaType.Figure, this.view, this.getPos, this.props);
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
58
|
initialise() {
|
|
@@ -19,6 +19,7 @@ exports.FigureElementView = void 0;
|
|
|
19
19
|
const transform_1 = require("@manuscripts/transform");
|
|
20
20
|
const prosemirror_state_1 = require("prosemirror-state");
|
|
21
21
|
const icons_1 = require("../icons");
|
|
22
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
22
23
|
const creators_1 = require("./creators");
|
|
23
24
|
const image_element_1 = require("./image_element");
|
|
24
25
|
class FigureElementView extends image_element_1.ImageElementView {
|
|
@@ -74,6 +75,8 @@ class FigureElementView extends image_element_1.ImageElementView {
|
|
|
74
75
|
title: 'Add figure',
|
|
75
76
|
});
|
|
76
77
|
this.addFigureBtn.addEventListener('click', () => this.addFigure());
|
|
78
|
+
this.addFigureBtn.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(() => this.addFigure()));
|
|
79
|
+
this.addFigureBtn.tabIndex = 0;
|
|
77
80
|
this.container.prepend(this.addFigureBtn);
|
|
78
81
|
}
|
|
79
82
|
}
|
|
@@ -31,15 +31,18 @@ const track_changes_utils_1 = require("../lib/track-changes-utils");
|
|
|
31
31
|
const base_node_view_1 = require("./base_node_view");
|
|
32
32
|
const creators_1 = require("./creators");
|
|
33
33
|
const ReactSubView_1 = __importDefault(require("./ReactSubView"));
|
|
34
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
34
35
|
class FootnoteView extends base_node_view_1.BaseNodeView {
|
|
35
36
|
constructor() {
|
|
36
37
|
super(...arguments);
|
|
37
38
|
this.initialise = () => {
|
|
38
39
|
this.dom = document.createElement('div');
|
|
39
40
|
this.dom.classList.add('footnote');
|
|
41
|
+
this.dom.tabIndex = 0;
|
|
40
42
|
this.contentDOM = document.createElement('div');
|
|
41
43
|
this.contentDOM.classList.add('footnote-text');
|
|
42
44
|
this.dom.addEventListener('mousedown', this.handleClick);
|
|
45
|
+
this.dom.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(this.handleClick));
|
|
43
46
|
this.updateContents();
|
|
44
47
|
};
|
|
45
48
|
this.handleClick = (event) => {
|
|
@@ -20,6 +20,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
21
|
exports.HeroImageView = void 0;
|
|
22
22
|
const icons_1 = require("../icons");
|
|
23
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
23
24
|
const block_view_1 = __importDefault(require("./block_view"));
|
|
24
25
|
const creators_1 = require("./creators");
|
|
25
26
|
class HeroImageView extends block_view_1.default {
|
|
@@ -48,13 +49,15 @@ class HeroImageView extends block_view_1.default {
|
|
|
48
49
|
heroImageToggleBtn.classList.add('toggle-btn', 'button-reset');
|
|
49
50
|
heroImageToggleBtn.innerHTML = icons_1.arrowUp;
|
|
50
51
|
heroImageToggleBtn.classList.toggle('collapsed', this.collapsed);
|
|
51
|
-
|
|
52
|
+
const handleToggle = () => {
|
|
52
53
|
this.collapsed = !this.collapsed;
|
|
53
54
|
if (this.contentDOM) {
|
|
54
55
|
this.contentDOM.style.display = this.collapsed ? 'none' : '';
|
|
55
56
|
}
|
|
56
57
|
heroImageToggleBtn.classList.toggle('collapsed', this.collapsed);
|
|
57
58
|
};
|
|
59
|
+
heroImageToggleBtn.onclick = handleToggle;
|
|
60
|
+
heroImageToggleBtn.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(handleToggle));
|
|
58
61
|
panel.appendChild(label);
|
|
59
62
|
panel.appendChild(heroImageToggleBtn);
|
|
60
63
|
return panel;
|
|
@@ -23,6 +23,7 @@ const style_guide_1 = require("@manuscripts/style-guide");
|
|
|
23
23
|
const transform_1 = require("@manuscripts/transform");
|
|
24
24
|
const icons_1 = require("../icons");
|
|
25
25
|
const media_1 = require("../lib/media");
|
|
26
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
26
27
|
const position_menu_1 = require("../lib/position-menu");
|
|
27
28
|
const block_view_1 = __importDefault(require("./block_view"));
|
|
28
29
|
const creators_1 = require("./creators");
|
|
@@ -200,14 +201,16 @@ class ImageElementView extends block_view_1.default {
|
|
|
200
201
|
label.innerText = 'Link';
|
|
201
202
|
const container = document.createElement('div');
|
|
202
203
|
container.classList.add('ext-link-editor-placeholder-container');
|
|
203
|
-
const placeholder = (0, media_1.createMediaPlaceholder)(media_1.MediaType.ExternalLink);
|
|
204
|
+
const placeholder = (0, media_1.createMediaPlaceholder)(media_1.MediaType.ExternalLink, this.view, this.getPos, this.props);
|
|
204
205
|
const closeButton = document.createElement('button');
|
|
205
206
|
closeButton.classList.add('close-button');
|
|
206
207
|
closeButton.setAttribute('aria-label', 'Close');
|
|
207
|
-
|
|
208
|
+
const handleClose = () => {
|
|
208
209
|
this.setIsEditingExtLink(false);
|
|
209
210
|
this.updateContents();
|
|
210
|
-
}
|
|
211
|
+
};
|
|
212
|
+
closeButton.addEventListener('click', handleClose);
|
|
213
|
+
closeButton.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(handleClose));
|
|
211
214
|
container.append(placeholder, closeButton);
|
|
212
215
|
this.extLinkEditorContainer.append(label, container);
|
|
213
216
|
if (can.uploadFile) {
|
|
@@ -222,10 +225,13 @@ class ImageElementView extends block_view_1.default {
|
|
|
222
225
|
button.appendChild(buttonText);
|
|
223
226
|
button.setAttribute('aria-label', 'Add linked file');
|
|
224
227
|
button.classList.add('icon-button');
|
|
225
|
-
button.
|
|
228
|
+
button.tabIndex = 0;
|
|
229
|
+
const handleAdd = () => {
|
|
226
230
|
this.setIsEditingExtLink(true);
|
|
227
231
|
this.updateContents();
|
|
228
|
-
}
|
|
232
|
+
};
|
|
233
|
+
button.addEventListener('click', handleAdd);
|
|
234
|
+
button.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(handleAdd));
|
|
229
235
|
this.extLinkEditorContainer.appendChild(button);
|
|
230
236
|
}
|
|
231
237
|
createLinkedFile() {
|
|
@@ -240,10 +246,12 @@ class ImageElementView extends block_view_1.default {
|
|
|
240
246
|
removeButton.classList.add('icon-button', 'remove-button');
|
|
241
247
|
removeButton.setAttribute('aria-label', 'Remove link');
|
|
242
248
|
removeButton.innerHTML = icons_1.deleteIcon;
|
|
243
|
-
|
|
249
|
+
const handleRemove = () => {
|
|
244
250
|
this.isEditingExtLink = false;
|
|
245
251
|
this.removeExtLink();
|
|
246
|
-
}
|
|
252
|
+
};
|
|
253
|
+
removeButton.addEventListener('click', handleRemove);
|
|
254
|
+
removeButton.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(handleRemove));
|
|
247
255
|
div.appendChild(removeButton);
|
|
248
256
|
this.extLinkEditorContainer.appendChild(div);
|
|
249
257
|
}
|
|
@@ -23,6 +23,7 @@ const style_guide_1 = require("@manuscripts/style-guide");
|
|
|
23
23
|
const prosemirror_state_1 = require("prosemirror-state");
|
|
24
24
|
const commands_1 = require("../commands");
|
|
25
25
|
const FootnotesSelector_1 = require("../components/views/FootnotesSelector");
|
|
26
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
26
27
|
const footnotes_1 = require("../lib/footnotes");
|
|
27
28
|
const track_changes_utils_1 = require("../lib/track-changes-utils");
|
|
28
29
|
const base_node_view_1 = require("./base_node_view");
|
|
@@ -108,7 +109,9 @@ class InlineFootnoteView extends base_node_view_1.BaseNodeView {
|
|
|
108
109
|
this.initialise = () => {
|
|
109
110
|
this.dom = this.createDOM();
|
|
110
111
|
this.dom.classList.add('footnote-marker');
|
|
112
|
+
this.dom.tabIndex = 0;
|
|
111
113
|
this.dom.addEventListener('click', this.handleClick);
|
|
114
|
+
this.dom.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(() => this.handleClick()));
|
|
112
115
|
this.updateContents();
|
|
113
116
|
};
|
|
114
117
|
this.selectNode = () => {
|
|
@@ -21,9 +21,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
21
21
|
exports.KeywordView = void 0;
|
|
22
22
|
const prosemirror_state_1 = require("prosemirror-state");
|
|
23
23
|
const DeleteKeywordDialog_1 = require("../components/keywords/DeleteKeywordDialog");
|
|
24
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
24
25
|
const base_node_view_1 = require("./base_node_view");
|
|
25
26
|
const creators_1 = require("./creators");
|
|
26
27
|
const ReactSubView_1 = __importDefault(require("./ReactSubView"));
|
|
28
|
+
const track_changes_utils_1 = require("../lib/track-changes-utils");
|
|
27
29
|
const deleteIcon = '<svg width="8px" height="8px" viewBox="0 0 26 26" xmlns="http://www.w3.org/2000/svg">\n' +
|
|
28
30
|
' <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">\n' +
|
|
29
31
|
' <g fill="#6E6E6E">\n' +
|
|
@@ -42,6 +44,8 @@ class KeywordView extends base_node_view_1.BaseNodeView {
|
|
|
42
44
|
this.createDOM = () => {
|
|
43
45
|
this.dom = document.createElement('span');
|
|
44
46
|
this.dom.classList.add('keyword');
|
|
47
|
+
this.dom.tabIndex = this.isFirstKeyword() ? 0 : -1;
|
|
48
|
+
this.dom.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(() => this.showConfirmationDialog()));
|
|
45
49
|
this.contentDOM = document.createElement('span');
|
|
46
50
|
};
|
|
47
51
|
this.showConfirmationDialog = () => {
|
|
@@ -63,6 +67,17 @@ class KeywordView extends base_node_view_1.BaseNodeView {
|
|
|
63
67
|
}
|
|
64
68
|
};
|
|
65
69
|
}
|
|
70
|
+
isFirstKeyword() {
|
|
71
|
+
const pos = this.getPos();
|
|
72
|
+
const parent = this.view.state.doc.resolve(pos).parent;
|
|
73
|
+
for (let i = 0; i < parent.childCount; i++) {
|
|
74
|
+
const child = parent.child(i);
|
|
75
|
+
if (!(0, track_changes_utils_1.isDeleted)(child)) {
|
|
76
|
+
return child === this.node;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
66
81
|
updateContents() {
|
|
67
82
|
super.updateContents();
|
|
68
83
|
this.dom.innerHTML = '';
|
|
@@ -20,6 +20,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
21
|
exports.KeywordGroupView = void 0;
|
|
22
22
|
const AddKeywordInline_1 = require("../components/keywords/AddKeywordInline");
|
|
23
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
24
|
+
const track_changes_utils_1 = require("../lib/track-changes-utils");
|
|
23
25
|
const block_view_1 = __importDefault(require("./block_view"));
|
|
24
26
|
const creators_1 = require("./creators");
|
|
25
27
|
const ReactSubView_1 = __importDefault(require("./ReactSubView"));
|
|
@@ -36,6 +38,13 @@ class KeywordGroupView extends block_view_1.default {
|
|
|
36
38
|
this.contentDOM.setAttribute('id', this.node.attrs.id);
|
|
37
39
|
this.contentDOM.setAttribute('contenteditable', 'false');
|
|
38
40
|
this.element.appendChild(this.contentDOM);
|
|
41
|
+
this.removeKeydownListener = (0, navigation_utils_1.createKeyboardInteraction)({
|
|
42
|
+
container: this.element,
|
|
43
|
+
navigation: {
|
|
44
|
+
getItems: () => Array.from(this.element.querySelectorAll('.keyword:not(.deleted), .keyword-add')),
|
|
45
|
+
arrowKeys: { forward: 'ArrowRight', backward: 'ArrowLeft' },
|
|
46
|
+
},
|
|
47
|
+
});
|
|
39
48
|
if (this.props.getCapabilities().editArticle) {
|
|
40
49
|
this.addingTools = (0, ReactSubView_1.default)(this.props, AddKeywordInline_1.AddKeywordInline, { getUpdatedNode: () => this.node }, this.node, this.getPos, this.view, ['keywords-editor']);
|
|
41
50
|
}
|
|
@@ -44,6 +53,35 @@ class KeywordGroupView extends block_view_1.default {
|
|
|
44
53
|
}
|
|
45
54
|
};
|
|
46
55
|
}
|
|
56
|
+
updateContents() {
|
|
57
|
+
super.updateContents();
|
|
58
|
+
this.setKeywordsTabIndices();
|
|
59
|
+
}
|
|
60
|
+
setKeywordsTabIndices() {
|
|
61
|
+
const container = this.contentDOM;
|
|
62
|
+
if (!container) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
let firstFocusableFound = false;
|
|
66
|
+
for (let i = 0; i < this.node.childCount; i++) {
|
|
67
|
+
const child = this.node.child(i);
|
|
68
|
+
const keyword = container.querySelector(`.keyword[id="${child.attrs.id}"]`);
|
|
69
|
+
if (!keyword) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (!(0, track_changes_utils_1.isDeleted)(child) && !firstFocusableFound) {
|
|
73
|
+
keyword.tabIndex = 0;
|
|
74
|
+
firstFocusableFound = true;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
keyword.tabIndex = -1;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
destroy() {
|
|
82
|
+
this.removeKeydownListener?.();
|
|
83
|
+
super.destroy();
|
|
84
|
+
}
|
|
47
85
|
}
|
|
48
86
|
exports.KeywordGroupView = KeywordGroupView;
|
|
49
87
|
exports.default = (0, creators_1.createNodeView)(KeywordGroupView);
|
|
@@ -26,6 +26,7 @@ class QuoteImageEditableView extends figure_editable_1.FigureEditableView {
|
|
|
26
26
|
this.createPlaceholder = () => {
|
|
27
27
|
const element = document.createElement('div');
|
|
28
28
|
element.classList.add('figure', 'placeholder');
|
|
29
|
+
element.tabIndex = 0;
|
|
29
30
|
const instructions = document.createElement('div');
|
|
30
31
|
instructions.classList.add('instructions');
|
|
31
32
|
instructions.innerHTML = `${icons_1.plusIcon}<div>Drag or click here to upload image</div>`;
|
|
@@ -20,6 +20,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
21
|
exports.SupplementsView = void 0;
|
|
22
22
|
const icons_1 = require("../icons");
|
|
23
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
23
24
|
const block_view_1 = __importDefault(require("./block_view"));
|
|
24
25
|
const creators_1 = require("./creators");
|
|
25
26
|
class SupplementsView extends block_view_1.default {
|
|
@@ -31,11 +32,13 @@ class SupplementsView extends block_view_1.default {
|
|
|
31
32
|
this.toggleButton = document.createElement('button');
|
|
32
33
|
this.toggleButton.classList.add('supplements-toggle-btn', 'button-reset');
|
|
33
34
|
this.toggleButton.innerHTML = icons_1.arrowUp;
|
|
34
|
-
|
|
35
|
+
const handleToggle = () => {
|
|
35
36
|
this.collapsed = !this.collapsed;
|
|
36
37
|
this.toggleContent();
|
|
37
38
|
this.toggleButton?.classList.toggle('collapsed', this.collapsed);
|
|
38
39
|
};
|
|
40
|
+
this.toggleButton.onclick = handleToggle;
|
|
41
|
+
this.toggleButton.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(handleToggle));
|
|
39
42
|
this.contentDOM = document.createElement('div');
|
|
40
43
|
this.contentDOM.classList.add('supplements-content');
|
|
41
44
|
this.contentDOM.classList.add('block');
|
package/dist/es/commands.js
CHANGED
|
@@ -34,6 +34,7 @@ import { setCommentSelection } from './plugins/comments';
|
|
|
34
34
|
import { getEditorProps } from './plugins/editor-props';
|
|
35
35
|
import { searchReplaceKey } from './plugins/search-replace';
|
|
36
36
|
import { checkForCompletion } from './plugins/section_title/autocompletion';
|
|
37
|
+
import { persistentCursor } from './plugins/persistent-cursor';
|
|
37
38
|
export const addToStart = (state, dispatch) => {
|
|
38
39
|
const { selection } = state;
|
|
39
40
|
const props = getEditorProps(state);
|
|
@@ -1296,10 +1297,12 @@ export const ignoreEnterInSubtitles = (state) => {
|
|
|
1296
1297
|
}
|
|
1297
1298
|
return false;
|
|
1298
1299
|
};
|
|
1299
|
-
export const exitEditorToContainer = () => {
|
|
1300
|
+
export const exitEditorToContainer = (state, dispatch, view) => {
|
|
1300
1301
|
const editorContainer = document.getElementById('editor');
|
|
1301
|
-
if (editorContainer) {
|
|
1302
|
+
if (editorContainer && dispatch && view) {
|
|
1302
1303
|
editorContainer.focus();
|
|
1304
|
+
const tr = view.state.tr.setMeta(persistentCursor, { on: true });
|
|
1305
|
+
view.dispatch(tr);
|
|
1303
1306
|
return true;
|
|
1304
1307
|
}
|
|
1305
1308
|
return false;
|
|
@@ -28,6 +28,12 @@ const NewKeywordButton = styled.button `
|
|
|
28
28
|
margin: 0;
|
|
29
29
|
padding: 0;
|
|
30
30
|
cursor: pointer;
|
|
31
|
+
|
|
32
|
+
&:focus-visible {
|
|
33
|
+
outline: 4px solid ${(props) => props.theme.colors.outline.focus};
|
|
34
|
+
outline-offset: 2px;
|
|
35
|
+
border-radius: 3px;
|
|
36
|
+
}
|
|
31
37
|
`;
|
|
32
38
|
const CreateKeywordButtonWrapper = styled.div `
|
|
33
39
|
position: absolute;
|
|
@@ -157,8 +163,13 @@ export const AddKeywordInline = ({ viewProps, getUpdatedNode }) => {
|
|
|
157
163
|
},
|
|
158
164
|
};
|
|
159
165
|
return (React.createElement(AddNewKeyword, { ref: nodeRef },
|
|
160
|
-
!isAddingNewKeyword && (React.createElement(NewKeywordButton, { onClick: () => {
|
|
166
|
+
!isAddingNewKeyword && (React.createElement(NewKeywordButton, { tabIndex: -1, className: "keyword-add", onClick: () => {
|
|
161
167
|
setIsAddingNewKeyword(true);
|
|
168
|
+
}, onKeyDown: (e) => {
|
|
169
|
+
if (e.key === 'Enter') {
|
|
170
|
+
e.preventDefault();
|
|
171
|
+
setIsAddingNewKeyword(true);
|
|
172
|
+
}
|
|
162
173
|
} }, "New keyword...")),
|
|
163
174
|
isAddingNewKeyword && React.createElement(KeywordInput, null),
|
|
164
175
|
isAddingNewKeyword && isValidNewKeyword() && (React.createElement(CreateKeywordButtonElement, null)),
|