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