@manuscripts/body-editor 1.9.4-LEAN-3584.1 → 1.9.5
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 +12 -3
- package/dist/cjs/keys/misc.js +1 -1
- package/dist/cjs/lib/context-menu.js +3 -1
- package/dist/cjs/plugins/comment_annotation.js +10 -4
- package/dist/cjs/plugins/footnotes/footnotes-utils.js +8 -3
- package/dist/cjs/plugins/footnotes/index.js +31 -39
- package/dist/cjs/views/inline_footnote.js +1 -0
- package/dist/es/commands.js +10 -2
- package/dist/es/keys/misc.js +2 -2
- package/dist/es/lib/context-menu.js +3 -1
- package/dist/es/plugins/comment_annotation.js +10 -4
- package/dist/es/plugins/footnotes/footnotes-utils.js +8 -3
- package/dist/es/plugins/footnotes/index.js +32 -40
- package/dist/es/views/inline_footnote.js +2 -1
- package/dist/types/commands.d.ts +1 -0
- package/dist/types/plugins/footnotes/footnotes-utils.d.ts +1 -1
- package/package.json +3 -3
- package/styles/Editor.css +9 -13
package/dist/cjs/commands.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.insertTableFootnote = exports.updateCommentAnnotationState = exports.addComment = exports.deleteHighlightMarkers = exports.insertHighlight = exports.createAndFillTableElement = exports.selectAllIsolating = exports.ignoreAtomBlockNodeForward = exports.isAtEndOfTextBlock = exports.ignoreAtomBlockNodeBackward = exports.isTextSelection = exports.isAtStartOfTextBlock = exports.ifInTableBody = exports.insertTOCSection = exports.insertBibliographySection = exports.insertList = exports.insertSection = exports.insertGraphicalAbstract = exports.insertInlineFootnote = exports.insertInlineEquation = exports.insertCrossReference = exports.insertInlineCitation = exports.insertLink = exports.insertSectionLabel = exports.insertBreak = exports.deleteBlock = exports.insertBlock = exports.insertFileAsFigure = exports.insertGeneralFootnote = exports.createBlock = exports.createSelection = exports.canInsert = exports.blockActive = exports.isNodeSelection = exports.markActive = void 0;
|
|
18
|
+
exports.insertTableFootnote = exports.updateCommentAnnotationState = exports.addComment = exports.deleteHighlightMarkers = exports.insertHighlight = exports.createAndFillTableElement = exports.selectAllIsolating = exports.ignoreAtomBlockNodeForward = exports.isAtEndOfTextBlock = exports.ignoreMetaNodeBackspaceCommand = exports.ignoreAtomBlockNodeBackward = exports.isTextSelection = exports.isAtStartOfTextBlock = exports.ifInTableBody = exports.insertTOCSection = exports.insertBibliographySection = exports.insertList = exports.insertSection = exports.insertGraphicalAbstract = exports.insertInlineFootnote = exports.insertInlineEquation = exports.insertCrossReference = exports.insertInlineCitation = exports.insertLink = exports.insertSectionLabel = exports.insertBreak = exports.deleteBlock = exports.insertBlock = exports.insertFileAsFigure = exports.insertGeneralFootnote = exports.createBlock = exports.createSelection = exports.canInsert = exports.blockActive = exports.isNodeSelection = exports.markActive = void 0;
|
|
19
19
|
const json_schema_1 = require("@manuscripts/json-schema");
|
|
20
20
|
const track_changes_plugin_1 = require("@manuscripts/track-changes-plugin");
|
|
21
21
|
const transform_1 = require("@manuscripts/transform");
|
|
@@ -498,6 +498,16 @@ const ignoreAtomBlockNodeBackward = (state, dispatch, view) => {
|
|
|
498
498
|
return node.isBlock && node.isAtom;
|
|
499
499
|
};
|
|
500
500
|
exports.ignoreAtomBlockNodeBackward = ignoreAtomBlockNodeBackward;
|
|
501
|
+
const ignoreMetaNodeBackspaceCommand = (state) => {
|
|
502
|
+
const { selection } = state;
|
|
503
|
+
if (!(0, exports.isNodeSelection)(selection)) {
|
|
504
|
+
return false;
|
|
505
|
+
}
|
|
506
|
+
return (selection.node.type === transform_1.schema.nodes.keyword_group ||
|
|
507
|
+
selection.node.type === transform_1.schema.nodes.affiliations ||
|
|
508
|
+
selection.node.type === transform_1.schema.nodes.contributors);
|
|
509
|
+
};
|
|
510
|
+
exports.ignoreMetaNodeBackspaceCommand = ignoreMetaNodeBackspaceCommand;
|
|
501
511
|
const findCutAfter = ($pos) => {
|
|
502
512
|
if (!$pos.parent.type.spec.isolating) {
|
|
503
513
|
for (let i = $pos.depth - 1; i >= 0; i--) {
|
|
@@ -750,8 +760,7 @@ const insertTableFootnote = (node, position, view, inlineFootnote) => {
|
|
|
750
760
|
else {
|
|
751
761
|
const inlineFootnotes = (0, prosemirror_utils_1.findChildrenByType)(node, transform_1.schema.nodes.inline_footnote);
|
|
752
762
|
footnoteIndex =
|
|
753
|
-
inlineFootnotes.filter(({ pos }) => position + pos <= insertedAt).length +
|
|
754
|
-
1;
|
|
763
|
+
inlineFootnotes.filter(({ pos }) => !(0, track_changes_utils_1.isRejectedInsert)(node) && position + pos <= insertedAt).length + 1;
|
|
755
764
|
const inlineFootnoteNode = state.schema.nodes.inline_footnote.create({
|
|
756
765
|
rids: [footnote.attrs.id],
|
|
757
766
|
contents: footnoteIndex === -1 ? inlineFootnotes.length : footnoteIndex,
|
package/dist/cjs/keys/misc.js
CHANGED
|
@@ -22,7 +22,7 @@ const prosemirror_inputrules_1 = require("prosemirror-inputrules");
|
|
|
22
22
|
const prosemirror_tables_1 = require("prosemirror-tables");
|
|
23
23
|
const commands_1 = require("../commands");
|
|
24
24
|
const customKeymap = {
|
|
25
|
-
Backspace: (0, prosemirror_commands_1.chainCommands)(prosemirror_inputrules_1.undoInputRule, commands_1.ignoreAtomBlockNodeBackward),
|
|
25
|
+
Backspace: (0, prosemirror_commands_1.chainCommands)(prosemirror_inputrules_1.undoInputRule, commands_1.ignoreAtomBlockNodeBackward, commands_1.ignoreMetaNodeBackspaceCommand),
|
|
26
26
|
Delete: commands_1.ignoreAtomBlockNodeForward,
|
|
27
27
|
Tab: (0, prosemirror_tables_1.goToNextCell)(1),
|
|
28
28
|
'Mod-z': prosemirror_history_1.undo,
|
|
@@ -208,6 +208,7 @@ class ContextMenu {
|
|
|
208
208
|
const tablesFootnoteLabels = (0, footnotes_utils_1.buildTableFootnoteLabels)(this.node);
|
|
209
209
|
const footnotesWithPos = (0, prosemirror_utils_1.findChildrenByType)(footnotesElementWithPos.node, transform_1.schema.nodes.footnote);
|
|
210
210
|
const footnotes = footnotesWithPos
|
|
211
|
+
.filter(({ node }) => !(0, track_changes_utils_1.isDeleted)(node) && !(0, track_changes_utils_1.isRejectedInsert)(node))
|
|
211
212
|
.map(({ node }) => ({
|
|
212
213
|
node: node,
|
|
213
214
|
index: tablesFootnoteLabels.get(node.attrs.id),
|
|
@@ -228,7 +229,8 @@ class ContextMenu {
|
|
|
228
229
|
this.view.state.doc
|
|
229
230
|
.slice(this.getPos(), insertedAt)
|
|
230
231
|
.content.descendants((node) => {
|
|
231
|
-
if (node.type === transform_1.schema.nodes.inline_footnote
|
|
232
|
+
if (node.type === transform_1.schema.nodes.inline_footnote &&
|
|
233
|
+
!(0, track_changes_utils_1.isRejectedInsert)(node)) {
|
|
232
234
|
inlineFootnoteIndex++;
|
|
233
235
|
return false;
|
|
234
236
|
}
|
|
@@ -53,11 +53,17 @@ exports.default = (props) => {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
const hasCommentChange = !!tr.steps.find((s) => {
|
|
56
|
-
var _a, _b;
|
|
56
|
+
var _a, _b, _c, _d;
|
|
57
57
|
if (s instanceof prosemirror_transform_1.ReplaceStep) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
if (s.slice.size > 0) {
|
|
59
|
+
return (((_a = newState.doc.nodeAt(s.from + 1)) === null || _a === void 0 ? void 0 : _a.type) ===
|
|
60
|
+
transform_1.schema.nodes.comment ||
|
|
61
|
+
((_b = newState.doc.nodeAt(s.from)) === null || _b === void 0 ? void 0 : _b.type) ===
|
|
62
|
+
transform_1.schema.nodes.highlight_marker);
|
|
63
|
+
}
|
|
64
|
+
return (((_c = oldState.doc.nodeAt(s.from)) === null || _c === void 0 ? void 0 : _c.type) === transform_1.schema.nodes.comment ||
|
|
65
|
+
((_d = oldState.doc.nodeAt(s.from)) === null || _d === void 0 ? void 0 : _d.type) ===
|
|
66
|
+
transform_1.schema.nodes.highlight_marker);
|
|
61
67
|
}
|
|
62
68
|
});
|
|
63
69
|
if (hasCommentChange) {
|
|
@@ -20,11 +20,13 @@ const track_changes_plugin_1 = require("@manuscripts/track-changes-plugin");
|
|
|
20
20
|
const transform_1 = require("@manuscripts/transform");
|
|
21
21
|
const prosemirror_model_1 = require("prosemirror-model");
|
|
22
22
|
const prosemirror_utils_1 = require("prosemirror-utils");
|
|
23
|
+
const track_changes_utils_1 = require("../../lib/track-changes-utils");
|
|
23
24
|
const findTableInlineFootnoteIds = ($pos) => {
|
|
24
25
|
var _a;
|
|
25
26
|
const tableElement = (_a = (0, prosemirror_utils_1.findParentNodeClosestToPos)($pos, (node) => node.type === transform_1.schema.nodes.table_element)) === null || _a === void 0 ? void 0 : _a.node.firstChild;
|
|
26
27
|
return new Set(tableElement
|
|
27
28
|
? (0, prosemirror_utils_1.findChildren)(tableElement, (node) => node.type === transform_1.schema.nodes.inline_footnote)
|
|
29
|
+
.filter(({ node }) => !(0, track_changes_utils_1.isRejectedInsert)(node))
|
|
28
30
|
.map(({ node }) => node.attrs.rids)
|
|
29
31
|
.flat()
|
|
30
32
|
: []);
|
|
@@ -49,6 +51,7 @@ const buildTableFootnoteLabels = (node) => {
|
|
|
49
51
|
]));
|
|
50
52
|
let index = 0;
|
|
51
53
|
(0, prosemirror_utils_1.findChildrenByType)(node, transform_1.schema.nodes.inline_footnote)
|
|
54
|
+
.filter(({ node }) => !(0, track_changes_utils_1.isRejectedInsert)(node))
|
|
52
55
|
.map(({ node }) => node.attrs.rids)
|
|
53
56
|
.flat()
|
|
54
57
|
.map((rid) => {
|
|
@@ -82,7 +85,9 @@ const orderTableFootnotes = (tr, footnotesElementWithPos, position) => {
|
|
|
82
85
|
exports.orderTableFootnotes = orderTableFootnotes;
|
|
83
86
|
const updateTableInlineFootnoteLabels = (tr, table) => {
|
|
84
87
|
const labels = (0, exports.buildTableFootnoteLabels)(table.node);
|
|
85
|
-
(0, prosemirror_utils_1.findChildrenByType)(table.node, transform_1.schema.nodes.inline_footnote)
|
|
88
|
+
(0, prosemirror_utils_1.findChildrenByType)(table.node, transform_1.schema.nodes.inline_footnote)
|
|
89
|
+
.filter(({ node }) => !(0, track_changes_utils_1.isRejectedInsert)(node))
|
|
90
|
+
.map(({ node, pos }) => {
|
|
86
91
|
const contents = node.attrs.rids
|
|
87
92
|
.map((rid) => labels.get(rid))
|
|
88
93
|
.join(',');
|
|
@@ -94,9 +99,9 @@ const updateTableInlineFootnoteLabels = (tr, table) => {
|
|
|
94
99
|
return tr;
|
|
95
100
|
};
|
|
96
101
|
exports.updateTableInlineFootnoteLabels = updateTableInlineFootnoteLabels;
|
|
97
|
-
const getInlineFootnotes = (id,
|
|
102
|
+
const getInlineFootnotes = (id, targetNode) => {
|
|
98
103
|
const inlineFootnotes = [];
|
|
99
|
-
|
|
104
|
+
targetNode.descendants((node, pos) => {
|
|
100
105
|
var _a;
|
|
101
106
|
if (node.type === transform_1.schema.nodes.inline_footnote) {
|
|
102
107
|
const footnote = node;
|
|
@@ -73,11 +73,20 @@ const uncitedFootnoteWidget = () => () => {
|
|
|
73
73
|
return element;
|
|
74
74
|
};
|
|
75
75
|
exports.uncitedFootnoteWidget = uncitedFootnoteWidget;
|
|
76
|
-
const deleteFootnoteWidget = (node, props,
|
|
76
|
+
const deleteFootnoteWidget = (node, props, id, tableElement) => (view, getPos) => {
|
|
77
77
|
const deleteBtn = document.createElement('span');
|
|
78
78
|
deleteBtn.className = 'delete-icon';
|
|
79
79
|
deleteBtn.innerHTML = assets_1.deleteIcon;
|
|
80
|
-
|
|
80
|
+
const parentType = tableElement ? 'table ' : '';
|
|
81
|
+
const footnote = {
|
|
82
|
+
type: node.type === transform_1.schema.nodes.footnote
|
|
83
|
+
? `${parentType}footnote`
|
|
84
|
+
: 'table general note',
|
|
85
|
+
message: node.type === transform_1.schema.nodes.footnote
|
|
86
|
+
? `This action will entirely remove the ${parentType}footnote from the list because it will no longer be used.`
|
|
87
|
+
: 'This action will entirely remove the table general note.',
|
|
88
|
+
};
|
|
89
|
+
deleteBtn.addEventListener('mousedown', () => {
|
|
81
90
|
const handleDelete = () => {
|
|
82
91
|
let tr = view.state.tr;
|
|
83
92
|
const pos = getPos();
|
|
@@ -95,7 +104,8 @@ const deleteFootnoteWidget = (node, props, footnoteType, footnoteMessage, id, ta
|
|
|
95
104
|
}
|
|
96
105
|
}
|
|
97
106
|
if (node.type === transform_1.schema.nodes.footnote && pos) {
|
|
98
|
-
const
|
|
107
|
+
const targetNode = tableElement ? tableElement.node : view.state.doc;
|
|
108
|
+
const inlineFootnotes = (0, footnotes_utils_1.getInlineFootnotes)(id, targetNode);
|
|
99
109
|
const nodeWithPos = (0, prosemirror_utils_1.findParentNodeClosestToPos)(tr.doc.resolve(pos), (node) => node.type === transform_1.schema.nodes.footnote);
|
|
100
110
|
if (nodeWithPos) {
|
|
101
111
|
const { pos: fnPos, node: fnNode } = nodeWithPos;
|
|
@@ -104,13 +114,13 @@ const deleteFootnoteWidget = (node, props, footnoteType, footnoteMessage, id, ta
|
|
|
104
114
|
if (inlineFootnotes) {
|
|
105
115
|
tr = view.state.tr;
|
|
106
116
|
inlineFootnotes.forEach((footnote) => {
|
|
107
|
-
const pos = footnote.pos + tableElement.pos;
|
|
117
|
+
const pos = footnote.pos + (tableElement ? tableElement.pos + 1 : 0);
|
|
108
118
|
if (footnote.node.attrs.rids.length > 1) {
|
|
109
119
|
const updatedRids = footnote.node.attrs.rids.filter((rid) => rid !== id);
|
|
110
120
|
tr.setNodeMarkup(tr.mapping.map(pos + 1), undefined, Object.assign(Object.assign({}, node.attrs), { rids: updatedRids }));
|
|
111
121
|
}
|
|
112
122
|
else {
|
|
113
|
-
tr.delete(tr.mapping.map(pos
|
|
123
|
+
tr.delete(tr.mapping.map(pos), tr.mapping.map(pos + footnote.node.nodeSize));
|
|
114
124
|
}
|
|
115
125
|
});
|
|
116
126
|
}
|
|
@@ -118,8 +128,8 @@ const deleteFootnoteWidget = (node, props, footnoteType, footnoteMessage, id, ta
|
|
|
118
128
|
view.dispatch(tr);
|
|
119
129
|
};
|
|
120
130
|
const componentProps = {
|
|
121
|
-
footnoteType:
|
|
122
|
-
footnoteMessage:
|
|
131
|
+
footnoteType: footnote.type,
|
|
132
|
+
footnoteMessage: footnote.message,
|
|
123
133
|
handleDelete: handleDelete,
|
|
124
134
|
};
|
|
125
135
|
(0, ReactSubView_1.default)(Object.assign(Object.assign({}, props), { dispatch: view.dispatch }), DeleteFootnoteDialog_1.DeleteFootnoteDialog, componentProps, node, () => getPos(), view);
|
|
@@ -158,19 +168,30 @@ exports.default = (props) => {
|
|
|
158
168
|
props: {
|
|
159
169
|
decorations: (state) => {
|
|
160
170
|
const decorations = [];
|
|
161
|
-
const
|
|
171
|
+
const tableElementFooter = (0, prosemirror_utils_1.findParentNodeOfType)(transform_1.schema.nodes.table_element_footer)(state.selection);
|
|
162
172
|
const tableElement = (0, prosemirror_utils_1.findParentNodeOfType)(transform_1.schema.nodes.table_element)(state.selection);
|
|
163
|
-
|
|
173
|
+
const footnote = (0, prosemirror_utils_1.findParentNodeOfType)(transform_1.schema.nodes.footnote)(state.selection);
|
|
174
|
+
let targetNode;
|
|
175
|
+
if (footnote) {
|
|
176
|
+
targetNode = footnote;
|
|
177
|
+
}
|
|
178
|
+
else if (tableElementFooter) {
|
|
179
|
+
targetNode = tableElementFooter;
|
|
180
|
+
}
|
|
181
|
+
const can = props.getCapabilities();
|
|
182
|
+
if (targetNode && can.editArticle) {
|
|
164
183
|
const parent = (0, utils_1.findParentNodeWithIdValue)(state.selection);
|
|
165
184
|
if (parent) {
|
|
166
185
|
decorations.push(prosemirror_view_1.Decoration.node(parent.pos, parent.pos + parent.node.nodeSize, {
|
|
167
186
|
class: 'footnote-selected',
|
|
168
187
|
}));
|
|
188
|
+
decorations.push(prosemirror_view_1.Decoration.widget(targetNode.pos + (footnote ? 1 : 2), deleteFootnoteWidget(targetNode.node, props, targetNode.node.attrs.id, tableElement), {
|
|
189
|
+
key: targetNode.node.attrs.id,
|
|
190
|
+
}));
|
|
169
191
|
}
|
|
170
192
|
}
|
|
171
193
|
const { labels } = exports.footnotesKey.getState(state);
|
|
172
194
|
let tableInlineFootnoteIds = undefined;
|
|
173
|
-
const can = props.getCapabilities();
|
|
174
195
|
state.doc.descendants((node, pos, parent) => {
|
|
175
196
|
var _a;
|
|
176
197
|
if ((0, transform_1.isFootnoteNode)(node)) {
|
|
@@ -191,35 +212,6 @@ exports.default = (props) => {
|
|
|
191
212
|
decorations.push(prosemirror_view_1.Decoration.widget(pos + node.nodeSize - 1, (0, exports.uncitedFootnoteWidget)()));
|
|
192
213
|
}
|
|
193
214
|
}
|
|
194
|
-
if (can.editArticle) {
|
|
195
|
-
if (tableElement) {
|
|
196
|
-
const footnote = (() => {
|
|
197
|
-
switch (node.type) {
|
|
198
|
-
case transform_1.schema.nodes.footnote:
|
|
199
|
-
return {
|
|
200
|
-
type: 'table footnote',
|
|
201
|
-
message: 'This action will entirely remove the table footnote from the list because it will no longer be used.',
|
|
202
|
-
};
|
|
203
|
-
default:
|
|
204
|
-
return {
|
|
205
|
-
type: 'table general note',
|
|
206
|
-
message: 'This action will entirely remove the table general note.',
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
})();
|
|
210
|
-
if (node.type === transform_1.schema.nodes.footnote) {
|
|
211
|
-
decorations.push(prosemirror_view_1.Decoration.widget(pos + 2, deleteFootnoteWidget(node, props, footnote.type, footnote.message, node.attrs.id, tableElement), {
|
|
212
|
-
key: node.attrs.id,
|
|
213
|
-
}));
|
|
214
|
-
}
|
|
215
|
-
else if (node.type === transform_1.schema.nodes.paragraph &&
|
|
216
|
-
(parent === null || parent === void 0 ? void 0 : parent.type) === transform_1.schema.nodes.table_element_footer) {
|
|
217
|
-
decorations.push(prosemirror_view_1.Decoration.widget(pos + 1, deleteFootnoteWidget(parent, props, footnote.type, footnote.message, parent.attrs.id, tableElement), {
|
|
218
|
-
key: parent.attrs.id,
|
|
219
|
-
}));
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
215
|
if (node.type === transform_1.schema.nodes.footnotes_element) {
|
|
224
216
|
if ((parent === null || parent === void 0 ? void 0 : parent.type) === transform_1.schema.nodes.table_element_footer) {
|
|
225
217
|
decorations.push(prosemirror_view_1.Decoration.node(pos, pos + node.nodeSize, {
|
|
@@ -81,6 +81,7 @@ class InlineFootnoteView extends base_node_view_1.BaseNodeView {
|
|
|
81
81
|
if (footnotesElement) {
|
|
82
82
|
const tablesFootnoteLabels = (0, footnotes_utils_1.buildTableFootnoteLabels)(tableElement.node);
|
|
83
83
|
footnotes = (0, prosemirror_utils_1.findChildrenByType)(footnotesElement, transform_1.schema.nodes.footnote)
|
|
84
|
+
.filter(({ node }) => !(0, track_changes_utils_1.isDeleted)(node) && !(0, track_changes_utils_1.isRejectedInsert)(node))
|
|
84
85
|
.map(({ node }) => ({
|
|
85
86
|
node: node,
|
|
86
87
|
index: tablesFootnoteLabels.get(node.attrs.id),
|
package/dist/es/commands.js
CHANGED
|
@@ -469,6 +469,15 @@ export const ignoreAtomBlockNodeBackward = (state, dispatch, view) => {
|
|
|
469
469
|
}
|
|
470
470
|
return node.isBlock && node.isAtom;
|
|
471
471
|
};
|
|
472
|
+
export const ignoreMetaNodeBackspaceCommand = (state) => {
|
|
473
|
+
const { selection } = state;
|
|
474
|
+
if (!isNodeSelection(selection)) {
|
|
475
|
+
return false;
|
|
476
|
+
}
|
|
477
|
+
return (selection.node.type === schema.nodes.keyword_group ||
|
|
478
|
+
selection.node.type === schema.nodes.affiliations ||
|
|
479
|
+
selection.node.type === schema.nodes.contributors);
|
|
480
|
+
};
|
|
472
481
|
const findCutAfter = ($pos) => {
|
|
473
482
|
if (!$pos.parent.type.spec.isolating) {
|
|
474
483
|
for (let i = $pos.depth - 1; i >= 0; i--) {
|
|
@@ -713,8 +722,7 @@ export const insertTableFootnote = (node, position, view, inlineFootnote) => {
|
|
|
713
722
|
else {
|
|
714
723
|
const inlineFootnotes = findChildrenByType(node, schema.nodes.inline_footnote);
|
|
715
724
|
footnoteIndex =
|
|
716
|
-
inlineFootnotes.filter(({ pos }) => position + pos <= insertedAt).length +
|
|
717
|
-
1;
|
|
725
|
+
inlineFootnotes.filter(({ pos }) => !isRejectedInsert(node) && position + pos <= insertedAt).length + 1;
|
|
718
726
|
const inlineFootnoteNode = state.schema.nodes.inline_footnote.create({
|
|
719
727
|
rids: [footnote.attrs.id],
|
|
720
728
|
contents: footnoteIndex === -1 ? inlineFootnotes.length : footnoteIndex,
|
package/dist/es/keys/misc.js
CHANGED
|
@@ -18,9 +18,9 @@ import { chainCommands, exitCode, joinDown, joinUp, lift, toggleMark, wrapIn, }
|
|
|
18
18
|
import { redo, undo } from 'prosemirror-history';
|
|
19
19
|
import { undoInputRule } from 'prosemirror-inputrules';
|
|
20
20
|
import { goToNextCell } from 'prosemirror-tables';
|
|
21
|
-
import { ignoreAtomBlockNodeBackward, ignoreAtomBlockNodeForward, insertBlock, insertBreak, insertCrossReference, insertInlineCitation, insertInlineEquation, insertSection, selectAllIsolating, } from '../commands';
|
|
21
|
+
import { ignoreAtomBlockNodeBackward, ignoreAtomBlockNodeForward, ignoreMetaNodeBackspaceCommand, insertBlock, insertBreak, insertCrossReference, insertInlineCitation, insertInlineEquation, insertSection, selectAllIsolating, } from '../commands';
|
|
22
22
|
const customKeymap = {
|
|
23
|
-
Backspace: chainCommands(undoInputRule, ignoreAtomBlockNodeBackward),
|
|
23
|
+
Backspace: chainCommands(undoInputRule, ignoreAtomBlockNodeBackward, ignoreMetaNodeBackspaceCommand),
|
|
24
24
|
Delete: ignoreAtomBlockNodeForward,
|
|
25
25
|
Tab: goToNextCell(1),
|
|
26
26
|
'Mod-z': undo,
|
|
@@ -201,6 +201,7 @@ export class ContextMenu {
|
|
|
201
201
|
const tablesFootnoteLabels = buildTableFootnoteLabels(this.node);
|
|
202
202
|
const footnotesWithPos = findChildrenByType(footnotesElementWithPos.node, schema.nodes.footnote);
|
|
203
203
|
const footnotes = footnotesWithPos
|
|
204
|
+
.filter(({ node }) => !isDeleted(node) && !isRejectedInsert(node))
|
|
204
205
|
.map(({ node }) => ({
|
|
205
206
|
node: node,
|
|
206
207
|
index: tablesFootnoteLabels.get(node.attrs.id),
|
|
@@ -221,7 +222,8 @@ export class ContextMenu {
|
|
|
221
222
|
this.view.state.doc
|
|
222
223
|
.slice(this.getPos(), insertedAt)
|
|
223
224
|
.content.descendants((node) => {
|
|
224
|
-
if (node.type === schema.nodes.inline_footnote
|
|
225
|
+
if (node.type === schema.nodes.inline_footnote &&
|
|
226
|
+
!isRejectedInsert(node)) {
|
|
225
227
|
inlineFootnoteIndex++;
|
|
226
228
|
return false;
|
|
227
229
|
}
|
|
@@ -47,11 +47,17 @@ export default (props) => {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
const hasCommentChange = !!tr.steps.find((s) => {
|
|
50
|
-
var _a, _b;
|
|
50
|
+
var _a, _b, _c, _d;
|
|
51
51
|
if (s instanceof ReplaceStep) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
if (s.slice.size > 0) {
|
|
53
|
+
return (((_a = newState.doc.nodeAt(s.from + 1)) === null || _a === void 0 ? void 0 : _a.type) ===
|
|
54
|
+
schema.nodes.comment ||
|
|
55
|
+
((_b = newState.doc.nodeAt(s.from)) === null || _b === void 0 ? void 0 : _b.type) ===
|
|
56
|
+
schema.nodes.highlight_marker);
|
|
57
|
+
}
|
|
58
|
+
return (((_c = oldState.doc.nodeAt(s.from)) === null || _c === void 0 ? void 0 : _c.type) === schema.nodes.comment ||
|
|
59
|
+
((_d = oldState.doc.nodeAt(s.from)) === null || _d === void 0 ? void 0 : _d.type) ===
|
|
60
|
+
schema.nodes.highlight_marker);
|
|
55
61
|
}
|
|
56
62
|
});
|
|
57
63
|
if (hasCommentChange) {
|
|
@@ -17,11 +17,13 @@ import { skipTracking } from '@manuscripts/track-changes-plugin';
|
|
|
17
17
|
import { isFootnoteNode, schema, } from '@manuscripts/transform';
|
|
18
18
|
import { Fragment } from 'prosemirror-model';
|
|
19
19
|
import { findChildren, findChildrenByType, findParentNodeClosestToPos, } from 'prosemirror-utils';
|
|
20
|
+
import { isRejectedInsert } from '../../lib/track-changes-utils';
|
|
20
21
|
export const findTableInlineFootnoteIds = ($pos) => {
|
|
21
22
|
var _a;
|
|
22
23
|
const tableElement = (_a = findParentNodeClosestToPos($pos, (node) => node.type === schema.nodes.table_element)) === null || _a === void 0 ? void 0 : _a.node.firstChild;
|
|
23
24
|
return new Set(tableElement
|
|
24
25
|
? findChildren(tableElement, (node) => node.type === schema.nodes.inline_footnote)
|
|
26
|
+
.filter(({ node }) => !isRejectedInsert(node))
|
|
25
27
|
.map(({ node }) => node.attrs.rids)
|
|
26
28
|
.flat()
|
|
27
29
|
: []);
|
|
@@ -44,6 +46,7 @@ export const buildTableFootnoteLabels = (node) => {
|
|
|
44
46
|
]));
|
|
45
47
|
let index = 0;
|
|
46
48
|
findChildrenByType(node, schema.nodes.inline_footnote)
|
|
49
|
+
.filter(({ node }) => !isRejectedInsert(node))
|
|
47
50
|
.map(({ node }) => node.attrs.rids)
|
|
48
51
|
.flat()
|
|
49
52
|
.map((rid) => {
|
|
@@ -75,7 +78,9 @@ export const orderTableFootnotes = (tr, footnotesElementWithPos, position) => {
|
|
|
75
78
|
};
|
|
76
79
|
export const updateTableInlineFootnoteLabels = (tr, table) => {
|
|
77
80
|
const labels = buildTableFootnoteLabels(table.node);
|
|
78
|
-
findChildrenByType(table.node, schema.nodes.inline_footnote)
|
|
81
|
+
findChildrenByType(table.node, schema.nodes.inline_footnote)
|
|
82
|
+
.filter(({ node }) => !isRejectedInsert(node))
|
|
83
|
+
.map(({ node, pos }) => {
|
|
79
84
|
const contents = node.attrs.rids
|
|
80
85
|
.map((rid) => labels.get(rid))
|
|
81
86
|
.join(',');
|
|
@@ -86,9 +91,9 @@ export const updateTableInlineFootnoteLabels = (tr, table) => {
|
|
|
86
91
|
});
|
|
87
92
|
return tr;
|
|
88
93
|
};
|
|
89
|
-
export const getInlineFootnotes = (id,
|
|
94
|
+
export const getInlineFootnotes = (id, targetNode) => {
|
|
90
95
|
const inlineFootnotes = [];
|
|
91
|
-
|
|
96
|
+
targetNode.descendants((node, pos) => {
|
|
92
97
|
var _a;
|
|
93
98
|
if (node.type === schema.nodes.inline_footnote) {
|
|
94
99
|
const footnote = node;
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
import { isFootnoteNode, isInlineFootnoteNode, schema, } from '@manuscripts/transform';
|
|
17
17
|
import { isEqual } from 'lodash';
|
|
18
18
|
import { NodeSelection, Plugin, PluginKey } from 'prosemirror-state';
|
|
19
|
-
import { findParentNodeClosestToPos, findParentNodeOfType,
|
|
19
|
+
import { findParentNodeClosestToPos, findParentNodeOfType, } from 'prosemirror-utils';
|
|
20
20
|
import { Decoration, DecorationSet } from 'prosemirror-view';
|
|
21
21
|
import { alertIcon, deleteIcon } from '../../assets';
|
|
22
22
|
import { DeleteFootnoteDialog, } from '../../components/views/DeleteFootnoteDialog';
|
|
@@ -65,11 +65,20 @@ export const uncitedFootnoteWidget = () => () => {
|
|
|
65
65
|
element.innerHTML = alertIcon;
|
|
66
66
|
return element;
|
|
67
67
|
};
|
|
68
|
-
const deleteFootnoteWidget = (node, props,
|
|
68
|
+
const deleteFootnoteWidget = (node, props, id, tableElement) => (view, getPos) => {
|
|
69
69
|
const deleteBtn = document.createElement('span');
|
|
70
70
|
deleteBtn.className = 'delete-icon';
|
|
71
71
|
deleteBtn.innerHTML = deleteIcon;
|
|
72
|
-
|
|
72
|
+
const parentType = tableElement ? 'table ' : '';
|
|
73
|
+
const footnote = {
|
|
74
|
+
type: node.type === schema.nodes.footnote
|
|
75
|
+
? `${parentType}footnote`
|
|
76
|
+
: 'table general note',
|
|
77
|
+
message: node.type === schema.nodes.footnote
|
|
78
|
+
? `This action will entirely remove the ${parentType}footnote from the list because it will no longer be used.`
|
|
79
|
+
: 'This action will entirely remove the table general note.',
|
|
80
|
+
};
|
|
81
|
+
deleteBtn.addEventListener('mousedown', () => {
|
|
73
82
|
const handleDelete = () => {
|
|
74
83
|
let tr = view.state.tr;
|
|
75
84
|
const pos = getPos();
|
|
@@ -87,7 +96,8 @@ const deleteFootnoteWidget = (node, props, footnoteType, footnoteMessage, id, ta
|
|
|
87
96
|
}
|
|
88
97
|
}
|
|
89
98
|
if (node.type === schema.nodes.footnote && pos) {
|
|
90
|
-
const
|
|
99
|
+
const targetNode = tableElement ? tableElement.node : view.state.doc;
|
|
100
|
+
const inlineFootnotes = getInlineFootnotes(id, targetNode);
|
|
91
101
|
const nodeWithPos = findParentNodeClosestToPos(tr.doc.resolve(pos), (node) => node.type === schema.nodes.footnote);
|
|
92
102
|
if (nodeWithPos) {
|
|
93
103
|
const { pos: fnPos, node: fnNode } = nodeWithPos;
|
|
@@ -96,13 +106,13 @@ const deleteFootnoteWidget = (node, props, footnoteType, footnoteMessage, id, ta
|
|
|
96
106
|
if (inlineFootnotes) {
|
|
97
107
|
tr = view.state.tr;
|
|
98
108
|
inlineFootnotes.forEach((footnote) => {
|
|
99
|
-
const pos = footnote.pos + tableElement.pos;
|
|
109
|
+
const pos = footnote.pos + (tableElement ? tableElement.pos + 1 : 0);
|
|
100
110
|
if (footnote.node.attrs.rids.length > 1) {
|
|
101
111
|
const updatedRids = footnote.node.attrs.rids.filter((rid) => rid !== id);
|
|
102
112
|
tr.setNodeMarkup(tr.mapping.map(pos + 1), undefined, Object.assign(Object.assign({}, node.attrs), { rids: updatedRids }));
|
|
103
113
|
}
|
|
104
114
|
else {
|
|
105
|
-
tr.delete(tr.mapping.map(pos
|
|
115
|
+
tr.delete(tr.mapping.map(pos), tr.mapping.map(pos + footnote.node.nodeSize));
|
|
106
116
|
}
|
|
107
117
|
});
|
|
108
118
|
}
|
|
@@ -110,8 +120,8 @@ const deleteFootnoteWidget = (node, props, footnoteType, footnoteMessage, id, ta
|
|
|
110
120
|
view.dispatch(tr);
|
|
111
121
|
};
|
|
112
122
|
const componentProps = {
|
|
113
|
-
footnoteType:
|
|
114
|
-
footnoteMessage:
|
|
123
|
+
footnoteType: footnote.type,
|
|
124
|
+
footnoteMessage: footnote.message,
|
|
115
125
|
handleDelete: handleDelete,
|
|
116
126
|
};
|
|
117
127
|
ReactSubView(Object.assign(Object.assign({}, props), { dispatch: view.dispatch }), DeleteFootnoteDialog, componentProps, node, () => getPos(), view);
|
|
@@ -150,19 +160,30 @@ export default (props) => {
|
|
|
150
160
|
props: {
|
|
151
161
|
decorations: (state) => {
|
|
152
162
|
const decorations = [];
|
|
153
|
-
const
|
|
163
|
+
const tableElementFooter = findParentNodeOfType(schema.nodes.table_element_footer)(state.selection);
|
|
154
164
|
const tableElement = findParentNodeOfType(schema.nodes.table_element)(state.selection);
|
|
155
|
-
|
|
165
|
+
const footnote = findParentNodeOfType(schema.nodes.footnote)(state.selection);
|
|
166
|
+
let targetNode;
|
|
167
|
+
if (footnote) {
|
|
168
|
+
targetNode = footnote;
|
|
169
|
+
}
|
|
170
|
+
else if (tableElementFooter) {
|
|
171
|
+
targetNode = tableElementFooter;
|
|
172
|
+
}
|
|
173
|
+
const can = props.getCapabilities();
|
|
174
|
+
if (targetNode && can.editArticle) {
|
|
156
175
|
const parent = findParentNodeWithIdValue(state.selection);
|
|
157
176
|
if (parent) {
|
|
158
177
|
decorations.push(Decoration.node(parent.pos, parent.pos + parent.node.nodeSize, {
|
|
159
178
|
class: 'footnote-selected',
|
|
160
179
|
}));
|
|
180
|
+
decorations.push(Decoration.widget(targetNode.pos + (footnote ? 1 : 2), deleteFootnoteWidget(targetNode.node, props, targetNode.node.attrs.id, tableElement), {
|
|
181
|
+
key: targetNode.node.attrs.id,
|
|
182
|
+
}));
|
|
161
183
|
}
|
|
162
184
|
}
|
|
163
185
|
const { labels } = footnotesKey.getState(state);
|
|
164
186
|
let tableInlineFootnoteIds = undefined;
|
|
165
|
-
const can = props.getCapabilities();
|
|
166
187
|
state.doc.descendants((node, pos, parent) => {
|
|
167
188
|
var _a;
|
|
168
189
|
if (isFootnoteNode(node)) {
|
|
@@ -183,35 +204,6 @@ export default (props) => {
|
|
|
183
204
|
decorations.push(Decoration.widget(pos + node.nodeSize - 1, uncitedFootnoteWidget()));
|
|
184
205
|
}
|
|
185
206
|
}
|
|
186
|
-
if (can.editArticle) {
|
|
187
|
-
if (tableElement) {
|
|
188
|
-
const footnote = (() => {
|
|
189
|
-
switch (node.type) {
|
|
190
|
-
case schema.nodes.footnote:
|
|
191
|
-
return {
|
|
192
|
-
type: 'table footnote',
|
|
193
|
-
message: 'This action will entirely remove the table footnote from the list because it will no longer be used.',
|
|
194
|
-
};
|
|
195
|
-
default:
|
|
196
|
-
return {
|
|
197
|
-
type: 'table general note',
|
|
198
|
-
message: 'This action will entirely remove the table general note.',
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
})();
|
|
202
|
-
if (node.type === schema.nodes.footnote) {
|
|
203
|
-
decorations.push(Decoration.widget(pos + 2, deleteFootnoteWidget(node, props, footnote.type, footnote.message, node.attrs.id, tableElement), {
|
|
204
|
-
key: node.attrs.id,
|
|
205
|
-
}));
|
|
206
|
-
}
|
|
207
|
-
else if (node.type === schema.nodes.paragraph &&
|
|
208
|
-
(parent === null || parent === void 0 ? void 0 : parent.type) === schema.nodes.table_element_footer) {
|
|
209
|
-
decorations.push(Decoration.widget(pos + 1, deleteFootnoteWidget(parent, props, footnote.type, footnote.message, parent.attrs.id, tableElement), {
|
|
210
|
-
key: parent.attrs.id,
|
|
211
|
-
}));
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
207
|
if (node.type === schema.nodes.footnotes_element) {
|
|
216
208
|
if ((parent === null || parent === void 0 ? void 0 : parent.type) === schema.nodes.table_element_footer) {
|
|
217
209
|
decorations.push(Decoration.node(pos, pos + node.nodeSize, {
|
|
@@ -17,7 +17,7 @@ import { TableFootnotesSelector, } from '@manuscripts/style-guide';
|
|
|
17
17
|
import { schema, } from '@manuscripts/transform';
|
|
18
18
|
import { findChildrenByType, findParentNodeClosestToPos, } from 'prosemirror-utils';
|
|
19
19
|
import { insertTableFootnote } from '../commands';
|
|
20
|
-
import { getChangeClasses, isDeleted, } from '../lib/track-changes-utils';
|
|
20
|
+
import { getChangeClasses, isDeleted, isRejectedInsert, } from '../lib/track-changes-utils';
|
|
21
21
|
import { buildTableFootnoteLabels } from '../plugins/footnotes/footnotes-utils';
|
|
22
22
|
import { BaseNodeView } from './base_node_view';
|
|
23
23
|
import { createNodeView } from './creators';
|
|
@@ -75,6 +75,7 @@ export class InlineFootnoteView extends BaseNodeView {
|
|
|
75
75
|
if (footnotesElement) {
|
|
76
76
|
const tablesFootnoteLabels = buildTableFootnoteLabels(tableElement.node);
|
|
77
77
|
footnotes = findChildrenByType(footnotesElement, schema.nodes.footnote)
|
|
78
|
+
.filter(({ node }) => !isDeleted(node) && !isRejectedInsert(node))
|
|
78
79
|
.map(({ node }) => ({
|
|
79
80
|
node: node,
|
|
80
81
|
index: tablesFootnoteLabels.get(node.attrs.id),
|
package/dist/types/commands.d.ts
CHANGED
|
@@ -48,6 +48,7 @@ export declare const ifInTableBody: (command: (state: ManuscriptEditorState) =>
|
|
|
48
48
|
export declare const isAtStartOfTextBlock: (state: ManuscriptEditorState, $cursor: ResolvedPos, view?: ManuscriptEditorView) => boolean;
|
|
49
49
|
export declare const isTextSelection: (selection: Selection) => selection is TextSelection;
|
|
50
50
|
export declare const ignoreAtomBlockNodeBackward: (state: ManuscriptEditorState, dispatch?: Dispatch, view?: ManuscriptEditorView) => boolean;
|
|
51
|
+
export declare const ignoreMetaNodeBackspaceCommand: (state: ManuscriptEditorState) => boolean;
|
|
51
52
|
export declare const isAtEndOfTextBlock: (state: ManuscriptEditorState, $cursor: ResolvedPos, view?: ManuscriptEditorView) => boolean;
|
|
52
53
|
export declare const ignoreAtomBlockNodeForward: (state: ManuscriptEditorState, dispatch?: Dispatch, view?: ManuscriptEditorView) => boolean;
|
|
53
54
|
export declare const selectAllIsolating: (state: ManuscriptEditorState, dispatch?: Dispatch) => boolean;
|
|
@@ -26,5 +26,5 @@ interface InlineFootnote {
|
|
|
26
26
|
node: InlineFootnoteNode;
|
|
27
27
|
pos: number;
|
|
28
28
|
}
|
|
29
|
-
export declare const getInlineFootnotes: (id: string,
|
|
29
|
+
export declare const getInlineFootnotes: (id: string, targetNode: ManuscriptNode) => InlineFootnote[];
|
|
30
30
|
export {};
|
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.9.
|
|
4
|
+
"version": "1.9.5",
|
|
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.7",
|
|
33
33
|
"@manuscripts/library": "^1.3.6",
|
|
34
|
-
"@manuscripts/style-guide": "1.12.
|
|
34
|
+
"@manuscripts/style-guide": "1.12.3",
|
|
35
35
|
"@manuscripts/track-changes-plugin": "1.7.10",
|
|
36
|
-
"@manuscripts/transform": "2.3.
|
|
36
|
+
"@manuscripts/transform": "2.3.3",
|
|
37
37
|
"astrocite-eutils": "^0.16.4",
|
|
38
38
|
"mathjax-full": "^3.2.2",
|
|
39
39
|
"codemirror": "^5.58.1",
|
package/styles/Editor.css
CHANGED
|
@@ -959,18 +959,19 @@
|
|
|
959
959
|
.ProseMirror .table-footnotes-element {
|
|
960
960
|
counter-reset: table_footnote;
|
|
961
961
|
}
|
|
962
|
-
.
|
|
963
|
-
display: none;
|
|
962
|
+
.delete-icon {
|
|
964
963
|
position: absolute;
|
|
965
964
|
right: -20px;
|
|
966
965
|
top: -13px;
|
|
967
966
|
cursor: pointer;
|
|
968
967
|
z-index: 1;
|
|
969
968
|
}
|
|
970
|
-
.
|
|
969
|
+
.delete-icon:hover svg path {
|
|
971
970
|
fill: #353535;
|
|
972
971
|
}
|
|
973
|
-
.ProseMirror .table-footnotes-element > div
|
|
972
|
+
.ProseMirror .table-footnotes-element > div,
|
|
973
|
+
.ProseMirror .block-footnotes_element > .block > div
|
|
974
|
+
{
|
|
974
975
|
position: relative;
|
|
975
976
|
}
|
|
976
977
|
|
|
@@ -990,29 +991,24 @@
|
|
|
990
991
|
margin-top: 0px;
|
|
991
992
|
}
|
|
992
993
|
|
|
993
|
-
.ProseMirror .
|
|
994
|
+
.ProseMirror .footnote-selected, .table-footer > div:has(> p.footnote-selected) > p {
|
|
994
995
|
background-color: #f2fbfc;
|
|
995
996
|
padding: 4px;
|
|
996
997
|
}
|
|
997
998
|
|
|
998
|
-
.ProseMirror .table-footer .footnote-selected .delete-icon ,.ProseMirror .table-footer .footnote-selected .deleted.rejected .delete-icon {
|
|
999
|
-
display: block;
|
|
1000
|
-
}
|
|
1001
999
|
.table-footer > div > p {
|
|
1002
1000
|
padding-bottom: 10px;
|
|
1003
1001
|
}
|
|
1004
1002
|
|
|
1005
|
-
.ProseMirror .table-footnotes-element .footnote-selected
|
|
1003
|
+
.ProseMirror .table-footnotes-element .footnote-selected,
|
|
1004
|
+
.ProseMirror .block-footnotes_element .footnote-selected
|
|
1005
|
+
{
|
|
1006
1006
|
border: 1px solid #bce7f6;
|
|
1007
1007
|
}
|
|
1008
1008
|
.table-footer > div:has(> p.footnote-selected) > p {
|
|
1009
1009
|
border-left: 1px solid #bce7f6;
|
|
1010
1010
|
border-right: 1px solid #bce7f6;
|
|
1011
1011
|
}
|
|
1012
|
-
.table-footer > div:has(> p.footnote-selected) > p:first-child .delete-icon {
|
|
1013
|
-
z-index: 2;
|
|
1014
|
-
display: block;
|
|
1015
|
-
}
|
|
1016
1012
|
.table-footer > div:has(> p.footnote-selected) > p:first-child {
|
|
1017
1013
|
border-top: 1px solid #bce7f6;
|
|
1018
1014
|
position: relative;
|