@zzish/math-rich-input 0.1.56 → 0.1.58
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/index.js +1036 -111
- package/dist/math-rich-input.css +1 -1
- package/dist/standalone.js +1 -1
- package/package.json +2 -2
- package/src/AccentBar.jsx +21 -21
- package/src/EquationEditor.jsx +44 -3
- package/src/EquationEditorModal.jsx +88 -0
- package/src/MathRichInput.css +3 -0
- package/src/MathRichInput.jsx +512 -66
- package/src/Toolbar.jsx +29 -15
- package/src/editTransaction.js +173 -0
- package/src/mathRichInputHelper.js +7 -3
- package/src/standalone.js +4 -1
package/dist/index.js
CHANGED
|
@@ -169,6 +169,57 @@ function _arrayLikeToArray(arr, len) {
|
|
|
169
169
|
function _nonIterableSpread() {
|
|
170
170
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
171
171
|
}
|
|
172
|
+
function _createForOfIteratorHelper(o, allowArrayLike) {
|
|
173
|
+
var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
|
|
174
|
+
if (!it) {
|
|
175
|
+
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
|
|
176
|
+
if (it) o = it;
|
|
177
|
+
var i = 0;
|
|
178
|
+
var F = function () {};
|
|
179
|
+
return {
|
|
180
|
+
s: F,
|
|
181
|
+
n: function () {
|
|
182
|
+
if (i >= o.length) return {
|
|
183
|
+
done: true
|
|
184
|
+
};
|
|
185
|
+
return {
|
|
186
|
+
done: false,
|
|
187
|
+
value: o[i++]
|
|
188
|
+
};
|
|
189
|
+
},
|
|
190
|
+
e: function (e) {
|
|
191
|
+
throw e;
|
|
192
|
+
},
|
|
193
|
+
f: F
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
197
|
+
}
|
|
198
|
+
var normalCompletion = true,
|
|
199
|
+
didErr = false,
|
|
200
|
+
err;
|
|
201
|
+
return {
|
|
202
|
+
s: function () {
|
|
203
|
+
it = it.call(o);
|
|
204
|
+
},
|
|
205
|
+
n: function () {
|
|
206
|
+
var step = it.next();
|
|
207
|
+
normalCompletion = step.done;
|
|
208
|
+
return step;
|
|
209
|
+
},
|
|
210
|
+
e: function (e) {
|
|
211
|
+
didErr = true;
|
|
212
|
+
err = e;
|
|
213
|
+
},
|
|
214
|
+
f: function () {
|
|
215
|
+
try {
|
|
216
|
+
if (!normalCompletion && it.return != null) it.return();
|
|
217
|
+
} finally {
|
|
218
|
+
if (didErr) throw err;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
}
|
|
172
223
|
|
|
173
224
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
174
225
|
|
|
@@ -18835,7 +18886,7 @@ var EquationEditor = /*#__PURE__*/function (_React$Component) {
|
|
|
18835
18886
|
_classCallCheck(this, EquationEditor);
|
|
18836
18887
|
_this = _callSuper(this, EquationEditor, [props]);
|
|
18837
18888
|
_defineProperty(_this, "handleInsert", function () {
|
|
18838
|
-
_this.handleInsertCallback(_this.
|
|
18889
|
+
_this.handleInsertCallback(_this.latexForInsert());
|
|
18839
18890
|
});
|
|
18840
18891
|
_defineProperty(_this, "handleCancel", function () {
|
|
18841
18892
|
_this.handleCancelCallback();
|
|
@@ -18848,8 +18899,14 @@ var EquationEditor = /*#__PURE__*/function (_React$Component) {
|
|
|
18848
18899
|
});
|
|
18849
18900
|
_defineProperty(_this, "handleKeyDown", function (e) {
|
|
18850
18901
|
try {
|
|
18902
|
+
if (e.key === "Escape") {
|
|
18903
|
+
e.preventDefault();
|
|
18904
|
+
e.stopPropagation();
|
|
18905
|
+
_this.handleCancelCallback();
|
|
18906
|
+
return;
|
|
18907
|
+
}
|
|
18851
18908
|
if (!_this.props.useExpertMode && e.key === "Enter") {
|
|
18852
|
-
_this.handleInsertCallback(_this.
|
|
18909
|
+
_this.handleInsertCallback(_this.latexForInsert());
|
|
18853
18910
|
e.preventDefault();
|
|
18854
18911
|
}
|
|
18855
18912
|
} catch (error) {
|
|
@@ -19022,12 +19079,35 @@ var EquationEditor = /*#__PURE__*/function (_React$Component) {
|
|
|
19022
19079
|
recentSymbolsCount: 0
|
|
19023
19080
|
};
|
|
19024
19081
|
_this.mathQuill = null;
|
|
19082
|
+
// MathQuill's own spelling of the formula the editor was opened with, read once when it mounts.
|
|
19083
|
+
_this.openedLatexInMathQuill = null;
|
|
19025
19084
|
_this.handleInsertCallback = props.handleInsert;
|
|
19026
19085
|
_this.handleCancelCallback = props.handleCancel;
|
|
19027
19086
|
return _this;
|
|
19028
19087
|
}
|
|
19088
|
+
|
|
19089
|
+
/**
|
|
19090
|
+
* The latex Insert hands back.
|
|
19091
|
+
*
|
|
19092
|
+
* Opening a formula makes MathQuill rewrite it in its own spelling (`\frac12` becomes `\frac{1}{2}`,
|
|
19093
|
+
* `\int` gains empty limits, `\,` is dropped), and that rewrite reaches state through an edit event
|
|
19094
|
+
* although nobody typed. While the content is still exactly that rewrite, or the original, the formula
|
|
19095
|
+
* has not been edited, so the original goes back and the host sees no change it did not make.
|
|
19096
|
+
*/
|
|
19029
19097
|
_inherits(EquationEditor, _React$Component);
|
|
19030
19098
|
return _createClass(EquationEditor, [{
|
|
19099
|
+
key: "latexForInsert",
|
|
19100
|
+
value: function latexForInsert() {
|
|
19101
|
+
var latex = this.state.latex;
|
|
19102
|
+
var opened = this.props.latex || "";
|
|
19103
|
+
if (opened === "") return latex;
|
|
19104
|
+
if (latex === opened) return opened;
|
|
19105
|
+
if (this.openedLatexInMathQuill !== null && latex === this.openedLatexInMathQuill) {
|
|
19106
|
+
return opened;
|
|
19107
|
+
}
|
|
19108
|
+
return latex;
|
|
19109
|
+
}
|
|
19110
|
+
}, {
|
|
19031
19111
|
key: "prettifyLatex",
|
|
19032
19112
|
value: function prettifyLatex(latex) {
|
|
19033
19113
|
// NB: replaceAll not suported on safari
|
|
@@ -19109,6 +19189,12 @@ var EquationEditor = /*#__PURE__*/function (_React$Component) {
|
|
|
19109
19189
|
key: "mathquillDidMount",
|
|
19110
19190
|
value: function mathquillDidMount(mathQuill) {
|
|
19111
19191
|
this.mathQuill = mathQuill;
|
|
19192
|
+
// Only the first mount, and only while the content is still the formula the editor was opened
|
|
19193
|
+
// with: a later mount (after switching modes) may hold the user's own edit, which must never be
|
|
19194
|
+
// mistaken for the untouched formula.
|
|
19195
|
+
if (this.openedLatexInMathQuill === null && this.state.latex === (this.props.latex || "")) {
|
|
19196
|
+
this.openedLatexInMathQuill = mathQuill.latex();
|
|
19197
|
+
}
|
|
19112
19198
|
}
|
|
19113
19199
|
}, {
|
|
19114
19200
|
key: "componentDidMount",
|
|
@@ -19215,8 +19301,11 @@ var EquationEditor = /*#__PURE__*/function (_React$Component) {
|
|
|
19215
19301
|
}, /*#__PURE__*/React__default["default"].createElement("div", {
|
|
19216
19302
|
className: "centerBox"
|
|
19217
19303
|
}, /*#__PURE__*/React__default["default"].createElement(reactMathquill.EditableMathField, {
|
|
19218
|
-
className: "editable"
|
|
19219
|
-
|
|
19304
|
+
className: "editable"
|
|
19305
|
+
// MathQuill rejects TeX's thin-space command and clears the whole formula.
|
|
19306
|
+
// Keep the original latex in state; only adapt spacing for its visual parser.
|
|
19307
|
+
,
|
|
19308
|
+
latex: this.state.latex.replace(/\\,/g, " "),
|
|
19220
19309
|
placeholder: "Type equation ..",
|
|
19221
19310
|
config: {
|
|
19222
19311
|
autoOperatorNames: AUTO_OPERATOR_NAMES
|
|
@@ -19298,6 +19387,9 @@ var EquationEditor = /*#__PURE__*/function (_React$Component) {
|
|
|
19298
19387
|
}(React__default["default"].Component);
|
|
19299
19388
|
|
|
19300
19389
|
var GLOBAL_lastSelectedExpertMode = false;
|
|
19390
|
+
|
|
19391
|
+
// Anything a host may use as a modal dialog.
|
|
19392
|
+
var DIALOG_SELECTOR = '[role="dialog"], [role="alertdialog"], [aria-modal="true"], dialog[open]';
|
|
19301
19393
|
var EquationEditorModal = /*#__PURE__*/function (_React$Component) {
|
|
19302
19394
|
function EquationEditorModal(props) {
|
|
19303
19395
|
var _this;
|
|
@@ -19307,9 +19399,80 @@ var EquationEditorModal = /*#__PURE__*/function (_React$Component) {
|
|
|
19307
19399
|
_this.handleInsertCallback(latex);
|
|
19308
19400
|
});
|
|
19309
19401
|
_defineProperty(_this, "handleClose", function () {
|
|
19402
|
+
var _this$origin;
|
|
19403
|
+
if (_this.closing) return;
|
|
19404
|
+
_this.closing = true;
|
|
19405
|
+
if ((_this$origin = _this.origin) !== null && _this$origin !== void 0 && _this$origin.isConnected) {
|
|
19406
|
+
_this.origin.focus({
|
|
19407
|
+
preventScroll: true
|
|
19408
|
+
});
|
|
19409
|
+
if (_this.originRange && _this.origin.contains(_this.originRange.commonAncestorContainer)) {
|
|
19410
|
+
var selection = window.getSelection();
|
|
19411
|
+
selection.removeAllRanges();
|
|
19412
|
+
selection.addRange(_this.originRange);
|
|
19413
|
+
}
|
|
19414
|
+
}
|
|
19310
19415
|
_this.handleCloseCallback();
|
|
19311
19416
|
});
|
|
19417
|
+
_defineProperty(_this, "handleKeyDown", function (event) {
|
|
19418
|
+
if (event.key !== "Escape") return;
|
|
19419
|
+
event.preventDefault();
|
|
19420
|
+
event.stopPropagation();
|
|
19421
|
+
_this.handleClose();
|
|
19422
|
+
});
|
|
19423
|
+
/**
|
|
19424
|
+
* The dialog's own keyboard boundary.
|
|
19425
|
+
*
|
|
19426
|
+
* The modal is a portal into document.body, so focus can leave it: a Tab from the last control reaches
|
|
19427
|
+
* whatever the host page has behind the overlay, and an Escape pressed out there never comes back here
|
|
19428
|
+
* (the handler above only sees events that bubble through the dialog). The capture listener keeps both
|
|
19429
|
+
* inside the dialog for as long as it is mounted: Tab wraps, Escape closes, and the originating field and
|
|
19430
|
+
* range are restored by handleClose.
|
|
19431
|
+
*/
|
|
19432
|
+
_defineProperty(_this, "handleDocumentKeyDown", function (event) {
|
|
19433
|
+
if (_this.closing || !_this.mounted) return;
|
|
19434
|
+
// A dialog the host opened or revealed over this one owns its own keyboard: Tab stays in it and Escape
|
|
19435
|
+
// closes it, not this editor. The host's modal around the field is beneath this editor and does not count.
|
|
19436
|
+
if (_this.focusIsInLaterDialog()) return;
|
|
19437
|
+
if (event.key === "Escape") {
|
|
19438
|
+
event.preventDefault();
|
|
19439
|
+
event.stopPropagation();
|
|
19440
|
+
_this.handleClose();
|
|
19441
|
+
return;
|
|
19442
|
+
}
|
|
19443
|
+
if (event.key !== "Tab") return;
|
|
19444
|
+
var root = _this.modalDiv;
|
|
19445
|
+
if (!root) return;
|
|
19446
|
+
var focusable = _toConsumableArray(root.querySelectorAll('a[href], button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"]), [contenteditable="true"]')).filter(function (element) {
|
|
19447
|
+
var _element$checkVisibil, _element$checkVisibil2;
|
|
19448
|
+
return (_element$checkVisibil = (_element$checkVisibil2 = element.checkVisibility) === null || _element$checkVisibil2 === void 0 ? void 0 : _element$checkVisibil2.call(element)) !== null && _element$checkVisibil !== void 0 ? _element$checkVisibil : true;
|
|
19449
|
+
});
|
|
19450
|
+
if (focusable.length === 0) return;
|
|
19451
|
+
var first = focusable[0],
|
|
19452
|
+
last = focusable[focusable.length - 1];
|
|
19453
|
+
var active = document.activeElement;
|
|
19454
|
+
var inside = root.contains(active);
|
|
19455
|
+
if (!inside) {
|
|
19456
|
+
event.preventDefault();
|
|
19457
|
+
(event.shiftKey ? last : first).focus({
|
|
19458
|
+
preventScroll: true
|
|
19459
|
+
});
|
|
19460
|
+
return;
|
|
19461
|
+
}
|
|
19462
|
+
if (!event.shiftKey && active === last) {
|
|
19463
|
+
event.preventDefault();
|
|
19464
|
+
first.focus({
|
|
19465
|
+
preventScroll: true
|
|
19466
|
+
});
|
|
19467
|
+
} else if (event.shiftKey && active === first) {
|
|
19468
|
+
event.preventDefault();
|
|
19469
|
+
last.focus({
|
|
19470
|
+
preventScroll: true
|
|
19471
|
+
});
|
|
19472
|
+
}
|
|
19473
|
+
});
|
|
19312
19474
|
_defineProperty(_this, "focusEquationEditor", function () {
|
|
19475
|
+
if (!_this.mounted || _this.closing) return;
|
|
19313
19476
|
console.log("🔍 Focusing equation editor...");
|
|
19314
19477
|
if (_this.equationEditor) {
|
|
19315
19478
|
console.log("🔍 EquationEditor ref found");
|
|
@@ -19364,15 +19527,36 @@ var EquationEditorModal = /*#__PURE__*/function (_React$Component) {
|
|
|
19364
19527
|
}
|
|
19365
19528
|
_inherits(EquationEditorModal, _React$Component);
|
|
19366
19529
|
return _createClass(EquationEditorModal, [{
|
|
19530
|
+
key: "focusIsInLaterDialog",
|
|
19531
|
+
value: function focusIsInLaterDialog() {
|
|
19532
|
+
var active = document.activeElement;
|
|
19533
|
+
if (!active || !active.closest || !this.modalDiv) return false;
|
|
19534
|
+
var dialog = active.closest(DIALOG_SELECTOR);
|
|
19535
|
+
if (!dialog || dialog === this.modalDiv || this.modalDiv.contains(dialog)) return false;
|
|
19536
|
+
// The host's own dialog around the field this editor was opened from is beneath it. Any other dialog
|
|
19537
|
+
// holding focus was opened or revealed over it, including one that was already in the DOM but hidden.
|
|
19538
|
+
return !(this.origin && dialog.contains(this.origin));
|
|
19539
|
+
}
|
|
19540
|
+
}, {
|
|
19367
19541
|
key: "componentDidMount",
|
|
19368
19542
|
value: function componentDidMount() {
|
|
19369
19543
|
var _this2 = this;
|
|
19544
|
+
this.mounted = true;
|
|
19545
|
+
this.origin = document.activeElement;
|
|
19546
|
+
var selection = window.getSelection();
|
|
19547
|
+
this.originRange = selection !== null && selection !== void 0 && selection.rangeCount ? selection.getRangeAt(0).cloneRange() : null;
|
|
19370
19548
|
// Store current scroll position to prevent jumping
|
|
19371
19549
|
this.originalScrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
|
19372
19550
|
|
|
19373
19551
|
// Create portal container if it doesn't exist
|
|
19374
19552
|
this.ensurePortalContainer();
|
|
19375
19553
|
|
|
19554
|
+
// Capture phase, so the dialog owns the keyboard even when focus has escaped it to the host page.
|
|
19555
|
+
this.documentKeyListener = function (event) {
|
|
19556
|
+
return _this2.handleDocumentKeyDown(event);
|
|
19557
|
+
};
|
|
19558
|
+
document.addEventListener("keydown", this.documentKeyListener, true);
|
|
19559
|
+
|
|
19376
19560
|
// Lock body scroll to prevent jumping in transform containers
|
|
19377
19561
|
this.lockBodyScroll();
|
|
19378
19562
|
|
|
@@ -19380,6 +19564,7 @@ var EquationEditorModal = /*#__PURE__*/function (_React$Component) {
|
|
|
19380
19564
|
// Need multiple RAF frames for proper CSS animation timing
|
|
19381
19565
|
requestAnimationFrame(function () {
|
|
19382
19566
|
requestAnimationFrame(function () {
|
|
19567
|
+
if (!_this2.mounted) return;
|
|
19383
19568
|
_this2.setState({
|
|
19384
19569
|
animationReady: true
|
|
19385
19570
|
}, function () {
|
|
@@ -19395,6 +19580,11 @@ var EquationEditorModal = /*#__PURE__*/function (_React$Component) {
|
|
|
19395
19580
|
key: "componentWillUnmount",
|
|
19396
19581
|
value: function componentWillUnmount() {
|
|
19397
19582
|
var _this3 = this;
|
|
19583
|
+
this.mounted = false;
|
|
19584
|
+
if (this.documentKeyListener) {
|
|
19585
|
+
document.removeEventListener("keydown", this.documentKeyListener, true);
|
|
19586
|
+
this.documentKeyListener = null;
|
|
19587
|
+
}
|
|
19398
19588
|
// Hide portal immediately to prevent flash
|
|
19399
19589
|
if (this.portalContainer) {
|
|
19400
19590
|
this.portalContainer.style.visibility = "hidden";
|
|
@@ -19513,6 +19703,10 @@ var EquationEditorModal = /*#__PURE__*/function (_React$Component) {
|
|
|
19513
19703
|
}
|
|
19514
19704
|
}), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
19515
19705
|
className: useClass,
|
|
19706
|
+
role: "dialog",
|
|
19707
|
+
"aria-modal": "true",
|
|
19708
|
+
"aria-label": "Equation Editor",
|
|
19709
|
+
onKeyDown: this.handleKeyDown,
|
|
19516
19710
|
ref: function ref(r) {
|
|
19517
19711
|
return _this5.modalDiv = r;
|
|
19518
19712
|
},
|
|
@@ -19870,7 +20064,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
19870
20064
|
return _this2.handleButtonClick(e, character);
|
|
19871
20065
|
},
|
|
19872
20066
|
onClick: function onClick(e) {
|
|
19873
|
-
|
|
20067
|
+
e.preventDefault();
|
|
20068
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character);
|
|
19874
20069
|
}
|
|
19875
20070
|
}, character);
|
|
19876
20071
|
})), !compactMode && /*#__PURE__*/React__default["default"].createElement("div", null, /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -19916,7 +20111,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
19916
20111
|
return _this2.handleButtonClick(e, character);
|
|
19917
20112
|
},
|
|
19918
20113
|
onClick: function onClick(e) {
|
|
19919
|
-
|
|
20114
|
+
e.preventDefault();
|
|
20115
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character);
|
|
19920
20116
|
}
|
|
19921
20117
|
}, character);
|
|
19922
20118
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -19934,7 +20130,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
19934
20130
|
return _this2.handleButtonClick(e, character, true);
|
|
19935
20131
|
},
|
|
19936
20132
|
onClick: function onClick(e) {
|
|
19937
|
-
|
|
20133
|
+
e.preventDefault();
|
|
20134
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
19938
20135
|
}
|
|
19939
20136
|
}, character);
|
|
19940
20137
|
}))), this.state.selectedTab === "Greek" && /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -19954,7 +20151,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
19954
20151
|
return _this2.handleButtonClick(e, character, true);
|
|
19955
20152
|
},
|
|
19956
20153
|
onClick: function onClick(e) {
|
|
19957
|
-
|
|
20154
|
+
e.preventDefault();
|
|
20155
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
19958
20156
|
}
|
|
19959
20157
|
}, character);
|
|
19960
20158
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -19972,7 +20170,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
19972
20170
|
return _this2.handleButtonClick(e, character, true);
|
|
19973
20171
|
},
|
|
19974
20172
|
onClick: function onClick(e) {
|
|
19975
|
-
|
|
20173
|
+
e.preventDefault();
|
|
20174
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
19976
20175
|
}
|
|
19977
20176
|
}, character);
|
|
19978
20177
|
}))), this.state.selectedTab === "Math" && /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -19992,7 +20191,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
19992
20191
|
return _this2.handleButtonClick(e, character, true);
|
|
19993
20192
|
},
|
|
19994
20193
|
onClick: function onClick(e) {
|
|
19995
|
-
|
|
20194
|
+
e.preventDefault();
|
|
20195
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
19996
20196
|
}
|
|
19997
20197
|
}, character);
|
|
19998
20198
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20010,7 +20210,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20010
20210
|
return _this2.handleButtonClick(e, character, true);
|
|
20011
20211
|
},
|
|
20012
20212
|
onClick: function onClick(e) {
|
|
20013
|
-
|
|
20213
|
+
e.preventDefault();
|
|
20214
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20014
20215
|
}
|
|
20015
20216
|
}, character);
|
|
20016
20217
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20028,7 +20229,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20028
20229
|
return _this2.handleButtonClick(e, character, true);
|
|
20029
20230
|
},
|
|
20030
20231
|
onClick: function onClick(e) {
|
|
20031
|
-
|
|
20232
|
+
e.preventDefault();
|
|
20233
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20032
20234
|
}
|
|
20033
20235
|
}, character);
|
|
20034
20236
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20046,7 +20248,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20046
20248
|
return _this2.handleButtonClick(e, character, true);
|
|
20047
20249
|
},
|
|
20048
20250
|
onClick: function onClick(e) {
|
|
20049
|
-
|
|
20251
|
+
e.preventDefault();
|
|
20252
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20050
20253
|
}
|
|
20051
20254
|
}, character);
|
|
20052
20255
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20064,7 +20267,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20064
20267
|
return _this2.handleButtonClick(e, character, true);
|
|
20065
20268
|
},
|
|
20066
20269
|
onClick: function onClick(e) {
|
|
20067
|
-
|
|
20270
|
+
e.preventDefault();
|
|
20271
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20068
20272
|
}
|
|
20069
20273
|
}, character);
|
|
20070
20274
|
}))), this.state.selectedTab === "Emoticons" && /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20084,7 +20288,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20084
20288
|
return _this2.handleButtonClick(e, character, true);
|
|
20085
20289
|
},
|
|
20086
20290
|
onClick: function onClick(e) {
|
|
20087
|
-
|
|
20291
|
+
e.preventDefault();
|
|
20292
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20088
20293
|
}
|
|
20089
20294
|
}, character);
|
|
20090
20295
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20102,7 +20307,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20102
20307
|
return _this2.handleButtonClick(e, character, true);
|
|
20103
20308
|
},
|
|
20104
20309
|
onClick: function onClick(e) {
|
|
20105
|
-
|
|
20310
|
+
e.preventDefault();
|
|
20311
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20106
20312
|
}
|
|
20107
20313
|
}, character);
|
|
20108
20314
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20120,7 +20326,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20120
20326
|
return _this2.handleButtonClick(e, character, true);
|
|
20121
20327
|
},
|
|
20122
20328
|
onClick: function onClick(e) {
|
|
20123
|
-
|
|
20329
|
+
e.preventDefault();
|
|
20330
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20124
20331
|
}
|
|
20125
20332
|
}, character);
|
|
20126
20333
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20138,7 +20345,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20138
20345
|
return _this2.handleButtonClick(e, character, true);
|
|
20139
20346
|
},
|
|
20140
20347
|
onClick: function onClick(e) {
|
|
20141
|
-
|
|
20348
|
+
e.preventDefault();
|
|
20349
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20142
20350
|
}
|
|
20143
20351
|
}, character);
|
|
20144
20352
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20156,7 +20364,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20156
20364
|
return _this2.handleButtonClick(e, character, true);
|
|
20157
20365
|
},
|
|
20158
20366
|
onClick: function onClick(e) {
|
|
20159
|
-
|
|
20367
|
+
e.preventDefault();
|
|
20368
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20160
20369
|
}
|
|
20161
20370
|
}, character);
|
|
20162
20371
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20174,7 +20383,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20174
20383
|
return _this2.handleButtonClick(e, character, true);
|
|
20175
20384
|
},
|
|
20176
20385
|
onClick: function onClick(e) {
|
|
20177
|
-
|
|
20386
|
+
e.preventDefault();
|
|
20387
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20178
20388
|
}
|
|
20179
20389
|
}, character);
|
|
20180
20390
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20192,7 +20402,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20192
20402
|
return _this2.handleButtonClick(e, character, true);
|
|
20193
20403
|
},
|
|
20194
20404
|
onClick: function onClick(e) {
|
|
20195
|
-
|
|
20405
|
+
e.preventDefault();
|
|
20406
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20196
20407
|
}
|
|
20197
20408
|
}, character);
|
|
20198
20409
|
}))), this.state.selectedTab === "More" && /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20212,7 +20423,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20212
20423
|
return _this2.handleButtonClick(e, character, true);
|
|
20213
20424
|
},
|
|
20214
20425
|
onClick: function onClick(e) {
|
|
20215
|
-
|
|
20426
|
+
e.preventDefault();
|
|
20427
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20216
20428
|
}
|
|
20217
20429
|
}, character);
|
|
20218
20430
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20230,7 +20442,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20230
20442
|
return _this2.handleButtonClick(e, character, true);
|
|
20231
20443
|
},
|
|
20232
20444
|
onClick: function onClick(e) {
|
|
20233
|
-
|
|
20445
|
+
e.preventDefault();
|
|
20446
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20234
20447
|
}
|
|
20235
20448
|
}, character);
|
|
20236
20449
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20248,7 +20461,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20248
20461
|
return _this2.handleButtonClick(e, character, true);
|
|
20249
20462
|
},
|
|
20250
20463
|
onClick: function onClick(e) {
|
|
20251
|
-
|
|
20464
|
+
e.preventDefault();
|
|
20465
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20252
20466
|
}
|
|
20253
20467
|
}, character);
|
|
20254
20468
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20266,7 +20480,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20266
20480
|
return _this2.handleButtonClick(e, character, true);
|
|
20267
20481
|
},
|
|
20268
20482
|
onClick: function onClick(e) {
|
|
20269
|
-
|
|
20483
|
+
e.preventDefault();
|
|
20484
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20270
20485
|
}
|
|
20271
20486
|
}, character);
|
|
20272
20487
|
})))))));
|
|
@@ -20302,8 +20517,10 @@ var Toolbar = /*#__PURE__*/function (_React$Component) {
|
|
|
20302
20517
|
});
|
|
20303
20518
|
});
|
|
20304
20519
|
_defineProperty(_this, "handleButtonClick", function (event, buttonName) {
|
|
20520
|
+
var _this$props$beforeAct, _this$props;
|
|
20305
20521
|
event.preventDefault();
|
|
20306
20522
|
event.stopPropagation();
|
|
20523
|
+
(_this$props$beforeAct = (_this$props = _this.props).beforeAction) === null || _this$props$beforeAct === void 0 || _this$props$beforeAct.call(_this$props);
|
|
20307
20524
|
_this.suppliedClickHandler(event, buttonName);
|
|
20308
20525
|
});
|
|
20309
20526
|
_defineProperty(_this, "handleAccentButtonClick", function (event, oldCharacter, newCharacter) {
|
|
@@ -20402,87 +20619,89 @@ var Toolbar = /*#__PURE__*/function (_React$Component) {
|
|
|
20402
20619
|
style: style,
|
|
20403
20620
|
ref: function ref(r) {
|
|
20404
20621
|
return _this2.toolbar = r;
|
|
20405
|
-
}
|
|
20622
|
+
},
|
|
20623
|
+
onBlur: this.props.onBlur
|
|
20406
20624
|
}, enableFontStyling && /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement("button", {
|
|
20625
|
+
type: "button",
|
|
20407
20626
|
name: "Bold",
|
|
20627
|
+
"aria-label": "Bold",
|
|
20408
20628
|
className: "Toolbar-button TB-narrow" + (this.props.activeButtons.bold ? " TB-selected" : ""),
|
|
20409
20629
|
onClick: function onClick(e) {
|
|
20410
|
-
return
|
|
20630
|
+
return _this2.handleButtonClick(e, "Bold");
|
|
20411
20631
|
},
|
|
20412
20632
|
onMouseDown: function onMouseDown(e) {
|
|
20413
20633
|
return e.preventDefault();
|
|
20414
|
-
},
|
|
20415
|
-
onMouseUp: function onMouseUp(e) {
|
|
20416
|
-
return _this2.handleButtonClick(e, "Bold");
|
|
20417
20634
|
}
|
|
20418
20635
|
}, /*#__PURE__*/React__default["default"].createElement("b", null, "B")), /*#__PURE__*/React__default["default"].createElement("button", {
|
|
20636
|
+
type: "button",
|
|
20419
20637
|
name: "Italic",
|
|
20638
|
+
"aria-label": "Italic",
|
|
20420
20639
|
className: "Toolbar-button TB-narrow" + (this.props.activeButtons.italic ? " TB-selected" : ""),
|
|
20421
20640
|
onClick: function onClick(e) {
|
|
20422
|
-
return
|
|
20641
|
+
return _this2.handleButtonClick(e, "Italic");
|
|
20423
20642
|
},
|
|
20424
20643
|
onMouseDown: function onMouseDown(e) {
|
|
20425
20644
|
return e.preventDefault();
|
|
20426
|
-
},
|
|
20427
|
-
onMouseUp: function onMouseUp(e) {
|
|
20428
|
-
return _this2.handleButtonClick(e, "Italic");
|
|
20429
20645
|
}
|
|
20430
20646
|
}, /*#__PURE__*/React__default["default"].createElement("i", null, "I")), /*#__PURE__*/React__default["default"].createElement("button", {
|
|
20647
|
+
type: "button",
|
|
20431
20648
|
name: "Underline",
|
|
20649
|
+
"aria-label": "Underline",
|
|
20432
20650
|
className: "Toolbar-button TB-narrow" + (this.props.activeButtons.underline ? " TB-selected" : ""),
|
|
20433
20651
|
onClick: function onClick(e) {
|
|
20434
|
-
return
|
|
20652
|
+
return _this2.handleButtonClick(e, "Underline");
|
|
20435
20653
|
},
|
|
20436
20654
|
onMouseDown: function onMouseDown(e) {
|
|
20437
20655
|
return e.preventDefault();
|
|
20438
|
-
},
|
|
20439
|
-
onMouseUp: function onMouseUp(e) {
|
|
20440
|
-
return _this2.handleButtonClick(e, "Underline");
|
|
20441
20656
|
}
|
|
20442
20657
|
}, /*#__PURE__*/React__default["default"].createElement("u", null, "U")), /*#__PURE__*/React__default["default"].createElement("button", {
|
|
20658
|
+
type: "button",
|
|
20443
20659
|
name: "Superscript",
|
|
20660
|
+
"aria-label": "Superscript",
|
|
20444
20661
|
className: "Toolbar-button TB-narrow" + (this.props.activeButtons.superscript ? " TB-selected" : ""),
|
|
20445
20662
|
onClick: function onClick(e) {
|
|
20446
|
-
return
|
|
20663
|
+
return _this2.handleButtonClick(e, "Superscript");
|
|
20447
20664
|
},
|
|
20448
20665
|
onMouseDown: function onMouseDown(e) {
|
|
20449
20666
|
return e.preventDefault();
|
|
20450
|
-
},
|
|
20451
|
-
onMouseUp: function onMouseUp(e) {
|
|
20452
|
-
return _this2.handleButtonClick(e, "Superscript");
|
|
20453
20667
|
}
|
|
20454
20668
|
}, "a", /*#__PURE__*/React__default["default"].createElement("sup", null, "x")), /*#__PURE__*/React__default["default"].createElement("button", {
|
|
20669
|
+
type: "button",
|
|
20455
20670
|
name: "Subscript",
|
|
20671
|
+
"aria-label": "Subscript",
|
|
20456
20672
|
className: "Toolbar-button TB-narrow" + (this.props.activeButtons.subscript ? " TB-selected" : ""),
|
|
20457
20673
|
onClick: function onClick(e) {
|
|
20458
|
-
return
|
|
20674
|
+
return _this2.handleButtonClick(e, "Subscript");
|
|
20459
20675
|
},
|
|
20460
20676
|
onMouseDown: function onMouseDown(e) {
|
|
20461
20677
|
return e.preventDefault();
|
|
20462
|
-
},
|
|
20463
|
-
onMouseUp: function onMouseUp(e) {
|
|
20464
|
-
return _this2.handleButtonClick(e, "Subscript");
|
|
20465
20678
|
}
|
|
20466
20679
|
}, "a", /*#__PURE__*/React__default["default"].createElement("sub", null, "x"))), /*#__PURE__*/React__default["default"].createElement("button", {
|
|
20680
|
+
type: "button",
|
|
20467
20681
|
name: "Accents",
|
|
20682
|
+
"aria-label": "Accents",
|
|
20683
|
+
"aria-expanded": this.state.showAccents,
|
|
20468
20684
|
className: "Toolbar-button TB-narrow" + (this.state.showAccents ? " TB-selected" : ""),
|
|
20469
20685
|
onMouseDown: function onMouseDown(e) {
|
|
20470
20686
|
return e.preventDefault();
|
|
20471
20687
|
},
|
|
20472
20688
|
onClick: function onClick(e) {
|
|
20473
|
-
|
|
20474
|
-
|
|
20475
|
-
|
|
20476
|
-
|
|
20689
|
+
var _this2$props$beforeAc, _this2$props;
|
|
20690
|
+
e.preventDefault();
|
|
20691
|
+
e.stopPropagation();
|
|
20692
|
+
(_this2$props$beforeAc = (_this2$props = _this2.props).beforeAction) === null || _this2$props$beforeAc === void 0 || _this2$props$beforeAc.call(_this2$props);
|
|
20693
|
+
_this2.showOrHideAccentBar(e);
|
|
20477
20694
|
}
|
|
20478
20695
|
}, "\xE1"), enableMath && /*#__PURE__*/React__default["default"].createElement("button", {
|
|
20696
|
+
type: "button",
|
|
20479
20697
|
name: "Equation",
|
|
20698
|
+
"aria-label": "Insert equation",
|
|
20480
20699
|
className: "Toolbar-button TB-wide",
|
|
20481
20700
|
onClick: function onClick(e) {
|
|
20482
|
-
return
|
|
20701
|
+
return _this2.handleButtonClick(e, "Equation");
|
|
20483
20702
|
},
|
|
20484
20703
|
onMouseDown: function onMouseDown(e) {
|
|
20485
|
-
return
|
|
20704
|
+
return e.preventDefault();
|
|
20486
20705
|
}
|
|
20487
20706
|
}, /*#__PURE__*/React__default["default"].createElement("div", {
|
|
20488
20707
|
dangerouslySetInnerHTML: {
|
|
@@ -20774,6 +20993,8 @@ function getMark() {
|
|
|
20774
20993
|
return MARK$1;
|
|
20775
20994
|
}
|
|
20776
20995
|
function isKatexNode(node) {
|
|
20996
|
+
// Callers probe siblings and parents that may not exist (the first node has no previousSibling).
|
|
20997
|
+
if (node === null || node === undefined) return false;
|
|
20777
20998
|
return node.className === "katex" || node.className === "katex-error";
|
|
20778
20999
|
}
|
|
20779
21000
|
function isTextNode(node) {
|
|
@@ -21479,7 +21700,6 @@ function getRangeParams(editableDiv) {
|
|
|
21479
21700
|
}
|
|
21480
21701
|
var selection = window.getSelection();
|
|
21481
21702
|
if (selection.rangeCount === 0) {
|
|
21482
|
-
console.error("Can't get range params, window.getSelection did not return any ranges");
|
|
21483
21703
|
return null;
|
|
21484
21704
|
}
|
|
21485
21705
|
var range = selection.getRangeAt(0);
|
|
@@ -21972,6 +22192,229 @@ function plainTextOffsetToGlobalOffset(editableDiv, plainTextOffset) {
|
|
|
21972
22192
|
*/
|
|
21973
22193
|
var SELECTION_MARK = MARK$1;
|
|
21974
22194
|
|
|
22195
|
+
/**
|
|
22196
|
+
* Capture browser editing intent in the logical text coordinates used by MathRichInput.
|
|
22197
|
+
*
|
|
22198
|
+
* The component deliberately reports a measured replacement range instead of asking a host to diff the
|
|
22199
|
+
* old and new strings. A host can therefore retain two equal names independently and reject a stale
|
|
22200
|
+
* event before it changes protected content.
|
|
22201
|
+
*/
|
|
22202
|
+
|
|
22203
|
+
var ZERO_WIDTH_SPACE = "\u200B";
|
|
22204
|
+
var BLOCK_TAGS = new Set(["p", "div", "section", "article", "blockquote", "pre", "li", "ul", "ol", "h1", "h2", "h3", "h4", "h5", "h6", "table", "thead", "tbody", "tfoot", "tr", "td", "th", "hr"]);
|
|
22205
|
+
var INERT_TAGS = new Set(["script", "style", "template", "head", "title"]);
|
|
22206
|
+
|
|
22207
|
+
/** Return whether a node is the rendered KaTeX island that cannot be edited character by character. */
|
|
22208
|
+
function isMathNode(node) {
|
|
22209
|
+
var _node$classList, _node$classList2;
|
|
22210
|
+
return node && node.nodeType === 1 && (((_node$classList = node.classList) === null || _node$classList === void 0 ? void 0 : _node$classList.contains("katex")) || ((_node$classList2 = node.classList) === null || _node$classList2 === void 0 ? void 0 : _node$classList2.contains("katex-error")));
|
|
22211
|
+
}
|
|
22212
|
+
|
|
22213
|
+
/** Return whether a tag contributes a logical line boundary to the source text. */
|
|
22214
|
+
function isBlock(node) {
|
|
22215
|
+
if (!node || node.nodeType !== 1) return false;
|
|
22216
|
+
return BLOCK_TAGS.has(node.tagName.toLowerCase());
|
|
22217
|
+
}
|
|
22218
|
+
function isInert(node) {
|
|
22219
|
+
if (!node || node.nodeType !== 1) return false;
|
|
22220
|
+
return INERT_TAGS.has(node.tagName.toLowerCase());
|
|
22221
|
+
}
|
|
22222
|
+
function trimZeroWidth(value) {
|
|
22223
|
+
return value.split(ZERO_WIDTH_SPACE).join("");
|
|
22224
|
+
}
|
|
22225
|
+
|
|
22226
|
+
/** Build the text coordinate string without reading attributes or rendered math markup. */
|
|
22227
|
+
function editableText(root) {
|
|
22228
|
+
if (!root) return "";
|
|
22229
|
+
var pieces = [];
|
|
22230
|
+
var pendingBoundary = false;
|
|
22231
|
+
var walk = function walk(node) {
|
|
22232
|
+
if (isInert(node)) return;
|
|
22233
|
+
if (isMathNode(node)) {
|
|
22234
|
+
var _node$querySelector;
|
|
22235
|
+
if (pendingBoundary && pieces.length && pieces[pieces.length - 1] !== "\n") pieces.push("\n");
|
|
22236
|
+
var latex = ((_node$querySelector = node.querySelector) === null || _node$querySelector === void 0 || (_node$querySelector = _node$querySelector.call(node, 'annotation[encoding="application/x-tex"]')) === null || _node$querySelector === void 0 ? void 0 : _node$querySelector.textContent) || "";
|
|
22237
|
+
pieces.push(latex);
|
|
22238
|
+
pendingBoundary = false;
|
|
22239
|
+
return;
|
|
22240
|
+
}
|
|
22241
|
+
if (node.nodeType === 3) {
|
|
22242
|
+
var text = trimZeroWidth(node.nodeValue || "");
|
|
22243
|
+
if (text && pendingBoundary && pieces.length && pieces[pieces.length - 1] !== "\n") pieces.push("\n");
|
|
22244
|
+
if (text) pieces.push(text);
|
|
22245
|
+
if (text) pendingBoundary = false;
|
|
22246
|
+
return;
|
|
22247
|
+
}
|
|
22248
|
+
if (node.nodeType !== 1 && node.nodeType !== 11) return;
|
|
22249
|
+
if (node.nodeType === 1 && node.tagName.toLowerCase() === "br") {
|
|
22250
|
+
pieces.push("\n");
|
|
22251
|
+
pendingBoundary = false;
|
|
22252
|
+
return;
|
|
22253
|
+
}
|
|
22254
|
+
var block = isBlock(node);
|
|
22255
|
+
if (block && pieces.length) pendingBoundary = true;
|
|
22256
|
+
var _iterator = _createForOfIteratorHelper(node.childNodes || []),
|
|
22257
|
+
_step;
|
|
22258
|
+
try {
|
|
22259
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
22260
|
+
var child = _step.value;
|
|
22261
|
+
walk(child);
|
|
22262
|
+
}
|
|
22263
|
+
} catch (err) {
|
|
22264
|
+
_iterator.e(err);
|
|
22265
|
+
} finally {
|
|
22266
|
+
_iterator.f();
|
|
22267
|
+
}
|
|
22268
|
+
if (block) pendingBoundary = true;
|
|
22269
|
+
};
|
|
22270
|
+
var _iterator2 = _createForOfIteratorHelper(root.childNodes || []),
|
|
22271
|
+
_step2;
|
|
22272
|
+
try {
|
|
22273
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
22274
|
+
var child = _step2.value;
|
|
22275
|
+
walk(child);
|
|
22276
|
+
}
|
|
22277
|
+
} catch (err) {
|
|
22278
|
+
_iterator2.e(err);
|
|
22279
|
+
} finally {
|
|
22280
|
+
_iterator2.f();
|
|
22281
|
+
}
|
|
22282
|
+
return pieces.join("");
|
|
22283
|
+
}
|
|
22284
|
+
function textBeforeEndpoint(root, container, offset) {
|
|
22285
|
+
if (!root || !container || !root.contains(container)) return null;
|
|
22286
|
+
var range = document.createRange();
|
|
22287
|
+
range.selectNodeContents(root);
|
|
22288
|
+
try {
|
|
22289
|
+
range.setEnd(container, offset);
|
|
22290
|
+
} catch (_error) {
|
|
22291
|
+
return null;
|
|
22292
|
+
}
|
|
22293
|
+
var clone = document.createElement("span");
|
|
22294
|
+
clone.appendChild(range.cloneContents());
|
|
22295
|
+
return editableText(clone).length;
|
|
22296
|
+
}
|
|
22297
|
+
|
|
22298
|
+
/** Read a collapsed or selected DOM range in logical UTF-16 offsets. */
|
|
22299
|
+
function selectionOffsets(root) {
|
|
22300
|
+
var _window$getSelection, _window;
|
|
22301
|
+
var selection = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : (_window$getSelection = (_window = window).getSelection) === null || _window$getSelection === void 0 ? void 0 : _window$getSelection.call(_window);
|
|
22302
|
+
if (!root || !selection || selection.rangeCount === 0) return null;
|
|
22303
|
+
var range = selection.getRangeAt(0);
|
|
22304
|
+
var from = textBeforeEndpoint(root, range.startContainer, range.startOffset);
|
|
22305
|
+
var to = textBeforeEndpoint(root, range.endContainer, range.endOffset);
|
|
22306
|
+
if (from === null || to === null) return null;
|
|
22307
|
+
return from <= to ? {
|
|
22308
|
+
from: from,
|
|
22309
|
+
to: to
|
|
22310
|
+
} : {
|
|
22311
|
+
from: to,
|
|
22312
|
+
to: from
|
|
22313
|
+
};
|
|
22314
|
+
}
|
|
22315
|
+
function expandSurrogateBoundary(text, from, to) {
|
|
22316
|
+
var before = text.charCodeAt(from - 1);
|
|
22317
|
+
var after = text.charCodeAt(from);
|
|
22318
|
+
if (before >= 0xd800 && before <= 0xdbff && after >= 0xdc00 && after <= 0xdfff) {
|
|
22319
|
+
return {
|
|
22320
|
+
from: from - 1,
|
|
22321
|
+
to: Math.max(to, from + 1)
|
|
22322
|
+
};
|
|
22323
|
+
}
|
|
22324
|
+
var at = text.charCodeAt(to - 1);
|
|
22325
|
+
var next = text.charCodeAt(to);
|
|
22326
|
+
if (at >= 0xd800 && at <= 0xdbff && next >= 0xdc00 && next <= 0xdfff) {
|
|
22327
|
+
return {
|
|
22328
|
+
from: Math.min(from, to - 1),
|
|
22329
|
+
to: to + 1
|
|
22330
|
+
};
|
|
22331
|
+
}
|
|
22332
|
+
return {
|
|
22333
|
+
from: from,
|
|
22334
|
+
to: to
|
|
22335
|
+
};
|
|
22336
|
+
}
|
|
22337
|
+
function textFromTransfer(dataTransfer) {
|
|
22338
|
+
var _dataTransfer$getData, _dataTransfer$getData2;
|
|
22339
|
+
if (!dataTransfer) return "";
|
|
22340
|
+
var plain = ((_dataTransfer$getData = dataTransfer.getData) === null || _dataTransfer$getData === void 0 ? void 0 : _dataTransfer$getData.call(dataTransfer, "text/plain")) || "";
|
|
22341
|
+
if (plain) return plain;
|
|
22342
|
+
var html = ((_dataTransfer$getData2 = dataTransfer.getData) === null || _dataTransfer$getData2 === void 0 ? void 0 : _dataTransfer$getData2.call(dataTransfer, "text/html")) || "";
|
|
22343
|
+
if (!html || typeof document === "undefined") return "";
|
|
22344
|
+
var probe = document.createElement("div");
|
|
22345
|
+
probe.innerHTML = html;
|
|
22346
|
+
return editableText(probe);
|
|
22347
|
+
}
|
|
22348
|
+
|
|
22349
|
+
/**
|
|
22350
|
+
* Convert a browser `beforeinput` event into an explicit replacement.
|
|
22351
|
+
*
|
|
22352
|
+
* A null return means the browser supplied no safe range or the operation is outside the supported text
|
|
22353
|
+
* edits. The caller still emits the intent, without an edit, so a protected host can refuse it loudly.
|
|
22354
|
+
*/
|
|
22355
|
+
function transactionFromBeforeInput(root, event) {
|
|
22356
|
+
var _event$data;
|
|
22357
|
+
var compositionStart = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
22358
|
+
var before = editableText(root);
|
|
22359
|
+
var selection = selectionOffsets(root);
|
|
22360
|
+
if (!selection) return {
|
|
22361
|
+
before: before,
|
|
22362
|
+
intent: intentForInputType(event === null || event === void 0 ? void 0 : event.inputType),
|
|
22363
|
+
edit: null
|
|
22364
|
+
};
|
|
22365
|
+
var inputType = (event === null || event === void 0 ? void 0 : event.inputType) || "insertText";
|
|
22366
|
+
var intent = intentForInputType(inputType);
|
|
22367
|
+
var from = selection.from,
|
|
22368
|
+
to = selection.to;
|
|
22369
|
+
var insert = (_event$data = event === null || event === void 0 ? void 0 : event.data) !== null && _event$data !== void 0 ? _event$data : "";
|
|
22370
|
+
if (inputType === "insertFromPaste" || inputType === "insertFromDrop") {
|
|
22371
|
+
insert = textFromTransfer(event === null || event === void 0 ? void 0 : event.dataTransfer);
|
|
22372
|
+
} else if (inputType === "insertLineBreak" || inputType === "insertParagraph") {
|
|
22373
|
+
insert = "\n";
|
|
22374
|
+
} else if (inputType === "deleteContentBackward" && from === to) {
|
|
22375
|
+
var _expandSurrogateBound = expandSurrogateBoundary(before, Math.max(0, from - 1), from);
|
|
22376
|
+
from = _expandSurrogateBound.from;
|
|
22377
|
+
to = _expandSurrogateBound.to;
|
|
22378
|
+
} else if (inputType === "deleteContentForward" && from === to) {
|
|
22379
|
+
var _expandSurrogateBound2 = expandSurrogateBoundary(before, from, Math.min(before.length, to + 1));
|
|
22380
|
+
from = _expandSurrogateBound2.from;
|
|
22381
|
+
to = _expandSurrogateBound2.to;
|
|
22382
|
+
} else if (inputType.startsWith("delete") && from === to) {
|
|
22383
|
+
return {
|
|
22384
|
+
before: before,
|
|
22385
|
+
intent: intent,
|
|
22386
|
+
edit: null
|
|
22387
|
+
};
|
|
22388
|
+
}
|
|
22389
|
+
var base = compositionStart && intent === "composition" ? compositionStart : {
|
|
22390
|
+
before: before,
|
|
22391
|
+
from: from,
|
|
22392
|
+
to: to
|
|
22393
|
+
};
|
|
22394
|
+
return {
|
|
22395
|
+
before: base.before,
|
|
22396
|
+
intent: intent,
|
|
22397
|
+
edit: {
|
|
22398
|
+
before: base.before,
|
|
22399
|
+
from: base.from,
|
|
22400
|
+
to: base.to,
|
|
22401
|
+
insert: insert
|
|
22402
|
+
}
|
|
22403
|
+
};
|
|
22404
|
+
}
|
|
22405
|
+
|
|
22406
|
+
/** Give hosts a stable vocabulary while preserving the browser's native inputType for diagnostics. */
|
|
22407
|
+
function intentForInputType(inputType) {
|
|
22408
|
+
if (!inputType) return "input";
|
|
22409
|
+
if (inputType.includes("Composition")) return "composition";
|
|
22410
|
+
if (inputType.includes("Paste")) return "paste";
|
|
22411
|
+
if (inputType.includes("Drop")) return "drop";
|
|
22412
|
+
if (inputType.includes("Cut")) return "cut";
|
|
22413
|
+
if (inputType === "historyUndo") return "undo";
|
|
22414
|
+
if (inputType === "historyRedo") return "redo";
|
|
22415
|
+
return "input";
|
|
22416
|
+
}
|
|
22417
|
+
|
|
21975
22418
|
var MIME_TYPE_PLAIN_TEXT = "text/plain";
|
|
21976
22419
|
var MIME_TYPE_HTML = "text/html";
|
|
21977
22420
|
var MIME_TYPE_TEX = "application/x-tex";
|
|
@@ -22178,23 +22621,34 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
22178
22621
|
var options = _this2.props.options || DEFAULT_OPTIONS;
|
|
22179
22622
|
if (isExpertMode === null) isExpertMode = options.isExpertMode;
|
|
22180
22623
|
if (selectedTab === null) selectedTab = options.selectedTab;
|
|
22181
|
-
|
|
22182
|
-
|
|
22183
|
-
_this2.undoHistory.push({
|
|
22624
|
+
var transaction = applyOptions.transaction || null;
|
|
22625
|
+
var historyState = {
|
|
22184
22626
|
value: value,
|
|
22185
22627
|
mimeType: mimeType,
|
|
22186
|
-
rangeParams: rangeParams
|
|
22187
|
-
|
|
22188
|
-
|
|
22628
|
+
rangeParams: rangeParams,
|
|
22629
|
+
transaction: transaction
|
|
22630
|
+
};
|
|
22631
|
+
if (applyOptions.recordHistory !== false) {
|
|
22632
|
+
// Add this to the history. The transaction is retained beside the rendered value so a host can
|
|
22633
|
+
// restore annotation snapshots on undo/redo instead of interpreting an inverse spelling anew.
|
|
22634
|
+
_this2.undoHistory.push(historyState);
|
|
22635
|
+
if (_this2.undoHistory.length > MAX_HISTORY_LENGTH) _this2.undoHistory.shift();
|
|
22636
|
+
}
|
|
22189
22637
|
|
|
22190
22638
|
// Debug what's being passed to parent
|
|
22191
22639
|
// console.log("APPLY CHANGES:", { value, mimeType });
|
|
22192
22640
|
|
|
22193
22641
|
// Call the parent handler to apply the changes
|
|
22194
|
-
_this2.onChangeCallback({
|
|
22642
|
+
_this2.onChangeCallback(_objectSpread2(_objectSpread2(_objectSpread2({
|
|
22195
22643
|
value: value,
|
|
22196
22644
|
mimeType: mimeType
|
|
22197
|
-
}, {
|
|
22645
|
+
}, transaction !== null && transaction !== void 0 && transaction.edit ? {
|
|
22646
|
+
edit: transaction.edit
|
|
22647
|
+
} : {}), transaction !== null && transaction !== void 0 && transaction.intent ? {
|
|
22648
|
+
intent: transaction.intent
|
|
22649
|
+
} : {}), transaction !== null && transaction !== void 0 && transaction.history ? {
|
|
22650
|
+
history: transaction.history
|
|
22651
|
+
} : {}), {
|
|
22198
22652
|
isExpertMode: isExpertMode,
|
|
22199
22653
|
selectedTab: selectedTab
|
|
22200
22654
|
});
|
|
@@ -22219,7 +22673,8 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
22219
22673
|
if (_this2.initialHistoryState == null) _this2.initialHistoryState = {
|
|
22220
22674
|
value: _this2.props.value,
|
|
22221
22675
|
mimeType: _this2.props.mimeType,
|
|
22222
|
-
rangeParams: _this2._getRangeParams()
|
|
22676
|
+
rangeParams: _this2._getRangeParams(),
|
|
22677
|
+
transaction: null
|
|
22223
22678
|
};
|
|
22224
22679
|
});
|
|
22225
22680
|
_defineProperty(_this2, "resetHistoryRedo", function () {
|
|
@@ -22238,22 +22693,59 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
22238
22693
|
return true;
|
|
22239
22694
|
});
|
|
22240
22695
|
_defineProperty(_this2, "undo", function () {
|
|
22241
|
-
var currentState = _this2.undoHistory.
|
|
22242
|
-
|
|
22243
|
-
|
|
22244
|
-
|
|
22245
|
-
|
|
22246
|
-
|
|
22247
|
-
|
|
22248
|
-
|
|
22249
|
-
|
|
22250
|
-
|
|
22696
|
+
var currentState = _this2.undoHistory[_this2.undoHistory.length - 1];
|
|
22697
|
+
if (!currentState) return;
|
|
22698
|
+
_this2.undoHistory.pop();
|
|
22699
|
+
var previousState = _this2.undoHistory[_this2.undoHistory.length - 1] || _this2.initialHistoryState;
|
|
22700
|
+
if (!previousState) return;
|
|
22701
|
+
_this2.redoHistory.push(currentState);
|
|
22702
|
+
var transaction = _this2.historyTransaction(currentState, "undo");
|
|
22703
|
+
_this2.applyChangesToComponent(previousState.value, previousState.mimeType, previousState.rangeParams, null, null, {
|
|
22704
|
+
transaction: transaction,
|
|
22705
|
+
recordHistory: false
|
|
22706
|
+
});
|
|
22251
22707
|
});
|
|
22252
22708
|
_defineProperty(_this2, "redo", function () {
|
|
22253
22709
|
var redoState = _this2.redoHistory.pop();
|
|
22254
|
-
if (redoState !== null
|
|
22255
|
-
_this2.applyChangesToComponent(redoState.value, redoState.mimeType, redoState.rangeParams
|
|
22710
|
+
if (redoState !== null && redoState !== undefined) {
|
|
22711
|
+
_this2.applyChangesToComponent(redoState.value, redoState.mimeType, redoState.rangeParams, null, null, {
|
|
22712
|
+
transaction: _this2.historyTransaction(redoState, "redo"),
|
|
22713
|
+
recordHistory: false
|
|
22714
|
+
});
|
|
22715
|
+
_this2.undoHistory.push(redoState);
|
|
22716
|
+
}
|
|
22717
|
+
});
|
|
22718
|
+
/** Build an explicit forward/inverse transaction for one history entry. */
|
|
22719
|
+
_defineProperty(_this2, "historyTransaction", function (state, direction) {
|
|
22720
|
+
var _original$history;
|
|
22721
|
+
var original = state === null || state === void 0 ? void 0 : state.transaction;
|
|
22722
|
+
if (!(original !== null && original !== void 0 && (_original$history = original.history) !== null && _original$history !== void 0 && _original$history.id) || !original.edit) {
|
|
22723
|
+
return {
|
|
22724
|
+
intent: direction,
|
|
22725
|
+
history: original !== null && original !== void 0 && original.history ? {
|
|
22726
|
+
id: original.history.id,
|
|
22727
|
+
direction: direction
|
|
22728
|
+
} : undefined
|
|
22729
|
+
};
|
|
22256
22730
|
}
|
|
22731
|
+
var edit = original.edit;
|
|
22732
|
+
var after = edit.before.slice(0, edit.from) + edit.insert + edit.before.slice(edit.to);
|
|
22733
|
+
var inverse = _objectSpread2({
|
|
22734
|
+
before: after,
|
|
22735
|
+
from: edit.from,
|
|
22736
|
+
to: edit.from + edit.insert.length,
|
|
22737
|
+
insert: edit.before.slice(edit.from, edit.to)
|
|
22738
|
+
}, edit.boundary ? {
|
|
22739
|
+
boundary: edit.boundary
|
|
22740
|
+
} : {});
|
|
22741
|
+
return {
|
|
22742
|
+
intent: direction,
|
|
22743
|
+
history: {
|
|
22744
|
+
id: original.history.id,
|
|
22745
|
+
direction: direction
|
|
22746
|
+
},
|
|
22747
|
+
edit: direction === "undo" ? inverse : edit
|
|
22748
|
+
};
|
|
22257
22749
|
});
|
|
22258
22750
|
_defineProperty(_this2, "_setRangeParams", function (params) {
|
|
22259
22751
|
try {
|
|
@@ -22295,6 +22787,7 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
22295
22787
|
restore(50);
|
|
22296
22788
|
});
|
|
22297
22789
|
_defineProperty(_this2, "handleKeyDownBackspace", function (e) {
|
|
22790
|
+
var beforeText = editableText(_this2.editableDiv);
|
|
22298
22791
|
var rangeParams = _this2._getRangeParams();
|
|
22299
22792
|
var start_node_index = rangeParams.startNodeIndex;
|
|
22300
22793
|
var end_node_index = rangeParams.endNodeIndex;
|
|
@@ -22331,7 +22824,21 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
22331
22824
|
startGlobalOffset: 0,
|
|
22332
22825
|
endGlobalOffset: 0
|
|
22333
22826
|
};
|
|
22334
|
-
_this2.applyChangesToComponent("", _this2.getMimeType(false, false), _new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab
|
|
22827
|
+
_this2.applyChangesToComponent("", _this2.getMimeType(false, false), _new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab, {
|
|
22828
|
+
transaction: {
|
|
22829
|
+
edit: {
|
|
22830
|
+
before: beforeText,
|
|
22831
|
+
from: 0,
|
|
22832
|
+
to: beforeText.length,
|
|
22833
|
+
insert: ""
|
|
22834
|
+
},
|
|
22835
|
+
intent: "cut",
|
|
22836
|
+
history: {
|
|
22837
|
+
id: "mri-".concat(++_this2.historySequence),
|
|
22838
|
+
direction: "forward"
|
|
22839
|
+
}
|
|
22840
|
+
}
|
|
22841
|
+
});
|
|
22335
22842
|
e.preventDefault();
|
|
22336
22843
|
return;
|
|
22337
22844
|
}
|
|
@@ -23188,6 +23695,11 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23188
23695
|
try {
|
|
23189
23696
|
// console.log("handleInput")
|
|
23190
23697
|
if (_this2.isComposing) return;
|
|
23698
|
+
// execCommand emits a synchronous input event; styleText records the
|
|
23699
|
+
// complete format transaction once after the command returns.
|
|
23700
|
+
if (_this2.formatCommandActive) return;
|
|
23701
|
+
var transaction = _this2.pendingTransaction;
|
|
23702
|
+
_this2.pendingTransaction = null;
|
|
23191
23703
|
debugMathRichInput("handleInput:start", {
|
|
23192
23704
|
inputType: event && event.nativeEvent ? event.nativeEvent.inputType : null,
|
|
23193
23705
|
data: event && event.nativeEvent ? event.nativeEvent.data : null,
|
|
@@ -23224,7 +23736,8 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23224
23736
|
_raw_text = removeEncodingIfPlainText(_raw_text, _mimeType, _this2.enableHtml());
|
|
23225
23737
|
_raw_text = _this2.stripEmptyInlineFormattingTags(_raw_text);
|
|
23226
23738
|
_this2.applyChangesToComponent(_raw_text, _mimeType, defaultParams, _this2.props.useExpertMode, _this2.props.selectedTab, {
|
|
23227
|
-
skipControlledRender: true
|
|
23739
|
+
skipControlledRender: true,
|
|
23740
|
+
transaction: transaction
|
|
23228
23741
|
});
|
|
23229
23742
|
return;
|
|
23230
23743
|
} else if (params.startNodeIndex === null || params.startNodeIndex === undefined) {
|
|
@@ -23259,7 +23772,8 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23259
23772
|
};
|
|
23260
23773
|
_this2.setOldRangeParams(validParams);
|
|
23261
23774
|
_this2.applyChangesToComponent(raw_text, mimeType, validParams, _this2.props.useExpertMode, _this2.props.selectedTab, {
|
|
23262
|
-
skipControlledRender: true
|
|
23775
|
+
skipControlledRender: true,
|
|
23776
|
+
transaction: transaction
|
|
23263
23777
|
});
|
|
23264
23778
|
debugMathRichInput("handleInput:after-apply", {
|
|
23265
23779
|
raw_text: raw_text,
|
|
@@ -23356,6 +23870,7 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23356
23870
|
});
|
|
23357
23871
|
_defineProperty(_this2, "handlePaste", function (event) {
|
|
23358
23872
|
try {
|
|
23873
|
+
_this2.pendingTransaction = null;
|
|
23359
23874
|
var clipboardData = event.clipboardData || window.clipboardData;
|
|
23360
23875
|
if (!clipboardData) {
|
|
23361
23876
|
return;
|
|
@@ -23380,6 +23895,8 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23380
23895
|
console.warn("Could not get range params for paste");
|
|
23381
23896
|
return;
|
|
23382
23897
|
}
|
|
23898
|
+
var beforePaste = editableText(_this2.editableDiv);
|
|
23899
|
+
var pasteSelection = _this2.captureSelectionOffsets();
|
|
23383
23900
|
|
|
23384
23901
|
// Store old range params for cursor positioning (like equation editor)
|
|
23385
23902
|
_this2.setOldRangeParams(rangeParams);
|
|
@@ -23605,7 +24122,34 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23605
24122
|
var cleanedRawText = removeEncodingIfPlainText(newRawText, actualMimeType, _this2.enableHtml());
|
|
23606
24123
|
|
|
23607
24124
|
// Apply the change using the component's standard flow
|
|
23608
|
-
|
|
24125
|
+
var insertionText = function () {
|
|
24126
|
+
if (!/<[^>]+>/.test(finalText)) return finalText;
|
|
24127
|
+
var probe = document.createElement("div");
|
|
24128
|
+
probe.innerHTML = finalText;
|
|
24129
|
+
return editableText(probe).replace(/\ufffc/g, "");
|
|
24130
|
+
}();
|
|
24131
|
+
var transaction = pasteSelection ? {
|
|
24132
|
+
edit: {
|
|
24133
|
+
before: beforePaste,
|
|
24134
|
+
from: pasteSelection.from,
|
|
24135
|
+
to: pasteSelection.to,
|
|
24136
|
+
insert: insertionText
|
|
24137
|
+
},
|
|
24138
|
+
intent: "paste",
|
|
24139
|
+
history: {
|
|
24140
|
+
id: "mri-".concat(++_this2.historySequence),
|
|
24141
|
+
direction: "forward"
|
|
24142
|
+
}
|
|
24143
|
+
} : {
|
|
24144
|
+
intent: "paste",
|
|
24145
|
+
history: {
|
|
24146
|
+
id: "mri-".concat(++_this2.historySequence),
|
|
24147
|
+
direction: "forward"
|
|
24148
|
+
}
|
|
24149
|
+
};
|
|
24150
|
+
_this2.applyChangesToComponent(cleanedRawText, actualMimeType, newRangeParams, _this2.props.useExpertMode, _this2.props.selectedTab, {
|
|
24151
|
+
transaction: transaction
|
|
24152
|
+
});
|
|
23609
24153
|
|
|
23610
24154
|
// A paste cannot rely on being re-rendered. It removed the selected content from the DOM itself,
|
|
23611
24155
|
// and if the host already holds the value being applied — the same words pasted back into the
|
|
@@ -23634,7 +24178,9 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23634
24178
|
var moveCursorOnInsert = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
23635
24179
|
var node = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
23636
24180
|
try {
|
|
24181
|
+
var _node;
|
|
23637
24182
|
var rangeParams = _this2._getRangeParams();
|
|
24183
|
+
var hasNode = node !== null && node !== undefined;
|
|
23638
24184
|
debugMathRichInput("showEquationEditor:start", {
|
|
23639
24185
|
moveCursorOnInsert: moveCursorOnInsert,
|
|
23640
24186
|
nodeProvided: Boolean(node),
|
|
@@ -23643,8 +24189,27 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23643
24189
|
innerHTML: _this2.editableDiv ? _this2.editableDiv.innerHTML : null,
|
|
23644
24190
|
selection: getSelectionSnapshot(_this2.editableDiv)
|
|
23645
24191
|
});
|
|
23646
|
-
|
|
23647
|
-
|
|
24192
|
+
// A node handed in by a click is enough to open the editor, even when the selection resolves to
|
|
24193
|
+
// nothing (-1) or is missing entirely: the node carries the latex and where it sits.
|
|
24194
|
+
if (!hasNode && (rangeParams === null || rangeParams.startNodeIndex < 0) && !_this2.isVisuallyEmpty()) {
|
|
24195
|
+
// No usable caret in a field that has content. The empty-field fallback below must never run
|
|
24196
|
+
// here: its marks stand for the WHOLE value, so Insert would replace the answer with the formula.
|
|
24197
|
+
// Put the caret at the end of the field and resolve it again; if that still fails, do not open.
|
|
24198
|
+
var endOfField = document.createRange();
|
|
24199
|
+
endOfField.selectNodeContents(_this2.editableDiv);
|
|
24200
|
+
endOfField.collapse(false);
|
|
24201
|
+
_this2.setCaretToRange(endOfField);
|
|
24202
|
+
rangeParams = _this2._getRangeParams();
|
|
24203
|
+
if (rangeParams === null || rangeParams.startNodeIndex < 0) {
|
|
24204
|
+
console.error("Could not find position of cursor in node list");
|
|
24205
|
+
return;
|
|
24206
|
+
}
|
|
24207
|
+
}
|
|
24208
|
+
if (!hasNode && (rangeParams === null || rangeParams.startNodeIndex < 0)) {
|
|
24209
|
+
// An empty field: there is nothing to keep, so the equation becomes its whole value.
|
|
24210
|
+
debugMathRichInput("showEquationEditor:empty-field", {
|
|
24211
|
+
rangeParams: rangeParams
|
|
24212
|
+
});
|
|
23648
24213
|
_this2.setOldRangeParams({
|
|
23649
24214
|
startNodeIndex: 2,
|
|
23650
24215
|
startOffset: 1,
|
|
@@ -23652,6 +24217,9 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23652
24217
|
endOffset: 1
|
|
23653
24218
|
});
|
|
23654
24219
|
_this2.markedRawText = MARK + " " + MARK;
|
|
24220
|
+
// A new equation: never the formula an earlier opening was editing.
|
|
24221
|
+
_this2.editingExistingEquation = false;
|
|
24222
|
+
_this2.editingNode = null;
|
|
23655
24223
|
_this2.moveCursorOnInsert = moveCursorOnInsert;
|
|
23656
24224
|
_this2.setState({
|
|
23657
24225
|
showEquationEditor: true,
|
|
@@ -23661,7 +24229,14 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23661
24229
|
}
|
|
23662
24230
|
var latex = "";
|
|
23663
24231
|
var offset = 0;
|
|
23664
|
-
if (
|
|
24232
|
+
if (!hasNode) node = _this2._findNodeWithIndex(rangeParams.startNodeIndex);
|
|
24233
|
+
|
|
24234
|
+
// The toolbar preserves a caret AFTER the formula, in the renderer's zero-width text node.
|
|
24235
|
+
// Resolve that boundary to the preceding formula so f(x) edits it instead of opening empty.
|
|
24236
|
+
// Ordinary text or a non-collapsed selection still starts a new equation.
|
|
24237
|
+
if (!hasNode && ((_node = node) === null || _node === void 0 ? void 0 : _node.nodeType) === Node.TEXT_NODE && rangeParams.startNodeIndex === rangeParams.endNodeIndex && rangeParams.startOffset === rangeParams.endOffset && node.textContent.slice(0, rangeParams.startOffset).replace(/\u200b/g, "") === "" && isKatexNode(node.previousSibling)) {
|
|
24238
|
+
node = node.previousSibling;
|
|
24239
|
+
}
|
|
23665
24240
|
|
|
23666
24241
|
// console.log(rangeParams)
|
|
23667
24242
|
// console.log(this.editableDiv.childNodes)
|
|
@@ -23681,7 +24256,7 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23681
24256
|
_this2.editingNode = node;
|
|
23682
24257
|
} else {
|
|
23683
24258
|
latex = "";
|
|
23684
|
-
offset = rangeParams.startOffset;
|
|
24259
|
+
offset = rangeParams ? rangeParams.startOffset : 0;
|
|
23685
24260
|
_this2.editingExistingEquation = false;
|
|
23686
24261
|
_this2.editingNode = null;
|
|
23687
24262
|
}
|
|
@@ -23709,6 +24284,7 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23709
24284
|
_this2.isMouseDownInEditable = false;
|
|
23710
24285
|
}, 0);
|
|
23711
24286
|
_this2.showEquationEditorOnMouseUp = false;
|
|
24287
|
+
_this2.equationEditorMouseDownKatexIndex = -1;
|
|
23712
24288
|
var node = null;
|
|
23713
24289
|
try {
|
|
23714
24290
|
node = event.target;
|
|
@@ -23724,6 +24300,11 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23724
24300
|
return;
|
|
23725
24301
|
}
|
|
23726
24302
|
_this2.showEquationEditorOnMouseUp = true;
|
|
24303
|
+
// The browser has no selection yet at mousedown and a click inside KaTeX may leave it inside the
|
|
24304
|
+
// rendered subtree or outside the field. The formula's POSITION is what survives until mouseup:
|
|
24305
|
+
// focusing the field redraws the editable and replaces every node with an identical one, so the
|
|
24306
|
+
// element pressed here is detached by the time the mouse is released.
|
|
24307
|
+
_this2.equationEditorMouseDownKatexIndex = _this2.katexNodesInField().indexOf(node);
|
|
23727
24308
|
// Save current range parameters so that we can restore them later if we wish
|
|
23728
24309
|
_this2.setOldRangeParams(_this2._getRangeParams());
|
|
23729
24310
|
|
|
@@ -23742,6 +24323,25 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23742
24323
|
|
|
23743
24324
|
// Clear selection anchor on mouse click
|
|
23744
24325
|
_this2.selectionAnchor = null;
|
|
24326
|
+
var selection = window.getSelection();
|
|
24327
|
+
var collapsedClick = selection === null || selection.rangeCount === 0 || selection.isCollapsed;
|
|
24328
|
+
|
|
24329
|
+
// A click on a formula opens the equation editor for THAT formula. The selection is not used to
|
|
24330
|
+
// find it: clicking KaTeX leaves the selection inside the rendered subtree (which the text model
|
|
24331
|
+
// reads as the position before the maths) or outside the field, and the editor then opened empty
|
|
24332
|
+
// and the caret came back at the start. The caret is put after the formula, which is one logical
|
|
24333
|
+
// character, so typing and Insert continue to its right.
|
|
24334
|
+
if (collapsedClick && _this2.showEquationEditorOnMouseUp) {
|
|
24335
|
+
// Focus BEFORE the node is looked up: focusing redraws the field, and a node resolved from the
|
|
24336
|
+
// old DOM would be detached by the time the range is built.
|
|
24337
|
+
_this2.editableDiv.focus();
|
|
24338
|
+
var mathNode = _this2.katexNodesInField()[_this2.equationEditorMouseDownKatexIndex] || null;
|
|
24339
|
+
if (mathNode !== null) {
|
|
24340
|
+
_this2.setCaretToRange(_this2.caretRangeAfterNode(mathNode));
|
|
24341
|
+
_this2.showEquationEditor(false, mathNode);
|
|
24342
|
+
return;
|
|
24343
|
+
}
|
|
24344
|
+
}
|
|
23745
24345
|
|
|
23746
24346
|
// A click that lands with the selection outside this field — a toolbar button, another field —
|
|
23747
24347
|
// gives no range at all. Dereferenced unguarded, this threw on every such click.
|
|
@@ -23754,11 +24354,6 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23754
24354
|
console.warn("Start or end node was null");
|
|
23755
24355
|
return;
|
|
23756
24356
|
}
|
|
23757
|
-
if (params.startNodeIndex === params.endNodeIndex && params.startOffset === params.endOffset && _this2.showEquationEditorOnMouseUp) {
|
|
23758
|
-
_this2.editableDiv.focus();
|
|
23759
|
-
_this2.showEquationEditor(false, startNode);
|
|
23760
|
-
return;
|
|
23761
|
-
}
|
|
23762
24357
|
|
|
23763
24358
|
// If our range starts or ends inside a katex node, move it out
|
|
23764
24359
|
var new_rangeParams = null;
|
|
@@ -23779,6 +24374,10 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23779
24374
|
new_rangeParams.endOffset = SMALL_SPACE_LENGTH;
|
|
23780
24375
|
}
|
|
23781
24376
|
if (new_rangeParams !== null) {
|
|
24377
|
+
// These node positions replace a selection inside KaTeX. Its old global offsets still point
|
|
24378
|
+
// before the atomic formula, so they must not override the corrected positions after it.
|
|
24379
|
+
new_rangeParams.startGlobalOffset = null;
|
|
24380
|
+
new_rangeParams.endGlobalOffset = null;
|
|
23782
24381
|
_this2._setRangeParams(new_rangeParams);
|
|
23783
24382
|
event.preventDefault();
|
|
23784
24383
|
return;
|
|
@@ -23812,6 +24411,27 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23812
24411
|
innerHTML: _this2.editableDiv ? _this2.editableDiv.innerHTML : null,
|
|
23813
24412
|
selection: getSelectionSnapshot(_this2.editableDiv)
|
|
23814
24413
|
});
|
|
24414
|
+
|
|
24415
|
+
// Insert with nothing to write: a formula that was opened and not edited, or a new equation left
|
|
24416
|
+
// empty. Writing back would send the host a change event for a value it already holds, and hosts
|
|
24417
|
+
// show "unsaved changes" on any change event. Close as Escape does and put the caret back.
|
|
24418
|
+
if (_this2.editingExistingEquation && latex === _this2.state.equationEditorLatex || !_this2.editingExistingEquation && latex === "") {
|
|
24419
|
+
var unchangedRangeParams = _this2.getOldRangeParams();
|
|
24420
|
+
_this2.setState({
|
|
24421
|
+
showEquationEditor: false
|
|
24422
|
+
}, function () {
|
|
24423
|
+
try {
|
|
24424
|
+
_this2.editableDiv.focus();
|
|
24425
|
+
if (unchangedRangeParams !== null) {
|
|
24426
|
+
_this2._setRangeParams(unchangedRangeParams);
|
|
24427
|
+
_this2.restoreRangeAfterBrowserWork(unchangedRangeParams, "equation-unchanged");
|
|
24428
|
+
}
|
|
24429
|
+
} catch (error) {
|
|
24430
|
+
console.error(error);
|
|
24431
|
+
}
|
|
24432
|
+
});
|
|
24433
|
+
return;
|
|
24434
|
+
}
|
|
23815
24435
|
var start_pos = _this2.markedRawText.indexOf(MARK);
|
|
23816
24436
|
var end_pos = _this2.markedRawText.indexOf(MARK, start_pos + MARK.length);
|
|
23817
24437
|
var oldRangeParams = _this2.getOldRangeParams();
|
|
@@ -23932,6 +24552,9 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23932
24552
|
// }
|
|
23933
24553
|
_defineProperty(_this2, "styleText", function (event, style) {
|
|
23934
24554
|
try {
|
|
24555
|
+
_this2.initialiseHistory();
|
|
24556
|
+
_this2.resetHistoryRedo();
|
|
24557
|
+
_this2.formatCommandActive = true;
|
|
23935
24558
|
style = style.toLowerCase();
|
|
23936
24559
|
var command = _this2.getStyleCommand(style);
|
|
23937
24560
|
var activeBefore = _this2.getActiveButtonsFromSelection();
|
|
@@ -23939,12 +24562,14 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23939
24562
|
var isCollapsed = selection === null || selection.rangeCount === 0 || selection.getRangeAt(0).collapsed;
|
|
23940
24563
|
var success = false;
|
|
23941
24564
|
var insertedTypingStylePlaceholder = false;
|
|
24565
|
+
var publishedByWhitespaceMove = false;
|
|
23942
24566
|
|
|
23943
24567
|
// This first part is a workaround whereby executing subscript or superscript
|
|
23944
24568
|
// within an existing subscript or superscript makes the text even smaller instead
|
|
23945
24569
|
// of toggling it off. Thus we manually toggle it off with some jigerry pokery!
|
|
23946
24570
|
if (isCollapsed && activeBefore[style] && _this2.moveTrailingWhitespaceOutsideInlineStyle(style, command)) {
|
|
23947
24571
|
success = true;
|
|
24572
|
+
publishedByWhitespaceMove = true;
|
|
23948
24573
|
} else if (isCollapsed && !activeBefore[style] && selection && selection.rangeCount > 0) {
|
|
23949
24574
|
success = _this2.insertInlineStylePlaceholder(style);
|
|
23950
24575
|
insertedTypingStylePlaceholder = success;
|
|
@@ -23966,15 +24591,29 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23966
24591
|
}
|
|
23967
24592
|
}
|
|
23968
24593
|
var rangeParams = _this2._getRangeParams();
|
|
23969
|
-
|
|
23970
|
-
if (
|
|
24594
|
+
if (!insertedTypingStylePlaceholder) _this2.cleanupEmptyInlineFormattingElements();
|
|
24595
|
+
if (!publishedByWhitespaceMove && rangeParams !== null && rangeParams !== undefined) {
|
|
23971
24596
|
_this2._setRangeParams(rangeParams);
|
|
23972
|
-
_this2.applyCurrentEditableDomToComponent(rangeParams
|
|
24597
|
+
_this2.applyCurrentEditableDomToComponent(rangeParams, {
|
|
24598
|
+
edit: {
|
|
24599
|
+
before: editableText(_this2.editableDiv),
|
|
24600
|
+
from: 0,
|
|
24601
|
+
to: 0,
|
|
24602
|
+
insert: ""
|
|
24603
|
+
},
|
|
24604
|
+
intent: "format",
|
|
24605
|
+
history: {
|
|
24606
|
+
id: "mri-".concat(++_this2.historySequence),
|
|
24607
|
+
direction: "forward"
|
|
24608
|
+
}
|
|
24609
|
+
});
|
|
23973
24610
|
}
|
|
23974
24611
|
_this2.setActiveButtonsIfChanged(_this2.getActiveButtonsFromSelection(rangeParams));
|
|
23975
24612
|
return success;
|
|
23976
24613
|
} catch (error) {
|
|
23977
24614
|
console.error(error);
|
|
24615
|
+
} finally {
|
|
24616
|
+
_this2.formatCommandActive = false;
|
|
23978
24617
|
}
|
|
23979
24618
|
});
|
|
23980
24619
|
_defineProperty(_this2, "handleToolbarButtonClick", function (event, buttonName) {
|
|
@@ -24014,6 +24653,7 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24014
24653
|
_defineProperty(_this2, "insertRawText", function (new_text) {
|
|
24015
24654
|
var selectInsertedText = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
24016
24655
|
try {
|
|
24656
|
+
var beforeText = editableText(_this2.editableDiv);
|
|
24017
24657
|
var rangeParams = _this2._getRangeParams();
|
|
24018
24658
|
var node = _this2._findNodeWithIndex(rangeParams.endNodeIndex);
|
|
24019
24659
|
var offset = rangeParams.endOffset;
|
|
@@ -24045,7 +24685,21 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24045
24685
|
// console.log(new_rangeParams)
|
|
24046
24686
|
|
|
24047
24687
|
new_raw_text = removeEncodingIfPlainText(new_raw_text, _this2.props.mimeType, _this2.enableHtml());
|
|
24048
|
-
_this2.applyChangesToComponent(new_raw_text, _this2.props.mimeType, new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab
|
|
24688
|
+
_this2.applyChangesToComponent(new_raw_text, _this2.props.mimeType, new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab, {
|
|
24689
|
+
transaction: {
|
|
24690
|
+
edit: {
|
|
24691
|
+
before: beforeText,
|
|
24692
|
+
from: rangeParams.startGlobalOffset,
|
|
24693
|
+
to: rangeParams.endGlobalOffset,
|
|
24694
|
+
insert: new_text
|
|
24695
|
+
},
|
|
24696
|
+
intent: "input",
|
|
24697
|
+
history: {
|
|
24698
|
+
id: "mri-".concat(++_this2.historySequence),
|
|
24699
|
+
direction: "forward"
|
|
24700
|
+
}
|
|
24701
|
+
}
|
|
24702
|
+
});
|
|
24049
24703
|
} catch (error) {
|
|
24050
24704
|
console.error(error);
|
|
24051
24705
|
}
|
|
@@ -24173,6 +24827,7 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24173
24827
|
});
|
|
24174
24828
|
_defineProperty(_this2, "removeNewLine", function () {
|
|
24175
24829
|
try {
|
|
24830
|
+
var beforeText = editableText(_this2.editableDiv);
|
|
24176
24831
|
var rangeParams = _this2._getRangeParams();
|
|
24177
24832
|
var node = _this2._findNodeWithIndex(rangeParams.endNodeIndex);
|
|
24178
24833
|
var prevNode = _this2._findNodeWithIndex(rangeParams.endNodeIndex - 1);
|
|
@@ -24189,13 +24844,28 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24189
24844
|
new_rangeParams.srartGlobalOffset--;
|
|
24190
24845
|
new_rangeParams.endGlobalOffset--;
|
|
24191
24846
|
new_raw_text = removeEncodingIfPlainText(new_raw_text, _this2.props.mimeType, _this2.enableHtml());
|
|
24192
|
-
_this2.applyChangesToComponent(new_raw_text, _this2.props.mimeType, new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab
|
|
24847
|
+
_this2.applyChangesToComponent(new_raw_text, _this2.props.mimeType, new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab, {
|
|
24848
|
+
transaction: {
|
|
24849
|
+
edit: {
|
|
24850
|
+
before: beforeText,
|
|
24851
|
+
from: Math.max(0, rangeParams.endGlobalOffset - 1),
|
|
24852
|
+
to: rangeParams.endGlobalOffset,
|
|
24853
|
+
insert: ""
|
|
24854
|
+
},
|
|
24855
|
+
intent: "input",
|
|
24856
|
+
history: {
|
|
24857
|
+
id: "mri-".concat(++_this2.historySequence),
|
|
24858
|
+
direction: "forward"
|
|
24859
|
+
}
|
|
24860
|
+
}
|
|
24861
|
+
});
|
|
24193
24862
|
} catch (error) {
|
|
24194
24863
|
console.error(error);
|
|
24195
24864
|
}
|
|
24196
24865
|
});
|
|
24197
24866
|
_defineProperty(_this2, "insertNewLine", function () {
|
|
24198
24867
|
try {
|
|
24868
|
+
var beforeText = editableText(_this2.editableDiv);
|
|
24199
24869
|
var rangeParams = _this2._getRangeParams();
|
|
24200
24870
|
var node = _this2._findNodeWithIndex(rangeParams.endNodeIndex);
|
|
24201
24871
|
var offset = rangeParams.endOffset;
|
|
@@ -24231,13 +24901,28 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24231
24901
|
// console.log("New range params after line insert")
|
|
24232
24902
|
// console.log(new_rangeParams)
|
|
24233
24903
|
|
|
24234
|
-
_this2.applyChangesToComponent(new_raw_text, _this2.props.mimeType, new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab
|
|
24904
|
+
_this2.applyChangesToComponent(new_raw_text, _this2.props.mimeType, new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab, {
|
|
24905
|
+
transaction: {
|
|
24906
|
+
edit: {
|
|
24907
|
+
before: beforeText,
|
|
24908
|
+
from: rangeParams.startGlobalOffset,
|
|
24909
|
+
to: rangeParams.endGlobalOffset,
|
|
24910
|
+
insert: "\n"
|
|
24911
|
+
},
|
|
24912
|
+
intent: "input",
|
|
24913
|
+
history: {
|
|
24914
|
+
id: "mri-".concat(++_this2.historySequence),
|
|
24915
|
+
direction: "forward"
|
|
24916
|
+
}
|
|
24917
|
+
}
|
|
24918
|
+
});
|
|
24235
24919
|
} catch (error) {
|
|
24236
24920
|
console.error(error);
|
|
24237
24921
|
}
|
|
24238
24922
|
});
|
|
24239
24923
|
_defineProperty(_this2, "insertAccentLetter", function (event, old_char, new_char) {
|
|
24240
24924
|
try {
|
|
24925
|
+
var beforeText = editableText(_this2.editableDiv);
|
|
24241
24926
|
var rangeParams = _this2._getRangeParams();
|
|
24242
24927
|
var node = _this2._findNodeWithIndex(rangeParams.startNodeIndex);
|
|
24243
24928
|
var offset = rangeParams.startOffset;
|
|
@@ -24261,7 +24946,21 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24261
24946
|
new_rangeParams = _objectSpread2({}, rangeParams);
|
|
24262
24947
|
}
|
|
24263
24948
|
new_raw_text = removeEncodingIfPlainText(new_raw_text, _this2.props.mimeType, _this2.enableHtml());
|
|
24264
|
-
_this2.applyChangesToComponent(new_raw_text, _this2.props.mimeType, new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab
|
|
24949
|
+
_this2.applyChangesToComponent(new_raw_text, _this2.props.mimeType, new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab, {
|
|
24950
|
+
transaction: {
|
|
24951
|
+
edit: {
|
|
24952
|
+
before: beforeText,
|
|
24953
|
+
from: old_char === null ? rangeParams.startGlobalOffset : Math.max(0, rangeParams.startGlobalOffset - 1),
|
|
24954
|
+
to: old_char === null ? rangeParams.startGlobalOffset : rangeParams.startGlobalOffset,
|
|
24955
|
+
insert: new_char
|
|
24956
|
+
},
|
|
24957
|
+
intent: "input",
|
|
24958
|
+
history: {
|
|
24959
|
+
id: "mri-".concat(++_this2.historySequence),
|
|
24960
|
+
direction: "forward"
|
|
24961
|
+
}
|
|
24962
|
+
}
|
|
24963
|
+
});
|
|
24265
24964
|
} catch (error) {
|
|
24266
24965
|
console.error(error);
|
|
24267
24966
|
}
|
|
@@ -24306,12 +25005,21 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24306
25005
|
currentRangeParams = null;
|
|
24307
25006
|
}
|
|
24308
25007
|
var savedRangeParams = _this2.getOldRangeParams();
|
|
24309
|
-
|
|
25008
|
+
// A missing selection at focus time is not "somewhere else": the browser has not placed a caret
|
|
25009
|
+
// yet, which reads as the START of the field. Treating null as "leave it alone" skipped both the
|
|
25010
|
+
// restore below and the move to the end, so the caret stayed where the browser had left it — 0.
|
|
25011
|
+
var currentIsAtStart = currentRangeParams === null || _this2.rangeIsAtStart(currentRangeParams);
|
|
25012
|
+
var shouldRestoreSavedRange = !_this2.isMouseDownInEditable && _this2.props.value !== "" && currentIsAtStart && _this2.rangeHasNonZeroPosition(savedRangeParams);
|
|
25013
|
+
// Focus without a click inside the field (a host focusing it, Tab, a click on the row around it)
|
|
25014
|
+
// carries no position of its own. Editing an existing answer means continuing at its end, so the
|
|
25015
|
+
// caret goes there; a click inside the field keeps the position the browser gave it.
|
|
25016
|
+
var shouldMoveToEnd = !_this2.isMouseDownInEditable && _this2.props.value !== "" && currentIsAtStart && !_this2.rangeHasNonZeroPosition(savedRangeParams);
|
|
24310
25017
|
debugMathRichInput("handleFocus:start", {
|
|
24311
25018
|
propsValue: _this2.props.value,
|
|
24312
25019
|
oldRangeParams: _this2.oldRangeParams,
|
|
24313
25020
|
currentRangeParams: currentRangeParams,
|
|
24314
25021
|
shouldRestoreSavedRange: shouldRestoreSavedRange,
|
|
25022
|
+
shouldMoveToEnd: shouldMoveToEnd,
|
|
24315
25023
|
innerHTML: _this2.editableDiv ? _this2.editableDiv.innerHTML : null,
|
|
24316
25024
|
selection: getSelectionSnapshot(_this2.editableDiv)
|
|
24317
25025
|
});
|
|
@@ -24325,6 +25033,22 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24325
25033
|
if (shouldRestoreSavedRange) {
|
|
24326
25034
|
_this2._setRangeParams(savedRangeParams);
|
|
24327
25035
|
_this2.restoreRangeAfterBrowserWork(savedRangeParams, "focus-restore");
|
|
25036
|
+
} else if (shouldMoveToEnd) {
|
|
25037
|
+
// One task later, not here: the browser places the caret as part of the focus default
|
|
25038
|
+
// action, and for a keyboard focus (Tab) that happens AFTER this callback — moving now was
|
|
25039
|
+
// simply overwritten. A task boundary is after both the pointer and the keyboard default.
|
|
25040
|
+
// The guard keeps a selection placed meanwhile (a host restoring its own range) untouched.
|
|
25041
|
+
window.setTimeout(function () {
|
|
25042
|
+
if (_this2.state.hasFocus !== true) return;
|
|
25043
|
+
var liveRangeParams = _this2._getRangeParams();
|
|
25044
|
+
if (liveRangeParams !== null && !_this2.rangeIsAtStart(liveRangeParams)) {
|
|
25045
|
+
return;
|
|
25046
|
+
}
|
|
25047
|
+
var endOfField = document.createRange();
|
|
25048
|
+
endOfField.selectNodeContents(_this2.editableDiv);
|
|
25049
|
+
endOfField.collapse(false);
|
|
25050
|
+
_this2.setCaretToRange(endOfField);
|
|
25051
|
+
}, 0);
|
|
24328
25052
|
}
|
|
24329
25053
|
debugMathRichInput("handleFocus:after-setState", {
|
|
24330
25054
|
selection: getSelectionSnapshot(_this2.editableDiv)
|
|
@@ -24335,11 +25059,12 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24335
25059
|
}
|
|
24336
25060
|
});
|
|
24337
25061
|
_defineProperty(_this2, "handleBlur", function (event) {
|
|
25062
|
+
var _this2$toolbar;
|
|
24338
25063
|
var onBlur = _this2.props.onBlur;
|
|
24339
25064
|
var currentRangeParams = null;
|
|
24340
25065
|
try {
|
|
24341
25066
|
currentRangeParams = _this2._getRangeParams();
|
|
24342
|
-
if (
|
|
25067
|
+
if (currentRangeParams !== null) {
|
|
24343
25068
|
_this2.setOldRangeParams(currentRangeParams);
|
|
24344
25069
|
}
|
|
24345
25070
|
} catch (error) {
|
|
@@ -24352,6 +25077,9 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24352
25077
|
innerHTML: _this2.editableDiv ? _this2.editableDiv.innerHTML : null,
|
|
24353
25078
|
selection: getSelectionSnapshot(_this2.editableDiv)
|
|
24354
25079
|
});
|
|
25080
|
+
// Keyboard focus on this editor's tools is still inside the editor. Keep both
|
|
25081
|
+
// the toolbar and the captured range until focus leaves the whole control.
|
|
25082
|
+
if (event.relatedTarget === _this2.editableDiv || (_this2$toolbar = _this2.toolbar) !== null && _this2$toolbar !== void 0 && (_this2$toolbar = _this2$toolbar.toolbar) !== null && _this2$toolbar !== void 0 && _this2$toolbar.contains(event.relatedTarget)) return;
|
|
24355
25083
|
if (onBlur != null) {
|
|
24356
25084
|
onBlur();
|
|
24357
25085
|
}
|
|
@@ -24369,10 +25097,66 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24369
25097
|
}
|
|
24370
25098
|
});
|
|
24371
25099
|
_defineProperty(_this2, "handleCompositionStart", function (event) {
|
|
25100
|
+
var _offsets$from, _offsets$to;
|
|
25101
|
+
var offsets = _this2.captureSelectionOffsets();
|
|
25102
|
+
_this2.compositionStart = {
|
|
25103
|
+
before: editableText(_this2.editableDiv),
|
|
25104
|
+
from: (_offsets$from = offsets === null || offsets === void 0 ? void 0 : offsets.from) !== null && _offsets$from !== void 0 ? _offsets$from : 0,
|
|
25105
|
+
to: (_offsets$to = offsets === null || offsets === void 0 ? void 0 : offsets.to) !== null && _offsets$to !== void 0 ? _offsets$to : 0
|
|
25106
|
+
};
|
|
24372
25107
|
_this2.isComposing = true;
|
|
24373
25108
|
});
|
|
24374
25109
|
_defineProperty(_this2, "handleCompositionEnd", function (event) {
|
|
24375
25110
|
_this2.isComposing = false;
|
|
25111
|
+
_this2.compositionStart = null;
|
|
25112
|
+
});
|
|
25113
|
+
_defineProperty(_this2, "captureSelectionOffsets", function () {
|
|
25114
|
+
try {
|
|
25115
|
+
var selection = window.getSelection();
|
|
25116
|
+
if (!selection || selection.rangeCount === 0) return null;
|
|
25117
|
+
var range = selection.getRangeAt(0);
|
|
25118
|
+
var before = editableText(_this2.editableDiv);
|
|
25119
|
+
var endpoint = function endpoint(container, offset) {
|
|
25120
|
+
var probe = document.createRange();
|
|
25121
|
+
probe.selectNodeContents(_this2.editableDiv);
|
|
25122
|
+
probe.setEnd(container, offset);
|
|
25123
|
+
var wrapper = document.createElement("span");
|
|
25124
|
+
wrapper.appendChild(probe.cloneContents());
|
|
25125
|
+
return editableText(wrapper).length;
|
|
25126
|
+
};
|
|
25127
|
+
var from = endpoint(range.startContainer, range.startOffset);
|
|
25128
|
+
var to = endpoint(range.endContainer, range.endOffset);
|
|
25129
|
+
return {
|
|
25130
|
+
before: before,
|
|
25131
|
+
from: Math.min(from, to),
|
|
25132
|
+
to: Math.max(from, to)
|
|
25133
|
+
};
|
|
25134
|
+
} catch (_error) {
|
|
25135
|
+
return null;
|
|
25136
|
+
}
|
|
25137
|
+
});
|
|
25138
|
+
/** Capture an input intent before the browser mutates the contenteditable DOM. */
|
|
25139
|
+
_defineProperty(_this2, "handleBeforeInput", function (event) {
|
|
25140
|
+
try {
|
|
25141
|
+
var captured = transactionFromBeforeInput(_this2.editableDiv, event, _this2.compositionStart ? {
|
|
25142
|
+
before: _this2.compositionStart.before,
|
|
25143
|
+
from: _this2.compositionStart.from,
|
|
25144
|
+
to: _this2.compositionStart.to
|
|
25145
|
+
} : null);
|
|
25146
|
+
var id = "mri-".concat(++_this2.historySequence);
|
|
25147
|
+
_this2.pendingTransaction = {
|
|
25148
|
+
edit: captured.edit || undefined,
|
|
25149
|
+
intent: captured.intent,
|
|
25150
|
+
history: {
|
|
25151
|
+
id: id,
|
|
25152
|
+
direction: "forward"
|
|
25153
|
+
}
|
|
25154
|
+
};
|
|
25155
|
+
} catch (_error) {
|
|
25156
|
+
_this2.pendingTransaction = {
|
|
25157
|
+
intent: "programmatic"
|
|
25158
|
+
};
|
|
25159
|
+
}
|
|
24376
25160
|
});
|
|
24377
25161
|
// Comprehensive LaTeX pattern detection and auto-wrapping in math tags
|
|
24378
25162
|
// Comprehensive LaTeX pattern detection for paste auto-wrapping
|
|
@@ -24509,6 +25293,14 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24509
25293
|
_this2.isMouseDownInEditable = false;
|
|
24510
25294
|
_this2.lastRenderedEditableHtml = null;
|
|
24511
25295
|
_this2.preserveNativeDomRangeParams = null;
|
|
25296
|
+
// The `dangerouslySetInnerHTML` prop object, reused while the html is unchanged. React re-applies
|
|
25297
|
+
// the markup on a commit when it is handed a fresh object, replacing the editable's nodes and the
|
|
25298
|
+
// caret with them; the same object tells React there is nothing to write.
|
|
25299
|
+
_this2.lastEditableHtmlProp = undefined;
|
|
25300
|
+
_this2.lastEditableHtmlPropHtml = null;
|
|
25301
|
+
// Which of the field's formulas the current mouse press started on. The node itself cannot be
|
|
25302
|
+
// kept: focusing a field redraws it, so the element that was pressed is already gone at mouseup.
|
|
25303
|
+
_this2.equationEditorMouseDownKatexIndex = -1;
|
|
24512
25304
|
_this2.lastSetActiveButtons = null;
|
|
24513
25305
|
_this2.onChangeCallback = _this2.props.onChange;
|
|
24514
25306
|
|
|
@@ -24518,6 +25310,9 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24518
25310
|
_this2.initialHistoryState = null;
|
|
24519
25311
|
_this2.undoHistory = [];
|
|
24520
25312
|
_this2.redoHistory = [];
|
|
25313
|
+
_this2.historySequence = 0;
|
|
25314
|
+
_this2.pendingTransaction = null;
|
|
25315
|
+
_this2.compositionStart = null;
|
|
24521
25316
|
_this2.accent = "";
|
|
24522
25317
|
|
|
24523
25318
|
// keeps track of whether user is composing in an IME - see https://developer.mozilla.org/en-US/docs/Web/API/CompositionEvent
|
|
@@ -24693,6 +25488,39 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24693
25488
|
endGlobalOffset: null
|
|
24694
25489
|
});
|
|
24695
25490
|
}
|
|
25491
|
+
|
|
25492
|
+
/** The caret's params, only when the selection is inside this field. */
|
|
25493
|
+
}, {
|
|
25494
|
+
key: "selectionRangeParams",
|
|
25495
|
+
value: function selectionRangeParams() {
|
|
25496
|
+
var selection = window.getSelection();
|
|
25497
|
+
if (!selection || selection.rangeCount === 0) return null;
|
|
25498
|
+
if (!this.editableDiv || !this.editableDiv.contains(selection.anchorNode)) {
|
|
25499
|
+
return null;
|
|
25500
|
+
}
|
|
25501
|
+
return this.getRangeParamsPreservingInlinePlaceholder();
|
|
25502
|
+
}
|
|
25503
|
+
|
|
25504
|
+
/**
|
|
25505
|
+
* The `dangerouslySetInnerHTML` prop, REUSED while the html is unchanged.
|
|
25506
|
+
*
|
|
25507
|
+
* React re-applies `dangerouslySetInnerHTML` on a commit when it is handed a new prop object, even
|
|
25508
|
+
* when the string in it is the one already in the DOM (measured with React 19: three writes of an
|
|
25509
|
+
* identical-length string, each replacing the editable's children — and with them the caret, which
|
|
25510
|
+
* then sat at the start of the field). The same object is what tells React there is nothing to
|
|
25511
|
+
* write, and that is how the field keeps the browser's own DOM and selection.
|
|
25512
|
+
*/
|
|
25513
|
+
}, {
|
|
25514
|
+
key: "editableHtmlProp",
|
|
25515
|
+
value: function editableHtmlProp(html) {
|
|
25516
|
+
if (this.lastEditableHtmlProp === undefined || this.lastEditableHtmlPropHtml !== html) {
|
|
25517
|
+
this.lastEditableHtmlPropHtml = html;
|
|
25518
|
+
this.lastEditableHtmlProp = {
|
|
25519
|
+
__html: html
|
|
25520
|
+
};
|
|
25521
|
+
}
|
|
25522
|
+
return this.lastEditableHtmlProp;
|
|
25523
|
+
}
|
|
24696
25524
|
}, {
|
|
24697
25525
|
key: "getEditableHtmlForRender",
|
|
24698
25526
|
value: function getEditableHtmlForRender(html) {
|
|
@@ -24721,8 +25549,12 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24721
25549
|
this.preserveNativeDomRangeParams = preserveRangeParams;
|
|
24722
25550
|
return liveEditableHtml;
|
|
24723
25551
|
}
|
|
25552
|
+
|
|
25553
|
+
// React will write this string: it differs from the one it last rendered. Remember where the
|
|
25554
|
+
// caret is so it can be put back if the write takes the selection with it. A click elsewhere
|
|
25555
|
+
// blurs the field before the commit, so the restore below never overrides another control.
|
|
25556
|
+
this.preserveNativeDomRangeParams = this.state.hasFocus === true && html !== this.lastRenderedEditableHtml ? this.selectionRangeParams() : null;
|
|
24724
25557
|
this.lastRenderedEditableHtml = html;
|
|
24725
|
-
this.preserveNativeDomRangeParams = null;
|
|
24726
25558
|
return html;
|
|
24727
25559
|
}
|
|
24728
25560
|
}, {
|
|
@@ -24954,7 +25786,19 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24954
25786
|
var rangeParams = this._getRangeParams();
|
|
24955
25787
|
if (rangeParams) {
|
|
24956
25788
|
this.setOldRangeParams(rangeParams);
|
|
24957
|
-
this.applyCurrentEditableDomToComponent(rangeParams
|
|
25789
|
+
this.applyCurrentEditableDomToComponent(rangeParams, {
|
|
25790
|
+
edit: {
|
|
25791
|
+
before: editableText(this.editableDiv),
|
|
25792
|
+
from: 0,
|
|
25793
|
+
to: 0,
|
|
25794
|
+
insert: ""
|
|
25795
|
+
},
|
|
25796
|
+
intent: "format",
|
|
25797
|
+
history: {
|
|
25798
|
+
id: "mri-".concat(++this.historySequence),
|
|
25799
|
+
direction: "forward"
|
|
25800
|
+
}
|
|
25801
|
+
});
|
|
24958
25802
|
}
|
|
24959
25803
|
debugMathRichInput("moveTrailingWhitespaceOutsideInlineStyle:after", {
|
|
24960
25804
|
style: style,
|
|
@@ -24970,6 +25814,7 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24970
25814
|
key: "applyCurrentEditableDomToComponent",
|
|
24971
25815
|
value: function applyCurrentEditableDomToComponent() {
|
|
24972
25816
|
var rangeParams = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
25817
|
+
var transaction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
24973
25818
|
if (!this.editableDiv) return;
|
|
24974
25819
|
if (rangeParams === null || rangeParams === undefined) {
|
|
24975
25820
|
rangeParams = this._getRangeParams();
|
|
@@ -24984,7 +25829,8 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24984
25829
|
rawText = removeEncodingIfPlainText(rawText, mimeType, this.enableHtml());
|
|
24985
25830
|
rawText = this.stripEmptyInlineFormattingTags(rawText);
|
|
24986
25831
|
this.applyChangesToComponent(rawText, mimeType, rangeParams, this.props.useExpertMode, this.props.selectedTab, {
|
|
24987
|
-
skipControlledRender: true
|
|
25832
|
+
skipControlledRender: true,
|
|
25833
|
+
transaction: transaction
|
|
24988
25834
|
});
|
|
24989
25835
|
}
|
|
24990
25836
|
}, {
|
|
@@ -25035,6 +25881,7 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
25035
25881
|
});
|
|
25036
25882
|
this.editableDiv.addEventListener("keydown", this.handleKeyDown);
|
|
25037
25883
|
this.editableDiv.addEventListener("keyup", this.handleKeyUp);
|
|
25884
|
+
this.editableDiv.addEventListener("beforeinput", this.handleBeforeInput);
|
|
25038
25885
|
this.editableDiv.addEventListener("paste", this.handlePaste);
|
|
25039
25886
|
this.editableDiv.addEventListener("copy", this.handleCopy);
|
|
25040
25887
|
if (this.props.autofocus === true) this.editableDiv.focus();
|
|
@@ -25048,6 +25895,7 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
25048
25895
|
try {
|
|
25049
25896
|
this.editableDiv.removeEventListener("keydown", this.handleKeyDown);
|
|
25050
25897
|
this.editableDiv.removeEventListener("keyup", this.handleKeyUp);
|
|
25898
|
+
this.editableDiv.removeEventListener("beforeinput", this.handleBeforeInput);
|
|
25051
25899
|
this.editableDiv.removeEventListener("paste", this.handlePaste);
|
|
25052
25900
|
this.editableDiv.removeEventListener("copy", this.handleCopy);
|
|
25053
25901
|
} catch (error) {
|
|
@@ -25208,25 +26056,77 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
25208
26056
|
if (this.preserveNativeDomRangeParams !== null && this.preserveNativeDomRangeParams !== undefined && this.state.hasFocus === true) {
|
|
25209
26057
|
var rangeParams = this.preserveNativeDomRangeParams;
|
|
25210
26058
|
this.preserveNativeDomRangeParams = null;
|
|
25211
|
-
|
|
25212
|
-
|
|
25213
|
-
|
|
25214
|
-
|
|
25215
|
-
this.
|
|
25216
|
-
|
|
25217
|
-
|
|
25218
|
-
|
|
26059
|
+
// Only when the commit really did take the caret. A selection still in the field is the
|
|
26060
|
+
// user's and is not ours to move; a click elsewhere has blurred the field, which is why the
|
|
26061
|
+
// focus check above owns that case.
|
|
26062
|
+
var liveRangeParams = this._getRangeParams();
|
|
26063
|
+
if (liveRangeParams === null || this.rangeIsAtStart(liveRangeParams)) {
|
|
26064
|
+
debugMathRichInput("componentDidUpdate:preserve-restore-before", {
|
|
26065
|
+
rangeParams: rangeParams,
|
|
26066
|
+
selection: getSelectionSnapshot(this.editableDiv)
|
|
26067
|
+
});
|
|
26068
|
+
this._setRangeParams(rangeParams);
|
|
26069
|
+
debugMathRichInput("componentDidUpdate:preserve-restore-after", {
|
|
26070
|
+
selection: getSelectionSnapshot(this.editableDiv)
|
|
26071
|
+
});
|
|
26072
|
+
}
|
|
25219
26073
|
}
|
|
25220
26074
|
} catch (error) {
|
|
25221
26075
|
console.error(error);
|
|
25222
26076
|
}
|
|
25223
26077
|
}
|
|
26078
|
+
}, {
|
|
26079
|
+
key: "katexNodesInField",
|
|
26080
|
+
value: /** The field's rendered formulas, in document order — the positions a click can land on. */
|
|
26081
|
+
function katexNodesInField() {
|
|
26082
|
+
return _toConsumableArray(this.editableDiv.querySelectorAll(".katex, .katex-error"));
|
|
26083
|
+
}
|
|
26084
|
+
|
|
26085
|
+
/**
|
|
26086
|
+
* Put the browser's selection at `range` and remember the position it resolves to.
|
|
26087
|
+
*
|
|
26088
|
+
* Used to place the caret where the component — not the browser — knows it belongs: after a formula
|
|
26089
|
+
* that was clicked, and at the end of a field that was focused without a click.
|
|
26090
|
+
*/
|
|
26091
|
+
}, {
|
|
26092
|
+
key: "setCaretToRange",
|
|
26093
|
+
value: function setCaretToRange(range) {
|
|
26094
|
+
try {
|
|
26095
|
+
var selection = window.getSelection();
|
|
26096
|
+
if (!selection) return;
|
|
26097
|
+
selection.removeAllRanges();
|
|
26098
|
+
selection.addRange(range);
|
|
26099
|
+
var params = this._getRangeParams();
|
|
26100
|
+
if (params) this.setOldRangeParams(params);
|
|
26101
|
+
} catch (error) {
|
|
26102
|
+
console.error(error);
|
|
26103
|
+
}
|
|
26104
|
+
}
|
|
26105
|
+
|
|
26106
|
+
/**
|
|
26107
|
+
* A range that starts immediately after `node`, in the text that follows it.
|
|
26108
|
+
*
|
|
26109
|
+
* `setStartAfter` alone reads back as a position INSIDE the KaTeX subtree — the last text node of the
|
|
26110
|
+
* formula is the nearest text — and the text model treats that as the position BEFORE the maths. The
|
|
26111
|
+
* renderer always leaves a zero-width text node after a formula, so the caret starts there instead:
|
|
26112
|
+
* after the maths, where typing continues.
|
|
26113
|
+
*/
|
|
26114
|
+
}, {
|
|
26115
|
+
key: "caretRangeAfterNode",
|
|
26116
|
+
value: function caretRangeAfterNode(node) {
|
|
26117
|
+
var range = document.createRange();
|
|
26118
|
+
var next = node.nextSibling;
|
|
26119
|
+
if (next !== null && next !== undefined) range.setStart(next, 0);else range.setStartAfter(node);
|
|
26120
|
+
range.collapse(true);
|
|
26121
|
+
return range;
|
|
26122
|
+
}
|
|
25224
26123
|
}, {
|
|
25225
26124
|
key: "insertAfterSmallSpace",
|
|
25226
26125
|
value: function insertAfterSmallSpace(new_char, rangeParams) {
|
|
25227
26126
|
try {
|
|
25228
26127
|
if (rangeParams === null || rangeParams === undefined) rangeParams = this._getRangeParams();
|
|
25229
26128
|
if (rangeParams.startOffset !== 0) console.warn("Unexpected startOffset " + rangeParams.startOffset + " in insertAfterSmallSpace");
|
|
26129
|
+
var beforeText = editableText(this.editableDiv);
|
|
25230
26130
|
var node = this._findNodeWithIndex(rangeParams.startNodeIndex);
|
|
25231
26131
|
if (node === null || node === undefined || node.nodeValue === null) {
|
|
25232
26132
|
console.warn("Could not find small-space text node");
|
|
@@ -25251,7 +26151,20 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
25251
26151
|
var new_raw_text = elementToMarkedRawText(this.editableDiv, null, 0, this.enableHtml());
|
|
25252
26152
|
new_raw_text = removeEncodingIfPlainText(new_raw_text, this.props.mimeType, this.enableHtml());
|
|
25253
26153
|
this.applyChangesToComponent(new_raw_text, this.props.mimeType, new_rangeParams, this.props.useExpertMode, this.props.selectedTab, {
|
|
25254
|
-
skipControlledRender: true
|
|
26154
|
+
skipControlledRender: true,
|
|
26155
|
+
transaction: {
|
|
26156
|
+
edit: {
|
|
26157
|
+
before: beforeText,
|
|
26158
|
+
from: rangeParams.startGlobalOffset,
|
|
26159
|
+
to: rangeParams.startGlobalOffset,
|
|
26160
|
+
insert: new_char
|
|
26161
|
+
},
|
|
26162
|
+
intent: "input",
|
|
26163
|
+
history: {
|
|
26164
|
+
id: "mri-".concat(++this.historySequence),
|
|
26165
|
+
direction: "forward"
|
|
26166
|
+
}
|
|
26167
|
+
}
|
|
25255
26168
|
});
|
|
25256
26169
|
} catch (error) {
|
|
25257
26170
|
console.error(error);
|
|
@@ -25328,6 +26241,20 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
25328
26241
|
className: "MathRichInput-hint",
|
|
25329
26242
|
"aria-hidden": "true"
|
|
25330
26243
|
}, this.props.placeholder)), this.state.hasFocus && /*#__PURE__*/React__default["default"].createElement(Toolbar, {
|
|
26244
|
+
ref: function ref(r) {
|
|
26245
|
+
return _this3.toolbar = r;
|
|
26246
|
+
},
|
|
26247
|
+
onBlur: this.handleBlur,
|
|
26248
|
+
beforeAction: function beforeAction() {
|
|
26249
|
+
if (document.activeElement !== _this3.editableDiv) {
|
|
26250
|
+
var range = _this3.getOldRangeParams();
|
|
26251
|
+
_this3.editableDiv.focus({
|
|
26252
|
+
preventScroll: true
|
|
26253
|
+
});
|
|
26254
|
+
if (range !== null) _this3._setRangeParams(range);
|
|
26255
|
+
}
|
|
26256
|
+
_this3.initialiseHistory();
|
|
26257
|
+
},
|
|
25331
26258
|
className: "Toolbar",
|
|
25332
26259
|
enableMath: this.enableMath(),
|
|
25333
26260
|
enableFontStyling: this.enableFontStyling(),
|
|
@@ -25360,9 +26287,7 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
25360
26287
|
onBlur: this.handleBlur,
|
|
25361
26288
|
onCompositionStart: this.handleCompositionStart,
|
|
25362
26289
|
onCompositionEnd: this.handleCompositionEnd,
|
|
25363
|
-
dangerouslySetInnerHTML:
|
|
25364
|
-
__html: editableHtml
|
|
25365
|
-
},
|
|
26290
|
+
dangerouslySetInnerHTML: this.editableHtmlProp(editableHtml),
|
|
25366
26291
|
"data-placeholder": this.props.placeholder || ""
|
|
25367
26292
|
}))), this.state.showEquationEditor && /*#__PURE__*/React__default["default"].createElement(EquationEditorModal, {
|
|
25368
26293
|
ref: function ref(r) {
|