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