@manuscripts/body-editor 3.16.3 → 3.17.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/lib/context-menu.js +28 -11
- package/dist/cjs/lib/popper.js +15 -1
- package/dist/cjs/lib/position-menu.js +175 -100
- package/dist/cjs/plugins/detect-inconsistency/index.js +6 -4
- package/dist/cjs/plugins/persist.js +3 -0
- package/dist/cjs/versions.js +1 -1
- package/dist/cjs/views/box_element.js +23 -1
- package/dist/cjs/views/caption_title.js +1 -1
- package/dist/cjs/views/image_element.js +7 -62
- package/dist/cjs/views/pullquote_element.js +23 -1
- package/dist/cjs/views/table_element.js +23 -1
- package/dist/es/lib/context-menu.js +29 -12
- package/dist/es/lib/popper.js +15 -1
- package/dist/es/lib/position-menu.js +173 -91
- package/dist/es/plugins/detect-inconsistency/index.js +6 -4
- package/dist/es/plugins/persist.js +3 -0
- package/dist/es/versions.js +1 -1
- package/dist/es/views/box_element.js +23 -1
- package/dist/es/views/caption_title.js +1 -1
- package/dist/es/views/image_element.js +7 -62
- package/dist/es/views/pullquote_element.js +23 -1
- package/dist/es/views/table_element.js +23 -1
- package/dist/types/lib/popper.d.ts +4 -2
- package/dist/types/lib/position-menu.d.ts +36 -11
- package/dist/types/versions.d.ts +1 -1
- package/dist/types/views/box_element.d.ts +6 -0
- package/dist/types/views/image_element.d.ts +2 -9
- package/dist/types/views/pullquote_element.d.ts +6 -0
- package/dist/types/views/table_element.d.ts +6 -0
- package/package.json +1 -1
- package/src/lib/context-menu.ts +42 -21
- package/src/lib/popper.ts +18 -1
- package/src/lib/position-menu.ts +242 -137
- package/src/plugins/detect-inconsistency/index.ts +6 -4
- package/src/plugins/persist.ts +3 -0
- package/src/versions.ts +1 -1
- package/src/views/box_element.ts +34 -1
- package/src/views/caption_title.ts +1 -1
- package/src/views/image_element.ts +12 -89
- package/src/views/pullquote_element.ts +33 -1
- package/src/views/table_element.ts +34 -1
- package/styles/AdvancedEditor.css +5 -8
- package/styles/Editor.css +9 -5
|
@@ -21,6 +21,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
21
21
|
exports.TableElementView = void 0;
|
|
22
22
|
const block_view_1 = __importDefault(require("./block_view"));
|
|
23
23
|
const creators_1 = require("./creators");
|
|
24
|
+
const position_menu_1 = require("../lib/position-menu");
|
|
24
25
|
class TableElementView extends block_view_1.default {
|
|
25
26
|
constructor() {
|
|
26
27
|
super(...arguments);
|
|
@@ -29,9 +30,30 @@ class TableElementView extends block_view_1.default {
|
|
|
29
30
|
this.contentDOM = document.createElement('figure');
|
|
30
31
|
this.contentDOM.classList.add('block');
|
|
31
32
|
this.contentDOM.setAttribute('id', this.node.attrs.id);
|
|
32
|
-
this.
|
|
33
|
+
this.container = document.createElement('div');
|
|
34
|
+
this.container.classList.add('container');
|
|
35
|
+
this.container.appendChild(this.contentDOM);
|
|
36
|
+
this.dom.appendChild(this.container);
|
|
33
37
|
};
|
|
34
38
|
}
|
|
39
|
+
updateContents() {
|
|
40
|
+
super.updateContents();
|
|
41
|
+
this.addTools();
|
|
42
|
+
}
|
|
43
|
+
addTools() {
|
|
44
|
+
this.addPositionMenu();
|
|
45
|
+
}
|
|
46
|
+
addPositionMenu() {
|
|
47
|
+
if (!this.positionMenu) {
|
|
48
|
+
this.positionMenu = new position_menu_1.HorizontalPositionMenu(this, this.updateHorizontalPosition, this.container);
|
|
49
|
+
}
|
|
50
|
+
this.positionMenu.create();
|
|
51
|
+
}
|
|
52
|
+
updateHorizontalPosition(horizontalPosition) {
|
|
53
|
+
const tr = this.view.state.tr;
|
|
54
|
+
tr.setNodeAttribute(this.getPos(), 'type', horizontalPosition);
|
|
55
|
+
this.view.dispatch(tr);
|
|
56
|
+
}
|
|
35
57
|
}
|
|
36
58
|
exports.TableElementView = TableElementView;
|
|
37
59
|
exports.default = (0, creators_1.createNodeView)(TableElementView);
|
|
@@ -22,7 +22,7 @@ import { createElement } from 'react';
|
|
|
22
22
|
import { renderToStaticMarkup } from 'react-dom/server';
|
|
23
23
|
import { addNodeComment, createBlock, findPosBeforeFirstSubsection, insertGeneralTableFootnote, insertInlineTableFootnote, } from '../commands';
|
|
24
24
|
import { PopperManager } from './popper';
|
|
25
|
-
import {
|
|
25
|
+
import { HorizontalPositionMenu } from './position-menu';
|
|
26
26
|
import { templateAllows } from './template';
|
|
27
27
|
import { getMatchingChild, isChildOfNodeTypes, isSelectionInNode, } from './utils';
|
|
28
28
|
const popper = new PopperManager();
|
|
@@ -32,8 +32,15 @@ const readonlyTypes = [
|
|
|
32
32
|
schema.nodes.bibliography_section,
|
|
33
33
|
schema.nodes.footnotes_section,
|
|
34
34
|
];
|
|
35
|
-
const
|
|
36
|
-
|
|
35
|
+
const getBoxElementOfSectionTitle = ($pos, node) => {
|
|
36
|
+
if (isSectionTitleNode(node)) {
|
|
37
|
+
const parent = $pos.node($pos.depth - 1);
|
|
38
|
+
if (parent.type === schema.nodes.box_element) {
|
|
39
|
+
return parent;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
};
|
|
37
44
|
export const sectionLevel = (depth) => {
|
|
38
45
|
switch (depth) {
|
|
39
46
|
case 1:
|
|
@@ -153,18 +160,28 @@ export class ContextMenu {
|
|
|
153
160
|
const menu = document.createElement('div');
|
|
154
161
|
menu.className = 'menu';
|
|
155
162
|
const $pos = this.resolvePos();
|
|
156
|
-
const
|
|
157
|
-
const type =
|
|
158
|
-
|
|
159
|
-
|
|
163
|
+
const boxParent = getBoxElementOfSectionTitle($pos, this.node);
|
|
164
|
+
const type = boxParent ? schema.nodes.box_element : this.node.type;
|
|
165
|
+
const positionableTypes = [
|
|
166
|
+
schema.nodes.figure_element,
|
|
167
|
+
schema.nodes.image_element,
|
|
168
|
+
schema.nodes.box_element,
|
|
169
|
+
schema.nodes.pullquote_element,
|
|
170
|
+
schema.nodes.table_element,
|
|
171
|
+
];
|
|
172
|
+
let nodeBase = this.node;
|
|
173
|
+
if (positionableTypes.includes(type)) {
|
|
160
174
|
const figure = getMatchingChild(this.node, (node) => node.type === schema.nodes.figure);
|
|
161
175
|
if (figure) {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
menu.appendChild(submenu);
|
|
176
|
+
nodeBase = figure;
|
|
177
|
+
}
|
|
178
|
+
if (boxParent) {
|
|
179
|
+
nodeBase = boxParent;
|
|
167
180
|
}
|
|
181
|
+
const submenuOptions = HorizontalPositionMenu.createPositionOptions(schema.nodes[nodeBase.type.name], nodeBase, nodeBase.attrs.type, this.view, () => popper.destroy());
|
|
182
|
+
const submenuLabel = 'Position';
|
|
183
|
+
const submenu = this.createSubmenu(submenuLabel, submenuOptions);
|
|
184
|
+
menu.appendChild(submenu);
|
|
168
185
|
}
|
|
169
186
|
if (type === schema.nodes.list) {
|
|
170
187
|
menu.appendChild(this.createMenuSection((section) => {
|
package/dist/es/lib/popper.js
CHANGED
|
@@ -19,9 +19,10 @@ export class PopperManager {
|
|
|
19
19
|
constructor() {
|
|
20
20
|
this.isActive = () => !!this.activePopper;
|
|
21
21
|
}
|
|
22
|
-
show(target, contents, placement = 'bottom', showArrow = true, modifiers = [], autoFocus = true) {
|
|
22
|
+
show(target, contents, placement = 'bottom', showArrow = true, modifiers = [], autoFocus = true, onDestroy = undefined) {
|
|
23
23
|
this.destroy();
|
|
24
24
|
this.triggerElement = target;
|
|
25
|
+
this.destructionListener = onDestroy;
|
|
25
26
|
window.requestAnimationFrame(() => {
|
|
26
27
|
const container = document.createElement('div');
|
|
27
28
|
container.className = 'popper';
|
|
@@ -91,6 +92,8 @@ export class PopperManager {
|
|
|
91
92
|
destroy() {
|
|
92
93
|
if (this.activePopper) {
|
|
93
94
|
this.removeContainerClass(this.activePopper.state.elements.reference);
|
|
95
|
+
this.destructionListener?.(this.activePopper);
|
|
96
|
+
this.destructionListener = undefined;
|
|
94
97
|
this.activePopper.destroy();
|
|
95
98
|
this.activePopper.state.elements.popper.remove();
|
|
96
99
|
if (this.handleDocumentClick) {
|
|
@@ -108,6 +111,17 @@ export class PopperManager {
|
|
|
108
111
|
this.activePopper.update();
|
|
109
112
|
}
|
|
110
113
|
}
|
|
114
|
+
replaceContent(newContent) {
|
|
115
|
+
if (this.container && this.activePopper) {
|
|
116
|
+
const arrow = this.container.querySelector('.popper-arrow');
|
|
117
|
+
this.container.innerHTML = '';
|
|
118
|
+
if (arrow) {
|
|
119
|
+
this.container.appendChild(arrow);
|
|
120
|
+
}
|
|
121
|
+
this.container.appendChild(newContent);
|
|
122
|
+
this.activePopper.update();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
111
125
|
focusInput(container, autoFocus = true) {
|
|
112
126
|
const input = container.querySelector('input');
|
|
113
127
|
if (input) {
|
|
@@ -15,100 +15,182 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { ContextMenu } from '@manuscripts/style-guide';
|
|
17
17
|
import { imageDefaultIcon, imageLeftIcon, imageRightIcon } from '../icons';
|
|
18
|
-
import {
|
|
19
|
-
import ReactSubView from '../views/ReactSubView';
|
|
18
|
+
import { createSubViewAsync } from '../views/ReactSubView';
|
|
20
19
|
import { handleEnterKey } from './navigation-utils';
|
|
21
20
|
import { updateNodeAttrs } from './view';
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
element.removeAttribute('data-alignment');
|
|
83
|
-
break;
|
|
21
|
+
export var HorizontalPositions;
|
|
22
|
+
(function (HorizontalPositions) {
|
|
23
|
+
HorizontalPositions["left"] = "half-left";
|
|
24
|
+
HorizontalPositions["right"] = "half-right";
|
|
25
|
+
HorizontalPositions["default"] = "";
|
|
26
|
+
})(HorizontalPositions || (HorizontalPositions = {}));
|
|
27
|
+
export class HorizontalPositionMenu {
|
|
28
|
+
constructor(parent, onChange, location, getPositionSource) {
|
|
29
|
+
this.menuOpen = false;
|
|
30
|
+
this.posMenuSelector = 'position-menu';
|
|
31
|
+
this.buttonClass = 'position-menu-button';
|
|
32
|
+
const preSource = getPositionSource?.() || parent.node;
|
|
33
|
+
if (typeof preSource.attrs.type === 'undefined') {
|
|
34
|
+
console.error("This node doesn't support horizontal alignment");
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
this.getPositionSource = getPositionSource;
|
|
38
|
+
this.location = location || parent.dom;
|
|
39
|
+
this.onChange = onChange.bind(parent);
|
|
40
|
+
this.parent = parent;
|
|
41
|
+
}
|
|
42
|
+
static createPositionOptions(nodeType, node, currentPosition, view, onComplete) {
|
|
43
|
+
const createAction = (position) => () => {
|
|
44
|
+
onComplete?.();
|
|
45
|
+
updateNodeAttrs(view, nodeType, {
|
|
46
|
+
...node.attrs,
|
|
47
|
+
type: position,
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
return [
|
|
51
|
+
{
|
|
52
|
+
title: 'Left',
|
|
53
|
+
action: createAction(HorizontalPositions.left),
|
|
54
|
+
IconComponent: imageLeftIcon,
|
|
55
|
+
iconName: 'ImageLeft',
|
|
56
|
+
selected: currentPosition === HorizontalPositions.left,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
title: 'Default',
|
|
60
|
+
action: createAction(HorizontalPositions.default),
|
|
61
|
+
IconComponent: imageDefaultIcon,
|
|
62
|
+
iconName: 'ImageDefault',
|
|
63
|
+
selected: !currentPosition || currentPosition === HorizontalPositions.default,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
title: 'Right',
|
|
67
|
+
action: createAction(HorizontalPositions.right),
|
|
68
|
+
IconComponent: imageRightIcon,
|
|
69
|
+
iconName: 'ImageRight',
|
|
70
|
+
selected: currentPosition === HorizontalPositions.right,
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
}
|
|
74
|
+
createPopperMenuPositionOptions(nodeType, node, currentPosition, view, onComplete) {
|
|
75
|
+
return HorizontalPositionMenu.createPositionOptions(nodeType, node, currentPosition, view, onComplete).map((option) => ({
|
|
76
|
+
label: option.title,
|
|
77
|
+
action: option.action,
|
|
78
|
+
icon: option.iconName,
|
|
79
|
+
selected: option.selected,
|
|
80
|
+
}));
|
|
84
81
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
82
|
+
createPositionMenuWrapper(currentPosition, props) {
|
|
83
|
+
const can = props.getCapabilities();
|
|
84
|
+
const positionMenuWrapper = document.createElement('div');
|
|
85
|
+
positionMenuWrapper.classList.add(this.posMenuSelector);
|
|
86
|
+
const positionMenuButton = document.createElement('div');
|
|
87
|
+
positionMenuButton.classList.add(this.buttonClass);
|
|
88
|
+
let icon;
|
|
89
|
+
switch (currentPosition) {
|
|
90
|
+
case HorizontalPositions.left:
|
|
91
|
+
icon = imageLeftIcon;
|
|
92
|
+
break;
|
|
93
|
+
case HorizontalPositions.right:
|
|
94
|
+
icon = imageRightIcon;
|
|
95
|
+
break;
|
|
96
|
+
default:
|
|
97
|
+
icon = imageDefaultIcon;
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
if (icon) {
|
|
101
|
+
positionMenuButton.innerHTML = icon;
|
|
102
|
+
}
|
|
103
|
+
const onClick = () => {
|
|
104
|
+
this.showPositionMenu();
|
|
105
|
+
};
|
|
106
|
+
if (can.editArticle) {
|
|
107
|
+
positionMenuButton.tabIndex = -1;
|
|
108
|
+
positionMenuButton.addEventListener('click', onClick);
|
|
109
|
+
positionMenuButton.addEventListener('keydown', handleEnterKey(onClick));
|
|
110
|
+
}
|
|
111
|
+
if (this.positionMenuWrapper) {
|
|
112
|
+
const button = this.positionMenuWrapper.querySelector('.' + this.buttonClass);
|
|
113
|
+
if (button) {
|
|
114
|
+
this.positionMenuWrapper.removeChild(button);
|
|
115
|
+
this.positionMenuWrapper.appendChild(positionMenuButton);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
positionMenuWrapper.appendChild(positionMenuButton);
|
|
120
|
+
this.positionMenuWrapper = positionMenuWrapper;
|
|
121
|
+
this.location.prepend(this.positionMenuWrapper);
|
|
122
|
+
}
|
|
103
123
|
}
|
|
104
|
-
|
|
105
|
-
|
|
124
|
+
getHorizontalPositionOptions(current, onPick, destroy) {
|
|
125
|
+
const componentProps = {
|
|
126
|
+
actions: [
|
|
127
|
+
{
|
|
128
|
+
label: 'Left',
|
|
129
|
+
action: () => {
|
|
130
|
+
destroy();
|
|
131
|
+
this.menuOpen = false;
|
|
132
|
+
onPick(HorizontalPositions.left);
|
|
133
|
+
},
|
|
134
|
+
icon: 'ImageLeft',
|
|
135
|
+
selected: current === HorizontalPositions.left,
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
label: 'Default',
|
|
139
|
+
action: () => {
|
|
140
|
+
destroy();
|
|
141
|
+
this.menuOpen = false;
|
|
142
|
+
onPick(HorizontalPositions.default);
|
|
143
|
+
},
|
|
144
|
+
icon: 'ImageDefault',
|
|
145
|
+
selected: !current,
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
label: 'Right',
|
|
149
|
+
action: () => {
|
|
150
|
+
destroy();
|
|
151
|
+
this.menuOpen = false;
|
|
152
|
+
onPick(HorizontalPositions.right);
|
|
153
|
+
},
|
|
154
|
+
icon: 'ImageRight',
|
|
155
|
+
selected: current === HorizontalPositions.right,
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
};
|
|
159
|
+
return componentProps;
|
|
160
|
+
}
|
|
161
|
+
showPositionMenu(force = false) {
|
|
162
|
+
const p = this.parent;
|
|
163
|
+
if (this.menuOpen && !force) {
|
|
164
|
+
p.props.popper.destroy();
|
|
165
|
+
this.menuOpen = false;
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const posSource = this.getPositionSource
|
|
169
|
+
? this.getPositionSource()
|
|
170
|
+
: this.parent.node;
|
|
171
|
+
const componentProps = this.getHorizontalPositionOptions(posSource?.attrs.type || HorizontalPositions.default, this.onChange, p.props.popper.destroy.bind(p.props.popper));
|
|
172
|
+
createSubViewAsync(p.props, ContextMenu, componentProps, p.node, p.getPos, p.view, ['context-menu', this.posMenuSelector]).then((content) => {
|
|
173
|
+
if (this.menuOpen && p.props.popper.isActive()) {
|
|
174
|
+
p.props.popper.replaceContent(content);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
p.props.popper.show(this.positionMenuWrapper, content, 'left', false, [], true, () => {
|
|
178
|
+
this.menuOpen = false;
|
|
179
|
+
});
|
|
180
|
+
this.menuOpen = true;
|
|
181
|
+
}
|
|
182
|
+
});
|
|
106
183
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
184
|
+
create() {
|
|
185
|
+
if (!this.parent) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const p = this.parent;
|
|
189
|
+
if (p.props.getCapabilities()?.editArticle) {
|
|
190
|
+
const posSource = this.getPositionSource
|
|
191
|
+
? this.getPositionSource()
|
|
192
|
+
: this.parent.node;
|
|
193
|
+
this.createPositionMenuWrapper(posSource?.attrs.type || HorizontalPositions.default, p.props);
|
|
194
|
+
}
|
|
111
195
|
}
|
|
112
|
-
|
|
113
|
-
return positionMenuWrapper;
|
|
114
|
-
};
|
|
196
|
+
}
|
|
@@ -22,10 +22,12 @@ export default (props) => {
|
|
|
22
22
|
key: detectInconsistencyKey,
|
|
23
23
|
state: {
|
|
24
24
|
init: (_, state) => buildPluginState(state, props, false),
|
|
25
|
-
apply: (tr, value, newState) => {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
apply: (tr, value, _, newState) => {
|
|
26
|
+
const metaValue = tr.getMeta(detectInconsistencyKey);
|
|
27
|
+
const showDecorations = metaValue !== undefined ? metaValue : value.showDecorations;
|
|
28
|
+
if (!tr.docChanged && metaValue === undefined) {
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
29
31
|
return buildPluginState(newState, props, showDecorations);
|
|
30
32
|
},
|
|
31
33
|
},
|
package/dist/es/versions.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = '3.
|
|
1
|
+
export const VERSION = '3.17.0';
|
|
2
2
|
export const MATHJAX_VERSION = '3.2.2';
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import BlockView from './block_view';
|
|
17
17
|
import { createNodeView } from './creators';
|
|
18
|
+
import { HorizontalPositionMenu } from '../lib/position-menu';
|
|
18
19
|
export class BoxElementView extends BlockView {
|
|
19
20
|
constructor() {
|
|
20
21
|
super(...arguments);
|
|
@@ -23,8 +24,29 @@ export class BoxElementView extends BlockView {
|
|
|
23
24
|
this.contentDOM = document.createElement(this.elementType);
|
|
24
25
|
this.contentDOM.className = 'block box-element';
|
|
25
26
|
this.contentDOM.setAttribute('id', this.node.attrs.id);
|
|
26
|
-
this.
|
|
27
|
+
this.container = document.createElement('div');
|
|
28
|
+
this.container.classList.add('container');
|
|
29
|
+
this.container.appendChild(this.contentDOM);
|
|
30
|
+
this.dom.appendChild(this.container);
|
|
27
31
|
};
|
|
28
32
|
}
|
|
33
|
+
updateContents() {
|
|
34
|
+
super.updateContents();
|
|
35
|
+
this.addTools();
|
|
36
|
+
}
|
|
37
|
+
addTools() {
|
|
38
|
+
this.addPositionMenu();
|
|
39
|
+
}
|
|
40
|
+
addPositionMenu() {
|
|
41
|
+
if (!this.positionMenu) {
|
|
42
|
+
this.positionMenu = new HorizontalPositionMenu(this, this.updateHorizontalPosition, this.container);
|
|
43
|
+
}
|
|
44
|
+
this.positionMenu.create();
|
|
45
|
+
}
|
|
46
|
+
updateHorizontalPosition(horizontalPosition) {
|
|
47
|
+
const tr = this.view.state.tr;
|
|
48
|
+
tr.setNodeAttribute(this.getPos(), 'type', horizontalPosition);
|
|
49
|
+
this.view.dispatch(tr);
|
|
50
|
+
}
|
|
29
51
|
}
|
|
30
52
|
export default createNodeView(BoxElementView);
|
|
@@ -24,7 +24,7 @@ export class CaptionTitleView extends BaseNodeView {
|
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
createDOM() {
|
|
27
|
-
this.dom = document.createElement('
|
|
27
|
+
this.dom = document.createElement('div');
|
|
28
28
|
this.dom.className = 'caption-title placeholder';
|
|
29
29
|
this.contentDOM = this.dom;
|
|
30
30
|
}
|
|
@@ -13,21 +13,13 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import { ContextMenu } from '@manuscripts/style-guide';
|
|
17
16
|
import { schema } from '@manuscripts/transform';
|
|
18
17
|
import { deleteIcon, linkIcon } from '../icons';
|
|
19
18
|
import { addInteractionHandlers, createMediaPlaceholder, MediaType, } from '../lib/media';
|
|
20
19
|
import { handleEnterKey } from '../lib/navigation-utils';
|
|
21
|
-
import {
|
|
20
|
+
import { HorizontalPositionMenu } from '../lib/position-menu';
|
|
22
21
|
import BlockView from './block_view';
|
|
23
22
|
import { createNodeView } from './creators';
|
|
24
|
-
import ReactSubView from './ReactSubView';
|
|
25
|
-
export var figurePositions;
|
|
26
|
-
(function (figurePositions) {
|
|
27
|
-
figurePositions["left"] = "half-left";
|
|
28
|
-
figurePositions["right"] = "half-right";
|
|
29
|
-
figurePositions["default"] = "";
|
|
30
|
-
})(figurePositions || (figurePositions = {}));
|
|
31
23
|
export class ImageElementView extends BlockView {
|
|
32
24
|
constructor() {
|
|
33
25
|
super(...arguments);
|
|
@@ -42,46 +34,6 @@ export class ImageElementView extends BlockView {
|
|
|
42
34
|
this.setExtLink({ extLink: result.id });
|
|
43
35
|
this.updateContents();
|
|
44
36
|
};
|
|
45
|
-
this.showPositionMenu = () => {
|
|
46
|
-
const firstFigure = this.getFirstFigure();
|
|
47
|
-
if (!firstFigure) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
this.props.popper.destroy();
|
|
51
|
-
const options = [
|
|
52
|
-
{
|
|
53
|
-
label: 'Left',
|
|
54
|
-
action: () => {
|
|
55
|
-
this.props.popper.destroy();
|
|
56
|
-
this.updateAllFiguresPosition(figurePositions.left);
|
|
57
|
-
},
|
|
58
|
-
icon: 'ImageLeft',
|
|
59
|
-
selected: this.figurePosition === figurePositions.left,
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
label: 'Default',
|
|
63
|
-
action: () => {
|
|
64
|
-
this.props.popper.destroy();
|
|
65
|
-
this.updateAllFiguresPosition(figurePositions.default);
|
|
66
|
-
},
|
|
67
|
-
icon: 'ImageDefault',
|
|
68
|
-
selected: !this.figurePosition,
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
label: 'Right',
|
|
72
|
-
action: () => {
|
|
73
|
-
this.props.popper.destroy();
|
|
74
|
-
this.updateAllFiguresPosition(figurePositions.right);
|
|
75
|
-
},
|
|
76
|
-
icon: 'ImageRight',
|
|
77
|
-
selected: this.figurePosition === figurePositions.right,
|
|
78
|
-
},
|
|
79
|
-
];
|
|
80
|
-
const componentProps = {
|
|
81
|
-
actions: options,
|
|
82
|
-
};
|
|
83
|
-
this.props.popper.show(this.positionMenuWrapper, ReactSubView(this.props, ContextMenu, componentProps, this.node, this.getPos, this.view, ['context-menu', 'position-menu']), 'left', false);
|
|
84
|
-
};
|
|
85
37
|
this.removeExtLink = () => {
|
|
86
38
|
this.setExtLink({ extLink: '' });
|
|
87
39
|
};
|
|
@@ -127,18 +79,6 @@ export class ImageElementView extends BlockView {
|
|
|
127
79
|
addTools() {
|
|
128
80
|
this.addPositionMenu();
|
|
129
81
|
}
|
|
130
|
-
addPositionMenu() {
|
|
131
|
-
if (this.props.getCapabilities()?.editArticle) {
|
|
132
|
-
const existingMenu = this.container.querySelector('.position-menu');
|
|
133
|
-
if (existingMenu) {
|
|
134
|
-
existingMenu.remove();
|
|
135
|
-
}
|
|
136
|
-
const firstFigure = this.getFirstFigure();
|
|
137
|
-
this.figurePosition = firstFigure?.attrs.type || figurePositions.default;
|
|
138
|
-
this.positionMenuWrapper = createPositionMenuWrapper(this.figurePosition, this.showPositionMenu, this.props);
|
|
139
|
-
this.container.prepend(this.positionMenuWrapper);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
82
|
getFirstFigure() {
|
|
143
83
|
if (this.node.type === schema.nodes.image_element) {
|
|
144
84
|
const figureNode = this.node.firstChild;
|
|
@@ -176,6 +116,12 @@ export class ImageElementView extends BlockView {
|
|
|
176
116
|
}
|
|
177
117
|
return figures;
|
|
178
118
|
}
|
|
119
|
+
addPositionMenu() {
|
|
120
|
+
if (!this.positionMenu) {
|
|
121
|
+
this.positionMenu = new HorizontalPositionMenu(this, this.updateAllFiguresPosition.bind(this), this.container, () => this.getFirstFigure());
|
|
122
|
+
}
|
|
123
|
+
this.positionMenu.create();
|
|
124
|
+
}
|
|
179
125
|
updateAllFiguresPosition(position) {
|
|
180
126
|
const figures = this.getAllFigures();
|
|
181
127
|
const { tr } = this.view.state;
|
|
@@ -186,7 +132,6 @@ export class ImageElementView extends BlockView {
|
|
|
186
132
|
});
|
|
187
133
|
});
|
|
188
134
|
this.view.dispatch(tr);
|
|
189
|
-
this.figurePosition = position;
|
|
190
135
|
}
|
|
191
136
|
createDnDPlaceholder() {
|
|
192
137
|
const can = this.props.getCapabilities();
|
|
@@ -21,6 +21,7 @@ import { setCommentSelection } from '../plugins/comments';
|
|
|
21
21
|
import BlockView from './block_view';
|
|
22
22
|
import { createNodeOrElementView } from './creators';
|
|
23
23
|
import ReactSubView from './ReactSubView';
|
|
24
|
+
import { HorizontalPositionMenu } from '../lib/position-menu';
|
|
24
25
|
export class PullquoteElementView extends BlockView {
|
|
25
26
|
constructor() {
|
|
26
27
|
super(...arguments);
|
|
@@ -43,7 +44,10 @@ export class PullquoteElementView extends BlockView {
|
|
|
43
44
|
this.contentDOM = document.createElement(this.elementType);
|
|
44
45
|
this.contentDOM.className = 'block';
|
|
45
46
|
this.contentDOM.classList.add('pullquote');
|
|
46
|
-
this.
|
|
47
|
+
this.container = document.createElement('div');
|
|
48
|
+
this.container.classList.add('container');
|
|
49
|
+
this.container.appendChild(this.contentDOM);
|
|
50
|
+
this.dom.appendChild(this.container);
|
|
47
51
|
this.dom.addEventListener('click', this.handleClick);
|
|
48
52
|
};
|
|
49
53
|
this.actionGutterButtons = () => {
|
|
@@ -78,5 +82,23 @@ export class PullquoteElementView extends BlockView {
|
|
|
78
82
|
tr.insert(this.getPos() + 1, schema.nodes.quote_image.create());
|
|
79
83
|
this.view.dispatch(tr);
|
|
80
84
|
}
|
|
85
|
+
updateContents() {
|
|
86
|
+
super.updateContents();
|
|
87
|
+
this.addTools();
|
|
88
|
+
}
|
|
89
|
+
addTools() {
|
|
90
|
+
this.addPositionMenu();
|
|
91
|
+
}
|
|
92
|
+
addPositionMenu() {
|
|
93
|
+
if (!this.positionMenu) {
|
|
94
|
+
this.positionMenu = new HorizontalPositionMenu(this, this.updateHorizontalPosition, this.container);
|
|
95
|
+
}
|
|
96
|
+
this.positionMenu.create();
|
|
97
|
+
}
|
|
98
|
+
updateHorizontalPosition(horizontalPosition) {
|
|
99
|
+
const tr = this.view.state.tr;
|
|
100
|
+
tr.setNodeAttribute(this.getPos(), 'type', horizontalPosition);
|
|
101
|
+
this.view.dispatch(tr);
|
|
102
|
+
}
|
|
81
103
|
}
|
|
82
104
|
export default createNodeOrElementView(PullquoteElementView, 'aside');
|