@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
@@ -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 TableElementView extends BlockView {
19
20
  constructor() {
20
21
  super(...arguments);
@@ -23,8 +24,29 @@ export class TableElementView extends BlockView {
23
24
  this.contentDOM = document.createElement('figure');
24
25
  this.contentDOM.classList.add('block');
25
26
  this.contentDOM.setAttribute('id', this.node.attrs.id);
26
- this.dom.appendChild(this.contentDOM);
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(TableElementView);
@@ -13,16 +13,18 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { Placement, StrictModifiers } from '@popperjs/core';
16
+ import { Instance, Placement, StrictModifiers } from '@popperjs/core';
17
17
  export declare class PopperManager {
18
18
  private activePopper?;
19
19
  private handleDocumentClick?;
20
20
  private triggerElement?;
21
21
  private container?;
22
- show(target: Element, contents: HTMLElement, placement?: Placement, showArrow?: boolean, modifiers?: Array<Partial<StrictModifiers>>, autoFocus?: boolean): void;
22
+ private destructionListener?;
23
+ show(target: Element, contents: HTMLElement, placement?: Placement, showArrow?: boolean, modifiers?: Array<Partial<StrictModifiers>>, autoFocus?: boolean, onDestroy?: ((i: Instance) => void) | undefined): void;
23
24
  destroy(): void;
24
25
  getContainer(): HTMLElement | undefined;
25
26
  update(): void;
27
+ replaceContent(newContent: HTMLElement): void;
26
28
  isActive: () => boolean;
27
29
  private focusInput;
28
30
  private addContainerClass;
@@ -15,20 +15,45 @@
15
15
  */
16
16
  import { ManuscriptEditorView, ManuscriptNode, ManuscriptNodeType } from '@manuscripts/transform';
17
17
  import { EditorProps } from '../configs/ManuscriptsEditor';
18
+ import BlockView from '../views/block_view';
19
+ export declare enum HorizontalPositions {
20
+ left = "half-left",
21
+ right = "half-right",
22
+ default = ""
23
+ }
18
24
  export interface PopperMenuPositionOption {
19
25
  label: string;
20
26
  action: () => void;
21
27
  icon: string;
22
28
  selected: boolean;
23
29
  }
24
- export declare const createPositionOptions: <T extends ManuscriptNode>(nodeType: ManuscriptNodeType, node: T, currentPosition: string, view: ManuscriptEditorView, onComplete?: () => void) => {
25
- title: string;
26
- action: () => void;
27
- IconComponent: string;
28
- iconName: string;
29
- selected: boolean;
30
- }[];
31
- export declare const createPopperMenuPositionOptions: <T extends ManuscriptNode>(nodeType: ManuscriptNodeType, node: T, currentPosition: string, view: ManuscriptEditorView, onComplete?: () => void) => PopperMenuPositionOption[];
32
- export declare const showPositionMenu: <T extends ManuscriptNode>(nodeType: ManuscriptNodeType, node: T, currentPosition: string, positionMenuWrapper: HTMLElement, view: ManuscriptEditorView, getPos: () => number, props: EditorProps) => void;
33
- export declare const setElementPositionAlignment: (element: HTMLElement, position: string) => void;
34
- export declare const createPositionMenuWrapper: (currentPosition: string, onClick: () => void, props: EditorProps) => HTMLDivElement;
30
+ export declare class HorizontalPositionMenu {
31
+ private parent;
32
+ menuOpen: boolean;
33
+ posMenuSelector: string;
34
+ onChange: (newPos: HorizontalPositions) => void;
35
+ positionMenuWrapper: HTMLDivElement;
36
+ location: HTMLElement;
37
+ getPositionSource?: () => ManuscriptNode | null;
38
+ constructor(parent: BlockView<ManuscriptNode>, onChange: (newPos: HorizontalPositions) => void, location?: HTMLElement, getPositionSource?: () => ManuscriptNode | null);
39
+ static createPositionOptions<T extends ManuscriptNode>(nodeType: ManuscriptNodeType, node: T, currentPosition: string, view: ManuscriptEditorView, onComplete?: () => void): {
40
+ title: string;
41
+ action: () => void;
42
+ IconComponent: string;
43
+ iconName: string;
44
+ selected: boolean;
45
+ }[];
46
+ createPopperMenuPositionOptions<T extends ManuscriptNode>(nodeType: ManuscriptNodeType, node: T, currentPosition: string, view: ManuscriptEditorView, onComplete?: () => void): PopperMenuPositionOption[];
47
+ buttonClass: string;
48
+ createPositionMenuWrapper(currentPosition: string, props: EditorProps): void;
49
+ getHorizontalPositionOptions(current: string, onPick: (newPos: HorizontalPositions) => void, destroy: () => void): {
50
+ actions: {
51
+ label: string;
52
+ action: () => void;
53
+ icon: string;
54
+ selected: boolean;
55
+ }[];
56
+ };
57
+ showPositionMenu(force?: boolean): void;
58
+ create(): void;
59
+ }
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "3.16.3";
1
+ export declare const VERSION = "3.17.0";
2
2
  export declare const MATHJAX_VERSION = "3.2.2";
@@ -17,7 +17,13 @@ import { BoxElementNode } from '@manuscripts/transform';
17
17
  import BlockView from './block_view';
18
18
  export declare class BoxElementView extends BlockView<BoxElementNode> {
19
19
  elementType: string;
20
+ container: HTMLDivElement;
20
21
  createElement: () => void;
22
+ updateContents(): void;
23
+ protected addTools(): void;
24
+ private positionMenu;
25
+ protected addPositionMenu(): void;
26
+ private updateHorizontalPosition;
21
27
  }
22
28
  declare const _default: (props: import("../configs/ManuscriptsEditor").EditorProps, dispatch?: import("..").Dispatch) => import("../types").NodeViewCreator<BoxElementView>;
23
29
  export default _default;
@@ -16,17 +16,11 @@
16
16
  import { ImageElementNode } from '@manuscripts/transform';
17
17
  import { Trackable } from '../types';
18
18
  import BlockView from './block_view';
19
- export declare enum figurePositions {
20
- left = "half-left",
21
- right = "half-right",
22
- default = ""
23
- }
24
19
  export declare class ImageElementView extends BlockView<Trackable<ImageElementNode>> {
25
20
  container: HTMLElement;
26
21
  subcontainer: HTMLElement;
27
22
  extLinkEditorContainer: HTMLDivElement;
28
- private positionMenuWrapper;
29
- private figurePosition;
23
+ private positionMenu;
30
24
  private isEditingExtLink;
31
25
  ignoreMutation: () => boolean;
32
26
  upload: (file: File) => Promise<void>;
@@ -35,10 +29,9 @@ export declare class ImageElementView extends BlockView<Trackable<ImageElementNo
35
29
  createElement(): void;
36
30
  updateContents(): void;
37
31
  protected addTools(): void;
38
- protected addPositionMenu(): void;
39
32
  private getFirstFigure;
40
33
  private getAllFigures;
41
- private showPositionMenu;
34
+ protected addPositionMenu(): void;
42
35
  private updateAllFiguresPosition;
43
36
  private removeExtLink;
44
37
  private setExtLink;
@@ -18,6 +18,8 @@ import BlockView from './block_view';
18
18
  export declare class PullquoteElementView extends BlockView<PullquoteElementNode> {
19
19
  elementType: string;
20
20
  contextMenu: HTMLElement;
21
+ container: HTMLDivElement;
22
+ private positionMenu;
21
23
  ignoreMutation: () => boolean;
22
24
  stopEvent: () => boolean;
23
25
  private handleClick;
@@ -25,7 +27,11 @@ export declare class PullquoteElementView extends BlockView<PullquoteElementNode
25
27
  handleAddFigure(): void;
26
28
  actionGutterButtons: () => HTMLElement[];
27
29
  addFigureContextMenu: () => HTMLElement | undefined;
30
+ updateContents(): void;
28
31
  destroy: () => void;
32
+ protected addTools(): void;
33
+ protected addPositionMenu(): void;
34
+ private updateHorizontalPosition;
29
35
  }
30
36
  declare const _default: (props: import("../configs/ManuscriptsEditor").EditorProps) => import("../types").NodeViewCreator<PullquoteElementView>;
31
37
  export default _default;
@@ -17,7 +17,13 @@ import { TableElementNode } from '@manuscripts/transform';
17
17
  import BlockView from './block_view';
18
18
  export declare class TableElementView extends BlockView<TableElementNode> {
19
19
  elementType: string;
20
+ container: HTMLDivElement;
21
+ private positionMenu;
20
22
  createElement: () => void;
23
+ updateContents(): void;
24
+ protected addTools(): void;
25
+ protected addPositionMenu(): void;
26
+ private updateHorizontalPosition;
21
27
  }
22
28
  declare const _default: (props: import("../configs/ManuscriptsEditor").EditorProps, dispatch?: import("..").Dispatch) => import("../types").NodeViewCreator<TableElementView>;
23
29
  export default _default;
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": "3.16.3",
4
+ "version": "3.17.0",
5
5
  "repository": "github:Atypon-OpenSource/manuscripts-body-editor",
6
6
  "license": "Apache-2.0",
7
7
  "main": "dist/cjs",
@@ -42,7 +42,7 @@ import {
42
42
  insertInlineTableFootnote,
43
43
  } from '../commands'
44
44
  import { PopperManager } from './popper'
45
- import { createPositionOptions } from './position-menu'
45
+ import { HorizontalPositionMenu } from './position-menu'
46
46
  import { templateAllows } from './template'
47
47
  import {
48
48
  getMatchingChild,
@@ -59,9 +59,18 @@ const readonlyTypes = [
59
59
  schema.nodes.footnotes_section,
60
60
  ]
61
61
 
62
- const isBoxElementSectionTitle = ($pos: ResolvedPos, node: ManuscriptNode) =>
63
- isSectionTitleNode(node) &&
64
- $pos.node($pos.depth - 1).type === schema.nodes.box_element
62
+ const getBoxElementOfSectionTitle = (
63
+ $pos: ResolvedPos,
64
+ node: ManuscriptNode
65
+ ) => {
66
+ if (isSectionTitleNode(node)) {
67
+ const parent = $pos.node($pos.depth - 1)
68
+ if (parent.type === schema.nodes.box_element) {
69
+ return parent
70
+ }
71
+ }
72
+ return null
73
+ }
65
74
 
66
75
  export const sectionLevel = (depth: number) => {
67
76
  switch (depth) {
@@ -245,31 +254,43 @@ export class ContextMenu {
245
254
  menu.className = 'menu'
246
255
 
247
256
  const $pos = this.resolvePos()
248
- const isBox = isBoxElementSectionTitle($pos, this.node)
249
- const type = isBox ? schema.nodes.box_element : this.node.type
257
+ const boxParent = getBoxElementOfSectionTitle($pos, this.node)
258
+ const type = boxParent ? schema.nodes.box_element : this.node.type
250
259
 
251
- if (
252
- type === schema.nodes.figure_element ||
253
- type === schema.nodes.image_element
254
- ) {
260
+ const positionableTypes = [
261
+ schema.nodes.figure_element,
262
+ schema.nodes.image_element,
263
+ schema.nodes.box_element,
264
+ schema.nodes.pullquote_element,
265
+ schema.nodes.table_element,
266
+ ]
267
+
268
+ let nodeBase = this.node
269
+
270
+ if (positionableTypes.includes(type)) {
255
271
  const figure = getMatchingChild(
256
272
  this.node,
257
273
  (node) => node.type === schema.nodes.figure
258
274
  )
259
275
 
260
276
  if (figure) {
261
- const attrType = figure.attrs.type
262
- const submenuOptions = createPositionOptions(
263
- schema.nodes.figure,
264
- figure,
265
- attrType,
266
- this.view,
267
- () => popper.destroy()
268
- )
269
- const submenuLabel = 'Position'
270
- const submenu = this.createSubmenu(submenuLabel, submenuOptions)
271
- menu.appendChild(submenu)
277
+ nodeBase = figure
278
+ }
279
+
280
+ if (boxParent) {
281
+ nodeBase = boxParent
272
282
  }
283
+
284
+ const submenuOptions = HorizontalPositionMenu.createPositionOptions(
285
+ schema.nodes[nodeBase.type.name],
286
+ nodeBase,
287
+ nodeBase.attrs.type,
288
+ this.view,
289
+ () => popper.destroy()
290
+ )
291
+ const submenuLabel = 'Position'
292
+ const submenu = this.createSubmenu(submenuLabel, submenuOptions)
293
+ menu.appendChild(submenu)
273
294
  }
274
295
 
275
296
  if (type === schema.nodes.list) {
package/src/lib/popper.ts CHANGED
@@ -27,6 +27,7 @@ export class PopperManager {
27
27
  private handleDocumentClick?: (e: Event) => void
28
28
  private triggerElement?: Element
29
29
  private container?: HTMLElement
30
+ private destructionListener?: (i: Instance) => void
30
31
 
31
32
  public show(
32
33
  target: Element,
@@ -34,7 +35,8 @@ export class PopperManager {
34
35
  placement: Placement = 'bottom',
35
36
  showArrow = true,
36
37
  modifiers: Array<Partial<StrictModifiers>> = [],
37
- autoFocus = true
38
+ autoFocus = true,
39
+ onDestroy: ((i: Instance) => void) | undefined = undefined
38
40
  ) {
39
41
  // destroy any existing popper first
40
42
  // checking activePopper is in destroy() method
@@ -42,6 +44,7 @@ export class PopperManager {
42
44
 
43
45
  // Store the trigger element to return focus later
44
46
  this.triggerElement = target
47
+ this.destructionListener = onDestroy
45
48
 
46
49
  window.requestAnimationFrame(() => {
47
50
  const container = document.createElement('div')
@@ -125,6 +128,8 @@ export class PopperManager {
125
128
  this.removeContainerClass(
126
129
  this.activePopper.state.elements.reference as Element
127
130
  )
131
+ this.destructionListener?.(this.activePopper)
132
+ this.destructionListener = undefined
128
133
  this.activePopper.destroy()
129
134
  this.activePopper.state.elements.popper.remove()
130
135
  if (this.handleDocumentClick) {
@@ -146,6 +151,18 @@ export class PopperManager {
146
151
  }
147
152
  }
148
153
 
154
+ public replaceContent(newContent: HTMLElement) {
155
+ if (this.container && this.activePopper) {
156
+ const arrow = this.container.querySelector('.popper-arrow')
157
+ this.container.innerHTML = ''
158
+ if (arrow) {
159
+ this.container.appendChild(arrow)
160
+ }
161
+ this.container.appendChild(newContent)
162
+ this.activePopper.update()
163
+ }
164
+ }
165
+
149
166
  public isActive = () => !!this.activePopper
150
167
 
151
168
  private focusInput(container: HTMLDivElement, autoFocus = true) {