@zzish/math-rich-input 0.1.28 → 0.1.30

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
@@ -21352,9 +21352,16 @@ function findNodeAndOffsetForGlobalOffset(node, globalOffset) {
21352
21352
  if (isTextNode(node)) {
21353
21353
  result.node = node;
21354
21354
  result.lastTextNode = node;
21355
+ console.log("Found text node \'" + node.nodeValue + "\' of length " + node.nodeValue.length);
21356
+ console.log("result.offset was: " + result.offset);
21355
21357
  result.offset += node.nodeValue.length;
21356
- if (nodeStartsWithSmallSpace(node)) result.offset -= 1; // console.log("result.offset now: "+result.offset)
21357
21358
 
21359
+ if (nodeStartsWithSmallSpace(node)) {
21360
+ console.log("Text node starts with small space");
21361
+ result.offset -= 1;
21362
+ }
21363
+
21364
+ console.log("result.offset now: " + result.offset);
21358
21365
  return false;
21359
21366
  }
21360
21367
 
@@ -21374,8 +21381,10 @@ function findNodeAndOffsetForGlobalOffset(node, globalOffset) {
21374
21381
  }
21375
21382
 
21376
21383
  if (node.nodeType === 1 && node.tagName === "P") {
21384
+ console.log("Leaving p node");
21377
21385
  result.node = null;
21378
21386
  result.offset++;
21387
+ console.log("result.offset now: " + result.offset);
21379
21388
  }
21380
21389
 
21381
21390
  return false;
@@ -21397,6 +21406,7 @@ function findNodeAndOffsetForGlobalOffsetInEditableDiv(editableDiv, globalOffset
21397
21406
  var result = {
21398
21407
  offset: 0
21399
21408
  };
21409
+ console.log("Finding node and offset within: " + editableDiv.outerHTML);
21400
21410
  findNodeAndOffsetForGlobalOffset(editableDiv, globalOffset, result);
21401
21411
  console.log(result);
21402
21412
 
@@ -21411,20 +21421,28 @@ function findNodeAndOffsetForGlobalOffsetInEditableDiv(editableDiv, globalOffset
21411
21421
  result.node = findFirstTextNode(editableDiv);
21412
21422
  result.offset = 0;
21413
21423
  }
21414
- } // if (result.offset === 0 &&
21415
- // result.node.nodeValue.length > 0 &&
21416
- // nodeStartsWithSmallSpace(result.node)) {
21417
- // result.offset = 1
21418
- // }
21424
+ }
21419
21425
 
21426
+ if (result.offset === 0 && result.node.nodeValue.length > 0 && nodeStartsWithSmallSpace(result.node)) {
21427
+ result.offset = 1;
21428
+ }
21429
+
21430
+ if (result.offset > result.node.nodeValue.length) {
21431
+ console.warn("Unexpected offset when converting global offset to node and offset");
21432
+ console.log("Global offset: " + globalOffset);
21433
+ console.log("Result:");
21434
+ console.log(result);
21435
+ console.log("result.offset > result.node.nodeValue.length");
21436
+ result.offset = result.node.nodeValue.length;
21437
+ }
21420
21438
 
21421
21439
  return result;
21422
21440
  } // https://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html
21423
21441
 
21424
21442
 
