@drghaliasri/butex 5.5.0 → 5.5.2

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.
@@ -196,7 +196,7 @@ var CommandNode = class extends BaseAstNode {
196
196
  arabicLatex() {
197
197
  const sup = this.superscript !== null ? this.superscript.arabicLatex() : "";
198
198
  const sub = this.subscript !== null ? this.subscript.arabicLatex() : "";
199
- const arabicName = this.name === "\\sqrt" ? "\\arabsqrt" : this.name;
199
+ const arabicName = this.name === "\\sqrt" || this.name === "\\arabsqrt" ? "\\arsqrt" : this.name;
200
200
  const content = renderCommandCore({
201
201
  name: arabicName,
202
202
  optionalArgs: this.optionalArgs,
@@ -2195,7 +2195,7 @@ function renderNodeArabic(node, options) {
2195
2195
  return arabicScripts(node, content, options);
2196
2196
  }
2197
2197
  if (node.kind === "sqrt" && node.radicand) {
2198
- const content = `\\arabsqrt${optionalRootIndexArabic(node, options)}{${renderChainArabic(node.radicand, options)}}`;
2198
+ const content = `\\arsqrt${optionalRootIndexArabic(node, options)}{${renderChainArabic(node.radicand, options)}}`;
2199
2199
  return arabicScripts(node, content, options);
2200
2200
  }
2201
2201
  if (node.kind === "overset" && node.baseExpr) {
@@ -5696,7 +5696,8 @@ ${BUTEX_FONT_FACE_CSS}
5696
5696
  transition: box-shadow 0.15s ease, border-color 0.15s ease;
5697
5697
  }
5698
5698
 
5699
- .surface:focus {
5699
+ .surface:focus,
5700
+ .surface.surface--typing-focus {
5700
5701
  border-color: var(--butex-focus-border, rgba(13, 148, 136, 0.45));
5701
5702
  box-shadow: 0 0 0 3px var(--butex-focus-shadow, rgba(13, 148, 136, 0.12));
5702
5703
  }
@@ -5898,7 +5899,7 @@ function injectBuTeXEditorStyles(doc) {
5898
5899
 
5899
5900
  // src/editor/runtime.ts
5900
5901
  function createEditorRuntime(options) {
5901
- const { surfaceEl } = options;
5902
+ const { surfaceEl, inputEl } = options;
5902
5903
  const buttonElements = options.buttonElements ?? {};
5903
5904
  const outsidePointerIgnoreSelectors = options.outsidePointerIgnoreSelectors ?? [];
5904
5905
  let session = options.initialSession ?? createStarterSession();
@@ -5912,6 +5913,23 @@ function createEditorRuntime(options) {
5912
5913
  let dragSelecting = false;
5913
5914
  let dragChainId = null;
5914
5915
  let dragChanged = false;
5916
+ let composingInput = false;
5917
+ let pendingCompositionText = null;
5918
+ function resetInputElement() {
5919
+ if (!inputEl) {
5920
+ return;
5921
+ }
5922
+ inputEl.value = "";
5923
+ }
5924
+ function focusInput() {
5925
+ if (!inputEl) {
5926
+ surfaceEl.focus();
5927
+ return;
5928
+ }
5929
+ inputEl.focus({ preventScroll: true });
5930
+ const end = inputEl.value.length;
5931
+ inputEl.setSelectionRange(end, end);
5932
+ }
5915
5933
  function notifySessionChange() {
5916
5934
  options.onSessionChange?.(session);
5917
5935
  }
@@ -6176,7 +6194,7 @@ function createEditorRuntime(options) {
6176
6194
  event.preventDefault();
6177
6195
  event.stopPropagation();
6178
6196
  startDragSelection(chainId, index);
6179
- surfaceEl.focus();
6197
+ focusInput();
6180
6198
  });
6181
6199
  slot.addEventListener("click", (event) => {
6182
6200
  if (dragChanged) {
@@ -6186,7 +6204,7 @@ function createEditorRuntime(options) {
6186
6204
  return;
6187
6205
  }
6188
6206
  applyTransient((prev) => setCaret(prev, chainId, index));
6189
- surfaceEl.focus();
6207
+ focusInput();
6190
6208
  });
6191
6209
  if (session.caret.chainId === chainId && session.caret.index === index) {
6192
6210
  const caret = document.createElement("span");
@@ -6218,7 +6236,7 @@ function createEditorRuntime(options) {
6218
6236
  event.preventDefault();
6219
6237
  event.stopPropagation();
6220
6238
  startDragSelection(chainId, indexInChain);
6221
- surfaceEl.focus();
6239
+ focusInput();
6222
6240
  });
6223
6241
  nodeEl.addEventListener("click", (event) => {
6224
6242
  if (dragChanged) {
@@ -6229,7 +6247,7 @@ function createEditorRuntime(options) {
6229
6247
  }
6230
6248
  event.stopPropagation();
6231
6249
  applyTransient((prev) => selectNode(prev, node.id));
6232
- surfaceEl.focus();
6250
+ focusInput();
6233
6251
  });
6234
6252
  const body = document.createElement("span");
6235
6253
  body.className = "node-body";
@@ -6264,7 +6282,7 @@ function createEditorRuntime(options) {
6264
6282
  const activeTree = session[activeTreeKey(session.activeSide)];
6265
6283
  surfaceEl.appendChild(buildChain(activeTree));
6266
6284
  if (initialKeyboardFocusPending) {
6267
- requestAnimationFrame(() => surfaceEl.focus());
6285
+ requestAnimationFrame(focusInput);
6268
6286
  initialKeyboardFocusPending = false;
6269
6287
  }
6270
6288
  notifySessionChange();
@@ -6302,7 +6320,7 @@ function createEditorRuntime(options) {
6302
6320
  }
6303
6321
  session = restored;
6304
6322
  render();
6305
- surfaceEl.focus();
6323
+ focusInput();
6306
6324
  }
6307
6325
  function performRedo() {
6308
6326
  const restored = restoreRedo(undoRedo, session);
@@ -6311,9 +6329,12 @@ function createEditorRuntime(options) {
6311
6329
  }
6312
6330
  session = restored;
6313
6331
  render();
6314
- surfaceEl.focus();
6332
+ focusInput();
6315
6333
  }
6316
6334
  function onKeyDown(event) {
6335
+ if (event.isComposing || event.key === "Process" || event.keyCode === 229) {
6336
+ return;
6337
+ }
6317
6338
  const shortcutMod = event.ctrlKey || event.metaKey;
6318
6339
  const keyLower = typeof event.key === "string" ? event.key.toLowerCase() : "";
6319
6340
  if (shortcutMod && !event.altKey && keyLower === "z") {
@@ -6412,6 +6433,70 @@ function createEditorRuntime(options) {
6412
6433
  applyStructural((prev) => insertChar(prev, char));
6413
6434
  }
6414
6435
  }
6436
+ function onBeforeInput(event) {
6437
+ if (composingInput || event.isComposing) {
6438
+ return;
6439
+ }
6440
+ if (event.inputType === "deleteContentBackward") {
6441
+ event.preventDefault();
6442
+ applyStructural((prev) => deleteBackward(prev));
6443
+ resetInputElement();
6444
+ return;
6445
+ }
6446
+ if (event.inputType === "deleteContentForward") {
6447
+ event.preventDefault();
6448
+ applyStructural((prev) => deleteForward(prev));
6449
+ resetInputElement();
6450
+ }
6451
+ }
6452
+ function onInput(event) {
6453
+ if (!inputEl || composingInput) {
6454
+ return;
6455
+ }
6456
+ const inputEvent = event;
6457
+ const text = inputEvent.data ?? inputEl.value;
6458
+ resetInputElement();
6459
+ if (pendingCompositionText !== null && (inputEvent.inputType === "insertFromComposition" || text === pendingCompositionText)) {
6460
+ pendingCompositionText = null;
6461
+ return;
6462
+ }
6463
+ pendingCompositionText = null;
6464
+ if (inputEvent.inputType === "deleteContentBackward") {
6465
+ applyStructural((prev) => deleteBackward(prev));
6466
+ return;
6467
+ }
6468
+ if (inputEvent.inputType === "deleteContentForward") {
6469
+ applyStructural((prev) => deleteForward(prev));
6470
+ return;
6471
+ }
6472
+ if (text) {
6473
+ applyStructural((prev) => pasteText(prev, text));
6474
+ }
6475
+ }
6476
+ function onCompositionStart() {
6477
+ composingInput = true;
6478
+ }
6479
+ function onCompositionEnd(event) {
6480
+ if (!inputEl) {
6481
+ return;
6482
+ }
6483
+ composingInput = false;
6484
+ const text = event.data || inputEl.value;
6485
+ resetInputElement();
6486
+ if (text) {
6487
+ applyStructural((prev) => pasteText(prev, text));
6488
+ }
6489
+ pendingCompositionText = text || null;
6490
+ window.setTimeout(() => {
6491
+ pendingCompositionText = null;
6492
+ }, 0);
6493
+ }
6494
+ function onInputFocus() {
6495
+ surfaceEl.classList.add("surface--typing-focus");
6496
+ }
6497
+ function onInputBlur() {
6498
+ surfaceEl.classList.remove("surface--typing-focus");
6499
+ }
6415
6500
  function isShortcutOnlyEvent(event) {
6416
6501
  if (!(event.ctrlKey || event.metaKey) || event.altKey) {
6417
6502
  return false;
@@ -6461,7 +6546,7 @@ function createEditorRuntime(options) {
6461
6546
  }
6462
6547
  event.preventDefault();
6463
6548
  startDragSelection(resolved.chainId, resolved.slotIndex);
6464
- surfaceEl.focus();
6549
+ focusInput();
6465
6550
  }
6466
6551
  function onSurfaceClick(event) {
6467
6552
  if (dragChanged) {
@@ -6478,7 +6563,7 @@ function createEditorRuntime(options) {
6478
6563
  } else {
6479
6564
  clearSelectionAndNodeHighlights();
6480
6565
  }
6481
- surfaceEl.focus();
6566
+ focusInput();
6482
6567
  }
6483
6568
  function onDocumentPointerDown(event) {
6484
6569
  const target = event.target;
@@ -6494,6 +6579,13 @@ function createEditorRuntime(options) {
6494
6579
  clearSelectionAndNodeHighlights();
6495
6580
  }
6496
6581
  surfaceEl.addEventListener("keydown", onKeyDown);
6582
+ inputEl?.addEventListener("keydown", onKeyDown);
6583
+ inputEl?.addEventListener("beforeinput", onBeforeInput);
6584
+ inputEl?.addEventListener("input", onInput);
6585
+ inputEl?.addEventListener("compositionstart", onCompositionStart);
6586
+ inputEl?.addEventListener("compositionend", onCompositionEnd);
6587
+ inputEl?.addEventListener("focus", onInputFocus);
6588
+ inputEl?.addEventListener("blur", onInputBlur);
6497
6589
  document.addEventListener("keydown", onDocumentKeyDown);
6498
6590
  document.addEventListener("mouseup", endDragSelection);
6499
6591
  document.addEventListener("mouseleave", endDragSelection);
@@ -6505,6 +6597,13 @@ function createEditorRuntime(options) {
6505
6597
  render,
6506
6598
  destroy: () => {
6507
6599
  surfaceEl.removeEventListener("keydown", onKeyDown);
6600
+ inputEl?.removeEventListener("keydown", onKeyDown);
6601
+ inputEl?.removeEventListener("beforeinput", onBeforeInput);
6602
+ inputEl?.removeEventListener("input", onInput);
6603
+ inputEl?.removeEventListener("compositionstart", onCompositionStart);
6604
+ inputEl?.removeEventListener("compositionend", onCompositionEnd);
6605
+ inputEl?.removeEventListener("focus", onInputFocus);
6606
+ inputEl?.removeEventListener("blur", onInputBlur);
6508
6607
  document.removeEventListener("keydown", onDocumentKeyDown);
6509
6608
  document.removeEventListener("mouseup", endDragSelection);
6510
6609
  document.removeEventListener("mouseleave", endDragSelection);
@@ -6525,6 +6624,7 @@ function createEditorRuntime(options) {
6525
6624
  uiLocale = locale;
6526
6625
  render();
6527
6626
  },
6627
+ focusInput,
6528
6628
  performUndo,
6529
6629
  performRedo,
6530
6630
  performCopy,
@@ -6532,27 +6632,27 @@ function createEditorRuntime(options) {
6532
6632
  performPaste,
6533
6633
  toggleSide: () => {
6534
6634
  applyTransient((prev) => switchSide(prev));
6535
- surfaceEl.focus();
6635
+ focusInput();
6536
6636
  },
6537
6637
  toggleSplitLeafTyping: () => {
6538
6638
  applyStructural((prev) => setSplitLeafTyping(prev, !prev.splitLeafTyping));
6539
- surfaceEl.focus();
6639
+ focusInput();
6540
6640
  },
6541
6641
  toggleArabicReverseNumberTyping: () => {
6542
6642
  applyStructural((prev) => setArabicReverseNumberTyping(prev, !prev.arabicReverseNumberTyping));
6543
- surfaceEl.focus();
6643
+ focusInput();
6544
6644
  },
6545
6645
  toggleTakweenCharacterFont: () => {
6546
6646
  applyTransient((prev) => toggleTakweenCharacterFont(prev));
6547
- surfaceEl.focus();
6647
+ focusInput();
6548
6648
  },
6549
6649
  setCurrentCharacterFont: (fontId) => {
6550
6650
  applyTransient((prev) => setCurrentCharacterFont(prev, fontId));
6551
- surfaceEl.focus();
6651
+ focusInput();
6552
6652
  },
6553
6653
  setCurrentDigitForm: (digitForm) => {
6554
6654
  applyStructural((prev) => setCurrentDigitForm(prev, digitForm));
6555
- surfaceEl.focus();
6655
+ focusInput();
6556
6656
  },
6557
6657
  insertDelimiterByKind: (kind) => {
6558
6658
  if (kind === "paren") {
@@ -6562,79 +6662,79 @@ function createEditorRuntime(options) {
6562
6662
  } else {
6563
6663
  applyStructural((prev) => insertDelimiterPair(prev, "\\left\\{", "\\right\\}"));
6564
6664
  }
6565
- surfaceEl.focus();
6665
+ focusInput();
6566
6666
  },
6567
6667
  insertFraction: () => {
6568
6668
  applyStructural((prev) => insertFraction(prev));
6569
- surfaceEl.focus();
6669
+ focusInput();
6570
6670
  },
6571
6671
  insertFirstDerivative: () => {
6572
6672
  applyStructural((prev) => insertFirstDerivative(prev));
6573
- surfaceEl.focus();
6673
+ focusInput();
6574
6674
  },
6575
6675
  insertSecondDerivative: () => {
6576
6676
  applyStructural((prev) => insertSecondDerivative(prev));
6577
- surfaceEl.focus();
6677
+ focusInput();
6578
6678
  },
6579
6679
  insertMatrixEnv: (style, rows, columns) => {
6580
6680
  applyStructural((prev) => insertMatrixEnv(prev, style, rows, columns));
6581
- surfaceEl.focus();
6681
+ focusInput();
6582
6682
  },
6583
6683
  insertArrayEnv: (rows, columns) => {
6584
6684
  applyStructural((prev) => insertArrayEnv(prev, rows, columns));
6585
- surfaceEl.focus();
6685
+ focusInput();
6586
6686
  },
6587
6687
  insertAlignedEnv: (rows, columns) => {
6588
6688
  applyStructural((prev) => insertAlignedEnv(prev, rows, columns));
6589
- surfaceEl.focus();
6689
+ focusInput();
6590
6690
  },
6591
6691
  insertSqrt: () => {
6592
6692
  applyStructural((prev) => insertSqrt(prev));
6593
- surfaceEl.focus();
6693
+ focusInput();
6594
6694
  },
6595
6695
  insertOverset: () => {
6596
6696
  applyStructural((prev) => insertOverset(prev));
6597
- surfaceEl.focus();
6697
+ focusInput();
6598
6698
  },
6599
6699
  insertUnderset: () => {
6600
6700
  applyStructural((prev) => insertUnderset(prev));
6601
- surfaceEl.focus();
6701
+ focusInput();
6602
6702
  },
6603
6703
  insertLimitsSeriesTemplate: (commandId) => {
6604
6704
  applyStructural((prev) => insertLimitsSeriesTemplate(prev, commandId));
6605
- surfaceEl.focus();
6705
+ focusInput();
6606
6706
  },
6607
6707
  insertAccentPair: () => {
6608
6708
  applyStructural((prev) => insertAccentPair(prev));
6609
- surfaceEl.focus();
6709
+ focusInput();
6610
6710
  },
6611
6711
  insertAccent: (accentId) => {
6612
6712
  applyStructural((prev) => insertAccent(prev, accentId));
6613
- surfaceEl.focus();
6713
+ focusInput();
6614
6714
  },
6615
6715
  insertAtomicCommand: (commandId) => {
6616
6716
  applyStructural((prev) => insertAtomicCommand(prev, commandId));
6617
- surfaceEl.focus();
6717
+ focusInput();
6618
6718
  },
6619
6719
  insertAtomicOperatorCommand: (commandId) => {
6620
6720
  applyStructural((prev) => insertAtomicOperatorCommand(prev, commandId));
6621
- surfaceEl.focus();
6721
+ focusInput();
6622
6722
  },
6623
6723
  addSup: () => {
6624
6724
  applyStructural((prev) => addSup(prev));
6625
- surfaceEl.focus();
6725
+ focusInput();
6626
6726
  },
6627
6727
  addSub: () => {
6628
6728
  applyStructural((prev) => addSub(prev));
6629
- surfaceEl.focus();
6729
+ focusInput();
6630
6730
  },
6631
6731
  removeSup: () => {
6632
6732
  applyStructural((prev) => removeSup(prev));
6633
- surfaceEl.focus();
6733
+ focusInput();
6634
6734
  },
6635
6735
  removeSub: () => {
6636
6736
  applyStructural((prev) => removeSub(prev));
6637
- surfaceEl.focus();
6737
+ focusInput();
6638
6738
  },
6639
6739
  setMatrixEnvStyle: (style) => {
6640
6740
  applyStructural((prev) => setMatrixEnvStyle(prev, style));
@@ -6656,7 +6756,7 @@ function createEditorRuntime(options) {
6656
6756
  },
6657
6757
  deleteStructure: () => {
6658
6758
  applyStructural((prev) => deleteStructure(prev));
6659
- surfaceEl.focus();
6759
+ focusInput();
6660
6760
  }
6661
6761
  };
6662
6762
  render();
@@ -6918,7 +7018,7 @@ function commandToEditorNode(node) {
6918
7018
  }
6919
7019
  return { editable: true, node: frac };
6920
7020
  }
6921
- if ((node.name === "\\sqrt" || node.name === "\\arabsqrt") && node.mandatoryArgs.length >= 1) {
7021
+ if ((node.name === "\\sqrt" || node.name === "\\arabsqrt" || node.name === "\\arsqrt") && node.mandatoryArgs.length >= 1) {
6922
7022
  const sqrt = createSqrtNode();
6923
7023
  const radicand = chainToEditorChain(node.mandatoryArgs[0]);
6924
7024
  if (!radicand.editable) {
@@ -8199,6 +8299,22 @@ var WIDGET_CHROME_CSS = `
8199
8299
  padding: 10px 12px;
8200
8300
  }
8201
8301
 
8302
+ .butex-widget .butex-editor-input-bridge {
8303
+ border: 0;
8304
+ font-size: 16px;
8305
+ height: 1px;
8306
+ margin: 0;
8307
+ max-height: 1px;
8308
+ min-height: 1px;
8309
+ opacity: 0;
8310
+ overflow: hidden;
8311
+ padding: 0;
8312
+ pointer-events: none;
8313
+ position: absolute;
8314
+ resize: none;
8315
+ width: 1px;
8316
+ }
8317
+
8202
8318
  .butex-widget .toolbar {
8203
8319
  display: flex;
8204
8320
  flex-wrap: wrap;
@@ -9205,6 +9321,7 @@ var ButexEditor = (0, import_react.forwardRef)(
9205
9321
  const messages = equationEditorMessages(uiLocale);
9206
9322
  const wrapperRef = (0, import_react.useRef)(null);
9207
9323
  const surfaceRef = (0, import_react.useRef)(null);
9324
+ const inputRef = (0, import_react.useRef)(null);
9208
9325
  const mathOutputRef = (0, import_react.useRef)(null);
9209
9326
  const renderErrorRef = (0, import_react.useRef)(null);
9210
9327
  const latexLinesRef = (0, import_react.useRef)(null);
@@ -9316,6 +9433,7 @@ ${arabic || currentMessages.empty}`;
9316
9433
  }
9317
9434
  const runtime = createEditorRuntime({
9318
9435
  surfaceEl,
9436
+ inputEl: inputRef.current,
9319
9437
  initialSession,
9320
9438
  defaultSide,
9321
9439
  uiLocale,
@@ -9357,7 +9475,7 @@ ${arabic || currentMessages.empty}`;
9357
9475
  } else {
9358
9476
  runtime.render();
9359
9477
  }
9360
- surfaceEl.focus();
9478
+ runtime.focusInput();
9361
9479
  return () => {
9362
9480
  runtime.destroy();
9363
9481
  runtimeRef.current = null;
@@ -9371,7 +9489,7 @@ ${arabic || currentMessages.empty}`;
9371
9489
  }
9372
9490
  }, [uiLocale]);
9373
9491
  function focusSurface() {
9374
- surfaceRef.current?.focus();
9492
+ runtimeRef.current?.focusInput();
9375
9493
  }
9376
9494
  function insertSelectedEnvironment(rows, columns) {
9377
9495
  if (envPaletteMode === "array") {
@@ -10449,6 +10567,20 @@ ${arabic || currentMessages.empty}`;
10449
10567
  "aria-label": messages.equationEditor
10450
10568
  }
10451
10569
  ),
10570
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
10571
+ "textarea",
10572
+ {
10573
+ ref: inputRef,
10574
+ className: "butex-editor-input-bridge",
10575
+ "aria-label": messages.equationEditor,
10576
+ autoCapitalize: "none",
10577
+ autoComplete: "off",
10578
+ autoCorrect: "off",
10579
+ inputMode: "text",
10580
+ spellCheck: false,
10581
+ tabIndex: -1
10582
+ }
10583
+ ),
10452
10584
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: renderErrorRef, className: "error", hidden: true })
10453
10585
  ] }),
10454
10586
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("section", { className: "panel panel-preview", "aria-label": messages.renderPreview, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: mathOutputRef, className: "preview-box" }) }),