@zzish/math-rich-input 0.1.25 → 0.1.27

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 CHANGED
@@ -18167,6 +18167,18 @@ var LATEX_SYMBOLS = [// {name:"Times",latex:"\\times",tooltip:"Times [#X)"},
18167
18167
  buttonLatex: "\\oint",
18168
18168
  tooltip: "Contour integral",
18169
18169
  moveCursor: -2
18170
+ }, {
18171
+ name: "Surface integral",
18172
+ latex: "\\oiint_{#}^{#}",
18173
+ buttonLatex: "\\oiint",
18174
+ tooltip: "Surface integral",
18175
+ moveCursor: -2
18176
+ }, {
18177
+ name: "Volume integral",
18178
+ latex: "\\oiiint_{#}^{#}",
18179
+ buttonLatex: "\\oiiint",
18180
+ tooltip: "Volume integral",
18181
+ moveCursor: -2
18170
18182
  }, {
18171
18183
  name: "Integral a b",
18172
18184
  latex: "\\int_{#}^{#}",
@@ -18235,6 +18247,11 @@ var LATEX_SYMBOLS = [// {name:"Times",latex:"\\times",tooltip:"Times [#X)"},
18235
18247
  latex: "\\pm",
18236
18248
  buttonLatex: "\\pm",
18237
18249
  tooltip: "Plus or minus"
18250
+ }, {
18251
+ name: "Minus or plus",
18252
+ latex: "\\mp",
18253
+ buttonLatex: "\\mp",
18254
+ tooltip: "Minus or plus"
18238
18255
  }, {
18239
18256
  name: "Times",
18240
18257
  latex: "\\times",
@@ -18620,7 +18637,7 @@ var BUTTON_AREAS = {
18620
18637
  "Common": ["Squared", "Power", "Subscript", "Over", "Surd", "Root", "Nth root", "Hat", "Line", "Ray", "Line segment", "Dot", "dxdy", "Partial dxdy", "Integral a b", "Sum a b", "Product a b", "Right arrow", "Infinity", "Limit x to infinity"],
18621
18638
  "Operators": ["Plus", "Minus", "Center dot", "Times", "Divide", "Equals", "Less than", "Greater than", "Not equal", "Less than or equal", "Greater than or equal", "Plus or minus", "Proportionate", "Approximately", "Implies"],
18622
18639
  "Angles": ["degree", "theta", "phi", "pi", "alpha", "beta", "gamma", "delta", "epsilon", "Delta", "angle", "Parallel", "Perpendicular", "Similar", "Congruent"],
18623
- "GreekLower": ["alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta", "theta", "iota", "kappa", "lambda", "mu", "nu", "xi", "omicron", "pi", "rho", "sigma", "tau", "upsilon", "phi", "chi", "psi", "omega"],
18640
+ "GreekLower": ["alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta", "theta", "iota", "kappa", "lambda", "mu", "nu", "xi", "omicron", "pi", "rho", "sigma", "tau", "upsilon", "phi", "varphi", "chi", "psi", "omega"],
18624
18641
  "GreekUpper": ["Gamma", "Delta", "Theta", "Lambda", "Xi", "Pi", "Sigma", "Phi", "Psi", "Omega", "nabla"],
18625
18642
  "Sets": ["cup", "cap", "in", "notin", "emptyset", "forall", "exists", "nexists", "subset", "subseteq", "supset", "supseteq", "nsubset", "nsubseteq", "neg", "Complex numbers", "Natural numbers", "Rational numbers", "Real numbers", "Integers"],
18626
18643
  "Misc": ["because", "therefore", "dots", "cdots", "ll", "gg", "leftarrow", "leftrightarrow", "Leftrightarrow", "mapsto", "bullet", "circ", "Box", "bigcirc", "bigtriangleup", "bigtriangledown", "heartsuit", "diamondsuit", "clubsuit", "spadesuit"],
@@ -18633,8 +18650,8 @@ var BUTTON_AREAS = {
18633
18650
  // "_Cu"]
18634
18651
  "Physics1": ["Squared", "Power", "Subscript", "Over", "Root", "Nth root", "Surd", "Root a over b", "Half", "Third", "Over root 2", "Over root 3", "sum", "delta", "Delta", "Capacitor discharge", "Radioactive decay", "Attenuation of rays", "Delta x over delta t", "dxdt"],
18635
18652
  "Physics2": ["Plus", "Minus", "Plus or minus", "Times", "Equals", "Approximately", "Proportionate"],
18636
- "Physics3": ["alpha", "varepsilon", "eta", "gamma", "lambda", "omega", "mu", "nu", "pi", "rho", "sigma", "phi", "varPhi", "theta", "overline{v_e}", "overline{v_\\mu}", "Subscript zero", "Subscript max", "Subscript min", "Subscript rms"],
18637
- "Expert": ["langle", "rangle", "Double integral", "Triple integral", "Contour integral", "Double dot", "Widehat", "Check", "Tilde", "Mathring", "Right arrow with text", "rightleftharpoons"],
18653
+ "Physics3": ["alpha", "varepsilon", "eta", "gamma", "lambda", "omega", "mu", "nu", "pi", "rho", "sigma", "phi", "Phi", "theta", "overline{v_e}", "overline{v_\\mu}", "Subscript zero", "Subscript max", "Subscript min", "Subscript rms"],
18654
+ "Expert": ["langle", "rangle", "Double integral", "Triple integral", "Contour integral", "Surface integral", "Volume integral", "Double dot", "Widehat", "Check", "Tilde", "Mathring", "Right arrow with text", "rightleftharpoons", "Minus or plus"],
18638
18655
  "Matrices": ["1-vector", "1x2 matrix", "1x3 matrix", "2-vector", "2x2 matrix", "2x3 matrix", "3-vector", "3x2 matrix", "3x3 matrix", "cdots", "vdots", "ddots", "vec{a}", "2x2 matrix round brackets", "2x2 matrix curly brackets"]
18639
18656
  };
18640
18657
 
@@ -18690,10 +18707,16 @@ function toDict(symbols) {
18690
18707
  return dict;
18691
18708
  }
18692
18709
 
18693
- var LATEX_SYMBOLS_DICT = toDict(LATEX_SYMBOLS);
18694
- var NORMAL_SYMBOLS_DICT = toDict(NORMAL_SYMBOLS);
18710
+ var LATEX_SYMBOLS_DICT = null;
18711
+ var NORMAL_SYMBOLS_DICT = null;
18712
+
18713
+ function initialise() {
18714
+ LATEX_SYMBOLS_DICT = toDict(LATEX_SYMBOLS);
18715
+ NORMAL_SYMBOLS_DICT = toDict(NORMAL_SYMBOLS);
18716
+ }
18695
18717
 
18696
18718
  function getSymbolData(name) {
18719
+ if (LATEX_SYMBOLS_DICT === null) initialise();
18697
18720
  if (name in LATEX_SYMBOLS_DICT) return LATEX_SYMBOLS_DICT[name];
18698
18721
  if (name in NORMAL_SYMBOLS_DICT) return NORMAL_SYMBOLS_DICT[name];
18699
18722
 
@@ -20699,7 +20722,7 @@ var SPAN_OPEN_BASE = "<span class=\"base\">";
20699
20722
  var SPAN_CLOSE = "</span>";
20700
20723
  var MARK$1 = String.fromCharCode(0); // const MARK = "_M_A_R_K_"
20701
20724
 
20702
- var MARK_REG_EXP$1 = new RegExp(MARK$1, "g");
20725
+ var MARK_REG_EXP = new RegExp(MARK$1, "g");
20703
20726
  var TEMP_CHAR = String.fromCharCode(1);
20704
20727
  var TEMP_CHAR_REG_EXP = new RegExp(TEMP_CHAR, "g");
20705
20728
  var DOLLAR_SLASH_REG_EXP = /\\\$/g;
@@ -20713,6 +20736,9 @@ var MIME_TYPE_HTML$1 = "text/html";
20713
20736
  var MIME_TYPE_TEX$1 = "application/x-tex";
20714
20737
  var MIME_TYPE_LATEX = "application/x-latex";
20715
20738
  var MIME_TYPE_ZZISH_HTML_MATH$1 = "application/x-zzish-html-math";
20739
+ function getMark() {
20740
+ return MARK$1;
20741
+ }
20716
20742
  function isKatexNode(node) {
20717
20743
  return node.className === "katex" || node.className === "katex-error";
20718
20744
  }
@@ -20724,7 +20750,8 @@ function isTextNode(node) {
20724
20750
  function isBIUNode(node) {
20725
20751
  if (node.nodeType !== 1) return false;
20726
20752
  var tagName = node.tagName.toLowerCase();
20727
- return tagName === "b" || tagName === "i" || tagName === "u" || tagName === "sup" || tagName === "sub" || tagName === "p";
20753
+ if (tagName === "span") return !isKatexNode(node);
20754
+ return tagName === "b" || tagName === "strong" || tagName === "i" || tagName === "em" || tagName === "u" || tagName === "sup" || tagName === "sub" || tagName === "p";
20728
20755
  }
20729
20756
 
20730
20757
  function isBrNode(node) {
@@ -20732,13 +20759,18 @@ function isBrNode(node) {
20732
20759
  return node.tagName.toLowerCase() === "br";
20733
20760
  }
20734
20761
 
20762
+ function nodeStartsWithSmallSpace(node) {
20763
+ if (node.nodeType === 3 && node.nodeValue.length >= 1 && node.nodeValue.charCodeAt(0) === SMALL_SPACE_CHAR_CODE$1) return true;
20764
+ return false;
20765
+ }
20766
+
20735
20767
  function isSmallSpace(node) {
20736
20768
  if (node.nodeType === 3 && node.nodeValue.length === 1 && node.nodeValue.charCodeAt(0) === SMALL_SPACE_CHAR_CODE$1) return true;
20737
20769
  return false;
20738
20770
  }
20739
20771
 
20740
- function startsWithSmallSpace(node) {
20741
- var textNode = findFirstTextNode(node);
20772
+ function startsWithSmallSpace(editableDiv) {
20773
+ var textNode = findFirstTextNode(editableDiv);
20742
20774
  return isSmallSpace(textNode);
20743
20775
  }
20744
20776
  function countNodeTypes(node) {
@@ -20782,7 +20814,7 @@ function getNodeTextLength(node) {
20782
20814
  return text.length;
20783
20815
  }
20784
20816
  function removeMarks(raw_text) {
20785
- return raw_text.replace(MARK_REG_EXP$1, "");
20817
+ return raw_text.replace(MARK_REG_EXP, "");
20786
20818
  }
20787
20819
  function getCharacterBeforeMarks(text) {
20788
20820
  var start = text.indexOf(MARK$1);
@@ -20960,8 +20992,6 @@ function addTextForNode(node, arrayOfText) {
20960
20992
  try {
20961
20993
  if (isTextNode(node)) {
20962
20994
  addText(arrayOfText, useHtmlMath ? encodeToHtml(node.nodeValue) : encodeToLatex(node.nodeValue), mark, offset, useHtmlMath);
20963
- } else if (isBrNode(node)) {
20964
- useHtmlMath && arrayOfText.push("<br>");
20965
20995
  } else if (isBIUNode(node)) {
20966
20996
  useHtmlMath && arrayOfText.push("<" + node.nodeName + ">");
20967
20997
 
@@ -21097,8 +21127,12 @@ function renderLatexString(katex, s, t) {
21097
21127
  return renderedString;
21098
21128
  }
21099
21129
  function rawTextToHtml(katex, string, mimeType) {
21100
- if (string === "") return "";
21101
- if (mimeType === null || mimeType === undefined || mimeType === "") mimeType = determineMimeType(string);
21130
+ if (string === "") return "<p>" + SMALL_SPACE$1 + "</p>";
21131
+
21132
+ if (mimeType == null || mimeType === "") {
21133
+ mimeType = determineMimeType(string);
21134
+ }
21135
+
21102
21136
  if (mimeType === MIME_TYPE_PLAIN_TEXT$1) return encodeToHtml(string);
21103
21137
  var parseAsTex;
21104
21138
  if (mimeType === MIME_TYPE_TEX$1 || mimeType === MIME_TYPE_LATEX) parseAsTex = true;else if (mimeType === MIME_TYPE_HTML$1 || mimeType === MIME_TYPE_ZZISH_HTML_MATH$1) parseAsTex = false;else {
@@ -21256,6 +21290,94 @@ function findNodeWithIndex(node, index) {
21256
21290
 
21257
21291
  return null;
21258
21292
  }
21293
+
21294
+ function findGlobalOffset(node, nodeToFind, offset) {
21295
+ var result = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
21296
+ // console.log(node.nodeType+":"+node.nodeValue+" === "+ nodeToFind.nodeType+":"+nodeToFind.nodeValue)
21297
+ // console.log(node === nodeToFind)
21298
+ if (result === null || result === undefined) throw error;
21299
+
21300
+ if (node === nodeToFind) {
21301
+ result.offset = result.offset + offset; // console.log("result.offset now: "+result.offset)
21302
+
21303
+ if (isTextNode(node) && nodeStartsWithSmallSpace(node)) {
21304
+ if (offset > 0) result.offset = result.offset - 1;
21305
+ }
21306
+
21307
+ return true;
21308
+ }
21309
+
21310
+ if (isKatexNode(node)) {
21311
+ if (node === nodeToFind || node.contains(nodeToFind)) return true;else {
21312
+ result.offset++;
21313
+ return false;
21314
+ }
21315
+ }
21316
+
21317
+ if (isTextNode(node)) {
21318
+ result.offset += node.nodeValue.length;
21319
+ if (nodeStartsWithSmallSpace(node)) result.offset -= 1;
21320
+ return false;
21321
+ }
21322
+
21323
+ var childNodes = node.childNodes;
21324
+ if (childNodes === null || childNodes === undefined) return false;
21325
+
21326
+ for (var i = 0; i < childNodes.length; i++) {
21327
+ var child = childNodes[i]; // console.log("Checking child:"+child.nodeType+":"+child.tagName+":"+child.nodeValue)
21328
+
21329
+ var found = findGlobalOffset(child, nodeToFind, offset, result);
21330
+ if (found) return true;
21331
+ }
21332
+
21333
+ if (node.nodeType === 1 && node.tagName === "P") {
21334
+ result.offset++;
21335
+ }
21336
+
21337
+ return false;
21338
+ }
21339
+
21340
+ function findNodeAndOffsetForGlobalOffset(node, globalOffset) {
21341
+ var result = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
21342
+
21343
+ if (isKatexNode(node)) {
21344
+ result.node = null;
21345
+ result.offset++;
21346
+ return false;
21347
+ }
21348
+
21349
+ if (isTextNode(node)) {
21350
+ result.node = node;
21351
+ result.lastTextNode = node;
21352
+ result.offset += node.nodeValue.length;
21353
+ if (nodeStartsWithSmallSpace(node)) result.offset -= 1; // console.log("result.offset now: "+result.offset)
21354
+
21355
+ return false;
21356
+ }
21357
+
21358
+ var childNodes = node.childNodes;
21359
+ if (childNodes === null || childNodes === undefined) return false;
21360
+
21361
+ for (var i = 0; i < childNodes.length; i++) {
21362
+ var found = findNodeAndOffsetForGlobalOffset(childNodes[i], globalOffset, result);
21363
+ if (found) return true;
21364
+
21365
+ if (result.node !== null && result.node !== undefined) {
21366
+ if (result.offset >= globalOffset) {
21367
+ result.offset = globalOffset - (result.offset - result.node.nodeValue.length);
21368
+ return true;
21369
+ }
21370
+ }
21371
+ }
21372
+
21373
+ if (node.nodeType === 1 && node.tagName === "P") {
21374
+ result.node = null;
21375
+ result.offset++;
21376
+ }
21377
+
21378
+ return false;
21379
+ }
21380
+
21259
21381
  function findFirstTextNode(node) {
21260
21382
  if (isTextNode(node)) return node;
21261
21383
  var nodes = node.childNodes;
@@ -21266,7 +21388,8 @@ function findFirstTextNode(node) {
21266
21388
  }
21267
21389
 
21268
21390
  return null;
21269
- }
21391
+ } // https://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html
21392
+
21270
21393
  function getRangeParams(editableDiv) {
21271
21394
  // console.log ("getRangeParams")
21272
21395
  // console.log("Inner html: "+editableDiv.innerHTML)
@@ -21284,22 +21407,135 @@ function getRangeParams(editableDiv) {
21284
21407
  return null;
21285
21408
  }
21286
21409
 
21287
- var range = selection.getRangeAt(0);
21410
+ var range = selection.getRangeAt(0); // logAllDescendants(editableDiv)
21411
+ // If the range is not within a text node, move it to a text node
21412
+ // This typically happens when the end of a range is at the start of a new line
21413
+
21414
+ if (range.startContainer.nodeType !== 3) {
21415
+ var textNode = findFirstTextNode(range.startContainer);
21416
+
21417
+ if (textNode !== null) {
21418
+ console.warn("Adjusting start pos in getRangeParams as container was of type: " + range.startContainer.nodeName);
21419
+ range.setStart(textNode, 0);
21420
+ } else {
21421
+ console.error("Unable to getRangeParams. seletion.startContainer is not a text node. " + "Node type: " + range.startContainer.nodeName);
21422
+ return null;
21423
+ }
21424
+ }
21425
+
21426
+ if (range.endContainer.nodeType !== 3) {
21427
+ var _textNode = findFirstTextNode(range.endContainer);
21428
+
21429
+ if (_textNode !== null) {
21430
+ console.warn("Adjusting end pos in getRangeParams as container was of type: " + range.endContainer.nodeName);
21431
+ range.setEnd(_textNode, 0);
21432
+ } else {
21433
+ console.error("Unable to getRangeParams. seletion.endContainer is not a text node. " + "Node type: " + range.endContainer.nodeName);
21434
+ return null;
21435
+ }
21436
+ } // Find the index of the start and end nodes
21437
+
21438
+
21288
21439
  var startNodeIndex = findIndexOfNode(editableDiv, range.startContainer);
21289
21440
  var endNodeIndex = findIndexOfNode(editableDiv, range.endContainer); // console.log(editableDiv)
21290
21441
  // console.log("Start node: "+range.startContainer)
21291
21442
  // console.log("Start node: |"+range.startContainer.nodeValue+"|")
21292
21443
  // console.log("Start node index found: "+startNodeIndex)
21293
21444
  // console.log("Start node offset: "+range.startOffset)
21445
+ // Find the global offset of the start and end nodes
21446
+
21447
+ var startResult = {
21448
+ offset: 0
21449
+ };
21450
+ findGlobalOffset(editableDiv, range.startContainer, range.startOffset, startResult); // console.log("Global offset of start: "+startResult.offset)
21451
+
21452
+ var endResult = {
21453
+ offset: 0
21454
+ };
21455
+ findGlobalOffset(editableDiv, range.endContainer, range.endOffset, endResult); // console.log("Global offset of end: "+endResult.offset)
21294
21456
 
21295
21457
  var rangeParams = {
21296
21458
  startNodeIndex: startNodeIndex,
21297
21459
  startOffset: range.startOffset,
21298
21460
  endNodeIndex: endNodeIndex,
21299
- endOffset: range.endOffset
21461
+ endOffset: range.endOffset,
21462
+ startGlobalOffset: startResult.offset,
21463
+ endGlobalOffset: endResult.offset
21300
21464
  };
21301
21465
  return rangeParams;
21302
21466
  }
21467
+
21468
+ function setRangeParamsFromGlobalOffsets(editableDiv, params) {
21469
+ var new_range = null;
21470
+
21471
+ try {
21472
+ if (params === null || params === undefined) throw new Error("Can't set range params: params === " + params);
21473
+ var startResult = {
21474
+ offset: 0
21475
+ };
21476
+ findNodeAndOffsetForGlobalOffset(editableDiv, params.startGlobalOffset, startResult); // console.log(startResult.node.nodeType+":"+startResult.node.tagName+":"+
21477
+ // startResult.node.nodeValue+":"+startResult.offset)
21478
+
21479
+ var endResult = {
21480
+ offset: 0
21481
+ };
21482
+ findNodeAndOffsetForGlobalOffset(editableDiv, params.endGlobalOffset, endResult); // console.log(endResult.node.nodeType+":"+endResult.node.tagName+":"+
21483
+ // endResult.node.nodeValue+":"+endResult.offset)
21484
+ // So the next bit of code should never be called in principle, but if we have
21485
+ // failed to find an appropriate node (this could happen if the global offset is bigger
21486
+ // than the length of the text in the node), then lets try and fix it
21487
+
21488
+ if (startResult.node === null || endResult.node === null) {
21489
+ console.warn("Can't set range from global offsets, as could not find text nodes");
21490
+ console.log(startResult);
21491
+ console.log(endResult);
21492
+
21493
+ if (startResult.node === null) {
21494
+ if (params.startGlobalOffset > 0 && startResult.lastTextNode !== null) {
21495
+ startResult.node = startResult.lastTextNode;
21496
+ startResult.offset = startResult.lastTextNode.nodeValue.length;
21497
+ } else {
21498
+ startResult.node = findFirstTextNode(editableDiv);
21499
+ startResult.offset = 0;
21500
+ }
21501
+ }
21502
+
21503
+ if (endResult.node === null) {
21504
+ if (params.endGlobalOffset > 0 && endResult.lastTextNode !== null) {
21505
+ endResult.node = endResult.lastTextNode;
21506
+ endResult.offset = endResult.lastTextNode.nodeValue.length;
21507
+ } else {
21508
+ endResult.node = findFirstTextNode(editableDiv);
21509
+ endResult.offset = 0;
21510
+ }
21511
+ }
21512
+ }
21513
+
21514
+ if (startResult.offset === 0 && startResult.node.nodeValue.length > 0 && nodeStartsWithSmallSpace(startResult.node)) {
21515
+ startResult.offset = 1;
21516
+ }
21517
+
21518
+ if (endResult.offset === 0 && endResult.node.nodeValue.length > 0 && nodeStartsWithSmallSpace(endResult.node)) {
21519
+ endResult.offset = 1;
21520
+ } // console.log("Setting range to:")
21521
+ // console.log(startResult.node.nodeType+":"+startResult.node.tagName+":"+
21522
+ // startResult.node.nodeValue+":"+startResult.offset)
21523
+
21524
+
21525
+ new_range = document.createRange();
21526
+ new_range.setStart(startResult.node, startResult.offset);
21527
+ new_range.setEnd(endResult.node, endResult.offset);
21528
+ var selection = window.getSelection();
21529
+ selection.removeAllRanges();
21530
+ selection.addRange(new_range);
21531
+ } catch (error) {
21532
+ console.error(error);
21533
+ console.log("Trying to set range:");
21534
+ console.log(new_range);
21535
+ console.log(editableDiv.childNodes);
21536
+ }
21537
+ }
21538
+
21303
21539
  function setRangeParams(editableDiv, params) {
21304
21540
  // console.log("setRangeParams")
21305
21541
  // console.log(params)
@@ -21311,6 +21547,11 @@ function setRangeParams(editableDiv, params) {
21311
21547
  return;
21312
21548
  }
21313
21549
 
21550
+ if (params.startGlobalOffset) {
21551
+ setRangeParamsFromGlobalOffsets(editableDiv, params);
21552
+ return;
21553
+ }
21554
+
21314
21555
  if (params.startNodeIndex === null || params.startNodeIndex === undefined) {
21315
21556
  console.error("Can't set range params: params.startNodeIndex === " + params.startNodeIndex);
21316
21557
  return;
@@ -21369,7 +21610,7 @@ function setRangeParams(editableDiv, params) {
21369
21610
  }
21370
21611
 
21371
21612
  if (endNode === null) {
21372
- console.error("Could not set range to start node with index " + params.endNodeIndex);
21613
+ console.error("Could not set range to end node with index " + params.endNodeIndex);
21373
21614
  endNode = findFirstTextNode(editableDiv);
21374
21615
  endOffset = 0;
21375
21616
  }
@@ -21386,6 +21627,12 @@ function setRangeParams(editableDiv, params) {
21386
21627
 
21387
21628
  new_range = document.createRange();
21388
21629
  new_range.setStart(startNode, startOffset);
21630
+
21631
+ if (endOffset > endNode.length) {
21632
+ console.warn("endOffset > endNode.length when setting range: " + endOffset + " > " + endNode.length + " - " + endNode.nodeType + " - " + endNode.nodeValue);
21633
+ endOffset = endNode.length;
21634
+ }
21635
+
21389
21636
  new_range.setEnd(endNode, endOffset); // console.log("Setting range")
21390
21637
  // console.log(new_range)
21391
21638
 
@@ -21400,6 +21647,163 @@ function setRangeParams(editableDiv, params) {
21400
21647
  }
21401
21648
  } // https://stackoverflow.com/questions/6659351/removing-all-script-tags-from-html-with-js-regular-expression
21402
21649
 
21650
+ function sanitiseHtmlForElement(element) {
21651
+ if (isTextNode(element)) return document.createTextNode(element.nodeValue);
21652
+
21653
+ if (isKatexNode(element)) {
21654
+ // console.log("Copying katex node")
21655
+ var clone = element.cloneNode(true);
21656
+ return clone;
21657
+ }
21658
+
21659
+ if (element.tagName === "HEAD" || element.tagName === "STYLE" || element.tagName === "LINK") return null;
21660
+ var new_element = null;
21661
+
21662
+ if (isBIUNode(element)) {
21663
+ // console.log("Updating descendent: "+element.textContent)
21664
+ new_element = document.createElement(element.tagName);
21665
+ } else if (element.nodeType === 1 && (element.tagName === "LI" || element.tagName === "DT" || element.tagName === "DD" || element.tagName === "THEAD" || element.tagName === "TR" || element.tagName === "H1" || element.tagName === "H2" || element.tagName === "H3" || element.tagName === "H4" || element.tagName === "H5" || element.tagName === "H6")) {
21666
+ // console.log("Converting descendent: <"+element.tagName+">"+element.textContent)
21667
+ new_element = document.createElement('p');
21668
+ } else {
21669
+ // console.log("Stripping descendent: <"+element.tagName+">"+element.textContent)
21670
+ new_element = document.createElement('span');
21671
+ }
21672
+
21673
+ if (element.hasChildNodes()) {
21674
+ for (var i = 0; i < element.childNodes.length; i++) {
21675
+ var new_child = sanitiseHtmlForElement(element.childNodes[i]);
21676
+ if (new_child !== null) new_element.appendChild(new_child);
21677
+ if (element.childNodes[i].tagName === "TH" || element.childNodes[i].tagName === "TD") new_element.appendChild(document.createTextNode(" "));
21678
+ }
21679
+ }
21680
+
21681
+ return new_element;
21682
+ }
21683
+
21684
+ var SPAN_TAG = new RegExp("<span>|</span>", "g"); // const BR_TAG_REG_EXP = new RegExp("<br[\s\S]*?>","g")
21685
+ // const COMMENT_TAG_REG_EXP = new RegExp("<!--.+?-->","g")
21686
+ // const COMMENT_TAG_REG_EXP = new RegExp("(?=<!--([\s\S]*?)-->","g")
21687
+ // const COMMENT_TAG_REG_EXP = new RegExp("<!--[\s\S]*?-->","gm")
21688
+ // const MULTI_WHITE_SPACE_REG_EXP = new RegExp("\s{2,}","gm")
21689
+
21690
+ var KATEX_START_HTML = "<span class=\"katex\"";
21691
+ var KATEX_END_HTML = "</span></span></span></span>";
21692
+ function sanitiseHtml(s) {
21693
+ // Remove all <br> tags (as some of these can be inside katex tags)
21694
+ s = s.replace(/<br[\s\S]*?>/gm, ""); // console.log("After removing comments:")
21695
+ // console.log(s)
21696
+ // Next, convert all elements to supported elements
21697
+
21698
+ var div = document.createElement('div');
21699
+ div.innerHTML = s;
21700
+ var sanitisedElement = sanitiseHtmlForElement(div);
21701
+ var sanitised = sanitisedElement.innerHTML; // Next, remove all span tags, except those for katex span nodes
21702
+ // NB: A simpler solution may have been to create something other than
21703
+ // span tags in the sanitiseHtmlForElement(div) method and then simply
21704
+ // remove all span tags.
21705
+
21706
+ var i = 0;
21707
+ var j = 0;
21708
+ var its = 0;
21709
+ var output = [];
21710
+
21711
+ do {
21712
+ its++;
21713
+ j = sanitised.indexOf(KATEX_START_HTML, i);
21714
+
21715
+ if (j < 0) {
21716
+ var _part = sanitised.substring(i, sanitised.length);
21717
+
21718
+ _part = _part.replace(SPAN_TAG, "");
21719
+ output.push(_part);
21720
+ break;
21721
+ }
21722
+
21723
+ var part = sanitised.substring(i, j);
21724
+ part = part.replace(SPAN_TAG, "");
21725
+ output.push(part);
21726
+ var k = sanitised.indexOf(KATEX_END_HTML, j) + KATEX_END_HTML.length;
21727
+
21728
+ if (k < 0) {
21729
+ console.warn("Unable to find closing katex tag");
21730
+ k = sanitised.length;
21731
+ }
21732
+
21733
+ output.push(sanitised.substring(j, k));
21734
+ i = k;
21735
+ } while (j > 0 && its < 20);
21736
+
21737
+ sanitised = output.join(""); // Remove new lines
21738
+
21739
+ sanitised = sanitised.replace(/(\r\n|\r|\n)/gm, ""); // new line
21740
+ // Convert any multispaces to a single space
21741
+
21742
+ sanitised = sanitised.replace(/\s{2,}/gm, " "); // 2 or more white spaces
21743
+ // Next, make sure that each line of html is wrapped in paragraph tags
21744
+
21745
+ i = 0;
21746
+ j = 0;
21747
+ its = 0;
21748
+ output = [];
21749
+
21750
+ do {
21751
+ its++;
21752
+ j = sanitised.indexOf("</p>", i);
21753
+
21754
+ if (j < 0) {
21755
+ output.push(sanitised.substring(i, sanitised.length));
21756
+ break;
21757
+ }
21758
+
21759
+ j = j + 4; // Move j four characters to end of </p> tag
21760
+
21761
+ output.push(sanitised.substring(i, j)); // copy as far as </p>
21762
+ // if we have reached the end of the string, finish
21763
+
21764
+ if (j === sanitised.length) break; // if not enough characters for a <p> then can't be a <p>
21765
+
21766
+ if (j + 3 > sanitised.length) {
21767
+ output.push("<p>");
21768
+ output.push(sanitised.substring(j, sanitised.length));
21769
+ output.push("</p>");
21770
+ break;
21771
+ } // If the next characters are the start of a paragraph tag then continue
21772
+
21773
+
21774
+ var nextChars = sanitised.substring(j, j + 3);
21775
+
21776
+ if (nextChars === "<p>") {
21777
+ i = j;
21778
+ continue;
21779
+ } // If the next characters are the start of a katex tag then continue
21780
+
21781
+
21782
+ if (j + KATEX_START_HTML.length < sanitised.length) {
21783
+ nextChars = sanitised.substring(j, j + KATEX_START_HTML.length);
21784
+
21785
+ if (nextChars === KATEX_START_HTML) {
21786
+ i = j;
21787
+ continue;
21788
+ }
21789
+ } // Ok! We have found some html that is not wrapped in a paragraph tag
21790
+ // Lets insert the paragraph tags
21791
+
21792
+
21793
+ output.push("<p>");
21794
+
21795
+ var _k = sanitised.indexOf("<p>", j);
21796
+
21797
+ if (_k < 0) _k = sanitised.length;
21798
+ output.push(sanitised.substring(j, _k));
21799
+ output.push("</p>");
21800
+ i = _k;
21801
+ } while (j > 0 && its < 20);
21802
+
21803
+ sanitised = output.join("");
21804
+ return sanitised;
21805
+ }
21806
+
21403
21807
  var MIME_TYPE_PLAIN_TEXT = "text/plain";
21404
21808
  var MIME_TYPE_HTML = "text/html";
21405
21809
  var MIME_TYPE_TEX = "application/x-tex";
@@ -21408,14 +21812,135 @@ var SMALL_SPACE_CHAR_CODE = 8203;
21408
21812
  var SMALL_SPACE = String.fromCharCode(SMALL_SPACE_CHAR_CODE);
21409
21813
  var SMALL_SPACE_LENGTH = SMALL_SPACE.length; // const SMALL_SPACE_REG_EXP = new RegExp(SMALL_SPACE, "g")
21410
21814
 
21411
- var MARK = "_M_A_R_K_";
21412
- var MARK_REG_EXP = new RegExp(MARK, "g"); // const LATEX_MARKER_START = "<annotation encoding=\"application/x-tex\">"
21815
+ var MARK = getMark();
21413
21816
  // const LATEX_MARKER_END = "</annotation>"
21414
21817
 
21415
21818
  var MAX_HISTORY_LENGTH = 100;
21416
21819
  var DEFAULT_OPTIONS = {
21417
21820
  useExpertMode: false,
21418
21821
  selectedTab: null
21822
+ }; // Consts for creating accented letters in handleKeyDownAccentHelper
21823
+
21824
+ var GRAVE_LETTERS = {
21825
+ a: "à",
21826
+ e: "è",
21827
+ i: "ì",
21828
+ o: "ò",
21829
+ u: "ù",
21830
+ d: "ð",
21831
+ A: "À",
21832
+ E: "È",
21833
+ I: "Ì",
21834
+ O: "Ò",
21835
+ U: "Ù",
21836
+ D: "Ð"
21837
+ };
21838
+ var ACCUTE_LETTERS = {
21839
+ a: "á",
21840
+ e: "é",
21841
+ i: "í",
21842
+ n: "ń",
21843
+ o: "ó",
21844
+ u: "ú",
21845
+ y: "ý",
21846
+ A: "Á",
21847
+ E: "É",
21848
+ I: "Í",
21849
+ N: "Ń",
21850
+ O: "Ó",
21851
+ U: "Ú",
21852
+ Y: "Ý"
21853
+ };
21854
+ var CARET_LETTERS = {
21855
+ a: "â",
21856
+ e: "ê",
21857
+ i: "î",
21858
+ o: "ô",
21859
+ u: "û",
21860
+ A: "Â",
21861
+ E: "Ê",
21862
+ I: "Î",
21863
+ O: "Ô",
21864
+ U: "Û"
21865
+ };
21866
+ var TILDE_LETTERS = {
21867
+ a: "ã",
21868
+ n: "ñ",
21869
+ o: "õ",
21870
+ A: "Ã",
21871
+ N: "Ñ",
21872
+ O: "Õ"
21873
+ };
21874
+ var COLON_LETTERS = {
21875
+ a: "ä",
21876
+ e: "ë",
21877
+ i: "ï",
21878
+ o: "ö",
21879
+ u: "ü",
21880
+ y: "ÿ",
21881
+ A: "Ä",
21882
+ E: "Ë",
21883
+ I: "Ï",
21884
+ O: "Ö",
21885
+ U: "Ü",
21886
+ Y: "Ÿ"
21887
+ };
21888
+ var AT_LETTERS = {
21889
+ a: "å",
21890
+ A: "Å"
21891
+ };
21892
+ var AND_LETTERS = {
21893
+ a: "æ",
21894
+ o: "œ",
21895
+ s: "ß",
21896
+ A: "Æ",
21897
+ O: "Œ",
21898
+ S: "ß"
21899
+ };
21900
+ var COMMA_LETTERS = {
21901
+ c: "ç",
21902
+ C: "Ç"
21903
+ };
21904
+ var SLASH_LETTERS = {
21905
+ o: "ø",
21906
+ O: "Ø"
21907
+ };
21908
+ var MINUS_LETTERS = {
21909
+ a: "ā",
21910
+ e: "ē",
21911
+ i: "ī",
21912
+ o: "ō",
21913
+ u: "ū",
21914
+ A: "Ā",
21915
+ E: "Ē",
21916
+ I: "Ī",
21917
+ O: "Ō",
21918
+ U: "Ū"
21919
+ };
21920
+ var CTRL_ALT_SHIFT_LETTERS = {
21921
+ "?": "¿",
21922
+ "!": "¡",
21923
+ "/": "¿",
21924
+ 1: "¡"
21925
+ }; // Necessary
21926
+
21927
+ var LETTERS = {
21928
+ "`": GRAVE_LETTERS,
21929
+ "'": ACCUTE_LETTERS,
21930
+ '"': ACCUTE_LETTERS,
21931
+ // Necessary
21932
+ "^": CARET_LETTERS,
21933
+ 6: CARET_LETTERS,
21934
+ "~": TILDE_LETTERS,
21935
+ ":": COLON_LETTERS,
21936
+ "@": AT_LETTERS,
21937
+ 2: AT_LETTERS,
21938
+ "&": AND_LETTERS,
21939
+ 7: AND_LETTERS,
21940
+ // Necessary
21941
+ ",": COMMA_LETTERS,
21942
+ "/": SLASH_LETTERS,
21943
+ "-": MINUS_LETTERS
21419
21944
  };
21420
21945
 
21421
21946
  var MathRichInput = /*#__PURE__*/function (_React$Component) {
@@ -21566,14 +22091,17 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
21566
22091
  }
21567
22092
 
21568
22093
  if (deleteToEmpty) {
22094
+ console.log("deleteToEmpty");
21569
22095
  var _new_rangeParams = {
21570
22096
  startNodeIndex: 0,
21571
- startOffset: 0,
22097
+ startOffset: 1,
21572
22098
  endNodeIndex: 0,
21573
- endOffset: 0
22099
+ endOffset: 1,
22100
+ startGlobalOffset: 0,
22101
+ endGlobalOffset: 0
21574
22102
  };
21575
22103
 
21576
- _this2.applyChangesToComponent("", MIME_TYPE_PLAIN_TEXT, _new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab);
22104
+ _this2.applyChangesToComponent("", _this2.getMimeType(false, false), _new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab);
21577
22105
 
21578
22106
  return;
21579
22107
  } // Treat backspace normally in the following situations
@@ -21658,202 +22186,36 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
21658
22186
  _defineProperty(_assertThisInitialized(_this2), "handleKeyDownArrowLeft", function (e) {
21659
22187
  var rangeParams = _this2._getRangeParams();
21660
22188
 
21661
- var index = rangeParams.startNodeIndex;
21662
- var offset = rangeParams.startOffset; // console.log("Old: "+index+"->"+offset)
21663
- // The user shouldn't be in a katex node, but lets deal with it anyway
21664
-
21665
- var node = _this2._findNodeWithIndex(index);
21666
-
21667
- if (isKatexNode(node)) {
21668
- console.warn("Cursor is inside katex node");
21669
-
21670
- var _new_index = index - 1; // Jump out of the latex node
21671
-
21672
-
21673
- var prev_node = _this2._findNodeWithIndex(index - 1);
21674
-
21675
- var _new_offset = getNodeTextLength(prev_node);
21676
-
21677
- var _new_rangeParams2 = {
21678
- startNodeIndex: _new_index,
21679
- startOffset: _new_offset,
21680
- endNodeIndex: _new_index,
21681
- endOffset: _new_offset
21682
- };
21683
-
21684
- _this2._setRangeParams(_new_rangeParams2);
21685
-
21686
- e.preventDefault();
21687
- return;
21688
- }
21689
-
21690
- if (offset > 2) return;
21691
- var new_index = -1;
21692
- var new_offset = -1; // Deal with case of inserted small space at start of <p> element or after katex node
21693
-
21694
- if (offset === 2) {
21695
- new_index = index;
21696
-
21697
- if (_this2.nodeStartsWithSmallSpace(node)) {
21698
- if (index > 0 && isKatexNode(_this2._findNodeWithIndex(index - 1))) new_offset = 1;else new_offset = 0;
21699
- } else new_offset = 1;
21700
- }
21701
-
21702
- if (offset === 1) {
21703
- if (_this2.nodeStartsWithSmallSpace(node)) {
21704
- if (index === 0) {
21705
- e.preventDefault();
21706
- return;
21707
- }
21708
-
21709
- var _prev_node = _this2._findNodeWithIndex(index - 1);
21710
-
21711
- if (index >= 2 && isKatexNode(_prev_node)) new_index = index - 2;else new_index = index - 1;
21712
-
21713
- var new_node = _this2._findNodeWithIndex(new_index);
21714
-
21715
- new_offset = getNodeTextLength(new_node);
21716
- } else {
21717
- new_index = index;
21718
- new_offset = 0;
21719
- }
21720
- }
21721
-
21722
- if (offset === 0) {
21723
- var _prev_node2 = _this2._findNodeWithIndex(index - 1);
21724
-
21725
- if (index >= 2 && isKatexNode(_prev_node2)) new_index = index - 2;else new_index = index - 1;
21726
-
21727
- var _new_node = _this2._findNodeWithIndex(new_index);
21728
-
21729
- new_offset = getNodeTextLength(_new_node);
21730
-
21731
- if (new_offset === 1) {
21732
- if (_this2.nodeStartsWithSmallSpace(_new_node)) {
21733
- if (index > 0 && isKatexNode(_this2._findNodeWithIndex(index - 1))) new_offset = 1;else new_offset = 0;
21734
- }
21735
- }
21736
- } // Move cursor to start of field if in starting small space
21737
-
21738
-
21739
- if (new_index === 0 && new_offset === 1 && _this2.inputStartsWithSmallSpace()) {
21740
- new_offset = 0;
21741
- }
21742
-
21743
- if (new_index === -1 || new_offset === -1) return;
22189
+ rangeParams.startNodeIndex;
22190
+ rangeParams.startOffset;
22191
+ var new_globalOffset = rangeParams.startGlobalOffset - 1;
21744
22192
  var new_rangeParams = {
21745
- startNodeIndex: new_index,
21746
- startOffset: new_offset,
21747
- endNodeIndex: new_index,
21748
- endOffset: new_offset
22193
+ startGlobalOffset: new_globalOffset,
22194
+ endGlobalOffset: new_globalOffset
21749
22195
  };
22196
+ e.preventDefault();
21750
22197
 
21751
22198
  _this2._setRangeParams(new_rangeParams);
21752
22199
 
21753
- e.preventDefault();
22200
+ return; // console.log("Old: "+index+"->"+offset)
21754
22201
  });
21755
22202
 
21756
22203
  _defineProperty(_assertThisInitialized(_this2), "handleKeyDownArrowRight", function (e) {
21757
22204
  // console.log("handleKeyDownArrowRight")
21758
22205
  var rangeParams = _this2._getRangeParams();
21759
22206
 
21760
- var index = rangeParams.startNodeIndex;
21761
- var offset = rangeParams.startOffset;
21762
- if (index < 0) // Empty input field
21763
- return;
21764
-
21765
- var node = _this2._findNodeWithIndex(index);
21766
-
21767
- var length = getNodeTextLength(node); // The user shouldn't be in a katex node, but lets deal with it anyway
21768
-
21769
- if (isKatexNode(node)) {
21770
- console.warn("Cursor is inside katex node");
21771
- var new_index = index + 1; // Jump out of the latex node
21772
-
21773
- var new_offset = SMALL_SPACE_LENGTH; // As there will be a SMALL_SPACE at the start of the text node
21774
-
21775
- var new_rangeParams = {
21776
- startNodeIndex: new_index,
21777
- startOffset: new_offset,
21778
- endNodeIndex: new_index,
21779
- endOffset: new_offset
21780
- };
21781
-
21782
- _this2._setRangeParams(new_rangeParams);
21783
-
21784
- e.preventDefault();
21785
- return;
21786
- } // Deal with case of inserted small space at start of <p> element
21787
-
21788
-
21789
- if (offset === 0) {
21790
- if (_this2.nodeStartsWithSmallSpace(node)) {
21791
- // console.log("Offset = 0 and node starts with small space");
21792
- var _new_index2 = -1;
21793
-
21794
- var _new_offset2 = -1;
21795
-
21796
- if (node.nodeValue.length > 1) {
21797
- _new_index2 = index;
21798
- _new_offset2 = SMALL_SPACE_LENGTH + 1;
21799
- } else {
21800
- _new_index2 = index + 1;
21801
-
21802
- var next_node = _this2._findNodeWithIndex(_new_index2);
21803
-
21804
- if (next_node !== null) {
21805
- if (isKatexNode(next_node)) {
21806
- _new_index2 = index + 2;
21807
- _new_offset2 = SMALL_SPACE_LENGTH;
21808
- } else {
21809
- _new_index2 = index + 1;
21810
- _new_offset2 = 0;
21811
- }
21812
- } else {
21813
- _new_index2 = index;
21814
- _new_offset2 = offset;
21815
- }
21816
- }
21817
-
21818
- var _new_rangeParams3 = {
21819
- startNodeIndex: _new_index2,
21820
- startOffset: _new_offset2,
21821
- endNodeIndex: _new_index2,
21822
- endOffset: _new_offset2
21823
- };
21824
-
21825
- _this2._setRangeParams(_new_rangeParams3);
21826
-
21827
- e.preventDefault();
21828
- return;
21829
- }
21830
- } // If at the end of a text node
21831
-
21832
-
21833
- if (offset === length || index === 0 && _this2.inputStartsWithSmallSpace()) {
21834
- var _next_node = _this2._findNodeWithIndex(index + 1); // If there is no next node, then we can't move, so do the default action
21835
- // If the next node is a normal node, do the default action
21836
-
21837
-
21838
- if (_next_node === null || !isKatexNode(_next_node)) return;
21839
-
21840
- var _new_index3 = index + 2; // Jump over the latex node
21841
-
21842
-
21843
- var _new_offset3 = SMALL_SPACE_LENGTH; // As there will be a SMALL_SPACE at the start of the text node
21844
-
21845
- var _new_rangeParams4 = {
21846
- startNodeIndex: _new_index3,
21847
- startOffset: _new_offset3,
21848
- endNodeIndex: _new_index3,
21849
- endOffset: _new_offset3
21850
- };
22207
+ rangeParams.startNodeIndex;
22208
+ rangeParams.startOffset;
22209
+ var new_globalOffset = rangeParams.startGlobalOffset + 1;
22210
+ var new_rangeParams = {
22211
+ startGlobalOffset: new_globalOffset,
22212
+ endGlobalOffset: new_globalOffset
22213
+ };
22214
+ e.preventDefault();
21851
22215
 
21852
- _this2._setRangeParams(_new_rangeParams4);
22216
+ _this2._setRangeParams(new_rangeParams);
21853
22217
 
21854
- e.preventDefault();
21855
- return;
21856
- }
22218
+ return;
21857
22219
  });
21858
22220
 
21859
22221
  _defineProperty(_assertThisInitialized(_this2), "editableDivIsPlainText", function () {
@@ -21892,10 +22254,18 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
21892
22254
  convert_to_latex = true;
21893
22255
  }
21894
22256
 
21895
- if (!convert_to_latex) return;
21896
- node.nodeValue = node.nodeValue.substring(0, first_dollar_pos) + MARK + node.nodeValue.substring(first_dollar_pos + 1, second_dollar_pos) + MARK + node.nodeValue.substring(second_dollar_pos);
21897
- var raw_text = elementToMarkedRawText(e.target, null, 0, _this2.enableHtml());
21898
- raw_text = raw_text.replace(MARK_REG_EXP, "$"); // We are turning one node into three and want the cursor at the start of the third node
22257
+ if (!convert_to_latex) return; // So we will convert to latex
22258
+ // If we get the raw text without replacing the dollars with marks, the dollars
22259
+ // will be converted to html codes. So we will replace them with marks and then
22260
+ // replace the marks with dollars later
22261
+ // Remove first dollar and insert marks into the node instead of dollars
22262
+
22263
+ var latex = node.nodeValue.substring(first_dollar_pos + 1, second_dollar_pos);
22264
+ node.nodeValue = node.nodeValue.substring(0, first_dollar_pos) + MARK + latex + MARK + node.nodeValue.substring(second_dollar_pos); // Get the raw text and now put the dollars back
22265
+
22266
+ var raw_text = elementToMarkedRawText(e.target, null, 0, _this2.enableHtml()); // now replace the marks with math
22267
+
22268
+ raw_text = replaceMarksWithMath(raw_text, latex, _this2.enableHtml()); // We are turning one node into three and want the cursor at the start of the third node
21899
22269
 
21900
22270
  var new_rangeParams = {
21901
22271
  startNodeIndex: params.startNodeIndex + 2,
@@ -21934,6 +22304,84 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
21934
22304
  e.preventDefault();
21935
22305
  });
21936
22306
 
22307
+ _defineProperty(_assertThisInitialized(_this2), "handleKeyDownAccentHelper", function (e) {
22308
+ // console.log(e.ctrlKey)
22309
+ // console.log(e.altKey)
22310
+ // console.log(e.shiftKey)
22311
+ var new_accent = "";
22312
+ var new_char = ""; // console.log(e.key)
22313
+
22314
+ if (e.ctrlKey) {
22315
+ // First check for CTRL+ALT+SHIFT keys
22316
+ if (e.shiftKey && e.altKey) {
22317
+ console.log(e.key);
22318
+ if (CTRL_ALT_SHIFT_LETTERS.hasOwnProperty(e.key)) new_char = CTRL_ALT_SHIFT_LETTERS[e.key];
22319
+ } // Second check special case of CTRL-tilde
22320
+ else if (e.shiftKey && e.key === "`") new_accent = "~"; // Finally check for normal accent keys
22321
+ else if (LETTERS.hasOwnProperty(e.key)) new_accent = e.key;
22322
+ } else if (_this2.accent !== "") {
22323
+ // Ignore key events for shift and caps lock as that can mean the user
22324
+ // is simply changing to or from capitals and we don't want to reset
22325
+ // this.accent in this case
22326
+ if (e.key === "Shift") return false;
22327
+ if (e.key === "CapsLock") return false; // Get the possible letters that use this accent and test to see if the
22328
+ // current key pressed is one of those letters.
22329
+
22330
+ var letters = LETTERS[_this2.accent];
22331
+ if (letters.hasOwnProperty(e.key)) new_char = letters[e.key];
22332
+ } // If a new accent has been set, store it in this.accent, otherwise clear this.accent
22333
+
22334
+
22335
+ if (new_accent === "") _this2.accent = "";else {
22336
+ e.preventDefault();
22337
+ _this2.accent = new_accent;
22338
+ console.log("Accent set: " + _this2.accent);
22339
+ return true;
22340
+ }
22341
+
22342
+ if (new_char !== "") {
22343
+ // Prevent the original character being insereted
22344
+ e.preventDefault(); // Insert the accented character a the cursor position
22345
+
22346
+ _this2.insertRawText(new_char, false);
22347
+
22348
+ return true;
22349
+ } // Mechanism 2 : Automatically convert a/` into à, for example
22350
+ // if (ACCENT_KEYS.includes(e.key)) {
22351
+ // let pos = e.target.selectionStart
22352
+ // let text = e.target.value
22353
+ // if (pos < 2)
22354
+ // return
22355
+ // if (text.charAt(pos-1) !== '/')
22356
+ // return
22357
+ // let letters = LETTERS[e.key]
22358
+ // let old_letter = text.charAt(pos-2)
22359
+ // if (letters.hasOwnProperty(old_letter)) {
22360
+ // e.preventDefault()
22361
+ // text = text.substring(0,pos-2) + letters[old_letter] + text.substring(pos)
22362
+ // this.setState({value:text},
22363
+ // () => {e.target.selectionStart = e.target.selectionEnd = pos - 1
22364
+ // })
22365
+ // return true
22366
+ // }
22367
+ // }
22368
+ // if (CTRL_ALT_SHIFT_KEYS.includes(e.key)) {
22369
+ // let pos = e.target.selectionStart
22370
+ // let text = e.target.value
22371
+ // if (pos < 1)
22372
+ // return
22373
+ // if (text.charAt(pos-1) !== '/')
22374
+ // return
22375
+ // e.preventDefault()
22376
+ // text = text.substring(0,pos-1) + CTRL_ALT_SHIFT_LETTERS[e.key] + text.substring(pos)
22377
+ // this.setState({value:text},
22378
+ // () => {e.target.selectionStart = e.target.selectionEnd = pos
22379
+ // })
22380
+ // return true
22381
+ // }
22382
+
22383
+ });
22384
+
21937
22385
  _defineProperty(_assertThisInitialized(_this2), "handleKeyDown", function (e) {
21938
22386
  try {
21939
22387
  // Lets set up or update the undo redo history
@@ -21947,23 +22395,41 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
21947
22395
 
21948
22396
  if (!(e.ctrlKey || e.metaKey)) _this2.resetHistoryRedo();
21949
22397
 
21950
- if ((e.metaKey || e.ctrlKey) && (e.key === "b" || e.key === "i" || e.key === "u" || e.key === "6" || e.key === "^" || e.key === "-" || e.key === "_")) {
21951
- if (!_this2.enableHtml()) {
21952
- e.preventDefault();
21953
- return;
21954
- }
21955
-
22398
+ if ((e.metaKey || e.ctrlKey) && (e.key === "b" || e.key === "i" || e.key === "u" || e.key === "6" || e.key === "^" || e.key === "-" || e.key === "_" || e.key === "+" || e.key === "=") && _this2.enableHtml()) {
21956
22399
  if (e.key === "b") _this2.styleText(e, "Bold");
21957
22400
  if (e.key === "i") _this2.styleText(e, "Italic");
21958
- if (e.key === "u") _this2.styleText(e, "Underline");
21959
- if (e.key === "6" || e.key === "^") _this2.styleText(e, "Superscript"); // don't apply subscript if it is the browser command key for "smaller"
22401
+ if (e.key === "u") _this2.styleText(e, "Underline"); // Don't apply superscript is ctrl ^, this is reserved for creating accents
21960
22402
 
21961
- if (/(Win)/i.test(window.navigator.platform) && e.ctrlKey && e.key === "-") return;
21962
- if (/(Mac)/i.test(window.navigator.platform) && e.metaKey && e.key === "-") return; // otherwise
22403
+ if (/(Win)/i.test(window.navigator.platform) && e.ctrlKey && (e.key === "6" || e.key === "^")) return; // otherwise
22404
+
22405
+ if (e.key === "6" || e.key === "^" || e.key === "+" || e.key === "=") _this2.styleText(e, "Superscript"); // Don't apply subscript if it is the browser command key for "smaller"
22406
+ // if (/(Win)/i.test(window.navigator.platform) && e.ctrlKey && e.key === "-")
22407
+ // return
22408
+ // if (/(Mac)/i.test(window.navigator.platform) && e.metaKey && e.key === "-")
22409
+ // return
22410
+ // otherwise
21963
22411
 
21964
22412
  if (e.key === "-" || e.key === "_") _this2.styleText(e, "Subscript");
21965
22413
  e.preventDefault();
21966
22414
  return;
22415
+ }
22416
+
22417
+ if ((e.metaKey || e.ctrlKey) && e.key === "v") {
22418
+ console.log("Executing paste");
22419
+ document.execCommand("paste");
22420
+ return;
22421
+ }
22422
+
22423
+ if ((e.metaKey || e.ctrlKey) && e.key === "c") {
22424
+ console.log("Executing copy");
22425
+ document.execCommand("copy");
22426
+ return;
22427
+ }
22428
+
22429
+ if ((e.metaKey || e.ctrlKey) && e.key === "x") {
22430
+ console.log("Executing cut");
22431
+ document.execCommand("cut");
22432
+ return;
21967
22433
  } // Ignore automatic key repeat presses on Windows so that we can show an accent bar on
21968
22434
  // long key press
21969
22435
 
@@ -22094,11 +22560,15 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22094
22560
  e.preventDefault();
22095
22561
  return;
22096
22562
  }
22097
- } // Check if inserting character in element that starts with small space
22563
+ }
22564
+
22565
+ if (_this2.handleKeyDownAccentHelper(e)) return; // Check if inserting character in element that starts with small space
22098
22566
 
22567
+ if (e.key.length === 1 && // ie, it's not something like "arrowLeft"
22568
+ params.startOffset === 0 && _this2.nodeStartsWithSmallSpace(startNode)) {
22569
+ console.log("Handling character input at start of text node with small space");
22099
22570
 
22100
- if (e.key.length === 1 && params.startOffset === 0 && _this2.nodeStartsWithSmallSpace(startNode)) {
22101
- _this2.replaceNextLetter(e.key);
22571
+ _this2.insertAfterSmallSpace(e.key, params);
22102
22572
 
22103
22573
  e.preventDefault();
22104
22574
  return;
@@ -22176,14 +22646,14 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22176
22646
  _new_offset4 = SMALL_SPACE_LENGTH;
22177
22647
  }
22178
22648
 
22179
- var _new_rangeParams5 = {
22649
+ var _new_rangeParams7 = {
22180
22650
  startNodeIndex: _new_index4,
22181
22651
  startOffset: _new_offset4,
22182
22652
  endNodeIndex: _new_index4,
22183
22653
  endOffset: _new_offset4
22184
22654
  }; // console.log(new_rangeParams)
22185
22655
 
22186
- _this2._setRangeParams(_new_rangeParams5);
22656
+ _this2._setRangeParams(_new_rangeParams7);
22187
22657
  }
22188
22658
  }
22189
22659
  }
@@ -22221,7 +22691,15 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22221
22691
  try {
22222
22692
  var rangeParams = _this2._getRangeParams();
22223
22693
 
22224
- if (rangeParams.startNodeIndex < 0) return;
22694
+ if (rangeParams === null || rangeParams === undefined) {
22695
+ console.warn("Unable to updateActiveButtons. rangeParams: " + rangeParams);
22696
+ return;
22697
+ }
22698
+
22699
+ if (rangeParams.startNodeIndex < 0) {
22700
+ console.warn("Unable to updateActiveButtons. rangeParams.startNodeIndex: " + rangeParams.startNodeIndex);
22701
+ return;
22702
+ }
22225
22703
 
22226
22704
  var node = _this2._findNodeWithIndex(rangeParams.startNodeIndex);
22227
22705
 
@@ -22273,6 +22751,46 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22273
22751
  }
22274
22752
  });
22275
22753
 
22754
+ _defineProperty(_assertThisInitialized(_this2), "handlePaste", function (event) {
22755
+ var clipboardData = event.clipboardData || window.clipboardData;
22756
+
22757
+ if (clipboardData === null || clipboardData === undefined) {
22758
+ console.warn("handlePaste called, but no clipboard data");
22759
+ return;
22760
+ }
22761
+
22762
+ for (var i = 0; i < clipboardData.types.length; i++) {
22763
+ console.log(clipboardData.types[i] + ": " + clipboardData.getData(clipboardData.types[i]));
22764
+ }
22765
+
22766
+ var pasteHtml = clipboardData.getData("text/html");
22767
+
22768
+ if (pasteHtml !== null && pasteHtml.length > 0) {
22769
+ console.log("** Paste html");
22770
+ console.log(pasteHtml);
22771
+ pasteHtml = sanitiseHtml(pasteHtml);
22772
+ console.log("** Santised paste html");
22773
+ console.log(pasteHtml);
22774
+
22775
+ _this2.insertHtml(pasteHtml);
22776
+
22777
+ event.preventDefault();
22778
+ } else {
22779
+ var paste = clipboardData.getData("text");
22780
+ var selection = window.getSelection();
22781
+
22782
+ if (!selection.rangeCount) {
22783
+ console.warn("handlePaste called, but unable to get selection");
22784
+ return false;
22785
+ }
22786
+
22787
+ event.preventDefault();
22788
+ selection.deleteFromDocument();
22789
+
22790
+ _this2.insertRawText(paste);
22791
+ }
22792
+ });
22793
+
22276
22794
  _defineProperty(_assertThisInitialized(_this2), "showEquationEditor", function () {
22277
22795
  var moveCursorOnInsert = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
22278
22796
  var node = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
@@ -22282,8 +22800,6 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22282
22800
 
22283
22801
  if (rangeParams.startNodeIndex < 0) {
22284
22802
  console.error("Could not find position of cursor in node list");
22285
- console.log(rangeParams);
22286
- console.log(_this2.editableDiv.childNodes);
22287
22803
 
22288
22804
  _this2.setOldRangeParams({
22289
22805
  startNodeIndex: 2,
@@ -22359,7 +22875,10 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22359
22875
  node = node.parentNode;
22360
22876
  } while (node !== _this2.editableDiv && node !== null);
22361
22877
 
22362
- if (!isLatex) return;
22878
+ if (!isLatex) {
22879
+ return;
22880
+ }
22881
+
22363
22882
  _this2.showEquationEditorOnMouseUp = true; // Save current range parameters so that we can restore them later if we wish
22364
22883
 
22365
22884
  _this2.setOldRangeParams(_this2._getRangeParams()); // this.editableDiv.focus()
@@ -22478,14 +22997,14 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22478
22997
  }
22479
22998
  }
22480
22999
 
22481
- var _new_rangeParams6 = {
23000
+ var _new_rangeParams8 = {
22482
23001
  startNodeIndex: new_index,
22483
23002
  startOffset: new_offset,
22484
23003
  endNodeIndex: new_index,
22485
23004
  endOffset: new_offset
22486
23005
  };
22487
23006
 
22488
- _this2.setOldRangeParams(_new_rangeParams6);
23007
+ _this2.setOldRangeParams(_new_rangeParams8);
22489
23008
 
22490
23009
  var _nodeCounts = _this2._countNodeTypes();
22491
23010
 
@@ -22493,7 +23012,7 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22493
23012
  if (_this2.editingExistingEquation) _mimeType = _this2.getMimeType(_nodeCounts.html > 0, _nodeCounts.katex > 1);else _mimeType = _this2.getMimeType(_nodeCounts.html > 0, _nodeCounts.katex > 0);
22494
23013
  _new_raw_text = removeEncodingIfPlainText(_new_raw_text, _mimeType, _this2.enableHtml());
22495
23014
 
22496
- _this2.applyChangesToComponent(_new_raw_text, _mimeType, _new_rangeParams6, _this2.props.useExpertMode, _this2.props.selectedTab);
23015
+ _this2.applyChangesToComponent(_new_raw_text, _mimeType, _new_rangeParams8, _this2.props.useExpertMode, _this2.props.selectedTab);
22497
23016
 
22498
23017
  _this2.setState({
22499
23018
  showEquationEditor: false
@@ -22504,20 +23023,7 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22504
23023
  // console.log("Latex returned from equation editor: "+latex)
22505
23024
 
22506
23025
 
22507
- var new_raw_text = replaceMarksWithMath(_this2.markedRawText, latex, _this2.enableHtml()); // let new_raw_text =
22508
- // this.markedRawText.substring(0,start_pos) +
22509
- // RAW_TEXT_MATH_START_TAG + latex + RAW_TEXT_MATH_END_TAG +
22510
- // this.markedRawText.substring(end_pos + MARK.length)
22511
- // console.log(
22512
- // "Old cursor pos: " +
22513
- // oldRangeParams.startNodeIndex +
22514
- // "->" +
22515
- // oldRangeParams.startOffset
22516
- // );
22517
- // console.log("Old raw text: " + this.props.value);
22518
- // console.log("Old raw text length: " + this.props.value.length);
22519
- // console.log("Old marked raw text:" + this.markedRawText);
22520
- // console.log("New raw text: " + new_raw_text);
23026
+ var new_raw_text = replaceMarksWithMath(_this2.markedRawText, latex, _this2.enableHtml());
22521
23027
 
22522
23028
  var new_rangeParams = _this2.getOldRangeParams();
22523
23029
 
@@ -22559,7 +23065,30 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22559
23065
  _defineProperty(_assertThisInitialized(_this2), "styleText", function (event, style) {
22560
23066
  try {
22561
23067
  style = style.toLowerCase();
22562
- var success = document.execCommand(style, false, null);
23068
+ var success = false; // This first part is a workaround whereby executing subscript or superscript
23069
+ // within an existing subscript or superscript makes the text even smaller instead
23070
+ // of toggling it off. Thus we manually toggle it off with some jigerry pokery!
23071
+
23072
+ if (style === "subscript" && _this2.state.activeButtons.subscript || style === "superscript" && _this2.state.activeButtons.superscript) {
23073
+ var selection = document.getSelection();
23074
+ var range = selection.getRangeAt(0);
23075
+
23076
+ if (range.endContainer === range.startContainer && range.endOffset === range.startOffset) {
23077
+ success = document.execCommand("insertText", false, " ");
23078
+ range.setEnd(range.endContainer, range.endOffset + 1);
23079
+ selection.removeAllRanges();
23080
+ selection.addRange(range);
23081
+ }
23082
+
23083
+ success = document.execCommand("removeFormat", false, null);
23084
+ if (_this2.state.activeButtons.bold) success = document.execCommand("bold", false, null);
23085
+ if (_this2.state.activeButtons.italic) success = document.execCommand("italic", false, null);
23086
+ if (_this2.state.activeButtons.underline) success = document.execCommand("underline", false, null);
23087
+ } else {
23088
+ // This is the normal code ...
23089
+ success = document.execCommand(style, false, null);
23090
+ }
23091
+
22563
23092
  var buttonState = _this2.state.activeButtons[style];
22564
23093
  if (buttonState === null || buttonState === undefined) return success;
22565
23094
  buttonState = !buttonState;
@@ -22613,7 +23142,9 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22613
23142
  }
22614
23143
  });
22615
23144
 
22616
- _defineProperty(_assertThisInitialized(_this2), "insertRawText", function (event, new_text) {
23145
+ _defineProperty(_assertThisInitialized(_this2), "insertRawText", function (new_text) {
23146
+ var selectInsertedText = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
23147
+
22617
23148
  try {
22618
23149
  var rangeParams = _this2._getRangeParams();
22619
23150
 
@@ -22625,12 +23156,166 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22625
23156
 
22626
23157
  var new_rangeParams = _objectSpread2({}, rangeParams);
22627
23158
 
22628
- new_raw_text = removeMarks(insertCharacterBeforeMarks(raw_text, new_text));
22629
- if (rangeParams.startNodeIndex === rangeParams.endNodeIndex && rangeParams.startOffset === rangeParams.endOffset) new_rangeParams.startOffset = new_rangeParams.startOffset + new_text.length;
23159
+ new_raw_text = removeMarks(insertCharacterBeforeMarks(raw_text, new_text)); // console.log("New raw text:")
23160
+ // console.log(new_raw_text)
23161
+ // if (rangeParams.startNodeIndex === rangeParams.endNodeIndex &&
23162
+ // rangeParams.startOffset === rangeParams.endOffset)
23163
+ // new_rangeParams.startOffset = new_rangeParams.startOffset + new_text.length
23164
+
22630
23165
  new_rangeParams.endOffset = new_rangeParams.endOffset + new_text.length;
22631
- new_raw_text = removeEncodingIfPlainText(new_raw_text, _this2.state.mimeType, _this2.enableHtml());
22632
23166
 
22633
- _this2.applyChangesToComponent(new_raw_text, _this2.state.mimeType, new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab);
23167
+ if (!selectInsertedText) {
23168
+ new_rangeParams.startNodeIndex = new_rangeParams.endNodeIndex;
23169
+ new_rangeParams.startOffset = new_rangeParams.endOffset;
23170
+ } // console.log("Setting new range params: ")
23171
+ // console.log(new_rangeParams)
23172
+ // console.log("Setting new mime-type: ")
23173
+ // console.log(this.props.mimeType)
23174
+
23175
+
23176
+ new_raw_text = removeEncodingIfPlainText(new_raw_text, _this2.props.mimeType, _this2.enableHtml());
23177
+
23178
+ _this2.applyChangesToComponent(new_raw_text, _this2.props.mimeType, new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab);
23179
+ } catch (error) {
23180
+ console.error(error);
23181
+ }
23182
+ });
23183
+
23184
+ _defineProperty(_assertThisInitialized(_this2), "pasteHtmlAtCaret", function (html, selectPastedContent) {
23185
+ var sel, range;
23186
+
23187
+ if (window.getSelection) {
23188
+ // IE9 and non-IE
23189
+ sel = window.getSelection();
23190
+
23191
+ if (sel.getRangeAt && sel.rangeCount) {
23192
+ range = sel.getRangeAt(0);
23193
+ range.deleteContents(); // Range.createContextualFragment() would be useful here but is
23194
+ // only relatively recently standardized and is not supported in
23195
+ // some browsers (IE9, for one)
23196
+
23197
+ var el = document.createElement("div");
23198
+ el.innerHTML = html;
23199
+ var frag = document.createDocumentFragment(),
23200
+ node,
23201
+ lastNode;
23202
+
23203
+ while (node = el.firstChild) {
23204
+ lastNode = frag.appendChild(node);
23205
+ }
23206
+
23207
+ var firstNode = frag.firstChild;
23208
+ range.insertNode(frag); // Preserve the selection
23209
+
23210
+ if (lastNode) {
23211
+ range = range.cloneRange();
23212
+ range.setStartAfter(lastNode);
23213
+
23214
+ if (selectPastedContent) {
23215
+ range.setStartBefore(firstNode);
23216
+ } else {
23217
+ range.collapse(true);
23218
+ }
23219
+
23220
+ sel.removeAllRanges();
23221
+ sel.addRange(range);
23222
+ }
23223
+ }
23224
+ } else if ((sel = document.selection) && sel.type != "Control") {
23225
+ // IE < 9
23226
+ var originalRange = sel.createRange();
23227
+ originalRange.collapse(true);
23228
+ sel.createRange().pasteHTML(html);
23229
+
23230
+ if (selectPastedContent) {
23231
+ range = sel.createRange();
23232
+ range.setEndPoint("StartToStart", originalRange);
23233
+ range.select();
23234
+ }
23235
+ }
23236
+ });
23237
+
23238
+ _defineProperty(_assertThisInitialized(_this2), "insertHtml", function (new_html) {
23239
+ try {
23240
+ // console.log("New html: "+new_html)
23241
+ // console.log("inserting: "+new_html)
23242
+ _this2.pasteHtmlAtCaret(new_html, true);
23243
+
23244
+ var new_rangeParams = null; // console.log("New range params: ")
23245
+
23246
+ try {
23247
+ new_rangeParams = _this2._getRangeParams(); // console.log("New range params: ")
23248
+ // console.log(new_rangeParams)
23249
+ } catch (error) {
23250
+ console.error(error);
23251
+ } // TODO: Fix the bug that fails to get range params correctly
23252
+
23253
+
23254
+ if (new_rangeParams.startNodeIndex < 0 || new_rangeParams.endNodeIndex < 0) {
23255
+ console.warn("Selection range params were not fetched correctly. Unable to set highlight inserted text.");
23256
+ } // Even if fetches valid range params, they are probably incorrect
23257
+ // So lets clear them for now
23258
+
23259
+
23260
+ new_rangeParams = {
23261
+ startNodeIndex: 0,
23262
+ startOffset: 0,
23263
+ endNodeIndex: 0,
23264
+ endOffset: 0
23265
+ };
23266
+ var new_raw_text = elementToMarkedRawText(_this2.editableDiv, null, -1, _this2.enableHtml()); // console.log("New raw text:"+new_raw_text)
23267
+
23268
+ var nodeCounts = _this2._countNodeTypes();
23269
+
23270
+ var mimeType = _this2.getMimeType(nodeCounts.html > 0, nodeCounts.math > 0);
23271
+
23272
+ new_raw_text = removeEncodingIfPlainText(new_raw_text, mimeType, _this2.enableHtml()); // OK, got to remove the double <p> and double </p> inserted
23273
+ // After inserting <p>a</p><p>b</p> into <p>xy</p> we will have
23274
+ // <P>x<P>a</P><P>b</P>y</P> and we want <P>xa</P><P>by</P>
23275
+
23276
+ try {
23277
+ var i = -1;
23278
+
23279
+ do {
23280
+ i = new_raw_text.indexOf("<P>", i + 1);
23281
+
23282
+ if (i >= 0) {
23283
+ var j = new_raw_text.indexOf("<P>", i + 1);
23284
+ var k = new_raw_text.indexOf("</P>", i + 1);
23285
+
23286
+ if (j >= 0) {
23287
+ if (k < 0 || k > j) {
23288
+ new_raw_text = new_raw_text.substring(0, j) + new_raw_text.substring(j + 3, new_raw_text.length);
23289
+ i = -1;
23290
+ }
23291
+ }
23292
+ }
23293
+ } while (i >= 0 && i < new_raw_text.length - 4);
23294
+
23295
+ i = -1;
23296
+
23297
+ do {
23298
+ i = new_raw_text.indexOf("</P>", i + 1);
23299
+
23300
+ if (i >= 0) {
23301
+ var _j = new_raw_text.indexOf("</P>", i + 1);
23302
+
23303
+ var _k = new_raw_text.indexOf("<P>", i + 1);
23304
+
23305
+ if (_j >= 0) {
23306
+ if (_k < 0 || _k > _j) {
23307
+ new_raw_text = new_raw_text.substring(0, i) + new_raw_text.substring(i + 4, new_raw_text.length);
23308
+ i = -1;
23309
+ }
23310
+ }
23311
+ }
23312
+ } while (i >= 0 && i < new_raw_text.length - 4);
23313
+ } catch (error) {
23314
+ console.error(error);
23315
+ } // console.log("New raw text:"+new_raw_text)
23316
+
23317
+
23318
+ _this2.applyChangesToComponent(new_raw_text, mimeType, new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab);
22634
23319
  } catch (error) {
22635
23320
  console.error(error);
22636
23321
  }
@@ -22655,14 +23340,12 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22655
23340
  new_rangeParams.startNodeIndex = rangeParams.startNodeIndex - 1;
22656
23341
  new_rangeParams.startOffset = new_offset;
22657
23342
  new_rangeParams.endNodeIndex = rangeParams.endNodeIndex - 1;
22658
- new_rangeParams.endOffset = new_offset; // console.log("About to apply new range params");
22659
- // console.log(new_rangeParams);
22660
- // console.log("Old nodes");
22661
- // console.log(this.editableDiv.childNodes);
22662
-
22663
- new_raw_text = removeEncodingIfPlainText(new_raw_text, _this2.state.mimeType, _this2.enableHtml());
23343
+ new_rangeParams.endOffset = new_offset;
23344
+ new_rangeParams.srartGlobalOffset--;
23345
+ new_rangeParams.endGlobalOffset--;
23346
+ new_raw_text = removeEncodingIfPlainText(new_raw_text, _this2.props.mimeType, _this2.enableHtml());
22664
23347
 
22665
- _this2.applyChangesToComponent(new_raw_text, _this2.state.mimeType, new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab);
23348
+ _this2.applyChangesToComponent(new_raw_text, _this2.props.mimeType, new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab);
22666
23349
  } catch (error) {
22667
23350
  console.error(error);
22668
23351
  }
@@ -22680,6 +23363,11 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22680
23363
 
22681
23364
  var new_rangeParams = _objectSpread2({}, rangeParams);
22682
23365
 
23366
+ if (new_rangeParams.startGlobalOffset) {
23367
+ new_rangeParams.startGlobalOffset++;
23368
+ new_rangeParams.endGlobalOffset++;
23369
+ }
23370
+
22683
23371
  if (_this2.enableHtml()) {
22684
23372
  new_raw_text = removeMarks(insertCharacterBeforeMarks(raw_text, "</p><p>"));
22685
23373
  if (new_raw_text.substring(0, 3).toLowerCase() !== "<p>") new_raw_text = "<p>" + new_raw_text + "</p>";
@@ -22691,39 +23379,11 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22691
23379
  new_raw_text = removeMarks(insertCharacterBeforeMarks(raw_text, "\n"));
22692
23380
  new_rangeParams.startOffset++;
22693
23381
  new_rangeParams.endOffset++;
22694
- } // console.log("About to apply new range params");
22695
- // console.log(new_rangeParams);
22696
- // console.log("Old nodes");
22697
- // console.log(this.editableDiv.childNodes);
22698
-
22699
-
22700
- new_raw_text = removeEncodingIfPlainText(new_raw_text, _this2.state.mimeType, _this2.enableHtml());
22701
-
22702
- _this2.applyChangesToComponent(new_raw_text, _this2.state.mimeType, new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab);
22703
- } catch (error) {
22704
- console.error(error);
22705
- }
22706
- });
22707
-
22708
- _defineProperty(_assertThisInitialized(_this2), "replaceNextLetter", function (new_char) {
22709
- try {
22710
- var rangeParams = _this2._getRangeParams();
22711
-
22712
- var node = _this2._findNodeWithIndex(rangeParams.endNodeIndex);
22713
-
22714
- var offset = rangeParams.endOffset + 1; // next letter
22715
-
22716
- var raw_text = elementToMarkedRawText(_this2.editableDiv, node, offset, _this2.enableHtml());
22717
- var new_raw_text = null;
22718
-
22719
- var new_rangeParams = _objectSpread2({}, rangeParams);
23382
+ }
22720
23383
 
22721
- new_raw_text = removeMarks(insertCharacterBeforeMarks(raw_text, new_char));
22722
- if (rangeParams.startNodeIndex === rangeParams.endNodeIndex && rangeParams.startOffset === rangeParams.endOffset) new_rangeParams.startOffset = new_rangeParams.startOffset + new_char.length + 1;
22723
- new_rangeParams.endOffset = new_rangeParams.endOffset + new_char.length + 1;
22724
- new_raw_text = removeEncodingIfPlainText(new_raw_text, _this2.state.mimeType, _this2.enableHtml());
23384
+ new_raw_text = removeEncodingIfPlainText(new_raw_text, _this2.props.mimeType, _this2.enableHtml());
22725
23385
 
22726
- _this2.applyChangesToComponent(new_raw_text, _this2.state.mimeType, new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab);
23386
+ _this2.applyChangesToComponent(new_raw_text, _this2.props.mimeType, new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab);
22727
23387
  } catch (error) {
22728
23388
  console.error(error);
22729
23389
  }
@@ -22733,23 +23393,33 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22733
23393
  try {
22734
23394
  var rangeParams = _this2._getRangeParams();
22735
23395
 
22736
- var node = _this2._findNodeWithIndex(rangeParams.endNodeIndex);
23396
+ var node = _this2._findNodeWithIndex(rangeParams.startNodeIndex);
22737
23397
 
22738
- var offset = rangeParams.endOffset;
23398
+ var offset = rangeParams.startOffset;
22739
23399
  var raw_text = elementToMarkedRawText(_this2.editableDiv, node, offset, _this2.enableHtml());
22740
23400
  var new_raw_text = null;
22741
-
22742
- var new_rangeParams = _objectSpread2({}, rangeParams);
23401
+ var new_rangeParams = null;
22743
23402
 
22744
23403
  if (old_char === null) {
23404
+ // insert new char
22745
23405
  new_raw_text = removeMarks(insertCharacterBeforeMarks(raw_text, new_char));
22746
- if (rangeParams.startNodeIndex === rangeParams.endNodeIndex && rangeParams.startOffset === rangeParams.endOffset) new_rangeParams.startOffset = new_rangeParams.startOffset + new_char.length;
22747
- new_rangeParams.endOffset = new_rangeParams.endOffset + new_char.length;
22748
- } else new_raw_text = removeMarks(replaceCharacterBeforeMarks(raw_text, new_char));
23406
+ new_rangeParams = {
23407
+ startNodeIndex: rangeParams.startNodeIndex,
23408
+ startOffset: rangeParams.startOffset + new_char.length,
23409
+ endNodeIndex: rangeParams.startNodeIndex,
23410
+ endOffset: rangeParams.startOffset + new_char.length,
23411
+ startGlobalOffset: rangeParams.startGlobalOffset + new_char.length,
23412
+ endGlobalOffset: rangeParams.startGlobalOffset + new_char.length
23413
+ };
23414
+ } else {
23415
+ // replace old char
23416
+ new_raw_text = removeMarks(replaceCharacterBeforeMarks(raw_text, new_char));
23417
+ new_rangeParams = _objectSpread2({}, rangeParams);
23418
+ }
22749
23419
 
22750
- new_raw_text = removeEncodingIfPlainText(new_raw_text, _this2.state.mimeType, _this2.enableHtml());
23420
+ new_raw_text = removeEncodingIfPlainText(new_raw_text, _this2.props.mimeType, _this2.enableHtml());
22751
23421
 
22752
- _this2.applyChangesToComponent(new_raw_text, _this2.state.mimeType, new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab);
23422
+ _this2.applyChangesToComponent(new_raw_text, _this2.props.mimeType, new_rangeParams, _this2.props.useExpertMode, _this2.props.selectedTab);
22753
23423
  } catch (error) {
22754
23424
  console.error(error);
22755
23425
  }
@@ -22767,6 +23437,10 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22767
23437
  }
22768
23438
  });
22769
23439
 
23440
+ _defineProperty(_assertThisInitialized(_this2), "focus", function () {
23441
+ _this2.editableDiv.focus();
23442
+ });
23443
+
22770
23444
  _defineProperty(_assertThisInitialized(_this2), "handleFocus", function (event) {
22771
23445
  var onFocus = _this2.props.onFocus;
22772
23446
 
@@ -22848,6 +23522,7 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22848
23522
  _this2.initialHistoryState = null;
22849
23523
  _this2.undoHistory = [];
22850
23524
  _this2.redoHistory = [];
23525
+ _this2.accent = "";
22851
23526
  return _this2;
22852
23527
  }
22853
23528
 
@@ -22949,6 +23624,8 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22949
23624
  setupKatex();
22950
23625
  this.editableDiv.addEventListener("keydown", this.handleKeyDown);
22951
23626
  this.editableDiv.addEventListener("keyup", this.handleKeyUp);
23627
+ this.editableDiv.addEventListener("paste", this.handlePaste);
23628
+ if (this.props.autofocus === true) this.editableDiv.focus();
22952
23629
  } catch (error) {
22953
23630
  console.error(error);
22954
23631
  }
@@ -22959,6 +23636,7 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22959
23636
  try {
22960
23637
  this.editableDiv.removeEventListener("keydown", this.handleKeyDown);
22961
23638
  this.editableDiv.removeEventListener("keyup", this.handleKeyUp);
23639
+ this.editableDiv.removeEventListener("paste", this.handlePaste);
22962
23640
  } catch (error) {
22963
23641
  console.error(error);
22964
23642
  }
@@ -22977,6 +23655,32 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22977
23655
  console.error(error);
22978
23656
  }
22979
23657
  }
23658
+ }, {
23659
+ key: "insertAfterSmallSpace",
23660
+ value: function insertAfterSmallSpace(new_char, rangeParams) {
23661
+ try {
23662
+ if (rangeParams === null || rangeParams === undefined) rangeParams = this._getRangeParams();
23663
+ if (rangeParams.startOffset !== 0) console.warn("Unexpected startOffset " + rangeParams.startOffset + " in insertAfterSmallSpace");
23664
+
23665
+ var node = this._findNodeWithIndex(rangeParams.startNodeIndex);
23666
+
23667
+ var raw_text = elementToMarkedRawText(this.editableDiv, node, 1, // after small space
23668
+ this.enableHtml());
23669
+ var new_raw_text = removeMarks(insertCharacterBeforeMarks(raw_text, new_char));
23670
+ var new_rangeParams = {
23671
+ startNodeIndex: rangeParams.startNodeIndex,
23672
+ startNodeOffset: 1 + new_char.length,
23673
+ endNodeIndex: rangeParams.startNodeIndex,
23674
+ endNodeOffset: 1 + new_char.length,
23675
+ startGlobalOffset: rangeParams.startGlobalOffset + new_char.length,
23676
+ endGlobalOffset: rangeParams.endGlobalOffset + new_char.length
23677
+ };
23678
+ new_raw_text = removeEncodingIfPlainText(new_raw_text, this.props.mimeType, this.enableHtml());
23679
+ this.applyChangesToComponent(new_raw_text, this.props.mimeType, new_rangeParams, this.props.useExpertMode, this.props.selectedTab);
23680
+ } catch (error) {
23681
+ console.error(error);
23682
+ }
23683
+ }
22980
23684
  }, {
22981
23685
  key: "render",
22982
23686
  value: function render() {