roosterjs-content-model-core 9.45.1 → 9.46.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/lib/command/cutCopy/getContentForCopy.js +4 -15
- package/lib/command/cutCopy/getContentForCopy.js.map +1 -1
- package/lib/coreApi/setDOMSelection/setDOMSelection.js +5 -58
- package/lib/coreApi/setDOMSelection/setDOMSelection.js.map +1 -1
- package/lib/coreApi/setDOMSelection/setTableCellsStyle.d.ts +17 -0
- package/lib/coreApi/setDOMSelection/setTableCellsStyle.js +85 -0
- package/lib/coreApi/setDOMSelection/setTableCellsStyle.js.map +1 -0
- package/lib/coreApi/setDOMSelection/toggleTableSelection.d.ts +8 -0
- package/lib/coreApi/setDOMSelection/toggleTableSelection.js +34 -0
- package/lib/coreApi/setDOMSelection/toggleTableSelection.js.map +1 -0
- package/lib/coreApi/switchShadowEdit/switchShadowEdit.js +3 -0
- package/lib/coreApi/switchShadowEdit/switchShadowEdit.js.map +1 -1
- package/lib/corePlugin/selection/SelectionPlugin.js +3 -0
- package/lib/corePlugin/selection/SelectionPlugin.js.map +1 -1
- package/lib/editor/Editor.js +1 -1
- package/lib/editor/Editor.js.map +1 -1
- package/lib-amd/command/cutCopy/getContentForCopy.js +5 -14
- package/lib-amd/command/cutCopy/getContentForCopy.js.map +1 -1
- package/lib-amd/coreApi/setDOMSelection/setDOMSelection.js +4 -58
- package/lib-amd/coreApi/setDOMSelection/setDOMSelection.js.map +1 -1
- package/lib-amd/coreApi/setDOMSelection/setTableCellsStyle.d.ts +17 -0
- package/lib-amd/coreApi/setDOMSelection/setTableCellsStyle.js +85 -0
- package/lib-amd/coreApi/setDOMSelection/setTableCellsStyle.js.map +1 -0
- package/lib-amd/coreApi/setDOMSelection/toggleTableSelection.d.ts +8 -0
- package/lib-amd/coreApi/setDOMSelection/toggleTableSelection.js +34 -0
- package/lib-amd/coreApi/setDOMSelection/toggleTableSelection.js.map +1 -0
- package/lib-amd/coreApi/switchShadowEdit/switchShadowEdit.js +3 -1
- package/lib-amd/coreApi/switchShadowEdit/switchShadowEdit.js.map +1 -1
- package/lib-amd/corePlugin/selection/SelectionPlugin.js +3 -0
- package/lib-amd/corePlugin/selection/SelectionPlugin.js.map +1 -1
- package/lib-amd/editor/Editor.js +1 -1
- package/lib-amd/editor/Editor.js.map +1 -1
- package/lib-mjs/command/cutCopy/getContentForCopy.js +5 -16
- package/lib-mjs/command/cutCopy/getContentForCopy.js.map +1 -1
- package/lib-mjs/coreApi/setDOMSelection/setDOMSelection.js +5 -58
- package/lib-mjs/coreApi/setDOMSelection/setDOMSelection.js.map +1 -1
- package/lib-mjs/coreApi/setDOMSelection/setTableCellsStyle.d.ts +17 -0
- package/lib-mjs/coreApi/setDOMSelection/setTableCellsStyle.js +80 -0
- package/lib-mjs/coreApi/setDOMSelection/setTableCellsStyle.js.map +1 -0
- package/lib-mjs/coreApi/setDOMSelection/toggleTableSelection.d.ts +8 -0
- package/lib-mjs/coreApi/setDOMSelection/toggleTableSelection.js +30 -0
- package/lib-mjs/coreApi/setDOMSelection/toggleTableSelection.js.map +1 -0
- package/lib-mjs/coreApi/switchShadowEdit/switchShadowEdit.js +3 -0
- package/lib-mjs/coreApi/switchShadowEdit/switchShadowEdit.js.map +1 -1
- package/lib-mjs/corePlugin/selection/SelectionPlugin.js +3 -0
- package/lib-mjs/corePlugin/selection/SelectionPlugin.js.map +1 -1
- package/lib-mjs/editor/Editor.js +1 -1
- package/lib-mjs/editor/Editor.js.map +1 -1
- package/package.json +4 -4
- package/lib/command/cutCopy/preprocessTable.d.ts +0 -5
- package/lib/command/cutCopy/preprocessTable.js +0 -22
- package/lib/command/cutCopy/preprocessTable.js.map +0 -1
- package/lib/command/cutCopy/pruneUnselectedModel.d.ts +0 -5
- package/lib/command/cutCopy/pruneUnselectedModel.js +0 -135
- package/lib/command/cutCopy/pruneUnselectedModel.js.map +0 -1
- package/lib-amd/command/cutCopy/preprocessTable.d.ts +0 -5
- package/lib-amd/command/cutCopy/preprocessTable.js +0 -22
- package/lib-amd/command/cutCopy/preprocessTable.js.map +0 -1
- package/lib-amd/command/cutCopy/pruneUnselectedModel.d.ts +0 -5
- package/lib-amd/command/cutCopy/pruneUnselectedModel.js +0 -136
- package/lib-amd/command/cutCopy/pruneUnselectedModel.js.map +0 -1
- package/lib-mjs/command/cutCopy/preprocessTable.d.ts +0 -5
- package/lib-mjs/command/cutCopy/preprocessTable.js +0 -18
- package/lib-mjs/command/cutCopy/preprocessTable.js.map +0 -1
- package/lib-mjs/command/cutCopy/pruneUnselectedModel.d.ts +0 -5
- package/lib-mjs/command/cutCopy/pruneUnselectedModel.js +0 -131
- package/lib-mjs/command/cutCopy/pruneUnselectedModel.js.map +0 -1
|
@@ -4,8 +4,6 @@ exports.getContentForCopy = exports.onNodeCreated = void 0;
|
|
|
4
4
|
var adjustImageSelectionOnSafari_1 = require("./adjustImageSelectionOnSafari");
|
|
5
5
|
var adjustSelectionForCopyCut_1 = require("./adjustSelectionForCopyCut");
|
|
6
6
|
var pasteCopyBlockEntityParser_1 = require("../../override/pasteCopyBlockEntityParser");
|
|
7
|
-
var preprocessTable_1 = require("./preprocessTable");
|
|
8
|
-
var pruneUnselectedModel_1 = require("./pruneUnselectedModel");
|
|
9
7
|
var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
10
8
|
/**
|
|
11
9
|
* @internal
|
|
@@ -31,22 +29,13 @@ exports.onNodeCreated = onNodeCreated;
|
|
|
31
29
|
function getContentForCopy(editor, isCut, event) {
|
|
32
30
|
var selection = editor.getDOMSelection();
|
|
33
31
|
(0, adjustImageSelectionOnSafari_1.adjustImageSelectionOnSafari)(editor, selection);
|
|
34
|
-
if (selection && (selection.type
|
|
32
|
+
if (selection && (selection.type !== 'range' || !selection.range.collapsed)) {
|
|
35
33
|
var pasteModel = editor.getContentModelCopy('disconnected');
|
|
36
|
-
(0,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (tableContext === null || tableContext === void 0 ? void 0 : tableContext.table) {
|
|
40
|
-
(0, preprocessTable_1.preprocessTable)(tableContext.table);
|
|
41
|
-
return true;
|
|
42
|
-
}
|
|
43
|
-
return false;
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
else if (selection.type === 'range') {
|
|
34
|
+
var context = (0, roosterjs_content_model_dom_1.createModelToDomContext)();
|
|
35
|
+
(0, roosterjs_content_model_dom_1.trimModelForSelection)(pasteModel, selection);
|
|
36
|
+
if (selection.type === 'range') {
|
|
47
37
|
(0, adjustSelectionForCopyCut_1.adjustSelectionForCopyCut)(pasteModel);
|
|
48
38
|
}
|
|
49
|
-
var context = (0, roosterjs_content_model_dom_1.createModelToDomContext)();
|
|
50
39
|
context.onNodeCreated = exports.onNodeCreated;
|
|
51
40
|
var doc = editor.getDocument();
|
|
52
41
|
var tempDiv = doc.createElement('div');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getContentForCopy.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/cutCopy/getContentForCopy.ts"],"names":[],"mappings":";;;AAAA,+EAA8E;AAC9E,yEAAwE;AACxE,wFAAmF;AACnF,
|
|
1
|
+
{"version":3,"file":"getContentForCopy.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/command/cutCopy/getContentForCopy.ts"],"names":[],"mappings":"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","sourcesContent":["import { adjustImageSelectionOnSafari } from './adjustImageSelectionOnSafari';\nimport { adjustSelectionForCopyCut } from './adjustSelectionForCopyCut';\nimport { onCreateCopyEntityNode } from '../../override/pasteCopyBlockEntityParser';\nimport {\n contentModelToDom,\n contentModelToText,\n createModelToDomContext,\n trimModelForSelection,\n isElementOfType,\n isNodeOfType,\n wrap,\n} from 'roosterjs-content-model-dom';\nimport type {\n DOMSelection,\n IEditor,\n OnNodeCreated,\n TextAndHtmlContentForCopy,\n} from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Exported only for unit testing\n */\nexport const onNodeCreated: OnNodeCreated = (modelElement, node): void => {\n if (isNodeOfType(node, 'ELEMENT_NODE') && isElementOfType(node, 'table')) {\n wrap(node.ownerDocument, node, 'div');\n }\n if (isNodeOfType(node, 'ELEMENT_NODE') && !node.isContentEditable) {\n node.removeAttribute('contenteditable');\n }\n onCreateCopyEntityNode(modelElement, node);\n};\n\n/**\n * Get the content for the copy event\n * @param editor The editor object\n * @param isCut if the event cut the content.\n * @param event the clipboard event that triggered the copy/cut\n * @returns\n */\nexport function getContentForCopy(\n editor: IEditor,\n isCut: boolean,\n event: ClipboardEvent\n): TextAndHtmlContentForCopy | null {\n const selection = editor.getDOMSelection();\n adjustImageSelectionOnSafari(editor, selection);\n\n if (selection && (selection.type !== 'range' || !selection.range.collapsed)) {\n const pasteModel = editor.getContentModelCopy('disconnected');\n const context = createModelToDomContext();\n trimModelForSelection(pasteModel, selection);\n\n if (selection.type === 'range') {\n adjustSelectionForCopyCut(pasteModel);\n }\n\n context.onNodeCreated = onNodeCreated;\n const doc = editor.getDocument();\n const tempDiv = doc.createElement('div');\n\n const selectionForCopy = contentModelToDom(doc, tempDiv, pasteModel, context);\n const newRange = selectionForCopy ? domSelectionToRange(doc, selectionForCopy) : null;\n if (newRange) {\n const { clonedRoot } = editor.triggerEvent('beforeCutCopy', {\n clonedRoot: tempDiv,\n range: newRange,\n rawEvent: event,\n isCut,\n });\n\n return {\n htmlContent: clonedRoot,\n textContent: contentModelToText(pasteModel),\n };\n }\n }\n return null;\n}\n\nfunction domSelectionToRange(doc: Document, selection: DOMSelection): Range | null {\n let newRange: Range | null = null;\n\n if (selection.type === 'table') {\n const table = selection.table;\n const elementToSelect =\n table.parentElement?.childElementCount == 1 ? table.parentElement : table;\n\n newRange = doc.createRange();\n newRange.selectNode(elementToSelect);\n } else if (selection.type === 'image') {\n newRange = doc.createRange();\n newRange.selectNode(selection.image);\n } else {\n newRange = selection.range;\n }\n\n return newRange;\n}\n"]}
|
|
@@ -6,12 +6,12 @@ var areSameSelections_1 = require("../../corePlugin/cache/areSameSelections");
|
|
|
6
6
|
var ensureUniqueId_1 = require("../setEditorStyle/ensureUniqueId");
|
|
7
7
|
var findLastedCoInMergedCell_1 = require("./findLastedCoInMergedCell");
|
|
8
8
|
var findTableCellElement_1 = require("./findTableCellElement");
|
|
9
|
-
var toggleCaret_1 = require("./toggleCaret");
|
|
10
9
|
var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
10
|
+
var setTableCellsStyle_1 = require("./setTableCellsStyle");
|
|
11
|
+
var toggleCaret_1 = require("./toggleCaret");
|
|
11
12
|
var DOM_SELECTION_CSS_KEY = '_DOMSelection';
|
|
12
13
|
var HIDE_SELECTION_CSS_KEY = '_DOMSelectionHideSelection';
|
|
13
14
|
var IMAGE_ID = 'image';
|
|
14
|
-
var TABLE_ID = 'table';
|
|
15
15
|
var TRANSPARENT_SELECTION_CSS_RULE = 'background-color: transparent !important;';
|
|
16
16
|
var SELECTION_SELECTOR = '*::selection';
|
|
17
17
|
var DEFAULT_SELECTION_BORDER_COLOR = '#DB626C';
|
|
@@ -19,7 +19,7 @@ var DEFAULT_SELECTION_BORDER_COLOR = '#DB626C';
|
|
|
19
19
|
* @internal
|
|
20
20
|
*/
|
|
21
21
|
var setDOMSelection = function (core, selection, skipSelectionChangedEvent) {
|
|
22
|
-
var _a
|
|
22
|
+
var _a;
|
|
23
23
|
var existingSelection = core.api.getDOMSelection(core);
|
|
24
24
|
if (existingSelection && selection && (0, areSameSelections_1.areSameSelections)(existingSelection, selection)) {
|
|
25
25
|
return;
|
|
@@ -74,22 +74,11 @@ var setDOMSelection = function (core, selection, skipSelectionChangedEvent) {
|
|
|
74
74
|
lastColumn: lastCell.col,
|
|
75
75
|
tableSelectionInfo: selection.tableSelectionInfo,
|
|
76
76
|
};
|
|
77
|
-
var tableId = (0, ensureUniqueId_1.ensureUniqueId)(table, TABLE_ID);
|
|
78
|
-
var tableSelector = (0, roosterjs_content_model_dom_1.getSafeIdSelector)(tableId);
|
|
79
|
-
var tableSelectors = firstCell.row == 0 &&
|
|
80
|
-
firstCell.col == 0 &&
|
|
81
|
-
lastCell.row == parsedTable.length - 1 &&
|
|
82
|
-
lastCell.col == ((_b = (_a = parsedTable[lastCell.row]) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) - 1
|
|
83
|
-
? [tableSelector, tableSelector + " *"]
|
|
84
|
-
: handleTableSelected(parsedTable, tableSelector, table, firstCell, lastCell);
|
|
85
77
|
core.selection.selection = selection;
|
|
86
|
-
|
|
87
|
-
? core.selection.tableCellSelectionBackgroundColorDark
|
|
88
|
-
: core.selection.tableCellSelectionBackgroundColor;
|
|
89
|
-
core.api.setEditorStyle(core, DOM_SELECTION_CSS_KEY, "background-color:" + tableSelectionColor + "!important;", tableSelectors);
|
|
78
|
+
(0, setTableCellsStyle_1.setTableCellsStyle)(core, table, parsedTable, firstCell, lastCell);
|
|
90
79
|
core.api.setEditorStyle(core, HIDE_SELECTION_CSS_KEY, TRANSPARENT_SELECTION_CSS_RULE, [SELECTION_SELECTOR]);
|
|
91
80
|
(0, toggleCaret_1.toggleCaret)(core, true /* hide */);
|
|
92
|
-
var nodeToSelect = ((
|
|
81
|
+
var nodeToSelect = ((_a = firstCell.cell) === null || _a === void 0 ? void 0 : _a.firstElementChild) || firstCell.cell;
|
|
93
82
|
if (nodeToSelect) {
|
|
94
83
|
setRangeSelection(doc, nodeToSelect || undefined, true /* collapse */);
|
|
95
84
|
}
|
|
@@ -115,48 +104,6 @@ var setDOMSelection = function (core, selection, skipSelectionChangedEvent) {
|
|
|
115
104
|
}
|
|
116
105
|
};
|
|
117
106
|
exports.setDOMSelection = setDOMSelection;
|
|
118
|
-
function handleTableSelected(parsedTable, tableSelector, table, firstCell, lastCell) {
|
|
119
|
-
var selectors = [];
|
|
120
|
-
// Get whether table has thead, tbody or tfoot, then Set the start and end of each of the table children,
|
|
121
|
-
// so we can build the selector according the element between the table and the row.
|
|
122
|
-
var cont = 0;
|
|
123
|
-
var indexes = (0, roosterjs_content_model_dom_1.toArray)(table.childNodes)
|
|
124
|
-
.filter(function (node) {
|
|
125
|
-
return ['THEAD', 'TBODY', 'TFOOT'].indexOf((0, roosterjs_content_model_dom_1.isNodeOfType)(node, 'ELEMENT_NODE') ? node.tagName : '') > -1;
|
|
126
|
-
})
|
|
127
|
-
.map(function (node) {
|
|
128
|
-
var result = {
|
|
129
|
-
el: node.tagName,
|
|
130
|
-
start: cont,
|
|
131
|
-
end: node.childNodes.length + cont,
|
|
132
|
-
};
|
|
133
|
-
cont = result.end;
|
|
134
|
-
return result;
|
|
135
|
-
});
|
|
136
|
-
parsedTable.forEach(function (row, rowIndex) {
|
|
137
|
-
var tdCount = 0;
|
|
138
|
-
//Get current TBODY/THEAD/TFOOT
|
|
139
|
-
var midElement = indexes.filter(function (ind) { return ind.start <= rowIndex && ind.end > rowIndex; })[0];
|
|
140
|
-
var middleElSelector = midElement ? '>' + midElement.el + '>' : '>';
|
|
141
|
-
var currentRow = midElement && rowIndex + 1 >= midElement.start
|
|
142
|
-
? rowIndex + 1 - midElement.start
|
|
143
|
-
: rowIndex + 1;
|
|
144
|
-
for (var cellIndex = 0; cellIndex < row.length; cellIndex++) {
|
|
145
|
-
var cell = row[cellIndex];
|
|
146
|
-
if (typeof cell == 'object') {
|
|
147
|
-
tdCount++;
|
|
148
|
-
if (rowIndex >= firstCell.row &&
|
|
149
|
-
rowIndex <= lastCell.row &&
|
|
150
|
-
cellIndex >= firstCell.col &&
|
|
151
|
-
cellIndex <= lastCell.col) {
|
|
152
|
-
var selector = "" + tableSelector + middleElSelector + " tr:nth-child(" + currentRow + ")>" + cell.tagName + ":nth-child(" + tdCount + ")";
|
|
153
|
-
selectors.push(selector, selector + ' *');
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
});
|
|
158
|
-
return selectors;
|
|
159
|
-
}
|
|
160
107
|
function setRangeSelection(doc, element, collapse) {
|
|
161
108
|
var _a;
|
|
162
109
|
if (element && doc.contains(element)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setDOMSelection.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/setDOMSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import { addRangeToSelection } from './addRangeToSelection';\nimport { areSameSelections } from '../../corePlugin/cache/areSameSelections';\nimport { ensureUniqueId } from '../setEditorStyle/ensureUniqueId';\nimport { findLastedCoInMergedCell } from './findLastedCoInMergedCell';\nimport { findTableCellElement } from './findTableCellElement';\nimport { toggleCaret } from './toggleCaret';\nimport {\n getSafeIdSelector,\n isNodeOfType,\n parseTableCells,\n toArray,\n} from 'roosterjs-content-model-dom';\nimport type {\n ParsedTable,\n SelectionChangedEvent,\n SetDOMSelection,\n TableCellCoordinate,\n} from 'roosterjs-content-model-types';\n\nconst DOM_SELECTION_CSS_KEY = '_DOMSelection';\nconst HIDE_SELECTION_CSS_KEY = '_DOMSelectionHideSelection';\nconst IMAGE_ID = 'image';\nconst TABLE_ID = 'table';\nconst TRANSPARENT_SELECTION_CSS_RULE = 'background-color: transparent !important;';\nconst SELECTION_SELECTOR = '*::selection';\nconst DEFAULT_SELECTION_BORDER_COLOR = '#DB626C';\n\n/**\n * @internal\n */\nexport const setDOMSelection: SetDOMSelection = (core, selection, skipSelectionChangedEvent) => {\n const existingSelection = core.api.getDOMSelection(core);\n\n if (existingSelection && selection && areSameSelections(existingSelection, selection)) {\n return;\n }\n\n // We are applying a new selection, so we don't need to apply cached selection in DOMEventPlugin.\n // Set skipReselectOnFocus to skip this behavior\n const skipReselectOnFocus = core.selection.skipReselectOnFocus;\n\n const doc = core.physicalRoot.ownerDocument;\n const isDarkMode = core.lifecycle.isDarkMode;\n core.selection.skipReselectOnFocus = true;\n core.api.setEditorStyle(core, DOM_SELECTION_CSS_KEY, null /*cssRule*/);\n core.api.setEditorStyle(core, HIDE_SELECTION_CSS_KEY, null /*cssRule*/);\n\n toggleCaret(core, false /* hide */);\n\n try {\n switch (selection?.type) {\n case 'image':\n const image = selection.image;\n\n core.selection.selection = selection;\n\n const imageSelectionColor = isDarkMode\n ? core.selection.imageSelectionBorderColorDark\n : core.selection.imageSelectionBorderColor;\n\n core.api.setEditorStyle(\n core,\n DOM_SELECTION_CSS_KEY,\n `outline-style:solid!important; outline-color:${\n imageSelectionColor || DEFAULT_SELECTION_BORDER_COLOR\n }!important;`,\n [getSafeIdSelector(ensureUniqueId(image, IMAGE_ID))]\n );\n core.api.setEditorStyle(\n core,\n HIDE_SELECTION_CSS_KEY,\n TRANSPARENT_SELECTION_CSS_RULE,\n [SELECTION_SELECTOR]\n );\n\n setRangeSelection(doc, image, false /* collapse */);\n break;\n case 'table':\n const { table, firstColumn, firstRow, lastColumn, lastRow } = selection;\n const parsedTable = parseTableCells(selection.table);\n let firstCell = {\n row: Math.min(firstRow, lastRow),\n col: Math.min(firstColumn, lastColumn),\n cell: <HTMLTableCellElement | null>null,\n };\n let lastCell = {\n row: Math.max(firstRow, lastRow),\n col: Math.max(firstColumn, lastColumn),\n };\n\n firstCell = findTableCellElement(parsedTable, firstCell) || firstCell;\n lastCell = findLastedCoInMergedCell(parsedTable, lastCell) || lastCell;\n\n if (\n isNaN(firstCell.row) ||\n isNaN(firstCell.col) ||\n isNaN(lastCell.row) ||\n isNaN(lastCell.col)\n ) {\n return;\n }\n\n selection = {\n type: 'table',\n table,\n firstRow: firstCell.row,\n firstColumn: firstCell.col,\n lastRow: lastCell.row,\n lastColumn: lastCell.col,\n tableSelectionInfo: selection.tableSelectionInfo,\n };\n\n const tableId = ensureUniqueId(table, TABLE_ID);\n const tableSelector = getSafeIdSelector(tableId);\n\n const tableSelectors =\n firstCell.row == 0 &&\n firstCell.col == 0 &&\n lastCell.row == parsedTable.length - 1 &&\n lastCell.col == (parsedTable[lastCell.row]?.length ?? 0) - 1\n ? [tableSelector, `${tableSelector} *`]\n : handleTableSelected(\n parsedTable,\n tableSelector,\n table,\n firstCell,\n lastCell\n );\n\n core.selection.selection = selection;\n\n const tableSelectionColor = isDarkMode\n ? core.selection.tableCellSelectionBackgroundColorDark\n : core.selection.tableCellSelectionBackgroundColor;\n core.api.setEditorStyle(\n core,\n DOM_SELECTION_CSS_KEY,\n `background-color:${tableSelectionColor}!important;`,\n tableSelectors\n );\n core.api.setEditorStyle(\n core,\n HIDE_SELECTION_CSS_KEY,\n TRANSPARENT_SELECTION_CSS_RULE,\n [SELECTION_SELECTOR]\n );\n\n toggleCaret(core, true /* hide */);\n\n const nodeToSelect = firstCell.cell?.firstElementChild || firstCell.cell;\n\n if (nodeToSelect) {\n setRangeSelection(\n doc,\n (nodeToSelect as HTMLElement) || undefined,\n true /* collapse */\n );\n }\n\n break;\n case 'range':\n addRangeToSelection(doc, selection.range, selection.isReverted);\n\n core.selection.selection = core.domHelper.hasFocus() ? null : selection;\n break;\n\n default:\n core.selection.selection = null;\n break;\n }\n } finally {\n core.selection.skipReselectOnFocus = skipReselectOnFocus;\n }\n\n if (!skipSelectionChangedEvent) {\n const eventData: SelectionChangedEvent = {\n eventType: 'selectionChanged',\n newSelection: selection,\n };\n\n core.api.triggerEvent(core, eventData, true /*broadcast*/);\n }\n};\n\nfunction handleTableSelected(\n parsedTable: ParsedTable,\n tableSelector: string,\n table: HTMLTableElement,\n firstCell: TableCellCoordinate,\n lastCell: TableCellCoordinate\n) {\n const selectors: string[] = [];\n\n // Get whether table has thead, tbody or tfoot, then Set the start and end of each of the table children,\n // so we can build the selector according the element between the table and the row.\n let cont = 0;\n const indexes = toArray(table.childNodes)\n .filter(\n (node): node is HTMLTableSectionElement =>\n ['THEAD', 'TBODY', 'TFOOT'].indexOf(\n isNodeOfType(node, 'ELEMENT_NODE') ? node.tagName : ''\n ) > -1\n )\n .map(node => {\n const result = {\n el: node.tagName,\n start: cont,\n end: node.childNodes.length + cont,\n };\n\n cont = result.end;\n return result;\n });\n\n parsedTable.forEach((row, rowIndex) => {\n let tdCount = 0;\n\n //Get current TBODY/THEAD/TFOOT\n const midElement = indexes.filter(ind => ind.start <= rowIndex && ind.end > rowIndex)[0];\n const middleElSelector = midElement ? '>' + midElement.el + '>' : '>';\n const currentRow =\n midElement && rowIndex + 1 >= midElement.start\n ? rowIndex + 1 - midElement.start\n : rowIndex + 1;\n\n for (let cellIndex = 0; cellIndex < row.length; cellIndex++) {\n const cell = row[cellIndex];\n\n if (typeof cell == 'object') {\n tdCount++;\n\n if (\n rowIndex >= firstCell.row &&\n rowIndex <= lastCell.row &&\n cellIndex >= firstCell.col &&\n cellIndex <= lastCell.col\n ) {\n const selector = `${tableSelector}${middleElSelector} tr:nth-child(${currentRow})>${cell.tagName}:nth-child(${tdCount})`;\n\n selectors.push(selector, selector + ' *');\n }\n }\n }\n });\n\n return selectors;\n}\n\nfunction setRangeSelection(doc: Document, element: HTMLElement | undefined, collapse: boolean) {\n if (element && doc.contains(element)) {\n const range = doc.createRange();\n let isReverted: boolean | undefined = undefined;\n\n range.selectNode(element);\n if (collapse) {\n range.collapse();\n } else {\n const selection = doc.defaultView?.getSelection();\n const range = selection && selection.rangeCount > 0 && selection.getRangeAt(0);\n if (selection && range) {\n isReverted =\n selection.focusNode != range.endContainer ||\n selection.focusOffset != range.endOffset;\n }\n }\n\n addRangeToSelection(doc, range, isReverted);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"setDOMSelection.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/setDOMSelection.ts"],"names":[],"mappings":"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","sourcesContent":["import { addRangeToSelection } from './addRangeToSelection';\nimport { areSameSelections } from '../../corePlugin/cache/areSameSelections';\nimport { ensureUniqueId } from '../setEditorStyle/ensureUniqueId';\nimport { findLastedCoInMergedCell } from './findLastedCoInMergedCell';\nimport { findTableCellElement } from './findTableCellElement';\nimport { getSafeIdSelector, parseTableCells } from 'roosterjs-content-model-dom';\nimport { setTableCellsStyle } from './setTableCellsStyle';\nimport { toggleCaret } from './toggleCaret';\nimport type { SelectionChangedEvent, SetDOMSelection } from 'roosterjs-content-model-types';\n\nconst DOM_SELECTION_CSS_KEY = '_DOMSelection';\nconst HIDE_SELECTION_CSS_KEY = '_DOMSelectionHideSelection';\nconst IMAGE_ID = 'image';\nconst TRANSPARENT_SELECTION_CSS_RULE = 'background-color: transparent !important;';\nconst SELECTION_SELECTOR = '*::selection';\nconst DEFAULT_SELECTION_BORDER_COLOR = '#DB626C';\n\n/**\n * @internal\n */\nexport const setDOMSelection: SetDOMSelection = (core, selection, skipSelectionChangedEvent) => {\n const existingSelection = core.api.getDOMSelection(core);\n\n if (existingSelection && selection && areSameSelections(existingSelection, selection)) {\n return;\n }\n\n // We are applying a new selection, so we don't need to apply cached selection in DOMEventPlugin.\n // Set skipReselectOnFocus to skip this behavior\n const skipReselectOnFocus = core.selection.skipReselectOnFocus;\n\n const doc = core.physicalRoot.ownerDocument;\n const isDarkMode = core.lifecycle.isDarkMode;\n core.selection.skipReselectOnFocus = true;\n core.api.setEditorStyle(core, DOM_SELECTION_CSS_KEY, null /*cssRule*/);\n core.api.setEditorStyle(core, HIDE_SELECTION_CSS_KEY, null /*cssRule*/);\n\n toggleCaret(core, false /* hide */);\n\n try {\n switch (selection?.type) {\n case 'image':\n const image = selection.image;\n\n core.selection.selection = selection;\n\n const imageSelectionColor = isDarkMode\n ? core.selection.imageSelectionBorderColorDark\n : core.selection.imageSelectionBorderColor;\n\n core.api.setEditorStyle(\n core,\n DOM_SELECTION_CSS_KEY,\n `outline-style:solid!important; outline-color:${\n imageSelectionColor || DEFAULT_SELECTION_BORDER_COLOR\n }!important;`,\n [getSafeIdSelector(ensureUniqueId(image, IMAGE_ID))]\n );\n core.api.setEditorStyle(\n core,\n HIDE_SELECTION_CSS_KEY,\n TRANSPARENT_SELECTION_CSS_RULE,\n [SELECTION_SELECTOR]\n );\n\n setRangeSelection(doc, image, false /* collapse */);\n break;\n case 'table':\n const { table, firstColumn, firstRow, lastColumn, lastRow } = selection;\n const parsedTable = parseTableCells(selection.table);\n let firstCell = {\n row: Math.min(firstRow, lastRow),\n col: Math.min(firstColumn, lastColumn),\n cell: <HTMLTableCellElement | null>null,\n };\n let lastCell = {\n row: Math.max(firstRow, lastRow),\n col: Math.max(firstColumn, lastColumn),\n };\n\n firstCell = findTableCellElement(parsedTable, firstCell) || firstCell;\n lastCell = findLastedCoInMergedCell(parsedTable, lastCell) || lastCell;\n\n if (\n isNaN(firstCell.row) ||\n isNaN(firstCell.col) ||\n isNaN(lastCell.row) ||\n isNaN(lastCell.col)\n ) {\n return;\n }\n\n selection = {\n type: 'table',\n table,\n firstRow: firstCell.row,\n firstColumn: firstCell.col,\n lastRow: lastCell.row,\n lastColumn: lastCell.col,\n tableSelectionInfo: selection.tableSelectionInfo,\n };\n\n core.selection.selection = selection;\n\n setTableCellsStyle(core, table, parsedTable, firstCell, lastCell);\n core.api.setEditorStyle(\n core,\n HIDE_SELECTION_CSS_KEY,\n TRANSPARENT_SELECTION_CSS_RULE,\n [SELECTION_SELECTOR]\n );\n\n toggleCaret(core, true /* hide */);\n\n const nodeToSelect = firstCell.cell?.firstElementChild || firstCell.cell;\n\n if (nodeToSelect) {\n setRangeSelection(\n doc,\n (nodeToSelect as HTMLElement) || undefined,\n true /* collapse */\n );\n }\n\n break;\n case 'range':\n addRangeToSelection(doc, selection.range, selection.isReverted);\n\n core.selection.selection = core.domHelper.hasFocus() ? null : selection;\n break;\n\n default:\n core.selection.selection = null;\n break;\n }\n } finally {\n core.selection.skipReselectOnFocus = skipReselectOnFocus;\n }\n\n if (!skipSelectionChangedEvent) {\n const eventData: SelectionChangedEvent = {\n eventType: 'selectionChanged',\n newSelection: selection,\n };\n\n core.api.triggerEvent(core, eventData, true /*broadcast*/);\n }\n};\n\nfunction setRangeSelection(doc: Document, element: HTMLElement | undefined, collapse: boolean) {\n if (element && doc.contains(element)) {\n const range = doc.createRange();\n let isReverted: boolean | undefined = undefined;\n\n range.selectNode(element);\n if (collapse) {\n range.collapse();\n } else {\n const selection = doc.defaultView?.getSelection();\n const range = selection && selection.rangeCount > 0 && selection.getRangeAt(0);\n if (selection && range) {\n isReverted =\n selection.focusNode != range.endContainer ||\n selection.focusOffset != range.endOffset;\n }\n }\n\n addRangeToSelection(doc, range, isReverted);\n }\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { EditorCore, ParsedTable, TableCellCoordinate } from 'roosterjs-content-model-types';
|
|
2
|
+
/**
|
|
3
|
+
* @internal
|
|
4
|
+
* Remove table cell selection styles
|
|
5
|
+
* @param core The EditorCore object
|
|
6
|
+
*/
|
|
7
|
+
export declare function removeTableCellsStyle(core: EditorCore): void;
|
|
8
|
+
/**
|
|
9
|
+
* @internal
|
|
10
|
+
* Set style for table cells in the selection
|
|
11
|
+
* @param core The EditorCore object
|
|
12
|
+
* @param table The HTML table element
|
|
13
|
+
* @param parsedTable The parsed table structure
|
|
14
|
+
* @param firstCell The coordinates of the first selected cell
|
|
15
|
+
* @param lastCell The coordinates of the last selected cell
|
|
16
|
+
*/
|
|
17
|
+
export declare function setTableCellsStyle(core: EditorCore, table: HTMLTableElement, parsedTable: ParsedTable, firstCell: TableCellCoordinate, lastCell: TableCellCoordinate): void;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setTableCellsStyle = exports.removeTableCellsStyle = void 0;
|
|
4
|
+
var ensureUniqueId_1 = require("../setEditorStyle/ensureUniqueId");
|
|
5
|
+
var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
6
|
+
var DOM_SELECTION_CSS_KEY = '_DOMSelection';
|
|
7
|
+
var TABLE_ID = 'table';
|
|
8
|
+
/**
|
|
9
|
+
* @internal
|
|
10
|
+
* Remove table cell selection styles
|
|
11
|
+
* @param core The EditorCore object
|
|
12
|
+
*/
|
|
13
|
+
function removeTableCellsStyle(core) {
|
|
14
|
+
core.api.setEditorStyle(core, DOM_SELECTION_CSS_KEY, '');
|
|
15
|
+
}
|
|
16
|
+
exports.removeTableCellsStyle = removeTableCellsStyle;
|
|
17
|
+
/**
|
|
18
|
+
* @internal
|
|
19
|
+
* Set style for table cells in the selection
|
|
20
|
+
* @param core The EditorCore object
|
|
21
|
+
* @param table The HTML table element
|
|
22
|
+
* @param parsedTable The parsed table structure
|
|
23
|
+
* @param firstCell The coordinates of the first selected cell
|
|
24
|
+
* @param lastCell The coordinates of the last selected cell
|
|
25
|
+
*/
|
|
26
|
+
function setTableCellsStyle(core, table, parsedTable, firstCell, lastCell) {
|
|
27
|
+
var _a, _b;
|
|
28
|
+
var tableId = (0, ensureUniqueId_1.ensureUniqueId)(table, TABLE_ID);
|
|
29
|
+
var tableSelector = (0, roosterjs_content_model_dom_1.getSafeIdSelector)(tableId);
|
|
30
|
+
var tableSelectionColor = core.lifecycle.isDarkMode
|
|
31
|
+
? core.selection.tableCellSelectionBackgroundColorDark
|
|
32
|
+
: core.selection.tableCellSelectionBackgroundColor;
|
|
33
|
+
var tableSelectors = firstCell.row == 0 &&
|
|
34
|
+
firstCell.col == 0 &&
|
|
35
|
+
lastCell.row == parsedTable.length - 1 &&
|
|
36
|
+
lastCell.col == ((_b = (_a = parsedTable[lastCell.row]) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) - 1
|
|
37
|
+
? [tableSelector, tableSelector + " *"]
|
|
38
|
+
: buildTableSelectors(parsedTable, tableSelector, table, firstCell, lastCell);
|
|
39
|
+
core.api.setEditorStyle(core, DOM_SELECTION_CSS_KEY, "background-color:" + tableSelectionColor + "!important;", tableSelectors);
|
|
40
|
+
}
|
|
41
|
+
exports.setTableCellsStyle = setTableCellsStyle;
|
|
42
|
+
/**
|
|
43
|
+
* @internal
|
|
44
|
+
* Build CSS selectors for table cells within the selection range
|
|
45
|
+
*/
|
|
46
|
+
function buildTableSelectors(parsedTable, tableSelector, table, firstCell, lastCell) {
|
|
47
|
+
var selectors = [];
|
|
48
|
+
var cont = 0;
|
|
49
|
+
var indexes = (0, roosterjs_content_model_dom_1.toArray)(table.childNodes)
|
|
50
|
+
.filter(function (node) {
|
|
51
|
+
return ['THEAD', 'TBODY', 'TFOOT'].indexOf((0, roosterjs_content_model_dom_1.isNodeOfType)(node, 'ELEMENT_NODE') ? node.tagName : '') > -1;
|
|
52
|
+
})
|
|
53
|
+
.map(function (node) {
|
|
54
|
+
var result = {
|
|
55
|
+
el: node.tagName,
|
|
56
|
+
start: cont,
|
|
57
|
+
end: node.childNodes.length + cont,
|
|
58
|
+
};
|
|
59
|
+
cont = result.end;
|
|
60
|
+
return result;
|
|
61
|
+
});
|
|
62
|
+
parsedTable.forEach(function (row, rowIndex) {
|
|
63
|
+
var tdCount = 0;
|
|
64
|
+
var midElement = indexes.filter(function (ind) { return ind.start <= rowIndex && ind.end > rowIndex; })[0];
|
|
65
|
+
var middleElSelector = midElement ? '>' + midElement.el + '>' : '>';
|
|
66
|
+
var currentRow = midElement && rowIndex + 1 >= midElement.start
|
|
67
|
+
? rowIndex + 1 - midElement.start
|
|
68
|
+
: rowIndex + 1;
|
|
69
|
+
for (var cellIndex = 0; cellIndex < row.length; cellIndex++) {
|
|
70
|
+
var cell = row[cellIndex];
|
|
71
|
+
if (typeof cell == 'object') {
|
|
72
|
+
tdCount++;
|
|
73
|
+
if (rowIndex >= firstCell.row &&
|
|
74
|
+
rowIndex <= lastCell.row &&
|
|
75
|
+
cellIndex >= firstCell.col &&
|
|
76
|
+
cellIndex <= lastCell.col) {
|
|
77
|
+
var selector = "" + tableSelector + middleElSelector + " tr:nth-child(" + currentRow + ")>" + cell.tagName + ":nth-child(" + tdCount + ")";
|
|
78
|
+
selectors.push(selector, selector + ' *');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
return selectors;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=setTableCellsStyle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setTableCellsStyle.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/setTableCellsStyle.ts"],"names":[],"mappings":"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","sourcesContent":["import { ensureUniqueId } from '../setEditorStyle/ensureUniqueId';\nimport { getSafeIdSelector, isNodeOfType, toArray } from 'roosterjs-content-model-dom';\nimport type { EditorCore, ParsedTable, TableCellCoordinate } from 'roosterjs-content-model-types';\n\nconst DOM_SELECTION_CSS_KEY = '_DOMSelection';\nconst TABLE_ID = 'table';\n\n/**\n * @internal\n * Remove table cell selection styles\n * @param core The EditorCore object\n */\nexport function removeTableCellsStyle(core: EditorCore) {\n core.api.setEditorStyle(core, DOM_SELECTION_CSS_KEY, '');\n}\n\n/**\n * @internal\n * Set style for table cells in the selection\n * @param core The EditorCore object\n * @param table The HTML table element\n * @param parsedTable The parsed table structure\n * @param firstCell The coordinates of the first selected cell\n * @param lastCell The coordinates of the last selected cell\n */\nexport function setTableCellsStyle(\n core: EditorCore,\n table: HTMLTableElement,\n parsedTable: ParsedTable,\n firstCell: TableCellCoordinate,\n lastCell: TableCellCoordinate\n) {\n const tableId = ensureUniqueId(table, TABLE_ID);\n const tableSelector = getSafeIdSelector(tableId);\n const tableSelectionColor = core.lifecycle.isDarkMode\n ? core.selection.tableCellSelectionBackgroundColorDark\n : core.selection.tableCellSelectionBackgroundColor;\n\n const tableSelectors =\n firstCell.row == 0 &&\n firstCell.col == 0 &&\n lastCell.row == parsedTable.length - 1 &&\n lastCell.col == (parsedTable[lastCell.row]?.length ?? 0) - 1\n ? [tableSelector, `${tableSelector} *`]\n : buildTableSelectors(parsedTable, tableSelector, table, firstCell, lastCell);\n\n core.api.setEditorStyle(\n core,\n DOM_SELECTION_CSS_KEY,\n `background-color:${tableSelectionColor}!important;`,\n tableSelectors\n );\n}\n\n/**\n * @internal\n * Build CSS selectors for table cells within the selection range\n */\nfunction buildTableSelectors(\n parsedTable: ParsedTable,\n tableSelector: string,\n table: HTMLTableElement,\n firstCell: TableCellCoordinate,\n lastCell: TableCellCoordinate\n): string[] {\n const selectors: string[] = [];\n\n let cont = 0;\n const indexes = toArray(table.childNodes)\n .filter(\n (node): node is HTMLTableSectionElement =>\n ['THEAD', 'TBODY', 'TFOOT'].indexOf(\n isNodeOfType(node, 'ELEMENT_NODE') ? node.tagName : ''\n ) > -1\n )\n .map(node => {\n const result = {\n el: node.tagName,\n start: cont,\n end: node.childNodes.length + cont,\n };\n\n cont = result.end;\n return result;\n });\n\n parsedTable.forEach((row, rowIndex) => {\n let tdCount = 0;\n\n const midElement = indexes.filter(ind => ind.start <= rowIndex && ind.end > rowIndex)[0];\n const middleElSelector = midElement ? '>' + midElement.el + '>' : '>';\n const currentRow =\n midElement && rowIndex + 1 >= midElement.start\n ? rowIndex + 1 - midElement.start\n : rowIndex + 1;\n\n for (let cellIndex = 0; cellIndex < row.length; cellIndex++) {\n const cell = row[cellIndex];\n\n if (typeof cell == 'object') {\n tdCount++;\n\n if (\n rowIndex >= firstCell.row &&\n rowIndex <= lastCell.row &&\n cellIndex >= firstCell.col &&\n cellIndex <= lastCell.col\n ) {\n const selector = `${tableSelector}${middleElSelector} tr:nth-child(${currentRow})>${cell.tagName}:nth-child(${tdCount})`;\n\n selectors.push(selector, selector + ' *');\n }\n }\n }\n });\n\n return selectors;\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { EditorCore } from 'roosterjs-content-model-types';
|
|
2
|
+
/**
|
|
3
|
+
* @internal
|
|
4
|
+
* Toggle table selection styles on/off
|
|
5
|
+
* @param core The EditorCore object
|
|
6
|
+
* @param isHiding True to hide the table selection background, false to show it
|
|
7
|
+
*/
|
|
8
|
+
export declare function toggleTableSelection(core: EditorCore, isHiding: boolean): void;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toggleTableSelection = void 0;
|
|
4
|
+
var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
5
|
+
var setTableCellsStyle_1 = require("./setTableCellsStyle");
|
|
6
|
+
/**
|
|
7
|
+
* @internal
|
|
8
|
+
* Toggle table selection styles on/off
|
|
9
|
+
* @param core The EditorCore object
|
|
10
|
+
* @param isHiding True to hide the table selection background, false to show it
|
|
11
|
+
*/
|
|
12
|
+
function toggleTableSelection(core, isHiding) {
|
|
13
|
+
var selection = core.selection.selection;
|
|
14
|
+
if ((selection === null || selection === void 0 ? void 0 : selection.type) === 'table') {
|
|
15
|
+
if (isHiding) {
|
|
16
|
+
(0, setTableCellsStyle_1.removeTableCellsStyle)(core);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
var table = selection.table, firstColumn = selection.firstColumn, firstRow = selection.firstRow, lastColumn = selection.lastColumn, lastRow = selection.lastRow;
|
|
20
|
+
var parsedTable = (0, roosterjs_content_model_dom_1.parseTableCells)(table);
|
|
21
|
+
var firstCell = {
|
|
22
|
+
row: Math.min(firstRow, lastRow),
|
|
23
|
+
col: Math.min(firstColumn, lastColumn),
|
|
24
|
+
};
|
|
25
|
+
var lastCell = {
|
|
26
|
+
row: Math.max(firstRow, lastRow),
|
|
27
|
+
col: Math.max(firstColumn, lastColumn),
|
|
28
|
+
};
|
|
29
|
+
(0, setTableCellsStyle_1.setTableCellsStyle)(core, table, parsedTable, firstCell, lastCell);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.toggleTableSelection = toggleTableSelection;
|
|
34
|
+
//# sourceMappingURL=toggleTableSelection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toggleTableSelection.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/toggleTableSelection.ts"],"names":[],"mappings":";;;AAAA,2EAA8D;AAC9D,2DAAiF;AAIjF;;;;;GAKG;AACH,SAAgB,oBAAoB,CAAC,IAAgB,EAAE,QAAiB;IACpE,IAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;IAE3C,IAAI,CAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,IAAI,MAAK,OAAO,EAAE;QAC7B,IAAI,QAAQ,EAAE;YACV,IAAA,0CAAqB,EAAC,IAAI,CAAC,CAAC;SAC/B;aAAM;YACK,IAAA,KAAK,GAAiD,SAAS,MAA1D,EAAE,WAAW,GAAoC,SAAS,YAA7C,EAAE,QAAQ,GAA0B,SAAS,SAAnC,EAAE,UAAU,GAAc,SAAS,WAAvB,EAAE,OAAO,GAAK,SAAS,QAAd,CAAe;YACxE,IAAM,WAAW,GAAG,IAAA,6CAAe,EAAC,KAAK,CAAC,CAAC;YAC3C,IAAM,SAAS,GAAwB;gBACnC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC;gBAChC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC;aACzC,CAAC;YACF,IAAM,QAAQ,GAAwB;gBAClC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC;gBAChC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC;aACzC,CAAC;YAEF,IAAA,uCAAkB,EAAC,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;SACrE;KACJ;AACL,CAAC;AArBD,oDAqBC","sourcesContent":["import { parseTableCells } from 'roosterjs-content-model-dom';\nimport { removeTableCellsStyle, setTableCellsStyle } from './setTableCellsStyle';\n\nimport type { EditorCore, TableCellCoordinate } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Toggle table selection styles on/off\n * @param core The EditorCore object\n * @param isHiding True to hide the table selection background, false to show it\n */\nexport function toggleTableSelection(core: EditorCore, isHiding: boolean) {\n const selection = core.selection.selection;\n\n if (selection?.type === 'table') {\n if (isHiding) {\n removeTableCellsStyle(core);\n } else {\n const { table, firstColumn, firstRow, lastColumn, lastRow } = selection;\n const parsedTable = parseTableCells(table);\n const firstCell: TableCellCoordinate = {\n row: Math.min(firstRow, lastRow),\n col: Math.min(firstColumn, lastColumn),\n };\n const lastCell: TableCellCoordinate = {\n row: Math.max(firstRow, lastRow),\n col: Math.max(firstColumn, lastColumn),\n };\n\n setTableCellsStyle(core, table, parsedTable, firstCell, lastCell);\n }\n }\n}\n"]}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.switchShadowEdit = void 0;
|
|
4
4
|
var roosterjs_content_model_dom_1 = require("roosterjs-content-model-dom");
|
|
5
5
|
var toggleCaret_1 = require("../setDOMSelection/toggleCaret");
|
|
6
|
+
var toggleTableSelection_1 = require("../setDOMSelection/toggleTableSelection");
|
|
6
7
|
/**
|
|
7
8
|
* @internal
|
|
8
9
|
* Switch the Shadow Edit mode of editor On/Off
|
|
@@ -26,11 +27,13 @@ var switchShadowEdit = function (editorCore, isOn) {
|
|
|
26
27
|
core.cache.cachedModel = model;
|
|
27
28
|
}
|
|
28
29
|
(0, toggleCaret_1.toggleCaret)(core, true /* hide */);
|
|
30
|
+
(0, toggleTableSelection_1.toggleTableSelection)(core, true /* hide */);
|
|
29
31
|
core.lifecycle.shadowEditFragment = fragment;
|
|
30
32
|
}
|
|
31
33
|
else {
|
|
32
34
|
core.lifecycle.shadowEditFragment = null;
|
|
33
35
|
(0, toggleCaret_1.toggleCaret)(core, false /* hide */);
|
|
36
|
+
(0, toggleTableSelection_1.toggleTableSelection)(core, false /* hide */);
|
|
34
37
|
core.api.triggerEvent(core, {
|
|
35
38
|
eventType: 'leavingShadowEdit',
|
|
36
39
|
}, false /*broadcast*/);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switchShadowEdit.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/switchShadowEdit/switchShadowEdit.ts"],"names":[],"mappings":";;;AAAA,2EAAgF;AAChF,8DAA6D;
|
|
1
|
+
{"version":3,"file":"switchShadowEdit.js","sourceRoot":"","sources":["../../../../../packages/roosterjs-content-model-core/lib/coreApi/switchShadowEdit/switchShadowEdit.ts"],"names":[],"mappings":";;;AAAA,2EAAgF;AAChF,8DAA6D;AAC7D,gFAA+E;AAG/E;;;;;GAKG;AACI,IAAM,gBAAgB,GAAqB,UAAC,UAAU,EAAE,IAAI;IAC/D,IAAM,IAAI,GAAG,UAAU,CAAC;IAExB,IAAI,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE;QAC7C,IAAI,IAAI,EAAE;YACN,IAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACjF,IAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,sBAAsB,EAAE,CAAC;YACzE,IAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAE7D,IAAA,4CAAc,EAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YAErC,IAAI,CAAC,GAAG,CAAC,YAAY,CACjB,IAAI,EACJ;gBACI,SAAS,EAAE,mBAAmB;aACjC,EACD,KAAK,CAAC,aAAa,CACtB,CAAC;YAEF,oIAAoI;YACpI,6DAA6D;YAC7D,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,KAAK,EAAE;gBAClC,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC;aAClC;YAED,IAAA,yBAAW,EAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;YACnC,IAAA,2CAAoB,EAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;YAE5C,IAAI,CAAC,SAAS,CAAC,kBAAkB,GAAG,QAAQ,CAAC;SAChD;aAAM;YACH,IAAI,CAAC,SAAS,CAAC,kBAAkB,GAAG,IAAI,CAAC;YAEzC,IAAA,yBAAW,EAAC,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;YACpC,IAAA,2CAAoB,EAAC,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;YAE7C,IAAI,CAAC,GAAG,CAAC,YAAY,CACjB,IAAI,EACJ;gBACI,SAAS,EAAE,mBAAmB;aACjC,EACD,KAAK,CAAC,aAAa,CACtB,CAAC;YAEF,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;gBACxB,iDAAiD;gBACjD,IAAA,+CAAiB,EAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,cAAO,CAAC,CAAC,CAAC;gBAEpD,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;oBACnD,eAAe,EAAE,IAAI,EAAE,qGAAqG;iBAC/H,CAAC,CAAC;aACN;SACJ;KACJ;AACL,CAAC,CAAC;AArDW,QAAA,gBAAgB,oBAqD3B","sourcesContent":["import { iterateSelections, moveChildNodes } from 'roosterjs-content-model-dom';\nimport { toggleCaret } from '../setDOMSelection/toggleCaret';\nimport { toggleTableSelection } from '../setDOMSelection/toggleTableSelection';\nimport type { SwitchShadowEdit } from 'roosterjs-content-model-types';\n\n/**\n * @internal\n * Switch the Shadow Edit mode of editor On/Off\n * @param editorCore The EditorCore object\n * @param isOn True to switch On, False to switch Off\n */\nexport const switchShadowEdit: SwitchShadowEdit = (editorCore, isOn): void => {\n const core = editorCore;\n\n if (isOn != !!core.lifecycle.shadowEditFragment) {\n if (isOn) {\n const model = !core.cache.cachedModel ? core.api.createContentModel(core) : null;\n const fragment = core.logicalRoot.ownerDocument.createDocumentFragment();\n const clonedRoot = core.logicalRoot.cloneNode(true /*deep*/);\n\n moveChildNodes(fragment, clonedRoot);\n\n core.api.triggerEvent(\n core,\n {\n eventType: 'enteredShadowEdit',\n },\n false /*broadcast*/\n );\n\n // This need to be done after EnteredShadowEdit event is triggered since EnteredShadowEdit event will cause a SelectionChanged event\n // if current selection is table selection or image selection\n if (!core.cache.cachedModel && model) {\n core.cache.cachedModel = model;\n }\n\n toggleCaret(core, true /* hide */);\n toggleTableSelection(core, true /* hide */);\n\n core.lifecycle.shadowEditFragment = fragment;\n } else {\n core.lifecycle.shadowEditFragment = null;\n\n toggleCaret(core, false /* hide */);\n toggleTableSelection(core, false /* hide */);\n\n core.api.triggerEvent(\n core,\n {\n eventType: 'leavingShadowEdit',\n },\n false /*broadcast*/\n );\n\n if (core.cache.cachedModel) {\n // Force clear cached element from selected block\n iterateSelections(core.cache.cachedModel, () => {});\n\n core.api.setContentModel(core, core.cache.cachedModel, {\n ignoreSelection: true, // Do not set focus and selection when quit shadow edit, focus may remain in UI control (picker, ...)\n });\n }\n }\n }\n};\n"]}
|