roosterjs 9.2.0 → 9.3.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/dist/rooster.js CHANGED
@@ -2095,7 +2095,7 @@ exports["default"] = getDarkColor;
2095
2095
 
2096
2096
  Object.defineProperty(exports, "__esModule", ({ value: true }));
2097
2097
  exports.formatTextSegmentBeforeSelectionMarker = exports.formatSegmentWithContentModel = exports.formatParagraphWithContentModel = exports.formatImageWithContentModel = exports.formatTableWithContentModel = exports.clearSelectedCells = exports.insertTableColumn = exports.insertTableRow = exports.insertEntity = exports.toggleCode = exports.setParagraphMargin = exports.adjustImageSelection = exports.setImageAltText = exports.adjustLinkSelection = exports.removeLink = exports.insertLink = exports.clearFormat = exports.getFormatState = exports.changeImage = exports.setImageBoxShadow = exports.setImageBorder = exports.setSpacing = exports.toggleBlockQuote = exports.setHeadingLevel = exports.setDirection = exports.setAlignment = exports.setIndentation = exports.setListStartNumber = exports.setListStyle = exports.insertImage = exports.changeCapitalization = exports.applySegmentFormat = exports.changeFontSize = exports.setTextColor = exports.setFontSize = exports.setFontName = exports.setBackgroundColor = exports.toggleSuperscript = exports.toggleSubscript = exports.toggleStrikethrough = exports.toggleUnderline = exports.toggleItalic = exports.toggleBold = exports.toggleNumbering = exports.toggleBullet = exports.applyTableBorderFormat = exports.editTable = exports.setTableCellShade = exports.formatTable = exports.insertTable = void 0;
2098
- exports.getListAnnounceData = exports.matchLink = exports.setModelIndentation = exports.findListItemsInSameThread = exports.setModelListStartNumber = exports.setModelListStyle = exports.setListType = void 0;
2098
+ exports.getListAnnounceData = exports.matchLink = exports.setModelIndentation = exports.findListItemsInSameThread = exports.setModelListStartNumber = exports.setModelListStyle = exports.setListType = exports.formatInsertPointWithContentModel = void 0;
2099
2099
  var insertTable_1 = __webpack_require__(/*! ./publicApi/table/insertTable */ "./packages/roosterjs-content-model-api/lib/publicApi/table/insertTable.ts");
2100
2100
  Object.defineProperty(exports, "insertTable", ({ enumerable: true, get: function () { return insertTable_1.insertTable; } }));
2101
2101
  var formatTable_1 = __webpack_require__(/*! ./publicApi/table/formatTable */ "./packages/roosterjs-content-model-api/lib/publicApi/table/formatTable.ts");
@@ -2196,6 +2196,8 @@ var formatSegmentWithContentModel_1 = __webpack_require__(/*! ./publicApi/utils/
2196
2196
  Object.defineProperty(exports, "formatSegmentWithContentModel", ({ enumerable: true, get: function () { return formatSegmentWithContentModel_1.formatSegmentWithContentModel; } }));
2197
2197
  var formatTextSegmentBeforeSelectionMarker_1 = __webpack_require__(/*! ./publicApi/utils/formatTextSegmentBeforeSelectionMarker */ "./packages/roosterjs-content-model-api/lib/publicApi/utils/formatTextSegmentBeforeSelectionMarker.ts");
2198
2198
  Object.defineProperty(exports, "formatTextSegmentBeforeSelectionMarker", ({ enumerable: true, get: function () { return formatTextSegmentBeforeSelectionMarker_1.formatTextSegmentBeforeSelectionMarker; } }));
2199
+ var formatInsertPointWithContentModel_1 = __webpack_require__(/*! ./publicApi/utils/formatInsertPointWithContentModel */ "./packages/roosterjs-content-model-api/lib/publicApi/utils/formatInsertPointWithContentModel.ts");
2200
+ Object.defineProperty(exports, "formatInsertPointWithContentModel", ({ enumerable: true, get: function () { return formatInsertPointWithContentModel_1.formatInsertPointWithContentModel; } }));
2199
2201
  var setListType_1 = __webpack_require__(/*! ./modelApi/list/setListType */ "./packages/roosterjs-content-model-api/lib/modelApi/list/setListType.ts");
2200
2202
  Object.defineProperty(exports, "setListType", ({ enumerable: true, get: function () { return setListType_1.setListType; } }));
2201
2203
  var setModelListStyle_1 = __webpack_require__(/*! ./modelApi/list/setModelListStyle */ "./packages/roosterjs-content-model-api/lib/modelApi/list/setModelListStyle.ts");
@@ -6664,7 +6666,11 @@ exports.formatInsertPointWithContentModel = void 0;
6664
6666
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
6665
6667
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
6666
6668
  /**
6667
- * @internal
6669
+ * Format content model at a given insert point with a callback function
6670
+ * @param editor The editor object
6671
+ * @param insertPoint The insert point to format
6672
+ * @param callback The callback function to format the content model
6673
+ * @param options Options to control the behavior of the formatting
6668
6674
  */
