roosterjs 9.30.0 → 9.32.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.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- // Type definitions for roosterjs (Version 9.30.0)
1
+ // Type definitions for roosterjs (Version 9.32.0)
2
2
  // Generated by dts tool from roosterjs
3
3
  // Project: https://github.com/Microsoft/roosterjs
4
4
 
@@ -5101,6 +5101,13 @@ interface Snapshot {
5101
5101
  * HTML content string
5102
5102
  */
5103
5103
  html: string;
5104
+ /**
5105
+ * Additional state supplied by plugins. When doing an undo/redo to this snapshot, this state will be added to the
5106
+ * content model context as additional state.
5107
+ */
5108
+ additionalState?: {
5109
+ [key: string]: string;
5110
+ };
5104
5111
  /**
5105
5112
  * Entity states related to this undo snapshots. When undo/redo to this snapshot, each entity state will trigger
5106
5113
  * an EntityOperation event with operation = EntityOperation.UpdateEntityState
@@ -5874,6 +5881,18 @@ interface BasePluginDomEvent<TPluginEventType extends PluginEventType, TRawEvent
5874
5881
  rawEvent: TRawEvent;
5875
5882
  }
5876
5883
 
5884
+ /**
5885
+ * Fired when an undo snapshot is about to be added
5886
+ */
5887
+ interface BeforeAddUndoSnapshotEvent extends BasePluginEvent<'beforeAddUndoSnapshot'> {
5888
+ /**
5889
+ * Additional state to be added to the snapshot
5890
+ */
5891
+ additionalState: {
5892
+ [key: string]: string;
5893
+ };
5894
+ }
5895
+
5877
5896
  /**
5878
5897
  * Provides a chance for plugin to change the content before it is copied from editor.
5879
5898
  */
@@ -5981,6 +6000,12 @@ interface ContentChangedEvent extends BasePluginEvent<'contentChanged'> {
5981
6000
  * Entities got changed (added or removed) during the content change process
5982
6001
  */
5983
6002
  readonly changedEntities?: ChangedEntity[];
6003
+ /**
6004
+ * Additional state added to the snapshot by plugins
6005
+ */
6006
+ readonly additionalState?: {
6007
+ [key: string]: string;
6008
+ };
5984
6009
  /**
5985
6010
  * Entity states related to this event
5986
6011
  */
@@ -6236,7 +6261,7 @@ interface MouseUpEvent extends BasePluginDomEvent<'mouseUp', MouseEvent> {
6236
6261
  /**
6237
6262
  * Editor plugin event interface
6238
6263
  */
6239
- type PluginEvent = BeforeCutCopyEvent | BeforeDisposeEvent | BeforeKeyboardEditingEvent | BeforeLogicalRootChangeEvent | BeforePasteEvent | BeforeSetContentEvent | CompositionEndEvent | ContentChangedEvent | ContextMenuEvent | RewriteFromModelEvent | EditImageEvent | EditorReadyEvent | EnterShadowEditEvent | EntityOperationEvent | ExtractContentWithDomEvent | EditorInputEvent | KeyDownEvent | KeyPressEvent | KeyUpEvent | LeaveShadowEditEvent | LogicalRootChangedEvent | MouseDownEvent | MouseUpEvent | ScrollEvent | SelectionChangedEvent | ZoomChangedEvent;
6264
+ type PluginEvent = BeforeAddUndoSnapshotEvent | BeforeCutCopyEvent | BeforeDisposeEvent | BeforeKeyboardEditingEvent | BeforeLogicalRootChangeEvent | BeforePasteEvent | BeforeSetContentEvent | CompositionEndEvent | ContentChangedEvent | ContextMenuEvent | RewriteFromModelEvent | EditImageEvent | EditorReadyEvent | EnterShadowEditEvent | EntityOperationEvent | ExtractContentWithDomEvent | EditorInputEvent | KeyDownEvent | KeyPressEvent | KeyUpEvent | LeaveShadowEditEvent | LogicalRootChangedEvent | MouseDownEvent | MouseUpEvent | ScrollEvent | SelectionChangedEvent | ZoomChangedEvent;
6240
6265
 
6241
6266
  /**
6242
6267
  * A type to extract data part of a plugin event type. Data part is the plugin event without eventType field.
@@ -6376,7 +6401,12 @@ type PluginEventType = /**
6376
6401
  * This event is used to clean up any features from the old logical root
6377
6402
  * before the new logical root is set.
6378
6403
  */
6379
- | 'beforeLogicalRootChange';
6404
+ | 'beforeLogicalRootChange'
6405
+ /**
6406
+ * Before an undo snapshot is added to the undo stack.
6407
+ * This event is used to give plugins a chance to add additional state to the snapshot.
6408
+ */
6409
+ | 'beforeAddUndoSnapshot';
6380
6410
 
6381
6411
  /**
6382
6412
  * This interface represents a PluginEvent wrapping native scroll event
@@ -8455,9 +8485,9 @@ function setAlignment(editor: IEditor, alignment: 'left' | 'center' | 'right' |
8455
8485
  /**
8456
8486
  * Set text direction of selected paragraphs (Left to right or Right to left)
8457
8487
  * @param editor The editor to set alignment
8458
- * @param direction Direction value: ltr (Left to right) or rtl (Right to left)
8488
+ * @param direction Direction value: ltr (Left to right) or rtl (Right to left), or 'auto' (Based on the first characters of the document, set the direction automatically)
8459
8489
  */
8460
- function setDirection(editor: IEditor, direction: 'ltr' | 'rtl'): void;
8490
+ function setDirection(editor: IEditor, direction: 'ltr' | 'rtl' | 'auto'): void;
8461
8491
 
8462
8492
  /**
8463
8493
  * Set heading level of selected paragraphs
package/dist/rooster.js CHANGED
@@ -2313,6 +2313,11 @@ exports.setModelDirection = void 0;
2313
2313
  var findListItemsInSameThread_1 = __webpack_require__(/*! ../list/findListItemsInSameThread */ "./packages/roosterjs-content-model-api/lib/modelApi/list/findListItemsInSameThread.ts");
2314
2314
  var splitSelectedParagraphByBr_1 = __webpack_require__(/*! ./splitSelectedParagraphByBr */ "./packages/roosterjs-content-model-api/lib/modelApi/block/splitSelectedParagraphByBr.ts");
2315
2315
  var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
2316
+ // Regexes for character direction detection
2317
+ // Strongly typed RTL character ranges. Referenced unicode's DerivedBidiClass.txt, excluding things in the 2 bit range.
2318
+ var RTL_CHAR_REGEX = /[\u0590-\u05FF\u0600-\u08FF\uFB1D-\uFDFF\uFE70-\uFEFF]/g;
2319
+ var URL_CHAR_REGEX = /http\S+|www\S+|https\S+|<a\s+(?:[^>]*?\s+)?href=(["']).*?\1.*?>.*?<\/a>/g;
2320
+ var WHITESPACE_REGEX = /\s/g;
2316
2321
  /**
2317
2322
  * @internal
2318
2323
  */
@@ -2321,18 +2326,25 @@ function setModelDirection(model, direction) {
2321
2326
  var paragraphOrListItemOrTable = (0, roosterjs_content_model_dom_1.getOperationalBlocks)(model, ['ListItem'], ['TableCell']);
2322
2327
  paragraphOrListItemOrTable.forEach(function (_a) {
2323
2328
  var block = _a.block;
2329
+ var calcDirection;
2330
+ if (direction === 'auto') {
2331
+ calcDirection = determineTextDirection(block);
2332
+ }
2333
+ else {
2334
+ calcDirection = direction;
2335
+ }
2324
2336
  if ((0, roosterjs_content_model_dom_1.isBlockGroupOfType)(block, 'ListItem')) {
2325
2337
  var items = (0, findListItemsInSameThread_1.findListItemsInSameThread)(model, block);
2326
2338
  items.forEach(function (readonlyItem) {
2327
2339
  var item = (0, roosterjs_content_model_dom_1.mutateBlock)(readonlyItem);
2328
2340
  item.levels.forEach(function (level) {
2329
- level.format.direction = direction;
2341
+ level.format.direction = calcDirection;
2330
2342
  });
2331
- item.blocks.forEach(function (block) { return internalSetDirection(block, direction); });
2343
+ item.blocks.forEach(function (block) { return internalSetDirection(block, calcDirection); });
2332
2344
  });
2333
2345
  }
2334
2346
  else if (block) {
2335
- internalSetDirection(block, direction);
2347
+ internalSetDirection(block, calcDirection);
2336
2348
  }
2337
2349
  });
2338
2350
  return paragraphOrListItemOrTable.length > 0;
@@ -2379,6 +2391,31 @@ function setProperty(format, key, value) {
2379
2391
  delete format[key];
2380
2392
  }
2381
2393
  }
2394
+ // Designed to match browser's 'auto' detection, by scanning over the inner text until it hits a strong LTR/RTL character
2395
+ function determineTextDirection(block) {
2396
+ if (block.blockType === 'Paragraph') {
2397
+ var findTextSegements = block.segments.filter(function (seg) { return seg.segmentType === 'Text'; });
2398
+ var innerText = findTextSegements.length > 0
2399
+ ? findTextSegements.reduce(function (prev, seg) { return prev + seg.text; }, '')
2400
+ : undefined;
2401
+ if (!!innerText) {
2402
+ // Remove links
2403
+ innerText = innerText.replace(URL_CHAR_REGEX, '');
2404
+ // Remove whitespace
2405
+ innerText = innerText.replace(WHITESPACE_REGEX, '');
2406
+ var rtlMatches = innerText.match(RTL_CHAR_REGEX);
2407
+ var rtlCount = rtlMatches ? rtlMatches.length : 0;
2408
+ var ltrCount = innerText.length - rtlCount;
2409
+ return rtlCount > ltrCount ? 'rtl' : 'ltr';
2410
+ }
2411
+ else {
2412
+ return 'ltr'; // Default to LTR if no text is found
2413
+ }
2414
+ }
2415
+ else {
2416
+ return 'ltr';
2417
+ }
2418
+ }
2382
2419
 
2383
2420
 
2384
2421
  /***/ }),
@@ -4884,7 +4921,7 @@ var setModelDirection_1 = __webpack_require__(/*! ../../modelApi/block/setModelD
4884
4921
  /**
4885
4922
  * Set text direction of selected paragraphs (Left to right or Right to left)
4886
4923
  * @param editor The editor to set alignment
4887
- * @param direction Direction value: ltr (Left to right) or rtl (Right to left)
4924
+ * @param direction Direction value: ltr (Left to right) or rtl (Right to left), or 'auto' (Based on the first characters of the document, set the direction automatically)
4888
4925
  */
4889
4926
  function setDirection(editor, direction) {
4890
4927
  editor.focus();
@@ -8561,6 +8598,12 @@ var addUndoSnapshot = function (core, canUndoByBackspace, entityStates) {
8561
8598
  var lifecycle = core.lifecycle, physicalRoot = core.physicalRoot, logicalRoot = core.logicalRoot, undo = core.undo;
8562
8599
  var snapshot = null;
8563
8600
  if (!lifecycle.shadowEditFragment) {
8601
+ // Give plugins the chance to add additional state to the snapshot
8602
+ var beforeAddUndoSnapshotEvent = {
8603
+ eventType: 'beforeAddUndoSnapshot',
8604
+ additionalState: {},
8605
+ };
8606
+ core.api.triggerEvent(core, beforeAddUndoSnapshotEvent, false);
8564
8607
  // Need to create snapshot selection before retrieve innerHTML since HTML can be changed during creating selection when normalize table
8565
8608
  var selection = (0, createSnapshotSelection_1.createSnapshotSelection)(core);
8566
8609
  var html = physicalRoot.innerHTML;
@@ -8597,6 +8640,7 @@ var addUndoSnapshot = function (core, canUndoByBackspace, entityStates) {
8597
8640
  }
8598
8641
  snapshot = {
8599
8642
  html: html,
8643
+ additionalState: beforeAddUndoSnapshotEvent.additionalState,
8600
8644
  entityStates: entityStates,
8601
8645
  isDarkMode: !!lifecycle.isDarkMode,
8602
8646
  selection: selection,
@@ -9709,6 +9753,7 @@ var restoreUndoSnapshot = function (core, snapshot) {
9709
9753
  (0, restoreSnapshotColors_1.restoreSnapshotColors)(core, snapshot);
9710
9754
  var event_1 = {
9711
9755
  eventType: 'contentChanged',
9756
+ additionalState: snapshot.additionalState,
9712
9757
  entityStates: snapshot.entityStates,
9713
9758
  source: roosterjs_content_model_dom_1.ChangeSource.SetContent,
9714
9759
  };
@@ -14367,6 +14412,8 @@ var SnapshotsManagerImpl = /** @class */ (function () {
14367
14412
  var currentSnapshot = this.snapshots.snapshots[this.snapshots.currentIndex];
14368
14413
  var isSameSnapshot = currentSnapshot &&
14369
14414
  currentSnapshot.html == snapshot.html &&
14415
+ !currentSnapshot.additionalState &&
14416
+ !snapshot.additionalState &&
14370
14417
  !currentSnapshot.entityStates &&
14371
14418
  !snapshot.entityStates;
14372
14419
  var addSnapshot = !currentSnapshot || shouldAddSnapshot(currentSnapshot, snapshot);
@@ -14432,6 +14479,11 @@ function createSnapshotsManager(snapshots) {
14432
14479
  exports.createSnapshotsManager = createSnapshotsManager;
14433
14480
  function shouldAddSnapshot(currentSnapshot, snapshot) {
14434
14481
  return (currentSnapshot.html !== snapshot.html ||
14482
+ (currentSnapshot.additionalState &&
14483
+ snapshot.additionalState &&
14484
+ JSON.stringify(currentSnapshot.additionalState) !==
14485
+ JSON.stringify(snapshot.additionalState)) ||
14486
+ (!currentSnapshot.additionalState && snapshot.additionalState) ||
14435
14487
  (currentSnapshot.entityStates &&
14436
14488
  snapshot.entityStates &&
14437
14489
  currentSnapshot.entityStates !== snapshot.entityStates) ||
@@ -31858,7 +31910,7 @@ function keyboardEnter(editor, rawEvent, handleNormalEnter) {
31858
31910
  var steps = rawEvent.shiftKey
31859
31911
  ? []
31860
31912
  : [handleAutoLink_1.handleAutoLink, handleEnterOnList_1.handleEnterOnList, deleteEmptyQuote_1.deleteEmptyQuote];
31861
- if (handleNormalEnter || hasEnterForEntity((_a = result.insertPoint) === null || _a === void 0 ? void 0 : _a.paragraph)) {
31913
+ if (handleNormalEnter || handleEnterForEntity((_a = result.insertPoint) === null || _a === void 0 ? void 0 : _a.paragraph)) {
31862
31914
  steps.push(handleEnterOnParagraph_1.handleEnterOnParagraph);
31863
31915
  }
31864
31916
  (0, roosterjs_content_model_dom_1.runEditSteps)(steps, result);
@@ -31882,9 +31934,9 @@ function keyboardEnter(editor, rawEvent, handleNormalEnter) {
31882
31934
  });
31883
31935
  }
31884
31936
  exports.keyboardEnter = keyboardEnter;
31885
- function hasEnterForEntity(paragraph) {
31937
+ function handleEnterForEntity(paragraph) {
31886
31938
  return (paragraph &&
31887
- (paragraph.isImplicit || paragraph.segments.some(function (x) { return x.segmentType == 'SelectionMarker'; })));
31939
+ (paragraph.isImplicit || paragraph.segments.some(function (x) { return x.segmentType == 'Entity'; })));
31888
31940
  }
31889
31941
 
31890
31942