@manuscripts/body-editor 1.6.20 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/configs/editor-plugins.js +2 -0
- package/dist/cjs/configs/editor-views.js +4 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/lib/track-changes-utils.js +11 -1
- package/dist/cjs/plugins/affiliations.js +118 -0
- package/dist/cjs/views/affiliation.js +75 -0
- package/dist/cjs/views/affiliations.js +24 -0
- package/dist/cjs/views/contributors.js +150 -11
- package/dist/cjs/views/figure_editable.js +2 -5
- package/dist/cjs/views/keyword.js +2 -1
- package/dist/es/configs/editor-plugins.js +2 -0
- package/dist/es/configs/editor-views.js +4 -0
- package/dist/es/index.js +1 -0
- package/dist/es/lib/track-changes-utils.js +9 -0
- package/dist/es/plugins/affiliations.js +114 -0
- package/dist/es/views/affiliation.js +71 -0
- package/dist/es/views/affiliations.js +17 -0
- package/dist/es/views/contributors.js +150 -11
- package/dist/es/views/figure_editable.js +2 -5
- package/dist/es/views/keyword.js +2 -1
- package/dist/types/configs/ManuscriptsEditor.d.ts +2 -0
- package/dist/types/configs/editor-views.d.ts +2 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/lib/track-changes-utils.d.ts +2 -0
- package/dist/types/plugins/affiliations.d.ts +26 -0
- package/dist/types/types.d.ts +4 -0
- package/dist/types/views/affiliation.d.ts +31 -0
- package/dist/types/views/affiliations.d.ts +9 -0
- package/dist/types/views/contributors.d.ts +24 -8
- package/package.json +3 -3
- package/styles/AdvancedEditor.css +143 -47
- package/styles/Editor.css +1 -2
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2019 Atypon Systems LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { isAffiliationNode, isContributorNode, } from '@manuscripts/transform';
|
|
17
|
+
import { Plugin, PluginKey } from 'prosemirror-state';
|
|
18
|
+
import { Decoration, DecorationSet } from 'prosemirror-view';
|
|
19
|
+
import { getActualAttrs, isDeleted, isPendingInsert, } from '../lib/track-changes-utils';
|
|
20
|
+
export const affiliationsKey = new PluginKey('affiliations');
|
|
21
|
+
export const buildPluginState = (doc) => {
|
|
22
|
+
const contributors = [];
|
|
23
|
+
const affiliations = [];
|
|
24
|
+
doc.descendants((node, pos) => {
|
|
25
|
+
if (isDeleted(node)) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (isAffiliationNode(node)) {
|
|
29
|
+
affiliations.push([node, pos]);
|
|
30
|
+
}
|
|
31
|
+
if (isContributorNode(node)) {
|
|
32
|
+
contributors.push([node, pos]);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
const iAffiliations = new Set();
|
|
36
|
+
contributors
|
|
37
|
+
.sort(([a], [b]) => {
|
|
38
|
+
return (Number(getActualAttrs(a).priority) - Number(getActualAttrs(b).priority));
|
|
39
|
+
})
|
|
40
|
+
.forEach(([author]) => {
|
|
41
|
+
getActualAttrs(author).affiliations.forEach((aff) => {
|
|
42
|
+
iAffiliations.add(aff);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
const indexedAffiliationIds = new Map([...iAffiliations].map((id, i) => [id, i + 1]));
|
|
46
|
+
return {
|
|
47
|
+
indexedAffiliationIds,
|
|
48
|
+
contributors,
|
|
49
|
+
affiliations,
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
let count = 0;
|
|
53
|
+
export default () => {
|
|
54
|
+
return new Plugin({
|
|
55
|
+
key: affiliationsKey,
|
|
56
|
+
state: {
|
|
57
|
+
init(config, instance) {
|
|
58
|
+
return buildPluginState(instance.doc);
|
|
59
|
+
},
|
|
60
|
+
apply(tr, value, oldState, newState) {
|
|
61
|
+
const prevPluginState = affiliationsKey.getState(oldState);
|
|
62
|
+
if (!tr.docChanged && prevPluginState) {
|
|
63
|
+
return prevPluginState;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
return buildPluginState(newState.doc);
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
appendTransaction(transactions, oldState, newState) {
|
|
71
|
+
const { indexedAffiliationIds } = affiliationsKey.getState(newState);
|
|
72
|
+
const oldPluginState = affiliationsKey.getState(oldState);
|
|
73
|
+
const { tr } = newState;
|
|
74
|
+
const affiliations = [];
|
|
75
|
+
newState.doc.descendants((node, pos) => {
|
|
76
|
+
if (isDeleted(node)) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (isAffiliationNode(node)) {
|
|
80
|
+
affiliations.push([node, pos]);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
for (const [id] of oldPluginState.indexedAffiliationIds.entries()) {
|
|
84
|
+
if (!indexedAffiliationIds.has(id)) {
|
|
85
|
+
const affiliation = affiliations.find(([node]) => node.attrs.id === id);
|
|
86
|
+
if (affiliation && !isPendingInsert(affiliation[0])) {
|
|
87
|
+
tr.delete(affiliation[1], affiliation[1] + affiliation[0].nodeSize);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
tr.setMeta('origin', 'affiliations');
|
|
92
|
+
return tr;
|
|
93
|
+
},
|
|
94
|
+
props: {
|
|
95
|
+
decorations: (state) => {
|
|
96
|
+
const decorations = [];
|
|
97
|
+
const allNodes = [];
|
|
98
|
+
state.doc.descendants((node, pos) => {
|
|
99
|
+
if (isAffiliationNode(node) || isContributorNode(node)) {
|
|
100
|
+
allNodes.push([node, pos]);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
if (allNodes.length) {
|
|
104
|
+
allNodes.forEach(([node, pos]) => {
|
|
105
|
+
decorations.push(Decoration.node(pos, pos + node.nodeSize, {}, {
|
|
106
|
+
refresh: count++,
|
|
107
|
+
}));
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
return DecorationSet.create(state.doc, decorations);
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2019 Atypon Systems LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { getActualAttrs } from '../lib/track-changes-utils';
|
|
17
|
+
import { affiliationsKey } from '../plugins/affiliations';
|
|
18
|
+
import { BaseNodeView } from './base_node_view';
|
|
19
|
+
import { createNodeView } from './creators';
|
|
20
|
+
export class AffiliationView extends BaseNodeView {
|
|
21
|
+
constructor() {
|
|
22
|
+
super(...arguments);
|
|
23
|
+
this.initialise = () => {
|
|
24
|
+
this.createDOM();
|
|
25
|
+
};
|
|
26
|
+
this.updateContents = () => {
|
|
27
|
+
var _a;
|
|
28
|
+
const attrs = this.node.attrs;
|
|
29
|
+
const pluginState = affiliationsKey.getState(this.view.state);
|
|
30
|
+
this.dom.innerHTML = this.formatAddress(getActualAttrs(this.node));
|
|
31
|
+
if (pluginState === null || pluginState === void 0 ? void 0 : pluginState.indexedAffiliationIds) {
|
|
32
|
+
const order = pluginState.indexedAffiliationIds.get(attrs.id);
|
|
33
|
+
this.dom.innerHTML = order
|
|
34
|
+
? `<b>${order}</b> ${this.dom.innerHTML}`
|
|
35
|
+
: this.dom.innerHTML;
|
|
36
|
+
this.dom.setAttribute('style', 'order: ' + (order || (pluginState === null || pluginState === void 0 ? void 0 : pluginState.affiliations.length) + 1));
|
|
37
|
+
}
|
|
38
|
+
if ((_a = attrs.dataTracked) === null || _a === void 0 ? void 0 : _a.length) {
|
|
39
|
+
this.dom.setAttribute('data-track-status', attrs.dataTracked[0].status);
|
|
40
|
+
this.dom.setAttribute('data-track-op', attrs.dataTracked[0].operation);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
this.dom.removeAttribute('data-track-status');
|
|
44
|
+
this.dom.removeAttribute('data-track-type');
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
this.createDOM = () => {
|
|
48
|
+
this.dom = document.createElement('div');
|
|
49
|
+
this.dom.classList.add('affiliation');
|
|
50
|
+
this.dom.setAttribute('id', this.node.attrs.id);
|
|
51
|
+
this.updateContents();
|
|
52
|
+
};
|
|
53
|
+
this.ignoreMutation = () => true;
|
|
54
|
+
this.stopEvent = () => true;
|
|
55
|
+
this.formatAddress = (affiliation) => {
|
|
56
|
+
const { department, institution, addressLine1, city, county, country, postCode, } = affiliation;
|
|
57
|
+
return [
|
|
58
|
+
department,
|
|
59
|
+
institution,
|
|
60
|
+
addressLine1,
|
|
61
|
+
city,
|
|
62
|
+
county,
|
|
63
|
+
country,
|
|
64
|
+
postCode,
|
|
65
|
+
]
|
|
66
|
+
.filter(Boolean)
|
|
67
|
+
.join(', ');
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export default createNodeView(AffiliationView);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import BlockView from './block_view';
|
|
2
|
+
import { createNodeView } from './creators';
|
|
3
|
+
export class AffiliationsView extends BlockView {
|
|
4
|
+
constructor() {
|
|
5
|
+
super(...arguments);
|
|
6
|
+
this.ignoreMutation = () => true;
|
|
7
|
+
this.stopEvent = () => true;
|
|
8
|
+
this.createElement = () => {
|
|
9
|
+
this.contentDOM = document.createElement(this.elementType);
|
|
10
|
+
this.contentDOM.className = 'block';
|
|
11
|
+
this.contentDOM.setAttribute('contenteditable', 'false');
|
|
12
|
+
this.dom.setAttribute('contenteditable', 'false');
|
|
13
|
+
this.dom.appendChild(this.contentDOM);
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export default createNodeView(AffiliationsView);
|
|
@@ -1,28 +1,167 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SecondaryButton } from '@manuscripts/style-guide';
|
|
2
|
+
import { isContributorNode } from '@manuscripts/transform';
|
|
3
|
+
import { getActualAttrs } from '../lib/track-changes-utils';
|
|
4
|
+
import { affiliationsKey } from '../plugins/affiliations';
|
|
5
|
+
import BlockView from './block_view';
|
|
2
6
|
import { createNodeView } from './creators';
|
|
3
7
|
import ReactSubView from './ReactSubView';
|
|
4
|
-
export class ContributorsView extends
|
|
8
|
+
export class ContributorsView extends BlockView {
|
|
5
9
|
constructor() {
|
|
6
10
|
super(...arguments);
|
|
7
11
|
this.initialise = () => {
|
|
8
12
|
this.createDOM();
|
|
13
|
+
this.createGutter('block-gutter', this.gutterButtons().filter(Boolean));
|
|
14
|
+
this.createElement();
|
|
15
|
+
this.createGutter('action-gutter', this.actionGutterButtons().filter(Boolean));
|
|
16
|
+
this.updateContents();
|
|
17
|
+
};
|
|
18
|
+
this.updateContents = () => {
|
|
19
|
+
this.updateClasses();
|
|
20
|
+
this.updateAttributes();
|
|
21
|
+
this.container.innerHTML = '';
|
|
22
|
+
this.buildAuthors();
|
|
23
|
+
this.createEditButton();
|
|
24
|
+
this.createLegend();
|
|
25
|
+
};
|
|
26
|
+
this.buildAuthors = () => {
|
|
27
|
+
var _a;
|
|
28
|
+
const authors = [];
|
|
29
|
+
const authorsWrapper = document.createElement('div');
|
|
30
|
+
authorsWrapper.classList.add('contributors-list');
|
|
31
|
+
(_a = this.node.content) === null || _a === void 0 ? void 0 : _a.forEach((node) => {
|
|
32
|
+
if (isContributorNode(node)) {
|
|
33
|
+
authors.push(node);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
authors
|
|
37
|
+
.sort((a, b) => Number(a.attrs.priority) - Number(b.attrs.priority))
|
|
38
|
+
.forEach((author, i) => {
|
|
39
|
+
if (getActualAttrs(author).role !== 'author') {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const jointAuthors = this.isJointFirstAuthor(authors, i);
|
|
43
|
+
authorsWrapper.appendChild(this.buildAuthor(author, jointAuthors));
|
|
44
|
+
});
|
|
45
|
+
this.container.appendChild(authorsWrapper);
|
|
46
|
+
};
|
|
47
|
+
this.buildAuthor = (node, isJointFirstAuthor) => {
|
|
48
|
+
var _a;
|
|
49
|
+
const pluginState = affiliationsKey.getState(this.view.state);
|
|
50
|
+
const attrs = node.attrs;
|
|
51
|
+
const displayAttr = getActualAttrs(node);
|
|
52
|
+
const container = document.createElement('button');
|
|
53
|
+
container.classList.add('contributor');
|
|
54
|
+
container.setAttribute('id', attrs.id);
|
|
55
|
+
container.setAttribute('contenteditable', 'false');
|
|
56
|
+
if ((_a = attrs.dataTracked) === null || _a === void 0 ? void 0 : _a.length) {
|
|
57
|
+
container.setAttribute('data-track-status', attrs.dataTracked[0].status);
|
|
58
|
+
container.setAttribute('data-track-op', attrs.dataTracked[0].operation);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
container.removeAttribute('data-track-status');
|
|
62
|
+
container.removeAttribute('data-track-type');
|
|
63
|
+
}
|
|
64
|
+
const can = this.props.getCapabilities();
|
|
65
|
+
const disableEditButton = !can.editMetadata;
|
|
66
|
+
const { bibliographicName, isCorresponding, email, id } = displayAttr;
|
|
67
|
+
container.addEventListener('click', (e) => {
|
|
68
|
+
e.preventDefault();
|
|
69
|
+
if (!disableEditButton) {
|
|
70
|
+
this.props.openAuthorEditing();
|
|
71
|
+
this.props.selectAuthorForEditing(id);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
const name = this.buildNameLiteral(bibliographicName);
|
|
75
|
+
container.innerHTML =
|
|
76
|
+
isCorresponding && email
|
|
77
|
+
? `<span class="name">${name} (${email})</span>`
|
|
78
|
+
: `<span class="name">${name}</span>`;
|
|
79
|
+
const noteText = [];
|
|
80
|
+
if (pluginState === null || pluginState === void 0 ? void 0 : pluginState.indexedAffiliationIds) {
|
|
81
|
+
displayAttr.affiliations.map((af) => {
|
|
82
|
+
const index = pluginState === null || pluginState === void 0 ? void 0 : pluginState.indexedAffiliationIds.get(af);
|
|
83
|
+
if (index) {
|
|
84
|
+
noteText.push(index.toString());
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
if (isJointFirstAuthor) {
|
|
89
|
+
container.appendChild(this.createNote('†', 'Joint contributor'));
|
|
90
|
+
}
|
|
91
|
+
if (noteText) {
|
|
92
|
+
container.appendChild(this.createNote(noteText.join(',')));
|
|
93
|
+
}
|
|
94
|
+
if (displayAttr.isCorresponding) {
|
|
95
|
+
container.appendChild(this.createNote('*', 'Corresponding author'));
|
|
96
|
+
}
|
|
97
|
+
return container;
|
|
98
|
+
};
|
|
99
|
+
this.initials = (given) => given
|
|
100
|
+
? given
|
|
101
|
+
.trim()
|
|
102
|
+
.split(' ')
|
|
103
|
+
.map((part) => part.substr(0, 1).toUpperCase() + '.')
|
|
104
|
+
.join('')
|
|
105
|
+
: '';
|
|
106
|
+
this.buildNameLiteral = ({ given = '', family = '', suffix = '' }) => {
|
|
107
|
+
if (!given && !family) {
|
|
108
|
+
return 'Unknown Author';
|
|
109
|
+
}
|
|
110
|
+
return [this.initials(given), family, suffix]
|
|
111
|
+
.filter((part) => part)
|
|
112
|
+
.join(' ');
|
|
113
|
+
};
|
|
114
|
+
this.isJointFirstAuthor = (authors, index) => {
|
|
115
|
+
const author = index === 0 ? authors[index] : authors[index - 1];
|
|
116
|
+
return Boolean(author.attrs.isJointContributor);
|
|
117
|
+
};
|
|
118
|
+
this.createElement = () => {
|
|
119
|
+
this.inner = document.createElement('div');
|
|
120
|
+
this.inner.classList.add('authors-container', 'block');
|
|
121
|
+
this.dom.appendChild(this.inner);
|
|
122
|
+
this.container = document.createElement('div');
|
|
123
|
+
this.container.classList.add('contributors');
|
|
124
|
+
this.inner.appendChild(this.container);
|
|
9
125
|
};
|
|
10
126
|
this.createDOM = () => {
|
|
11
127
|
this.dom = document.createElement('div');
|
|
12
|
-
this.dom.classList.add('
|
|
128
|
+
this.dom.classList.add('block-container', `block-${this.node.type.name}`);
|
|
129
|
+
};
|
|
130
|
+
this.createEditButton = () => {
|
|
13
131
|
const can = this.props.getCapabilities();
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
132
|
+
const button = ReactSubView(this.props, SecondaryButton, {
|
|
133
|
+
mini: true,
|
|
134
|
+
onClick: this.props.openAuthorEditing,
|
|
135
|
+
className: 'edit-authors-button',
|
|
136
|
+
disabled: !can.editMetadata,
|
|
137
|
+
children: 'Edit Authors',
|
|
138
|
+
}, this.node, this.getPos, this.view);
|
|
139
|
+
this.container.appendChild(button);
|
|
140
|
+
};
|
|
141
|
+
this.createLegend = () => {
|
|
142
|
+
const state = affiliationsKey.getState(this.view.state);
|
|
143
|
+
if (state === null || state === void 0 ? void 0 : state.contributors) {
|
|
144
|
+
const isThereJointContributor = state.contributors.find(([contributor]) => contributor.attrs.isJointContributor);
|
|
145
|
+
if (isThereJointContributor) {
|
|
146
|
+
const element = document.createElement('p');
|
|
147
|
+
element.classList.add('contributors-legend');
|
|
148
|
+
element.innerHTML =
|
|
149
|
+
'<span class="symbol">†</span>These authors contributed equally to this work.';
|
|
150
|
+
this.container.appendChild(element);
|
|
151
|
+
}
|
|
22
152
|
}
|
|
23
153
|
};
|
|
24
154
|
this.ignoreMutation = () => true;
|
|
25
155
|
this.stopEvent = () => true;
|
|
26
156
|
}
|
|
157
|
+
createNote(text = '', title = '') {
|
|
158
|
+
const el = document.createElement('span');
|
|
159
|
+
el.innerHTML = text;
|
|
160
|
+
if (title) {
|
|
161
|
+
el.setAttribute('title', title);
|
|
162
|
+
}
|
|
163
|
+
el.classList.add('contributor-note');
|
|
164
|
+
return el;
|
|
165
|
+
}
|
|
27
166
|
}
|
|
28
167
|
export default createNodeView(ContributorsView);
|
|
@@ -26,6 +26,7 @@ import { UnsupportedFormatFileIcon, } from '@manuscripts/style-guide';
|
|
|
26
26
|
import { createElement } from 'react';
|
|
27
27
|
import ReactDOM from 'react-dom';
|
|
28
28
|
import { FigureOptions, } from '../components/views/FigureDropdown';
|
|
29
|
+
import { getActualAttrs } from '../lib/track-changes-utils';
|
|
29
30
|
import { createEditableNodeView } from './creators';
|
|
30
31
|
import { FigureView } from './figure';
|
|
31
32
|
import { figureUploader } from './figure_uploader';
|
|
@@ -44,12 +45,8 @@ export class FigureEditableView extends FigureView {
|
|
|
44
45
|
};
|
|
45
46
|
this.updateContents = () => {
|
|
46
47
|
var _a, _b;
|
|
47
|
-
|
|
48
|
+
const attrs = getActualAttrs(this.node);
|
|
48
49
|
if ((_a = this.node.attrs.dataTracked) === null || _a === void 0 ? void 0 : _a.length) {
|
|
49
|
-
if (this.node.attrs.dataTracked[0].status === 'rejected' &&
|
|
50
|
-
this.node.attrs.dataTracked[0].operation === 'set_attrs') {
|
|
51
|
-
attrs = this.node.attrs.dataTracked[0].oldAttrs;
|
|
52
|
-
}
|
|
53
50
|
this.dom.setAttribute('data-track-status', this.node.attrs.dataTracked[0].status);
|
|
54
51
|
this.dom.setAttribute('data-track-op', this.node.attrs.dataTracked[0].operation);
|
|
55
52
|
}
|
package/dist/es/views/keyword.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
+
import { TextSelection } from 'prosemirror-state';
|
|
16
17
|
import { DeleteKeywordDialog, } from '../components/keywords/DeleteKeywordDialog';
|
|
17
18
|
import { getChangeClasses } from '../lib/track-changes-utils';
|
|
18
19
|
import { BaseNodeView } from './base_node_view';
|
|
@@ -61,7 +62,7 @@ export class KeywordView extends BaseNodeView {
|
|
|
61
62
|
const pos = this.getPos();
|
|
62
63
|
const handleDelete = () => {
|
|
63
64
|
const tr = this.view.state.tr;
|
|
64
|
-
tr.delete(pos, pos + keyword.nodeSize);
|
|
65
|
+
tr.setSelection(TextSelection.near(this.view.state.doc.resolve(0))).delete(pos, pos + keyword.nodeSize + 1);
|
|
65
66
|
this.view.dispatch(tr);
|
|
66
67
|
};
|
|
67
68
|
const componentProps = {
|
|
@@ -53,6 +53,8 @@ export interface EditorProps {
|
|
|
53
53
|
retrySync: (componentIDs: string[]) => Promise<void>;
|
|
54
54
|
environment?: string;
|
|
55
55
|
collabProvider?: CollabProvider;
|
|
56
|
+
openAuthorEditing: () => void;
|
|
57
|
+
selectAuthorForEditing: (authorId: string) => void;
|
|
56
58
|
}
|
|
57
59
|
export declare const createEditorState: (props: EditorProps) => EditorState;
|
|
58
60
|
export declare const createEditorView: (props: EditorProps, root: HTMLElement, state: EditorState, dispatch: Dispatch) => EditorView;
|
|
@@ -139,6 +139,8 @@ declare const _default: (props: EditorProps, dispatch: Dispatch) => {
|
|
|
139
139
|
citation: import("../types").NodeViewCreator<import("../views/citation_editable").CitationEditableView>;
|
|
140
140
|
cross_reference: import("../types").NodeViewCreator<import("../views/cross_reference_editable").CrossReferenceEditableView>;
|
|
141
141
|
contributors: import("../types").NodeViewCreator<import("../views/contributors").ContributorsView<any>>;
|
|
142
|
+
affiliations: import("../types").NodeViewCreator<import("../views/affiliations").AffiliationsView<any>>;
|
|
143
|
+
affiliation: import("../types").NodeViewCreator<import("../views/affiliation").AffiliationView<any>>;
|
|
142
144
|
equation: import("../types").NodeViewCreator<import("../views/equation_editable").EquationEditableView>;
|
|
143
145
|
equation_element: import("../types").NodeViewCreator<{
|
|
144
146
|
gutterButtons: () => HTMLElement[];
|
package/dist/types/index.d.ts
CHANGED
|
@@ -27,4 +27,5 @@ export * from './toolbar';
|
|
|
27
27
|
export * from './plugins/highlight';
|
|
28
28
|
export { commentScroll, isThereSelector, isHighlightComment, } from './plugins/comment_annotation';
|
|
29
29
|
export * from './lib/utils';
|
|
30
|
+
export * from './lib/track-changes-utils';
|
|
30
31
|
export * from './useEditor';
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
+
import { ManuscriptNode } from '@manuscripts/transform';
|
|
16
17
|
import { Node as ProsemirrorNode } from 'prosemirror-model';
|
|
17
18
|
export declare function isRejectedInsert(node: ProsemirrorNode): boolean;
|
|
18
19
|
export declare function isDeleted(node: ProsemirrorNode): boolean;
|
|
@@ -21,3 +22,4 @@ export declare function isPending(node: ProsemirrorNode): boolean;
|
|
|
21
22
|
export declare function isPendingSetAttrs(node: ProsemirrorNode): boolean;
|
|
22
23
|
export declare function getChangeClasses(node: ProsemirrorNode): string[];
|
|
23
24
|
export declare function isTracked(node: ProsemirrorNode): boolean;
|
|
25
|
+
export declare function getActualAttrs<T extends ManuscriptNode>(node: T): T["attrs"];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2019 Atypon Systems LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { AffiliationNode, ContributorNode, ManuscriptNode } from '@manuscripts/transform';
|
|
17
|
+
import { Plugin, PluginKey } from 'prosemirror-state';
|
|
18
|
+
interface PluginState {
|
|
19
|
+
indexedAffiliationIds: Map<string, number>;
|
|
20
|
+
contributors: Array<[ContributorNode, number]>;
|
|
21
|
+
affiliations: Array<[AffiliationNode, number]>;
|
|
22
|
+
}
|
|
23
|
+
export declare const affiliationsKey: PluginKey<PluginState>;
|
|
24
|
+
export declare const buildPluginState: (doc: ManuscriptNode) => PluginState;
|
|
25
|
+
declare const _default: () => Plugin<PluginState>;
|
|
26
|
+
export default _default;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
+
import { TrackedAttrs } from '@manuscripts/track-changes-plugin';
|
|
16
17
|
import { ManuscriptEditorState, ManuscriptEditorView, ManuscriptNode, ManuscriptNodeView, ManuscriptTransaction } from '@manuscripts/transform';
|
|
17
18
|
import { Decoration } from 'prosemirror-view';
|
|
18
19
|
export type EditorAction = (state: ManuscriptEditorState, dispatch?: (tr: ManuscriptTransaction) => void, view?: ManuscriptEditorView) => boolean;
|
|
@@ -24,3 +25,6 @@ export type ChangeReceiver = (op: string, id?: string, data?: ManuscriptNode | n
|
|
|
24
25
|
export interface SyncError {
|
|
25
26
|
_id: string;
|
|
26
27
|
}
|
|
28
|
+
export type TrackableAttributes<T extends ManuscriptNode> = T['attrs'] & {
|
|
29
|
+
dataTracked?: TrackedAttrs[];
|
|
30
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2019 Atypon Systems LLC
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { Capabilities } from '@manuscripts/style-guide';
|
|
17
|
+
import { AffiliationNode, ManuscriptNodeView } from '@manuscripts/transform';
|
|
18
|
+
import { BaseNodeProps, BaseNodeView } from './base_node_view';
|
|
19
|
+
export interface Props extends BaseNodeProps {
|
|
20
|
+
getCapabilities: () => Capabilities;
|
|
21
|
+
}
|
|
22
|
+
export declare class AffiliationView<PropsType extends BaseNodeProps> extends BaseNodeView<PropsType> implements ManuscriptNodeView {
|
|
23
|
+
initialise: () => void;
|
|
24
|
+
updateContents: () => void;
|
|
25
|
+
protected createDOM: () => void;
|
|
26
|
+
ignoreMutation: () => boolean;
|
|
27
|
+
stopEvent: () => boolean;
|
|
28
|
+
formatAddress: (affiliation: AffiliationNode['attrs']) => string;
|
|
29
|
+
}
|
|
30
|
+
declare const _default: (props: BaseNodeProps, dispatch?: import("..").Dispatch | undefined) => import("../types").NodeViewCreator<AffiliationView<any>>;
|
|
31
|
+
export default _default;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import BlockView from './block_view';
|
|
2
|
+
import { EditableBlockProps } from './editable_block';
|
|
3
|
+
export declare class AffiliationsView<PropsType extends EditableBlockProps> extends BlockView<PropsType> {
|
|
4
|
+
ignoreMutation: () => boolean;
|
|
5
|
+
stopEvent: () => boolean;
|
|
6
|
+
createElement: () => void;
|
|
7
|
+
}
|
|
8
|
+
declare const _default: (props: import("./base_node_view").BaseNodeProps, dispatch?: import("..").Dispatch | undefined) => import("../types").NodeViewCreator<AffiliationsView<any>>;
|
|
9
|
+
export default _default;
|
|
@@ -1,15 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import { Capabilities } from '@manuscripts/style-guide';
|
|
2
|
+
import { ContributorNode } from '@manuscripts/transform';
|
|
3
|
+
import BlockView from './block_view';
|
|
4
4
|
import { EditableBlockProps } from './editable_block';
|
|
5
5
|
export interface ContributorsProps extends EditableBlockProps {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
getCapabilities: () => Capabilities;
|
|
7
|
+
openAuthorEditing: () => void;
|
|
8
|
+
selectAuthorForEditing: (authorId: string) => void;
|
|
8
9
|
}
|
|
9
|
-
export declare class ContributorsView<PropsType extends ContributorsProps> extends
|
|
10
|
-
private metadata;
|
|
10
|
+
export declare class ContributorsView<PropsType extends ContributorsProps> extends BlockView<PropsType> {
|
|
11
11
|
initialise: () => void;
|
|
12
|
-
|
|
12
|
+
updateContents: () => void;
|
|
13
|
+
buildAuthors: () => void;
|
|
14
|
+
container: HTMLElement;
|
|
15
|
+
inner: HTMLElement;
|
|
16
|
+
buildAuthor: (node: ContributorNode, isJointFirstAuthor: boolean) => HTMLButtonElement;
|
|
17
|
+
createNote(text?: string, title?: string): HTMLSpanElement;
|
|
18
|
+
initials: (given: string) => string;
|
|
19
|
+
buildNameLiteral: ({ given, family, suffix }: {
|
|
20
|
+
given?: string | undefined;
|
|
21
|
+
family?: string | undefined;
|
|
22
|
+
suffix?: string | undefined;
|
|
23
|
+
}) => string;
|
|
24
|
+
isJointFirstAuthor: (authors: ContributorNode[], index: number) => boolean;
|
|
25
|
+
createElement: () => void;
|
|
26
|
+
createDOM: () => void;
|
|
27
|
+
createEditButton: () => void;
|
|
28
|
+
createLegend: () => void;
|
|
13
29
|
ignoreMutation: () => boolean;
|
|
14
30
|
stopEvent: () => boolean;
|
|
15
31
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@manuscripts/body-editor",
|
|
3
3
|
"description": "Prosemirror components for editing and viewing manuscripts",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.7.0",
|
|
5
5
|
"repository": "github:Atypon-OpenSource/manuscripts-body-editor",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"main": "dist/cjs",
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"@manuscripts/assets": "^0.6.4",
|
|
32
32
|
"@manuscripts/json-schema": "^2.2.2",
|
|
33
33
|
"@manuscripts/library": "1.3.2",
|
|
34
|
-
"@manuscripts/style-guide": "1.7.
|
|
34
|
+
"@manuscripts/style-guide": "1.7.4",
|
|
35
35
|
"@manuscripts/track-changes-plugin": "^1.7.5",
|
|
36
|
-
"@manuscripts/transform": "2.
|
|
36
|
+
"@manuscripts/transform": "2.1.1",
|
|
37
37
|
"astrocite-eutils": "^0.16.4",
|
|
38
38
|
"axios": "^1.6.7",
|
|
39
39
|
"codemirror": "^5.58.1",
|