1 | /**
|
2 | * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
3 | * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
4 | */
|
5 | /**
|
6 | * @module table/tableselection
|
7 | */
|
8 | import { Plugin } from 'ckeditor5/src/core';
|
9 | import type { Element, DocumentFragment } from 'ckeditor5/src/engine';
|
10 | import TableUtils from './tableutils';
|
11 | import '../theme/tableselection.css';
|
12 | /**
|
13 | * This plugin enables the advanced table cells, rows and columns selection.
|
14 | * It is loaded automatically by the {@link module:table/table~Table} plugin.
|
15 | */
|
16 | export default class TableSelection extends Plugin {
|
17 | /**
|
18 | * @inheritDoc
|
19 | */
|
20 | static get pluginName(): 'TableSelection';
|
21 | /**
|
22 | * @inheritDoc
|
23 | */
|
24 | static get requires(): readonly [typeof TableUtils, typeof TableUtils];
|
25 | /**
|
26 | * @inheritDoc
|
27 | */
|
28 | init(): void;
|
29 | /**
|
30 | * Returns the currently selected table cells or `null` if it is not a table cells selection.
|
31 | */
|
32 | getSelectedTableCells(): Array<Element> | null;
|
33 | /**
|
34 | * Returns the selected table fragment as a document fragment.
|
35 | */
|
36 | getSelectionAsFragment(): DocumentFragment | null;
|
37 | /**
|
38 | * Sets the model selection based on given anchor and target cells (can be the same cell).
|
39 | * Takes care of setting the backward flag.
|
40 | *
|
41 | * ```ts
|
42 | * const modelRoot = editor.model.document.getRoot();
|
43 | * const firstCell = modelRoot.getNodeByPath( [ 0, 0, 0 ] );
|
44 | * const lastCell = modelRoot.getNodeByPath( [ 0, 0, 1 ] );
|
45 | *
|
46 | * const tableSelection = editor.plugins.get( 'TableSelection' );
|
47 | * tableSelection.setCellSelection( firstCell, lastCell );
|
48 | * ```
|
49 | */
|
50 | setCellSelection(anchorCell: Element, targetCell: Element): void;
|
51 | /**
|
52 | * Returns the focus cell from the current selection.
|
53 | */
|
54 | getFocusCell(): Element | null;
|
55 | /**
|
56 | * Returns the anchor cell from the current selection.
|
57 | */
|
58 | getAnchorCell(): Element | null;
|
59 | /**
|
60 | * Defines a selection converter which marks the selected cells with a specific class.
|
61 | *
|
62 | * The real DOM selection is put in the last cell. Since the order of ranges is dependent on whether the
|
63 | * selection is backward or not, the last cell will usually be close to the "focus" end of the selection
|
64 | * (a selection has anchor and focus).
|
65 | *
|
66 | * The real DOM selection is then hidden with CSS.
|
67 | */
|
68 | private _defineSelectionConverter;
|
69 | /**
|
70 | * Creates a listener that reacts to changes in {@link #isEnabled} and, if the plugin was disabled,
|
71 | * it collapses the multi-cell selection to a regular selection placed inside a table cell.
|
72 | *
|
73 | * This listener helps features that disable the table selection plugin bring the selection
|
74 | * to a clear state they can work with (for instance, because they don't support multiple cell selection).
|
75 | */
|
76 | private _enablePluginDisabling;
|
77 | /**
|
78 | * Overrides the default `model.deleteContent()` behavior over a selected table fragment.
|
79 | *
|
80 | * @param args Delete content method arguments.
|
81 | */
|
82 | private _handleDeleteContent;
|
83 | /**
|
84 | * This handler makes it possible to remove the content of all selected cells by starting to type.
|
85 | * If you take a look at {@link #_defineSelectionConverter} you will find out that despite the multi-cell selection being set
|
86 | * in the model, the view selection is collapsed in the last cell (because most browsers are unable to render multi-cell selections;
|
87 | * yes, it's a hack).
|
88 | *
|
89 | * When multiple cells are selected in the model and the user starts to type, the
|
90 | * {@link module:engine/view/document~Document#event:insertText} event carries information provided by the
|
91 | * beforeinput DOM event, that in turn only knows about this collapsed DOM selection in the last cell.
|
92 | *
|
93 | * As a result, the selected cells have no chance to be cleaned up. To fix this, this listener intercepts
|
94 | * the event and injects the custom view selection in the data that translates correctly to the actual state
|
95 | * of the multi-cell selection in the model.
|
96 | *
|
97 | * @param data Insert text event data.
|
98 | */
|
99 | private _handleInsertTextEvent;
|
100 | /**
|
101 | * Returns an array of table cells that should be selected based on the
|
102 | * given anchor cell and target (focus) cell.
|
103 | *
|
104 | * The cells are returned in a reverse direction if the selection is backward.
|
105 | */
|
106 | private _getCellsToSelect;
|
107 | }
|