@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
package/dist/cjs/lib/popper.js
CHANGED
|
@@ -17,18 +17,36 @@
|
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.PopperManager = void 0;
|
|
19
19
|
const core_1 = require("@popperjs/core");
|
|
20
|
+
const navigation_utils_1 = require("./navigation-utils");
|
|
20
21
|
class PopperManager {
|
|
21
22
|
constructor() {
|
|
22
23
|
this.isActive = () => !!this.activePopper;
|
|
23
24
|
}
|
|
24
25
|
show(target, contents, placement = 'bottom', showArrow = true, modifiers = []) {
|
|
25
26
|
this.destroy();
|
|
27
|
+
this.triggerElement = target;
|
|
26
28
|
window.requestAnimationFrame(() => {
|
|
27
29
|
const container = document.createElement('div');
|
|
28
30
|
container.className = 'popper';
|
|
31
|
+
this.container = container;
|
|
29
32
|
container.addEventListener('click', (e) => {
|
|
30
33
|
e.stopPropagation();
|
|
31
34
|
});
|
|
35
|
+
const closeAndRestoreFocus = (e) => {
|
|
36
|
+
e.preventDefault();
|
|
37
|
+
e.stopPropagation();
|
|
38
|
+
this.destroy();
|
|
39
|
+
if (this.triggerElement instanceof HTMLElement) {
|
|
40
|
+
this.triggerElement.focus();
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
(0, navigation_utils_1.createKeyboardInteraction)({
|
|
44
|
+
container,
|
|
45
|
+
additionalKeys: {
|
|
46
|
+
Escape: closeAndRestoreFocus,
|
|
47
|
+
Tab: closeAndRestoreFocus,
|
|
48
|
+
},
|
|
49
|
+
});
|
|
32
50
|
if (showArrow) {
|
|
33
51
|
const arrow = document.createElement('div');
|
|
34
52
|
arrow.className = 'popper-arrow';
|
|
@@ -80,15 +98,21 @@ class PopperManager {
|
|
|
80
98
|
window.removeEventListener('click', this.handleDocumentClick);
|
|
81
99
|
}
|
|
82
100
|
delete this.activePopper;
|
|
101
|
+
delete this.container;
|
|
83
102
|
}
|
|
84
103
|
}
|
|
104
|
+
getContainer() {
|
|
105
|
+
return this.container;
|
|
106
|
+
}
|
|
85
107
|
update() {
|
|
86
108
|
if (this.activePopper) {
|
|
87
109
|
this.activePopper.update();
|
|
88
110
|
}
|
|
89
111
|
}
|
|
90
112
|
focusInput(container) {
|
|
91
|
-
const
|
|
113
|
+
const input = container.querySelector('input');
|
|
114
|
+
const button = container.querySelector('button:not([disabled])');
|
|
115
|
+
const element = input || button;
|
|
92
116
|
if (element) {
|
|
93
117
|
element.focus();
|
|
94
118
|
}
|
|
@@ -23,6 +23,7 @@ const style_guide_1 = require("@manuscripts/style-guide");
|
|
|
23
23
|
const icons_1 = require("../icons");
|
|
24
24
|
const image_element_1 = require("../views/image_element");
|
|
25
25
|
const ReactSubView_1 = __importDefault(require("../views/ReactSubView"));
|
|
26
|
+
const navigation_utils_1 = require("./navigation-utils");
|
|
26
27
|
const view_1 = require("./view");
|
|
27
28
|
const createPositionOptions = (nodeType, node, currentPosition, view, onComplete) => {
|
|
28
29
|
const createAction = (position) => () => {
|
|
@@ -114,7 +115,9 @@ const createPositionMenuWrapper = (currentPosition, onClick, props) => {
|
|
|
114
115
|
positionMenuButton.innerHTML = icon;
|
|
115
116
|
}
|
|
116
117
|
if (can.editArticle) {
|
|
118
|
+
positionMenuButton.tabIndex = 0;
|
|
117
119
|
positionMenuButton.addEventListener('click', onClick);
|
|
120
|
+
positionMenuButton.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(onClick));
|
|
118
121
|
}
|
|
119
122
|
positionMenuWrapper.appendChild(positionMenuButton);
|
|
120
123
|
return positionMenuWrapper;
|
package/dist/cjs/lib/utils.js
CHANGED
|
@@ -22,6 +22,7 @@ const prosemirror_model_1 = require("prosemirror-model");
|
|
|
22
22
|
const prosemirror_utils_1 = require("prosemirror-utils");
|
|
23
23
|
const config_1 = require("../components/references/ReferenceForm/config");
|
|
24
24
|
const icons_1 = require("../icons");
|
|
25
|
+
const navigation_utils_1 = require("./navigation-utils");
|
|
25
26
|
const editor_props_1 = require("../plugins/editor-props");
|
|
26
27
|
function* iterateChildren(node, recurse = false) {
|
|
27
28
|
for (let i = 0; i < node.childCount; i++) {
|
|
@@ -158,10 +159,14 @@ const createToggleButton = (listener, what) => {
|
|
|
158
159
|
altTitlesButton.classList.add('toggle-button-open', 'button-reset');
|
|
159
160
|
altTitlesButton.setAttribute('aria-label', `Expand ${what}`);
|
|
160
161
|
altTitlesButton.innerHTML = icons_1.arrowDown;
|
|
161
|
-
|
|
162
|
+
const activate = (e) => {
|
|
162
163
|
e.preventDefault();
|
|
163
|
-
listener();
|
|
164
|
+
listener(e);
|
|
165
|
+
};
|
|
166
|
+
altTitlesButton.addEventListener('click', (e) => {
|
|
167
|
+
activate(e);
|
|
164
168
|
});
|
|
169
|
+
altTitlesButton.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(activate));
|
|
165
170
|
return altTitlesButton;
|
|
166
171
|
};
|
|
167
172
|
exports.createToggleButton = createToggleButton;
|
|
@@ -7,10 +7,18 @@ const prosemirror_view_1 = require("prosemirror-view");
|
|
|
7
7
|
const utils_1 = require("../lib/utils");
|
|
8
8
|
exports.accessibilityElementKey = new prosemirror_state_1.PluginKey('accessibility-element');
|
|
9
9
|
const nodeTypes = [transform_1.schema.nodes.alt_text, transform_1.schema.nodes.long_desc];
|
|
10
|
-
const handleExpandButtonClick = (view, node) => {
|
|
10
|
+
const handleExpandButtonClick = (view, node, event) => {
|
|
11
11
|
const tr = view.state.tr;
|
|
12
12
|
(0, exports.toggleAccessibilitySection)(tr, node);
|
|
13
13
|
view.dispatch(tr);
|
|
14
|
+
const isKeyboardEvent = event.type === 'keydown';
|
|
15
|
+
if (isKeyboardEvent) {
|
|
16
|
+
const parentElement = view.dom.querySelector(`[id="${node.attrs.id}"]`);
|
|
17
|
+
if (parentElement) {
|
|
18
|
+
const firstInput = parentElement.querySelector('.accessibility_element_input');
|
|
19
|
+
firstInput?.focus();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
14
22
|
};
|
|
15
23
|
const isSelectionWithin = (node, pos, selection) => {
|
|
16
24
|
if (!selection || !nodeTypes.includes(node.type)) {
|
|
@@ -27,7 +35,7 @@ const buildExpandButtonDecorations = (doc) => {
|
|
|
27
35
|
const container = document.createElement('div');
|
|
28
36
|
container.className =
|
|
29
37
|
'accessibility_element_expander_button_container';
|
|
30
|
-
container.appendChild((0, utils_1.createToggleButton)(() => handleExpandButtonClick(view, node), 'additional info'));
|
|
38
|
+
container.appendChild((0, utils_1.createToggleButton)((e) => handleExpandButtonClick(view, node, e), 'additional info'));
|
|
31
39
|
return container;
|
|
32
40
|
}, {
|
|
33
41
|
key: node.attrs.id,
|
|
@@ -20,15 +20,21 @@ const prosemirror_state_1 = require("prosemirror-state");
|
|
|
20
20
|
const prosemirror_view_1 = require("prosemirror-view");
|
|
21
21
|
const uuid_1 = require("uuid");
|
|
22
22
|
const icons_1 = require("../icons");
|
|
23
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
23
24
|
const utils_1 = require("../lib/utils");
|
|
24
25
|
const createAddSubtitleButton = (handler) => {
|
|
25
26
|
const button = document.createElement('span');
|
|
26
27
|
button.className = 'add-subtitle';
|
|
27
28
|
button.innerHTML = `${icons_1.addAuthorIcon} <span class="add-subtitle-text">Add subtitle</span>`;
|
|
28
|
-
button.
|
|
29
|
-
|
|
29
|
+
button.tabIndex = 0;
|
|
30
|
+
const activate = (event) => {
|
|
31
|
+
event.preventDefault();
|
|
30
32
|
handler();
|
|
33
|
+
};
|
|
34
|
+
button.addEventListener('mousedown', (e) => {
|
|
35
|
+
activate(e);
|
|
31
36
|
});
|
|
37
|
+
button.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(activate));
|
|
32
38
|
return button;
|
|
33
39
|
};
|
|
34
40
|
exports.default = (props) => new prosemirror_state_1.Plugin({
|
|
@@ -134,11 +134,16 @@ exports.default = () => {
|
|
|
134
134
|
else if (pState.title[0].textContent.length) {
|
|
135
135
|
const titleEnd = pState.title[0].nodeSize + pState.title[1];
|
|
136
136
|
decorations.push(prosemirror_view_1.Decoration.widget(titleEnd - 1, (view) => {
|
|
137
|
-
return (0, utils_1.createToggleButton)(() => {
|
|
137
|
+
return (0, utils_1.createToggleButton)((e) => {
|
|
138
138
|
const tr = view.state.tr.setMeta(exports.altTitlesKey, {
|
|
139
139
|
collapsed: false,
|
|
140
140
|
});
|
|
141
141
|
view.dispatch((0, track_changes_plugin_1.skipTracking)(tr));
|
|
142
|
+
const isKeyboardEvent = e.type === 'keydown';
|
|
143
|
+
if (isKeyboardEvent) {
|
|
144
|
+
const altTitle = view.dom.querySelector('.alt-title-text');
|
|
145
|
+
altTitle?.focus();
|
|
146
|
+
}
|
|
142
147
|
}, 'alternative titles');
|
|
143
148
|
}, {
|
|
144
149
|
side: -1,
|
|
@@ -5,10 +5,28 @@ const transform_1 = require("@manuscripts/transform");
|
|
|
5
5
|
const prosemirror_state_1 = require("prosemirror-state");
|
|
6
6
|
const prosemirror_utils_1 = require("prosemirror-utils");
|
|
7
7
|
const prosemirror_view_1 = require("prosemirror-view");
|
|
8
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
8
9
|
const comments_1 = require("../lib/comments");
|
|
9
10
|
exports.commentsKey = new prosemirror_state_1.PluginKey('comments');
|
|
10
11
|
const COMMENT_SELECTION = 'comment-selection';
|
|
11
12
|
const EMPTY_SELECTION = {};
|
|
13
|
+
const handleCommentMarkerInteraction = (view, target) => {
|
|
14
|
+
const state = view.state;
|
|
15
|
+
const com = exports.commentsKey.getState(state);
|
|
16
|
+
const marker = target?.closest('[data-key]');
|
|
17
|
+
if (!marker && !com?.selection) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const tr = state.tr;
|
|
21
|
+
if (marker) {
|
|
22
|
+
const key = marker.dataset.key;
|
|
23
|
+
(0, exports.setCommentSelection)(tr, key, undefined, false);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
(0, exports.clearCommentSelection)(tr);
|
|
27
|
+
}
|
|
28
|
+
view.dispatch(tr);
|
|
29
|
+
};
|
|
12
30
|
exports.default = () => {
|
|
13
31
|
return new prosemirror_state_1.Plugin({
|
|
14
32
|
key: exports.commentsKey,
|
|
@@ -27,22 +45,16 @@ exports.default = () => {
|
|
|
27
45
|
props: {
|
|
28
46
|
decorations: (state) => exports.commentsKey.getState(state)?.decorations,
|
|
29
47
|
handleClick: (view, pos, e) => {
|
|
30
|
-
const state = view.state;
|
|
31
|
-
const com = exports.commentsKey.getState(state);
|
|
32
48
|
const target = e.target;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
(0, exports.clearCommentSelection)(tr);
|
|
44
|
-
}
|
|
45
|
-
view.dispatch(tr);
|
|
49
|
+
return handleCommentMarkerInteraction(view, target);
|
|
50
|
+
},
|
|
51
|
+
handleDOMEvents: {
|
|
52
|
+
keydown: (view, e) => {
|
|
53
|
+
return (0, navigation_utils_1.handleEnterKey)(() => {
|
|
54
|
+
const target = document.activeElement;
|
|
55
|
+
handleCommentMarkerInteraction(view, target);
|
|
56
|
+
})(e);
|
|
57
|
+
},
|
|
46
58
|
},
|
|
47
59
|
},
|
|
48
60
|
});
|
|
@@ -49,12 +49,10 @@ exports.default = () => {
|
|
|
49
49
|
},
|
|
50
50
|
handleDOMEvents: {
|
|
51
51
|
focus(view, event) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const newTr = view.state.tr.setMeta(exports.persistentCursor, { on: true });
|
|
57
|
-
view.dispatch(newTr);
|
|
52
|
+
if (this.getState(view.state)?.on) {
|
|
53
|
+
const newTr = view.state.tr.setMeta(exports.persistentCursor, { on: false });
|
|
54
|
+
view.dispatch(newTr);
|
|
55
|
+
}
|
|
58
56
|
},
|
|
59
57
|
},
|
|
60
58
|
},
|
|
@@ -6,6 +6,7 @@ const prosemirror_state_1 = require("prosemirror-state");
|
|
|
6
6
|
const prosemirror_utils_1 = require("prosemirror-utils");
|
|
7
7
|
const prosemirror_view_1 = require("prosemirror-view");
|
|
8
8
|
const icons_1 = require("../icons");
|
|
9
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
9
10
|
exports.sectionCategoryKey = new prosemirror_state_1.PluginKey('section-category');
|
|
10
11
|
exports.default = (props) => new prosemirror_state_1.Plugin({
|
|
11
12
|
key: exports.sectionCategoryKey,
|
|
@@ -32,27 +33,51 @@ const createMenuItem = (props, contents, handler, isDisabled, isSelected) => {
|
|
|
32
33
|
item.classList.add('disabled');
|
|
33
34
|
}
|
|
34
35
|
item.textContent = contents;
|
|
35
|
-
item.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
});
|
|
36
|
+
item.setAttribute('tabindex', '0');
|
|
37
|
+
item.addEventListener('mousedown', handler);
|
|
38
|
+
item.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(handler));
|
|
39
39
|
return item;
|
|
40
40
|
};
|
|
41
41
|
const createMenu = (props, currentCategory, categories, usedCategoryIDs, onSelect) => {
|
|
42
42
|
const menu = document.createElement('div');
|
|
43
43
|
menu.className = 'section-category menu';
|
|
44
|
+
const menuItems = [];
|
|
45
|
+
const removeKeydownListener = (0, navigation_utils_1.createKeyboardInteraction)({
|
|
46
|
+
container: document,
|
|
47
|
+
navigation: {
|
|
48
|
+
getItems: () => menuItems,
|
|
49
|
+
arrowKeys: {
|
|
50
|
+
forward: 'ArrowDown',
|
|
51
|
+
backward: 'ArrowUp',
|
|
52
|
+
},
|
|
53
|
+
getCurrentElement: () => document.activeElement,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
const destroy = () => {
|
|
57
|
+
removeKeydownListener();
|
|
58
|
+
props.popper.destroy();
|
|
59
|
+
};
|
|
44
60
|
categories.forEach((category) => {
|
|
45
|
-
const item = createMenuItem(props, category.titles[0], () =>
|
|
61
|
+
const item = createMenuItem(props, category.titles[0], () => {
|
|
62
|
+
onSelect(category);
|
|
63
|
+
destroy();
|
|
64
|
+
}, category.isUnique && usedCategoryIDs.has(category.id), currentCategory === category);
|
|
65
|
+
menuItems.push(item);
|
|
46
66
|
menu.appendChild(item);
|
|
47
67
|
});
|
|
48
|
-
return menu;
|
|
68
|
+
return { menu, destroy };
|
|
49
69
|
};
|
|
50
70
|
const createButton = (props, view, pos, currentCategory, categories, usedCategoryIDs, canEdit = true, disabled) => {
|
|
71
|
+
let menuInstance = null;
|
|
51
72
|
const handleSelect = (category) => {
|
|
52
73
|
const tr = view.state.tr;
|
|
53
74
|
tr.setNodeAttribute(pos, 'category', category.id);
|
|
54
75
|
view.dispatch(tr);
|
|
55
76
|
};
|
|
77
|
+
const openMenu = () => {
|
|
78
|
+
menuInstance = createMenu(props, currentCategory, categories, usedCategoryIDs, handleSelect);
|
|
79
|
+
props.popper.show(button, menuInstance.menu, 'bottom-end', false);
|
|
80
|
+
};
|
|
56
81
|
const button = document.createElement('button');
|
|
57
82
|
button.innerHTML = icons_1.sectionCategoryIcon;
|
|
58
83
|
button.classList.add('section-category-button');
|
|
@@ -65,9 +90,17 @@ const createButton = (props, view, pos, currentCategory, categories, usedCategor
|
|
|
65
90
|
button.classList.add('disabled');
|
|
66
91
|
}
|
|
67
92
|
else if (canEdit) {
|
|
68
|
-
button.addEventListener('
|
|
69
|
-
|
|
70
|
-
|
|
93
|
+
button.addEventListener('click', openMenu);
|
|
94
|
+
(0, navigation_utils_1.createKeyboardInteraction)({
|
|
95
|
+
container: button,
|
|
96
|
+
additionalKeys: {
|
|
97
|
+
Enter: openMenu,
|
|
98
|
+
Escape: (e) => {
|
|
99
|
+
e.preventDefault();
|
|
100
|
+
menuInstance?.destroy();
|
|
101
|
+
menuInstance = null;
|
|
102
|
+
},
|
|
103
|
+
},
|
|
71
104
|
});
|
|
72
105
|
}
|
|
73
106
|
return button;
|
|
@@ -22,24 +22,43 @@ const commands_1 = require("../commands");
|
|
|
22
22
|
const icons_1 = require("../icons");
|
|
23
23
|
const languages_1 = require("../lib/languages");
|
|
24
24
|
const template_1 = require("../lib/template");
|
|
25
|
-
const
|
|
25
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
26
|
+
const createMenuItem = (props, contents, handler, isSelected = false, tabIndex) => {
|
|
26
27
|
const item = document.createElement('div');
|
|
27
28
|
item.className = `menu-item ${isSelected ? 'selected' : ''}`;
|
|
28
29
|
item.textContent = contents;
|
|
29
|
-
item.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
});
|
|
30
|
+
item.tabIndex = tabIndex;
|
|
31
|
+
item.addEventListener('mousedown', handler);
|
|
32
|
+
item.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(handler));
|
|
33
33
|
return item;
|
|
34
34
|
};
|
|
35
35
|
const createLanguageMenu = (props, selectedCode, onSelect) => {
|
|
36
36
|
const menu = document.createElement('div');
|
|
37
37
|
menu.className = 'language menu';
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
const menuItems = [];
|
|
39
|
+
const removeKeydownListener = (0, navigation_utils_1.createKeyboardInteraction)({
|
|
40
|
+
container: document,
|
|
41
|
+
navigation: {
|
|
42
|
+
getItems: () => menuItems,
|
|
43
|
+
arrowKeys: {
|
|
44
|
+
forward: 'ArrowDown',
|
|
45
|
+
backward: 'ArrowUp',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
const destroy = () => {
|
|
50
|
+
removeKeydownListener();
|
|
51
|
+
props.popper.destroy();
|
|
52
|
+
};
|
|
53
|
+
props.languages.forEach((language, index) => {
|
|
54
|
+
const item = createMenuItem(props, (0, languages_1.getLanguageLabel)(language), () => {
|
|
55
|
+
onSelect(language.code);
|
|
56
|
+
destroy();
|
|
57
|
+
}, selectedCode === language.code, index === 0 ? 0 : -1);
|
|
58
|
+
menuItems.push(item);
|
|
40
59
|
menu.appendChild(item);
|
|
41
60
|
});
|
|
42
|
-
return menu;
|
|
61
|
+
return { menu, destroy };
|
|
43
62
|
};
|
|
44
63
|
exports.default = (props) => new prosemirror_state_1.Plugin({
|
|
45
64
|
props: {
|
|
@@ -66,10 +85,11 @@ exports.default = (props) => new prosemirror_state_1.Plugin({
|
|
|
66
85
|
if (canEdit) {
|
|
67
86
|
widgets.push(prosemirror_view_1.Decoration.widget(pos + 1, (view) => {
|
|
68
87
|
const $span = document.createElement('span');
|
|
88
|
+
$span.tabIndex = 0;
|
|
69
89
|
$span.className = 'add-trans-abstract';
|
|
70
90
|
$span.title = 'Add translation';
|
|
71
91
|
$span.innerHTML = `${icons_1.addAuthorIcon} <span class="add-trans-abstract-text">Add translation</span>`;
|
|
72
|
-
|
|
92
|
+
const handleActivate = (event) => {
|
|
73
93
|
event.preventDefault();
|
|
74
94
|
event.stopPropagation();
|
|
75
95
|
if (isGraphical && category) {
|
|
@@ -78,7 +98,9 @@ exports.default = (props) => new prosemirror_state_1.Plugin({
|
|
|
78
98
|
else {
|
|
79
99
|
(0, commands_1.insertTransAbstract)(view.state, view.dispatch, node.attrs.category, pos + node.nodeSize);
|
|
80
100
|
}
|
|
81
|
-
}
|
|
101
|
+
};
|
|
102
|
+
$span.addEventListener('mousedown', handleActivate);
|
|
103
|
+
$span.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(handleActivate));
|
|
82
104
|
return $span;
|
|
83
105
|
}));
|
|
84
106
|
}
|
|
@@ -94,12 +116,14 @@ exports.default = (props) => new prosemirror_state_1.Plugin({
|
|
|
94
116
|
$btn.className = 'language-selector-btn';
|
|
95
117
|
$btn.setAttribute('data-cy', 'language-selector-btn');
|
|
96
118
|
$btn.contentEditable = 'false';
|
|
119
|
+
$btn.tabIndex = canEdit ? 0 : -1;
|
|
97
120
|
const code = node.attrs.lang || 'en';
|
|
98
121
|
const lang = (0, languages_1.getLanguage)(code, props.languages);
|
|
99
122
|
const label = (0, languages_1.getLanguageLabel)(lang);
|
|
100
123
|
$btn.innerHTML = `<span>${label}</span> ${icons_1.translateIcon}`;
|
|
101
124
|
if (canEdit) {
|
|
102
|
-
|
|
125
|
+
let menuInstance = null;
|
|
126
|
+
const handleOpenMenu = (event) => {
|
|
103
127
|
event.preventDefault();
|
|
104
128
|
event.stopPropagation();
|
|
105
129
|
props.popper.destroy();
|
|
@@ -107,9 +131,21 @@ exports.default = (props) => new prosemirror_state_1.Plugin({
|
|
|
107
131
|
const tr = view.state.tr.setNodeAttribute(pos, 'lang', code);
|
|
108
132
|
view.dispatch(tr);
|
|
109
133
|
};
|
|
110
|
-
|
|
111
|
-
props.popper.show($btn, menu, 'bottom-end', false);
|
|
134
|
+
menuInstance = createLanguageMenu(props, code, handleSelect);
|
|
135
|
+
props.popper.show($btn, menuInstance.menu, 'bottom-end', false);
|
|
136
|
+
};
|
|
137
|
+
(0, navigation_utils_1.createKeyboardInteraction)({
|
|
138
|
+
container: $btn,
|
|
139
|
+
additionalKeys: {
|
|
140
|
+
Enter: handleOpenMenu,
|
|
141
|
+
Escape: (e) => {
|
|
142
|
+
e.preventDefault();
|
|
143
|
+
menuInstance?.destroy();
|
|
144
|
+
menuInstance = null;
|
|
145
|
+
},
|
|
146
|
+
},
|
|
112
147
|
});
|
|
148
|
+
$btn.addEventListener('mousedown', handleOpenMenu);
|
|
113
149
|
}
|
|
114
150
|
return $btn;
|
|
115
151
|
}));
|
package/dist/cjs/versions.js
CHANGED
|
@@ -5,6 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.AccessibilityElementView = void 0;
|
|
7
7
|
const transform_1 = require("@manuscripts/transform");
|
|
8
|
+
const prosemirror_state_1 = require("prosemirror-state");
|
|
9
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
8
10
|
const block_view_1 = __importDefault(require("./block_view"));
|
|
9
11
|
const creators_1 = require("./creators");
|
|
10
12
|
class AccessibilityElementView extends block_view_1.default {
|
|
@@ -29,6 +31,34 @@ class AccessibilityElementView extends block_view_1.default {
|
|
|
29
31
|
super.createElement();
|
|
30
32
|
this.contentDOM.className = 'accessibility_element_input';
|
|
31
33
|
this.contentDOM.setAttribute('contenteditable', 'true');
|
|
34
|
+
this.contentDOM.tabIndex = this.node.type === transform_1.schema.nodes.alt_text ? 0 : -1;
|
|
35
|
+
this.removeKeydownListener = (0, navigation_utils_1.createKeyboardInteraction)({
|
|
36
|
+
container: this.contentDOM,
|
|
37
|
+
navigation: {
|
|
38
|
+
getItems: () => {
|
|
39
|
+
const parentEl = this.dom.parentElement;
|
|
40
|
+
if (!parentEl) {
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
return Array.from(parentEl.querySelectorAll('.accessibility_element_input'));
|
|
44
|
+
},
|
|
45
|
+
arrowKeys: { forward: 'ArrowDown', backward: 'ArrowUp' },
|
|
46
|
+
getCurrentElement: () => this.contentDOM,
|
|
47
|
+
},
|
|
48
|
+
additionalKeys: {
|
|
49
|
+
Enter: (e) => {
|
|
50
|
+
e.preventDefault();
|
|
51
|
+
const pos = this.getPos();
|
|
52
|
+
const tr = this.view.state.tr.setSelection(prosemirror_state_1.TextSelection.create(this.view.state.doc, pos + 1));
|
|
53
|
+
this.view.dispatch(tr);
|
|
54
|
+
this.view.focus();
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
destroy() {
|
|
60
|
+
this.removeKeydownListener?.();
|
|
61
|
+
super.destroy();
|
|
32
62
|
}
|
|
33
63
|
}
|
|
34
64
|
exports.AccessibilityElementView = AccessibilityElementView;
|
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.AltTitleView = void 0;
|
|
19
|
+
const prosemirror_state_1 = require("prosemirror-state");
|
|
20
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
19
21
|
const base_node_view_1 = require("./base_node_view");
|
|
20
22
|
const creators_1 = require("./creators");
|
|
21
23
|
class AltTitleView extends base_node_view_1.BaseNodeView {
|
|
@@ -34,11 +36,38 @@ class AltTitleView extends base_node_view_1.BaseNodeView {
|
|
|
34
36
|
this.dom.setAttribute('data-type', this.node.attrs.type);
|
|
35
37
|
this.contentDOM = document.createElement('div');
|
|
36
38
|
this.contentDOM.classList.add('alt-title-text');
|
|
39
|
+
this.contentDOM.tabIndex = this.node.attrs.type === 'running' ? 0 : -1;
|
|
40
|
+
this.removeKeydownListener = (0, navigation_utils_1.createKeyboardInteraction)({
|
|
41
|
+
container: this.contentDOM,
|
|
42
|
+
navigation: {
|
|
43
|
+
getItems: () => {
|
|
44
|
+
const allAltTitles = Array.from(this.view.dom.querySelectorAll('.alt-title-text'));
|
|
45
|
+
return allAltTitles;
|
|
46
|
+
},
|
|
47
|
+
arrowKeys: { forward: 'ArrowDown', backward: 'ArrowUp' },
|
|
48
|
+
getCurrentElement: () => this.contentDOM,
|
|
49
|
+
},
|
|
50
|
+
additionalKeys: {
|
|
51
|
+
Enter: (e) => {
|
|
52
|
+
e.preventDefault();
|
|
53
|
+
const pos = this.getPos();
|
|
54
|
+
if (typeof pos === 'number') {
|
|
55
|
+
const tr = this.view.state.tr.setSelection(prosemirror_state_1.TextSelection.create(this.view.state.doc, pos + 1));
|
|
56
|
+
this.view.dispatch(tr);
|
|
57
|
+
this.view.focus();
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
});
|
|
37
62
|
this.dom.appendChild(label);
|
|
38
63
|
this.dom.appendChild(this.contentDOM);
|
|
39
64
|
this.updateContents();
|
|
40
65
|
};
|
|
41
66
|
}
|
|
67
|
+
destroy() {
|
|
68
|
+
this.removeKeydownListener?.();
|
|
69
|
+
super.destroy();
|
|
70
|
+
}
|
|
42
71
|
}
|
|
43
72
|
exports.AltTitleView = AltTitleView;
|
|
44
73
|
exports.default = (0, creators_1.createNodeView)(AltTitleView);
|
|
@@ -25,6 +25,7 @@ const icons_1 = require("../icons");
|
|
|
25
25
|
const alt_titles_1 = require("../plugins/alt-titles");
|
|
26
26
|
const block_view_1 = __importDefault(require("./block_view"));
|
|
27
27
|
const creators_1 = require("./creators");
|
|
28
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
28
29
|
class AltTitleSectionView extends block_view_1.default {
|
|
29
30
|
constructor() {
|
|
30
31
|
super(...arguments);
|
|
@@ -47,7 +48,7 @@ class AltTitleSectionView extends block_view_1.default {
|
|
|
47
48
|
button.classList.add('alt-titles-closing-button', 'button-reset');
|
|
48
49
|
button.setAttribute('aria-label', 'Collapse alternative titles');
|
|
49
50
|
button.innerHTML = icons_1.arrowDown;
|
|
50
|
-
|
|
51
|
+
const handleCollapse = () => {
|
|
51
52
|
const tr = this.view.state.tr.setMeta(alt_titles_1.altTitlesKey, {
|
|
52
53
|
collapsed: true,
|
|
53
54
|
});
|
|
@@ -59,7 +60,14 @@ class AltTitleSectionView extends block_view_1.default {
|
|
|
59
60
|
tr.setSelection(prosemirror_state_1.TextSelection.create(tr.doc, titleEndPos));
|
|
60
61
|
}
|
|
61
62
|
this.view.dispatch(tr);
|
|
63
|
+
const toggleButton = this.view.dom.querySelector('.toggle-button-open');
|
|
64
|
+
toggleButton?.focus();
|
|
65
|
+
};
|
|
66
|
+
button.addEventListener('click', (e) => {
|
|
67
|
+
e.preventDefault();
|
|
68
|
+
handleCollapse();
|
|
62
69
|
});
|
|
70
|
+
button.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(() => handleCollapse()));
|
|
63
71
|
closingPanel.appendChild(button);
|
|
64
72
|
return closingPanel;
|
|
65
73
|
}
|