6669
6675
  function formatInsertPointWithContentModel(editor, insertPoint, callback, options) {
6670
6676
  var bundle = {
@@ -7531,16 +7537,7 @@ function isCssVariable(value) {
7531
7537
  Object.defineProperty(exports, "__esModule", ({ value: true }));
7532
7538
  exports.exportContent = void 0;
7533
7539
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
7534
- /**
7535
- * Export string content of editor
7536
- * @param editor The editor to get content from
7537
- * @param mode Mode of content to export. It supports:
7538
- * - HTML: Export HTML content. If there are entities, this will cause EntityOperation event with option = 'replaceTemporaryContent' to get a dehydrated entity
7539
- * - PlainText: Export plain text content
7540
- * - PlainTextFast: Export plain text using editor's textContent property directly
7541
- * @param options @optional Options for Model to DOM conversion
7542
- */
7543
- function exportContent(editor, mode, options) {
7540
+ function exportContent(editor, mode, optionsOrCallbacks) {
7544
7541
  if (mode === void 0) { mode = 'HTML'; }
7545
7542
  if (mode == 'PlainTextFast') {
7546
7543
  return editor.getDOMHelper().getTextContent();
@@ -7548,12 +7545,12 @@ function exportContent(editor, mode, options) {
7548
7545
  else {
7549
7546
  var model = editor.getContentModelCopy('clean');
7550
7547
  if (mode == 'PlainText') {
7551
- return (0, roosterjs_content_model_dom_1.contentModelToText)(model);
7548
+ return (0, roosterjs_content_model_dom_1.contentModelToText)(model, undefined /*separator*/, optionsOrCallbacks);
7552
7549
  }
7553
7550
  else {
7554
7551
  var doc = editor.getDocument();
7555
7552
  var div = doc.createElement('div');
7556
- (0, roosterjs_content_model_dom_1.contentModelToDom)(doc, div, model, (0, roosterjs_content_model_dom_1.createModelToDomContext)(undefined /*editorContext*/, options));
7553
+ (0, roosterjs_content_model_dom_1.contentModelToDom)(doc, div, model, (0, roosterjs_content_model_dom_1.createModelToDomContext)(undefined /*editorContext*/, optionsOrCallbacks));
7557
7554
  editor.triggerEvent('extractContentWithDom', { clonedRoot: div }, true /*broadcast*/);
7558
7555
  return div.innerHTML;
7559
7556
  }
@@ -7759,6 +7756,7 @@ function mergePasteContent(editor, eventResult, clipboardData) {
7759
7756
  }, {
7760
7757
  changeSource: roosterjs_content_model_dom_1.ChangeSource.Paste,
7761
7758
  getChangeData: function () { return clipboardData; },
7759
+ scrollCaretIntoView: true,
7762
7760
  apiName: 'paste',
7763
7761
  });
7764
7762
  }
@@ -7806,7 +7804,10 @@ function paste(editor, clipboardData, pasteType) {
7806
7804
  editor.focus();
7807
7805
  var trustedHTMLHandler = editor.getTrustedHTMLHandler();
7808
7806
  if (!clipboardData.modelBeforePaste) {
7809
- clipboardData.modelBeforePaste = (0, mergePasteContent_1.cloneModelForPaste)(editor.getContentModelCopy('connected'));
7807
+ editor.formatContentModel(function (model) {
7808
+ clipboardData.modelBeforePaste = (0, mergePasteContent_1.cloneModelForPaste)(model);
7809
+ return false;
7810
+ });
7810
7811
  }
7811
7812
  // 1. Prepare variables
7812
7813
  var doc = createDOMFromHtml(clipboardData.rawHtml, trustedHTMLHandler);
@@ -8427,34 +8428,33 @@ var createContentModel = function (core, option, selectionOverride) {
8427
8428
  var _a;
8428
8429
  // Flush all mutations if any, so that we can get an up-to-date Content Model
8429
8430
  (_a = core.cache.textMutationObserver) === null || _a === void 0 ? void 0 : _a.flushMutations();
8430
- var cachedModel = selectionOverride || (option && !option.tryGetFromCache) ? null : core.cache.cachedModel;
8431
- if (cachedModel && core.lifecycle.shadowEditFragment) {
8432
- // When in shadow edit, use a cloned model so we won't pollute the cached one
8433
- cachedModel = (0, roosterjs_content_model_dom_1.cloneModel)(cachedModel, { includeCachedElement: true });
8431
+ if (!selectionOverride && (!option || option.tryGetFromCache)) {
8432
+ var cachedModel = core.cache.cachedModel;
8433
+ if (cachedModel) {
8434
+ // When in shadow edit, use a cloned model so we won't pollute the cached one
8435
+ return core.lifecycle.shadowEditFragment
8436
+ ? (0, roosterjs_content_model_dom_1.cloneModel)(cachedModel, { includeCachedElement: true })
8437
+ : cachedModel;
8438
+ }
8434
8439
  }
8435
- if (cachedModel) {
8436
- return cachedModel;
8440
+ var selection = selectionOverride == 'none'
8441
+ ? undefined
8442
+ : selectionOverride || core.api.getDOMSelection(core) || undefined;
8443
+ var saveIndex = !option && !selectionOverride;
8444
+ var editorContext = core.api.createEditorContext(core, saveIndex);
8445
+ var settings = core.environment.domToModelSettings;
8446
+ var domToModelContext = option
8447
+ ? (0, roosterjs_content_model_dom_1.createDomToModelContext)(editorContext, settings.builtIn, settings.customized, option)
8448
+ : (0, roosterjs_content_model_dom_1.createDomToModelContextWithConfig)(settings.calculated, editorContext);
8449
+ if (selection) {
8450
+ domToModelContext.selection = selection;
8437
8451
  }
8438
- else {
8439
- var selection = selectionOverride == 'none'
8440
- ? undefined
8441
- : selectionOverride || core.api.getDOMSelection(core) || undefined;
8442
- var saveIndex = !option && !selectionOverride;
8443
- var editorContext = core.api.createEditorContext(core, saveIndex);
8444
- var settings = core.environment.domToModelSettings;
8445
- var domToModelContext = option
8446
- ? (0, roosterjs_content_model_dom_1.createDomToModelContext)(editorContext, settings.builtIn, settings.customized, option)
8447
- : (0, roosterjs_content_model_dom_1.createDomToModelContextWithConfig)(settings.calculated, editorContext);
8448
- if (selection) {
8449
- domToModelContext.selection = selection;
8450
- }
8451
- var model = (0, roosterjs_content_model_dom_1.domToContentModel)(core.logicalRoot, domToModelContext);
8452
- if (saveIndex) {
8453
- core.cache.cachedModel = model;
8454
- (0, updateCachedSelection_1.updateCachedSelection)(core.cache, selection);
8455
- }
8456
- return model;
8452
+ var model = (0, roosterjs_content_model_dom_1.domToContentModel)(core.logicalRoot, domToModelContext);
8453
+ if (saveIndex) {
8454
+ core.cache.cachedModel = model;
8455
+ (0, updateCachedSelection_1.updateCachedSelection)(core.cache, selection);
8457
8456
  }
8457
+ return model;
8458
8458
  };
8459
8459
  exports.createContentModel = createContentModel;
8460
8460
 
@@ -8574,7 +8574,7 @@ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-mo
8574
8574
  */
8575
8575
  var formatContentModel = function (core, formatter, options, domToModelOptions) {
8576
8576
  var _a;
8577
- var _b = options || {}, apiName = _b.apiName, onNodeCreated = _b.onNodeCreated, getChangeData = _b.getChangeData, changeSource = _b.changeSource, rawEvent = _b.rawEvent, selectionOverride = _b.selectionOverride;
8577
+ var _b = options || {}, apiName = _b.apiName, onNodeCreated = _b.onNodeCreated, getChangeData = _b.getChangeData, changeSource = _b.changeSource, rawEvent = _b.rawEvent, selectionOverride = _b.selectionOverride, scrollCaretIntoView = _b.scrollCaretIntoView;
8578
8578
  var model = core.api.createContentModel(core, domToModelOptions, selectionOverride);
8579
8579
  var context = {
8580
8580
  newEntities: [],
@@ -8599,6 +8599,11 @@ var formatContentModel = function (core, formatter, options, domToModelOptions)
8599
8599
  (_a = core.api.setContentModel(core, model, hasFocus ? undefined : { ignoreSelection: true }, // If editor did not have focus before format, do not set focus after format
8600
8600
  onNodeCreated)) !== null && _a !== void 0 ? _a : undefined;
8601
8601
  handlePendingFormat(core, context, selection);
8602
+ if (selection && scrollCaretIntoView) {
8603
+ var selectionRoot = (0, roosterjs_content_model_dom_1.getSelectionRootNode)(selection);
8604
+ var rootElement = selectionRoot && core.domHelper.findClosestElementAncestor(selectionRoot);
8605
+ rootElement === null || rootElement === void 0 ? void 0 : rootElement.scrollIntoView();
8606
+ }
8602
8607
  var eventData = {
8603
8608
  eventType: 'contentChanged',
8604
8609
  contentModel: clearModelCache ? undefined : model,
@@ -9291,7 +9296,7 @@ var TABLE_ID = 'table';
9291
9296
  var DEFAULT_SELECTION_BORDER_COLOR = '#DB626C';
9292
9297
  var TABLE_CSS_RULE = 'background-color:#C6C6C6!important;';
9293
9298
  var CARET_CSS_RULE = 'caret-color: transparent';
9294
- var TRANSPARENT_SELECTION_CSS_RULE = 'background-color: transparent !important';
9299
+ var TRANSPARENT_SELECTION_CSS_RULE = 'background-color: transparent !important;';
9295
9300
  var SELECTION_SELECTOR = '*::selection';
9296
9301
  /**
9297
9302
  * @internal
@@ -9309,9 +9314,12 @@ var setDOMSelection = function (core, selection, skipSelectionChangedEvent) {
9309
9314
  try {
9310
9315
  switch (selection === null || selection === void 0 ? void 0 : selection.type) {
9311
9316
  case 'image':
9312
- var image = selection.image;
9313
- core.selection.selection = selection;
9314
- core.api.setEditorStyle(core, DOM_SELECTION_CSS_KEY, "outline-style:auto!important; outline-color:" + (core.selection.imageSelectionBorderColor || DEFAULT_SELECTION_BORDER_COLOR) + "!important;", ["#" + (0, ensureUniqueId_1.ensureUniqueId)(image, IMAGE_ID)]);
9317
+ var image = ensureImageHasSpanParent(selection.image);
9318
+ core.selection.selection = {
9319
+ type: 'image',
9320
+ image: image,
9321
+ };
9322
+ core.api.setEditorStyle(core, DOM_SELECTION_CSS_KEY, "outline-style:auto!important; outline-color:" + (core.selection.imageSelectionBorderColor || DEFAULT_SELECTION_BORDER_COLOR) + "!important;", ["span:has(>img#" + (0, ensureUniqueId_1.ensureUniqueId)(image, IMAGE_ID) + ")"]);
9315
9323
  core.api.setEditorStyle(core, HIDE_SELECTION_CSS_KEY, TRANSPARENT_SELECTION_CSS_RULE, [SELECTION_SELECTOR]);
9316
9324
  setRangeSelection(doc, image, false /* collapse */);
9317
9325
  break;
@@ -9442,6 +9450,18 @@ function setRangeSelection(doc, element, collapse) {
9442
9450
  (0, addRangeToSelection_1.addRangeToSelection)(doc, range, isReverted);
9443
9451
  }
9444
9452
  }
9453
+ function ensureImageHasSpanParent(image) {
9454
+ var parent = image.parentElement;
9455
+ if (parent &&
9456
+ (0, roosterjs_content_model_dom_1.isNodeOfType)(parent, 'ELEMENT_NODE') &&
9457
+ (0, roosterjs_content_model_dom_1.isElementOfType)(parent, 'span') &&
9458
+ parent.firstChild == image &&
9459
+ parent.lastChild == image) {
9460
+ return image;
9461
+ }
9462
+ (0, roosterjs_content_model_dom_1.wrap)(image.ownerDocument, image, 'span');
9463
+ return image;
9464
+ }
9445
9465
 
9446
9466
 
9447
9467
  /***/ }),
@@ -12992,6 +13012,11 @@ var UndoPlugin = /** @class */ (function () {
12992
13012
  case 'beforeKeyboardEditing':
12993
13013
  this.onBeforeKeyboardEditing(event.rawEvent);
12994
13014
  break;
13015
+ case 'mouseDown':
13016
+ if (this.state.snapshotsManager.hasNewContent) {
13017
+ this.addUndoSnapshot();
13018
+ }
13019
+ break;
12995
13020
  }
12996
13021
  };
12997
13022
  UndoPlugin.prototype.onKeyDown = function (editor, evt) {
@@ -13189,9 +13214,6 @@ var Editor = /** @class */ (function () {
13189
13214
  /**
13190
13215
  * Create Content Model from DOM tree in this editor
13191
13216
  * @param mode What kind of Content Model we want. Currently we support the following values:
13192
- * - connected: Returns a connect Content Model object. "Connected" means if there is any entity inside editor, the returned Content Model will
13193
- * contain the same wrapper element for entity. This option should only be used in some special cases. In most cases we should use "disconnected"
13194
- * to get a fully disconnected Content Model so that any change to the model will not impact editor content.
13195
13217
  * - disconnected: Returns a disconnected clone of Content Model from editor which you can do any change on it and it won't impact the editor content.
13196
13218
  * If there is any entity in editor, the returned object will contain cloned copy of entity wrapper element.
13197
13219
  * If editor is in dark mode, the cloned entity will be converted back to light mode.
@@ -13201,10 +13223,7 @@ var Editor = /** @class */ (function () {
13201
13223
  Editor.prototype.getContentModelCopy = function (mode) {
13202
13224
  var core = this.getCore();
13203
13225
  switch (mode) {
13204
- case 'connected':
13205
- return core.api.createContentModel(core, {
13206
- tryGetFromCache: true, // Pass an option here to force disable save index
13207
- });
13226
+ case 'connected': // Get a connected model is deprecated. Now we will always return disconnected model
13208
13227
  case 'disconnected':
13209
13228
  return (0, roosterjs_content_model_dom_1.cloneModel)(core.api.createContentModel(core, {
13210
13229
  processorOverride: {
@@ -25135,7 +25154,8 @@ function removeUnnecessarySpan(root) {
25135
25154
  for (var child = root.firstChild; child;) {
25136
25155
  if ((0, isNodeOfType_1.isNodeOfType)(child, 'ELEMENT_NODE') &&
25137
25156
  child.tagName == 'SPAN' &&
25138
- child.attributes.length == 0) {
25157
+ child.attributes.length == 0 &&
25158
+ !isImageSpan(child)) {
25139
25159
  var node = child;
25140
25160
  var refNode = child.nextSibling;
25141
25161
  child = child.nextSibling;
@@ -25152,6 +25172,11 @@ function removeUnnecessarySpan(root) {
25152
25172
  }
25153
25173
  }
25154
25174
  exports.removeUnnecessarySpan = removeUnnecessarySpan;
25175
+ var isImageSpan = function (child) {
25176
+ return ((0, isNodeOfType_1.isNodeOfType)(child.firstChild, 'ELEMENT_NODE') &&
25177
+ child.firstChild.tagName == 'IMG' &&
25178
+ child.firstChild == child.lastChild);
25179
+ };
25155
25180
 
25156
25181
 
25157
25182
  /***/ }),
@@ -25290,65 +25315,84 @@ exports.stackFormat = stackFormat;
25290
25315
  Object.defineProperty(exports, "__esModule", ({ value: true }));
25291
25316
  exports.contentModelToText = void 0;
25292
25317
  var TextForHR = '________________________________________';
25318
+ var defaultCallbacks = {
25319
+ onDivider: function (divider) { return (divider.tagName == 'hr' ? TextForHR : ''); },
25320
+ onEntityBlock: function () { return ''; },
25321
+ onEntitySegment: function (entity) { var _a; return (_a = entity.wrapper.textContent) !== null && _a !== void 0 ? _a : ''; },
25322
+ onGeneralSegment: function (segment) { var _a; return (_a = segment.element.textContent) !== null && _a !== void 0 ? _a : ''; },
25323
+ onImage: function () { return ' '; },
25324
+ onText: function (text) { return text.text; },
25325
+ onParagraph: function () { return true; },
25326
+ onTable: function () { return true; },
25327
+ onBlockGroup: function () { return true; },
25328
+ };
25293
25329
  /**
25294
25330
  * Convert Content Model to plain text
25295
25331
  * @param model The source Content Model
25296
25332
  * @param [separator='\r\n'] The separator string used for connect lines
25333
+ * @param callbacks Callbacks to customize the behavior of contentModelToText function
25297
25334
  */
25298
- function contentModelToText(model, separator) {
25335
+ function contentModelToText(model, separator, callbacks) {
25299
25336
  if (separator === void 0) { separator = '\r\n'; }
25300
25337
  var textArray = [];
25301
- contentModelToTextArray(model, textArray);
25338
+ var fullCallbacks = Object.assign({}, defaultCallbacks, callbacks);
25339
+ contentModelToTextArray(model, textArray, fullCallbacks);
25302
25340
  return textArray.join(separator);
25303
25341
  }
25304
25342
  exports.contentModelToText = contentModelToText;
25305
- function contentModelToTextArray(group, textArray) {
25306
- group.blocks.forEach(function (block) {
25307
- switch (block.blockType) {
25308
- case 'Paragraph':
25309
- var text_1 = '';
25310
- block.segments.forEach(function (segment) {
25311
- switch (segment.segmentType) {
25312
- case 'Br':
25343
+ function contentModelToTextArray(group, textArray, callbacks) {
25344
+ if (callbacks.onBlockGroup(group)) {
25345
+ group.blocks.forEach(function (block) {
25346
+ switch (block.blockType) {
25347
+ case 'Paragraph':
25348
+ if (callbacks.onParagraph(block)) {
25349
+ var text_1 = '';
25350
+ block.segments.forEach(function (segment) {
25351
+ switch (segment.segmentType) {
25352
+ case 'Br':
25353
+ textArray.push(text_1);
25354
+ text_1 = '';
25355
+ break;
25356
+ case 'Entity':
25357
+ text_1 += callbacks.onEntitySegment(segment);
25358
+ break;
25359
+ case 'General':
25360
+ text_1 += callbacks.onGeneralSegment(segment);
25361
+ break;
25362
+ case 'Text':
25363
+ text_1 += callbacks.onText(segment);
25364
+ break;
25365
+ case 'Image':
25366
+ text_1 += callbacks.onImage(segment);
25367
+ break;
25368
+ }
25369
+ });
25370
+ if (text_1) {
25313
25371
  textArray.push(text_1);
25314
- text_1 = '';
25315
- break;
25316
- case 'Entity':
25317
- text_1 += segment.wrapper.textContent || '';
25318
- break;
25319
- case 'General':
25320
- text_1 += segment.element.textContent || '';
25321
- break;
25322
- case 'Text':
25323
- text_1 += segment.text;
25324
- break;
25325
- case 'Image':
25326
- text_1 += ' ';
25327
- break;
25372
+ }
25328
25373
  }
25329
- });
25330
- if (text_1) {
25331
- textArray.push(text_1);
25332
- }
25333
- break;
25334
- case 'Divider':
25335
- textArray.push(block.tagName == 'hr' ? TextForHR : '');
25336
- break;
25337
- case 'Entity':
25338
- textArray.push('');
25339
- break;
25340
- case 'Table':
25341
- block.rows.forEach(function (row) {
25342
- return row.cells.forEach(function (cell) {
25343
- contentModelToTextArray(cell, textArray);
25344
- });
25345
- });
25346
- break;
25347
- case 'BlockGroup':
25348
- contentModelToTextArray(block, textArray);
25349
- break;
25350
- }
25351
- });
25374
+ break;
25375
+ case 'Divider':
25376
+ textArray.push(callbacks.onDivider(block));
25377
+ break;
25378
+ case 'Entity':
25379
+ textArray.push(callbacks.onEntityBlock(block));
25380
+ break;
25381
+ case 'Table':
25382
+ if (callbacks.onTable(block)) {
25383
+ block.rows.forEach(function (row) {
25384
+ return row.cells.forEach(function (cell) {
25385
+ contentModelToTextArray(cell, textArray, callbacks);
25386
+ });
25387
+ });
25388
+ }
25389
+ break;
25390
+ case 'BlockGroup':
25391
+ contentModelToTextArray(block, textArray, callbacks);
25392
+ break;
25393
+ }
25394
+ });
25395
+ }
25352
25396
  }
25353
25397
 
25354
25398
 
@@ -27139,6 +27183,7 @@ function keyboardDelete(editor, rawEvent) {
27139
27183
  rawEvent: rawEvent,
27140
27184
  changeSource: roosterjs_content_model_dom_1.ChangeSource.Keyboard,
27141
27185
  getChangeData: function () { return rawEvent.which; },
27186
+ scrollCaretIntoView: true,
27142
27187
  apiName: rawEvent.key == 'Delete' ? 'handleDeleteKey' : 'handleBackspaceKey',
27143
27188
  });
27144
27189
  }
@@ -27231,6 +27276,7 @@ function keyboardInput(editor, rawEvent) {
27231
27276
  return false;
27232
27277
  }
27233
27278
  }, {
27279
+ scrollCaretIntoView: true,
27234
27280
  rawEvent: rawEvent,
27235
27281
  });
27236
27282
  return true;
@@ -27730,7 +27776,7 @@ var HyperlinkPlugin = /** @class */ (function () {
27730
27776
  */
27731
27777
  HyperlinkPlugin.prototype.onPluginEvent = function (event) {
27732
27778
  var _this = this;
27733
- var _a, _b;
27779
+ var _a, _b, _c;
27734
27780
  var matchedLink;
27735
27781
  if (event.eventType == 'keyDown') {
27736
27782
  var selection = (_a = this.editor) === null || _a === void 0 ? void 0 : _a.getDOMSelection();
@@ -27775,6 +27821,9 @@ var HyperlinkPlugin = /** @class */ (function () {
27775
27821
  }
27776
27822
  });
27777
27823
  }
27824
+ else if (event.eventType == 'contentChanged') {
27825
+ (_c = this.domHelper) === null || _c === void 0 ? void 0 : _c.setDomAttribute('title', null /*value*/);
27826
+ }
27778
27827
  };
27779
27828
  HyperlinkPlugin.prototype.runWithHyperlink = function (node, callback) {
27780
27829
  var _a;
@@ -30583,11 +30632,13 @@ var TableEditPlugin = /** @class */ (function () {
30583
30632
  * The container must not be affected by transform: scale(), otherwise the position calculation will be wrong.
30584
30633
  * If not specified, the plugin will be inserted in document.body
30585
30634
  * @param onTableEditorCreated An optional callback to customize the Table Editors elements when created.
30635
+ * @param disableFeatures An optional array of TableEditFeatures to disable
30586
30636
  */
30587
- function TableEditPlugin(anchorContainerSelector, onTableEditorCreated) {
30637
+ function TableEditPlugin(anchorContainerSelector, onTableEditorCreated, disableFeatures) {
30588
30638
  var _this = this;
30589
30639
  this.anchorContainerSelector = anchorContainerSelector;
30590
30640
  this.onTableEditorCreated = onTableEditorCreated;
30641
+ this.disableFeatures = disableFeatures;
30591
30642
  this.editor = null;
30592
30643
  this.onMouseMoveDisposer = null;
30593
30644
  this.tableRectMap = null;
@@ -30696,7 +30747,7 @@ var TableEditPlugin = /** @class */ (function () {
30696
30747
  var container = this.anchorContainerSelector
30697
30748
  ? this.editor.getDocument().querySelector(this.anchorContainerSelector)
30698
30749
  : undefined;
30699
- this.tableEditor = new TableEditor_1.TableEditor(this.editor, table, this.invalidateTableRects, (0, roosterjs_content_model_dom_1.isNodeOfType)(container, 'ELEMENT_NODE') ? container : undefined, event === null || event === void 0 ? void 0 : event.currentTarget, this.onTableEditorCreated);
30750
+ this.tableEditor = new TableEditor_1.TableEditor(this.editor, table, this.invalidateTableRects, (0, roosterjs_content_model_dom_1.isNodeOfType)(container, 'ELEMENT_NODE') ? container : undefined, event === null || event === void 0 ? void 0 : event.currentTarget, this.onTableEditorCreated, this.disableFeatures);
30700
30751
  }
30701
30752
  };
30702
30753
  TableEditPlugin.prototype.disposeTableEditor = function () {
@@ -30781,7 +30832,7 @@ var TOP_OR_SIDE;
30781
30832
  * When set a different current table or change current TD, we need to update these areas
30782
30833
  */
30783
30834
  var TableEditor = /** @class */ (function () {
30784
- function TableEditor(editor, table, onChanged, anchorContainer, contentDiv, onTableEditorCreated) {
30835
+ function TableEditor(editor, table, onChanged, anchorContainer, contentDiv, onTableEditorCreated, disableFeatures) {
30785
30836
  var _this = this;
30786
30837
  var _a;
30787
30838
  this.editor = editor;
@@ -30790,6 +30841,7 @@ var TableEditor = /** @class */ (function () {
30790
30841
  this.anchorContainer = anchorContainer;
30791
30842
  this.contentDiv = contentDiv;
30792
30843
  this.onTableEditorCreated = onTableEditorCreated;
30844
+ this.disableFeatures = disableFeatures;
30793
30845
  // 1, 2 - Insert a column or a row
30794
30846
  this.horizontalInserter = null;
30795
30847
  this.verticalInserter = null;
@@ -30801,9 +30853,9 @@ var TableEditor = /** @class */ (function () {
30801
30853
  // 6 - Move as well as select whole table
30802
30854
  this.tableMover = null;
30803
30855
  this.range = null;
30804
- this.onEditorCreated = function (editorType, element) {
30856
+ this.onEditorCreated = function (featureType, element) {
30805
30857
  var _a;
30806
- var disposer = (_a = _this.onTableEditorCreated) === null || _a === void 0 ? void 0 : _a.call(_this, editorType, element);
30858
+ var disposer = (_a = _this.onTableEditorCreated) === null || _a === void 0 ? void 0 : _a.call(_this, featureType, element);
30807
30859
  var onMouseOut = element && _this.getOnMouseOut(element);
30808
30860
  if (onMouseOut) {
30809
30861
  element.addEventListener('mouseout', onMouseOut);
@@ -30834,6 +30886,16 @@ var TableEditor = /** @class */ (function () {
30834
30886
  _this.disposeTableResizer();
30835
30887
  _this.onStartResize();
30836
30888
  };
30889
+ this.onStartTableMove = function () {
30890
+ _this.isCurrentlyEditing = true;
30891
+ _this.disposeTableResizer();
30892
+ _this.disposeTableInserter();
30893
+ _this.disposeCellResizers();
30894
+ };
30895
+ this.onEndTableMove = function () {
30896
+ _this.disposeTableMover();
30897
+ return _this.onFinishEditing();
30898
+ };
30837
30899
  this.onInserted = function () {
30838
30900
  _this.disposeTableResizer();
30839
30901
  _this.onFinishEditing();
@@ -30864,7 +30926,8 @@ var TableEditor = /** @class */ (function () {
30864
30926
  ev.relatedTarget != feature &&
30865
30927
  (0, roosterjs_content_model_dom_1.isNodeOfType)(_this.contentDiv, 'ELEMENT_NODE') &&
30866
30928
  (0, roosterjs_content_model_dom_1.isNodeOfType)(ev.relatedTarget, 'ELEMENT_NODE') &&
30867
- !(_this.contentDiv == ev.relatedTarget)) {
30929
+ !(_this.contentDiv == ev.relatedTarget) &&
30930
+ !_this.isEditing()) {
30868
30931
  _this.dispose();
30869
30932
  }
30870
30933
  };
@@ -30935,7 +30998,8 @@ var TableEditor = /** @class */ (function () {
30935
30998
  if (i === 0 && topOrSide == 0 /* top */) {
30936
30999
  var center = (tdRect.left + tdRect.right) / 2;
30937
31000
  var isOnRightHalf = this.isRTL ? x < center : x > center;
30938
- this.setInserterTd(isOnRightHalf ? td : tr.cells[j - 1], false /*isHorizontal*/);
31001
+ !this.isFeatureDisabled('VerticalTableInserter') &&
31002
+ this.setInserterTd(isOnRightHalf ? td : tr.cells[j - 1], false /*isHorizontal*/);
30939
31003
  }
30940
31004
  else if (j === 0 && topOrSide == 1 /* side */) {
30941
31005
  var tdAbove = (_a = this.table.rows[i - 1]) === null || _a === void 0 ? void 0 : _a.cells[0];
@@ -30947,14 +31011,15 @@ var TableEditor = /** @class */ (function () {
30947
31011
  : this.isRTL
30948
31012
  ? tdAboveRect.right === tdRect.right
30949
31013
  : tdAboveRect.left === tdRect.left;
30950
- this.setInserterTd(y < (tdRect.top + tdRect.bottom) / 2 && isTdNotAboveMerged
30951
- ? tdAbove
30952
- : td, true /*isHorizontal*/);
31014
+ !this.isFeatureDisabled('HorizontalTableInserter') &&
31015
+ this.setInserterTd(y < (tdRect.top + tdRect.bottom) / 2 && isTdNotAboveMerged
31016
+ ? tdAbove
31017
+ : td, true /*isHorizontal*/);
30953
31018
  }
30954
31019
  else {
30955
31020
  this.setInserterTd(null);
30956
31021
  }
30957
- this.setResizingTd(td);
31022
+ !this.isFeatureDisabled('CellResizer') && this.setResizingTd(td);
30958
31023
  //Cell found
30959
31024
  break;
30960
31025
  }
@@ -30967,10 +31032,12 @@ var TableEditor = /** @class */ (function () {
30967
31032
  this.setEditorFeatures();
30968
31033
  };
30969
31034
  TableEditor.prototype.setEditorFeatures = function () {
30970
- if (!this.tableMover) {
30971
- this.tableMover = (0, TableMover_1.createTableMover)(this.table, this.editor, this.isRTL, this.onSelect, this.contentDiv, this.anchorContainer, this.onEditorCreated);
31035
+ var disableSelector = this.isFeatureDisabled('TableSelector');
31036
+ var disableMovement = this.isFeatureDisabled('TableMover');
31037
+ if (!this.tableMover && !(disableSelector && disableMovement)) {
31038
+ this.tableMover = (0, TableMover_1.createTableMover)(this.table, this.editor, this.isRTL, disableSelector ? function () { } : this.onSelect, this.onStartTableMove, this.onEndTableMove, this.contentDiv, this.anchorContainer, this.onEditorCreated, disableMovement);
30972
31039
  }
30973
- if (!this.tableResizer) {
31040
+ if (!this.tableResizer && !this.isFeatureDisabled('TableResizer')) {
30974
31041
  this.tableResizer = (0, TableResizer_1.createTableResizer)(this.table, this.editor, this.isRTL, this.onStartTableResize, this.onFinishEditing, this.contentDiv, this.anchorContainer, this.onTableEditorCreated);
30975
31042
  }
30976
31043
  };
@@ -31042,6 +31109,10 @@ var TableEditor = /** @class */ (function () {
31042
31109
  }
31043
31110
  this.editor.takeSnapshot();
31044
31111
  };
31112
+ TableEditor.prototype.isFeatureDisabled = function (feature) {
31113
+ var _a;
31114
+ return (_a = this.disableFeatures) === null || _a === void 0 ? void 0 : _a.includes(feature);
31115
+ };
31045
31116
  return TableEditor;
31046
31117
  }());
31047
31118
  exports.TableEditor = TableEditor;
@@ -31058,12 +31129,20 @@ exports.TableEditor = TableEditor;
31058
31129
  "use strict";
31059
31130
 
31060
31131
  Object.defineProperty(exports, "__esModule", ({ value: true }));
31061
- exports.createCellResizer = void 0;
31132
+ exports.createCellResizer = exports.VERTICAL_RESIZER_ID = exports.HORIZONTAL_RESIZER_ID = void 0;
31062
31133
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
31063
31134
  var createElement_1 = __webpack_require__(/*! ../../../pluginUtils/CreateElement/createElement */ "./packages/roosterjs-content-model-plugins/lib/pluginUtils/CreateElement/createElement.ts");
31064
31135
  var DragAndDropHelper_1 = __webpack_require__(/*! ../../../pluginUtils/DragAndDrop/DragAndDropHelper */ "./packages/roosterjs-content-model-plugins/lib/pluginUtils/DragAndDrop/DragAndDropHelper.ts");
31065
31136
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
31066
31137
  var CELL_RESIZER_WIDTH = 4;
31138
+ /**
31139
+ * @internal
31140
+ */
31141
+ exports.HORIZONTAL_RESIZER_ID = 'horizontalResizer';
31142
+ /**
31143
+ * @internal
31144
+ */
31145
+ exports.VERTICAL_RESIZER_ID = 'verticalResizer';
31067
31146
  /**
31068
31147
  * @internal
31069
31148
  */
@@ -31205,7 +31284,7 @@ function setHorizontalPosition(context, trigger) {
31205
31284
  var td = context.td;
31206
31285
  var rect = (0, roosterjs_content_model_dom_1.normalizeRect)(td.getBoundingClientRect());
31207
31286
  if (rect) {
31208
- trigger.id = 'horizontalResizer';
31287
+ trigger.id = exports.HORIZONTAL_RESIZER_ID;
31209
31288
  trigger.style.top = rect.bottom - CELL_RESIZER_WIDTH + 'px';
31210
31289
  trigger.style.left = rect.left + 'px';
31211
31290
  trigger.style.width = rect.right - rect.left + 'px';
@@ -31216,7 +31295,7 @@ function setVerticalPosition(context, trigger) {
31216
31295
  var td = context.td, isRTL = context.isRTL;
31217
31296
  var rect = (0, roosterjs_content_model_dom_1.normalizeRect)(td.getBoundingClientRect());
31218
31297
  if (rect) {
31219
- trigger.id = 'verticalResizer';
31298
+ trigger.id = exports.VERTICAL_RESIZER_ID;
31220
31299
  trigger.style.top = rect.top + 'px';
31221
31300
  trigger.style.left = (isRTL ? rect.left : rect.right) - CELL_RESIZER_WIDTH + 1 + 'px';
31222
31301
  trigger.style.width = CELL_RESIZER_WIDTH + 'px';
@@ -31240,13 +31319,13 @@ exports.disposeTableEditFeature = void 0;
31240
31319
  /**
31241
31320
  * @internal
31242
31321
  */
31243
- function disposeTableEditFeature(resizer) {
31322
+ function disposeTableEditFeature(feature) {
31244
31323
  var _a, _b, _c;
31245
- if (resizer) {
31246
- (_a = resizer.featureHandler) === null || _a === void 0 ? void 0 : _a.dispose();
31247
- resizer.featureHandler = null;
31248
- (_c = (_b = resizer.div) === null || _b === void 0 ? void 0 : _b.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(resizer.div);
31249
- resizer.div = null;
31324
+ if (feature) {
31325
+ (_a = feature.featureHandler) === null || _a === void 0 ? void 0 : _a.dispose();
31326
+ feature.featureHandler = null;
31327
+ (_c = (_b = feature.div) === null || _b === void 0 ? void 0 : _b.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(feature.div);
31328
+ feature.div = null;
31250
31329
  }
31251
31330
  }
31252
31331
  exports.disposeTableEditFeature = disposeTableEditFeature;
@@ -31263,7 +31342,7 @@ exports.disposeTableEditFeature = disposeTableEditFeature;
31263
31342
  "use strict";
31264
31343
 
31265
31344
  Object.defineProperty(exports, "__esModule", ({ value: true }));
31266
- exports.createTableInserter = void 0;
31345
+ exports.createTableInserter = exports.VERTICAL_INSERTER_ID = exports.HORIZONTAL_INSERTER_ID = void 0;
31267
31346
  var createElement_1 = __webpack_require__(/*! ../../../pluginUtils/CreateElement/createElement */ "./packages/roosterjs-content-model-plugins/lib/pluginUtils/CreateElement/createElement.ts");
31268
31347
  var getIntersectedRect_1 = __webpack_require__(/*! ../../../pluginUtils/Rect/getIntersectedRect */ "./packages/roosterjs-content-model-plugins/lib/pluginUtils/Rect/getIntersectedRect.ts");
31269
31348
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
@@ -31272,6 +31351,14 @@ var INSERTER_COLOR = '#4A4A4A';
31272
31351
  var INSERTER_COLOR_DARK_MODE = 'white';
31273
31352
  var INSERTER_SIDE_LENGTH = 12;
31274
31353
  var INSERTER_BORDER_SIZE = 1;
31354
+ /**
31355
+ * @internal
31356
+ */
31357
+ exports.HORIZONTAL_INSERTER_ID = 'horizontalInserter';
31358
+ /**
31359
+ * @internal
31360
+ */
31361
+ exports.VERTICAL_INSERTER_ID = 'verticalInserter';
31275
31362
  /**
31276
31363
  * @internal
31277
31364
  */
@@ -31286,7 +31373,7 @@ function createTableInserter(editor, td, table, isRTL, isHorizontal, onInsert, a
31286
31373
  var div = (0, createElement_1.createElement)(createElementData, document_1);
31287
31374
  if (isHorizontal) {
31288
31375
  // tableRect.left/right is used because the Inserter is always intended to be on the side
31289
- div.id = 'horizontalInserter';
31376
+ div.id = exports.HORIZONTAL_INSERTER_ID;
31290
31377
  div.style.left = (isRTL
31291
31378
  ? tableRect.right
31292
31379
  : tableRect.left - (INSERTER_SIDE_LENGTH - 1 + 2 * INSERTER_BORDER_SIZE)) + "px";
@@ -31294,7 +31381,7 @@ function createTableInserter(editor, td, table, isRTL, isHorizontal, onInsert, a
31294
31381
  div.firstChild.style.width = tableRect.right - tableRect.left + "px";
31295
31382
  }
31296
31383
  else {
31297
- div.id = 'verticalInserter';
31384
+ div.id = exports.VERTICAL_INSERTER_ID;
31298
31385
  div.style.left = (isRTL ? tdRect.left - 8 : tdRect.right - 8) + "px";
31299
31386
  // tableRect.top is used because the Inserter is always intended to be on top
31300
31387
  div.style.top = tableRect.top - (INSERTER_SIDE_LENGTH - 1 + 2 * INSERTER_BORDER_SIZE) + "px";
@@ -31384,19 +31471,24 @@ function getInsertElementData(isHorizontal, isDark, isRTL, backgroundColor) {
31384
31471
  "use strict";
31385
31472
 
31386
31473
  Object.defineProperty(exports, "__esModule", ({ value: true }));
31387
- exports.createTableMover = void 0;
31474
+ exports.onDragEnd = exports.onDragging = exports.onDragStart = exports.createTableMover = exports.TABLE_MOVER_ID = void 0;
31388
31475
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
31389
31476
  var createElement_1 = __webpack_require__(/*! ../../../pluginUtils/CreateElement/createElement */ "./packages/roosterjs-content-model-plugins/lib/pluginUtils/CreateElement/createElement.ts");
31390
31477
  var DragAndDropHelper_1 = __webpack_require__(/*! ../../../pluginUtils/DragAndDrop/DragAndDropHelper */ "./packages/roosterjs-content-model-plugins/lib/pluginUtils/DragAndDrop/DragAndDropHelper.ts");
31478
+ var roosterjs_content_model_api_1 = __webpack_require__(/*! roosterjs-content-model-api */ "./packages/roosterjs-content-model-api/lib/index.ts");
31391
31479
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
31392
31480
  var TABLE_MOVER_LENGTH = 12;
31393
- var TABLE_MOVER_ID = '_Table_Mover';
31394
31481
  /**
31395
31482
  * @internal
31483
+ */
31484
+ exports.TABLE_MOVER_ID = '_Table_Mover';
31485
+ var TABLE_MOVER_STYLE_KEY = '_TableMoverCursorStyle';
31486
+ /**
31487
+ * @internal
31488
+ * Allows user to move table to another position
31396
31489
  * Contains the function to select whole table
31397
- * Moving behavior not implemented yet
31398
31490
  */
31399
- function createTableMover(table, editor, isRTL, onFinishDragging, contentDiv, anchorContainer, onTableEditorCreated) {
31491
+ function createTableMover(table, editor, isRTL, onFinishDragging, onStart, onEnd, contentDiv, anchorContainer, onTableEditorCreated, disableMovement) {
31400
31492
  var rect = (0, roosterjs_content_model_dom_1.normalizeRect)(table.getBoundingClientRect());
31401
31493
  if (!isTableTopVisible(editor, rect, contentDiv)) {
31402
31494
  return null;
@@ -31405,10 +31497,10 @@ function createTableMover(table, editor, isRTL, onFinishDragging, contentDiv, an
31405
31497
  var document = table.ownerDocument;
31406
31498
  var createElementData = {
31407
31499
  tag: 'div',
31408
- style: 'position: fixed; cursor: all-scroll; user-select: none; border: 1px solid #808080',
31500
+ style: 'position: fixed; cursor: move; user-select: none; border: 1px solid #808080',
31409
31501
  };
31410
31502
  var div = (0, createElement_1.createElement)(createElementData, document);
31411
- div.id = TABLE_MOVER_ID;
31503
+ div.id = exports.TABLE_MOVER_ID;
31412
31504
  div.style.width = TABLE_MOVER_LENGTH + "px";
31413
31505
  div.style.height = TABLE_MOVER_LENGTH + "px";
31414
31506
  (anchorContainer || document.body).appendChild(div);
@@ -31417,24 +31509,28 @@ function createTableMover(table, editor, isRTL, onFinishDragging, contentDiv, an
31417
31509
  zoomScale: zoomScale,
31418
31510
  rect: rect,
31419
31511
  isRTL: isRTL,
31512
+ editor: editor,
31513
+ div: div,
31514
+ onFinishDragging: onFinishDragging,
31515
+ onStart: onStart,
31516
+ onEnd: onEnd,
31517
+ disableMovement: disableMovement,
31420
31518
  };
31421
31519
  setDivPosition(context, div);
31422
- var onDragEnd = function (context, event) {
31423
- if (event.target == div) {
31424
- onFinishDragging(context.table);
31425
- }
31426
- return false;
31427
- };
31428
- var featureHandler = new TableMoverFeature(div, context, setDivPosition, {
31429
- onDragEnd: onDragEnd,
31430
- }, context.zoomScale, onTableEditorCreated);
31431
- return { div: div, featureHandler: featureHandler, node: table };
31520
+ var featureHandler = new TableMoverFeature(div, context, function () { }, disableMovement
31521
+ ? { onDragEnd: onDragEnd }
31522
+ : {
31523
+ onDragStart: onDragStart,
31524
+ onDragging: onDragging,
31525
+ onDragEnd: onDragEnd,
31526
+ }, context.zoomScale, onTableEditorCreated, editor.getEnvironment().isMobileOrTablet);
31527
+ return { node: table, div: div, featureHandler: featureHandler };
31432
31528
  }
31433
31529
  exports.createTableMover = createTableMover;
31434
31530
  var TableMoverFeature = /** @class */ (function (_super) {
31435
31531
  (0, tslib_1.__extends)(TableMoverFeature, _super);
31436
- function TableMoverFeature(div, context, onSubmit, handler, zoomScale, onTableEditorCreated) {
31437
- var _this = _super.call(this, div, context, onSubmit, handler, zoomScale) || this;
31532
+ function TableMoverFeature(div, context, onSubmit, handler, zoomScale, onTableEditorCreated, forceMobile) {
31533
+ var _this = _super.call(this, div, context, onSubmit, handler, zoomScale, forceMobile) || this;
31438
31534
  _this.disposer = onTableEditorCreated === null || onTableEditorCreated === void 0 ? void 0 : onTableEditorCreated('TableMover', div);
31439
31535
  return _this;
31440
31536
  }
@@ -31461,6 +31557,188 @@ function isTableTopVisible(editor, rect, contentDiv) {
31461
31557
  }
31462
31558
  return true;
31463
31559
  }
31560
+ function setTableMoverCursor(editor, state, type) {
31561
+ var _a;
31562
+ editor === null || editor === void 0 ? void 0 : editor.setEditorStyle(TABLE_MOVER_STYLE_KEY, state ? (_a = 'cursor: ' + type) !== null && _a !== void 0 ? _a : 'move' : null);
31563
+ }
31564
+ // Get insertion point from coordinate.
31565
+ function getNodePositionFromEvent(editor, x, y) {
31566
+ var doc = editor.getDocument();
31567
+ var domHelper = editor.getDOMHelper();
31568
+ if (doc.caretRangeFromPoint) {
31569
+ // Chrome, Edge, Safari, Opera
31570
+ var range = doc.caretRangeFromPoint(x, y);
31571
+ if (range && domHelper.isNodeInEditor(range.startContainer)) {
31572
+ return { node: range.startContainer, offset: range.startOffset };
31573
+ }
31574
+ }
31575
+ if ('caretPositionFromPoint' in doc) {
31576
+ // Firefox
31577
+ var pos = doc.caretPositionFromPoint(x, y);
31578
+ if (pos && domHelper.isNodeInEditor(pos.offsetNode)) {
31579
+ return { node: pos.offsetNode, offset: pos.offset };
31580
+ }
31581
+ }
31582
+ if (doc.elementFromPoint) {
31583
+ // Fallback
31584
+ var element = doc.elementFromPoint(x, y);
31585
+ if (element && domHelper.isNodeInEditor(element)) {
31586
+ return { node: element, offset: 0 };
31587
+ }
31588
+ }
31589
+ return null;
31590
+ }
31591
+ /**
31592
+ * @internal
31593
+ * Exported for testing
31594
+ */
31595
+ function onDragStart(context) {
31596
+ var _a;
31597
+ context.onStart();
31598
+ var editor = context.editor, table = context.table, div = context.div;
31599
+ setTableMoverCursor(editor, true, 'move');
31600
+ // Create table outline rectangle
31601
+ var trect = table.getBoundingClientRect();
31602
+ var createElementData = {
31603
+ tag: 'div',
31604
+ style: 'position: fixed; user-select: none; border: 1px solid #808080',
31605
+ };
31606
+ var tableRect = (0, createElement_1.createElement)(createElementData, document);
31607
+ tableRect.style.width = trect.width + "px";
31608
+ tableRect.style.height = trect.height + "px";
31609
+ tableRect.style.top = trect.top + "px";
31610
+ tableRect.style.left = trect.left + "px";
31611
+ (_a = div.parentNode) === null || _a === void 0 ? void 0 : _a.appendChild(tableRect);
31612
+ // Get current selection
31613
+ var initialSelection = editor.getDOMSelection();
31614
+ // Select first cell of the table
31615
+ editor.setDOMSelection({
31616
+ type: 'table',
31617
+ firstColumn: 0,
31618
+ firstRow: 0,
31619
+ lastColumn: 0,
31620
+ lastRow: 0,
31621
+ table: table,
31622
+ });
31623
+ // Get the table content model
31624
+ var _b = (0, tslib_1.__read)((0, roosterjs_content_model_dom_1.getFirstSelectedTable)(editor.getContentModelCopy('disconnected')), 1), cmTable = _b[0];
31625
+ // Restore selection
31626
+ editor.setDOMSelection(initialSelection);
31627
+ return {
31628
+ cmTable: cmTable,
31629
+ initialSelection: initialSelection,
31630
+ tableRect: tableRect,
31631
+ };
31632
+ }
31633
+ exports.onDragStart = onDragStart;
31634
+ /**
31635
+ * @internal
31636
+ * Exported for testing
31637
+ */
31638
+ function onDragging(context, event, initValue) {
31639
+ var tableRect = initValue.tableRect;
31640
+ var editor = context.editor;
31641
+ // Move table outline rectangle
31642
+ tableRect.style.top = event.clientY + TABLE_MOVER_LENGTH + "px";
31643
+ tableRect.style.left = event.clientX + TABLE_MOVER_LENGTH + "px";
31644
+ var pos = getNodePositionFromEvent(editor, event.clientX, event.clientY);
31645
+ if (pos) {
31646
+ var range = editor.getDocument().createRange();
31647
+ range.setStart(pos.node, pos.offset);
31648
+ range.collapse(true);
31649
+ editor.setDOMSelection({ type: 'range', range: range, isReverted: false });
31650
+ return true;
31651
+ }
31652
+ return false;
31653
+ }
31654
+ exports.onDragging = onDragging;
31655
+ /**
31656
+ * @internal
31657
+ * Exported for testing
31658
+ */
31659
+ function onDragEnd(context, event, initValue) {
31660
+ var _a, _b;
31661
+ var editor = context.editor, table = context.table, selectWholeTable = context.onFinishDragging, disableMovement = context.disableMovement;
31662
+ var element = event.target;
31663
+ // Remove table outline rectangle
31664
+ initValue === null || initValue === void 0 ? void 0 : initValue.tableRect.remove();
31665
+ // Reset cursor
31666
+ setTableMoverCursor(editor, false);
31667
+ if (element == context.div) {
31668
+ // Table mover was only clicked, select whole table
31669
+ selectWholeTable(table);
31670
+ context.onEnd();
31671
+ return true;
31672
+ }
31673
+ else {
31674
+ // Check if table was dragged on itself, element is not in editor, or movement is disabled
31675
+ if (table.contains(element) ||
31676
+ !editor.getDOMHelper().isNodeInEditor(element) ||
31677
+ disableMovement) {
31678
+ editor.setDOMSelection((_a = initValue === null || initValue === void 0 ? void 0 : initValue.initialSelection) !== null && _a !== void 0 ? _a : null);
31679
+ context.onEnd();
31680
+ return false;
31681
+ }
31682
+ var insertionSuccess_1 = false;
31683
+ // Get position to insert table
31684
+ var insertPosition = getNodePositionFromEvent(editor, event.clientX, event.clientY);
31685
+ if (insertPosition) {
31686
+ // Move table to new position
31687
+ (0, roosterjs_content_model_api_1.formatInsertPointWithContentModel)(editor, insertPosition, function (model, context, ip) {
31688
+ var _a;
31689
+ // Remove old table
31690
+ var _b = (0, tslib_1.__read)((0, roosterjs_content_model_dom_1.getFirstSelectedTable)(model), 2), oldTable = _b[0], path = _b[1];
31691
+ if (oldTable) {
31692
+ var index = path[0].blocks.indexOf(oldTable);
31693
+ path[0].blocks.splice(index, 1);
31694
+ }
31695
+ if (ip && (initValue === null || initValue === void 0 ? void 0 : initValue.cmTable)) {
31696
+ // Insert new table
31697
+ var doc = (0, roosterjs_content_model_dom_1.createContentModelDocument)();
31698
+ doc.blocks.push(initValue.cmTable);
31699
+ insertionSuccess_1 = !!(0, roosterjs_content_model_dom_1.mergeModel)(model, doc, context, {
31700
+ mergeFormat: 'none',
31701
+ insertPosition: ip,
31702
+ });
31703
+ if (insertionSuccess_1) {
31704
+ // After mergeModel, the new table should be selected
31705
+ var finalTable = (_a = (0, roosterjs_content_model_dom_1.getFirstSelectedTable)(model)[0]) !== null && _a !== void 0 ? _a : initValue.cmTable;
31706
+ if (finalTable) {
31707
+ // Add selection marker to the first cell of the table
31708
+ var FirstCell = finalTable.rows[0].cells[0];
31709
+ var markerParagraph = FirstCell === null || FirstCell === void 0 ? void 0 : FirstCell.blocks[0];
31710
+ if ((markerParagraph === null || markerParagraph === void 0 ? void 0 : markerParagraph.blockType) == 'Paragraph') {
31711
+ var marker = (0, roosterjs_content_model_dom_1.createSelectionMarker)(model.format);
31712
+ markerParagraph.segments.unshift(marker);
31713
+ (0, roosterjs_content_model_dom_1.setParagraphNotImplicit)(markerParagraph);
31714
+ (0, roosterjs_content_model_dom_1.setSelection)(FirstCell, marker);
31715
+ }
31716
+ }
31717
+ }
31718
+ return insertionSuccess_1;
31719
+ }
31720
+ }, {
31721
+ // Select first cell of the old table
31722
+ selectionOverride: {
31723
+ type: 'table',
31724
+ firstColumn: 0,
31725
+ firstRow: 0,
31726
+ lastColumn: 0,
31727
+ lastRow: 0,
31728
+ table: table,
31729
+ },
31730
+ apiName: 'TableMover',
31731
+ });
31732
+ }
31733
+ else {
31734
+ // No movement, restore initial selection
31735
+ editor.setDOMSelection((_b = initValue === null || initValue === void 0 ? void 0 : initValue.initialSelection) !== null && _b !== void 0 ? _b : null);
31736
+ }
31737
+ context.onEnd();
31738
+ return insertionSuccess_1;
31739
+ }
31740
+ }
31741
+ exports.onDragEnd = onDragEnd;
31464
31742
 
31465
31743
 
31466
31744
  /***/ }),
@@ -31474,13 +31752,16 @@ function isTableTopVisible(editor, rect, contentDiv) {
31474
31752
  "use strict";
31475
31753
 
31476
31754
  Object.defineProperty(exports, "__esModule", ({ value: true }));
31477
- exports.createTableResizer = void 0;
31755
+ exports.createTableResizer = exports.TABLE_RESIZER_ID = void 0;
31478
31756
  var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
31479
31757
  var createElement_1 = __webpack_require__(/*! ../../../pluginUtils/CreateElement/createElement */ "./packages/roosterjs-content-model-plugins/lib/pluginUtils/CreateElement/createElement.ts");
31480
31758
  var DragAndDropHelper_1 = __webpack_require__(/*! ../../../pluginUtils/DragAndDrop/DragAndDropHelper */ "./packages/roosterjs-content-model-plugins/lib/pluginUtils/DragAndDrop/DragAndDropHelper.ts");
31481
31759
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
31482
31760
  var TABLE_RESIZER_LENGTH = 12;
31483
- var TABLE_RESIZER_ID = '_Table_Resizer';
31761
+ /**
31762
+ * @internal
31763
+ */
31764
+ exports.TABLE_RESIZER_ID = '_Table_Resizer';
31484
31765
  /**
31485
31766
  * @internal
31486
31767
  */
@@ -31496,7 +31777,7 @@ function createTableResizer(table, editor, isRTL, onStart, onEnd, contentDiv, an
31496
31777
  style: "position: fixed; cursor: " + (isRTL ? 'ne' : 'nw') + "-resize; user-select: none; border: 1px solid #808080",
31497
31778
  };
31498
31779
  var div = (0, createElement_1.createElement)(createElementData, document);
31499
- div.id = TABLE_RESIZER_ID;
31780
+ div.id = exports.TABLE_RESIZER_ID;
31500
31781
  div.style.width = TABLE_RESIZER_LENGTH + "px";
31501
31782
  div.style.height = TABLE_RESIZER_LENGTH + "px";
31502
31783
  (anchorContainer || document.body).appendChild(div);
@@ -31720,7 +32001,8 @@ var WatermarkPlugin = /** @class */ (function () {
31720
32001
  if (!editor) {
31721
32002
  return;
31722
32003
  }
31723
- if (event.eventType == 'input' && event.rawEvent.inputType == 'insertText') {
32004
+ if ((event.eventType == 'input' && event.rawEvent.inputType == 'insertText') ||
32005
+ event.eventType == 'compositionEnd') {
31724
32006
  // When input text, editor must not be empty, so we can do hide watermark now without checking content model
31725
32007
  this.showHide(editor, false /*isEmpty*/);
31726
32008
  }
@@ -31801,6 +32083,10 @@ function isModelEmptyFast(model) {
31801
32083
  })) {
31802
32084
  return false; // Has meaningful segments, it is not empty
31803
32085
  }
32086
+ else if ((firstBlock.format.marginRight && parseFloat(firstBlock.format.marginRight) > 0) ||
32087
+ (firstBlock.format.marginLeft && parseFloat(firstBlock.format.marginLeft) > 0)) {
32088
+ return false; // Has margin (indentation is changed), it is not empty
32089
+ }
31804
32090
  else {
31805
32091
  return firstBlock.segments.filter(function (x) { return x.segmentType == 'Br'; }).length <= 1; // If there are more than one BR, it is not empty, otherwise it is empty
31806
32092
  }