roosterjs 9.52.0 → 9.54.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-adapter-amd-min.js +1 -1
- package/dist/rooster-adapter-amd-min.js.map +1 -1
- package/dist/rooster-adapter-amd.js +2 -0
- package/dist/rooster-adapter-amd.js.map +1 -1
- package/dist/rooster-adapter-min.js +1 -1
- package/dist/rooster-adapter-min.js.map +1 -1
- package/dist/rooster-adapter.js +2 -0
- package/dist/rooster-adapter.js.map +1 -1
- package/dist/rooster-amd-min.js +1 -1
- package/dist/rooster-amd-min.js.map +1 -1
- package/dist/rooster-amd.d.ts +128 -5
- package/dist/rooster-amd.js +793 -417
- package/dist/rooster-amd.js.map +1 -1
- package/dist/rooster-min.js +1 -1
- package/dist/rooster-min.js.map +1 -1
- package/dist/rooster-react.js +92 -92
- package/dist/rooster-react.js.map +1 -1
- package/dist/rooster.d.ts +128 -5
- package/dist/rooster.js +793 -417
- package/dist/rooster.js.map +1 -1
- package/package.json +7 -7
package/dist/rooster.js
CHANGED
|
@@ -8020,6 +8020,15 @@ function formatInsertPointWithContentModel(editor, insertPoint, callback, option
|
|
|
8020
8020
|
textWithSelection: getShadowTextProcessor(bundle),
|
|
8021
8021
|
},
|
|
8022
8022
|
tryGetFromCache: false,
|
|
8023
|
+
// When an element carries "container level" styles such as margin or padding, we first
|
|
8024
|
+
// wrap it in a FormatContainer. After all its child nodes are processed, we decide whether
|
|
8025
|
+
// to keep the FormatContainer or fall back to a plain paragraph when it only wraps a single
|
|
8026
|
+
// paragraph. However, formatInsertPointWithContentModel persists the Content Model group path
|
|
8027
|
+
// during processing so the later formatting callback can still use it (see the
|
|
8028
|
+
// DomToModelContextWithPath interface below). If the FormatContainer falls back to a paragraph,
|
|
8029
|
+
// it is removed from the model and the persisted path becomes invalid. To keep the path valid,
|
|
8030
|
+
// we skip the fallback check here and always keep the FormatContainer when one is needed.
|
|
8031
|
+
skipFormatContainerFallbackCheck: true,
|
|
8023
8032
|
});
|
|
8024
8033
|
}
|
|
8025
8034
|
exports.formatInsertPointWithContentModel = formatInsertPointWithContentModel;
|
|
@@ -9057,9 +9066,12 @@ function getContentForCopy(editor, isCut, event) {
|
|
|
9057
9066
|
rawEvent: event,
|
|
9058
9067
|
isCut: isCut,
|
|
9059
9068
|
}).clonedRoot;
|
|
9069
|
+
// Build the text content from the (possibly modified) cloned root DOM tree so that any
|
|
9070
|
+
// changes made by beforeCutCopy event handlers are reflected in the plain text result as well
|
|
9071
|
+
var textModel = (0, roosterjs_content_model_dom_1.domToContentModel)(clonedRoot, (0, roosterjs_content_model_dom_1.createDomToModelContext)());
|
|
9060
9072
|
return {
|
|
9061
9073
|
htmlContent: clonedRoot,
|
|
9062
|
-
textContent: (0, roosterjs_content_model_dom_1.contentModelToText)(
|
|
9074
|
+
textContent: (0, roosterjs_content_model_dom_1.contentModelToText)(textModel),
|
|
9063
9075
|
};
|
|
9064
9076
|
}
|
|
9065
9077
|
}
|
|
@@ -9927,6 +9939,7 @@ var announce = function (core, announceData) {
|
|
|
9927
9939
|
var textToAnnounce = formatString(template || text, formatStrings);
|
|
9928
9940
|
if (!core.lifecycle.announceContainer) {
|
|
9929
9941
|
core.lifecycle.announceContainer = (0, createAriaLiveElement_1.createAriaLiveElement)(core.physicalRoot.ownerDocument);
|
|
9942
|
+
core.domHelper.appendToRoot(core.lifecycle.announceContainer);
|
|
9930
9943
|
}
|
|
9931
9944
|
if (textToAnnounce && core.lifecycle.announceContainer) {
|
|
9932
9945
|
var announceContainer = core.lifecycle.announceContainer;
|
|
@@ -10100,6 +10113,9 @@ var createContentModel = function (core, option, selectionOverride) {
|
|
|
10100
10113
|
var domToModelContext = option
|
|
10101
10114
|
? (0, roosterjs_content_model_dom_1.createDomToModelContext)(editorContext, settings.builtIn, settings.customized, option)
|
|
10102
10115
|
: (0, roosterjs_content_model_dom_1.createDomToModelContextWithConfig)(settings.calculated, editorContext);
|
|
10116
|
+
if (option === null || option === void 0 ? void 0 : option.skipFormatContainerFallbackCheck) {
|
|
10117
|
+
domToModelContext.skipFormatContainerFallbackCheck = true;
|
|
10118
|
+
}
|
|
10103
10119
|
if (selection) {
|
|
10104
10120
|
domToModelContext.selection = selection;
|
|
10105
10121
|
}
|
|
@@ -10418,16 +10434,19 @@ var getDOMSelection = function (core) {
|
|
|
10418
10434
|
exports.getDOMSelection = getDOMSelection;
|
|
10419
10435
|
function getNewSelection(core) {
|
|
10420
10436
|
var _a;
|
|
10437
|
+
var range = core.domHelper.getSelectionRange();
|
|
10438
|
+
if (!range || !core.logicalRoot.contains(range.commonAncestorContainer)) {
|
|
10439
|
+
return null;
|
|
10440
|
+
}
|
|
10421
10441
|
var selection = (_a = core.logicalRoot.ownerDocument.defaultView) === null || _a === void 0 ? void 0 : _a.getSelection();
|
|
10422
|
-
var
|
|
10423
|
-
|
|
10424
|
-
|
|
10425
|
-
|
|
10426
|
-
|
|
10427
|
-
|
|
10428
|
-
|
|
10429
|
-
|
|
10430
|
-
: null;
|
|
10442
|
+
var isReverted = selection
|
|
10443
|
+
? selection.focusNode != range.endContainer || selection.focusOffset != range.endOffset
|
|
10444
|
+
: false;
|
|
10445
|
+
return {
|
|
10446
|
+
type: 'range',
|
|
10447
|
+
range: range,
|
|
10448
|
+
isReverted: isReverted,
|
|
10449
|
+
};
|
|
10431
10450
|
}
|
|
10432
10451
|
|
|
10433
10452
|
|
|
@@ -10871,43 +10890,6 @@ var setContentModel = function (core, model, option, onNodeCreated, isInitializi
|
|
|
10871
10890
|
exports.setContentModel = setContentModel;
|
|
10872
10891
|
|
|
10873
10892
|
|
|
10874
|
-
/***/ },
|
|
10875
|
-
|
|
10876
|
-
/***/ "./packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/addRangeToSelection.ts"
|
|
10877
|
-
/*!**************************************************************************************************!*\
|
|
10878
|
-
!*** ./packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/addRangeToSelection.ts ***!
|
|
10879
|
-
\**************************************************************************************************/
|
|
10880
|
-
(__unused_webpack_module, exports, __webpack_require__) {
|
|
10881
|
-
|
|
10882
|
-
"use strict";
|
|
10883
|
-
|
|
10884
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
10885
|
-
exports.addRangeToSelection = void 0;
|
|
10886
|
-
var areSameSelections_1 = __webpack_require__(/*! ../../corePlugin/cache/areSameSelections */ "./packages/roosterjs-content-model-core/lib/corePlugin/cache/areSameSelections.ts");
|
|
10887
|
-
/**
|
|
10888
|
-
* @internal
|
|
10889
|
-
*/
|
|
10890
|
-
function addRangeToSelection(doc, range, isReverted) {
|
|
10891
|
-
var _a;
|
|
10892
|
-
if (isReverted === void 0) { isReverted = false; }
|
|
10893
|
-
var selection = (_a = doc.defaultView) === null || _a === void 0 ? void 0 : _a.getSelection();
|
|
10894
|
-
if (selection) {
|
|
10895
|
-
var currentRange = selection.rangeCount > 0 && selection.getRangeAt(0);
|
|
10896
|
-
if (currentRange && (0, areSameSelections_1.areSameRanges)(currentRange, range)) {
|
|
10897
|
-
return;
|
|
10898
|
-
}
|
|
10899
|
-
selection.removeAllRanges();
|
|
10900
|
-
if (!isReverted) {
|
|
10901
|
-
selection.addRange(range);
|
|
10902
|
-
}
|
|
10903
|
-
else {
|
|
10904
|
-
selection.setBaseAndExtent(range.endContainer, range.endOffset, range.startContainer, range.startOffset);
|
|
10905
|
-
}
|
|
10906
|
-
}
|
|
10907
|
-
}
|
|
10908
|
-
exports.addRangeToSelection = addRangeToSelection;
|
|
10909
|
-
|
|
10910
|
-
|
|
10911
10893
|
/***/ },
|
|
10912
10894
|
|
|
10913
10895
|
/***/ "./packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/findLastedCoInMergedCell.ts"
|
|
@@ -11009,7 +10991,6 @@ exports.findTableCellElement = findTableCellElement;
|
|
|
11009
10991
|
|
|
11010
10992
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
11011
10993
|
exports.setDOMSelection = void 0;
|
|
11012
|
-
var addRangeToSelection_1 = __webpack_require__(/*! ./addRangeToSelection */ "./packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/addRangeToSelection.ts");
|
|
11013
10994
|
var areSameSelections_1 = __webpack_require__(/*! ../../corePlugin/cache/areSameSelections */ "./packages/roosterjs-content-model-core/lib/corePlugin/cache/areSameSelections.ts");
|
|
11014
10995
|
var ensureUniqueId_1 = __webpack_require__(/*! ../setEditorStyle/ensureUniqueId */ "./packages/roosterjs-content-model-core/lib/coreApi/setEditorStyle/ensureUniqueId.ts");
|
|
11015
10996
|
var findLastedCoInMergedCell_1 = __webpack_require__(/*! ./findLastedCoInMergedCell */ "./packages/roosterjs-content-model-core/lib/coreApi/setDOMSelection/findLastedCoInMergedCell.ts");
|
|
@@ -11035,7 +11016,6 @@ var setDOMSelection = function (core, selection, skipSelectionChangedEvent) {
|
|
|
11035
11016
|
// We are applying a new selection, so we don't need to apply cached selection in DOMEventPlugin.
|
|
11036
11017
|
// Set skipReselectOnFocus to skip this behavior
|
|
11037
11018
|
var skipReselectOnFocus = core.selection.skipReselectOnFocus;
|
|
11038
|
-
var doc = core.physicalRoot.ownerDocument;
|
|
11039
11019
|
var isDarkMode = core.lifecycle.isDarkMode;
|
|
11040
11020
|
core.selection.skipReselectOnFocus = true;
|
|
11041
11021
|
core.api.setEditorStyle(core, DOM_SELECTION_CSS_KEY, null /*cssRule*/);
|
|
@@ -11051,7 +11031,7 @@ var setDOMSelection = function (core, selection, skipSelectionChangedEvent) {
|
|
|
11051
11031
|
: core.selection.imageSelectionBorderColor;
|
|
11052
11032
|
core.api.setEditorStyle(core, DOM_SELECTION_CSS_KEY, "outline-style:solid!important; outline-color:" + (imageSelectionColor || DEFAULT_SELECTION_BORDER_COLOR) + "!important;", [(0, roosterjs_content_model_dom_1.getSafeIdSelector)((0, ensureUniqueId_1.ensureUniqueId)(image, IMAGE_ID))]);
|
|
11053
11033
|
core.api.setEditorStyle(core, HIDE_SELECTION_CSS_KEY, TRANSPARENT_SELECTION_CSS_RULE, [SELECTION_SELECTOR]);
|
|
11054
|
-
setRangeSelection(
|
|
11034
|
+
setRangeSelection(core, image, false /* collapse */);
|
|
11055
11035
|
break;
|
|
11056
11036
|
case 'table':
|
|
11057
11037
|
var table = selection.table, firstColumn = selection.firstColumn, firstRow = selection.firstRow, lastColumn = selection.lastColumn, lastRow = selection.lastRow;
|
|
@@ -11088,11 +11068,11 @@ var setDOMSelection = function (core, selection, skipSelectionChangedEvent) {
|
|
|
11088
11068
|
(0, toggleCaret_1.toggleCaret)(core, true /* hide */);
|
|
11089
11069
|
var nodeToSelect = ((_a = firstCell.cell) === null || _a === void 0 ? void 0 : _a.firstElementChild) || firstCell.cell;
|
|
11090
11070
|
if (nodeToSelect) {
|
|
11091
|
-
setRangeSelection(
|
|
11071
|
+
setRangeSelection(core, nodeToSelect || undefined, true /* collapse */);
|
|
11092
11072
|
}
|
|
11093
11073
|
break;
|
|
11094
11074
|
case 'range':
|
|
11095
|
-
|
|
11075
|
+
core.domHelper.setSelectionRange(selection.range, selection.isReverted);
|
|
11096
11076
|
core.selection.selection = core.domHelper.hasFocus() ? null : selection;
|
|
11097
11077
|
break;
|
|
11098
11078
|
default:
|
|
@@ -11112,9 +11092,10 @@ var setDOMSelection = function (core, selection, skipSelectionChangedEvent) {
|
|
|
11112
11092
|
}
|
|
11113
11093
|
};
|
|
11114
11094
|
exports.setDOMSelection = setDOMSelection;
|
|
11115
|
-
function setRangeSelection(
|
|
11095
|
+
function setRangeSelection(core, element, collapse) {
|
|
11116
11096
|
var _a;
|
|
11117
|
-
if (element &&
|
|
11097
|
+
if (element && core.domHelper.isNodeInEditor(element)) {
|
|
11098
|
+
var doc = core.physicalRoot.ownerDocument;
|
|
11118
11099
|
var range = doc.createRange();
|
|
11119
11100
|
var isReverted = undefined;
|
|
11120
11101
|
range.selectNode(element);
|
|
@@ -11130,7 +11111,7 @@ function setRangeSelection(doc, element, collapse) {
|
|
|
11130
11111
|
selection.focusOffset != range_1.endOffset;
|
|
11131
11112
|
}
|
|
11132
11113
|
}
|
|
11133
|
-
|
|
11114
|
+
core.domHelper.setSelectionRange(range, isReverted);
|
|
11134
11115
|
}
|
|
11135
11116
|
}
|
|
11136
11117
|
|
|
@@ -11317,9 +11298,9 @@ var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-mo
|
|
|
11317
11298
|
*/
|
|
11318
11299
|
function ensureUniqueId(element, idPrefix) {
|
|
11319
11300
|
idPrefix = element.id || idPrefix;
|
|
11320
|
-
var
|
|
11301
|
+
var root = element.getRootNode();
|
|
11321
11302
|
var i = 0;
|
|
11322
|
-
while (!element.id ||
|
|
11303
|
+
while (!element.id || root.querySelectorAll((0, roosterjs_content_model_dom_1.getSafeIdSelector)(element.id)).length > 1) {
|
|
11323
11304
|
element.id = idPrefix + '_' + i++;
|
|
11324
11305
|
}
|
|
11325
11306
|
return element.id;
|
|
@@ -11352,7 +11333,7 @@ var setEditorStyle = function (core, key, cssRule, subSelectors, maxRuleLength)
|
|
|
11352
11333
|
if (!styleElement && cssRule) {
|
|
11353
11334
|
var doc = core.physicalRoot.ownerDocument;
|
|
11354
11335
|
styleElement = doc.createElement('style');
|
|
11355
|
-
|
|
11336
|
+
core.domHelper.appendToRoot(styleElement);
|
|
11356
11337
|
styleElement.dataset.roosterjsStyleKey = key;
|
|
11357
11338
|
core.lifecycle.styleElements[key] = styleElement;
|
|
11358
11339
|
}
|
|
@@ -11606,6 +11587,11 @@ var CachePlugin = /** @class */ (function () {
|
|
|
11606
11587
|
_this.invalidateCache();
|
|
11607
11588
|
}
|
|
11608
11589
|
break;
|
|
11590
|
+
case 'attribute':
|
|
11591
|
+
if (!_this.state.domIndexer.reconcileImageAttribute(mutation.element, mutation.attributeName)) {
|
|
11592
|
+
_this.invalidateCache();
|
|
11593
|
+
}
|
|
11594
|
+
break;
|
|
11609
11595
|
case 'unknown':
|
|
11610
11596
|
_this.invalidateCache();
|
|
11611
11597
|
break;
|
|
@@ -11830,12 +11816,13 @@ exports.createParagraphMap = createParagraphMap;
|
|
|
11830
11816
|
/*!*****************************************************************************************!*\
|
|
11831
11817
|
!*** ./packages/roosterjs-content-model-core/lib/corePlugin/cache/areSameSelections.ts ***!
|
|
11832
11818
|
\*****************************************************************************************/
|
|
11833
|
-
(__unused_webpack_module, exports) {
|
|
11819
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
11834
11820
|
|
|
11835
11821
|
"use strict";
|
|
11836
11822
|
|
|
11837
11823
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
11838
|
-
exports.
|
|
11824
|
+
exports.areSameTableSelections = exports.areSameSelections = void 0;
|
|
11825
|
+
var areSameRanges_1 = __webpack_require__(/*! ../../utils/areSameRanges */ "./packages/roosterjs-content-model-core/lib/utils/areSameRanges.ts");
|
|
11839
11826
|
/**
|
|
11840
11827
|
* @internal
|
|
11841
11828
|
* Check if the given selections are the same
|
|
@@ -11861,7 +11848,7 @@ function areSameSelections(sel1, sel2) {
|
|
|
11861
11848
|
range1.endOffset == end.offset);
|
|
11862
11849
|
}
|
|
11863
11850
|
else {
|
|
11864
|
-
return areSameRanges(range1, sel2.range);
|
|
11851
|
+
return (0, areSameRanges_1.areSameRanges)(range1, sel2.range);
|
|
11865
11852
|
}
|
|
11866
11853
|
}
|
|
11867
11854
|
else {
|
|
@@ -11880,7 +11867,6 @@ var TableSelectionKeys = [
|
|
|
11880
11867
|
'firstRow',
|
|
11881
11868
|
'lastRow',
|
|
11882
11869
|
];
|
|
11883
|
-
var RangeKeys = ['startContainer', 'endContainer', 'startOffset', 'endOffset'];
|
|
11884
11870
|
/**
|
|
11885
11871
|
* @internal
|
|
11886
11872
|
*/
|
|
@@ -11888,13 +11874,6 @@ function areSameTableSelections(t1, t2) {
|
|
|
11888
11874
|
return areSame(t1, t2, TableSelectionKeys);
|
|
11889
11875
|
}
|
|
11890
11876
|
exports.areSameTableSelections = areSameTableSelections;
|
|
11891
|
-
/**
|
|
11892
|
-
* @internal
|
|
11893
|
-
*/
|
|
11894
|
-
function areSameRanges(r1, r2) {
|
|
11895
|
-
return areSame(r1, r2, RangeKeys);
|
|
11896
|
-
}
|
|
11897
|
-
exports.areSameRanges = areSameRanges;
|
|
11898
11877
|
function isCacheSelection(sel) {
|
|
11899
11878
|
return !!sel.start;
|
|
11900
11879
|
}
|
|
@@ -12072,7 +12051,13 @@ var DomIndexerImpl = /** @class */ (function () {
|
|
|
12072
12051
|
}
|
|
12073
12052
|
else {
|
|
12074
12053
|
var marker1 = this.reconcileNodeSelection(startContainer, startOffset);
|
|
12075
|
-
|
|
12054
|
+
// Pass marker1 to the second call so its adjacent-marker cleanup
|
|
12055
|
+
// does not consume the SelectionMarker we just inserted. Without
|
|
12056
|
+
// this guard, when marker1 lands directly next to endContainer's
|
|
12057
|
+
// segment in paragraph.segments (e.g. startOffset == startContainer
|
|
12058
|
+
// text length), the second splice would absorb marker1 and leave
|
|
12059
|
+
// setSelection with a dangling reference. See issue #3341.
|
|
12060
|
+
var marker2 = this.reconcileNodeSelection(endContainer, endOffset, undefined, undefined, marker1);
|
|
12076
12061
|
if (marker1 && marker2) {
|
|
12077
12062
|
if (newSelection.isReverted) {
|
|
12078
12063
|
model.hasRevertedRangeSelection = true;
|
|
@@ -12138,6 +12123,33 @@ var DomIndexerImpl = /** @class */ (function () {
|
|
|
12138
12123
|
return false;
|
|
12139
12124
|
}
|
|
12140
12125
|
};
|
|
12126
|
+
DomIndexerImpl.prototype.reconcileImageAttribute = function (element, attributeName) {
|
|
12127
|
+
var _a, _b;
|
|
12128
|
+
if ((0, roosterjs_content_model_dom_1.isElementOfType)(element, 'img')) {
|
|
12129
|
+
var image = (_a = getIndexedSegmentItem(element)) === null || _a === void 0 ? void 0 : _a.segments[0];
|
|
12130
|
+
if ((image === null || image === void 0 ? void 0 : image.segmentType) == 'Image') {
|
|
12131
|
+
if (attributeName == 'src') {
|
|
12132
|
+
// Use getAttribute('src') instead of retrieving src directly, in case the src
|
|
12133
|
+
// has port and may be stripped by browser. This matches imageProcessor.
|
|
12134
|
+
image.src = (_b = element.getAttribute('src')) !== null && _b !== void 0 ? _b : '';
|
|
12135
|
+
return true;
|
|
12136
|
+
}
|
|
12137
|
+
else if (attributeName.indexOf('data-') == 0) {
|
|
12138
|
+
// A data-* attribute may be added, modified or removed. Rebuild the whole
|
|
12139
|
+
// dataset from DOM to keep it in sync, the same way imageProcessor builds it.
|
|
12140
|
+
var dataset_1 = image.dataset;
|
|
12141
|
+
(0, roosterjs_content_model_dom_1.getObjectKeys)(dataset_1).forEach(function (key) {
|
|
12142
|
+
delete dataset_1[key];
|
|
12143
|
+
});
|
|
12144
|
+
(0, roosterjs_content_model_dom_1.getObjectKeys)(element.dataset).forEach(function (key) {
|
|
12145
|
+
dataset_1[key] = element.dataset[key] || '';
|
|
12146
|
+
});
|
|
12147
|
+
return true;
|
|
12148
|
+
}
|
|
12149
|
+
}
|
|
12150
|
+
}
|
|
12151
|
+
return false;
|
|
12152
|
+
};
|
|
12141
12153
|
DomIndexerImpl.prototype.onBlockEntityDelimiter = function (node, entity, parent) {
|
|
12142
12154
|
if ((0, roosterjs_content_model_dom_1.isNodeOfType)(node, 'ELEMENT_NODE') && (0, roosterjs_content_model_dom_1.isEntityDelimiter)(node) && node.firstChild) {
|
|
12143
12155
|
var indexedDelimiter = node.firstChild;
|
|
@@ -12148,10 +12160,10 @@ var DomIndexerImpl = /** @class */ (function () {
|
|
|
12148
12160
|
var start = selection.start, end = selection.end;
|
|
12149
12161
|
return start.node == end.node && start.offset == end.offset;
|
|
12150
12162
|
};
|
|
12151
|
-
DomIndexerImpl.prototype.reconcileNodeSelection = function (node, offset, defaultFormat, selectionMarker) {
|
|
12163
|
+
DomIndexerImpl.prototype.reconcileNodeSelection = function (node, offset, defaultFormat, selectionMarker, preserveMarker) {
|
|
12152
12164
|
if ((0, roosterjs_content_model_dom_1.isNodeOfType)(node, 'TEXT_NODE')) {
|
|
12153
12165
|
if (isIndexedSegment(node)) {
|
|
12154
|
-
return this.reconcileTextSelection(node, offset, undefined, selectionMarker);
|
|
12166
|
+
return this.reconcileTextSelection(node, offset, undefined, selectionMarker, preserveMarker);
|
|
12155
12167
|
}
|
|
12156
12168
|
else if (isIndexedDelimiter(node)) {
|
|
12157
12169
|
return this.reconcileDelimiterSelection(node, defaultFormat);
|
|
@@ -12181,7 +12193,7 @@ var DomIndexerImpl = /** @class */ (function () {
|
|
|
12181
12193
|
}
|
|
12182
12194
|
return marker;
|
|
12183
12195
|
};
|
|
12184
|
-
DomIndexerImpl.prototype.reconcileTextSelection = function (textNode, startOffset, endOffset, selectionMarker) {
|
|
12196
|
+
DomIndexerImpl.prototype.reconcileTextSelection = function (textNode, startOffset, endOffset, selectionMarker, preserveMarker) {
|
|
12185
12197
|
var _a;
|
|
12186
12198
|
var _b, _c, _d, _e, _f, _g;
|
|
12187
12199
|
var _h = textNode.__roosterjsContentModel, paragraph = _h.paragraph, segments = _h.segments;
|
|
@@ -12234,11 +12246,13 @@ var DomIndexerImpl = /** @class */ (function () {
|
|
|
12234
12246
|
var lastIndex = paragraph.segments.indexOf(last);
|
|
12235
12247
|
if (firstIndex >= 0 && lastIndex >= 0) {
|
|
12236
12248
|
while (firstIndex > 0 &&
|
|
12237
|
-
paragraph.segments[firstIndex - 1].segmentType == 'SelectionMarker'
|
|
12249
|
+
paragraph.segments[firstIndex - 1].segmentType == 'SelectionMarker' &&
|
|
12250
|
+
paragraph.segments[firstIndex - 1] !== preserveMarker) {
|
|
12238
12251
|
firstIndex--;
|
|
12239
12252
|
}
|
|
12240
12253
|
while (lastIndex < paragraph.segments.length - 1 &&
|
|
12241
|
-
paragraph.segments[lastIndex + 1].segmentType == 'SelectionMarker'
|
|
12254
|
+
paragraph.segments[lastIndex + 1].segmentType == 'SelectionMarker' &&
|
|
12255
|
+
paragraph.segments[lastIndex + 1] !== preserveMarker) {
|
|
12242
12256
|
lastIndex++;
|
|
12243
12257
|
}
|
|
12244
12258
|
(_a = paragraph.segments).splice.apply(_a, (0, tslib_1.__spreadArray)([firstIndex, lastIndex - firstIndex + 1], (0, tslib_1.__read)(newSegments), false));
|
|
@@ -12451,6 +12465,16 @@ var TextMutationObserverImpl = /** @class */ (function () {
|
|
|
12451
12465
|
(0, roosterjs_content_model_dom_1.isNodeOfType)(target, 'ELEMENT_NODE')) {
|
|
12452
12466
|
_this.onMutation({ type: 'elementId', element: target });
|
|
12453
12467
|
}
|
|
12468
|
+
else if (mutation.attributeName &&
|
|
12469
|
+
(0, roosterjs_content_model_dom_1.isNodeOfType)(target, 'ELEMENT_NODE') &&
|
|
12470
|
+
(mutation.attributeName == 'src' ||
|
|
12471
|
+
mutation.attributeName.indexOf('data-') == 0)) {
|
|
12472
|
+
_this.onMutation({
|
|
12473
|
+
type: 'attribute',
|
|
12474
|
+
element: target,
|
|
12475
|
+
attributeName: mutation.attributeName,
|
|
12476
|
+
});
|
|
12477
|
+
}
|
|
12454
12478
|
else {
|
|
12455
12479
|
// We cannot handle attributes changes on editor content for now
|
|
12456
12480
|
canHandle = false;
|
|
@@ -14356,6 +14380,7 @@ var LifecyclePlugin = /** @class */ (function () {
|
|
|
14356
14380
|
delete this.state.rewriteFromModel;
|
|
14357
14381
|
// Initialize the Announce container.
|
|
14358
14382
|
this.state.announceContainer = (0, createAriaLiveElement_1.createAriaLiveElement)(editor.getDocument());
|
|
14383
|
+
editor.getDOMHelper().appendToRoot(this.state.announceContainer);
|
|
14359
14384
|
};
|
|
14360
14385
|
/**
|
|
14361
14386
|
* Dispose this plugin
|
|
@@ -14549,20 +14574,23 @@ var SelectionPlugin = /** @class */ (function () {
|
|
|
14549
14574
|
}
|
|
14550
14575
|
};
|
|
14551
14576
|
this.onSelectionChange = function () {
|
|
14552
|
-
var _a;
|
|
14577
|
+
var _a, _b;
|
|
14553
14578
|
if (((_a = _this.editor) === null || _a === void 0 ? void 0 : _a.hasFocus()) && !_this.editor.isInShadowEdit()) {
|
|
14554
14579
|
var newSelection = _this.editor.getDOMSelection();
|
|
14580
|
+
var domHelper = _this.editor.getDOMHelper();
|
|
14555
14581
|
//If am image selection changed to a wider range due a keyboard event, we should update the selection
|
|
14556
|
-
var
|
|
14557
|
-
if (
|
|
14558
|
-
var image = (0, isSingleImageInSelection_1.isSingleImageInSelection)(
|
|
14582
|
+
var range = domHelper.getSelectionRange();
|
|
14583
|
+
if (range) {
|
|
14584
|
+
var image = (0, isSingleImageInSelection_1.isSingleImageInSelection)(range);
|
|
14559
14585
|
if ((newSelection === null || newSelection === void 0 ? void 0 : newSelection.type) == 'image' && !image) {
|
|
14560
|
-
var
|
|
14586
|
+
var sel = (_b = _this.editor.getDocument().defaultView) === null || _b === void 0 ? void 0 : _b.getSelection();
|
|
14587
|
+
var isReverted = sel
|
|
14588
|
+
? sel.focusNode != range.endContainer || sel.focusOffset != range.endOffset
|
|
14589
|
+
: false;
|
|
14561
14590
|
_this.editor.setDOMSelection({
|
|
14562
14591
|
type: 'range',
|
|
14563
14592
|
range: range,
|
|
14564
|
-
isReverted:
|
|
14565
|
-
selection.focusOffset != range.endOffset,
|
|
14593
|
+
isReverted: isReverted,
|
|
14566
14594
|
});
|
|
14567
14595
|
}
|
|
14568
14596
|
else if ((newSelection === null || newSelection === void 0 ? void 0 : newSelection.type) !== 'image' && image) {
|
|
@@ -15951,10 +15979,23 @@ exports.Editor = Editor;
|
|
|
15951
15979
|
|
|
15952
15980
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
15953
15981
|
exports.createDOMHelper = void 0;
|
|
15982
|
+
var areSameRanges_1 = __webpack_require__(/*! ../../utils/areSameRanges */ "./packages/roosterjs-content-model-core/lib/utils/areSameRanges.ts");
|
|
15954
15983
|
var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
|
|
15984
|
+
function isSelectionWithComposedRanges(sel) {
|
|
15985
|
+
return 'getComposedRanges' in sel;
|
|
15986
|
+
}
|
|
15987
|
+
function isShadowRoot(node) {
|
|
15988
|
+
return 'host' in node;
|
|
15989
|
+
}
|
|
15955
15990
|
var DOMHelperImpl = /** @class */ (function () {
|
|
15956
15991
|
function DOMHelperImpl(contentDiv, options) {
|
|
15992
|
+
var _a;
|
|
15957
15993
|
this.contentDiv = contentDiv;
|
|
15994
|
+
var rootNode = contentDiv.getRootNode();
|
|
15995
|
+
this.shadowRoot = (options === null || options === void 0 ? void 0 : options.useShadowDom) && isShadowRoot(rootNode) ? rootNode : null;
|
|
15996
|
+
this.doc = contentDiv.ownerDocument;
|
|
15997
|
+
var sel = (_a = this.doc.defaultView) === null || _a === void 0 ? void 0 : _a.getSelection();
|
|
15998
|
+
this.useComposedRanges = !!(this.shadowRoot && sel && 'getComposedRanges' in sel);
|
|
15958
15999
|
}
|
|
15959
16000
|
DOMHelperImpl.prototype.queryElements = function (selector) {
|
|
15960
16001
|
return (0, roosterjs_content_model_dom_1.toArray)(this.contentDiv.querySelectorAll(selector));
|
|
@@ -16016,7 +16057,9 @@ var DOMHelperImpl = /** @class */ (function () {
|
|
|
16016
16057
|
return this.contentDiv;
|
|
16017
16058
|
};
|
|
16018
16059
|
DOMHelperImpl.prototype.hasFocus = function () {
|
|
16019
|
-
var activeElement = this.
|
|
16060
|
+
var activeElement = this.shadowRoot
|
|
16061
|
+
? this.shadowRoot.activeElement
|
|
16062
|
+
: this.doc.activeElement;
|
|
16020
16063
|
return !!(activeElement && this.contentDiv.contains(activeElement));
|
|
16021
16064
|
};
|
|
16022
16065
|
/**
|
|
@@ -16083,6 +16126,51 @@ var DOMHelperImpl = /** @class */ (function () {
|
|
|
16083
16126
|
DOMHelperImpl.prototype.getRangesByText = function (text, matchCase, wholeWord) {
|
|
16084
16127
|
return (0, roosterjs_content_model_dom_1.getRangesByText)(this.contentDiv, text, matchCase, wholeWord, true /*editableOnly*/);
|
|
16085
16128
|
};
|
|
16129
|
+
DOMHelperImpl.prototype.getSelectionRange = function () {
|
|
16130
|
+
var _a;
|
|
16131
|
+
var sel = (_a = this.doc.defaultView) === null || _a === void 0 ? void 0 : _a.getSelection();
|
|
16132
|
+
if (!sel) {
|
|
16133
|
+
return null;
|
|
16134
|
+
}
|
|
16135
|
+
if (this.useComposedRanges && this.shadowRoot && isSelectionWithComposedRanges(sel)) {
|
|
16136
|
+
var staticRanges = sel.getComposedRanges({
|
|
16137
|
+
shadowRoots: [this.shadowRoot],
|
|
16138
|
+
});
|
|
16139
|
+
if ((staticRanges === null || staticRanges === void 0 ? void 0 : staticRanges.length) > 0) {
|
|
16140
|
+
var sr = staticRanges[0];
|
|
16141
|
+
var range = this.doc.createRange();
|
|
16142
|
+
range.setStart(sr.startContainer, sr.startOffset);
|
|
16143
|
+
range.setEnd(sr.endContainer, sr.endOffset);
|
|
16144
|
+
return range;
|
|
16145
|
+
}
|
|
16146
|
+
return null;
|
|
16147
|
+
}
|
|
16148
|
+
return sel.rangeCount > 0 ? sel.getRangeAt(0) : null;
|
|
16149
|
+
};
|
|
16150
|
+
DOMHelperImpl.prototype.setSelectionRange = function (range, isReverted) {
|
|
16151
|
+
var _a;
|
|
16152
|
+
if (isReverted === void 0) { isReverted = false; }
|
|
16153
|
+
var sel = (_a = this.doc.defaultView) === null || _a === void 0 ? void 0 : _a.getSelection();
|
|
16154
|
+
var currentRange = this.getSelectionRange();
|
|
16155
|
+
if (!sel || (currentRange && (0, areSameRanges_1.areSameRanges)(range, currentRange))) {
|
|
16156
|
+
return;
|
|
16157
|
+
}
|
|
16158
|
+
var startContainer = range.startContainer, startOffset = range.startOffset, endContainer = range.endContainer, endOffset = range.endOffset;
|
|
16159
|
+
if (!isReverted) {
|
|
16160
|
+
sel.setBaseAndExtent(startContainer, startOffset, endContainer, endOffset);
|
|
16161
|
+
}
|
|
16162
|
+
else {
|
|
16163
|
+
sel.setBaseAndExtent(endContainer, endOffset, startContainer, startOffset);
|
|
16164
|
+
}
|
|
16165
|
+
};
|
|
16166
|
+
DOMHelperImpl.prototype.appendToRoot = function (element) {
|
|
16167
|
+
if (this.shadowRoot) {
|
|
16168
|
+
this.shadowRoot.appendChild(element);
|
|
16169
|
+
}
|
|
16170
|
+
else {
|
|
16171
|
+
this.doc.body.appendChild(element);
|
|
16172
|
+
}
|
|
16173
|
+
};
|
|
16086
16174
|
return DOMHelperImpl;
|
|
16087
16175
|
}());
|
|
16088
16176
|
/**
|
|
@@ -16199,7 +16287,10 @@ function createEditorCore(contentDiv, options) {
|
|
|
16199
16287
|
corePlugins.lifecycle,
|
|
16200
16288
|
], false), environment: createEditorEnvironment(contentDiv, options), darkColorHandler: (0, DarkColorHandlerImpl_1.createDarkColorHandler)(contentDiv, (_b = options.getDarkColor) !== null && _b !== void 0 ? _b : getDarkColorFallback, options.knownColors, options.generateColorKey), trustedHTMLHandler: options.trustedHTMLHandler && !(0, domCreator_1.isDOMCreator)(options.trustedHTMLHandler)
|
|
16201
16289
|
? options.trustedHTMLHandler
|
|
16202
|
-
: (0, domCreator_1.createTrustedHTMLHandler)(domCreator), domCreator: domCreator, domHelper: (0, DOMHelperImpl_1.createDOMHelper)(contentDiv
|
|
16290
|
+
: (0, domCreator_1.createTrustedHTMLHandler)(domCreator), domCreator: domCreator, domHelper: (0, DOMHelperImpl_1.createDOMHelper)(contentDiv, {
|
|
16291
|
+
useShadowDom: !!options.experimentalFeatures &&
|
|
16292
|
+
options.experimentalFeatures.indexOf('ShadowDom') >= 0,
|
|
16293
|
+
}) }, getPluginState(corePlugins)), { disposeErrorHandler: options.disposeErrorHandler, onFixUpModel: options.onFixUpModel, experimentalFeatures: options.experimentalFeatures ? (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(options.experimentalFeatures), false) : [] });
|
|
16203
16294
|
}
|
|
16204
16295
|
exports.createEditorCore = createEditorCore;
|
|
16205
16296
|
function createEditorEnvironment(contentDiv, options) {
|
|
@@ -16357,6 +16448,8 @@ var containerSizeFormatParser = function (format, element) {
|
|
|
16357
16448
|
if (element.tagName == 'DIV' || element.tagName == 'P') {
|
|
16358
16449
|
delete format.width;
|
|
16359
16450
|
delete format.height;
|
|
16451
|
+
delete format.maxHeight;
|
|
16452
|
+
delete format.maxWidth;
|
|
16360
16453
|
}
|
|
16361
16454
|
};
|
|
16362
16455
|
exports.containerSizeFormatParser = containerSizeFormatParser;
|
|
@@ -16653,6 +16746,29 @@ var pasteWhiteSpaceFormatParser = function (format, element, context, defaultSty
|
|
|
16653
16746
|
exports.pasteWhiteSpaceFormatParser = pasteWhiteSpaceFormatParser;
|
|
16654
16747
|
|
|
16655
16748
|
|
|
16749
|
+
/***/ },
|
|
16750
|
+
|
|
16751
|
+
/***/ "./packages/roosterjs-content-model-core/lib/utils/areSameRanges.ts"
|
|
16752
|
+
/*!**************************************************************************!*\
|
|
16753
|
+
!*** ./packages/roosterjs-content-model-core/lib/utils/areSameRanges.ts ***!
|
|
16754
|
+
\**************************************************************************/
|
|
16755
|
+
(__unused_webpack_module, exports) {
|
|
16756
|
+
|
|
16757
|
+
"use strict";
|
|
16758
|
+
|
|
16759
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
16760
|
+
exports.areSameRanges = void 0;
|
|
16761
|
+
var RangeKeys = ['startContainer', 'endContainer', 'startOffset', 'endOffset'];
|
|
16762
|
+
/**
|
|
16763
|
+
* @internal
|
|
16764
|
+
* Check if two ranges have the same start and end positions.
|
|
16765
|
+
*/
|
|
16766
|
+
function areSameRanges(r1, r2) {
|
|
16767
|
+
return RangeKeys.every(function (k) { return r1[k] == r2[k]; });
|
|
16768
|
+
}
|
|
16769
|
+
exports.areSameRanges = areSameRanges;
|
|
16770
|
+
|
|
16771
|
+
|
|
16656
16772
|
/***/ },
|
|
16657
16773
|
|
|
16658
16774
|
/***/ "./packages/roosterjs-content-model-core/lib/utils/createAriaLiveElement.ts"
|
|
@@ -16678,7 +16794,6 @@ function createAriaLiveElement(document) {
|
|
|
16678
16794
|
div.style.whiteSpace = 'nowrap';
|
|
16679
16795
|
div.style.width = '1px';
|
|
16680
16796
|
div.ariaLive = 'assertive';
|
|
16681
|
-
document.body.appendChild(div);
|
|
16682
16797
|
return div;
|
|
16683
16798
|
}
|
|
16684
16799
|
exports.createAriaLiveElement = createAriaLiveElement;
|
|
@@ -18076,7 +18191,9 @@ var formatContainerProcessorInternal = function (group, element, context, forceF
|
|
|
18076
18191
|
if (element.style.fontSize && parseInt(element.style.fontSize) == 0) {
|
|
18077
18192
|
formatContainer.zeroFontSize = true;
|
|
18078
18193
|
}
|
|
18079
|
-
if (
|
|
18194
|
+
if (!context.skipFormatContainerFallbackCheck &&
|
|
18195
|
+
shouldFallbackToParagraph(formatContainer) &&
|
|
18196
|
+
!forceFormatContainer) {
|
|
18080
18197
|
// For DIV container that only has one paragraph child, container style can be merged into paragraph
|
|
18081
18198
|
// and no need to have this container
|
|
18082
18199
|
var paragraph = formatContainer.blocks[0];
|
|
@@ -21169,11 +21286,13 @@ exports.directionFormatHandler = {
|
|
|
21169
21286
|
format.direction = dir == 'rtl' ? 'rtl' : 'ltr';
|
|
21170
21287
|
}
|
|
21171
21288
|
},
|
|
21172
|
-
apply: function (format, element) {
|
|
21289
|
+
apply: function (format, element, context) {
|
|
21173
21290
|
if (format.direction) {
|
|
21174
21291
|
element.style.direction = format.direction;
|
|
21175
21292
|
}
|
|
21176
|
-
if (format.direction == 'rtl' &&
|
|
21293
|
+
if (format.direction == 'rtl' &&
|
|
21294
|
+
(0, isElementOfType_1.isElementOfType)(element, 'table') &&
|
|
21295
|
+
context.implicitFormat.direction != 'rtl') {
|
|
21177
21296
|
element.style.justifySelf = 'flex-end';
|
|
21178
21297
|
}
|
|
21179
21298
|
},
|
|
@@ -21710,6 +21829,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
|
21710
21829
|
exports.borderFormatHandler = void 0;
|
|
21711
21830
|
var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
|
|
21712
21831
|
var borderKeys_1 = __webpack_require__(/*! ../utils/borderKeys */ "./packages/roosterjs-content-model-dom/lib/formatHandlers/utils/borderKeys.ts");
|
|
21832
|
+
var borderValues_1 = __webpack_require__(/*! ../../domUtils/style/borderValues */ "./packages/roosterjs-content-model-dom/lib/domUtils/style/borderValues.ts");
|
|
21713
21833
|
// This array needs to match BorderKeys array
|
|
21714
21834
|
var BorderWidthKeys = [
|
|
21715
21835
|
'borderTopWidth',
|
|
@@ -21738,7 +21858,17 @@ exports.borderFormatHandler = {
|
|
|
21738
21858
|
width = '0px';
|
|
21739
21859
|
}
|
|
21740
21860
|
if (value && width != defaultWidth) {
|
|
21741
|
-
|
|
21861
|
+
var result = value;
|
|
21862
|
+
if (result.includes('initial')) {
|
|
21863
|
+
// Remove 'initial' from the last part (color) of the border value
|
|
21864
|
+
// since browsers ignore it when setting the inline style property
|
|
21865
|
+
var border = (0, borderValues_1.extractBorderValues)(value);
|
|
21866
|
+
if (border.color === 'initial') {
|
|
21867
|
+
border.color = '';
|
|
21868
|
+
}
|
|
21869
|
+
result = (0, borderValues_1.combineBorderValue)(border);
|
|
21870
|
+
}
|
|
21871
|
+
format[key] = result == 'none' ? '' : result;
|
|
21742
21872
|
}
|
|
21743
21873
|
});
|
|
21744
21874
|
var borderRadius = element.style.borderRadius;
|
|
@@ -24140,6 +24270,7 @@ var createText_1 = __webpack_require__(/*! ../creators/createText */ "./packages
|
|
|
24140
24270
|
var ensureParagraph_1 = __webpack_require__(/*! ./ensureParagraph */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/ensureParagraph.ts");
|
|
24141
24271
|
var hasSpacesOnly_1 = __webpack_require__(/*! ./hasSpacesOnly */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/hasSpacesOnly.ts");
|
|
24142
24272
|
var isWhiteSpacePreserved_1 = __webpack_require__(/*! ../../domUtils/isWhiteSpacePreserved */ "./packages/roosterjs-content-model-dom/lib/domUtils/isWhiteSpacePreserved.ts");
|
|
24273
|
+
var stripInvisibleUnicode_1 = __webpack_require__(/*! ./stripInvisibleUnicode */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/stripInvisibleUnicode.ts");
|
|
24143
24274
|
/**
|
|
24144
24275
|
* Add a new text segment to current paragraph
|
|
24145
24276
|
* @param group Current BlockGroup that the paragraph belong to
|
|
@@ -24155,7 +24286,11 @@ function addTextSegment(group, text, context) {
|
|
|
24155
24286
|
if (!(0, hasSpacesOnly_1.hasSpacesOnly)(text) ||
|
|
24156
24287
|
((_a = paragraph === null || paragraph === void 0 ? void 0 : paragraph.segments.length) !== null && _a !== void 0 ? _a : 0) > 0 ||
|
|
24157
24288
|
(0, isWhiteSpacePreserved_1.isWhiteSpacePreserved)(paragraph === null || paragraph === void 0 ? void 0 : paragraph.format.whiteSpace)) {
|
|
24158
|
-
|
|
24289
|
+
var filteredText = context.experimentalFeatures &&
|
|
24290
|
+
context.experimentalFeatures.indexOf('FilterInvisibleUnicode') > -1
|
|
24291
|
+
? (0, stripInvisibleUnicode_1.stripInvisibleUnicode)(text)
|
|
24292
|
+
: text;
|
|
24293
|
+
textModel = (0, createText_1.createText)(filteredText, context.segmentFormat);
|
|
24159
24294
|
if (context.isInSelection) {
|
|
24160
24295
|
textModel.isSelected = true;
|
|
24161
24296
|
}
|
|
@@ -24790,6 +24925,34 @@ function normalizeSegmentFormat(format, environment) {
|
|
|
24790
24925
|
exports.normalizeSegmentFormat = normalizeSegmentFormat;
|
|
24791
24926
|
|
|
24792
24927
|
|
|
24928
|
+
/***/ },
|
|
24929
|
+
|
|
24930
|
+
/***/ "./packages/roosterjs-content-model-dom/lib/modelApi/common/stripInvisibleUnicode.ts"
|
|
24931
|
+
/*!*******************************************************************************************!*\
|
|
24932
|
+
!*** ./packages/roosterjs-content-model-dom/lib/modelApi/common/stripInvisibleUnicode.ts ***!
|
|
24933
|
+
\*******************************************************************************************/
|
|
24934
|
+
(__unused_webpack_module, exports) {
|
|
24935
|
+
|
|
24936
|
+
"use strict";
|
|
24937
|
+
|
|
24938
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
24939
|
+
exports.stripInvisibleUnicode = void 0;
|
|
24940
|
+
// According to https://embracethered.com/blog/posts/2024/hiding-and-finding-text-with-unicode-tags/
|
|
24941
|
+
// there are some invisible unicode characters in the range of U+E0000 to U+EFFFF, which are used for hiding text in HTML.
|
|
24942
|
+
// We need to strip them out before processing the pasted content, otherwise they will be treated as normal text and cause unexpected behavior.
|
|
24943
|
+
var INVISIBLE_UNICODE_REGEX = /[\u{E0000}-\u{EFFFF}]/gu;
|
|
24944
|
+
/**
|
|
24945
|
+
* @internal
|
|
24946
|
+
* Strip invisible unicode characters from the given string
|
|
24947
|
+
* @param value The string to be processed
|
|
24948
|
+
* @returns The string with invisible unicode characters removed
|
|
24949
|
+
*/
|
|
24950
|
+
function stripInvisibleUnicode(value) {
|
|
24951
|
+
return value.replace(INVISIBLE_UNICODE_REGEX, '');
|
|
24952
|
+
}
|
|
24953
|
+
exports.stripInvisibleUnicode = stripInvisibleUnicode;
|
|
24954
|
+
|
|
24955
|
+
|
|
24793
24956
|
/***/ },
|
|
24794
24957
|
|
|
24795
24958
|
/***/ "./packages/roosterjs-content-model-dom/lib/modelApi/common/unwrapBlock.ts"
|
|
@@ -25248,16 +25411,25 @@ exports.createParagraphDecorator = createParagraphDecorator;
|
|
|
25248
25411
|
|
|
25249
25412
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
25250
25413
|
exports.createSelectionMarker = void 0;
|
|
25251
|
-
var
|
|
25414
|
+
var EmptySegmentFormat_1 = __webpack_require__(/*! ../../constants/EmptySegmentFormat */ "./packages/roosterjs-content-model-dom/lib/constants/EmptySegmentFormat.ts");
|
|
25415
|
+
var getObjectKeys_1 = __webpack_require__(/*! ../../domUtils/getObjectKeys */ "./packages/roosterjs-content-model-dom/lib/domUtils/getObjectKeys.ts");
|
|
25252
25416
|
/**
|
|
25253
25417
|
* Create a ContentModelSelectionMarker model
|
|
25254
25418
|
* @param format @optional The format of this model
|
|
25255
25419
|
*/
|
|
25256
25420
|
function createSelectionMarker(format) {
|
|
25421
|
+
var filteredFormat = {};
|
|
25422
|
+
if (format) {
|
|
25423
|
+
(0, getObjectKeys_1.getObjectKeys)(EmptySegmentFormat_1.EmptySegmentFormat).forEach(function (key) {
|
|
25424
|
+
if (key in format) {
|
|
25425
|
+
filteredFormat[key] = format[key];
|
|
25426
|
+
}
|
|
25427
|
+
});
|
|
25428
|
+
}
|
|
25257
25429
|
return {
|
|
25258
25430
|
segmentType: 'SelectionMarker',
|
|
25259
25431
|
isSelected: true,
|
|
25260
|
-
format:
|
|
25432
|
+
format: filteredFormat,
|
|
25261
25433
|
};
|
|
25262
25434
|
}
|
|
25263
25435
|
exports.createSelectionMarker = createSelectionMarker;
|
|
@@ -28558,6 +28730,7 @@ function internalIterateSelections(path, callback, option, table, treatAllAsSele
|
|
|
28558
28730
|
|
|
28559
28731
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
28560
28732
|
exports.setSelection = void 0;
|
|
28733
|
+
var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
|
|
28561
28734
|
var isGeneralSegment_1 = __webpack_require__(/*! ../typeCheck/isGeneralSegment */ "./packages/roosterjs-content-model-dom/lib/modelApi/typeCheck/isGeneralSegment.ts");
|
|
28562
28735
|
var mutate_1 = __webpack_require__(/*! ../common/mutate */ "./packages/roosterjs-content-model-dom/lib/modelApi/common/mutate.ts");
|
|
28563
28736
|
/**
|
|
@@ -28595,6 +28768,7 @@ function setSelectionToBlockGroup(group, isInSelection, start, end) {
|
|
|
28595
28768
|
});
|
|
28596
28769
|
}
|
|
28597
28770
|
function setSelectionToBlock(block, isInSelection, start, end) {
|
|
28771
|
+
var _a;
|
|
28598
28772
|
switch (block.blockType) {
|
|
28599
28773
|
case 'BlockGroup':
|
|
28600
28774
|
return setSelectionToBlockGroup(block, isInSelection, start, end);
|
|
@@ -28615,16 +28789,31 @@ function setSelectionToBlock(block, isInSelection, start, end) {
|
|
|
28615
28789
|
return isInSelection;
|
|
28616
28790
|
});
|
|
28617
28791
|
case 'Paragraph':
|
|
28618
|
-
var
|
|
28792
|
+
var state_1 = {
|
|
28793
|
+
segmentsToDelete: [],
|
|
28794
|
+
boundaryMarkers: [],
|
|
28795
|
+
hasSelectedNonMarker: false,
|
|
28796
|
+
};
|
|
28619
28797
|
block.segments.forEach(function (segment, i) {
|
|
28620
28798
|
isInSelection = handleSelection(isInSelection, segment, start, end, function (isInSelection) {
|
|
28621
|
-
return setSelectionToSegment(block, segment, isInSelection,
|
|
28799
|
+
return setSelectionToSegment(block, segment, isInSelection, state_1, start, end, i);
|
|
28622
28800
|
});
|
|
28623
28801
|
});
|
|
28624
|
-
if (
|
|
28802
|
+
if (state_1.hasSelectedNonMarker) {
|
|
28803
|
+
// This paragraph contains a real (non-marker) selected segment, so any leading/trailing
|
|
28804
|
+
// selection marker of the range is redundant within this paragraph and can be removed.
|
|
28805
|
+
// We only do this within the same paragraph: a boundary marker at a paragraph edge must be
|
|
28806
|
+
// kept to distinguish "selection starts at the beginning of this line" from "selection
|
|
28807
|
+
// starts at the end of the previous line".
|
|
28808
|
+
(_a = state_1.segmentsToDelete).push.apply(_a, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(state_1.boundaryMarkers), false));
|
|
28809
|
+
}
|
|
28810
|
+
if (state_1.segmentsToDelete.length > 0) {
|
|
28625
28811
|
var mutablePara = (0, mutate_1.mutateBlock)(block);
|
|
28626
28812
|
var index = void 0;
|
|
28627
|
-
|
|
28813
|
+
// Sort ascending so the pop()-based splice below always removes the highest index first,
|
|
28814
|
+
// keeping the remaining indices valid (boundary markers may sit before queued deletions).
|
|
28815
|
+
state_1.segmentsToDelete.sort(function (a, b) { return a - b; });
|
|
28816
|
+
while ((index = state_1.segmentsToDelete.pop()) !== undefined) {
|
|
28628
28817
|
if (index >= 0) {
|
|
28629
28818
|
mutablePara.segments.splice(index, 1);
|
|
28630
28819
|
}
|
|
@@ -28673,14 +28862,23 @@ function findCell(table, cell) {
|
|
|
28673
28862
|
: -1;
|
|
28674
28863
|
return { row: row, col: col };
|
|
28675
28864
|
}
|
|
28676
|
-
function setSelectionToSegment(paragraph, segment, isInSelection,
|
|
28865
|
+
function setSelectionToSegment(paragraph, segment, isInSelection, state, start, end, i) {
|
|
28866
|
+
if (segment.segmentType != 'SelectionMarker' && isInSelection) {
|
|
28867
|
+
state.hasSelectedNonMarker = true;
|
|
28868
|
+
}
|
|
28677
28869
|
switch (segment.segmentType) {
|
|
28678
28870
|
case 'SelectionMarker':
|
|
28679
28871
|
if (!isInSelection || (segment != start && segment != end)) {
|
|
28680
28872
|
// Delete the selection marker when
|
|
28681
28873
|
// 1. It is not in selection any more. Or
|
|
28682
28874
|
// 2. It is in middle of selection, so no need to have it
|
|
28683
|
-
segmentsToDelete.push(i);
|
|
28875
|
+
state.segmentsToDelete.push(i);
|
|
28876
|
+
}
|
|
28877
|
+
else {
|
|
28878
|
+
// It is a leading/trailing selection marker of a range selection. Keep it for now, but
|
|
28879
|
+
// remember it so it can be removed later if this same paragraph also contains a real
|
|
28880
|
+
// (non-marker) selected segment, in which case the marker is redundant.
|
|
28881
|
+
state.boundaryMarkers.push(i);
|
|
28684
28882
|
}
|
|
28685
28883
|
return isInSelection;
|
|
28686
28884
|
case 'General':
|
|
@@ -29121,7 +29319,7 @@ var handleBlockGroupChildren = function (doc, parent, group, context) {
|
|
|
29121
29319
|
(_a = context.domIndexer) === null || _a === void 0 ? void 0 : _a.onBlockEntity(childBlock, group);
|
|
29122
29320
|
}
|
|
29123
29321
|
});
|
|
29124
|
-
cleanUpNodeStack(listFormat.nodeStack, context);
|
|
29322
|
+
cleanUpNodeStack(listFormat.nodeStack, context, parent);
|
|
29125
29323
|
// Remove all rest node if any since they don't appear in content model
|
|
29126
29324
|
(0, cleanUpRestNodes_1.cleanUpRestNodes)(refNode, context.rewriteFromModel);
|
|
29127
29325
|
}
|
|
@@ -29130,7 +29328,7 @@ var handleBlockGroupChildren = function (doc, parent, group, context) {
|
|
|
29130
29328
|
}
|
|
29131
29329
|
};
|
|
29132
29330
|
exports.handleBlockGroupChildren = handleBlockGroupChildren;
|
|
29133
|
-
function cleanUpNodeStack(nodeStack, context) {
|
|
29331
|
+
function cleanUpNodeStack(nodeStack, context, leavingParent) {
|
|
29134
29332
|
var _a, _b;
|
|
29135
29333
|
if (nodeStack.length > 0) {
|
|
29136
29334
|
// Clear list stack, only run to nodeStack[1] because nodeStack[0] is the parent node
|
|
@@ -29138,6 +29336,13 @@ function cleanUpNodeStack(nodeStack, context) {
|
|
|
29138
29336
|
var node = (_b = (_a = nodeStack.pop()) === null || _a === void 0 ? void 0 : _a.refNode) !== null && _b !== void 0 ? _b : null;
|
|
29139
29337
|
(0, cleanUpRestNodes_1.cleanUpRestNodes)(node, context.rewriteFromModel);
|
|
29140
29338
|
}
|
|
29339
|
+
if (leavingParent && nodeStack[0].node == leavingParent) {
|
|
29340
|
+
// When leaving a parent node that is the same with the root of node stack
|
|
29341
|
+
// It means the whole list node stack is being invalidated, so we clear it
|
|
29342
|
+
while (nodeStack.length > 0) {
|
|
29343
|
+
nodeStack.pop();
|
|
29344
|
+
}
|
|
29345
|
+
}
|
|
29141
29346
|
}
|
|
29142
29347
|
}
|
|
29143
29348
|
|
|
@@ -29332,14 +29537,16 @@ var handleFormatContainer = function (doc, parent, container, context, refNode)
|
|
|
29332
29537
|
(0, applyFormat_1.applyFormat)(containerNode_1, context.formatAppliers.segmentOnBlock, container.format, context);
|
|
29333
29538
|
(0, applyFormat_1.applyFormat)(containerNode_1, context.formatAppliers.container, container.format, context);
|
|
29334
29539
|
});
|
|
29335
|
-
|
|
29336
|
-
(
|
|
29540
|
+
(0, stackFormat_1.stackFormat)(context, container.format.direction ? { direction: container.format.direction } : null, function () {
|
|
29541
|
+
if (container.tagName == 'pre') {
|
|
29542
|
+
(0, stackFormat_1.stackFormat)(context, PreChildFormat, function () {
|
|
29543
|
+
context.modelHandlers.blockGroupChildren(doc, containerNode_1, container, context);
|
|
29544
|
+
});
|
|
29545
|
+
}
|
|
29546
|
+
else {
|
|
29337
29547
|
context.modelHandlers.blockGroupChildren(doc, containerNode_1, container, context);
|
|
29338
|
-
}
|
|
29339
|
-
}
|
|
29340
|
-
else {
|
|
29341
|
-
context.modelHandlers.blockGroupChildren(doc, containerNode_1, container, context);
|
|
29342
|
-
}
|
|
29548
|
+
}
|
|
29549
|
+
});
|
|
29343
29550
|
element = containerNode_1;
|
|
29344
29551
|
}
|
|
29345
29552
|
if (element) {
|
|
@@ -29629,7 +29836,9 @@ var handleListItem = function (doc, parent, listItem, context, refNode) {
|
|
|
29629
29836
|
// Need to apply listItemElement formats after applying metadata since the list numbers value relies on the result of metadata handling
|
|
29630
29837
|
(0, applyFormat_1.applyFormat)(li, context.formatAppliers.listItemElement, listItem.format, context);
|
|
29631
29838
|
(0, stackFormat_1.stackFormat)(context, listItem.formatHolder.format, function () {
|
|
29632
|
-
|
|
29839
|
+
(0, stackFormat_1.stackFormat)(context, listItem.format.direction ? { direction: listItem.format.direction } : null, function () {
|
|
29840
|
+
context.modelHandlers.blockGroupChildren(doc, li, listItem, context);
|
|
29841
|
+
});
|
|
29633
29842
|
});
|
|
29634
29843
|
}
|
|
29635
29844
|
else {
|
|
@@ -30001,7 +30210,9 @@ var handleTable = function (doc, parent, table, context, refNode) {
|
|
|
30001
30210
|
(0, applyFormat_1.applyFormat)(td_1, context.formatAppliers.tableCellBorder, cell.format, context);
|
|
30002
30211
|
(0, applyFormat_1.applyFormat)(td_1, context.formatAppliers.dataset, cell.dataset, context);
|
|
30003
30212
|
}
|
|
30004
|
-
|
|
30213
|
+
(0, stackFormat_1.stackFormat)(context, cell.format.direction ? { direction: cell.format.direction } : null, function () {
|
|
30214
|
+
context.modelHandlers.blockGroupChildren(doc, td_1, cell, context);
|
|
30215
|
+
});
|
|
30005
30216
|
});
|
|
30006
30217
|
(_f = context.onNodeCreated) === null || _f === void 0 ? void 0 : _f.call(context, cell, td_1);
|
|
30007
30218
|
}
|
|
@@ -30520,40 +30731,17 @@ exports.MarkdownHeadings = {
|
|
|
30520
30731
|
"use strict";
|
|
30521
30732
|
|
|
30522
30733
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
30523
|
-
exports.convertContentModelToMarkdown = exports.convertMarkdownToContentModel = void 0;
|
|
30734
|
+
exports.MarkdownPastePlugin = exports.isPastedContentMarkdown = exports.isContentMarkdown = exports.convertContentModelToMarkdown = exports.convertMarkdownToContentModel = void 0;
|
|
30524
30735
|
var convertMarkdownToContentModel_1 = __webpack_require__(/*! ./markdownToModel/convertMarkdownToContentModel */ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/convertMarkdownToContentModel.ts");
|
|
30525
30736
|
Object.defineProperty(exports, "convertMarkdownToContentModel", ({ enumerable: true, get: function () { return convertMarkdownToContentModel_1.convertMarkdownToContentModel; } }));
|
|
30526
30737
|
var convertContentModelToMarkdown_1 = __webpack_require__(/*! ./modelToMarkdown/convertContentModelToMarkdown */ "./packages/roosterjs-content-model-markdown/lib/modelToMarkdown/convertContentModelToMarkdown.ts");
|
|
30527
30738
|
Object.defineProperty(exports, "convertContentModelToMarkdown", ({ enumerable: true, get: function () { return convertContentModelToMarkdown_1.convertContentModelToMarkdown; } }));
|
|
30528
|
-
|
|
30529
|
-
|
|
30530
|
-
|
|
30531
|
-
|
|
30532
|
-
|
|
30533
|
-
|
|
30534
|
-
!*** ./packages/roosterjs-content-model-markdown/lib/markdownToModel/appliers/applyLink.ts ***!
|
|
30535
|
-
\*********************************************************************************************/
|
|
30536
|
-
(__unused_webpack_module, exports) {
|
|
30537
|
-
|
|
30538
|
-
"use strict";
|
|
30539
|
-
|
|
30540
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
30541
|
-
exports.applyLink = void 0;
|
|
30542
|
-
/**
|
|
30543
|
-
* @internal
|
|
30544
|
-
*/
|
|
30545
|
-
function applyLink(textSegment, text, url) {
|
|
30546
|
-
textSegment.text = text;
|
|
30547
|
-
textSegment.link = {
|
|
30548
|
-
dataset: {},
|
|
30549
|
-
format: {
|
|
30550
|
-
href: url,
|
|
30551
|
-
underline: true,
|
|
30552
|
-
},
|
|
30553
|
-
};
|
|
30554
|
-
return textSegment;
|
|
30555
|
-
}
|
|
30556
|
-
exports.applyLink = applyLink;
|
|
30739
|
+
var isContentMarkdown_1 = __webpack_require__(/*! ./publicApi/isContentMarkdown */ "./packages/roosterjs-content-model-markdown/lib/publicApi/isContentMarkdown.ts");
|
|
30740
|
+
Object.defineProperty(exports, "isContentMarkdown", ({ enumerable: true, get: function () { return isContentMarkdown_1.isContentMarkdown; } }));
|
|
30741
|
+
var isPastedContentMarkdown_1 = __webpack_require__(/*! ./publicApi/isPastedContentMarkdown */ "./packages/roosterjs-content-model-markdown/lib/publicApi/isPastedContentMarkdown.ts");
|
|
30742
|
+
Object.defineProperty(exports, "isPastedContentMarkdown", ({ enumerable: true, get: function () { return isPastedContentMarkdown_1.isPastedContentMarkdown; } }));
|
|
30743
|
+
var MarkdownPastePlugin_1 = __webpack_require__(/*! ./plugins/MarkdownPastePlugin */ "./packages/roosterjs-content-model-markdown/lib/plugins/MarkdownPastePlugin.ts");
|
|
30744
|
+
Object.defineProperty(exports, "MarkdownPastePlugin", ({ enumerable: true, get: function () { return MarkdownPastePlugin_1.MarkdownPastePlugin; } }));
|
|
30557
30745
|
|
|
30558
30746
|
|
|
30559
30747
|
/***/ },
|
|
@@ -30570,46 +30758,39 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
|
30570
30758
|
exports.applySegmentFormatting = void 0;
|
|
30571
30759
|
var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
|
|
30572
30760
|
var adjustHeading_1 = __webpack_require__(/*! ../utils/adjustHeading */ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/utils/adjustHeading.ts");
|
|
30573
|
-
var applyLink_1 = __webpack_require__(/*! ./applyLink */ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/appliers/applyLink.ts");
|
|
30574
|
-
var applyTextFormatting_1 = __webpack_require__(/*! ./applyTextFormatting */ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/appliers/applyTextFormatting.ts");
|
|
30575
30761
|
var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
|
|
30576
|
-
var
|
|
30577
|
-
var splitParagraphSegments_1 = __webpack_require__(/*! ../utils/splitParagraphSegments */ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/utils/splitParagraphSegments.ts");
|
|
30762
|
+
var parseInlineSegments_1 = __webpack_require__(/*! ../utils/parseInlineSegments */ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/utils/parseInlineSegments.ts");
|
|
30578
30763
|
/**
|
|
30579
30764
|
* @internal
|
|
30580
30765
|
*/
|
|
30581
30766
|
function applySegmentFormatting(text, paragraph, decorator) {
|
|
30582
|
-
var e_1, _a
|
|
30767
|
+
var e_1, _a;
|
|
30583
30768
|
if (text.length === 0) {
|
|
30584
30769
|
var br = (0, roosterjs_content_model_dom_1.createBr)();
|
|
30585
30770
|
paragraph.segments.push(br);
|
|
30586
30771
|
}
|
|
30587
30772
|
else {
|
|
30588
|
-
var
|
|
30773
|
+
var segments = [];
|
|
30774
|
+
(0, parseInlineSegments_1.parseInlineSegments)(text, segments);
|
|
30775
|
+
// Apply heading adjustment to the first text-bearing segment, if any.
|
|
30776
|
+
var headingAdjusted = false;
|
|
30589
30777
|
try {
|
|
30590
|
-
for (var
|
|
30591
|
-
var segment =
|
|
30592
|
-
|
|
30593
|
-
|
|
30594
|
-
|
|
30595
|
-
|
|
30596
|
-
|
|
30597
|
-
else {
|
|
30598
|
-
if (segment.type === 'link') {
|
|
30599
|
-
(0, applyLink_1.applyLink)(formattedSegment, segment.text, segment.url);
|
|
30600
|
-
}
|
|
30601
|
-
var segmentWithAdjustedHeading = (0, adjustHeading_1.adjustHeading)(formattedSegment, decorator);
|
|
30602
|
-
if (segmentWithAdjustedHeading) {
|
|
30603
|
-
var formattedSegments = (0, applyTextFormatting_1.applyTextFormatting)(formattedSegment);
|
|
30604
|
-
(_b = paragraph.segments).push.apply(_b, (0, tslib_1.__spreadArray)([], (0, tslib_1.__read)(formattedSegments), false));
|
|
30778
|
+
for (var segments_1 = (0, tslib_1.__values)(segments), segments_1_1 = segments_1.next(); !segments_1_1.done; segments_1_1 = segments_1.next()) {
|
|
30779
|
+
var segment = segments_1_1.value;
|
|
30780
|
+
if (!headingAdjusted && segment.segmentType === 'Text') {
|
|
30781
|
+
var adjusted = (0, adjustHeading_1.adjustHeading)(segment, decorator);
|
|
30782
|
+
headingAdjusted = true;
|
|
30783
|
+
if (!adjusted) {
|
|
30784
|
+
continue;
|
|
30605
30785
|
}
|
|
30606
30786
|
}
|
|
30787
|
+
paragraph.segments.push(segment);
|
|
30607
30788
|
}
|
|
30608
30789
|
}
|
|
30609
30790
|
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
30610
30791
|
finally {
|
|
30611
30792
|
try {
|
|
30612
|
-
if (
|
|
30793
|
+
if (segments_1_1 && !segments_1_1.done && (_a = segments_1.return)) _a.call(segments_1);
|
|
30613
30794
|
}
|
|
30614
30795
|
finally { if (e_1) throw e_1.error; }
|
|
30615
30796
|
}
|
|
@@ -30621,199 +30802,57 @@ exports.applySegmentFormatting = applySegmentFormatting;
|
|
|
30621
30802
|
|
|
30622
30803
|
/***/ },
|
|
30623
30804
|
|
|
30624
|
-
/***/ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/
|
|
30625
|
-
|
|
30626
|
-
!*** ./packages/roosterjs-content-model-markdown/lib/markdownToModel/
|
|
30627
|
-
|
|
30805
|
+
/***/ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/convertMarkdownToContentModel.ts"
|
|
30806
|
+
/*!********************************************************************************************************!*\
|
|
30807
|
+
!*** ./packages/roosterjs-content-model-markdown/lib/markdownToModel/convertMarkdownToContentModel.ts ***!
|
|
30808
|
+
\********************************************************************************************************/
|
|
30628
30809
|
(__unused_webpack_module, exports, __webpack_require__) {
|
|
30629
30810
|
|
|
30630
30811
|
"use strict";
|
|
30631
30812
|
|
|
30632
30813
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
30633
|
-
exports.
|
|
30634
|
-
var
|
|
30635
|
-
|
|
30814
|
+
exports.convertMarkdownToContentModel = void 0;
|
|
30815
|
+
var markdownProcessor_1 = __webpack_require__(/*! ./processor/markdownProcessor */ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/processor/markdownProcessor.ts");
|
|
30816
|
+
function convertMarkdownToContentModel(text, splitLinesPatternOrOptions) {
|
|
30817
|
+
var _a;
|
|
30818
|
+
var options = (_a = (typeof splitLinesPatternOrOptions === 'string'
|
|
30819
|
+
? {
|
|
30820
|
+
splitLinesPattern: splitLinesPatternOrOptions,
|
|
30821
|
+
}
|
|
30822
|
+
: splitLinesPatternOrOptions)) !== null && _a !== void 0 ? _a : {};
|
|
30823
|
+
return (0, markdownProcessor_1.markdownProcessor)(text, options);
|
|
30824
|
+
}
|
|
30825
|
+
exports.convertMarkdownToContentModel = convertMarkdownToContentModel;
|
|
30826
|
+
|
|
30827
|
+
|
|
30828
|
+
/***/ },
|
|
30829
|
+
|
|
30830
|
+
/***/ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/creators/createBlockGroupFromMarkdown.ts"
|
|
30831
|
+
/*!****************************************************************************************************************!*\
|
|
30832
|
+
!*** ./packages/roosterjs-content-model-markdown/lib/markdownToModel/creators/createBlockGroupFromMarkdown.ts ***!
|
|
30833
|
+
\****************************************************************************************************************/
|
|
30834
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
30835
|
+
|
|
30836
|
+
"use strict";
|
|
30837
|
+
|
|
30838
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
30839
|
+
exports.createBlockGroupFromMarkdown = void 0;
|
|
30840
|
+
var createBlockQuoteFromMarkdown_1 = __webpack_require__(/*! ./createBlockQuoteFromMarkdown */ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/creators/createBlockQuoteFromMarkdown.ts");
|
|
30841
|
+
var createListFromMarkdown_1 = __webpack_require__(/*! ./createListFromMarkdown */ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/creators/createListFromMarkdown.ts");
|
|
30842
|
+
var MarkdownBlockGroupType = {
|
|
30843
|
+
unordered_list: 'ListItem',
|
|
30844
|
+
ordered_list: 'ListItem',
|
|
30845
|
+
blockquote: 'FormatContainer',
|
|
30846
|
+
};
|
|
30636
30847
|
/**
|
|
30637
30848
|
* @internal
|
|
30638
30849
|
*/
|
|
30639
|
-
function
|
|
30640
|
-
|
|
30641
|
-
|
|
30642
|
-
if (isOnlyFormattingMarkers(text)) {
|
|
30643
|
-
return [textSegment];
|
|
30644
|
-
}
|
|
30645
|
-
var textSegments = [];
|
|
30646
|
-
var currentState = { bold: false, italic: false, strikethrough: false };
|
|
30647
|
-
var currentText = '';
|
|
30648
|
-
var i = 0;
|
|
30649
|
-
while (i < text.length) {
|
|
30650
|
-
var marker = parseMarkerAt(text, i);
|
|
30651
|
-
if (marker) {
|
|
30652
|
-
// Check if this marker should be treated as formatting or as literal text
|
|
30653
|
-
if (shouldToggleFormatting(text, i, marker, currentState)) {
|
|
30654
|
-
// If we have accumulated text, create a segment for it
|
|
30655
|
-
if (currentText.length > 0) {
|
|
30656
|
-
textSegments.push(createFormattedSegment(currentText, textSegment.format, currentState, textSegment.link));
|
|
30657
|
-
currentText = '';
|
|
30658
|
-
}
|
|
30659
|
-
// Toggle the formatting state
|
|
30660
|
-
toggleFormatting(currentState, marker.type);
|
|
30661
|
-
// Skip the marker characters
|
|
30662
|
-
i += marker.length;
|
|
30663
|
-
}
|
|
30664
|
-
else {
|
|
30665
|
-
// Treat as regular text if marker is not valid in this context
|
|
30666
|
-
currentText += text[i];
|
|
30667
|
-
i++;
|
|
30668
|
-
}
|
|
30669
|
-
}
|
|
30670
|
-
else {
|
|
30671
|
-
// Regular character, add to current text
|
|
30672
|
-
currentText += text[i];
|
|
30673
|
-
i++;
|
|
30674
|
-
}
|
|
30675
|
-
}
|
|
30676
|
-
// Add any remaining text as a final segment
|
|
30677
|
-
if (currentText.length > 0) {
|
|
30678
|
-
textSegments.push(createFormattedSegment(currentText, textSegment.format, currentState, textSegment.link));
|
|
30679
|
-
}
|
|
30680
|
-
// If no meaningful formatting was applied, return the original segment
|
|
30681
|
-
if (textSegments.length === 0 ||
|
|
30682
|
-
(textSegments.length === 1 && textSegments[0].text === textSegment.text)) {
|
|
30683
|
-
return [textSegment];
|
|
30684
|
-
}
|
|
30685
|
-
return textSegments;
|
|
30686
|
-
}
|
|
30687
|
-
exports.applyTextFormatting = applyTextFormatting;
|
|
30688
|
-
function isOnlyFormattingMarkers(text) {
|
|
30689
|
-
// Remove all potential formatting markers and see if anything remains
|
|
30690
|
-
var remaining = text;
|
|
30691
|
-
remaining = remaining.replace(/\*\*/g, ''); // Remove **
|
|
30692
|
-
remaining = remaining.replace(/~~/g, ''); // Remove ~~
|
|
30693
|
-
remaining = remaining.replace(/\*/g, ''); // Remove *
|
|
30694
|
-
// If nothing remains after removing all markers, it was only markers
|
|
30695
|
-
return remaining.length === 0;
|
|
30696
|
-
}
|
|
30697
|
-
function parseMarkerAt(text, index) {
|
|
30698
|
-
var remaining = text.substring(index);
|
|
30699
|
-
if (remaining.startsWith('~~')) {
|
|
30700
|
-
return { type: 'strikethrough', length: 2 };
|
|
30701
|
-
}
|
|
30702
|
-
if (remaining.startsWith('**')) {
|
|
30703
|
-
return { type: 'bold', length: 2 };
|
|
30850
|
+
function createBlockGroupFromMarkdown(text, patternName, options, group) {
|
|
30851
|
+
if (MarkdownBlockGroupType[patternName] === 'ListItem') {
|
|
30852
|
+
return (0, createListFromMarkdown_1.createListFromMarkdown)(text, patternName === 'ordered_list' ? 'OL' : 'UL', options);
|
|
30704
30853
|
}
|
|
30705
|
-
|
|
30706
|
-
return
|
|
30707
|
-
}
|
|
30708
|
-
return null;
|
|
30709
|
-
}
|
|
30710
|
-
function shouldToggleFormatting(text, index, marker, currentState) {
|
|
30711
|
-
var nextChar = index + marker.length < text.length ? text.charAt(index + marker.length) : '';
|
|
30712
|
-
var isCurrentlyActive = getCurrentFormatState(currentState, marker.type);
|
|
30713
|
-
if (isCurrentlyActive) {
|
|
30714
|
-
// We're currently in this format, so any marker can close it
|
|
30715
|
-
return true;
|
|
30716
|
-
}
|
|
30717
|
-
else {
|
|
30718
|
-
// We're not in this format, so this marker would open it
|
|
30719
|
-
// Opening markers must be followed by non-whitespace
|
|
30720
|
-
return nextChar.length > 0 && !isWhitespace(nextChar);
|
|
30721
|
-
}
|
|
30722
|
-
}
|
|
30723
|
-
function isWhitespace(char) {
|
|
30724
|
-
return /\s/.test(char);
|
|
30725
|
-
}
|
|
30726
|
-
function toggleFormatting(state, type) {
|
|
30727
|
-
switch (type) {
|
|
30728
|
-
case 'bold':
|
|
30729
|
-
state.bold = !state.bold;
|
|
30730
|
-
break;
|
|
30731
|
-
case 'italic':
|
|
30732
|
-
state.italic = !state.italic;
|
|
30733
|
-
break;
|
|
30734
|
-
case 'strikethrough':
|
|
30735
|
-
state.strikethrough = !state.strikethrough;
|
|
30736
|
-
break;
|
|
30737
|
-
}
|
|
30738
|
-
}
|
|
30739
|
-
function getCurrentFormatState(state, type) {
|
|
30740
|
-
switch (type) {
|
|
30741
|
-
case 'bold':
|
|
30742
|
-
return state.bold;
|
|
30743
|
-
case 'italic':
|
|
30744
|
-
return state.italic;
|
|
30745
|
-
case 'strikethrough':
|
|
30746
|
-
return state.strikethrough;
|
|
30747
|
-
}
|
|
30748
|
-
}
|
|
30749
|
-
function createFormattedSegment(text, baseFormat, state, link) {
|
|
30750
|
-
var format = (0, tslib_1.__assign)({}, baseFormat);
|
|
30751
|
-
if (state.bold) {
|
|
30752
|
-
format.fontWeight = 'bold';
|
|
30753
|
-
}
|
|
30754
|
-
if (state.italic) {
|
|
30755
|
-
format.italic = true;
|
|
30756
|
-
}
|
|
30757
|
-
if (state.strikethrough) {
|
|
30758
|
-
format.strikethrough = true;
|
|
30759
|
-
}
|
|
30760
|
-
return (0, roosterjs_content_model_dom_1.createText)(text, format, link);
|
|
30761
|
-
}
|
|
30762
|
-
|
|
30763
|
-
|
|
30764
|
-
/***/ },
|
|
30765
|
-
|
|
30766
|
-
/***/ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/convertMarkdownToContentModel.ts"
|
|
30767
|
-
/*!********************************************************************************************************!*\
|
|
30768
|
-
!*** ./packages/roosterjs-content-model-markdown/lib/markdownToModel/convertMarkdownToContentModel.ts ***!
|
|
30769
|
-
\********************************************************************************************************/
|
|
30770
|
-
(__unused_webpack_module, exports, __webpack_require__) {
|
|
30771
|
-
|
|
30772
|
-
"use strict";
|
|
30773
|
-
|
|
30774
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
30775
|
-
exports.convertMarkdownToContentModel = void 0;
|
|
30776
|
-
var markdownProcessor_1 = __webpack_require__(/*! ./processor/markdownProcessor */ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/processor/markdownProcessor.ts");
|
|
30777
|
-
function convertMarkdownToContentModel(text, splitLinesPatternOrOptions) {
|
|
30778
|
-
var _a;
|
|
30779
|
-
var options = (_a = (typeof splitLinesPatternOrOptions === 'string'
|
|
30780
|
-
? {
|
|
30781
|
-
splitLinesPattern: splitLinesPatternOrOptions,
|
|
30782
|
-
}
|
|
30783
|
-
: splitLinesPatternOrOptions)) !== null && _a !== void 0 ? _a : {};
|
|
30784
|
-
return (0, markdownProcessor_1.markdownProcessor)(text, options);
|
|
30785
|
-
}
|
|
30786
|
-
exports.convertMarkdownToContentModel = convertMarkdownToContentModel;
|
|
30787
|
-
|
|
30788
|
-
|
|
30789
|
-
/***/ },
|
|
30790
|
-
|
|
30791
|
-
/***/ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/creators/createBlockGroupFromMarkdown.ts"
|
|
30792
|
-
/*!****************************************************************************************************************!*\
|
|
30793
|
-
!*** ./packages/roosterjs-content-model-markdown/lib/markdownToModel/creators/createBlockGroupFromMarkdown.ts ***!
|
|
30794
|
-
\****************************************************************************************************************/
|
|
30795
|
-
(__unused_webpack_module, exports, __webpack_require__) {
|
|
30796
|
-
|
|
30797
|
-
"use strict";
|
|
30798
|
-
|
|
30799
|
-
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
30800
|
-
exports.createBlockGroupFromMarkdown = void 0;
|
|
30801
|
-
var createBlockQuoteFromMarkdown_1 = __webpack_require__(/*! ./createBlockQuoteFromMarkdown */ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/creators/createBlockQuoteFromMarkdown.ts");
|
|
30802
|
-
var createListFromMarkdown_1 = __webpack_require__(/*! ./createListFromMarkdown */ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/creators/createListFromMarkdown.ts");
|
|
30803
|
-
var MarkdownBlockGroupType = {
|
|
30804
|
-
unordered_list: 'ListItem',
|
|
30805
|
-
ordered_list: 'ListItem',
|
|
30806
|
-
blockquote: 'FormatContainer',
|
|
30807
|
-
};
|
|
30808
|
-
/**
|
|
30809
|
-
* @internal
|
|
30810
|
-
*/
|
|
30811
|
-
function createBlockGroupFromMarkdown(text, patternName, options, group) {
|
|
30812
|
-
if (MarkdownBlockGroupType[patternName] === 'ListItem') {
|
|
30813
|
-
return (0, createListFromMarkdown_1.createListFromMarkdown)(text, patternName === 'ordered_list' ? 'OL' : 'UL', options);
|
|
30814
|
-
}
|
|
30815
|
-
else {
|
|
30816
|
-
return (0, createBlockQuoteFromMarkdown_1.createBlockQuoteFromMarkdown)(text, options, group);
|
|
30854
|
+
else {
|
|
30855
|
+
return (0, createBlockQuoteFromMarkdown_1.createBlockQuoteFromMarkdown)(text, options, group);
|
|
30817
30856
|
}
|
|
30818
30857
|
}
|
|
30819
30858
|
exports.createBlockGroupFromMarkdown = createBlockGroupFromMarkdown;
|
|
@@ -31358,29 +31397,154 @@ exports.isMarkdownTable = isMarkdownTable;
|
|
|
31358
31397
|
|
|
31359
31398
|
/***/ },
|
|
31360
31399
|
|
|
31361
|
-
/***/ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/utils/
|
|
31362
|
-
|
|
31363
|
-
!*** ./packages/roosterjs-content-model-markdown/lib/markdownToModel/utils/
|
|
31364
|
-
|
|
31365
|
-
(__unused_webpack_module, exports) {
|
|
31400
|
+
/***/ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/utils/parseInlineSegments.ts"
|
|
31401
|
+
/*!****************************************************************************************************!*\
|
|
31402
|
+
!*** ./packages/roosterjs-content-model-markdown/lib/markdownToModel/utils/parseInlineSegments.ts ***!
|
|
31403
|
+
\****************************************************************************************************/
|
|
31404
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
31366
31405
|
|
|
31367
31406
|
"use strict";
|
|
31368
31407
|
|
|
31369
31408
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
31370
|
-
exports.
|
|
31371
|
-
|
|
31372
|
-
|
|
31373
|
-
//
|
|
31374
|
-
|
|
31375
|
-
//
|
|
31376
|
-
|
|
31377
|
-
|
|
31378
|
-
|
|
31379
|
-
|
|
31409
|
+
exports.parseInlineSegments = void 0;
|
|
31410
|
+
var createImageSegment_1 = __webpack_require__(/*! ../creators/createImageSegment */ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/creators/createImageSegment.ts");
|
|
31411
|
+
var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
|
|
31412
|
+
// Matches a markdown link [text](url) anchored at the start of the input.
|
|
31413
|
+
var linkPattern = /^\[([^\[\]]+)\]\(([^\)]+)\)/;
|
|
31414
|
+
// Matches a markdown image  anchored at the start of the input.
|
|
31415
|
+
var imagePattern = /^!\[([^\[\]]+)\]\(([^\)]+)\)/;
|
|
31416
|
+
/**
|
|
31417
|
+
* @internal
|
|
31418
|
+
* Parse a markdown inline string into Content Model segments. Supports bold/italic/
|
|
31419
|
+
* strikethrough markers, links, and images, and keeps formatting state active across
|
|
31420
|
+
* link boundaries (e.g. **[link](url)**).
|
|
31421
|
+
*/
|
|
31422
|
+
function parseInlineSegments(text, segments, state, link) {
|
|
31423
|
+
if (state === void 0) { state = { bold: false, italic: false, strikethrough: false }; }
|
|
31424
|
+
var buffer = '';
|
|
31425
|
+
var i = 0;
|
|
31426
|
+
var flushBuffer = function () {
|
|
31427
|
+
if (buffer.length > 0) {
|
|
31428
|
+
segments.push(createFormattedSegment(buffer, state, link));
|
|
31429
|
+
buffer = '';
|
|
31430
|
+
}
|
|
31431
|
+
};
|
|
31432
|
+
while (i < text.length) {
|
|
31433
|
+
var remaining = text.substring(i);
|
|
31434
|
+
// Escaped character: a backslash followed by an ASCII punctuation character emits
|
|
31435
|
+
// that character literally (e.g. "\*" -> "*") and is never treated as a marker.
|
|
31436
|
+
if (text[i] === '\\' && i + 1 < text.length && isEscapable(text[i + 1])) {
|
|
31437
|
+
buffer += text[i + 1];
|
|
31438
|
+
i += 2;
|
|
31439
|
+
continue;
|
|
31440
|
+
}
|
|
31441
|
+
// Image: 
|
|
31442
|
+
var imgMatch = imagePattern.exec(remaining);
|
|
31443
|
+
if (imgMatch && isValidUrl(imgMatch[2])) {
|
|
31444
|
+
flushBuffer();
|
|
31445
|
+
segments.push((0, createImageSegment_1.createImageSegment)(imgMatch[1], imgMatch[2]));
|
|
31446
|
+
i += imgMatch[0].length;
|
|
31447
|
+
continue;
|
|
31448
|
+
}
|
|
31449
|
+
// Link: [text](url) — keep outer formatting state active inside the link
|
|
31450
|
+
var linkMatch = linkPattern.exec(remaining);
|
|
31451
|
+
if (linkMatch && isValidUrl(linkMatch[2])) {
|
|
31452
|
+
flushBuffer();
|
|
31453
|
+
var innerLink = {
|
|
31454
|
+
dataset: {},
|
|
31455
|
+
format: { href: linkMatch[2], underline: true },
|
|
31456
|
+
};
|
|
31457
|
+
parseInlineSegments(linkMatch[1], segments, state, innerLink);
|
|
31458
|
+
i += linkMatch[0].length;
|
|
31459
|
+
continue;
|
|
31460
|
+
}
|
|
31461
|
+
// Formatting marker
|
|
31462
|
+
var marker = parseMarkerAt(text, i);
|
|
31463
|
+
if (marker && shouldToggleFormatting(text, i, marker, state)) {
|
|
31464
|
+
flushBuffer();
|
|
31465
|
+
toggleFormatting(state, marker.type);
|
|
31466
|
+
i += marker.length;
|
|
31467
|
+
continue;
|
|
31468
|
+
}
|
|
31469
|
+
buffer += text[i];
|
|
31470
|
+
i++;
|
|
31471
|
+
}
|
|
31472
|
+
flushBuffer();
|
|
31473
|
+
}
|
|
31474
|
+
exports.parseInlineSegments = parseInlineSegments;
|
|
31475
|
+
function parseMarkerAt(text, index) {
|
|
31476
|
+
var remaining = text.substring(index);
|
|
31477
|
+
if (remaining.startsWith('~~')) {
|
|
31478
|
+
return { type: 'strikethrough', length: 2 };
|
|
31479
|
+
}
|
|
31480
|
+
if (remaining.startsWith('**')) {
|
|
31481
|
+
return { type: 'bold', length: 2 };
|
|
31482
|
+
}
|
|
31483
|
+
if (remaining.startsWith('*')) {
|
|
31484
|
+
return { type: 'italic', length: 1 };
|
|
31485
|
+
}
|
|
31486
|
+
return null;
|
|
31487
|
+
}
|
|
31488
|
+
function shouldToggleFormatting(text, index, marker, currentState) {
|
|
31489
|
+
var isCurrentlyActive = getCurrentFormatState(currentState, marker.type);
|
|
31490
|
+
if (isCurrentlyActive) {
|
|
31491
|
+
return true;
|
|
31492
|
+
}
|
|
31493
|
+
// Opening marker must be followed by a non-whitespace character.
|
|
31494
|
+
var nextIndex = index + marker.length;
|
|
31495
|
+
var nextChar = nextIndex < text.length ? text.charAt(nextIndex) : '';
|
|
31496
|
+
if (nextChar.length === 0 || isWhitespace(nextChar)) {
|
|
31497
|
+
return false;
|
|
31498
|
+
}
|
|
31499
|
+
return true;
|
|
31500
|
+
}
|
|
31501
|
+
function isWhitespace(char) {
|
|
31502
|
+
return /\s/.test(char);
|
|
31503
|
+
}
|
|
31504
|
+
function isEscapable(char) {
|
|
31505
|
+
// Per CommonMark, any ASCII punctuation character may be backslash-escaped.
|
|
31506
|
+
return /[!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~]/.test(char);
|
|
31507
|
+
}
|
|
31508
|
+
function toggleFormatting(state, type) {
|
|
31509
|
+
switch (type) {
|
|
31510
|
+
case 'bold':
|
|
31511
|
+
state.bold = !state.bold;
|
|
31512
|
+
break;
|
|
31513
|
+
case 'italic':
|
|
31514
|
+
state.italic = !state.italic;
|
|
31515
|
+
break;
|
|
31516
|
+
case 'strikethrough':
|
|
31517
|
+
state.strikethrough = !state.strikethrough;
|
|
31518
|
+
break;
|
|
31519
|
+
}
|
|
31520
|
+
}
|
|
31521
|
+
function getCurrentFormatState(state, type) {
|
|
31522
|
+
switch (type) {
|
|
31523
|
+
case 'bold':
|
|
31524
|
+
return state.bold;
|
|
31525
|
+
case 'italic':
|
|
31526
|
+
return state.italic;
|
|
31527
|
+
case 'strikethrough':
|
|
31528
|
+
return state.strikethrough;
|
|
31529
|
+
}
|
|
31530
|
+
}
|
|
31531
|
+
function createFormattedSegment(text, state, link) {
|
|
31532
|
+
var format = {};
|
|
31533
|
+
if (state.bold) {
|
|
31534
|
+
format.fontWeight = 'bold';
|
|
31535
|
+
}
|
|
31536
|
+
if (state.italic) {
|
|
31537
|
+
format.italic = true;
|
|
31538
|
+
}
|
|
31539
|
+
if (state.strikethrough) {
|
|
31540
|
+
format.strikethrough = true;
|
|
31541
|
+
}
|
|
31542
|
+
return (0, roosterjs_content_model_dom_1.createText)(text, format, link);
|
|
31543
|
+
}
|
|
31544
|
+
function isValidUrl(url) {
|
|
31380
31545
|
if (!url) {
|
|
31381
31546
|
return false;
|
|
31382
31547
|
}
|
|
31383
|
-
// Accept common non-http schemes and relative paths
|
|
31384
31548
|
if (url.startsWith('data:') ||
|
|
31385
31549
|
url.startsWith('blob:') ||
|
|
31386
31550
|
url.startsWith('/') ||
|
|
@@ -31395,51 +31559,7 @@ var isValidUrl = function (url) {
|
|
|
31395
31559
|
catch (_) {
|
|
31396
31560
|
return false;
|
|
31397
31561
|
}
|
|
31398
|
-
};
|
|
31399
|
-
function pushText(result, text) {
|
|
31400
|
-
var last = result[result.length - 1];
|
|
31401
|
-
if (last && last.type === 'text') {
|
|
31402
|
-
last.text += text;
|
|
31403
|
-
}
|
|
31404
|
-
else {
|
|
31405
|
-
result.push({ type: 'text', text: text, url: '' });
|
|
31406
|
-
}
|
|
31407
31562
|
}
|
|
31408
|
-
/**
|
|
31409
|
-
* @internal
|
|
31410
|
-
*/
|
|
31411
|
-
function splitParagraphSegments(text) {
|
|
31412
|
-
var result = [];
|
|
31413
|
-
var lastIndex = 0;
|
|
31414
|
-
var match = null;
|
|
31415
|
-
while ((match = linkRegex.exec(text)) !== null) {
|
|
31416
|
-
if (match.index > lastIndex) {
|
|
31417
|
-
pushText(result, text.slice(lastIndex, match.index));
|
|
31418
|
-
}
|
|
31419
|
-
if (match[2] && match[3]) {
|
|
31420
|
-
if (isValidUrl(match[3])) {
|
|
31421
|
-
result.push({ type: 'link', text: match[2], url: match[3] });
|
|
31422
|
-
}
|
|
31423
|
-
else {
|
|
31424
|
-
pushText(result, match[0]);
|
|
31425
|
-
}
|
|
31426
|
-
}
|
|
31427
|
-
else if (match[5] && match[6]) {
|
|
31428
|
-
if (isValidUrl(match[6])) {
|
|
31429
|
-
result.push({ type: 'image', text: match[5], url: match[6] });
|
|
31430
|
-
}
|
|
31431
|
-
else {
|
|
31432
|
-
pushText(result, match[0]);
|
|
31433
|
-
}
|
|
31434
|
-
}
|
|
31435
|
-
lastIndex = linkRegex.lastIndex;
|
|
31436
|
-
}
|
|
31437
|
-
if (lastIndex < text.length) {
|
|
31438
|
-
pushText(result, text.slice(lastIndex));
|
|
31439
|
-
}
|
|
31440
|
-
return result;
|
|
31441
|
-
}
|
|
31442
|
-
exports.splitParagraphSegments = splitParagraphSegments;
|
|
31443
31563
|
|
|
31444
31564
|
|
|
31445
31565
|
/***/ },
|
|
@@ -31700,20 +31820,30 @@ function createMarkdownParagraph(paragraph, context) {
|
|
|
31700
31820
|
}
|
|
31701
31821
|
exports.createMarkdownParagraph = createMarkdownParagraph;
|
|
31702
31822
|
function textProcessor(text) {
|
|
31703
|
-
var
|
|
31704
|
-
|
|
31705
|
-
|
|
31706
|
-
|
|
31707
|
-
|
|
31708
|
-
|
|
31823
|
+
var _a = text.format, fontWeight = _a.fontWeight, italic = _a.italic, strikethrough = _a.strikethrough;
|
|
31824
|
+
var hasInlineFormat = fontWeight == 'bold' || italic || strikethrough;
|
|
31825
|
+
if (!hasInlineFormat) {
|
|
31826
|
+
return text.link ? "[" + text.text + "](" + text.link.format.href + ")" : text.text;
|
|
31827
|
+
}
|
|
31828
|
+
// Move leading/trailing whitespace outside the markers so the emitted
|
|
31829
|
+
// markdown is valid (CommonMark requires emphasis markers to hug
|
|
31830
|
+
// non-whitespace), e.g. "world " with <b> => " " + "**world**".
|
|
31831
|
+
var match = /^(\s*)([\s\S]*?)(\s*)$/.exec(text.text);
|
|
31832
|
+
var _b = (0, tslib_1.__read)(match ? match : ['', '', text.text, ''], 4), leading = _b[1], core = _b[2], trailing = _b[3];
|
|
31833
|
+
if (!core) {
|
|
31834
|
+
return text.text;
|
|
31835
|
+
}
|
|
31836
|
+
var inner = text.link ? "[" + core + "](" + text.link.format.href + ")" : core;
|
|
31837
|
+
if (fontWeight == 'bold') {
|
|
31838
|
+
inner = "**" + inner + "**";
|
|
31839
|
+
}
|
|
31840
|
+
if (strikethrough) {
|
|
31841
|
+
inner = "~~" + inner + "~~";
|
|
31709
31842
|
}
|
|
31710
|
-
if (
|
|
31711
|
-
|
|
31712
|
-
}
|
|
31713
|
-
if (text.format.italic) {
|
|
31714
|
-
markdownString = "*" + markdownString + "*";
|
|
31843
|
+
if (italic) {
|
|
31844
|
+
inner = "*" + inner + "*";
|
|
31715
31845
|
}
|
|
31716
|
-
return
|
|
31846
|
+
return "" + leading + inner + trailing;
|
|
31717
31847
|
}
|
|
31718
31848
|
|
|
31719
31849
|
|
|
@@ -31878,6 +32008,252 @@ function modelProcessor(model, newLine) {
|
|
|
31878
32008
|
exports.modelProcessor = modelProcessor;
|
|
31879
32009
|
|
|
31880
32010
|
|
|
32011
|
+
/***/ },
|
|
32012
|
+
|
|
32013
|
+
/***/ "./packages/roosterjs-content-model-markdown/lib/plugins/MarkdownPastePlugin.ts"
|
|
32014
|
+
/*!**************************************************************************************!*\
|
|
32015
|
+
!*** ./packages/roosterjs-content-model-markdown/lib/plugins/MarkdownPastePlugin.ts ***!
|
|
32016
|
+
\**************************************************************************************/
|
|
32017
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
32018
|
+
|
|
32019
|
+
"use strict";
|
|
32020
|
+
|
|
32021
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
32022
|
+
exports.MarkdownPastePlugin = void 0;
|
|
32023
|
+
var roosterjs_content_model_dom_1 = __webpack_require__(/*! roosterjs-content-model-dom */ "./packages/roosterjs-content-model-dom/lib/index.ts");
|
|
32024
|
+
var convertMarkdownToContentModel_1 = __webpack_require__(/*! ../markdownToModel/convertMarkdownToContentModel */ "./packages/roosterjs-content-model-markdown/lib/markdownToModel/convertMarkdownToContentModel.ts");
|
|
32025
|
+
var isPastedContentMarkdown_1 = __webpack_require__(/*! ../publicApi/isPastedContentMarkdown */ "./packages/roosterjs-content-model-markdown/lib/publicApi/isPastedContentMarkdown.ts");
|
|
32026
|
+
var DefaultOptions = {
|
|
32027
|
+
autoConversion: false,
|
|
32028
|
+
};
|
|
32029
|
+
/**
|
|
32030
|
+
* Markdown paste plugin. Handles the BeforePaste event and, when the pasted content
|
|
32031
|
+
* can be interpreted as markdown, converts the plain text into a Content Model and
|
|
32032
|
+
* pastes it as rich markdown content instead of the original clipboard HTML.
|
|
32033
|
+
*/
|
|
32034
|
+
var MarkdownPastePlugin = /** @class */ (function () {
|
|
32035
|
+
/**
|
|
32036
|
+
* Construct a new instance of MarkdownPastePlugin
|
|
32037
|
+
* @param options Options to control the markdown paste behavior
|
|
32038
|
+
*/
|
|
32039
|
+
function MarkdownPastePlugin(options) {
|
|
32040
|
+
this.editor = null;
|
|
32041
|
+
this.options = options !== null && options !== void 0 ? options : DefaultOptions;
|
|
32042
|
+
}
|
|
32043
|
+
/**
|
|
32044
|
+
* Get name of this plugin
|
|
32045
|
+
*/
|
|
32046
|
+
MarkdownPastePlugin.prototype.getName = function () {
|
|
32047
|
+
return 'MarkdownPaste';
|
|
32048
|
+
};
|
|
32049
|
+
/**
|
|
32050
|
+
* The first method that editor will call to a plugin when editor is initializing.
|
|
32051
|
+
* It will pass in the editor instance, plugin should take this chance to save the
|
|
32052
|
+
* editor reference so that it can call to any editor method or format API later.
|
|
32053
|
+
* @param editor The editor object
|
|
32054
|
+
*/
|
|
32055
|
+
MarkdownPastePlugin.prototype.initialize = function (editor) {
|
|
32056
|
+
this.editor = editor;
|
|
32057
|
+
};
|
|
32058
|
+
/**
|
|
32059
|
+
* The last method that editor will call to a plugin before it is disposed.
|
|
32060
|
+
* Plugin can take this chance to clear the reference to editor. After this method is
|
|
32061
|
+
* called, plugin should not call to any editor method since it will result in error.
|
|
32062
|
+
*/
|
|
32063
|
+
MarkdownPastePlugin.prototype.dispose = function () {
|
|
32064
|
+
this.editor = null;
|
|
32065
|
+
};
|
|
32066
|
+
/**
|
|
32067
|
+
* Core method for a plugin. Once an event happens in editor, editor will call this
|
|
32068
|
+
* method of each plugin to handle the event as long as the event is not handled
|
|
32069
|
+
* exclusively by another plugin.
|
|
32070
|
+
* @param event The event to handle:
|
|
32071
|
+
*/
|
|
32072
|
+
MarkdownPastePlugin.prototype.onPluginEvent = function (event) {
|
|
32073
|
+
if (!this.editor || event.eventType != 'beforePaste') {
|
|
32074
|
+
return;
|
|
32075
|
+
}
|
|
32076
|
+
var shouldConvert = event.pasteType === 'asMarkdown' || this.options.autoConversion;
|
|
32077
|
+
if (shouldConvert && (0, isPastedContentMarkdown_1.isPastedContentMarkdown)(this.editor, event.clipboardData)) {
|
|
32078
|
+
convertPastedTextToMarkdown(this.editor, event.fragment, event.clipboardData.text);
|
|
32079
|
+
}
|
|
32080
|
+
};
|
|
32081
|
+
return MarkdownPastePlugin;
|
|
32082
|
+
}());
|
|
32083
|
+
exports.MarkdownPastePlugin = MarkdownPastePlugin;
|
|
32084
|
+
function convertPastedTextToMarkdown(editor, fragment, text) {
|
|
32085
|
+
var model = (0, convertMarkdownToContentModel_1.convertMarkdownToContentModel)(text, {
|
|
32086
|
+
emptyLine: 'merge',
|
|
32087
|
+
});
|
|
32088
|
+
while (fragment.firstChild) {
|
|
32089
|
+
fragment.removeChild(fragment.firstChild);
|
|
32090
|
+
}
|
|
32091
|
+
(0, roosterjs_content_model_dom_1.contentModelToDom)(editor.getDocument(), fragment, model, (0, roosterjs_content_model_dom_1.createModelToDomContext)());
|
|
32092
|
+
}
|
|
32093
|
+
|
|
32094
|
+
|
|
32095
|
+
/***/ },
|
|
32096
|
+
|
|
32097
|
+
/***/ "./packages/roosterjs-content-model-markdown/lib/publicApi/isContentMarkdown.ts"
|
|
32098
|
+
/*!**************************************************************************************!*\
|
|
32099
|
+
!*** ./packages/roosterjs-content-model-markdown/lib/publicApi/isContentMarkdown.ts ***!
|
|
32100
|
+
\**************************************************************************************/
|
|
32101
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
32102
|
+
|
|
32103
|
+
"use strict";
|
|
32104
|
+
|
|
32105
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
32106
|
+
exports.isContentMarkdown = void 0;
|
|
32107
|
+
var tslib_1 = __webpack_require__(/*! tslib */ "./node_modules/tslib/tslib.es6.mjs");
|
|
32108
|
+
// Block-level markdown patterns. A line that matches any of these is considered markdown.
|
|
32109
|
+
var BlockPatterns = [
|
|
32110
|
+
/^#{1,6}\s.+/,
|
|
32111
|
+
/^\s*>\s.+/,
|
|
32112
|
+
/^\s*[\*\-\+]\s.+/,
|
|
32113
|
+
/^\s*\d+\.\s.+/,
|
|
32114
|
+
/^---+$/,
|
|
32115
|
+
/^\s*\|.*\|\s*$/, // table row: "| a | b |"
|
|
32116
|
+
];
|
|
32117
|
+
// Inline markdown patterns. The text contains markdown if any of these match anywhere.
|
|
32118
|
+
var InlinePatterns = [
|
|
32119
|
+
/!\[[^\[\]]+\]\([^\)\s]+\)/,
|
|
32120
|
+
/\[[^\[\]]+\]\([^\)\s]+\)/,
|
|
32121
|
+
/\*\*[^\s*][^*]*\*\*/,
|
|
32122
|
+
/(^|[^*])\*[^\s*][^*]*\*([^*]|$)/,
|
|
32123
|
+
/~~[^\s~][^~]*~~/, // strikethrough: ~~text~~
|
|
32124
|
+
];
|
|
32125
|
+
/**
|
|
32126
|
+
* Detect whether the given plain text contains any markdown markup.
|
|
32127
|
+
* Recognizes block-level patterns (headings, blockquotes, lists, horizontal rules, tables)
|
|
32128
|
+
* and inline patterns (bold, italic, strikethrough, links, images).
|
|
32129
|
+
* @param text The plain text to check.
|
|
32130
|
+
* @returns True if the text contains any markdown markup, false otherwise.
|
|
32131
|
+
*/
|
|
32132
|
+
function isContentMarkdown(text) {
|
|
32133
|
+
var e_1, _a, e_2, _b, e_3, _c;
|
|
32134
|
+
if (!text || !text.trim()) {
|
|
32135
|
+
return false;
|
|
32136
|
+
}
|
|
32137
|
+
var lines = text.split(/\r\n|\r|\n/);
|
|
32138
|
+
try {
|
|
32139
|
+
for (var lines_1 = (0, tslib_1.__values)(lines), lines_1_1 = lines_1.next(); !lines_1_1.done; lines_1_1 = lines_1.next()) {
|
|
32140
|
+
var line = lines_1_1.value;
|
|
32141
|
+
try {
|
|
32142
|
+
for (var BlockPatterns_1 = (e_2 = void 0, (0, tslib_1.__values)(BlockPatterns)), BlockPatterns_1_1 = BlockPatterns_1.next(); !BlockPatterns_1_1.done; BlockPatterns_1_1 = BlockPatterns_1.next()) {
|
|
32143
|
+
var pattern = BlockPatterns_1_1.value;
|
|
32144
|
+
if (pattern.test(line)) {
|
|
32145
|
+
return true;
|
|
32146
|
+
}
|
|
32147
|
+
}
|
|
32148
|
+
}
|
|
32149
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
32150
|
+
finally {
|
|
32151
|
+
try {
|
|
32152
|
+
if (BlockPatterns_1_1 && !BlockPatterns_1_1.done && (_b = BlockPatterns_1.return)) _b.call(BlockPatterns_1);
|
|
32153
|
+
}
|
|
32154
|
+
finally { if (e_2) throw e_2.error; }
|
|
32155
|
+
}
|
|
32156
|
+
}
|
|
32157
|
+
}
|
|
32158
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
32159
|
+
finally {
|
|
32160
|
+
try {
|
|
32161
|
+
if (lines_1_1 && !lines_1_1.done && (_a = lines_1.return)) _a.call(lines_1);
|
|
32162
|
+
}
|
|
32163
|
+
finally { if (e_1) throw e_1.error; }
|
|
32164
|
+
}
|
|
32165
|
+
try {
|
|
32166
|
+
for (var InlinePatterns_1 = (0, tslib_1.__values)(InlinePatterns), InlinePatterns_1_1 = InlinePatterns_1.next(); !InlinePatterns_1_1.done; InlinePatterns_1_1 = InlinePatterns_1.next()) {
|
|
32167
|
+
var pattern = InlinePatterns_1_1.value;
|
|
32168
|
+
if (pattern.test(text)) {
|
|
32169
|
+
return true;
|
|
32170
|
+
}
|
|
32171
|
+
}
|
|
32172
|
+
}
|
|
32173
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
32174
|
+
finally {
|
|
32175
|
+
try {
|
|
32176
|
+
if (InlinePatterns_1_1 && !InlinePatterns_1_1.done && (_c = InlinePatterns_1.return)) _c.call(InlinePatterns_1);
|
|
32177
|
+
}
|
|
32178
|
+
finally { if (e_3) throw e_3.error; }
|
|
32179
|
+
}
|
|
32180
|
+
return false;
|
|
32181
|
+
}
|
|
32182
|
+
exports.isContentMarkdown = isContentMarkdown;
|
|
32183
|
+
|
|
32184
|
+
|
|
32185
|
+
/***/ },
|
|
32186
|
+
|
|
32187
|
+
/***/ "./packages/roosterjs-content-model-markdown/lib/publicApi/isPastedContentMarkdown.ts"
|
|
32188
|
+
/*!********************************************************************************************!*\
|
|
32189
|
+
!*** ./packages/roosterjs-content-model-markdown/lib/publicApi/isPastedContentMarkdown.ts ***!
|
|
32190
|
+
\********************************************************************************************/
|
|
32191
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
32192
|
+
|
|
32193
|
+
"use strict";
|
|
32194
|
+
|
|
32195
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
32196
|
+
exports.isPastedContentMarkdown = void 0;
|
|
32197
|
+
var isContentMarkdown_1 = __webpack_require__(/*! ./isContentMarkdown */ "./packages/roosterjs-content-model-markdown/lib/publicApi/isContentMarkdown.ts");
|
|
32198
|
+
// Tags that are considered "thin wrappers", which only add structure (such as line breaks)
|
|
32199
|
+
// around the plain text without applying any real formatting to its content.
|
|
32200
|
+
var ThinWrapperTags = new Set(['DIV', 'P', 'BR', 'SPAN']);
|
|
32201
|
+
var AllowedAttributes = new Set(['class', 'style']);
|
|
32202
|
+
/**
|
|
32203
|
+
* Detect whether the given clipboard content can be interpreted as markdown.
|
|
32204
|
+
* @param editor The editor instance.
|
|
32205
|
+
* @param clipboardData The clipboard data to check.
|
|
32206
|
+
* @returns True if the content can be interpreted as markdown, false otherwise.
|
|
32207
|
+
*/
|
|
32208
|
+
function isPastedContentMarkdown(editor, clipboardData) {
|
|
32209
|
+
var text = clipboardData.text, rawHtml = clipboardData.rawHtml;
|
|
32210
|
+
if (!text || !text.trim()) {
|
|
32211
|
+
return false;
|
|
32212
|
+
}
|
|
32213
|
+
if ((0, isContentMarkdown_1.isContentMarkdown)(text)) {
|
|
32214
|
+
if (!rawHtml) {
|
|
32215
|
+
return true;
|
|
32216
|
+
}
|
|
32217
|
+
var doc = editor.getDocument();
|
|
32218
|
+
var trustedHTMLHandler = editor.getDOMCreator();
|
|
32219
|
+
var fragment = parseHtmlToFragment(rawHtml, doc, trustedHTMLHandler);
|
|
32220
|
+
return isThinWrapperOfPlainText(fragment, text);
|
|
32221
|
+
}
|
|
32222
|
+
return false;
|
|
32223
|
+
}
|
|
32224
|
+
exports.isPastedContentMarkdown = isPastedContentMarkdown;
|
|
32225
|
+
function isThinWrapperOfPlainText(fragment, text) {
|
|
32226
|
+
var elements = fragment.querySelectorAll('*');
|
|
32227
|
+
for (var i = 0; i < elements.length; i++) {
|
|
32228
|
+
var element = elements[i];
|
|
32229
|
+
if (!ThinWrapperTags.has(element.tagName)) {
|
|
32230
|
+
return false;
|
|
32231
|
+
}
|
|
32232
|
+
for (var j = 0; j < element.attributes.length; j++) {
|
|
32233
|
+
var attr = element.attributes[j];
|
|
32234
|
+
if (!AllowedAttributes.has(attr.name) && !attr.name.startsWith('data-')) {
|
|
32235
|
+
return false;
|
|
32236
|
+
}
|
|
32237
|
+
}
|
|
32238
|
+
}
|
|
32239
|
+
return removeWhitespace(fragment.textContent || '') === removeWhitespace(text);
|
|
32240
|
+
}
|
|
32241
|
+
function removeWhitespace(text) {
|
|
32242
|
+
return text.replace(/\s/g, '');
|
|
32243
|
+
}
|
|
32244
|
+
function parseHtmlToFragment(html, doc, trustedHTMLHandler) {
|
|
32245
|
+
var parsedDoc = trustedHTMLHandler.htmlToDOM(html);
|
|
32246
|
+
var fragment = doc.createDocumentFragment();
|
|
32247
|
+
var body = parsedDoc === null || parsedDoc === void 0 ? void 0 : parsedDoc.body;
|
|
32248
|
+
if (body) {
|
|
32249
|
+
while (body.firstChild) {
|
|
32250
|
+
fragment.appendChild(body.firstChild);
|
|
32251
|
+
}
|
|
32252
|
+
}
|
|
32253
|
+
return fragment;
|
|
32254
|
+
}
|
|
32255
|
+
|
|
32256
|
+
|
|
31881
32257
|
/***/ },
|
|
31882
32258
|
|
|
31883
32259
|
/***/ "./packages/roosterjs-content-model-plugins/lib/announce/AnnouncePlugin.ts"
|