@manuscripts/body-editor 3.13.10 → 3.13.12
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 +21 -2
- package/dist/cjs/components/views/FigureDropdown.js +8 -0
- package/dist/cjs/configs/editor-views.js +6 -0
- package/dist/cjs/icons.js +2 -1
- package/dist/cjs/lib/files.js +6 -1
- package/dist/cjs/menus.js +8 -0
- package/dist/cjs/node-type-icons.js +4 -0
- package/dist/cjs/plugins/accessibility_element.js +2 -1
- package/dist/cjs/versions.js +1 -1
- package/dist/cjs/views/accessibility_element.js +7 -1
- package/dist/cjs/views/affiliations.js +5 -1
- package/dist/cjs/views/caption.js +0 -1
- package/dist/cjs/views/caption_title.js +0 -1
- package/dist/cjs/views/headshot_element.js +74 -0
- package/dist/cjs/views/headshot_element_editable.js +20 -0
- package/dist/cjs/views/headshot_grid.js +82 -0
- package/dist/cjs/views/headshot_grid_editable.js +21 -0
- package/dist/cjs/views/headshot_image_editable.js +79 -0
- package/dist/cjs/views/supplement.js +16 -1
- package/dist/es/commands.js +18 -0
- package/dist/es/components/views/FigureDropdown.js +8 -0
- package/dist/es/configs/editor-views.js +6 -0
- package/dist/es/icons.js +2 -1
- package/dist/es/lib/files.js +6 -1
- package/dist/es/menus.js +9 -1
- package/dist/es/node-type-icons.js +5 -1
- package/dist/es/plugins/accessibility_element.js +2 -1
- package/dist/es/versions.js +1 -1
- package/dist/es/views/accessibility_element.js +7 -1
- package/dist/es/views/affiliations.js +5 -1
- package/dist/es/views/caption.js +0 -1
- package/dist/es/views/caption_title.js +0 -1
- package/dist/es/views/headshot_element.js +70 -0
- package/dist/es/views/headshot_element_editable.js +18 -0
- package/dist/es/views/headshot_grid.js +75 -0
- package/dist/es/views/headshot_grid_editable.js +19 -0
- package/dist/es/views/headshot_image_editable.js +75 -0
- package/dist/es/views/supplement.js +16 -1
- package/dist/types/commands.d.ts +1 -0
- package/dist/types/icons.d.ts +1 -0
- package/dist/types/versions.d.ts +1 -1
- package/dist/types/views/headshot_element.d.ts +29 -0
- package/dist/types/views/headshot_element_editable.d.ts +18 -0
- package/dist/types/views/headshot_grid.d.ts +28 -0
- package/dist/types/views/headshot_grid_editable.d.ts +44 -0
- package/dist/types/views/headshot_image_editable.d.ts +28 -0
- package/dist/types/views/supplement.d.ts +1 -0
- package/package.json +2 -2
- package/src/commands.ts +27 -0
- package/src/components/views/FigureDropdown.tsx +11 -0
- package/src/configs/editor-views.ts +6 -0
- package/src/icons.ts +2 -0
- package/src/lib/files.ts +7 -1
- package/src/menus.tsx +10 -0
- package/src/node-type-icons.tsx +12 -0
- package/src/plugins/accessibility_element.ts +4 -1
- package/src/versions.ts +1 -1
- package/src/views/accessibility_element.ts +7 -1
- package/src/views/affiliations.ts +6 -1
- package/src/views/caption.ts +0 -1
- package/src/views/caption_title.ts +0 -1
- package/src/views/headshot_element.ts +98 -0
- package/src/views/headshot_element_editable.ts +20 -0
- package/src/views/headshot_grid.ts +98 -0
- package/src/views/headshot_grid_editable.ts +21 -0
- package/src/views/headshot_image_editable.ts +93 -0
- package/src/views/supplement.ts +15 -2
- package/styles/AdvancedEditor.css +169 -1
- package/styles/Editor.css +1 -1
package/dist/cjs/commands.js
CHANGED
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.
|
|
19
|
-
exports.paste = exports.copySelection = exports.exitEditorToContainer = exports.ignoreEnterInSubtitles = exports.insertHeroImage = exports.activateSearchReplace = exports.activateSearch = exports.autoComplete = exports.addColumns = exports.addHeaderRow = exports.addRows = void 0;
|
|
18
|
+
exports.addNodeComment = exports.createAndFillTableElement = exports.selectAllIsolating = exports.ignoreAtomBlockNodeForward = exports.isAtEndOfTextBlock = exports.ignoreMetaNodeBackspaceCommand = exports.ignoreAtomBlockNodeBackward = exports.isTextSelection = exports.isAtStartOfTextBlock = exports.insertTransGraphicalAbstract = exports.insertTransAbstract = exports.insertTOCSection = exports.insertBibliographySection = exports.insertList = exports.insertKeywords = exports.insertAward = exports.insertAffiliation = exports.insertContributors = exports.insertGraphicalAbstract = exports.insertBackmatterSection = exports.insertAbstractSection = exports.insertSection = exports.insertHeadshotGrid = exports.insertBoxElement = exports.insertInlineFootnote = exports.insertFootnotesElement = exports.insertTableElementFooter = exports.insertInlineEquation = exports.insertCrossReference = exports.insertInlineCitation = exports.insertLink = exports.insertSectionLabel = exports.findPosBeforeFirstSubsection = exports.insertBreak = exports.deleteBlock = exports.insertBlock = exports.insertAttachment = exports.insertSupplement = exports.insertTable = exports.insertEmbed = exports.insertFigure = exports.insertGeneralTableFootnote = exports.insertInlineTableFootnote = exports.createBlock = exports.createSelection = exports.canInsert = exports.blockActive = exports.isNodeSelection = exports.markActive = exports.addToStart = void 0;
|
|
19
|
+
exports.paste = exports.copySelection = exports.exitEditorToContainer = exports.ignoreEnterInSubtitles = exports.insertHeroImage = exports.activateSearchReplace = exports.activateSearch = exports.autoComplete = exports.addColumns = exports.addHeaderRow = exports.addRows = exports.addInlineComment = void 0;
|
|
20
20
|
const track_changes_plugin_1 = require("@manuscripts/track-changes-plugin");
|
|
21
21
|
const transform_1 = require("@manuscripts/transform");
|
|
22
22
|
const prosemirror_model_1 = require("prosemirror-model");
|
|
@@ -598,6 +598,25 @@ const insertBoxElement = (state, dispatch) => {
|
|
|
598
598
|
return true;
|
|
599
599
|
};
|
|
600
600
|
exports.insertBoxElement = insertBoxElement;
|
|
601
|
+
const insertHeadshotGrid = (state, dispatch) => {
|
|
602
|
+
const selection = state.selection;
|
|
603
|
+
const { nodes } = transform_1.schema;
|
|
604
|
+
const isBody = (0, prosemirror_utils_1.hasParentNodeOfType)(nodes.body)(selection);
|
|
605
|
+
if (!isBody) {
|
|
606
|
+
return false;
|
|
607
|
+
}
|
|
608
|
+
const position = findBlockInsertPosition(state);
|
|
609
|
+
if (position && dispatch) {
|
|
610
|
+
const headshotElement = transform_1.schema.nodes.headshot_element.createAndFill();
|
|
611
|
+
const node = nodes.headshot_grid.create({}, headshotElement);
|
|
612
|
+
const tr = state.tr.insert(position, node);
|
|
613
|
+
const headshotNamePosition = position + 2;
|
|
614
|
+
tr.setSelection(prosemirror_state_1.TextSelection.create(tr.doc, headshotNamePosition));
|
|
615
|
+
dispatch(tr.scrollIntoView());
|
|
616
|
+
}
|
|
617
|
+
return true;
|
|
618
|
+
};
|
|
619
|
+
exports.insertHeadshotGrid = insertHeadshotGrid;
|
|
601
620
|
const insertSection = (subsection = false) => (state, dispatch, view) => {
|
|
602
621
|
const { nodes } = transform_1.schema;
|
|
603
622
|
const $pos = state.selection.$from;
|
|
@@ -119,6 +119,14 @@ const FigureOptions = ({ can, getDoc, getFiles, onDownload, onUpload, onDetach,
|
|
|
119
119
|
}
|
|
120
120
|
}, [isOpen, container.classList]);
|
|
121
121
|
useDropdownKeyboardNav(isOpen, dropdownRef, toggleOpen);
|
|
122
|
+
const hasAnyActions = !!showDownload ||
|
|
123
|
+
!!showUpload ||
|
|
124
|
+
!!showDetach ||
|
|
125
|
+
!!showReplace ||
|
|
126
|
+
showDelete();
|
|
127
|
+
if (!hasAnyActions) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
122
130
|
const isEmbedMode = !!onReplaceEmbed;
|
|
123
131
|
const groupFiles = (0, files_1.memoGroupFiles)();
|
|
124
132
|
return (react_1.default.createElement(DropdownWrapper, { ref: wrapperRef },
|
|
@@ -31,6 +31,9 @@ const footnote_1 = __importDefault(require("../views/footnote"));
|
|
|
31
31
|
const footnotes_element_1 = __importDefault(require("../views/footnotes_element"));
|
|
32
32
|
const general_table_footnote_1 = __importDefault(require("../views/general_table_footnote"));
|
|
33
33
|
const hero_image_editable_1 = __importDefault(require("../views/hero_image_editable"));
|
|
34
|
+
const headshot_grid_editable_1 = __importDefault(require("../views/headshot_grid_editable"));
|
|
35
|
+
const headshot_element_1 = __importDefault(require("../views/headshot_element"));
|
|
36
|
+
const headshot_image_editable_1 = __importDefault(require("../views/headshot_image_editable"));
|
|
34
37
|
const image_element_editable_1 = __importDefault(require("../views/image_element_editable"));
|
|
35
38
|
const inline_equation_editable_1 = __importDefault(require("../views/inline_equation_editable"));
|
|
36
39
|
const inline_footnote_editable_1 = __importDefault(require("../views/inline_footnote_editable"));
|
|
@@ -111,6 +114,9 @@ exports.default = (props, dispatch) => {
|
|
|
111
114
|
long_desc: (0, accessibility_element_1.default)(props, dispatch),
|
|
112
115
|
alt_text: (0, accessibility_element_1.default)(props, dispatch),
|
|
113
116
|
hero_image: (0, hero_image_editable_1.default)(props, dispatch),
|
|
117
|
+
headshot_grid: (0, headshot_grid_editable_1.default)(props, dispatch),
|
|
118
|
+
headshot_element: (0, headshot_element_1.default)(props, dispatch),
|
|
119
|
+
headshot_image: (0, headshot_image_editable_1.default)(props, dispatch),
|
|
114
120
|
abstracts: (0, abstracts_1.default)(props),
|
|
115
121
|
trans_abstract: (0, translated_abstract_editable_1.default)(props),
|
|
116
122
|
trans_graphical_abstract: (0, trans_graphical_abstract_editable_1.default)(props),
|
package/dist/cjs/icons.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ORCIDIcon = exports.tickIcon = exports.fileMainDocumentIcon = exports.linkIcon = exports.translateIcon = exports.draggableIcon = exports.fileCorruptedIcon = exports.imageDefaultIcon = exports.imageLeftIcon = exports.imageRightIcon = exports.plusIcon = exports.lockIcon = exports.scrollIcon = exports.sectionCategoryIcon = exports.editIcon = exports.deleteIcon = exports.alertIcon = exports.arrowUp = exports.arrowDown = exports.addAuthorIcon = void 0;
|
|
3
|
+
exports.ORCIDIcon = exports.tickIcon = exports.fileMainDocumentIcon = exports.linkIcon = exports.translateIcon = exports.draggableIcon = exports.fileCorruptedIcon = exports.imageDefaultIcon = exports.imageLeftIcon = exports.imageRightIcon = exports.plusIcon = exports.lockIcon = exports.scrollIcon = exports.sectionCategoryIcon = exports.editIcon = exports.deleteIcon = exports.cameraIcon = exports.alertIcon = exports.arrowUp = exports.arrowDown = exports.addAuthorIcon = void 0;
|
|
4
4
|
const style_guide_1 = require("@manuscripts/style-guide");
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const server_1 = require("react-dom/server");
|
|
@@ -9,6 +9,7 @@ exports.addAuthorIcon = renderIcon(style_guide_1.AddAuthorIcon);
|
|
|
9
9
|
exports.arrowDown = renderIcon(style_guide_1.ArrowDownCircleIcon);
|
|
10
10
|
exports.arrowUp = renderIcon(style_guide_1.ArrowUpIcon);
|
|
11
11
|
exports.alertIcon = renderIcon(style_guide_1.AlertIcon);
|
|
12
|
+
exports.cameraIcon = renderIcon(style_guide_1.CameraIcon);
|
|
12
13
|
exports.deleteIcon = renderIcon(style_guide_1.DeleteIcon);
|
|
13
14
|
exports.editIcon = renderIcon(style_guide_1.EditIcon);
|
|
14
15
|
exports.sectionCategoryIcon = renderIcon(style_guide_1.SectionCategoryIcon);
|
package/dist/cjs/lib/files.js
CHANGED
|
@@ -13,6 +13,7 @@ const figureTypes = [
|
|
|
13
13
|
transform_1.schema.nodes.figure_element,
|
|
14
14
|
transform_1.schema.nodes.image_element,
|
|
15
15
|
transform_1.schema.nodes.hero_image,
|
|
16
|
+
transform_1.schema.nodes.headshot_grid,
|
|
16
17
|
transform_1.schema.nodes.embed,
|
|
17
18
|
];
|
|
18
19
|
function memoGroupFiles() {
|
|
@@ -56,7 +57,11 @@ const groupFiles = (doc, files) => {
|
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
else {
|
|
59
|
-
|
|
60
|
+
const descend = node.type === transform_1.schema.nodes.headshot_grid;
|
|
61
|
+
const figureNodeType = node.type === transform_1.schema.nodes.headshot_grid
|
|
62
|
+
? transform_1.schema.nodes.headshot_image
|
|
63
|
+
: transform_1.schema.nodes.figure;
|
|
64
|
+
for (const figure of (0, prosemirror_utils_1.findChildrenByType)(node, figureNodeType, descend)) {
|
|
60
65
|
if ((0, track_changes_utils_1.isHidden)(figure.node)) {
|
|
61
66
|
continue;
|
|
62
67
|
}
|
package/dist/cjs/menus.js
CHANGED
|
@@ -272,6 +272,14 @@ const getEditorMenus = (editor) => {
|
|
|
272
272
|
run: doCommand(commands_1.insertBoxElement),
|
|
273
273
|
isHidden: !(0, template_1.templateAllows)(state, transform_1.schema.nodes.box_element),
|
|
274
274
|
},
|
|
275
|
+
{
|
|
276
|
+
id: 'insert-headshot-grid',
|
|
277
|
+
label: 'Headshot Panel',
|
|
278
|
+
isEnabled: (0, utils_1.isEditAllowed)(state) &&
|
|
279
|
+
isCommandValid((0, commands_1.canInsert)(transform_1.schema.nodes.headshot_grid)),
|
|
280
|
+
run: doCommand(commands_1.insertHeadshotGrid),
|
|
281
|
+
isHidden: !(0, template_1.templateAllows)(state, transform_1.schema.nodes.headshot_grid),
|
|
282
|
+
},
|
|
275
283
|
{
|
|
276
284
|
role: 'separator',
|
|
277
285
|
},
|
|
@@ -23,6 +23,8 @@ const style_guide_1 = require("@manuscripts/style-guide");
|
|
|
23
23
|
const transform_1 = require("@manuscripts/transform");
|
|
24
24
|
const react_1 = __importDefault(require("react"));
|
|
25
25
|
const { nodes } = transform_1.schema;
|
|
26
|
+
const OutlineHeadshotGridIcon = () => (react_1.default.createElement(style_guide_1.FileHeadshotGridIcon, { width: "12", height: "12" }));
|
|
27
|
+
const OutlineHeadshotElementIcon = () => (react_1.default.createElement(style_guide_1.AvatarIcon, { width: "16", height: "16" }));
|
|
26
28
|
const OutlineImageIcon = () => (react_1.default.createElement(style_guide_1.FileImageIcon, { width: "11", height: "14" }));
|
|
27
29
|
const OutlineSupplementsIcon = () => (react_1.default.createElement(style_guide_1.SupplementsIcon, { width: "11", height: "14" }));
|
|
28
30
|
const OutlineMainDocumentIcon = () => (react_1.default.createElement(style_guide_1.FileDocumentIcon, { width: "11", height: "14" }));
|
|
@@ -44,6 +46,8 @@ const icons = new Map([
|
|
|
44
46
|
[nodes.hero_image, OutlineImageIcon],
|
|
45
47
|
[nodes.supplements, OutlineSupplementsIcon],
|
|
46
48
|
[nodes.attachments, OutlineMainDocumentIcon],
|
|
49
|
+
[nodes.headshot_grid, OutlineHeadshotGridIcon],
|
|
50
|
+
[nodes.headshot_element, OutlineHeadshotElementIcon],
|
|
47
51
|
]);
|
|
48
52
|
const nodeTypeIcon = (nodeType, listType) => {
|
|
49
53
|
if (nodeType === transform_1.schema.nodes.list) {
|
|
@@ -30,7 +30,8 @@ const isSelectionWithin = (node, pos, selection) => {
|
|
|
30
30
|
const buildExpandButtonDecorations = (doc) => {
|
|
31
31
|
const decorations = [];
|
|
32
32
|
doc.descendants((node, pos) => {
|
|
33
|
-
if (node.type.
|
|
33
|
+
if (node.type !== transform_1.schema.nodes.headshot_element &&
|
|
34
|
+
node.type.spec.content?.includes('alt_text')) {
|
|
34
35
|
decorations.push(prosemirror_view_1.Decoration.widget(pos + node.nodeSize - 1, (view) => {
|
|
35
36
|
const container = document.createElement('div');
|
|
36
37
|
container.className =
|
package/dist/cjs/versions.js
CHANGED
|
@@ -9,8 +9,15 @@ const prosemirror_state_1 = require("prosemirror-state");
|
|
|
9
9
|
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
10
10
|
const block_view_1 = __importDefault(require("./block_view"));
|
|
11
11
|
const creators_1 = require("./creators");
|
|
12
|
+
const empty_1 = __importDefault(require("./empty"));
|
|
12
13
|
class AccessibilityElementView extends block_view_1.default {
|
|
13
14
|
initialise() {
|
|
15
|
+
const $pos = this.view.state.doc.resolve(this.getPos());
|
|
16
|
+
if ($pos.parent.type === transform_1.schema.nodes.headshot_element) {
|
|
17
|
+
const { dom } = (0, empty_1.default)('accessibility_element')();
|
|
18
|
+
this.dom = dom;
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
14
21
|
this.createDOM();
|
|
15
22
|
this.createElement();
|
|
16
23
|
this.updateContents();
|
|
@@ -30,7 +37,6 @@ class AccessibilityElementView extends block_view_1.default {
|
|
|
30
37
|
createElement() {
|
|
31
38
|
super.createElement();
|
|
32
39
|
this.contentDOM.className = 'accessibility_element_input';
|
|
33
|
-
this.contentDOM.setAttribute('contenteditable', 'true');
|
|
34
40
|
this.contentDOM.tabIndex = this.node.type === transform_1.schema.nodes.alt_text ? 0 : -1;
|
|
35
41
|
this.removeKeydownListener = (0, navigation_utils_1.createKeyboardInteraction)({
|
|
36
42
|
container: this.contentDOM,
|
|
@@ -120,7 +120,6 @@ class AffiliationsView extends block_view_1.default {
|
|
|
120
120
|
this.container = document.createElement('div');
|
|
121
121
|
this.container.classList.add('affiliations', 'block');
|
|
122
122
|
this.container.contentEditable = 'false';
|
|
123
|
-
this.container.addEventListener('click', this.handleClick);
|
|
124
123
|
this.dom.setAttribute('contenteditable', 'false');
|
|
125
124
|
this.dom.appendChild(this.container);
|
|
126
125
|
}
|
|
@@ -140,6 +139,11 @@ class AffiliationsView extends block_view_1.default {
|
|
|
140
139
|
this.updateSelection();
|
|
141
140
|
}
|
|
142
141
|
buildAffiliations(affs) {
|
|
142
|
+
const can = this.props.getCapabilities();
|
|
143
|
+
this.container.removeEventListener('click', this.handleClick);
|
|
144
|
+
if (can.editMetadata) {
|
|
145
|
+
this.container.addEventListener('click', this.handleClick);
|
|
146
|
+
}
|
|
143
147
|
const elements = [];
|
|
144
148
|
for (const affiliation of affs.affiliations) {
|
|
145
149
|
const index = affs.indexedAffiliationIds.get(affiliation.id);
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* © 2026 Atypon Systems LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.HeadshotElement = void 0;
|
|
19
|
+
const prosemirror_state_1 = require("prosemirror-state");
|
|
20
|
+
const icons_1 = require("../icons");
|
|
21
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
22
|
+
const base_node_view_1 = require("./base_node_view");
|
|
23
|
+
const creators_1 = require("./creators");
|
|
24
|
+
class HeadshotElement extends base_node_view_1.BaseNodeView {
|
|
25
|
+
constructor() {
|
|
26
|
+
super(...arguments);
|
|
27
|
+
this.elementType = 'div';
|
|
28
|
+
this.createElement = () => {
|
|
29
|
+
this.dom = document.createElement('div');
|
|
30
|
+
this.dom.classList.add('headshot-element');
|
|
31
|
+
this.dom.tabIndex = 0;
|
|
32
|
+
this.dom.setAttribute('id', this.node.attrs.id);
|
|
33
|
+
this.container = document.createElement('div');
|
|
34
|
+
this.container.classList.add('block');
|
|
35
|
+
this.dom.appendChild(this.container);
|
|
36
|
+
this.contentDOM = document.createElement('div');
|
|
37
|
+
this.contentDOM.classList.add('block-container', 'headshot-element-block');
|
|
38
|
+
this.container.appendChild(this.contentDOM);
|
|
39
|
+
const can = this.props.getCapabilities();
|
|
40
|
+
if (can.editArticle) {
|
|
41
|
+
this.deleteHeadshotButton = document.createElement('button');
|
|
42
|
+
this.deleteHeadshotButton.innerHTML = icons_1.plusIcon;
|
|
43
|
+
this.deleteHeadshotButton.classList.add('headshot-remove-button');
|
|
44
|
+
this.deleteHeadshotButton.setAttribute('data-cy', 'headshot-delete');
|
|
45
|
+
this.deleteHeadshotButton.contentEditable = 'false';
|
|
46
|
+
this.deleteHeadshotButton.addEventListener('click', this.handleDeleteHeadshot);
|
|
47
|
+
this.deleteHeadshotButton.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(this.handleDeleteHeadshot));
|
|
48
|
+
this.container.appendChild(this.deleteHeadshotButton);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
this.handleDeleteHeadshot = () => {
|
|
52
|
+
const { state, dispatch } = this.view;
|
|
53
|
+
const { tr } = state;
|
|
54
|
+
const pos = this.getPos();
|
|
55
|
+
tr.delete(pos, pos + this.node.nodeSize);
|
|
56
|
+
this.view.focus();
|
|
57
|
+
const $pos = tr.doc.resolve(pos);
|
|
58
|
+
if ($pos.node().nodeSize > 2) {
|
|
59
|
+
tr.setSelection(prosemirror_state_1.TextSelection.near(tr.doc.resolve($pos.start()))).scrollIntoView();
|
|
60
|
+
}
|
|
61
|
+
dispatch(tr);
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
initialise() {
|
|
65
|
+
this.createElement();
|
|
66
|
+
this.updateContents();
|
|
67
|
+
}
|
|
68
|
+
destroy() {
|
|
69
|
+
this.deleteHeadshotButton?.removeEventListener('click', this.handleDeleteHeadshot);
|
|
70
|
+
super.destroy();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.HeadshotElement = HeadshotElement;
|
|
74
|
+
exports.default = (0, creators_1.createNodeView)(HeadshotElement);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* © 2026 Atypon Systems LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
const creators_1 = require("./creators");
|
|
19
|
+
const headshot_element_1 = require("./headshot_element");
|
|
20
|
+
exports.default = (0, creators_1.createEditableNodeView)(headshot_element_1.HeadshotElement);
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* © 2026 Atypon Systems LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
18
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.HeadshotGridView = void 0;
|
|
22
|
+
const transform_1 = require("@manuscripts/transform");
|
|
23
|
+
const prosemirror_state_1 = require("prosemirror-state");
|
|
24
|
+
const icons_1 = require("../icons");
|
|
25
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
26
|
+
const block_view_1 = __importDefault(require("./block_view"));
|
|
27
|
+
const creators_1 = require("./creators");
|
|
28
|
+
class HeadshotGridView extends block_view_1.default {
|
|
29
|
+
constructor() {
|
|
30
|
+
super(...arguments);
|
|
31
|
+
this.elementType = 'div';
|
|
32
|
+
this.createElement = () => {
|
|
33
|
+
this.container = document.createElement('div');
|
|
34
|
+
this.container.classList.add('block', 'headshot-grid-container');
|
|
35
|
+
this.dom.appendChild(this.container);
|
|
36
|
+
this.contentDOM = document.createElement('div');
|
|
37
|
+
this.contentDOM.classList.add('headshot-grid-block');
|
|
38
|
+
this.contentDOM.setAttribute('id', this.node.attrs.id);
|
|
39
|
+
this.removeKeydownListener = (0, navigation_utils_1.createKeyboardInteraction)({
|
|
40
|
+
container: this.contentDOM,
|
|
41
|
+
navigation: {
|
|
42
|
+
arrowKeys: { forward: 'ArrowDown', backward: 'ArrowUp' },
|
|
43
|
+
getItems: () => [...(this.contentDOM?.children || [])],
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
this.container.appendChild(this.contentDOM);
|
|
47
|
+
const can = this.props.getCapabilities();
|
|
48
|
+
if (can.editArticle) {
|
|
49
|
+
this.addHeadshotButton = document.createElement('button');
|
|
50
|
+
this.addHeadshotButton.classList.add('add-headshot-element-button');
|
|
51
|
+
this.addHeadshotButton.setAttribute('data-cy', 'headshot-add');
|
|
52
|
+
this.addHeadshotButton.contentEditable = 'false';
|
|
53
|
+
this.addHeadshotButton.innerHTML = icons_1.addAuthorIcon;
|
|
54
|
+
const buttonText = document.createElement('span');
|
|
55
|
+
buttonText.classList.add('add-headshot-element-text');
|
|
56
|
+
buttonText.innerText = 'Add Headshot';
|
|
57
|
+
this.addHeadshotButton.appendChild(buttonText);
|
|
58
|
+
this.addHeadshotButton.addEventListener('click', this.handleAddHeadshot);
|
|
59
|
+
this.addHeadshotButton.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(this.handleAddHeadshot));
|
|
60
|
+
this.container.appendChild(this.addHeadshotButton);
|
|
61
|
+
}
|
|
62
|
+
this.dom.appendChild(this.container);
|
|
63
|
+
};
|
|
64
|
+
this.handleAddHeadshot = () => {
|
|
65
|
+
const { state, dispatch } = this.view;
|
|
66
|
+
const { tr } = state;
|
|
67
|
+
const headshotElementNode = transform_1.schema.nodes.headshot_element.createAndFill();
|
|
68
|
+
const insertPos = this.getPos() + 1;
|
|
69
|
+
tr.insert(insertPos, headshotElementNode);
|
|
70
|
+
this.view.focus();
|
|
71
|
+
tr.setSelection(prosemirror_state_1.TextSelection.create(tr.doc, insertPos));
|
|
72
|
+
dispatch(tr.scrollIntoView());
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
destroy() {
|
|
76
|
+
this.addHeadshotButton?.removeEventListener('click', this.handleAddHeadshot);
|
|
77
|
+
this.removeKeydownListener?.();
|
|
78
|
+
super.destroy();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.HeadshotGridView = HeadshotGridView;
|
|
82
|
+
exports.default = (0, creators_1.createNodeView)(HeadshotGridView);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* © 2026 Atypon Systems LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
const creators_1 = require("./creators");
|
|
19
|
+
const editable_block_1 = require("./editable_block");
|
|
20
|
+
const headshot_grid_1 = require("./headshot_grid");
|
|
21
|
+
exports.default = (0, creators_1.createEditableNodeView)((0, editable_block_1.EditableBlock)(headshot_grid_1.HeadshotGridView));
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* © 2026 Atypon Systems LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.HeadshotImageEditableView = void 0;
|
|
19
|
+
const track_changes_plugin_1 = require("@manuscripts/track-changes-plugin");
|
|
20
|
+
const icons_1 = require("../icons");
|
|
21
|
+
const navigation_utils_1 = require("../lib/navigation-utils");
|
|
22
|
+
const creators_1 = require("./creators");
|
|
23
|
+
const figure_editable_1 = require("./figure_editable");
|
|
24
|
+
class HeadshotImageEditableView extends figure_editable_1.FigureEditableView {
|
|
25
|
+
constructor() {
|
|
26
|
+
super(...arguments);
|
|
27
|
+
this.ignoreMutation = () => true;
|
|
28
|
+
this.createPlaceholder = () => {
|
|
29
|
+
const element = document.createElement('div');
|
|
30
|
+
element.classList.add('figure', 'placeholder');
|
|
31
|
+
element.tabIndex = 0;
|
|
32
|
+
const instructions = document.createElement('div');
|
|
33
|
+
instructions.classList.add('instructions');
|
|
34
|
+
instructions.innerHTML = `${icons_1.cameraIcon}<div>Upload<br>photo</div>`;
|
|
35
|
+
element.appendChild(instructions);
|
|
36
|
+
return element;
|
|
37
|
+
};
|
|
38
|
+
this.handleDetachImage = () => {
|
|
39
|
+
const { state, dispatch } = this.view;
|
|
40
|
+
const pos = this.getPos();
|
|
41
|
+
dispatch(state.tr.delete(pos, pos + this.node.nodeSize));
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
createDOM() {
|
|
45
|
+
this.dom = document.createElement('figure');
|
|
46
|
+
this.container = document.createElement('div');
|
|
47
|
+
this.container.className = 'headshot-figure';
|
|
48
|
+
this.container.contentEditable = 'false';
|
|
49
|
+
this.dom.appendChild(this.container);
|
|
50
|
+
}
|
|
51
|
+
addTools() {
|
|
52
|
+
const src = this.node.attrs.src;
|
|
53
|
+
const files = this.props.getFiles();
|
|
54
|
+
const file = src && files.filter((f) => f.id === src)[0];
|
|
55
|
+
const link = file && this.props.fileManagement.previewLink(file);
|
|
56
|
+
const can = this.props.getCapabilities();
|
|
57
|
+
if (can.detachFile && link) {
|
|
58
|
+
this.detachImageButton = document.createElement('button');
|
|
59
|
+
this.detachImageButton.innerHTML = icons_1.plusIcon;
|
|
60
|
+
this.detachImageButton.classList.add('headshot-remove-button');
|
|
61
|
+
this.detachImageButton.setAttribute('data-cy', 'headshot-image-detach');
|
|
62
|
+
this.detachImageButton.contentEditable = 'false';
|
|
63
|
+
this.detachImageButton.addEventListener('click', this.handleDetachImage);
|
|
64
|
+
this.detachImageButton.addEventListener('keydown', (0, navigation_utils_1.handleEnterKey)(this.handleDetachImage));
|
|
65
|
+
this.container.appendChild(this.detachImageButton);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
updateContents() {
|
|
69
|
+
super.updateContents();
|
|
70
|
+
(0, track_changes_plugin_1.addTrackChangesAttributes)(this.node.attrs, this.dom);
|
|
71
|
+
(0, track_changes_plugin_1.addTrackChangesClassNames)(this.node.attrs, this.dom);
|
|
72
|
+
}
|
|
73
|
+
destroy() {
|
|
74
|
+
this.detachImageButton?.removeEventListener('click', this.handleDetachImage);
|
|
75
|
+
super.destroy();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.HeadshotImageEditableView = HeadshotImageEditableView;
|
|
79
|
+
exports.default = (0, creators_1.createEditableNodeView)(HeadshotImageEditableView);
|
|
@@ -25,6 +25,7 @@ const creators_1 = require("./creators");
|
|
|
25
25
|
class SupplementView extends base_node_view_1.BaseNodeView {
|
|
26
26
|
constructor() {
|
|
27
27
|
super(...arguments);
|
|
28
|
+
this.dragAndDropInitialized = false;
|
|
28
29
|
this.ignoreMutation = () => true;
|
|
29
30
|
this.createElement = () => {
|
|
30
31
|
this.dom = document.createElement('div');
|
|
@@ -43,11 +44,25 @@ class SupplementView extends base_node_view_1.BaseNodeView {
|
|
|
43
44
|
initialise() {
|
|
44
45
|
this.createElement();
|
|
45
46
|
this.updateContents();
|
|
46
|
-
this.setupDragAndDrop();
|
|
47
47
|
}
|
|
48
48
|
updateContents() {
|
|
49
49
|
super.updateContents();
|
|
50
50
|
this.refreshFileInfo();
|
|
51
|
+
const can = this.props.getCapabilities();
|
|
52
|
+
this.dom.draggable = can.editArticle;
|
|
53
|
+
if (can.editArticle) {
|
|
54
|
+
if (!this.dragAndDropInitialized) {
|
|
55
|
+
this.setupDragAndDrop();
|
|
56
|
+
this.dragAndDropInitialized = true;
|
|
57
|
+
}
|
|
58
|
+
if (!this.dragIcon) {
|
|
59
|
+
this.addDragIcon();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
this.dragIcon?.remove();
|
|
64
|
+
this.dragIcon = undefined;
|
|
65
|
+
}
|
|
51
66
|
}
|
|
52
67
|
getDropSide(element, clientY) {
|
|
53
68
|
const { top, bottom } = element.getBoundingClientRect();
|
package/dist/es/commands.js
CHANGED
|
@@ -567,6 +567,24 @@ export const insertBoxElement = (state, dispatch) => {
|
|
|
567
567
|
}
|
|
568
568
|
return true;
|
|
569
569
|
};
|
|
570
|
+
export const insertHeadshotGrid = (state, dispatch) => {
|
|
571
|
+
const selection = state.selection;
|
|
572
|
+
const { nodes } = schema;
|
|
573
|
+
const isBody = hasParentNodeOfType(nodes.body)(selection);
|
|
574
|
+
if (!isBody) {
|
|
575
|
+
return false;
|
|
576
|
+
}
|
|
577
|
+
const position = findBlockInsertPosition(state);
|
|
578
|
+
if (position && dispatch) {
|
|
579
|
+
const headshotElement = schema.nodes.headshot_element.createAndFill();
|
|
580
|
+
const node = nodes.headshot_grid.create({}, headshotElement);
|
|
581
|
+
const tr = state.tr.insert(position, node);
|
|
582
|
+
const headshotNamePosition = position + 2;
|
|
583
|
+
tr.setSelection(TextSelection.create(tr.doc, headshotNamePosition));
|
|
584
|
+
dispatch(tr.scrollIntoView());
|
|
585
|
+
}
|
|
586
|
+
return true;
|
|
587
|
+
};
|
|
570
588
|
export const insertSection = (subsection = false) => (state, dispatch, view) => {
|
|
571
589
|
const { nodes } = schema;
|
|
572
590
|
const $pos = state.selection.$from;
|
|
@@ -80,6 +80,14 @@ export const FigureOptions = ({ can, getDoc, getFiles, onDownload, onUpload, onD
|
|
|
80
80
|
}
|
|
81
81
|
}, [isOpen, container.classList]);
|
|
82
82
|
useDropdownKeyboardNav(isOpen, dropdownRef, toggleOpen);
|
|
83
|
+
const hasAnyActions = !!showDownload ||
|
|
84
|
+
!!showUpload ||
|
|
85
|
+
!!showDetach ||
|
|
86
|
+
!!showReplace ||
|
|
87
|
+
showDelete();
|
|
88
|
+
if (!hasAnyActions) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
83
91
|
const isEmbedMode = !!onReplaceEmbed;
|
|
84
92
|
const groupFiles = memoGroupFiles();
|
|
85
93
|
return (React.createElement(DropdownWrapper, { ref: wrapperRef },
|
|
@@ -26,6 +26,9 @@ import footnote from '../views/footnote';
|
|
|
26
26
|
import footnotesElement from '../views/footnotes_element';
|
|
27
27
|
import generalTableFootnote from '../views/general_table_footnote';
|
|
28
28
|
import heroImage from '../views/hero_image_editable';
|
|
29
|
+
import headshotGrid from '../views/headshot_grid_editable';
|
|
30
|
+
import headshotElement from '../views/headshot_element';
|
|
31
|
+
import headshotImage from '../views/headshot_image_editable';
|
|
29
32
|
import imageElement from '../views/image_element_editable';
|
|
30
33
|
import inlineEquation from '../views/inline_equation_editable';
|
|
31
34
|
import inlineFootnote from '../views/inline_footnote_editable';
|
|
@@ -106,6 +109,9 @@ export default (props, dispatch) => {
|
|
|
106
109
|
long_desc: accessibilityElement(props, dispatch),
|
|
107
110
|
alt_text: accessibilityElement(props, dispatch),
|
|
108
111
|
hero_image: heroImage(props, dispatch),
|
|
112
|
+
headshot_grid: headshotGrid(props, dispatch),
|
|
113
|
+
headshot_element: headshotElement(props, dispatch),
|
|
114
|
+
headshot_image: headshotImage(props, dispatch),
|
|
109
115
|
abstracts: abstracts(props),
|
|
110
116
|
trans_abstract: transAbstract(props),
|
|
111
117
|
trans_graphical_abstract: transGraphicalAbstract(props),
|
package/dist/es/icons.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AddAuthorIcon, AlertIcon, ArrowDownCircleIcon, ArrowUpIcon, DeleteIcon, DraggableIcon, EditIcon, FileCorruptedIcon, FileMainDocumentIcon, ImageDefaultIcon, ImageLeftIcon, ImageRightIcon, LinkIcon, LockIcon, ORCIDIcon as ORCID, PlusIcon, ScrollIcon, SectionCategoryIcon, TickIcon, TranslateIcon, } from '@manuscripts/style-guide';
|
|
1
|
+
import { AddAuthorIcon, AlertIcon, ArrowDownCircleIcon, ArrowUpIcon, CameraIcon, DeleteIcon, DraggableIcon, EditIcon, FileCorruptedIcon, FileMainDocumentIcon, ImageDefaultIcon, ImageLeftIcon, ImageRightIcon, LinkIcon, LockIcon, ORCIDIcon as ORCID, PlusIcon, ScrollIcon, SectionCategoryIcon, TickIcon, TranslateIcon, } from '@manuscripts/style-guide';
|
|
2
2
|
import { createElement } from 'react';
|
|
3
3
|
import { renderToStaticMarkup } from 'react-dom/server';
|
|
4
4
|
const renderIcon = (c) => renderToStaticMarkup(createElement(c));
|
|
@@ -6,6 +6,7 @@ export const addAuthorIcon = renderIcon(AddAuthorIcon);
|
|
|
6
6
|
export const arrowDown = renderIcon(ArrowDownCircleIcon);
|
|
7
7
|
export const arrowUp = renderIcon(ArrowUpIcon);
|
|
8
8
|
export const alertIcon = renderIcon(AlertIcon);
|
|
9
|
+
export const cameraIcon = renderIcon(CameraIcon);
|
|
9
10
|
export const deleteIcon = renderIcon(DeleteIcon);
|
|
10
11
|
export const editIcon = renderIcon(EditIcon);
|
|
11
12
|
export const sectionCategoryIcon = renderIcon(SectionCategoryIcon);
|