@zzish/math-rich-input 0.1.57 → 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 +469 -77
- 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 +269 -29
- package/src/Toolbar.jsx +29 -15
- package/src/mathRichInputHelper.js +7 -3
package/dist/index.js
CHANGED
|
@@ -18886,7 +18886,7 @@ var EquationEditor = /*#__PURE__*/function (_React$Component) {
|
|
|
18886
18886
|
_classCallCheck(this, EquationEditor);
|
|
18887
18887
|
_this = _callSuper(this, EquationEditor, [props]);
|
|
18888
18888
|
_defineProperty(_this, "handleInsert", function () {
|
|
18889
|
-
_this.handleInsertCallback(_this.
|
|
18889
|
+
_this.handleInsertCallback(_this.latexForInsert());
|
|
18890
18890
|
});
|
|
18891
18891
|
_defineProperty(_this, "handleCancel", function () {
|
|
18892
18892
|
_this.handleCancelCallback();
|
|
@@ -18899,8 +18899,14 @@ var EquationEditor = /*#__PURE__*/function (_React$Component) {
|
|
|
18899
18899
|
});
|
|
18900
18900
|
_defineProperty(_this, "handleKeyDown", function (e) {
|
|
18901
18901
|
try {
|
|
18902
|
+
if (e.key === "Escape") {
|
|
18903
|
+
e.preventDefault();
|
|
18904
|
+
e.stopPropagation();
|
|
18905
|
+
_this.handleCancelCallback();
|
|
18906
|
+
return;
|
|
18907
|
+
}
|
|
18902
18908
|
if (!_this.props.useExpertMode && e.key === "Enter") {
|
|
18903
|
-
_this.handleInsertCallback(_this.
|
|
18909
|
+
_this.handleInsertCallback(_this.latexForInsert());
|
|
18904
18910
|
e.preventDefault();
|
|
18905
18911
|
}
|
|
18906
18912
|
} catch (error) {
|
|
@@ -19073,12 +19079,35 @@ var EquationEditor = /*#__PURE__*/function (_React$Component) {
|
|
|
19073
19079
|
recentSymbolsCount: 0
|
|
19074
19080
|
};
|
|
19075
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;
|
|
19076
19084
|
_this.handleInsertCallback = props.handleInsert;
|
|
19077
19085
|
_this.handleCancelCallback = props.handleCancel;
|
|
19078
19086
|
return _this;
|
|
19079
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
|
+
*/
|
|
19080
19097
|
_inherits(EquationEditor, _React$Component);
|
|
19081
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
|
+
}, {
|
|
19082
19111
|
key: "prettifyLatex",
|
|
19083
19112
|
value: function prettifyLatex(latex) {
|
|
19084
19113
|
// NB: replaceAll not suported on safari
|
|
@@ -19160,6 +19189,12 @@ var EquationEditor = /*#__PURE__*/function (_React$Component) {
|
|
|
19160
19189
|
key: "mathquillDidMount",
|
|
19161
19190
|
value: function mathquillDidMount(mathQuill) {
|
|
19162
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
|
+
}
|
|
19163
19198
|
}
|
|
19164
19199
|
}, {
|
|
19165
19200
|
key: "componentDidMount",
|
|
@@ -19266,8 +19301,11 @@ var EquationEditor = /*#__PURE__*/function (_React$Component) {
|
|
|
19266
19301
|
}, /*#__PURE__*/React__default["default"].createElement("div", {
|
|
19267
19302
|
className: "centerBox"
|
|
19268
19303
|
}, /*#__PURE__*/React__default["default"].createElement(reactMathquill.EditableMathField, {
|
|
19269
|
-
className: "editable"
|
|
19270
|
-
|
|
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, " "),
|
|
19271
19309
|
placeholder: "Type equation ..",
|
|
19272
19310
|
config: {
|
|
19273
19311
|
autoOperatorNames: AUTO_OPERATOR_NAMES
|
|
@@ -19349,6 +19387,9 @@ var EquationEditor = /*#__PURE__*/function (_React$Component) {
|
|
|
19349
19387
|
}(React__default["default"].Component);
|
|
19350
19388
|
|
|
19351
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]';
|
|
19352
19393
|
var EquationEditorModal = /*#__PURE__*/function (_React$Component) {
|
|
19353
19394
|
function EquationEditorModal(props) {
|
|
19354
19395
|
var _this;
|
|
@@ -19358,9 +19399,80 @@ var EquationEditorModal = /*#__PURE__*/function (_React$Component) {
|
|
|
19358
19399
|
_this.handleInsertCallback(latex);
|
|
19359
19400
|
});
|
|
19360
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
|
+
}
|
|
19361
19415
|
_this.handleCloseCallback();
|
|
19362
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
|
+
});
|
|
19363
19474
|
_defineProperty(_this, "focusEquationEditor", function () {
|
|
19475
|
+
if (!_this.mounted || _this.closing) return;
|
|
19364
19476
|
console.log("🔍 Focusing equation editor...");
|
|
19365
19477
|
if (_this.equationEditor) {
|
|
19366
19478
|
console.log("🔍 EquationEditor ref found");
|
|
@@ -19415,15 +19527,36 @@ var EquationEditorModal = /*#__PURE__*/function (_React$Component) {
|
|
|
19415
19527
|
}
|
|
19416
19528
|
_inherits(EquationEditorModal, _React$Component);
|
|
19417
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
|
+
}, {
|
|
19418
19541
|
key: "componentDidMount",
|
|
19419
19542
|
value: function componentDidMount() {
|
|
19420
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;
|
|
19421
19548
|
// Store current scroll position to prevent jumping
|
|
19422
19549
|
this.originalScrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
|
19423
19550
|
|
|
19424
19551
|
// Create portal container if it doesn't exist
|
|
19425
19552
|
this.ensurePortalContainer();
|
|
19426
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
|
+
|
|
19427
19560
|
// Lock body scroll to prevent jumping in transform containers
|
|
19428
19561
|
this.lockBodyScroll();
|
|
19429
19562
|
|
|
@@ -19431,6 +19564,7 @@ var EquationEditorModal = /*#__PURE__*/function (_React$Component) {
|
|
|
19431
19564
|
// Need multiple RAF frames for proper CSS animation timing
|
|
19432
19565
|
requestAnimationFrame(function () {
|
|
19433
19566
|
requestAnimationFrame(function () {
|
|
19567
|
+
if (!_this2.mounted) return;
|
|
19434
19568
|
_this2.setState({
|
|
19435
19569
|
animationReady: true
|
|
19436
19570
|
}, function () {
|
|
@@ -19446,6 +19580,11 @@ var EquationEditorModal = /*#__PURE__*/function (_React$Component) {
|
|
|
19446
19580
|
key: "componentWillUnmount",
|
|
19447
19581
|
value: function componentWillUnmount() {
|
|
19448
19582
|
var _this3 = this;
|
|
19583
|
+
this.mounted = false;
|
|
19584
|
+
if (this.documentKeyListener) {
|
|
19585
|
+
document.removeEventListener("keydown", this.documentKeyListener, true);
|
|
19586
|
+
this.documentKeyListener = null;
|
|
19587
|
+
}
|
|
19449
19588
|
// Hide portal immediately to prevent flash
|
|
19450
19589
|
if (this.portalContainer) {
|
|
19451
19590
|
this.portalContainer.style.visibility = "hidden";
|
|
@@ -19564,6 +19703,10 @@ var EquationEditorModal = /*#__PURE__*/function (_React$Component) {
|
|
|
19564
19703
|
}
|
|
19565
19704
|
}), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
19566
19705
|
className: useClass,
|
|
19706
|
+
role: "dialog",
|
|
19707
|
+
"aria-modal": "true",
|
|
19708
|
+
"aria-label": "Equation Editor",
|
|
19709
|
+
onKeyDown: this.handleKeyDown,
|
|
19567
19710
|
ref: function ref(r) {
|
|
19568
19711
|
return _this5.modalDiv = r;
|
|
19569
19712
|
},
|
|
@@ -19921,7 +20064,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
19921
20064
|
return _this2.handleButtonClick(e, character);
|
|
19922
20065
|
},
|
|
19923
20066
|
onClick: function onClick(e) {
|
|
19924
|
-
|
|
20067
|
+
e.preventDefault();
|
|
20068
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character);
|
|
19925
20069
|
}
|
|
19926
20070
|
}, character);
|
|
19927
20071
|
})), !compactMode && /*#__PURE__*/React__default["default"].createElement("div", null, /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -19967,7 +20111,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
19967
20111
|
return _this2.handleButtonClick(e, character);
|
|
19968
20112
|
},
|
|
19969
20113
|
onClick: function onClick(e) {
|
|
19970
|
-
|
|
20114
|
+
e.preventDefault();
|
|
20115
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character);
|
|
19971
20116
|
}
|
|
19972
20117
|
}, character);
|
|
19973
20118
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -19985,7 +20130,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
19985
20130
|
return _this2.handleButtonClick(e, character, true);
|
|
19986
20131
|
},
|
|
19987
20132
|
onClick: function onClick(e) {
|
|
19988
|
-
|
|
20133
|
+
e.preventDefault();
|
|
20134
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
19989
20135
|
}
|
|
19990
20136
|
}, character);
|
|
19991
20137
|
}))), this.state.selectedTab === "Greek" && /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20005,7 +20151,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20005
20151
|
return _this2.handleButtonClick(e, character, true);
|
|
20006
20152
|
},
|
|
20007
20153
|
onClick: function onClick(e) {
|
|
20008
|
-
|
|
20154
|
+
e.preventDefault();
|
|
20155
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20009
20156
|
}
|
|
20010
20157
|
}, character);
|
|
20011
20158
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20023,7 +20170,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20023
20170
|
return _this2.handleButtonClick(e, character, true);
|
|
20024
20171
|
},
|
|
20025
20172
|
onClick: function onClick(e) {
|
|
20026
|
-
|
|
20173
|
+
e.preventDefault();
|
|
20174
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20027
20175
|
}
|
|
20028
20176
|
}, character);
|
|
20029
20177
|
}))), this.state.selectedTab === "Math" && /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20043,7 +20191,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20043
20191
|
return _this2.handleButtonClick(e, character, true);
|
|
20044
20192
|
},
|
|
20045
20193
|
onClick: function onClick(e) {
|
|
20046
|
-
|
|
20194
|
+
e.preventDefault();
|
|
20195
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20047
20196
|
}
|
|
20048
20197
|
}, character);
|
|
20049
20198
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20061,7 +20210,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20061
20210
|
return _this2.handleButtonClick(e, character, true);
|
|
20062
20211
|
},
|
|
20063
20212
|
onClick: function onClick(e) {
|
|
20064
|
-
|
|
20213
|
+
e.preventDefault();
|
|
20214
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20065
20215
|
}
|
|
20066
20216
|
}, character);
|
|
20067
20217
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20079,7 +20229,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20079
20229
|
return _this2.handleButtonClick(e, character, true);
|
|
20080
20230
|
},
|
|
20081
20231
|
onClick: function onClick(e) {
|
|
20082
|
-
|
|
20232
|
+
e.preventDefault();
|
|
20233
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20083
20234
|
}
|
|
20084
20235
|
}, character);
|
|
20085
20236
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20097,7 +20248,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20097
20248
|
return _this2.handleButtonClick(e, character, true);
|
|
20098
20249
|
},
|
|
20099
20250
|
onClick: function onClick(e) {
|
|
20100
|
-
|
|
20251
|
+
e.preventDefault();
|
|
20252
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20101
20253
|
}
|
|
20102
20254
|
}, character);
|
|
20103
20255
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20115,7 +20267,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20115
20267
|
return _this2.handleButtonClick(e, character, true);
|
|
20116
20268
|
},
|
|
20117
20269
|
onClick: function onClick(e) {
|
|
20118
|
-
|
|
20270
|
+
e.preventDefault();
|
|
20271
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20119
20272
|
}
|
|
20120
20273
|
}, character);
|
|
20121
20274
|
}))), this.state.selectedTab === "Emoticons" && /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20135,7 +20288,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20135
20288
|
return _this2.handleButtonClick(e, character, true);
|
|
20136
20289
|
},
|
|
20137
20290
|
onClick: function onClick(e) {
|
|
20138
|
-
|
|
20291
|
+
e.preventDefault();
|
|
20292
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20139
20293
|
}
|
|
20140
20294
|
}, character);
|
|
20141
20295
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20153,7 +20307,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20153
20307
|
return _this2.handleButtonClick(e, character, true);
|
|
20154
20308
|
},
|
|
20155
20309
|
onClick: function onClick(e) {
|
|
20156
|
-
|
|
20310
|
+
e.preventDefault();
|
|
20311
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20157
20312
|
}
|
|
20158
20313
|
}, character);
|
|
20159
20314
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20171,7 +20326,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20171
20326
|
return _this2.handleButtonClick(e, character, true);
|
|
20172
20327
|
},
|
|
20173
20328
|
onClick: function onClick(e) {
|
|
20174
|
-
|
|
20329
|
+
e.preventDefault();
|
|
20330
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20175
20331
|
}
|
|
20176
20332
|
}, character);
|
|
20177
20333
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20189,7 +20345,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20189
20345
|
return _this2.handleButtonClick(e, character, true);
|
|
20190
20346
|
},
|
|
20191
20347
|
onClick: function onClick(e) {
|
|
20192
|
-
|
|
20348
|
+
e.preventDefault();
|
|
20349
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20193
20350
|
}
|
|
20194
20351
|
}, character);
|
|
20195
20352
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20207,7 +20364,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20207
20364
|
return _this2.handleButtonClick(e, character, true);
|
|
20208
20365
|
},
|
|
20209
20366
|
onClick: function onClick(e) {
|
|
20210
|
-
|
|
20367
|
+
e.preventDefault();
|
|
20368
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20211
20369
|
}
|
|
20212
20370
|
}, character);
|
|
20213
20371
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20225,7 +20383,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20225
20383
|
return _this2.handleButtonClick(e, character, true);
|
|
20226
20384
|
},
|
|
20227
20385
|
onClick: function onClick(e) {
|
|
20228
|
-
|
|
20386
|
+
e.preventDefault();
|
|
20387
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20229
20388
|
}
|
|
20230
20389
|
}, character);
|
|
20231
20390
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20243,7 +20402,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20243
20402
|
return _this2.handleButtonClick(e, character, true);
|
|
20244
20403
|
},
|
|
20245
20404
|
onClick: function onClick(e) {
|
|
20246
|
-
|
|
20405
|
+
e.preventDefault();
|
|
20406
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20247
20407
|
}
|
|
20248
20408
|
}, character);
|
|
20249
20409
|
}))), this.state.selectedTab === "More" && /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20263,7 +20423,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20263
20423
|
return _this2.handleButtonClick(e, character, true);
|
|
20264
20424
|
},
|
|
20265
20425
|
onClick: function onClick(e) {
|
|
20266
|
-
|
|
20426
|
+
e.preventDefault();
|
|
20427
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20267
20428
|
}
|
|
20268
20429
|
}, character);
|
|
20269
20430
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20281,7 +20442,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20281
20442
|
return _this2.handleButtonClick(e, character, true);
|
|
20282
20443
|
},
|
|
20283
20444
|
onClick: function onClick(e) {
|
|
20284
|
-
|
|
20445
|
+
e.preventDefault();
|
|
20446
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20285
20447
|
}
|
|
20286
20448
|
}, character);
|
|
20287
20449
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20299,7 +20461,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20299
20461
|
return _this2.handleButtonClick(e, character, true);
|
|
20300
20462
|
},
|
|
20301
20463
|
onClick: function onClick(e) {
|
|
20302
|
-
|
|
20464
|
+
e.preventDefault();
|
|
20465
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20303
20466
|
}
|
|
20304
20467
|
}, character);
|
|
20305
20468
|
})), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
@@ -20317,7 +20480,8 @@ var AccentBar = /*#__PURE__*/function (_React$Component) {
|
|
|
20317
20480
|
return _this2.handleButtonClick(e, character, true);
|
|
20318
20481
|
},
|
|
20319
20482
|
onClick: function onClick(e) {
|
|
20320
|
-
|
|
20483
|
+
e.preventDefault();
|
|
20484
|
+
if (e.detail === 0) _this2.handleButtonClick(e, character, true);
|
|
20321
20485
|
}
|
|
20322
20486
|
}, character);
|
|
20323
20487
|
})))))));
|
|
@@ -20353,8 +20517,10 @@ var Toolbar = /*#__PURE__*/function (_React$Component) {
|
|
|
20353
20517
|
});
|
|
20354
20518
|
});
|
|
20355
20519
|
_defineProperty(_this, "handleButtonClick", function (event, buttonName) {
|
|
20520
|
+
var _this$props$beforeAct, _this$props;
|
|
20356
20521
|
event.preventDefault();
|
|
20357
20522
|
event.stopPropagation();
|
|
20523
|
+
(_this$props$beforeAct = (_this$props = _this.props).beforeAction) === null || _this$props$beforeAct === void 0 || _this$props$beforeAct.call(_this$props);
|
|
20358
20524
|
_this.suppliedClickHandler(event, buttonName);
|
|
20359
20525
|
});
|
|
20360
20526
|
_defineProperty(_this, "handleAccentButtonClick", function (event, oldCharacter, newCharacter) {
|
|
@@ -20453,87 +20619,89 @@ var Toolbar = /*#__PURE__*/function (_React$Component) {
|
|
|
20453
20619
|
style: style,
|
|
20454
20620
|
ref: function ref(r) {
|
|
20455
20621
|
return _this2.toolbar = r;
|
|
20456
|
-
}
|
|
20622
|
+
},
|
|
20623
|
+
onBlur: this.props.onBlur
|
|
20457
20624
|
}, enableFontStyling && /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement("button", {
|
|
20625
|
+
type: "button",
|
|
20458
20626
|
name: "Bold",
|
|
20627
|
+
"aria-label": "Bold",
|
|
20459
20628
|
className: "Toolbar-button TB-narrow" + (this.props.activeButtons.bold ? " TB-selected" : ""),
|
|
20460
20629
|
onClick: function onClick(e) {
|
|
20461
|
-
return
|
|
20630
|
+
return _this2.handleButtonClick(e, "Bold");
|
|
20462
20631
|
},
|
|
20463
20632
|
onMouseDown: function onMouseDown(e) {
|
|
20464
20633
|
return e.preventDefault();
|
|
20465
|
-
},
|
|
20466
|
-
onMouseUp: function onMouseUp(e) {
|
|
20467
|
-
return _this2.handleButtonClick(e, "Bold");
|
|
20468
20634
|
}
|
|
20469
20635
|
}, /*#__PURE__*/React__default["default"].createElement("b", null, "B")), /*#__PURE__*/React__default["default"].createElement("button", {
|
|
20636
|
+
type: "button",
|
|
20470
20637
|
name: "Italic",
|
|
20638
|
+
"aria-label": "Italic",
|
|
20471
20639
|
className: "Toolbar-button TB-narrow" + (this.props.activeButtons.italic ? " TB-selected" : ""),
|
|
20472
20640
|
onClick: function onClick(e) {
|
|
20473
|
-
return
|
|
20641
|
+
return _this2.handleButtonClick(e, "Italic");
|
|
20474
20642
|
},
|
|
20475
20643
|
onMouseDown: function onMouseDown(e) {
|
|
20476
20644
|
return e.preventDefault();
|
|
20477
|
-
},
|
|
20478
|
-
onMouseUp: function onMouseUp(e) {
|
|
20479
|
-
return _this2.handleButtonClick(e, "Italic");
|
|
20480
20645
|
}
|
|
20481
20646
|
}, /*#__PURE__*/React__default["default"].createElement("i", null, "I")), /*#__PURE__*/React__default["default"].createElement("button", {
|
|
20647
|
+
type: "button",
|
|
20482
20648
|
name: "Underline",
|
|
20649
|
+
"aria-label": "Underline",
|
|
20483
20650
|
className: "Toolbar-button TB-narrow" + (this.props.activeButtons.underline ? " TB-selected" : ""),
|
|
20484
20651
|
onClick: function onClick(e) {
|
|
20485
|
-
return
|
|
20652
|
+
return _this2.handleButtonClick(e, "Underline");
|
|
20486
20653
|
},
|
|
20487
20654
|
onMouseDown: function onMouseDown(e) {
|
|
20488
20655
|
return e.preventDefault();
|
|
20489
|
-
},
|
|
20490
|
-
onMouseUp: function onMouseUp(e) {
|
|
20491
|
-
return _this2.handleButtonClick(e, "Underline");
|
|
20492
20656
|
}
|
|
20493
20657
|
}, /*#__PURE__*/React__default["default"].createElement("u", null, "U")), /*#__PURE__*/React__default["default"].createElement("button", {
|
|
20658
|
+
type: "button",
|
|
20494
20659
|
name: "Superscript",
|
|
20660
|
+
"aria-label": "Superscript",
|
|
20495
20661
|
className: "Toolbar-button TB-narrow" + (this.props.activeButtons.superscript ? " TB-selected" : ""),
|
|
20496
20662
|
onClick: function onClick(e) {
|
|
20497
|
-
return
|
|
20663
|
+
return _this2.handleButtonClick(e, "Superscript");
|
|
20498
20664
|
},
|
|
20499
20665
|
onMouseDown: function onMouseDown(e) {
|
|
20500
20666
|
return e.preventDefault();
|
|
20501
|
-
},
|
|
20502
|
-
onMouseUp: function onMouseUp(e) {
|
|
20503
|
-
return _this2.handleButtonClick(e, "Superscript");
|
|
20504
20667
|
}
|
|
20505
20668
|
}, "a", /*#__PURE__*/React__default["default"].createElement("sup", null, "x")), /*#__PURE__*/React__default["default"].createElement("button", {
|
|
20669
|
+
type: "button",
|
|
20506
20670
|
name: "Subscript",
|
|
20671
|
+
"aria-label": "Subscript",
|
|
20507
20672
|
className: "Toolbar-button TB-narrow" + (this.props.activeButtons.subscript ? " TB-selected" : ""),
|
|
20508
20673
|
onClick: function onClick(e) {
|
|
20509
|
-
return
|
|
20674
|
+
return _this2.handleButtonClick(e, "Subscript");
|
|
20510
20675
|
},
|
|
20511
20676
|
onMouseDown: function onMouseDown(e) {
|
|
20512
20677
|
return e.preventDefault();
|
|
20513
|
-
},
|
|
20514
|
-
onMouseUp: function onMouseUp(e) {
|
|
20515
|
-
return _this2.handleButtonClick(e, "Subscript");
|
|
20516
20678
|
}
|
|
20517
20679
|
}, "a", /*#__PURE__*/React__default["default"].createElement("sub", null, "x"))), /*#__PURE__*/React__default["default"].createElement("button", {
|
|
20680
|
+
type: "button",
|
|
20518
20681
|
name: "Accents",
|
|
20682
|
+
"aria-label": "Accents",
|
|
20683
|
+
"aria-expanded": this.state.showAccents,
|
|
20519
20684
|
className: "Toolbar-button TB-narrow" + (this.state.showAccents ? " TB-selected" : ""),
|
|
20520
20685
|
onMouseDown: function onMouseDown(e) {
|
|
20521
20686
|
return e.preventDefault();
|
|
20522
20687
|
},
|
|
20523
20688
|
onClick: function onClick(e) {
|
|
20524
|
-
|
|
20525
|
-
|
|
20526
|
-
|
|
20527
|
-
|
|
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);
|
|
20528
20694
|
}
|
|
20529
20695
|
}, "\xE1"), enableMath && /*#__PURE__*/React__default["default"].createElement("button", {
|
|
20696
|
+
type: "button",
|
|
20530
20697
|
name: "Equation",
|
|
20698
|
+
"aria-label": "Insert equation",
|
|
20531
20699
|
className: "Toolbar-button TB-wide",
|
|
20532
20700
|
onClick: function onClick(e) {
|
|
20533
|
-
return
|
|
20701
|
+
return _this2.handleButtonClick(e, "Equation");
|
|
20534
20702
|
},
|
|
20535
20703
|
onMouseDown: function onMouseDown(e) {
|
|
20536
|
-
return
|
|
20704
|
+
return e.preventDefault();
|
|
20537
20705
|
}
|
|
20538
20706
|
}, /*#__PURE__*/React__default["default"].createElement("div", {
|
|
20539
20707
|
dangerouslySetInnerHTML: {
|
|
@@ -20825,6 +20993,8 @@ function getMark() {
|
|
|
20825
20993
|
return MARK$1;
|
|
20826
20994
|
}
|
|
20827
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;
|
|
20828
20998
|
return node.className === "katex" || node.className === "katex-error";
|
|
20829
20999
|
}
|
|
20830
21000
|
function isTextNode(node) {
|
|
@@ -21530,7 +21700,6 @@ function getRangeParams(editableDiv) {
|
|
|
21530
21700
|
}
|
|
21531
21701
|
var selection = window.getSelection();
|
|
21532
21702
|
if (selection.rangeCount === 0) {
|
|
21533
|
-
console.error("Can't get range params, window.getSelection did not return any ranges");
|
|
21534
21703
|
return null;
|
|
21535
21704
|
}
|
|
21536
21705
|
var range = selection.getRangeAt(0);
|
|
@@ -23526,6 +23695,9 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
23526
23695
|
try {
|
|
23527
23696
|
// console.log("handleInput")
|
|
23528
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;
|
|
23529
23701
|
var transaction = _this2.pendingTransaction;
|
|
23530
23702
|
_this2.pendingTransaction = null;
|
|
23531
23703
|
debugMathRichInput("handleInput:start", {
|
|
@@ -24006,7 +24178,9 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24006
24178
|
var moveCursorOnInsert = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
24007
24179
|
var node = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
24008
24180
|
try {
|
|
24181
|
+
var _node;
|
|
24009
24182
|
var rangeParams = _this2._getRangeParams();
|
|
24183
|
+
var hasNode = node !== null && node !== undefined;
|
|
24010
24184
|
debugMathRichInput("showEquationEditor:start", {
|
|
24011
24185
|
moveCursorOnInsert: moveCursorOnInsert,
|
|
24012
24186
|
nodeProvided: Boolean(node),
|
|
@@ -24015,8 +24189,27 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24015
24189
|
innerHTML: _this2.editableDiv ? _this2.editableDiv.innerHTML : null,
|
|
24016
24190
|
selection: getSelectionSnapshot(_this2.editableDiv)
|
|
24017
24191
|
});
|
|
24018
|
-
|
|
24019
|
-
|
|
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
|
+
});
|
|
24020
24213
|
_this2.setOldRangeParams({
|
|
24021
24214
|
startNodeIndex: 2,
|
|
24022
24215
|
startOffset: 1,
|
|
@@ -24024,6 +24217,9 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24024
24217
|
endOffset: 1
|
|
24025
24218
|
});
|
|
24026
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;
|
|
24027
24223
|
_this2.moveCursorOnInsert = moveCursorOnInsert;
|
|
24028
24224
|
_this2.setState({
|
|
24029
24225
|
showEquationEditor: true,
|
|
@@ -24033,7 +24229,14 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24033
24229
|
}
|
|
24034
24230
|
var latex = "";
|
|
24035
24231
|
var offset = 0;
|
|
24036
|
-
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
|
+
}
|
|
24037
24240
|
|
|
24038
24241
|
// console.log(rangeParams)
|
|
24039
24242
|
// console.log(this.editableDiv.childNodes)
|
|
@@ -24053,7 +24256,7 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24053
24256
|
_this2.editingNode = node;
|
|
24054
24257
|
} else {
|
|
24055
24258
|
latex = "";
|
|
24056
|
-
offset = rangeParams.startOffset;
|
|
24259
|
+
offset = rangeParams ? rangeParams.startOffset : 0;
|
|
24057
24260
|
_this2.editingExistingEquation = false;
|
|
24058
24261
|
_this2.editingNode = null;
|
|
24059
24262
|
}
|
|
@@ -24081,6 +24284,7 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24081
24284
|
_this2.isMouseDownInEditable = false;
|
|
24082
24285
|
}, 0);
|
|
24083
24286
|
_this2.showEquationEditorOnMouseUp = false;
|
|
24287
|
+
_this2.equationEditorMouseDownKatexIndex = -1;
|
|
24084
24288
|
var node = null;
|
|
24085
24289
|
try {
|
|
24086
24290
|
node = event.target;
|
|
@@ -24096,6 +24300,11 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24096
24300
|
return;
|
|
24097
24301
|
}
|
|
24098
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);
|
|
24099
24308
|
// Save current range parameters so that we can restore them later if we wish
|
|
24100
24309
|
_this2.setOldRangeParams(_this2._getRangeParams());
|
|
24101
24310
|
|
|
@@ -24114,6 +24323,25 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24114
24323
|
|
|
24115
24324
|
// Clear selection anchor on mouse click
|
|
24116
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
|
+
}
|
|
24117
24345
|
|
|
24118
24346
|
// A click that lands with the selection outside this field — a toolbar button, another field —
|
|
24119
24347
|
// gives no range at all. Dereferenced unguarded, this threw on every such click.
|
|
@@ -24126,11 +24354,6 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24126
24354
|
console.warn("Start or end node was null");
|
|
24127
24355
|
return;
|
|
24128
24356
|
}
|
|
24129
|
-
if (params.startNodeIndex === params.endNodeIndex && params.startOffset === params.endOffset && _this2.showEquationEditorOnMouseUp) {
|
|
24130
|
-
_this2.editableDiv.focus();
|
|
24131
|
-
_this2.showEquationEditor(false, startNode);
|
|
24132
|
-
return;
|
|
24133
|
-
}
|
|
24134
24357
|
|
|
24135
24358
|
// If our range starts or ends inside a katex node, move it out
|
|
24136
24359
|
var new_rangeParams = null;
|
|
@@ -24151,6 +24374,10 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24151
24374
|
new_rangeParams.endOffset = SMALL_SPACE_LENGTH;
|
|
24152
24375
|
}
|
|
24153
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;
|
|
24154
24381
|
_this2._setRangeParams(new_rangeParams);
|
|
24155
24382
|
event.preventDefault();
|
|
24156
24383
|
return;
|
|
@@ -24184,6 +24411,27 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24184
24411
|
innerHTML: _this2.editableDiv ? _this2.editableDiv.innerHTML : null,
|
|
24185
24412
|
selection: getSelectionSnapshot(_this2.editableDiv)
|
|
24186
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
|
+
}
|
|
24187
24435
|
var start_pos = _this2.markedRawText.indexOf(MARK);
|
|
24188
24436
|
var end_pos = _this2.markedRawText.indexOf(MARK, start_pos + MARK.length);
|
|
24189
24437
|
var oldRangeParams = _this2.getOldRangeParams();
|
|
@@ -24304,6 +24552,9 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24304
24552
|
// }
|
|
24305
24553
|
_defineProperty(_this2, "styleText", function (event, style) {
|
|
24306
24554
|
try {
|
|
24555
|
+
_this2.initialiseHistory();
|
|
24556
|
+
_this2.resetHistoryRedo();
|
|
24557
|
+
_this2.formatCommandActive = true;
|
|
24307
24558
|
style = style.toLowerCase();
|
|
24308
24559
|
var command = _this2.getStyleCommand(style);
|
|
24309
24560
|
var activeBefore = _this2.getActiveButtonsFromSelection();
|
|
@@ -24311,12 +24562,14 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24311
24562
|
var isCollapsed = selection === null || selection.rangeCount === 0 || selection.getRangeAt(0).collapsed;
|
|
24312
24563
|
var success = false;
|
|
24313
24564
|
var insertedTypingStylePlaceholder = false;
|
|
24565
|
+
var publishedByWhitespaceMove = false;
|
|
24314
24566
|
|
|
24315
24567
|
// This first part is a workaround whereby executing subscript or superscript
|
|
24316
24568
|
// within an existing subscript or superscript makes the text even smaller instead
|
|
24317
24569
|
// of toggling it off. Thus we manually toggle it off with some jigerry pokery!
|
|
24318
24570
|
if (isCollapsed && activeBefore[style] && _this2.moveTrailingWhitespaceOutsideInlineStyle(style, command)) {
|
|
24319
24571
|
success = true;
|
|
24572
|
+
publishedByWhitespaceMove = true;
|
|
24320
24573
|
} else if (isCollapsed && !activeBefore[style] && selection && selection.rangeCount > 0) {
|
|
24321
24574
|
success = _this2.insertInlineStylePlaceholder(style);
|
|
24322
24575
|
insertedTypingStylePlaceholder = success;
|
|
@@ -24339,7 +24592,7 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24339
24592
|
}
|
|
24340
24593
|
var rangeParams = _this2._getRangeParams();
|
|
24341
24594
|
if (!insertedTypingStylePlaceholder) _this2.cleanupEmptyInlineFormattingElements();
|
|
24342
|
-
if (rangeParams !== null && rangeParams !== undefined) {
|
|
24595
|
+
if (!publishedByWhitespaceMove && rangeParams !== null && rangeParams !== undefined) {
|
|
24343
24596
|
_this2._setRangeParams(rangeParams);
|
|
24344
24597
|
_this2.applyCurrentEditableDomToComponent(rangeParams, {
|
|
24345
24598
|
edit: {
|
|
@@ -24359,6 +24612,8 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24359
24612
|
return success;
|
|
24360
24613
|
} catch (error) {
|
|
24361
24614
|
console.error(error);
|
|
24615
|
+
} finally {
|
|
24616
|
+
_this2.formatCommandActive = false;
|
|
24362
24617
|
}
|
|
24363
24618
|
});
|
|
24364
24619
|
_defineProperty(_this2, "handleToolbarButtonClick", function (event, buttonName) {
|
|
@@ -24750,12 +25005,21 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24750
25005
|
currentRangeParams = null;
|
|
24751
25006
|
}
|
|
24752
25007
|
var savedRangeParams = _this2.getOldRangeParams();
|
|
24753
|
-
|
|
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);
|
|
24754
25017
|
debugMathRichInput("handleFocus:start", {
|
|
24755
25018
|
propsValue: _this2.props.value,
|
|
24756
25019
|
oldRangeParams: _this2.oldRangeParams,
|
|
24757
25020
|
currentRangeParams: currentRangeParams,
|
|
24758
25021
|
shouldRestoreSavedRange: shouldRestoreSavedRange,
|
|
25022
|
+
shouldMoveToEnd: shouldMoveToEnd,
|
|
24759
25023
|
innerHTML: _this2.editableDiv ? _this2.editableDiv.innerHTML : null,
|
|
24760
25024
|
selection: getSelectionSnapshot(_this2.editableDiv)
|
|
24761
25025
|
});
|
|
@@ -24769,6 +25033,22 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24769
25033
|
if (shouldRestoreSavedRange) {
|
|
24770
25034
|
_this2._setRangeParams(savedRangeParams);
|
|
24771
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);
|
|
24772
25052
|
}
|
|
24773
25053
|
debugMathRichInput("handleFocus:after-setState", {
|
|
24774
25054
|
selection: getSelectionSnapshot(_this2.editableDiv)
|
|
@@ -24779,11 +25059,12 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24779
25059
|
}
|
|
24780
25060
|
});
|
|
24781
25061
|
_defineProperty(_this2, "handleBlur", function (event) {
|
|
25062
|
+
var _this2$toolbar;
|
|
24782
25063
|
var onBlur = _this2.props.onBlur;
|
|
24783
25064
|
var currentRangeParams = null;
|
|
24784
25065
|
try {
|
|
24785
25066
|
currentRangeParams = _this2._getRangeParams();
|
|
24786
|
-
if (
|
|
25067
|
+
if (currentRangeParams !== null) {
|
|
24787
25068
|
_this2.setOldRangeParams(currentRangeParams);
|
|
24788
25069
|
}
|
|
24789
25070
|
} catch (error) {
|
|
@@ -24796,6 +25077,9 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
24796
25077
|
innerHTML: _this2.editableDiv ? _this2.editableDiv.innerHTML : null,
|
|
24797
25078
|
selection: getSelectionSnapshot(_this2.editableDiv)
|
|
24798
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;
|
|
24799
25083
|
if (onBlur != null) {
|
|
24800
25084
|
onBlur();
|
|
24801
25085
|
}
|
|
@@ -25009,6 +25293,14 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
25009
25293
|
_this2.isMouseDownInEditable = false;
|
|
25010
25294
|
_this2.lastRenderedEditableHtml = null;
|
|
25011
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;
|
|
25012
25304
|
_this2.lastSetActiveButtons = null;
|
|
25013
25305
|
_this2.onChangeCallback = _this2.props.onChange;
|
|
25014
25306
|
|
|
@@ -25196,6 +25488,39 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
25196
25488
|
endGlobalOffset: null
|
|
25197
25489
|
});
|
|
25198
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
|
+
}
|
|
25199
25524
|
}, {
|
|
25200
25525
|
key: "getEditableHtmlForRender",
|
|
25201
25526
|
value: function getEditableHtmlForRender(html) {
|
|
@@ -25224,8 +25549,12 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
25224
25549
|
this.preserveNativeDomRangeParams = preserveRangeParams;
|
|
25225
25550
|
return liveEditableHtml;
|
|
25226
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;
|
|
25227
25557
|
this.lastRenderedEditableHtml = html;
|
|
25228
|
-
this.preserveNativeDomRangeParams = null;
|
|
25229
25558
|
return html;
|
|
25230
25559
|
}
|
|
25231
25560
|
}, {
|
|
@@ -25727,19 +26056,70 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
25727
26056
|
if (this.preserveNativeDomRangeParams !== null && this.preserveNativeDomRangeParams !== undefined && this.state.hasFocus === true) {
|
|
25728
26057
|
var rangeParams = this.preserveNativeDomRangeParams;
|
|
25729
26058
|
this.preserveNativeDomRangeParams = null;
|
|
25730
|
-
|
|
25731
|
-
|
|
25732
|
-
|
|
25733
|
-
|
|
25734
|
-
this.
|
|
25735
|
-
|
|
25736
|
-
|
|
25737
|
-
|
|
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
|
+
}
|
|
25738
26073
|
}
|
|
25739
26074
|
} catch (error) {
|
|
25740
26075
|
console.error(error);
|
|
25741
26076
|
}
|
|
25742
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
|
+
}
|
|
25743
26123
|
}, {
|
|
25744
26124
|
key: "insertAfterSmallSpace",
|
|
25745
26125
|
value: function insertAfterSmallSpace(new_char, rangeParams) {
|
|
@@ -25861,6 +26241,20 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
25861
26241
|
className: "MathRichInput-hint",
|
|
25862
26242
|
"aria-hidden": "true"
|
|
25863
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
|
+
},
|
|
25864
26258
|
className: "Toolbar",
|
|
25865
26259
|
enableMath: this.enableMath(),
|
|
25866
26260
|
enableFontStyling: this.enableFontStyling(),
|
|
@@ -25893,9 +26287,7 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
|
|
|
25893
26287
|
onBlur: this.handleBlur,
|
|
25894
26288
|
onCompositionStart: this.handleCompositionStart,
|
|
25895
26289
|
onCompositionEnd: this.handleCompositionEnd,
|
|
25896
|
-
dangerouslySetInnerHTML:
|
|
25897
|
-
__html: editableHtml
|
|
25898
|
-
},
|
|
26290
|
+
dangerouslySetInnerHTML: this.editableHtmlProp(editableHtml),
|
|
25899
26291
|
"data-placeholder": this.props.placeholder || ""
|
|
25900
26292
|
}))), this.state.showEquationEditor && /*#__PURE__*/React__default["default"].createElement(EquationEditorModal, {
|
|
25901
26293
|
ref: function ref(r) {
|