1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | import { Rect } from 'ckeditor5/src/utils';
|
9 | import { BalloonPanelView } from 'ckeditor5/src/ui';
|
10 | import { getTableWidgetAncestor } from './widget';
|
11 | const DEFAULT_BALLOON_POSITIONS = BalloonPanelView.defaultPositions;
|
12 | const BALLOON_POSITIONS = [
|
13 | DEFAULT_BALLOON_POSITIONS.northArrowSouth,
|
14 | DEFAULT_BALLOON_POSITIONS.northArrowSouthWest,
|
15 | DEFAULT_BALLOON_POSITIONS.northArrowSouthEast,
|
16 | DEFAULT_BALLOON_POSITIONS.southArrowNorth,
|
17 | DEFAULT_BALLOON_POSITIONS.southArrowNorthWest,
|
18 | DEFAULT_BALLOON_POSITIONS.southArrowNorthEast,
|
19 | DEFAULT_BALLOON_POSITIONS.viewportStickyNorth
|
20 | ];
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 | export function repositionContextualBalloon(editor, target) {
|
30 | const balloon = editor.plugins.get('ContextualBalloon');
|
31 | if (getTableWidgetAncestor(editor.editing.view.document.selection)) {
|
32 | let position;
|
33 | if (target === 'cell') {
|
34 | position = getBalloonCellPositionData(editor);
|
35 | }
|
36 | else {
|
37 | position = getBalloonTablePositionData(editor);
|
38 | }
|
39 | balloon.updatePosition(position);
|
40 | }
|
41 | }
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 | export function getBalloonTablePositionData(editor) {
|
50 | const firstPosition = editor.model.document.selection.getFirstPosition();
|
51 | const modelTable = firstPosition.findAncestor('table');
|
52 | const viewTable = editor.editing.mapper.toViewElement(modelTable);
|
53 | return {
|
54 | target: editor.editing.view.domConverter.mapViewToDom(viewTable),
|
55 | positions: BALLOON_POSITIONS
|
56 | };
|
57 | }
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 | export function getBalloonCellPositionData(editor) {
|
66 | const mapper = editor.editing.mapper;
|
67 | const domConverter = editor.editing.view.domConverter;
|
68 | const selection = editor.model.document.selection;
|
69 | if (selection.rangeCount > 1) {
|
70 | return {
|
71 | target: () => createBoundingRect(selection.getRanges(), editor),
|
72 | positions: BALLOON_POSITIONS
|
73 | };
|
74 | }
|
75 | const modelTableCell = getTableCellAtPosition(selection.getFirstPosition());
|
76 | const viewTableCell = mapper.toViewElement(modelTableCell);
|
77 | return {
|
78 | target: domConverter.mapViewToDom(viewTableCell),
|
79 | positions: BALLOON_POSITIONS
|
80 | };
|
81 | }
|
82 |
|
83 |
|
84 |
|
85 |
|
86 |
|
87 | function getTableCellAtPosition(position) {
|
88 | const isTableCellSelected = position.nodeAfter && position.nodeAfter.is('element', 'tableCell');
|
89 | return isTableCellSelected ? position.nodeAfter : position.findAncestor('tableCell');
|
90 | }
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 | function createBoundingRect(ranges, editor) {
|
98 | const mapper = editor.editing.mapper;
|
99 | const domConverter = editor.editing.view.domConverter;
|
100 | const rects = Array.from(ranges).map(range => {
|
101 | const modelTableCell = getTableCellAtPosition(range.start);
|
102 | const viewTableCell = mapper.toViewElement(modelTableCell);
|
103 | return new Rect(domConverter.mapViewToDom(viewTableCell));
|
104 | });
|
105 | return Rect.getBoundingRect(rects);
|
106 | }
|