21425
21443
  function getRangeParams(editableDiv) {
21426
- // console.log ("getRangeParams")
21427
- // console.log("Inner html: "+editableDiv.innerHTML)
21444
+ console.log("getRangeParams"); // console.log("Inner html: "+editableDiv.innerHTML)
21445
+
21428
21446
  var isSupported = typeof window.getSelection !== "undefined";
21429
21447
 
21430
21448
  if (!isSupported) {
@@ -21543,17 +21561,18 @@ function setRangeParams(editableDiv, params) {
21543
21561
 
21544
21562
 
21545
21563
  if (params.startGlobalOffset !== null && params.startGlobalOffset !== undefined) {
21564
+ console.log("Setting range from global offsets");
21546
21565
  setRangeParamsFromGlobalOffsets(editableDiv, params);
21547
21566
  return;
21548
21567
  } // Otherwise use the old way of doing things
21549
21568
 
21550
21569
 
21570
+ console.log("Setting range from node index and local offset");
21571
+
21551
21572
  if (params.startNodeIndex === null || params.startNodeIndex === undefined) {
21552
21573
  console.error("Can't set range params: params.startNodeIndex === " + params.startNodeIndex);
21553
21574
  return;
21554
- } // console.log("Setting cursor to range params: "+params.startNodeIndex+"->"+params.startOffset)
21555
- // console.log(params)
21556
-
21575
+ }
21557
21576
 
21558
21577
  if (params.startNodeIndex < 0) {
21559
21578
  console.error("Can't set range params: params.startNodeIndex < 0");
@@ -21563,34 +21582,32 @@ function setRangeParams(editableDiv, params) {
21563
21582
  var nodes = editableDiv.childNodes;
21564
21583
 
21565
21584
  if (params.startNodeIndex === 0 && params.startOffset === 0 && nodes.length === 0) {
21566
- // console.log("Not setting range params")
21567
21585
  return;
21568
- } // console.log("Node["+params.startNodeIndex+"]:")
21569
- // console.log(nodes[params.startNodeIndex])
21586
+ } // Set the offsets within the nodes
21570
21587
 
21571
21588
 
21572
21589
  var startOffset = params.startOffset;
21573
21590
  var endOffset = params.endOffset; // Handle special case of auto inserted SMALL CHAR at beginning of input
21591
+ // TODO This sectin may no longer be neceesary and may be introducing a bug
21574
21592
 
21575
21593
  if (params.startNodeIndex === 0 && params.startOffset === 1 && isSmallSpace(nodes[0])) startOffset = 0;
21576
- if (params.endNodeIndex === 0 && params.endOffset === 1 && isSmallSpace(nodes[0])) endOffset = 0;
21594
+ if (params.endNodeIndex === 0 && params.endOffset === 1 && isSmallSpace(nodes[0])) endOffset = 0; // Find the nodes
21595
+
21577
21596
  var startNode = findNodeWithIndex(editableDiv, params.startNodeIndex);
21578
- var endNode = findNodeWithIndex(editableDiv, params.endNodeIndex); // Lets make sure we are setting
21579
- // if (params.startNodeIndex !== 0 &&
21580
- // params.startOffset === 0) {
21581
- // if (getNodeText(startNode).charAt(0) === SMALL_SPACE)
21582
- // startOffset = SMALL_SPACE.length
21583
- // }
21584
- // if (params.endNodeIndex !== 0 &&
21585
- // params.endOffset === 0) {
21586
- // if (getNodeText(endNode).charAt(0) === SMALL_SPACE)
21587
- // endOffset = SMALL_SPACE.length
21588
- // }
21589
- // console.log("End: "+params.endNodeIndex+"->"+endOffset)
21590
- // Set range in document
21597
+ var endNode = findNodeWithIndex(editableDiv, params.endNodeIndex);
21598
+ console.log("Setting range to start in node:");
21599
+ console.log(" node type: " + startNode.nodeType);
21600
+ console.log(" tag name: " + startNode.tagName);
21601
+ console.log(" node value: " + startNode.nodeValue);
21602
+ console.log(" offset:" + startOffset);
21603
+ console.log("Setting range to end in node:");
21604
+ console.log(" node type: " + endNode.nodeType);
21605
+ console.log(" tag name: " + endNode.tagName);
21606
+ console.log(" node value: " + endNode.nodeValue);
21607
+ console.log(" offset:" + endOffset); // Set range in document
21591
21608
 
21592
21609
  if (startNode === null) {
21593
- console.error("Could not set range to start node with index " + params.startNodeIndex);
21610
+ console.warn("Could not set range to start node with index " + params.startNodeIndex);
21594
21611
  startNode = findFirstTextNode(editableDiv);
21595
21612
  startOffset = 0;
21596
21613
  }
@@ -21606,7 +21623,7 @@ function setRangeParams(editableDiv, params) {
21606
21623
  }
21607
21624
 
21608
21625
  if (endNode === null) {
21609
- console.error("Could not set range to end node with index " + params.endNodeIndex);
21626
+ console.warn("Could not set range to end node with index " + params.endNodeIndex);
21610
21627
  endNode = findFirstTextNode(editableDiv);
21611
21628
  endOffset = 0;
21612
21629
  }
@@ -21622,11 +21639,17 @@ function setRangeParams(editableDiv, params) {
21622
21639
  }
21623
21640
 
21624
21641
  new_range = document.createRange();
21642
+
21643
+ if (startOffset > startNode.nodeValue.length) {
21644
+ console.warn("endOffset > endNode.nodeValue.length when setting range: " + startOffset + " > " + startNode.nodeValue.length + " - " + stateNode.nodeType + " - " + startNode.nodeValue);
21645
+ startOffset = startNode.nodeValue.length;
21646
+ }
21647
+
21625
21648
  new_range.setStart(startNode, startOffset);
21626
21649
 
21627
- if (endOffset > endNode.length) {
21628
- console.warn("endOffset > endNode.length when setting range: " + endOffset + " > " + endNode.length + " - " + endNode.nodeType + " - " + endNode.nodeValue);
21629
- endOffset = endNode.length;
21650
+ if (endOffset > endNode.nodeValue.length) {
21651
+ console.warn("endOffset > endNode.nodeValue.length when setting range: " + endOffset + " > " + endNode.nodeValue.length + " - " + endNode.nodeType + " - " + endNode.nodeValue);
21652
+ endOffset = endNode.nodeValue.length;
21630
21653
  }
21631
21654
 
21632
21655
  new_range.setEnd(endNode, endOffset); // console.log("Setting range")
@@ -21956,18 +21979,12 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
21956
21979
  });
21957
21980
 
21958
21981
  _defineProperty(_assertThisInitialized(_this2), "applyChangesToComponent", function (value, mimeType, rangeParams, isExpertMode, selectedTab) {
21959
- // if (this.props.outputTex !== null && this.props.outputTex !== undefined && this.props.outputTex) {
21960
- // if (mimeType === MIME_TYPE_HTML) {
21961
- // console.warn("Html found when outputTex=true")
21962
- // value = convertHtmlToPlainText(value)
21963
- // mimeType = MIME_TYPE_PLAIN_TEXT
21964
- // } else if (mimeType === MIME_TYPE_ZZISH_HTML_MATH) {
21965
- // value = convertHtmlMathToTex(value)
21966
- // mimeType = MIME_TYPE_TEX
21967
- // }
21968
- // }
21969
21982
  // rangeParams, isExpertMode and selectedTab can be null, in which case we will set them
21970
- if (rangeParams === null) rangeParams = _this2.lastSetRangeParams;else _this2.rangeParamsToSetAfterComponentUpdate = rangeParams;
21983
+ if (rangeParams === null) rangeParams = _this2.lastSetRangeParams;
21984
+ _this2.afterComponentUpdateData = {
21985
+ rangeParams: rangeParams,
21986
+ value: value
21987
+ };
21971
21988
  var options = _this2.props.options || DEFAULT_OPTIONS;
21972
21989
  if (isExpertMode === null) isExpertMode = options.isExpertMode;
21973
21990
  if (selectedTab === null) selectedTab = options.selectedTab; // Add this to the history
@@ -22187,17 +22204,27 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22187
22204
  rangeParams.startOffset;
22188
22205
  console.log("handleKeyDownArrowLeft");
22189
22206
  console.log(rangeParams);
22190
- var new_globalOffset = rangeParams.startGlobalOffset - 1;
22191
- var new_rangeParams = {
22192
- startGlobalOffset: new_globalOffset,
22193
- endGlobalOffset: new_globalOffset
22194
- };
22207
+ var new_globalOffset = rangeParams.endGlobalOffset - 1;
22208
+ var new_rangeParams = null;
22209
+
22210
+ if (e.shiftKey && new_globalOffset > rangeParams.startGlobalOffset) {
22211
+ new_rangeParams = {
22212
+ startGlobalOffset: rangeParams.startGlobalOffset,
22213
+ endGlobalOffset: new_globalOffset
22214
+ };
22215
+ } else {
22216
+ new_rangeParams = {
22217
+ startGlobalOffset: new_globalOffset,
22218
+ endGlobalOffset: new_globalOffset
22219
+ };
22220
+ }
22221
+
22195
22222
  console.log(new_rangeParams);
22196
22223
  e.preventDefault();
22197
22224
 
22198
22225
  _this2._setRangeParams(new_rangeParams);
22199
22226
 
22200
- return; // console.log("Old: "+index+"->"+offset)
22227
+ return;
22201
22228
  });
22202
22229
 
22203
22230
  _defineProperty(_assertThisInitialized(_this2), "handleKeyDownArrowRight", function (e) {
@@ -22206,11 +22233,21 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22206
22233
 
22207
22234
  rangeParams.startNodeIndex;
22208
22235
  rangeParams.startOffset;
22209
- var new_globalOffset = rangeParams.startGlobalOffset + 1;
22210
- var new_rangeParams = {
22211
- startGlobalOffset: new_globalOffset,
22212
- endGlobalOffset: new_globalOffset
22213
- };
22236
+ var new_rangeParams = null;
22237
+ var new_globalOffset = rangeParams.endGlobalOffset + 1;
22238
+
22239
+ if (e.shiftKey && new_globalOffset > rangeParams.startGlobalOffset) {
22240
+ new_rangeParams = {
22241
+ startGlobalOffset: rangeParams.startGlobalOffset,
22242
+ endGlobalOffset: new_globalOffset
22243
+ };
22244
+ } else {
22245
+ new_rangeParams = {
22246
+ startGlobalOffset: new_globalOffset,
22247
+ endGlobalOffset: new_globalOffset
22248
+ };
22249
+ }
22250
+
22214
22251
  e.preventDefault();
22215
22252
 
22216
22253
  _this2._setRangeParams(new_rangeParams);
@@ -22630,30 +22667,30 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22630
22667
 
22631
22668
  if (_index >= 0) {
22632
22669
  if (isKatexNode(_this2._findNodeWithIndex(_index))) {
22633
- var _new_index4 = 0;
22634
- var _new_offset4 = 0;
22670
+ var _new_index = 0;
22671
+ var _new_offset = 0;
22635
22672
 
22636
22673
  if (_index - 1 >= 0) {
22637
- _new_index4 = _index - 1;
22638
- _new_offset4 = getNodeTextLength(_this2._findNodeWithIndex(_new_index4));
22674
+ _new_index = _index - 1;
22675
+ _new_offset = getNodeTextLength(_this2._findNodeWithIndex(_new_index));
22639
22676
 
22640
- if (_new_offset4 < 0) {
22677
+ if (_new_offset < 0) {
22641
22678
  console.error("Failed to get node text length");
22642
- _new_offset4 = 0;
22679
+ _new_offset = 0;
22643
22680
  }
22644
22681
  } else {
22645
- _new_index4 = _index + 1;
22646
- _new_offset4 = SMALL_SPACE_LENGTH;
22682
+ _new_index = _index + 1;
22683
+ _new_offset = SMALL_SPACE_LENGTH;
22647
22684
  }
22648
22685
 
22649
- var _new_rangeParams7 = {
22650
- startNodeIndex: _new_index4,
22651
- startOffset: _new_offset4,
22652
- endNodeIndex: _new_index4,
22653
- endOffset: _new_offset4
22686
+ var _new_rangeParams2 = {
22687
+ startNodeIndex: _new_index,
22688
+ startOffset: _new_offset,
22689
+ endNodeIndex: _new_index,
22690
+ endOffset: _new_offset
22654
22691
  }; // console.log(new_rangeParams)
22655
22692
 
22656
- _this2._setRangeParams(_new_rangeParams7);
22693
+ _this2._setRangeParams(_new_rangeParams2);
22657
22694
  }
22658
22695
  }
22659
22696
  }
@@ -22690,6 +22727,8 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
22690
22727
 
22691
22728
  _defineProperty(_assertThisInitialized(_this2), "updateActiveButtons", function () {
22692
22729
  try {
22730
+ console.log("updateActiveButtons");
22731
+
22693
22732
  var rangeParams = _this2._getRangeParams();
22694
22733
 
22695
22734
  if (rangeParams === null || rangeParams === undefined) {
@@ -23000,14 +23039,14 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
23000
23039
  }
23001
23040
  }
23002
23041
 
23003
- var _new_rangeParams8 = {
23042
+ var _new_rangeParams3 = {
23004
23043
  startNodeIndex: new_index,
23005
23044
  startOffset: new_offset,
23006
23045
  endNodeIndex: new_index,
23007
23046
  endOffset: new_offset
23008
23047
  };
23009
23048
 
23010
- _this2.setOldRangeParams(_new_rangeParams8);
23049
+ _this2.setOldRangeParams(_new_rangeParams3);
23011
23050
 
23012
23051
  var _nodeCounts = _this2._countNodeTypes();
23013
23052
 
@@ -23015,7 +23054,7 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
23015
23054
  if (_this2.editingExistingEquation) _mimeType = _this2.getMimeType(_nodeCounts.html > 0, _nodeCounts.katex > 1);else _mimeType = _this2.getMimeType(_nodeCounts.html > 0, _nodeCounts.katex > 0);
23016
23055
  _new_raw_text = removeEncodingIfPlainText(_new_raw_text, _mimeType, _this2.enableHtml());
23017
23056
 
23018
- _this2.applyChangesToComponent(_new_raw_text, _mimeType, _new_rangeParams8, _this2.props.useExpertMode, _this2.props.selectedTab);
23057
+ _this2.applyChangesToComponent(_new_raw_text, _mimeType, _new_rangeParams3, _this2.props.useExpertMode, _this2.props.selectedTab);
23019
23058
 
23020
23059
  _this2.setState({
23021
23060
  showEquationEditor: false
@@ -23521,7 +23560,7 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
23521
23560
  };
23522
23561
  _this2.moveCursorOnInsert = false; // Elements defining the current state of range
23523
23562
 
23524
- _this2.rangeParamsToSetAfterComponentUpdate = null; // Set this to update the selection after rendering
23563
+ _this2.afterComponentUpdateData = null; // Set this to update the selection after rendering
23525
23564
 
23526
23565
  _this2.lastSetRangeParmas = null; // This is set automatically each time the range params are set with setRangeParams
23527
23566
 
@@ -23656,10 +23695,12 @@ var MathRichInput = /*#__PURE__*/function (_React$Component) {
23656
23695
  key: "componentDidUpdate",
23657
23696
  value: function componentDidUpdate() {
23658
23697
  try {
23659
- if (this.rangeParamsToSetAfterComponentUpdate !== null && this.rangeParamsToSetAfterComponentUpdate !== undefined) {
23660
- this._setRangeParams(this.rangeParamsToSetAfterComponentUpdate);
23698
+ console.log("componentDidUpdate");
23699
+
23700
+ if (this.afterComponentUpdateData !== null && this.afterComponentUpdateData !== undefined && this.afterComponentUpdateData.value === this.props.value) {
23701
+ this._setRangeParams(this.afterComponentUpdateData.rangeParams);
23661
23702
 
23662
- this.rangeParamsToSetAfterComponentUpdate = null;
23703
+ this.afterComponentUpdateData = null;
23663
23704
  this.updateActiveButtons();
23664
23705
  }
23665
23706
  } catch (error) {
@@ -78,6 +78,136 @@
78
78
  padding: 2px;
79
79
  margin: 0px 2px;
80
80
  }
81
+ /* Note that the top left position of the toolbar is set programatically in componentDidMount */
82
+
83
+ .Toolbar {
84
+ position: absolute;
85
+ z-index: 1;
86
+ display: flex;
87
+ height: 42px;
88
+ background-color: white;
89
+ border: 1px solid #d0d0d0;
90
+ border-radius: 5px;
91
+ box-shadow: 1px 1px 5px #a0a0a0;
92
+ animation: 0.5s fadeIn1;
93
+ animation-fill-mode: forwards;
94
+ }
95
+
96
+ @keyframes fadeIn1 {
97
+ 0% {
98
+ opacity: 0;
99
+ }
100
+ 100% {
101
+ opacity: 1;
102
+ }
103
+ }
104
+
105
+ .Toolbar-button {
106
+ font-family: sans-serif;
107
+ font-size: 16px;
108
+ width: 40px;
109
+ height: 36px;
110
+ background-color: white;
111
+ border-radius: 5px;
112
+ border: 0px;
113
+ padding: 1px;
114
+ margin: 2px;
115
+ }
116
+
117
+ .Toolbar-button:hover {
118
+ color: white;
119
+ background: #663676;
120
+ cursor: pointer;
121
+ }
122
+
123
+ .Toolbar-button:active {
124
+ background: #808080;
125
+ color: white;
126
+ cursor: pointer;
127
+ }
128
+
129
+ .TB-narrow {
130
+ width: 30px;
131
+ }
132
+
133
+ .TB-wide {
134
+ width: 46px;
135
+ }
136
+
137
+ .TB-selected {
138
+ background: #d0d0d0;
139
+ color: black;
140
+ cursor: pointer;
141
+ animation: 0.2s TB-fadeIn;
142
+ animation-fill-mode: forwards;
143
+ }
144
+
145
+ .TB-selected:hover {
146
+ color: white;
147
+ background: #663676;
148
+ cursor: pointer;
149
+ }
150
+
151
+ @keyframes TB-fadeIn {
152
+ 00% {
153
+ background: white;
154
+ }
155
+ 100% {
156
+ background: #d0d0d0;
157
+ }
158
+ }
159
+
160
+ /* Tooltip text */
161
+ .Toolbar-button .tooltiptext {
162
+ font-weight: normal;
163
+ visibility: hidden;
164
+ width: 100px;
165
+ background-color: #222;
166
+ color: #fff;
167
+ /*font-weight: bold;*/
168
+ font-size: 12px;
169
+ text-align: center;
170
+ padding: 4px 10px;
171
+ border-radius: 6px;
172
+
173
+ /* Position the tooltip text - see examples below! */
174
+ position: absolute;
175
+ z-index: 2;
176
+ top: -90%; /* Must leave a small gap between tooltip and button */
177
+ left: 50px;
178
+
179
+ /* transform: translate (50%,0%); */
180
+ }
181
+
182
+ /* Show the tooltip text when you mouse over the tooltip container */
183
+ .Toolbar-button:hover .tooltiptext {
184
+ animation: 0.8s fadeIn2;
185
+ animation-fill-mode: forwards;
186
+ visibility: visible;
187
+ /* width: 100px; */
188
+ /* top: -90%; */ /* Must leave a small gap between tooltip and button */
189
+ /* left: 20%; */
190
+ /* margin-left: -50px; */
191
+ }
192
+
193
+ @keyframes fadeIn2 {
194
+ 00% {
195
+ opacity: 0;
196
+ }
197
+ 70% {
198
+ opacity: 0;
199
+ }
200
+ 100% {
201
+ visibility: visible;
202
+ opacity: 0.9;
203
+ }
204
+ }
205
+
206
+ /* .tooltip {
207
+ position: relative;
208
+ display: inline-block;
209
+ border-bottom: 1px dotted black; /* If you want dots under the hoverable text
210
+ } */
81
211
  .EquationEditorModal-background {
82
212
  position: fixed;
83
213
  top: 0;
@@ -233,136 +363,6 @@
233
363
  .EquationEditorModal .slider.round:before {
234
364
  border-radius: 50%;
235
365
  }
236
- /* Note that the top left position of the toolbar is set programatically in componentDidMount */
237
-
238
- .Toolbar {
239
- position: absolute;
240
- z-index: 1;
241
- display: flex;
242
- height: 42px;
243
- background-color: white;
244
- border: 1px solid #d0d0d0;
245
- border-radius: 5px;
246
- box-shadow: 1px 1px 5px #a0a0a0;
247
- animation: 0.5s fadeIn1;
248
- animation-fill-mode: forwards;
249
- }
250
-
251
- @keyframes fadeIn1 {
252
- 0% {
253
- opacity: 0;
254
- }
255
- 100% {
256
- opacity: 1;
257
- }
258
- }
259
-
260
- .Toolbar-button {
261
- font-family: sans-serif;
262
- font-size: 16px;
263
- width: 40px;
264
- height: 36px;
265
- background-color: white;
266
- border-radius: 5px;
267
- border: 0px;
268
- padding: 1px;
269
- margin: 2px;
270
- }
271
-
272
- .Toolbar-button:hover {
273
- color: white;
274
- background: #663676;
275
- cursor: pointer;
276
- }
277
-
278
- .Toolbar-button:active {
279
- background: #808080;
280
- color: white;
281
- cursor: pointer;
282
- }
283
-
284
- .TB-narrow {
285
- width: 30px;
286
- }
287
-
288
- .TB-wide {
289
- width: 46px;
290
- }
291
-
292
- .TB-selected {
293
- background: #d0d0d0;
294
- color: black;
295
- cursor: pointer;
296
- animation: 0.2s TB-fadeIn;
297
- animation-fill-mode: forwards;
298
- }
299
-
300
- .TB-selected:hover {
301
- color: white;
302
- background: #663676;
303
- cursor: pointer;
304
- }
305
-
306
- @keyframes TB-fadeIn {
307
- 00% {
308
- background: white;
309
- }
310
- 100% {
311
- background: #d0d0d0;
312
- }
313
- }
314
-
315
- /* Tooltip text */
316
- .Toolbar-button .tooltiptext {
317
- font-weight: normal;
318
- visibility: hidden;
319
- width: 100px;
320
- background-color: #222;
321
- color: #fff;
322
- /*font-weight: bold;*/
323
- font-size: 12px;
324
- text-align: center;
325
- padding: 4px 10px;
326
- border-radius: 6px;
327
-
328
- /* Position the tooltip text - see examples below! */
329
- position: absolute;
330
- z-index: 2;
331
- top: -90%; /* Must leave a small gap between tooltip and button */
332
- left: 50px;
333
-
334
- /* transform: translate (50%,0%); */
335
- }
336
-
337
- /* Show the tooltip text when you mouse over the tooltip container */
338
- .Toolbar-button:hover .tooltiptext {
339
- animation: 0.8s fadeIn2;
340
- animation-fill-mode: forwards;
341
- visibility: visible;
342
- /* width: 100px; */
343
- /* top: -90%; */ /* Must leave a small gap between tooltip and button */
344
- /* left: 20%; */
345
- /* margin-left: -50px; */
346
- }
347
-
348
- @keyframes fadeIn2 {
349
- 00% {
350
- opacity: 0;
351
- }
352
- 70% {
353
- opacity: 0;
354
- }
355
- 100% {
356
- visibility: visible;
357
- opacity: 0.9;
358
- }
359
- }
360
-
361
- /* .tooltip {
362
- position: relative;
363
- display: inline-block;
364
- border-bottom: 1px dotted black; /* If you want dots under the hoverable text
365
- } */
366
366
  /* Note that the top left position of the accent bar is set programatically in componentDidMount */
367
367
 
368
368
  .AccentBar {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zzish/math-rich-input",
3
- "version": "0.1.28",
3
+ "version": "0.1.30",
4
4
  "description": "React component for user to enter rich text with embedded math equations.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -194,7 +194,7 @@ export default class MathRichInput extends React.Component {
194
194
  this.moveCursorOnInsert = false;
195
195
 
196
196
  // Elements defining the current state of range
197
- this.rangeParamsToSetAfterComponentUpdate = null; // Set this to update the selection after rendering
197
+ this.afterComponentUpdateData = null; // Set this to update the selection after rendering
198
198
  this.lastSetRangeParmas = null; // This is set automatically each time the range params are set with setRangeParams
199
199
 
200
200
  this.lastSetActiveButtons = null;
@@ -286,20 +286,10 @@ export default class MathRichInput extends React.Component {
286
286
  isExpertMode,
287
287
  selectedTab
288
288
  ) => {
289
- // if (this.props.outputTex !== null && this.props.outputTex !== undefined && this.props.outputTex) {
290
- // if (mimeType === MIME_TYPE_HTML) {
291
- // console.warn("Html found when outputTex=true")
292
- // value = convertHtmlToPlainText(value)
293
- // mimeType = MIME_TYPE_PLAIN_TEXT
294
- // } else if (mimeType === MIME_TYPE_ZZISH_HTML_MATH) {
295
- // value = convertHtmlMathToTex(value)
296
- // mimeType = MIME_TYPE_TEX
297
- // }
298
- // }
299
-
300
289
  // rangeParams, isExpertMode and selectedTab can be null, in which case we will set them
301
290
  if (rangeParams === null) rangeParams = this.lastSetRangeParams;
302
- else this.rangeParamsToSetAfterComponentUpdate = rangeParams;
291
+
292
+ this.afterComponentUpdateData = { rangeParams, value };
303
293
 
304
294
  let options = this.props.options || DEFAULT_OPTIONS;
305
295
  if (isExpertMode === null) isExpertMode = options.isExpertMode;
@@ -461,7 +451,7 @@ export default class MathRichInput extends React.Component {
461
451
  }
462
452
 
463
453
  if (deleteToEmpty) {
464
- console.log("deleteToEmpty")
454
+ console.log("deleteToEmpty");
465
455
  let new_rangeParams = {
466
456
  startNodeIndex: 0,
467
457
  startOffset: 1,
@@ -477,7 +467,7 @@ export default class MathRichInput extends React.Component {
477
467
  this.props.useExpertMode,
478
468
  this.props.selectedTab
479
469
  );
480
- e.preventDefault()
470
+ e.preventDefault();
481
471
  return;
482
472
  }
483
473
 
@@ -590,112 +580,25 @@ export default class MathRichInput extends React.Component {
590
580
  let index = rangeParams.startNodeIndex;
591
581
  let offset = rangeParams.startOffset;
592
582
 
593
- console.log("handleKeyDownArrowLeft")
594
- console.log(rangeParams)
595
- let new_globalOffset = rangeParams.startGlobalOffset - 1;
596
-
597
- let new_rangeParams = {
598
- startGlobalOffset: new_globalOffset,
599
- endGlobalOffset: new_globalOffset,
600
- };
601
- console.log(new_rangeParams)
602
- e.preventDefault();
603
- this._setRangeParams(new_rangeParams);
604
- return;
605
-
606
- // console.log("Old: "+index+"->"+offset)
607
-
608
- // The user shouldn't be in a katex node, but lets deal with it anyway
609
- let node = this._findNodeWithIndex(index);
610
- if (isKatexNode(node)) {
611
- console.warn("Cursor is inside katex node");
612
- let new_index = index - 1; // Jump out of the latex node
613
- let prev_node = this._findNodeWithIndex(index - 1);
614
- let new_offset = getNodeTextLength(prev_node);
615
-
616
- let new_rangeParams = {
617
- startNodeIndex: new_index,
618
- startOffset: new_offset,
619
- endNodeIndex: new_index,
620
- endOffset: new_offset,
621
- startGlobalOffset: new_globalOffset,
583
+ console.log("handleKeyDownArrowLeft");
584
+ console.log(rangeParams);
585
+ let new_globalOffset = rangeParams.endGlobalOffset - 1;
586
+ let new_rangeParams = null;
587
+ if (e.shiftKey && new_globalOffset > rangeParams.startGlobalOffset) {
588
+ new_rangeParams = {
589
+ startGlobalOffset: rangeParams.startGlobalOffset,
622
590
  endGlobalOffset: new_globalOffset,
623
591
  };
624
- this._setRangeParams(new_rangeParams);
625
- e.preventDefault();
626
- return;
627
- }
628
-
629
- if (offset > 2) return;
630
-
631
- let new_index = -1;
632
- let new_offset = -1;
633
-
634
- // Deal with case of inserted small space at start of <p> element or after katex node
635
- if (offset === 2) {
636
- new_index = index;
637
- if (this.nodeStartsWithSmallSpace(node)) {
638
- if (index > 0 && isKatexNode(this._findNodeWithIndex(index - 1)))
639
- new_offset = 1;
640
- else new_offset = 0;
641
- } else new_offset = 1;
642
- }
643
-
644
- if (offset === 1) {
645
- if (this.nodeStartsWithSmallSpace(node)) {
646
- if (index === 0) {
647
- e.preventDefault();
648
- return;
649
- }
650
- let prev_node = this._findNodeWithIndex(index - 1);
651
- if (index >= 2 && isKatexNode(prev_node)) new_index = index - 2;
652
- else new_index = index - 1;
653
-
654
- let new_node = this._findNodeWithIndex(new_index);
655
- new_offset = getNodeTextLength(new_node);
656
- } else {
657
- new_index = index;
658
- new_offset = 0;
659
- }
660
- }
661
-
662
- if (offset === 0) {
663
- let prev_node = this._findNodeWithIndex(index - 1);
664
- if (index >= 2 && isKatexNode(prev_node)) new_index = index - 2;
665
- else new_index = index - 1;
666
- let new_node = this._findNodeWithIndex(new_index);
667
- new_offset = getNodeTextLength(new_node);
668
- if (new_offset === 1) {
669
- if (this.nodeStartsWithSmallSpace(new_node)) {
670
- if (index > 0 && isKatexNode(this._findNodeWithIndex(index - 1)))
671
- new_offset = 1;
672
- else new_offset = 0;
673
- }
674
- }
675
- }
676
-
677
- // Move cursor to start of field if in starting small space
678
- if (
679
- new_index === 0 &&
680
- new_offset === 1 &&
681
- this.inputStartsWithSmallSpace()
682
- ) {
683
- new_offset = 0;
684
- }
685
-
686
- if (new_index === -1 || new_offset === -1) return;
687
- else {
688
- let new_rangeParams = {
689
- startNodeIndex: new_index,
690
- startOffset: new_offset,
691
- endNodeIndex: new_index,
692
- endOffset: new_offset,
592
+ } else {
593
+ new_rangeParams = {
693
594
  startGlobalOffset: new_globalOffset,
694
595
  endGlobalOffset: new_globalOffset,
695
596
  };
696
- this._setRangeParams(new_rangeParams);
697
- e.preventDefault();
698
597
  }
598
+ console.log(new_rangeParams);
599
+ e.preventDefault();
600
+ this._setRangeParams(new_rangeParams);
601
+ return;
699
602
  };
700
603
 
701
604
  handleKeyDownArrowRight = (e) => {
@@ -704,103 +607,22 @@ export default class MathRichInput extends React.Component {
704
607
  let index = rangeParams.startNodeIndex;
705
608
  let offset = rangeParams.startOffset;
706
609
 
707
- let new_globalOffset = rangeParams.startGlobalOffset + 1;
708
- let new_rangeParams = {
709
- startGlobalOffset: new_globalOffset,
710
- endGlobalOffset: new_globalOffset,
711
- };
712
- e.preventDefault();
713
- this._setRangeParams(new_rangeParams);
714
- return;
715
-
716
- if (index < 0)
717
- // Empty input field
718
- return;
719
-
720
- let node = this._findNodeWithIndex(index);
721
- let length = getNodeTextLength(node);
722
-
723
- // The user shouldn't be in a katex node, but lets deal with it anyway
724
- if (isKatexNode(node)) {
725
- console.warn("Cursor is inside katex node");
726
- let new_index = index + 1; // Jump out of the latex node
727
- let new_offset = SMALL_SPACE_LENGTH; // As there will be a SMALL_SPACE at the start of the text node
728
-
729
- let new_rangeParams = {
730
- startNodeIndex: new_index,
731
- startOffset: new_offset,
732
- endNodeIndex: new_index,
733
- endOffset: new_offset,
610
+ let new_rangeParams = null;
611
+ let new_globalOffset = rangeParams.endGlobalOffset + 1;
612
+ if (e.shiftKey && new_globalOffset > rangeParams.startGlobalOffset) {
613
+ new_rangeParams = {
614
+ startGlobalOffset: rangeParams.startGlobalOffset,
615
+ endGlobalOffset: new_globalOffset,
734
616
  };
735
- this._setRangeParams(new_rangeParams);
736
- e.preventDefault();
737
- return;
738
- }
739
-
740
- // Deal with case of inserted small space at start of <p> element
741
- if (offset === 0) {
742
- if (this.nodeStartsWithSmallSpace(node)) {
743
- // console.log("Offset = 0 and node starts with small space");
744
- let new_index = -1;
745
- let new_offset = -1;
746
-
747
- if (node.nodeValue.length > 1) {
748
- new_index = index;
749
- new_offset = SMALL_SPACE_LENGTH + 1;
750
- } else {
751
- new_index = index + 1;
752
- let next_node = this._findNodeWithIndex(new_index);
753
- if (next_node !== null) {
754
- if (isKatexNode(next_node)) {
755
- new_index = index + 2;
756
- new_offset = SMALL_SPACE_LENGTH;
757
- } else {
758
- new_index = index + 1;
759
- new_offset = 0;
760
- }
761
- } else {
762
- new_index = index;
763
- new_offset = offset;
764
- }
765
- }
766
- let new_rangeParams = {
767
- startNodeIndex: new_index,
768
- startOffset: new_offset,
769
- endNodeIndex: new_index,
770
- endOffset: new_offset,
771
- };
772
- this._setRangeParams(new_rangeParams);
773
-
774
- e.preventDefault();
775
- return;
776
- }
777
- }
778
-
779
- // If at the end of a text node
780
- if (
781
- offset === length ||
782
- (index === 0 && this.inputStartsWithSmallSpace())
783
- ) {
784
- let next_node = this._findNodeWithIndex(index + 1);
785
-
786
- // If there is no next node, then we can't move, so do the default action
787
- // If the next node is a normal node, do the default action
788
- if (next_node === null || !isKatexNode(next_node)) return;
789
-
790
- let new_index = index + 2; // Jump over the latex node
791
- let new_offset = SMALL_SPACE_LENGTH; // As there will be a SMALL_SPACE at the start of the text node
792
-
793
- let new_rangeParams = {
794
- startNodeIndex: new_index,
795
- startOffset: new_offset,
796
- endNodeIndex: new_index,
797
- endOffset: new_offset,
617
+ } else {
618
+ new_rangeParams = {
619
+ startGlobalOffset: new_globalOffset,
620
+ endGlobalOffset: new_globalOffset,
798
621
  };
799
- this._setRangeParams(new_rangeParams);
800
-
801
- e.preventDefault();
802
- return;
803
622
  }
623
+ e.preventDefault();
624
+ this._setRangeParams(new_rangeParams);
625
+ return;
804
626
  };
805
627
 
806
628
  editableDivIsPlainText = () => {
@@ -1199,14 +1021,17 @@ export default class MathRichInput extends React.Component {
1199
1021
  }
1200
1022
  }
1201
1023
 
1202
- if (this.handleKeyDownAccentHelper(e))
1203
- return;
1024
+ if (this.handleKeyDownAccentHelper(e)) return;
1204
1025
 
1205
1026
  // Check if inserting character in element that starts with small space
1206
- if (e.key.length === 1 && // ie, it's not something like "arrowLeft"
1207
- params.startOffset === 0 &&
1208
- this.nodeStartsWithSmallSpace(startNode)) {
1209
- console.log("Handling character input at start of text node with small space")
1027
+ if (
1028
+ e.key.length === 1 && // ie, it's not something like "arrowLeft"
1029
+ params.startOffset === 0 &&
1030
+ this.nodeStartsWithSmallSpace(startNode)
1031
+ ) {
1032
+ console.log(
1033
+ "Handling character input at start of text node with small space"
1034
+ );
1210
1035
  this.insertAfterSmallSpace(e.key, params);
1211
1036
  e.preventDefault();
1212
1037
  return;
@@ -1311,14 +1136,14 @@ export default class MathRichInput extends React.Component {
1311
1136
 
1312
1137
  handleInput = (event) => {
1313
1138
  try {
1314
- console.log("handleInput")
1139
+ console.log("handleInput");
1315
1140
  let raw_text = elementToMarkedRawText(
1316
1141
  this.editableDiv,
1317
1142
  null,
1318
1143
  0,
1319
1144
  this.enableHtml()
1320
1145
  );
1321
- console.log("handleInput 2")
1146
+ console.log("handleInput 2");
1322
1147
  const params = this._getRangeParams();
1323
1148
  if (params === null || params === undefined)
1324
1149
  console.error("Could not get range params from input field");
@@ -1357,6 +1182,7 @@ export default class MathRichInput extends React.Component {
1357
1182
 
1358
1183
  updateActiveButtons = () => {
1359
1184
  try {
1185
+ console.log("updateActiveButtons");
1360
1186
  let rangeParams = this._getRangeParams();
1361
1187
  if (rangeParams === null || rangeParams === undefined) {
1362
1188
  console.warn(
@@ -1475,12 +1301,14 @@ export default class MathRichInput extends React.Component {
1475
1301
 
1476
1302
  componentDidUpdate() {
1477
1303
  try {
1304
+ console.log("componentDidUpdate");
1478
1305
  if (
1479
- this.rangeParamsToSetAfterComponentUpdate !== null &&
1480
- this.rangeParamsToSetAfterComponentUpdate !== undefined
1306
+ this.afterComponentUpdateData !== null &&
1307
+ this.afterComponentUpdateData !== undefined &&
1308
+ this.afterComponentUpdateData.value === this.props.value
1481
1309
  ) {
1482
- this._setRangeParams(this.rangeParamsToSetAfterComponentUpdate);
1483
- this.rangeParamsToSetAfterComponentUpdate = null;
1310
+ this._setRangeParams(this.afterComponentUpdateData.rangeParams);
1311
+ this.afterComponentUpdateData = null;
1484
1312
  this.updateActiveButtons();
1485
1313
  }
1486
1314
  } catch (error) {
@@ -1665,8 +1493,8 @@ export default class MathRichInput extends React.Component {
1665
1493
  let start_pos = this.markedRawText.indexOf(MARK);
1666
1494
  let end_pos = this.markedRawText.indexOf(MARK, start_pos + MARK.length);
1667
1495
  let oldRangeParams = this.getOldRangeParams();
1668
- console.log("Old range params")
1669
- console.log(oldRangeParams)
1496
+ console.log("Old range params");
1497
+ console.log(oldRangeParams);
1670
1498
 
1671
1499
  // Handle case of empty string returned
1672
1500
  if (latex === "") {
@@ -2123,10 +1951,10 @@ export default class MathRichInput extends React.Component {
2123
1951
  this.enableHtml()
2124
1952
  );
2125
1953
 
2126
- console.log("Raw text before line insert")
2127
- console.log(raw_text)
2128
- console.log("Range params before line insert")
2129
- console.log(rangeParams)
1954
+ console.log("Raw text before line insert");
1955
+ console.log(raw_text);
1956
+ console.log("Range params before line insert");
1957
+ console.log(rangeParams);
2130
1958
 
2131
1959
  let new_raw_text = null;
2132
1960
  let new_rangeParams = { ...rangeParams };
@@ -2146,7 +1974,6 @@ export default class MathRichInput extends React.Component {
2146
1974
  new_rangeParams.startGlobalOffset++;
2147
1975
  new_rangeParams.endGlobalOffset++;
2148
1976
  }
2149
-
2150
1977
  } else {
2151
1978
  new_raw_text = removeMarks(insertCharacterBeforeMarks(raw_text, "\n"));
2152
1979
  new_rangeParams.startOffset++;
@@ -2158,12 +1985,11 @@ export default class MathRichInput extends React.Component {
2158
1985
  this.props.mimeType,
2159
1986
  this.enableHtml()
2160
1987
  );
2161
-
2162
- console.log("New raw text after line insert")
2163
- console.log(new_raw_text)
2164
- console.log("New range params after line insert")
2165
- console.log(new_rangeParams)
2166
1988
 
1989
+ console.log("New raw text after line insert");
1990
+ console.log(new_raw_text);
1991
+ console.log("New range params after line insert");
1992
+ console.log(new_rangeParams);
2167
1993
 
2168
1994
  this.applyChangesToComponent(
2169
1995
  new_raw_text,
@@ -2183,34 +2009,39 @@ export default class MathRichInput extends React.Component {
2183
2009
  rangeParams = this._getRangeParams();
2184
2010
 
2185
2011
  if (rangeParams.startOffset !== 0)
2186
- console.warn("Unexpected startOffset "+rangeParams.startOffset+" in insertAfterSmallSpace")
2187
-
2012
+ console.warn(
2013
+ "Unexpected startOffset " +
2014
+ rangeParams.startOffset +
2015
+ " in insertAfterSmallSpace"
2016
+ );
2017
+
2188
2018
  let node = this._findNodeWithIndex(rangeParams.startNodeIndex);
2189
2019
  let raw_text = elementToMarkedRawText(
2190
- this.editableDiv,
2191
- node,
2192
- 1, // after small space
2193
- this.enableHtml()
2194
- );
2020
+ this.editableDiv,
2021
+ node,
2022
+ 1, // after small space
2023
+ this.enableHtml()
2024
+ );
2195
2025
 
2196
2026
  let new_raw_text = removeMarks(
2197
- insertCharacterBeforeMarks(raw_text, new_char))
2027
+ insertCharacterBeforeMarks(raw_text, new_char)
2028
+ );
2198
2029
 
2199
2030
  let new_rangeParams = {
2200
- startNodeIndex:rangeParams.startNodeIndex,
2201
- startNodeOffset:1+new_char.length,
2202
- endNodeIndex:rangeParams.startNodeIndex,
2203
- endNodeOffset:1+new_char.length,
2204
- startGlobalOffset:rangeParams.startGlobalOffset+new_char.length,
2205
- endGlobalOffset:rangeParams.endGlobalOffset+new_char.length,
2206
- }
2207
-
2031
+ startNodeIndex: rangeParams.startNodeIndex,
2032
+ startNodeOffset: 1 + new_char.length,
2033
+ endNodeIndex: rangeParams.startNodeIndex,
2034
+ endNodeOffset: 1 + new_char.length,
2035
+ startGlobalOffset: rangeParams.startGlobalOffset + new_char.length,
2036
+ endGlobalOffset: rangeParams.endGlobalOffset + new_char.length,
2037
+ };
2038
+
2208
2039
  new_raw_text = removeEncodingIfPlainText(
2209
2040
  new_raw_text,
2210
2041
  this.props.mimeType,
2211
2042
  this.enableHtml()
2212
2043
  );
2213
-
2044
+
2214
2045
  this.applyChangesToComponent(
2215
2046
  new_raw_text,
2216
2047
  this.props.mimeType,
@@ -2221,7 +2052,7 @@ export default class MathRichInput extends React.Component {
2221
2052
  } catch (error) {
2222
2053
  console.error(error);
2223
2054
  }
2224
- };
2055
+ }
2225
2056
 
2226
2057
  insertAccentLetter = (event, old_char, new_char) => {
2227
2058
  try {
@@ -2239,18 +2070,24 @@ export default class MathRichInput extends React.Component {
2239
2070
  let new_raw_text = null;
2240
2071
  let new_rangeParams = null;
2241
2072
 
2242
- if (old_char === null) { // insert new char
2243
- new_raw_text = removeMarks(insertCharacterBeforeMarks(raw_text, new_char));
2073
+ if (old_char === null) {
2074
+ // insert new char
2075
+ new_raw_text = removeMarks(
2076
+ insertCharacterBeforeMarks(raw_text, new_char)
2077
+ );
2244
2078
  new_rangeParams = {
2245
- startNodeIndex:rangeParams.startNodeIndex,
2246
- startOffset:rangeParams.startOffset + new_char.length,
2247
- endNodeIndex:rangeParams.startNodeIndex,
2248
- endOffset:rangeParams.startOffset + new_char.length,
2249
- startGlobalOffset:rangeParams.startGlobalOffset + new_char.length,
2250
- endGlobalOffset:rangeParams.startGlobalOffset + new_char.length
2251
- }
2252
- } else { // replace old char
2253
- new_raw_text = removeMarks(replaceCharacterBeforeMarks(raw_text, new_char));
2079
+ startNodeIndex: rangeParams.startNodeIndex,
2080
+ startOffset: rangeParams.startOffset + new_char.length,
2081
+ endNodeIndex: rangeParams.startNodeIndex,
2082
+ endOffset: rangeParams.startOffset + new_char.length,
2083
+ startGlobalOffset: rangeParams.startGlobalOffset + new_char.length,
2084
+ endGlobalOffset: rangeParams.startGlobalOffset + new_char.length,
2085
+ };
2086
+ } else {
2087
+ // replace old char
2088
+ new_raw_text = removeMarks(
2089
+ replaceCharacterBeforeMarks(raw_text, new_char)
2090
+ );
2254
2091
  new_rangeParams = { ...rangeParams };
2255
2092
  }
2256
2093
 
@@ -2259,7 +2096,7 @@ export default class MathRichInput extends React.Component {
2259
2096
  this.props.mimeType,
2260
2097
  this.enableHtml()
2261
2098
  );
2262
-
2099
+
2263
2100
  this.applyChangesToComponent(
2264
2101
  new_raw_text,
2265
2102
  this.props.mimeType,
@@ -79,10 +79,10 @@ function isBrNode(node) {
79
79
  }
80
80
 
81
81
  function nodeStartsWithSmallSpace(node) {
82
- if (node.nodeType === 3 &&
83
- node.nodeValue.length >= 1 &&
84
- node.nodeValue.charCodeAt(0) === SMALL_SPACE_CHAR_CODE)
85
- return true;
82
+ if (node.nodeType === 3 &&
83
+ node.nodeValue.length >= 1 &&
84
+ node.nodeValue.charCodeAt(0) === SMALL_SPACE_CHAR_CODE)
85
+ return true;
86
86
  return false;
87
87
  }
88
88
 
@@ -722,7 +722,7 @@ function findGlobalOffset(node, nodeToFind, offset, result=null) {
722
722
  result.offset ++
723
723
  }
724
724
 
725
- return false;
725
+ return false;
726
726
  }
727
727
 
728
728
  function findNodeAndOffsetForGlobalOffset(node, globalOffset, result=null) {
@@ -734,10 +734,14 @@ function findNodeAndOffsetForGlobalOffset(node, globalOffset, result=null) {
734
734
  if (isTextNode(node)) {
735
735
  result.node = node
736
736
  result.lastTextNode = node
737
+ console.log("Found text node \'"+node.nodeValue+"\' of length "+node.nodeValue.length)
738
+ console.log("result.offset was: "+result.offset)
737
739
  result.offset += node.nodeValue.length
738
- if (nodeStartsWithSmallSpace(node))
740
+ if (nodeStartsWithSmallSpace(node)) {
741
+ console.log("Text node starts with small space")
739
742
  result.offset -= 1
740
- // console.log("result.offset now: "+result.offset)
743
+ }
744
+ console.log("result.offset now: "+result.offset)
741
745
  return false
742
746
  }
743
747
  const childNodes = node.childNodes
@@ -758,8 +762,10 @@ function findNodeAndOffsetForGlobalOffset(node, globalOffset, result=null) {
758
762
  }
759
763
 
760
764
  if (node.nodeType === 1 && node.tagName === "P") {
765
+ console.log("Leaving p node")
761
766
  result.node = null
762
767
  result.offset ++
768
+ console.log("result.offset now: "+result.offset)
763
769
  }
764
770
  return false;
765
771
  }
@@ -780,6 +786,7 @@ export function findFirstTextNode(node) {
780
786
 
781
787
  function findNodeAndOffsetForGlobalOffsetInEditableDiv(editableDiv, globalOffset) {
782
788
  let result = {offset:0}
789
+ console.log("Finding node and offset within: "+editableDiv.outerHTML)
783
790
  findNodeAndOffsetForGlobalOffset(editableDiv, globalOffset, result)
784
791
  console.log(result)
785
792
 
@@ -796,18 +803,27 @@ function findNodeAndOffsetForGlobalOffsetInEditableDiv(editableDiv, globalOffset
796
803
  }
797
804
  }
798
805
 
799
- // if (result.offset === 0 &&
800
- // result.node.nodeValue.length > 0 &&
801
- // nodeStartsWithSmallSpace(result.node)) {
802
- // result.offset = 1
803
- // }
806
+ if (result.offset === 0 &&
807
+ result.node.nodeValue.length > 0 &&
808
+ nodeStartsWithSmallSpace(result.node)) {
809
+ result.offset = 1
810
+ }
811
+
812
+ if (result.offset > result.node.nodeValue.length) {
813
+ console.warn("Unexpected offset when converting global offset to node and offset")
814
+ console.log("Global offset: "+globalOffset)
815
+ console.log("Result:")
816
+ console.log(result)
817
+ console.log("result.offset > result.node.nodeValue.length")
818
+ result.offset = result.node.nodeValue.length
819
+ }
804
820
 
805
821
  return result
806
822
  }
807
823
 
808
824
  // https://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html
809
825
  export function getRangeParams(editableDiv) {
810
- // console.log ("getRangeParams")
826
+ console.log ("getRangeParams")
811
827
  // console.log("Inner html: "+editableDiv.innerHTML)
812
828
  const isSupported = typeof window.getSelection !== "undefined";
813
829
  if (!isSupported) {
@@ -822,6 +838,7 @@ export function getRangeParams(editableDiv) {
822
838
  }
823
839
 
824
840
  const range = selection.getRangeAt(0);
841
+
825
842
  // logAllDescendants(editableDiv)
826
843
  // If the range is not within a text node, move it to a text node
827
844
  // This typically happens when the end of a range is at the start of a new line
@@ -927,38 +944,34 @@ export function setRangeParams(editableDiv, params) {
927
944
 
928
945
  // New way of doing things
929
946
  if (params.startGlobalOffset !== null && params.startGlobalOffset !== undefined) {
947
+ console.log("Setting range from global offsets")
930
948
  setRangeParamsFromGlobalOffsets(editableDiv, params)
931
949
  return
932
950
  }
933
951
 
934
952
  // Otherwise use the old way of doing things
953
+ console.log("Setting range from node index and local offset")
935
954
 
936
955
  if (params.startNodeIndex === null || params.startNodeIndex === undefined) {
937
956
  console.error("Can't set range params: params.startNodeIndex === "+params.startNodeIndex)
938
957
  return
939
958
  }
940
-
941
- // console.log("Setting cursor to range params: "+params.startNodeIndex+"->"+params.startOffset)
942
- // console.log(params)
943
-
944
959
  if (params.startNodeIndex < 0) {
945
960
  console.error("Can't set range params: params.startNodeIndex < 0")
946
961
  return
947
962
  }
948
963
 
949
-
950
964
  let nodes = editableDiv.childNodes
951
965
  if (params.startNodeIndex === 0 && params.startOffset === 0 && nodes.length === 0) {
952
- // console.log("Not setting range params")
953
966
  return
954
967
  }
955
968
 
956
- // console.log("Node["+params.startNodeIndex+"]:")
957
- // console.log(nodes[params.startNodeIndex])
969
+ // Set the offsets within the nodes
958
970
  let startOffset = params.startOffset
959
971
  let endOffset = params.endOffset
960
972
 
961
973
  // Handle special case of auto inserted SMALL CHAR at beginning of input
974
+ // TODO This sectin may no longer be neceesary and may be introducing a bug
962
975
  if (params.startNodeIndex === 0 &&
963
976
  params.startOffset === 1 &&
964
977
  isSmallSpace(nodes[0]))
@@ -969,25 +982,26 @@ export function setRangeParams(editableDiv, params) {
969
982
  isSmallSpace(nodes[0]))
970
983
  endOffset = 0
971
984
 
985
+
986
+ // Find the nodes
972
987
  let startNode = findNodeWithIndex(editableDiv, params.startNodeIndex)
973
988
  let endNode = findNodeWithIndex(editableDiv, params.endNodeIndex)
974
989
 
975
- // Lets make sure we are setting
976
- // if (params.startNodeIndex !== 0 &&
977
- // params.startOffset === 0) {
978
- // if (getNodeText(startNode).charAt(0) === SMALL_SPACE)
979
- // startOffset = SMALL_SPACE.length
980
- // }
981
- // if (params.endNodeIndex !== 0 &&
982
- // params.endOffset === 0) {
983
- // if (getNodeText(endNode).charAt(0) === SMALL_SPACE)
984
- // endOffset = SMALL_SPACE.length
985
- // }
986
- // console.log("End: "+params.endNodeIndex+"->"+endOffset)
990
+ console.log("Setting range to start in node:")
991
+ console.log(" node type: "+startNode.nodeType)
992
+ console.log(" tag name: "+startNode.tagName)
993
+ console.log(" node value: "+startNode.nodeValue)
994
+ console.log(" offset:"+startOffset)
995
+
996
+ console.log("Setting range to end in node:")
997
+ console.log(" node type: "+endNode.nodeType)
998
+ console.log(" tag name: "+endNode.tagName)
999
+ console.log(" node value: "+endNode.nodeValue)
1000
+ console.log(" offset:"+endOffset)
987
1001
 
988
1002
  // Set range in document
989
1003
  if (startNode === null) {
990
- console.error("Could not set range to start node with index "+params.startNodeIndex)
1004
+ console.warn("Could not set range to start node with index "+params.startNodeIndex)
991
1005
  startNode = findFirstTextNode(editableDiv)
992
1006
  startOffset = 0
993
1007
  }
@@ -1004,7 +1018,7 @@ export function setRangeParams(editableDiv, params) {
1004
1018
  }
1005
1019
 
1006
1020
  if (endNode === null) {
1007
- console.error("Could not set range to end node with index "+params.endNodeIndex)
1021
+ console.warn("Could not set range to end node with index "+params.endNodeIndex)
1008
1022
  endNode = findFirstTextNode(editableDiv)
1009
1023
  endOffset = 0
1010
1024
  }
@@ -1021,13 +1035,21 @@ export function setRangeParams(editableDiv, params) {
1021
1035
  }
1022
1036
 
1023
1037
  new_range = document.createRange();
1038
+ if (startOffset > startNode.nodeValue.length) {
1039
+ console.warn("endOffset > endNode.nodeValue.length when setting range: "+
1040
+ startOffset+ " > "+startNode.nodeValue.length+
1041
+ " - "+stateNode.nodeType+
1042
+ " - "+startNode.nodeValue)
1043
+ startOffset = startNode.nodeValue.length
1044
+ }
1045
+
1024
1046
  new_range.setStart(startNode, startOffset);
1025
- if (endOffset > endNode.length) {
1026
- console.warn("endOffset > endNode.length when setting range: "+
1027
- endOffset+ " > "+endNode.length+
1047
+ if (endOffset > endNode.nodeValue.length) {
1048
+ console.warn("endOffset > endNode.nodeValue.length when setting range: "+
1049
+ endOffset+ " > "+endNode.nodeValue.length+
1028
1050
  " - "+endNode.nodeType+
1029
1051
  " - "+endNode.nodeValue)
1030
- endOffset = endNode.length
1052
+ endOffset = endNode.nodeValue.length
1031
1053
  }
1032
1054
  new_range.setEnd(endNode, endOffset);
1033
1055