tiny-markdown-editor 0.1.3 → 0.1.5

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/lib/TinyMDE.js CHANGED
@@ -1,122 +1,56 @@
1
1
  "use strict";
2
2
 
3
- require("core-js/modules/es.symbol");
4
-
5
- require("core-js/modules/es.symbol.description");
6
-
7
- require("core-js/modules/es.symbol.iterator");
8
-
9
- require("core-js/modules/es.symbol.replace");
10
-
11
- require("core-js/modules/es.array.concat");
12
-
13
- require("core-js/modules/es.array.from");
14
-
15
- require("core-js/modules/es.array.includes");
16
-
17
- require("core-js/modules/es.array.index-of");
18
-
19
- require("core-js/modules/es.array.iterator");
20
-
21
- require("core-js/modules/es.array.join");
22
-
23
- require("core-js/modules/es.array.reduce");
24
-
25
- require("core-js/modules/es.array.slice");
26
-
27
- require("core-js/modules/es.array.splice");
28
-
29
- require("core-js/modules/es.function.name");
30
-
31
- require("core-js/modules/es.map");
32
-
33
- require("core-js/modules/es.object.assign");
34
-
35
- require("core-js/modules/es.object.get-prototype-of");
36
-
37
- require("core-js/modules/es.object.keys");
38
-
39
- require("core-js/modules/es.object.to-string");
40
-
41
- require("core-js/modules/es.reflect.construct");
42
-
43
- require("core-js/modules/es.regexp.constructor");
44
-
45
- require("core-js/modules/es.regexp.exec");
46
-
47
- require("core-js/modules/es.regexp.to-string");
48
-
49
- require("core-js/modules/es.string.includes");
50
-
51
- require("core-js/modules/es.string.iterator");
52
-
53
- require("core-js/modules/es.string.match");
54
-
55
- require("core-js/modules/es.string.replace");
56
-
57
- require("core-js/modules/es.string.split");
58
-
59
- require("core-js/modules/es.string.trim");
60
-
61
- require("core-js/modules/es.weak-map");
62
-
63
- require("core-js/modules/web.dom-collections.iterator");
64
-
3
+ require("core-js/modules/es.array.slice.js");
4
+ require("core-js/modules/es.object.to-string.js");
5
+ require("core-js/modules/es.array.from.js");
6
+ require("core-js/modules/es.string.iterator.js");
7
+ require("core-js/modules/es.symbol.js");
8
+ require("core-js/modules/es.symbol.description.js");
9
+ require("core-js/modules/es.symbol.iterator.js");
10
+ require("core-js/modules/es.array.iterator.js");
11
+ require("core-js/modules/web.dom-collections.iterator.js");
12
+ require("core-js/modules/es.object.set-prototype-of.js");
13
+ require("core-js/modules/es.regexp.constructor.js");
14
+ require("core-js/modules/es.regexp.to-string.js");
15
+ require("core-js/modules/es.weak-map.js");
16
+ require("core-js/modules/es.array.reduce.js");
17
+ require("core-js/modules/es.object.keys.js");
18
+ require("core-js/modules/es.symbol.replace.js");
65
19
  Object.defineProperty(exports, "__esModule", {
66
20
  value: true
67
21
  });
68
22
  exports.default = void 0;
69
-
23
+ require("core-js/modules/es.regexp.exec.js");
24
+ require("core-js/modules/es.string.split.js");
25
+ require("core-js/modules/es.string.replace.js");
26
+ require("core-js/modules/es.string.match.js");
27
+ require("core-js/modules/es.string.trim.js");
28
+ require("core-js/modules/es.array.concat.js");
29
+ require("core-js/modules/es.parse-int.js");
30
+ require("core-js/modules/es.array.splice.js");
31
+ require("core-js/modules/es.array.includes.js");
32
+ require("core-js/modules/es.string.includes.js");
33
+ require("core-js/modules/es.object.assign.js");
34
+ require("core-js/modules/es.object.define-property.js");
70
35
  var _grammar = require("./grammar");
71
-
72
- function _wrapRegExp(re, groups) { _wrapRegExp = function _wrapRegExp(re, groups) { return new BabelRegExp(re, undefined, groups); }; var _RegExp = _wrapNativeSuper(RegExp); var _super = RegExp.prototype; var _groups = new WeakMap(); function BabelRegExp(re, flags, groups) { var _this = _RegExp.call(this, re, flags); _groups.set(_this, groups || _groups.get(re)); return _this; } _inherits(BabelRegExp, _RegExp); BabelRegExp.prototype.exec = function (str) { var result = _super.exec.call(this, str); if (result) result.groups = buildGroups(result, this); return result; }; BabelRegExp.prototype[Symbol.replace] = function (str, substitution) { if (typeof substitution === "string") { var groups = _groups.get(this); return _super[Symbol.replace].call(this, str, substitution.replace(/\$<([^>]+)>/g, function (_, name) { return "$" + groups[name]; })); } else if (typeof substitution === "function") { var _this = this; return _super[Symbol.replace].call(this, str, function () { var args = []; args.push.apply(args, arguments); if (_typeof(args[args.length - 1]) !== "object") { args.push(buildGroups(args, _this)); } return substitution.apply(this, args); }); } else { return _super[Symbol.replace].call(this, str, substitution); } }; function buildGroups(result, re) { var g = _groups.get(re); return Object.keys(g).reduce(function (groups, name) { groups[name] = result[g[name]]; return groups; }, Object.create(null)); } return _wrapRegExp.apply(this, arguments); }
73
-
74
- function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
75
-
76
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
77
-
78
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
79
-
80
- function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }
81
-
82
- function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
83
-
84
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
85
-
86
- function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }
87
-
88
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
89
-
90
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
91
-
36
+ function _wrapRegExp() { _wrapRegExp = function _wrapRegExp(re, groups) { return new BabelRegExp(re, void 0, groups); }; var _super = RegExp.prototype, _groups = new WeakMap(); function BabelRegExp(re, flags, groups) { var _this = new RegExp(re, flags); return _groups.set(_this, groups || _groups.get(re)), _setPrototypeOf(_this, BabelRegExp.prototype); } function buildGroups(result, re) { var g = _groups.get(re); return Object.keys(g).reduce(function (groups, name) { var i = g[name]; if ("number" == typeof i) groups[name] = result[i];else { for (var k = 0; void 0 === result[i[k]] && k + 1 < i.length;) { k++; } groups[name] = result[i[k]]; } return groups; }, Object.create(null)); } return _inherits(BabelRegExp, RegExp), BabelRegExp.prototype.exec = function (str) { var result = _super.exec.call(this, str); if (result) { result.groups = buildGroups(result, this); var indices = result.indices; indices && (indices.groups = buildGroups(indices, this)); } return result; }, BabelRegExp.prototype[Symbol.replace] = function (str, substitution) { if ("string" == typeof substitution) { var groups = _groups.get(this); return _super[Symbol.replace].call(this, str, substitution.replace(/\$<([^>]+)>/g, function (_, name) { var group = groups[name]; return "$" + (Array.isArray(group) ? group.join("$") : group); })); } if ("function" == typeof substitution) { var _this = this; return _super[Symbol.replace].call(this, str, function () { var args = arguments; return "object" != _typeof(args[args.length - 1]) && (args = [].slice.call(args)).push(buildGroups(args, _this)), substitution.apply(this, args); }); } return _super[Symbol.replace].call(this, str, substitution); }, _wrapRegExp.apply(this, arguments); }
37
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
38
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
92
39
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
93
-
94
40
  function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
95
-
96
- function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
97
-
41
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
98
42
  function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
99
-
100
- function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
101
-
102
- function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
103
-
43
+ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
44
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
104
45
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
105
-
106
46
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
107
-
108
47
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
109
-
110
48
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
111
-
112
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
113
-
49
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
114
50
  var Editor = /*#__PURE__*/function () {
115
51
  function Editor() {
116
52
  var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
117
-
118
53
  _classCallCheck(this, Editor);
119
-
120
54
  this.e = null;
121
55
  this.textarea = null;
122
56
  this.lines = [];
@@ -133,77 +67,67 @@ var Editor = /*#__PURE__*/function () {
133
67
  };
134
68
  var element = props.element;
135
69
  this.textarea = props.textarea;
136
-
137
70
  if (this.textarea && !this.textarea.tagName) {
138
71
  this.textarea = document.getElementById(this.textarea);
139
72
  if (!element) element = this.textarea;
140
73
  }
141
-
142
74
  if (element && !element.tagName) {
143
75
  element = document.getElementById(props.element);
144
76
  }
145
-
146
77
  if (!element) {
147
78
  element = document.getElementsByTagName('body')[0];
148
79
  }
149
-
150
80
  if (element.tagName == 'TEXTAREA') {
151
81
  this.textarea = element;
152
82
  element = this.textarea.parentNode;
153
83
  }
154
-
155
84
  if (this.textarea) {
156
85
  this.textarea.style.display = 'none';
157
86
  }
158
-
159
- this.createEditorElement(element); // TODO Placeholder for empty content
160
-
87
+ this.createEditorElement(element);
88
+ // TODO Placeholder for empty content
161
89
  this.setContent(props.content || (this.textarea ? this.textarea.value : false) || '# Hello TinyMDE!\nEdit **here**');
162
90
  }
91
+
163
92
  /**
164
93
  * Creates the editor element inside the target element of the DOM tree
165
94
  * @param element The target element of the DOM tree
166
95
  */
167
-
168
-
169
96
  _createClass(Editor, [{
170
97
  key: "createEditorElement",
171
98
  value: function createEditorElement(element) {
172
99
  var _this = this;
173
-
174
100
  this.e = document.createElement('div');
175
101
  this.e.className = 'TinyMDE';
176
- this.e.contentEditable = true; // The following is important for formatting purposes, but also since otherwise the browser replaces subsequent spaces with &nbsp; &nbsp;
102
+ this.e.contentEditable = true;
103
+ // The following is important for formatting purposes, but also since otherwise the browser replaces subsequent spaces with &nbsp; &nbsp;
177
104
  // That breaks a lot of stuff, so we do this here and not in CSS—therefore, you don't have to remember to but this in the CSS file
178
-
179
- this.e.style.whiteSpace = 'pre-wrap'; // Avoid formatting (B / I / U) popping up on iOS
180
-
105
+ this.e.style.whiteSpace = 'pre-wrap';
106
+ // Avoid formatting (B / I / U) popping up on iOS
181
107
  this.e.style.webkitUserModify = 'read-write-plaintext-only';
182
-
183
108
  if (this.textarea && this.textarea.parentNode == element && this.textarea.nextSibling) {
184
109
  element.insertBefore(this.e, this.textarea.nextSibling);
185
110
  } else {
186
111
  element.appendChild(this.e);
187
112
  }
188
-
189
113
  this.e.addEventListener("input", function (e) {
190
114
  return _this.handleInputEvent(e);
191
- }); // this.e.addEventListener("keydown", (e) => this.handleKeydownEvent(e));
192
-
115
+ });
116
+ // this.e.addEventListener("keydown", (e) => this.handleKeydownEvent(e));
193
117
  document.addEventListener("selectionchange", function (e) {
194
118
  return _this.handleSelectionChangeEvent(e);
195
119
  });
196
120
  this.e.addEventListener("paste", function (e) {
197
121
  return _this.handlePaste(e);
198
- }); // this.e.addEventListener('keydown', (e) => this.handleKeyDown(e));
199
-
122
+ });
123
+ // this.e.addEventListener('keydown', (e) => this.handleKeyDown(e));
200
124
  this.lineElements = this.e.childNodes; // this will automatically update
201
125
  }
126
+
202
127
  /**
203
128
  * Sets the editor content.
204
129
  * @param {string} content The new Markdown content
205
130
  */
206
-
207
131
  }, {
208
132
  key: "setContent",
209
133
  value: function setContent(content) {
@@ -211,60 +135,57 @@ var Editor = /*#__PURE__*/function () {
211
135
  while (this.e.firstChild) {
212
136
  this.e.removeChild(this.e.firstChild);
213
137
  }
214
-
215
138
  this.lines = content.split(/(?:\r\n|\r|\n)/);
216
139
  this.lineDirty = [];
217
-
218
140
  for (var lineNum = 0; lineNum < this.lines.length; lineNum++) {
219
141
  var le = document.createElement('div');
220
142
  this.e.appendChild(le);
221
143
  this.lineDirty.push(true);
222
144
  }
223
-
224
145
  this.lineTypes = new Array(this.lines.length);
225
146
  this.updateFormatting();
226
147
  this.fireChange();
227
148
  }
149
+
228
150
  /**
229
151
  * Gets the editor content as a Markdown string.
230
152
  * @returns {string} The editor content as a markdown string
231
153
  */
232
-
233
154
  }, {
234
155
  key: "getContent",
235
156
  value: function getContent() {
236
157
  return this.lines.join('\n');
237
158
  }
159
+
238
160
  /**
239
161
  * This is the main method to update the formatting (from this.lines to HTML output)
240
162
  */
241
-
242
163
  }, {
243
164
  key: "updateFormatting",
244
165
  value: function updateFormatting() {
245
166
  // First, parse line types. This will update this.lineTypes, this.lineReplacements, and this.lineCaptures
246
167
  // We don't apply the formatting yet
247
- this.updateLineTypes(); // Collect any valid link labels from link reference definitions—we need that for formatting to determine what's a valid link
248
-
249
- this.updateLinkLabels(); // Now, apply the formatting
250
-
168
+ this.updateLineTypes();
169
+ // Collect any valid link labels from link reference definitions—we need that for formatting to determine what's a valid link
170
+ this.updateLinkLabels();
171
+ // Now, apply the formatting
251
172
  this.applyLineTypes();
252
173
  }
174
+
253
175
  /**
254
176
  * Updates this.linkLabels: For every link reference definition (line type TMLinkReferenceDefinition), we collect the label
255
177
  */
256
-
257
178
  }, {
258
179
  key: "updateLinkLabels",
259
180
  value: function updateLinkLabels() {
260
181
  this.linkLabels = [];
261
-
262
182
  for (var l = 0; l < this.lines.length; l++) {
263
183
  if (this.lineTypes[l] == 'TMLinkReferenceDefinition') {
264
184
  this.linkLabels.push(this.lineCaptures[l][_grammar.lineGrammar.TMLinkReferenceDefinition.labelPlaceholder]);
265
185
  }
266
186
  }
267
187
  }
188
+
268
189
  /**
269
190
  * Helper function to replace placeholders from a RegExp capture. The replacement string can contain regular dollar placeholders (e.g., $1),
270
191
  * which are interpreted like in String.replace(), but also double dollar placeholders ($$1). In the case of double dollar placeholders,
@@ -275,30 +196,28 @@ var Editor = /*#__PURE__*/function () {
275
196
  * @param capture The result of a RegExp.exec() call
276
197
  * @returns The replacement string, with placeholders replaced from the capture result.
277
198
  */
278
-
279
199
  }, {
280
200
  key: "replace",
281
201
  value: function replace(replacement, capture) {
282
202
  var _this2 = this;
283
-
284
203
  return replacement.replace(/\$\$([0-9])/g, function (str, p1) {
285
204
  return "<span class=\"TMInlineFormatted\">".concat(_this2.processInlineStyles(capture[p1]), "</span>");
286
205
  }).replace(/\$([0-9])/g, function (str, p1) {
287
206
  return (0, _grammar.htmlescape)(capture[p1]);
288
207
  });
289
208
  }
209
+
290
210
  /**
291
211
  * Applies the line types (from this.lineTypes as well as the capture result in this.lineReplacements and this.lineCaptures)
292
212
  * and processes inline formatting for all lines.
293
213
  */
294
-
295
214
  }, {
296
215
  key: "applyLineTypes",
297
216
  value: function applyLineTypes() {
298
217
  for (var lineNum = 0; lineNum < this.lines.length; lineNum++) {
299
218
  if (this.lineDirty[lineNum]) {
300
- var contentHTML = this.replace(this.lineReplacements[lineNum], this.lineCaptures[lineNum]); // this.lineHTML[lineNum] = (contentHTML == '' ? '<br />' : contentHTML); // Prevent empty elements which can't be selected etc.
301
-
219
+ var contentHTML = this.replace(this.lineReplacements[lineNum], this.lineCaptures[lineNum]);
220
+ // this.lineHTML[lineNum] = (contentHTML == '' ? '<br />' : contentHTML); // Prevent empty elements which can't be selected etc.
302
221
  this.lineElements[lineNum].className = this.lineTypes[lineNum];
303
222
  this.lineElements[lineNum].removeAttribute('style');
304
223
  this.lineElements[lineNum].innerHTML = contentHTML == '' ? '<br />' : contentHTML; // Prevent empty elements which can't be selected etc.
@@ -307,30 +226,28 @@ var Editor = /*#__PURE__*/function () {
307
226
  this.lineElements[lineNum].dataset.lineNum = lineNum;
308
227
  }
309
228
  }
229
+
310
230
  /**
311
231
  * Determines line types for all lines based on the line / block grammar. Captures the results of the respective line
312
232
  * grammar regular expressions.
313
233
  * Updates this.lineTypes, this.lineCaptures, and this.lineReplacements.
314
234
  */
315
-
316
235
  }, {
317
236
  key: "updateLineTypes",
318
237
  value: function updateLineTypes() {
319
238
  var codeBlockType = false;
320
239
  var codeBlockSeqLength = 0;
321
240
  var htmlBlock = false;
322
-
323
241
  for (var lineNum = 0; lineNum < this.lines.length; lineNum++) {
324
242
  var lineType = 'TMPara';
325
243
  var lineCapture = [this.lines[lineNum]];
326
244
  var lineReplacement = '$$0'; // Default replacement for paragraph: Inline format the entire line
245
+
327
246
  // Check ongoing code blocks
328
247
  // if (lineNum > 0 && (this.lineTypes[lineNum - 1] == 'TMCodeFenceBacktickOpen' || this.lineTypes[lineNum - 1] == 'TMFencedCodeBacktick')) {
329
-
330
248
  if (codeBlockType == 'TMCodeFenceBacktickOpen') {
331
249
  // We're in a backtick-fenced code block, check if the current line closes it
332
250
  var capture = _grammar.lineGrammar.TMCodeFenceBacktickClose.regexp.exec(this.lines[lineNum]);
333
-
334
251
  if (capture && capture.groups['seq'].length >= codeBlockSeqLength) {
335
252
  lineType = 'TMCodeFenceBacktickClose';
336
253
  lineReplacement = _grammar.lineGrammar.TMCodeFenceBacktickClose.replacement;
@@ -341,32 +258,30 @@ var Editor = /*#__PURE__*/function () {
341
258
  lineReplacement = '$0';
342
259
  lineCapture = [this.lines[lineNum]];
343
260
  }
344
- } // if (lineNum > 0 && (this.lineTypes[lineNum - 1] == 'TMCodeFenceTildeOpen' || this.lineTypes[lineNum - 1] == 'TMFencedCodeTilde')) {
261
+ }
262
+ // if (lineNum > 0 && (this.lineTypes[lineNum - 1] == 'TMCodeFenceTildeOpen' || this.lineTypes[lineNum - 1] == 'TMFencedCodeTilde')) {
345
263
  else if (codeBlockType == 'TMCodeFenceTildeOpen') {
346
- // We're in a tilde-fenced code block
347
- var _capture = _grammar.lineGrammar.TMCodeFenceTildeClose.regexp.exec(this.lines[lineNum]);
348
-
349
- if (_capture && _capture.groups['seq'].length >= codeBlockSeqLength) {
350
- lineType = 'TMCodeFenceTildeClose';
351
- lineReplacement = _grammar.lineGrammar.TMCodeFenceTildeClose.replacement;
352
- lineCapture = _capture;
353
- codeBlockType = false;
354
- } else {
355
- lineType = 'TMFencedCodeTilde';
356
- lineReplacement = '$0';
357
- lineCapture = [this.lines[lineNum]];
358
- }
359
- } // Check HTML block types
360
-
264
+ // We're in a tilde-fenced code block
265
+ var _capture = _grammar.lineGrammar.TMCodeFenceTildeClose.regexp.exec(this.lines[lineNum]);
266
+ if (_capture && _capture.groups['seq'].length >= codeBlockSeqLength) {
267
+ lineType = 'TMCodeFenceTildeClose';
268
+ lineReplacement = _grammar.lineGrammar.TMCodeFenceTildeClose.replacement;
269
+ lineCapture = _capture;
270
+ codeBlockType = false;
271
+ } else {
272
+ lineType = 'TMFencedCodeTilde';
273
+ lineReplacement = '$0';
274
+ lineCapture = [this.lines[lineNum]];
275
+ }
276
+ }
361
277
 
278
+ // Check HTML block types
362
279
  if (lineType == 'TMPara' && htmlBlock === false) {
363
280
  var _iterator = _createForOfIteratorHelper(_grammar.htmlBlockGrammar),
364
- _step;
365
-
281
+ _step;
366
282
  try {
367
283
  for (_iterator.s(); !(_step = _iterator.n()).done;) {
368
284
  var htmlBlockType = _step.value;
369
-
370
285
  if (this.lines[lineNum].match(htmlBlockType.start)) {
371
286
  // Matching start condition. Check if this tag can start here (not all start conditions allow breaking a paragraph).
372
287
  if (htmlBlockType.paraInterrupt || lineNum == 0 || !(this.lineTypes[lineNum - 1] == 'TMPara' || this.lineTypes[lineNum - 1] == 'TMUL' || this.lineTypes[lineNum - 1] == 'TMOL' || this.lineTypes[lineNum - 1] == 'TMBlockquote')) {
@@ -381,14 +296,12 @@ var Editor = /*#__PURE__*/function () {
381
296
  _iterator.f();
382
297
  }
383
298
  }
384
-
385
299
  if (htmlBlock !== false) {
386
300
  lineType = 'TMHTMLBlock';
387
301
  lineReplacement = '$0'; // No formatting in TMHTMLBlock
388
-
389
302
  lineCapture = [this.lines[lineNum]]; // This should already be set but better safe than sorry
390
- // Check if HTML block should be closed
391
303
 
304
+ // Check if HTML block should be closed
392
305
  if (htmlBlock.end) {
393
306
  // Specific end condition
394
307
  if (this.lines[lineNum].match(htmlBlock.end)) {
@@ -400,14 +313,13 @@ var Editor = /*#__PURE__*/function () {
400
313
  htmlBlock = false;
401
314
  }
402
315
  }
403
- } // Check all regexps if we haven't applied one of the code block types
404
-
316
+ }
405
317
 
318
+ // Check all regexps if we haven't applied one of the code block types
406
319
  if (lineType == 'TMPara') {
407
320
  for (var type in _grammar.lineGrammar) {
408
321
  if (_grammar.lineGrammar[type].regexp) {
409
322
  var _capture2 = _grammar.lineGrammar[type].regexp.exec(this.lines[lineNum]);
410
-
411
323
  if (_capture2) {
412
324
  lineType = type;
413
325
  lineReplacement = _grammar.lineGrammar[type].replacement;
@@ -416,39 +328,37 @@ var Editor = /*#__PURE__*/function () {
416
328
  }
417
329
  }
418
330
  }
419
- } // If we've opened a code block, remember that
420
-
331
+ }
421
332
 
333
+ // If we've opened a code block, remember that
422
334
  if (lineType == 'TMCodeFenceBacktickOpen' || lineType == 'TMCodeFenceTildeOpen') {
423
335
  codeBlockType = lineType;
424
336
  codeBlockSeqLength = lineCapture.groups['seq'].length;
425
- } // Link reference definition and indented code can't interrupt a paragraph
426
-
337
+ }
427
338
 
339
+ // Link reference definition and indented code can't interrupt a paragraph
428
340
  if ((lineType == 'TMIndentedCode' || lineType == 'TMLinkReferenceDefinition') && lineNum > 0 && (this.lineTypes[lineNum - 1] == 'TMPara' || this.lineTypes[lineNum - 1] == 'TMUL' || this.lineTypes[lineNum - 1] == 'TMOL' || this.lineTypes[lineNum - 1] == 'TMBlockquote')) {
429
341
  // Fall back to TMPara
430
342
  lineType = 'TMPara';
431
343
  lineCapture = [this.lines[lineNum]];
432
344
  lineReplacement = '$$0';
433
- } // Setext H2 markers that can also be interpreted as an empty list item should be regarded as such (as per CommonMark spec)
434
-
345
+ }
435
346
 
347
+ // Setext H2 markers that can also be interpreted as an empty list item should be regarded as such (as per CommonMark spec)
436
348
  if (lineType == 'TMSetextH2Marker') {
437
349
  var _capture3 = _grammar.lineGrammar.TMUL.regexp.exec(this.lines[lineNum]);
438
-
439
350
  if (_capture3) {
440
351
  lineType = 'TMUL';
441
352
  lineReplacement = _grammar.lineGrammar.TMUL.replacement;
442
353
  lineCapture = _capture3;
443
354
  }
444
- } // Setext headings are only valid if preceded by a paragraph (and if so, they change the type of the previous paragraph)
445
-
355
+ }
446
356
 
357
+ // Setext headings are only valid if preceded by a paragraph (and if so, they change the type of the previous paragraph)
447
358
  if (lineType == 'TMSetextH1Marker' || lineType == 'TMSetextH2Marker') {
448
359
  if (lineNum == 0 || this.lineTypes[lineNum - 1] != 'TMPara') {
449
360
  // Setext marker is invalid. However, a H2 marker might still be a valid HR, so let's check that
450
361
  var _capture4 = _grammar.lineGrammar.TMHR.regexp.exec(this.lines[lineNum]);
451
-
452
362
  if (_capture4) {
453
363
  // Valid HR
454
364
  lineType = 'TMHR';
@@ -464,34 +374,30 @@ var Editor = /*#__PURE__*/function () {
464
374
  // Valid setext marker. Change types of preceding para lines
465
375
  var headingLine = lineNum - 1;
466
376
  var headingLineType = lineType == 'TMSetextH1Marker' ? 'TMSetextH1' : 'TMSetextH2';
467
-
468
377
  do {
469
378
  if (this.lineTypes[headingLineType] != headingLineType) {
470
379
  this.lineTypes[headingLine] = headingLineType;
471
380
  this.lineDirty[headingLineType] = true;
472
381
  }
473
-
474
382
  this.lineReplacements[headingLine] = '$$0';
475
383
  this.lineCaptures[headingLine] = [this.lines[headingLine]];
476
384
  headingLine--;
477
385
  } while (headingLine >= 0 && this.lineTypes[headingLine] == 'TMPara');
478
386
  }
479
- } // Lastly, save the line style to be applied later
480
-
481
-
387
+ }
388
+ // Lastly, save the line style to be applied later
482
389
  if (this.lineTypes[lineNum] != lineType) {
483
390
  this.lineTypes[lineNum] = lineType;
484
391
  this.lineDirty[lineNum] = true;
485
392
  }
486
-
487
393
  this.lineReplacements[lineNum] = lineReplacement;
488
394
  this.lineCaptures[lineNum] = lineCapture;
489
395
  }
490
396
  }
397
+
491
398
  /**
492
399
  * Updates all line contents from the HTML, then re-applies formatting.
493
400
  */
494
-
495
401
  }, {
496
402
  key: "updateLineContentsAndFormatting",
497
403
  value: function updateLineContentsAndFormatting() {
@@ -499,6 +405,7 @@ var Editor = /*#__PURE__*/function () {
499
405
  this.updateLineContents();
500
406
  this.updateFormatting();
501
407
  }
408
+
502
409
  /**
503
410
  * Attempts to parse a link or image at the current position. This assumes that the opening [ or ![ has already been matched.
504
411
  * Returns false if this is not a valid link, image. See below for more information
@@ -508,7 +415,6 @@ var Editor = /*#__PURE__*/function () {
508
415
  * Otherwise returns an object with two properties: output is the string to be included in the processed output,
509
416
  * charCount is the number of input characters (from originalString) consumed.
510
417
  */
511
-
512
418
  }, {
513
419
  key: "parseLinkOrImage",
514
420
  value: function parseLinkOrImage(originalString, isImage) {
@@ -523,81 +429,74 @@ var Editor = /*#__PURE__*/function () {
523
429
  var linkLabel = [];
524
430
  var linkDetails = []; // If matched, this will be an array: [whitespace + link destination delimiter, link destination, link destination delimiter, whitespace, link title delimiter, link title, link title delimiter + whitespace]. All can be empty strings.
525
431
 
526
- textOuter: while (currentOffset < originalString.length && linkText === false
527
- /* empty string is okay */
528
- ) {
529
- var string = originalString.substr(currentOffset); // Capture any escapes and code blocks at current position, they bind more strongly than links
530
- // We don't have to actually process them here, that'll be done later in case the link / image is valid, but we need to skip over them.
432
+ textOuter: while (currentOffset < originalString.length && linkText === false /* empty string is okay */) {
433
+ var string = originalString.substr(currentOffset);
531
434
 
435
+ // Capture any escapes and code blocks at current position, they bind more strongly than links
436
+ // We don't have to actually process them here, that'll be done later in case the link / image is valid, but we need to skip over them.
532
437
  for (var _i = 0, _arr = ['escape', 'code', 'autolink', 'html']; _i < _arr.length; _i++) {
533
438
  var rule = _arr[_i];
534
-
535
439
  var cap = _grammar.inlineGrammar[rule].regexp.exec(string);
536
-
537
440
  if (cap) {
538
441
  currentOffset += cap[0].length;
539
442
  continue textOuter;
540
443
  }
541
- } // Check for image. It's okay for an image to be included in a link or image
542
-
444
+ }
543
445
 
446
+ // Check for image. It's okay for an image to be included in a link or image
544
447
  if (string.match(_grammar.inlineGrammar.imageOpen.regexp)) {
545
448
  // Opening image. It's okay if this is a matching pair of brackets
546
449
  bracketLevel++;
547
450
  currentOffset += 2;
548
451
  continue textOuter;
549
- } // Check for link (not an image because that would have been captured and skipped over above)
550
-
452
+ }
551
453
 
454
+ // Check for link (not an image because that would have been captured and skipped over above)
552
455
  if (string.match(_grammar.inlineGrammar.linkOpen.regexp)) {
553
456
  // Opening bracket. Two things to do:
554
457
  // 1) it's okay if this part of a pair of brackets.
555
458
  // 2) If we are currently trying to parse a link, this nested bracket musn't start a valid link (no nested links allowed)
556
- bracketLevel++; // if (bracketLevel >= 2) return false; // Nested unescaped brackets, this doesn't qualify as a link / image
557
-
459
+ bracketLevel++;
460
+ // if (bracketLevel >= 2) return false; // Nested unescaped brackets, this doesn't qualify as a link / image
558
461
  if (!isImage) {
559
462
  if (this.parseLinkOrImage(string, false)) {
560
463
  // Valid link inside this possible link, which makes this link invalid (inner links beat outer ones)
561
464
  return false;
562
465
  }
563
466
  }
564
-
565
467
  currentOffset += 1;
566
468
  continue textOuter;
567
- } // Check for closing bracket
568
-
469
+ }
569
470
 
471
+ // Check for closing bracket
570
472
  if (string.match(/^\]/)) {
571
473
  bracketLevel--;
572
-
573
474
  if (bracketLevel == 0) {
574
475
  // Found matching bracket and haven't found anything disqualifying this as link / image.
575
476
  linkText = originalString.substr(textOffset, currentOffset - textOffset);
576
477
  currentOffset++;
577
478
  continue textOuter;
578
479
  }
579
- } // Nothing matches, proceed to next char
580
-
480
+ }
581
481
 
482
+ // Nothing matches, proceed to next char
582
483
  currentOffset++;
583
- } // Did we find a link text (i.e., find a matching closing bracket?)
584
-
484
+ }
585
485
 
486
+ // Did we find a link text (i.e., find a matching closing bracket?)
586
487
  if (linkText === false) return false; // Nope
587
- // So far, so good. We've got a valid link text. Let's see what type of link this is
588
488
 
589
- var nextChar = currentOffset < originalString.length ? originalString.substr(currentOffset, 1) : ''; // REFERENCE LINKS
489
+ // So far, so good. We've got a valid link text. Let's see what type of link this is
490
+ var nextChar = currentOffset < originalString.length ? originalString.substr(currentOffset, 1) : '';
590
491
 
492
+ // REFERENCE LINKS
591
493
  if (nextChar == '[') {
592
494
  var _string = originalString.substr(currentOffset);
593
-
594
495
  var _cap = _grammar.inlineGrammar.linkLabel.regexp.exec(_string);
595
-
596
496
  if (_cap) {
597
497
  // Valid link label
598
498
  currentOffset += _cap[0].length;
599
499
  linkLabel.push(_cap[1], _cap[2], _cap[3]);
600
-
601
500
  if (_cap[_grammar.inlineGrammar.linkLabel.labelPlaceholder]) {
602
501
  // Full reference link
603
502
  linkRef = _cap[_grammar.inlineGrammar.linkLabel.labelPlaceholder];
@@ -611,68 +510,59 @@ var Editor = /*#__PURE__*/function () {
611
510
  }
612
511
  } else if (nextChar != '(') {
613
512
  // Shortcut ref link
614
- linkRef = linkText.trim(); // INLINE LINKS
513
+ linkRef = linkText.trim();
514
+
515
+ // INLINE LINKS
615
516
  } else {
616
517
  // nextChar == '('
518
+
617
519
  // Potential inline link
618
520
  currentOffset++;
619
521
  var parenthesisLevel = 1;
620
-
621
522
  inlineOuter: while (currentOffset < originalString.length && parenthesisLevel > 0) {
622
- var _string2 = originalString.substr(currentOffset); // Process whitespace
623
-
523
+ var _string2 = originalString.substr(currentOffset);
624
524
 
525
+ // Process whitespace
625
526
  var _cap2 = /^\s+/.exec(_string2);
626
-
627
527
  if (_cap2) {
628
528
  switch (linkDetails.length) {
629
529
  case 0:
630
530
  linkDetails.push(_cap2[0]);
631
531
  break;
632
532
  // Opening whitespace
633
-
634
533
  case 1:
635
534
  linkDetails.push(_cap2[0]);
636
535
  break;
637
536
  // Open destination, but not a destination yet; desination opened with <
638
-
639
537
  case 2:
640
538
  // Open destination with content in it. Whitespace only allowed if opened by angle bracket, otherwise this closes the destination
641
539
  if (linkDetails[0].match(/</)) {
642
540
  linkDetails[1] = linkDetails[1].concat(_cap2[0]);
643
541
  } else {
644
542
  if (parenthesisLevel != 1) return false; // Unbalanced parenthesis
645
-
646
543
  linkDetails.push(''); // Empty end delimiter for destination
647
-
648
544
  linkDetails.push(_cap2[0]); // Whitespace in between destination and title
649
545
  }
650
546
 
651
547
  break;
652
-
653
548
  case 3:
654
549
  linkDetails.push(_cap2[0]);
655
550
  break;
656
551
  // Whitespace between destination and title
657
-
658
552
  case 4:
659
553
  return false;
660
554
  // This should never happen (no opener for title yet, but more whitespace to capture)
661
-
662
555
  case 5:
663
556
  linkDetails.push('');
664
557
  // Whitespace at beginning of title, push empty title and continue
665
-
666
558
  case 6:
667
559
  linkDetails[5] = linkDetails[5].concat(_cap2[0]);
668
560
  break;
669
561
  // Whitespace in title
670
-
671
562
  case 7:
672
563
  linkDetails[6] = linkDetails[6].concat(_cap2[0]);
673
564
  break;
674
565
  // Whitespace after closing delimiter
675
-
676
566
  default:
677
567
  return false;
678
568
  // We should never get here
@@ -680,44 +570,36 @@ var Editor = /*#__PURE__*/function () {
680
570
 
681
571
  currentOffset += _cap2[0].length;
682
572
  continue inlineOuter;
683
- } // Process backslash escapes
684
-
573
+ }
685
574
 
575
+ // Process backslash escapes
686
576
  _cap2 = _grammar.inlineGrammar.escape.regexp.exec(_string2);
687
-
688
577
  if (_cap2) {
689
578
  switch (linkDetails.length) {
690
579
  case 0:
691
580
  linkDetails.push('');
692
581
  // this opens the link destination, add empty opening delimiter and proceed to next case
693
-
694
582
  case 1:
695
583
  linkDetails.push(_cap2[0]);
696
584
  break;
697
585
  // This opens the link destination, append it
698
-
699
586
  case 2:
700
587
  linkDetails[1] = linkDetails[1].concat(_cap2[0]);
701
588
  break;
702
589
  // Part of the link destination
703
-
704
590
  case 3:
705
591
  return false;
706
592
  // Lacking opening delimiter for link title
707
-
708
593
  case 4:
709
594
  return false;
710
595
  // Lcaking opening delimiter for link title
711
-
712
596
  case 5:
713
597
  linkDetails.push('');
714
598
  // This opens the link title
715
-
716
599
  case 6:
717
600
  linkDetails[5] = linkDetails[5].concat(_cap2[0]);
718
601
  break;
719
602
  // Part of the link title
720
-
721
603
  default:
722
604
  return false;
723
605
  // After link title was closed, without closing parenthesis
@@ -725,85 +607,75 @@ var Editor = /*#__PURE__*/function () {
725
607
 
726
608
  currentOffset += _cap2[0].length;
727
609
  continue inlineOuter;
728
- } // Process opening angle bracket as deilimiter of destination
729
-
610
+ }
730
611
 
612
+ // Process opening angle bracket as deilimiter of destination
731
613
  if (linkDetails.length < 2 && _string2.match(/^</)) {
732
614
  if (linkDetails.length == 0) linkDetails.push('');
733
615
  linkDetails[0] = linkDetails[0].concat('<');
734
616
  currentOffset++;
735
617
  continue inlineOuter;
736
- } // Process closing angle bracket as delimiter of destination
737
-
618
+ }
738
619
 
620
+ // Process closing angle bracket as delimiter of destination
739
621
  if ((linkDetails.length == 1 || linkDetails.length == 2) && _string2.match(/^>/)) {
740
622
  if (linkDetails.length == 1) linkDetails.push(''); // Empty link destination
741
-
742
623
  linkDetails.push('>');
743
624
  currentOffset++;
744
625
  continue inlineOuter;
745
- } // Process non-parenthesis delimiter for title.
746
-
626
+ }
747
627
 
748
- _cap2 = /^["']/.exec(_string2); // For this to be a valid opener, we have to either have no destination, only whitespace so far,
628
+ // Process non-parenthesis delimiter for title.
629
+ _cap2 = /^["']/.exec(_string2);
630
+ // For this to be a valid opener, we have to either have no destination, only whitespace so far,
749
631
  // or a destination with trailing whitespace.
750
-
751
632
  if (_cap2 && (linkDetails.length == 0 || linkDetails.length == 1 || linkDetails.length == 4)) {
752
633
  while (linkDetails.length < 4) {
753
634
  linkDetails.push('');
754
635
  }
755
-
756
636
  linkDetails.push(_cap2[0]);
757
637
  currentOffset++;
758
638
  continue inlineOuter;
759
- } // For this to be a valid closer, we have to have an opener and some or no title, and this has to match the opener
760
-
639
+ }
761
640
 
641
+ // For this to be a valid closer, we have to have an opener and some or no title, and this has to match the opener
762
642
  if (_cap2 && (linkDetails.length == 5 || linkDetails.length == 6) && linkDetails[4] == _cap2[0]) {
763
643
  if (linkDetails.length == 5) linkDetails.push(''); // Empty link title
764
-
765
644
  linkDetails.push(_cap2[0]);
766
645
  currentOffset++;
767
646
  continue inlineOuter;
768
- } // Other cases (linkDetails.length == 2, 3, 7) will be handled with the "default" case below.
769
- // Process opening parenthesis
770
-
647
+ }
648
+ // Other cases (linkDetails.length == 2, 3, 7) will be handled with the "default" case below.
771
649
 
650
+ // Process opening parenthesis
772
651
  if (_string2.match(/^\(/)) {
773
652
  switch (linkDetails.length) {
774
653
  case 0:
775
654
  linkDetails.push('');
776
655
  // this opens the link destination, add empty opening delimiter and proceed to next case
777
-
778
656
  case 1:
779
657
  linkDetails.push('');
780
658
  // This opens the link destination
781
-
782
659
  case 2:
783
660
  // Part of the link destination
784
661
  linkDetails[1] = linkDetails[1].concat('(');
785
662
  if (!linkDetails[0].match(/<$/)) parenthesisLevel++;
786
663
  break;
787
-
788
664
  case 3:
789
665
  linkDetails.push('');
790
666
  // opening delimiter for link title
791
-
792
667
  case 4:
793
668
  linkDetails.push('(');
794
669
  break;
795
670
  // opening delimiter for link title
796
-
797
671
  case 5:
798
672
  linkDetails.push('');
799
673
  // opens the link title, add empty title content and proceed to next case
800
-
801
674
  case 6:
802
675
  // Part of the link title. Un-escaped parenthesis only allowed in " or ' delimited title
803
676
  if (linkDetails[4] == '(') return false;
804
677
  linkDetails[5] = linkDetails[5].concat('(');
805
678
  break;
806
-
807
679
  default:
808
680
  return false;
809
681
  // After link title was closed, without closing parenthesis
@@ -811,18 +683,16 @@ var Editor = /*#__PURE__*/function () {
811
683
 
812
684
  currentOffset++;
813
685
  continue inlineOuter;
814
- } // Process closing parenthesis
815
-
686
+ }
816
687
 
688
+ // Process closing parenthesis
817
689
  if (_string2.match(/^\)/)) {
818
690
  if (linkDetails.length <= 2) {
819
691
  // We are inside the link destination. Parentheses have to be matched if not in angle brackets
820
692
  while (linkDetails.length < 2) {
821
693
  linkDetails.push('');
822
694
  }
823
-
824
695
  if (!linkDetails[0].match(/<$/)) parenthesisLevel--;
825
-
826
696
  if (parenthesisLevel > 0) {
827
697
  linkDetails[1] = linkDetails[1].concat(')');
828
698
  }
@@ -846,47 +716,38 @@ var Editor = /*#__PURE__*/function () {
846
716
  linkDetails.push('');
847
717
  }
848
718
  }
849
-
850
719
  currentOffset++;
851
720
  continue inlineOuter;
852
- } // Any old character
853
-
721
+ }
854
722
 
723
+ // Any old character
855
724
  _cap2 = /^./.exec(_string2);
856
-
857
725
  if (_cap2) {
858
726
  switch (linkDetails.length) {
859
727
  case 0:
860
728
  linkDetails.push('');
861
729
  // this opens the link destination, add empty opening delimiter and proceed to next case
862
-
863
730
  case 1:
864
731
  linkDetails.push(_cap2[0]);
865
732
  break;
866
733
  // This opens the link destination, append it
867
-
868
734
  case 2:
869
735
  linkDetails[1] = linkDetails[1].concat(_cap2[0]);
870
736
  break;
871
737
  // Part of the link destination
872
-
873
738
  case 3:
874
739
  return false;
875
740
  // Lacking opening delimiter for link title
876
-
877
741
  case 4:
878
742
  return false;
879
743
  // Lcaking opening delimiter for link title
880
-
881
744
  case 5:
882
745
  linkDetails.push('');
883
746
  // This opens the link title
884
-
885
747
  case 6:
886
748
  linkDetails[5] = linkDetails[5].concat(_cap2[0]);
887
749
  break;
888
750
  // Part of the link title
889
-
890
751
  default:
891
752
  return false;
892
753
  // After link title was closed, without closing parenthesis
@@ -895,7 +756,6 @@ var Editor = /*#__PURE__*/function () {
895
756
  currentOffset += _cap2[0].length;
896
757
  continue inlineOuter;
897
758
  }
898
-
899
759
  throw "Infinite loop"; // we should never get here since the last test matches any character
900
760
  }
901
761
 
@@ -905,14 +765,11 @@ var Editor = /*#__PURE__*/function () {
905
765
  if (linkRef !== false) {
906
766
  // Ref link; check that linkRef is valid
907
767
  var valid = false;
908
-
909
768
  var _iterator2 = _createForOfIteratorHelper(this.linkLabels),
910
- _step2;
911
-
769
+ _step2;
912
770
  try {
913
771
  for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
914
772
  var _label = _step2.value;
915
-
916
773
  if (_label == linkRef) {
917
774
  valid = true;
918
775
  break;
@@ -923,60 +780,52 @@ var Editor = /*#__PURE__*/function () {
923
780
  } finally {
924
781
  _iterator2.f();
925
782
  }
926
-
927
783
  var label = valid ? "TMLinkLabel TMLinkLabel_Valid" : "TMLinkLabel TMLinkLabel_Invalid";
928
784
  var output = "<span class=\"TMMark TMMark_".concat(type, "\">").concat(opener, "</span><span class=\"").concat(type, " ").concat(linkLabel.length < 3 || !linkLabel[1] ? label : "", "\">").concat(this.processInlineStyles(linkText), "</span><span class=\"TMMark TMMark_").concat(type, "\">]</span>");
929
-
930
785
  if (linkLabel.length >= 3) {
931
786
  output = output.concat("<span class=\"TMMark TMMark_".concat(type, "\">").concat(linkLabel[0], "</span>"), "<span class=\"".concat(label, "\">").concat(linkLabel[1], "</span>"), "<span class=\"TMMark TMMark_".concat(type, "\">").concat(linkLabel[2], "</span>"));
932
787
  }
933
-
934
788
  return {
935
789
  output: output,
936
790
  charCount: currentOffset
937
791
  };
938
792
  } else if (linkDetails) {
939
793
  // Inline link
794
+
940
795
  // This should never happen, but better safe than sorry.
941
796
  while (linkDetails.length < 7) {
942
797
  linkDetails.push('');
943
798
  }
944
-
945
799
  return {
946
800
  output: "<span class=\"TMMark TMMark_".concat(type, "\">").concat(opener, "</span><span class=\"").concat(type, "\">").concat(this.processInlineStyles(linkText), "</span><span class=\"TMMark TMMark_").concat(type, "\">](").concat(linkDetails[0], "</span><span class=\"").concat(type, "Destination\">").concat(linkDetails[1], "</span><span class=\"TMMark TMMark_").concat(type, "\">").concat(linkDetails[2]).concat(linkDetails[3]).concat(linkDetails[4], "</span><span class=\"").concat(type, "Title\">").concat(linkDetails[5], "</span><span class=\"TMMark TMMark_").concat(type, "\">").concat(linkDetails[6], ")</span>"),
947
801
  charCount: currentOffset
948
802
  };
949
803
  }
950
-
951
804
  return false;
952
805
  }
806
+
953
807
  /**
954
808
  * Formats a markdown string as HTML, using Markdown inline formatting.
955
809
  * @param {string} originalString The input (markdown inline formatted) string
956
810
  * @returns {string} The HTML formatted output
957
811
  */
958
-
959
812
  }, {
960
813
  key: "processInlineStyles",
961
814
  value: function processInlineStyles(originalString) {
962
815
  var _this3 = this;
963
-
964
816
  var processed = '';
965
817
  var stack = []; // Stack is an array of objects of the format: {delimiter, delimString, count, output}
966
-
967
818
  var offset = 0;
968
819
  var string = originalString;
969
-
970
820
  var _loop = function _loop() {
971
821
  var _loop2 = function _loop2() {
972
822
  var rule = _arr2[_i2];
973
-
974
823
  var cap = _grammar.inlineGrammar[rule].regexp.exec(string);
975
-
976
824
  if (cap) {
977
825
  string = string.substr(cap[0].length);
978
826
  offset += cap[0].length;
979
- processed += _grammar.inlineGrammar[rule].replacement // .replace(/\$\$([1-9])/g, (str, p1) => processInlineStyles(cap[p1])) // todo recursive calling
827
+ processed += _grammar.inlineGrammar[rule].replacement
828
+ // .replace(/\$\$([1-9])/g, (str, p1) => processInlineStyles(cap[p1])) // todo recursive calling
980
829
  .replace(/\$([1-9])/g, function (str, p1) {
981
830
  return (0, _grammar.htmlescape)(cap[p1]);
982
831
  });
@@ -985,70 +834,68 @@ var Editor = /*#__PURE__*/function () {
985
834
  };
986
835
  }
987
836
  };
988
-
989
837
  // Process simple rules (non-delimiter)
990
838
  for (var _i2 = 0, _arr2 = ['escape', 'code', 'autolink', 'html']; _i2 < _arr2.length; _i2++) {
991
839
  var _ret2 = _loop2();
992
-
993
840
  if (_typeof(_ret2) === "object") return _ret2.v;
994
- } // Check for links / images
995
-
841
+ }
996
842
 
843
+ // Check for links / images
997
844
  var potentialLink = string.match(_grammar.inlineGrammar.linkOpen.regexp);
998
845
  var potentialImage = string.match(_grammar.inlineGrammar.imageOpen.regexp);
999
-
1000
846
  if (potentialImage || potentialLink) {
1001
847
  var result = _this3.parseLinkOrImage(string, potentialImage);
1002
-
1003
848
  if (result) {
1004
849
  processed = "".concat(processed).concat(result.output);
1005
850
  string = string.substr(result.charCount);
1006
851
  offset += result.charCount;
1007
852
  return "continue|outer";
1008
853
  }
1009
- } // Check for em / strong delimiters
1010
-
854
+ }
1011
855
 
856
+ // Check for em / strong delimiters
1012
857
  var cap = /(^\*+)|(^_+)/.exec(string);
1013
-
1014
858
  if (cap) {
1015
859
  var delimCount = cap[0].length;
1016
860
  var delimString = cap[0];
1017
861
  var currentDelimiter = cap[0][0]; // This should be * or _
1018
862
 
1019
- string = string.substr(cap[0].length); // We have a delimiter run. Let's check if it can open or close an emphasis.
863
+ string = string.substr(cap[0].length);
1020
864
 
1021
- var preceding = offset > 0 ? originalString.substr(0, offset) : ' '; // beginning and end of line count as whitespace
865
+ // We have a delimiter run. Let's check if it can open or close an emphasis.
1022
866
 
867
+ var preceding = offset > 0 ? originalString.substr(0, offset) : ' '; // beginning and end of line count as whitespace
1023
868
  var following = offset + cap[0].length < originalString.length ? string : ' ';
1024
869
  var punctuationFollows = following.match(_grammar.punctuationLeading);
1025
870
  var punctuationPrecedes = preceding.match(_grammar.punctuationTrailing);
1026
871
  var whitespaceFollows = following.match(/^\s/);
1027
- var whitespacePrecedes = preceding.match(/\s$/); // These are the rules for right-flanking and left-flanking delimiter runs as per CommonMark spec
872
+ var whitespacePrecedes = preceding.match(/\s$/);
1028
873
 
874
+ // These are the rules for right-flanking and left-flanking delimiter runs as per CommonMark spec
1029
875
  var canOpen = !whitespaceFollows && (!punctuationFollows || !!whitespacePrecedes || !!punctuationPrecedes);
1030
- var canClose = !whitespacePrecedes && (!punctuationPrecedes || !!whitespaceFollows || !!punctuationFollows); // Underscores have more detailed rules than just being part of left- or right-flanking run:
876
+ var canClose = !whitespacePrecedes && (!punctuationPrecedes || !!whitespaceFollows || !!punctuationFollows);
1031
877
 
878
+ // Underscores have more detailed rules than just being part of left- or right-flanking run:
1032
879
  if (currentDelimiter == '_' && canOpen && canClose) {
1033
880
  canOpen = punctuationPrecedes;
1034
881
  canClose = punctuationFollows;
1035
- } // If the delimiter can close, check the stack if there's something it can close
1036
-
882
+ }
1037
883
 
884
+ // If the delimiter can close, check the stack if there's something it can close
1038
885
  if (canClose) {
1039
- var stackPointer = stack.length - 1; // See if we can find a matching opening delimiter, move down through the stack
1040
-
886
+ var stackPointer = stack.length - 1;
887
+ // See if we can find a matching opening delimiter, move down through the stack
1041
888
  while (delimCount && stackPointer >= 0) {
1042
889
  if (stack[stackPointer].delimiter == currentDelimiter) {
1043
890
  // We found a matching delimiter, let's construct the formatted string
891
+
1044
892
  // Firstly, if we skipped any stack levels, pop them immediately (non-matching delimiters)
1045
893
  while (stackPointer < stack.length - 1) {
1046
894
  var _entry = stack.pop();
1047
-
1048
895
  processed = "".concat(_entry.output).concat(_entry.delimString.substr(0, _entry.count)).concat(processed);
1049
- } // Then, format the string
1050
-
896
+ }
1051
897
 
898
+ // Then, format the string
1052
899
  if (delimCount >= 2 && stack[stackPointer].count >= 2) {
1053
900
  // Strong
1054
901
  processed = "<span class=\"TMMark\">".concat(currentDelimiter).concat(currentDelimiter, "</span><strong class=\"TMStrong\">").concat(processed, "</strong><span class=\"TMMark\">").concat(currentDelimiter).concat(currentDelimiter, "</span>");
@@ -1059,12 +906,11 @@ var Editor = /*#__PURE__*/function () {
1059
906
  processed = "<span class=\"TMMark\">".concat(currentDelimiter, "</span><em class=\"TMEm\">").concat(processed, "</em><span class=\"TMMark\">").concat(currentDelimiter, "</span>");
1060
907
  delimCount -= 1;
1061
908
  stack[stackPointer].count -= 1;
1062
- } // If that stack level is empty now, pop it
1063
-
909
+ }
1064
910
 
911
+ // If that stack level is empty now, pop it
1065
912
  if (stack[stackPointer].count == 0) {
1066
913
  var _entry2 = stack.pop();
1067
-
1068
914
  processed = "".concat(_entry2.output).concat(processed);
1069
915
  stackPointer--;
1070
916
  }
@@ -1074,9 +920,8 @@ var Editor = /*#__PURE__*/function () {
1074
920
  stackPointer--;
1075
921
  }
1076
922
  }
1077
- } // If there are still delimiters left, and the delimiter run can open, push it on the stack
1078
-
1079
-
923
+ }
924
+ // If there are still delimiters left, and the delimiter run can open, push it on the stack
1080
925
  if (delimCount && canOpen) {
1081
926
  stack.push({
1082
927
  delimiter: currentDelimiter,
@@ -1085,43 +930,36 @@ var Editor = /*#__PURE__*/function () {
1085
930
  output: processed
1086
931
  });
1087
932
  processed = ''; // Current formatted output has been pushed on the stack and will be prepended when the stack gets popped
1088
-
1089
933
  delimCount = 0;
1090
- } // Any delimiters that are left (closing unmatched) are appended to the output.
1091
-
934
+ }
1092
935
 
936
+ // Any delimiters that are left (closing unmatched) are appended to the output.
1093
937
  if (delimCount) {
1094
938
  processed = "".concat(processed).concat(delimString.substr(0, delimCount));
1095
939
  }
1096
-
1097
940
  offset += cap[0].length;
1098
941
  return "continue|outer";
1099
- } // Check for strikethrough delimiter
1100
-
942
+ }
1101
943
 
944
+ // Check for strikethrough delimiter
1102
945
  cap = /^~~/.exec(string);
1103
-
1104
946
  if (cap) {
1105
947
  var consumed = false;
1106
-
1107
- var _stackPointer = stack.length - 1; // See if we can find a matching opening delimiter, move down through the stack
1108
-
1109
-
948
+ var _stackPointer = stack.length - 1;
949
+ // See if we can find a matching opening delimiter, move down through the stack
1110
950
  while (!consumed && _stackPointer >= 0) {
1111
951
  if (stack[_stackPointer].delimiter == '~') {
1112
952
  // We found a matching delimiter, let's construct the formatted string
953
+
1113
954
  // Firstly, if we skipped any stack levels, pop them immediately (non-matching delimiters)
1114
955
  while (_stackPointer < stack.length - 1) {
1115
956
  var _entry4 = stack.pop();
1116
-
1117
957
  processed = "".concat(_entry4.output).concat(_entry4.delimString.substr(0, _entry4.count)).concat(processed);
1118
- } // Then, format the string
1119
-
958
+ }
1120
959
 
960
+ // Then, format the string
1121
961
  processed = "<span class=\"TMMark\">~~</span><del class=\"TMStrikethrough\">".concat(processed, "</del><span class=\"TMMark\">~~</span>");
1122
-
1123
962
  var _entry3 = stack.pop();
1124
-
1125
963
  processed = "".concat(_entry3.output).concat(processed);
1126
964
  consumed = true;
1127
965
  } else {
@@ -1129,9 +967,9 @@ var Editor = /*#__PURE__*/function () {
1129
967
  // Go down one level in the stack
1130
968
  _stackPointer--;
1131
969
  }
1132
- } // If there are still delimiters left, and the delimiter run can open, push it on the stack
1133
-
970
+ }
1134
971
 
972
+ // If there are still delimiters left, and the delimiter run can open, push it on the stack
1135
973
  if (!consumed) {
1136
974
  stack.push({
1137
975
  delimiter: '~',
@@ -1145,11 +983,10 @@ var Editor = /*#__PURE__*/function () {
1145
983
  offset += cap[0].length;
1146
984
  string = string.substr(cap[0].length);
1147
985
  return "continue|outer";
1148
- } // Process 'default' rule
1149
-
986
+ }
1150
987
 
988
+ // Process 'default' rule
1151
989
  cap = _grammar.inlineGrammar.default.regexp.exec(string);
1152
-
1153
990
  if (cap) {
1154
991
  string = string.substr(cap[0].length);
1155
992
  offset += cap[0].length;
@@ -1158,42 +995,37 @@ var Editor = /*#__PURE__*/function () {
1158
995
  });
1159
996
  return "continue|outer";
1160
997
  }
1161
-
1162
998
  throw 'Infinite loop!';
1163
999
  };
1164
-
1165
1000
  outer: while (string) {
1166
1001
  var _ret = _loop();
1167
-
1168
1002
  if (_ret === "continue|outer") continue outer;
1169
- } // Empty the stack, any opening delimiters are unused
1170
-
1003
+ }
1171
1004
 
1005
+ // Empty the stack, any opening delimiters are unused
1172
1006
  while (stack.length) {
1173
1007
  var entry = stack.pop();
1174
1008
  processed = "".concat(entry.output).concat(entry.delimString.substr(0, entry.count)).concat(processed);
1175
1009
  }
1176
-
1177
1010
  return processed;
1178
1011
  }
1012
+
1179
1013
  /**
1180
1014
  * Clears the line dirty flag (resets it to an array of false)
1181
1015
  */
1182
-
1183
1016
  }, {
1184
1017
  key: "clearDirtyFlag",
1185
1018
  value: function clearDirtyFlag() {
1186
1019
  this.lineDirty = new Array(this.lines.length);
1187
-
1188
1020
  for (var i = 0; i < this.lineDirty.length; i++) {
1189
1021
  this.lineDirty[i] = false;
1190
1022
  }
1191
1023
  }
1024
+
1192
1025
  /**
1193
1026
  * Updates the class properties (lines, lineElements) from the DOM.
1194
1027
  * @returns true if contents changed
1195
1028
  */
1196
-
1197
1029
  }, {
1198
1030
  key: "updateLineContents",
1199
1031
  value: function updateLineContents() {
@@ -1201,40 +1033,33 @@ var Editor = /*#__PURE__*/function () {
1201
1033
  // Check if we have changed anything about the number of lines (inserted or deleted a paragraph)
1202
1034
  // < 0 means line(s) removed; > 0 means line(s) added
1203
1035
  var lineDelta = this.e.childElementCount - this.lines.length;
1204
-
1205
1036
  if (lineDelta) {
1206
1037
  // yup. Let's try how much we can salvage (find out which lines from beginning and end were unchanged)
1207
1038
  // Find lines from the beginning that haven't changed...
1208
1039
  var firstChangedLine = 0;
1209
-
1210
1040
  while (firstChangedLine <= this.lines.length && firstChangedLine <= this.lineElements.length && this.lineElements[firstChangedLine] // Check that the line element hasn't been deleted
1211
1041
  && this.lines[firstChangedLine] == this.lineElements[firstChangedLine].textContent) {
1212
1042
  firstChangedLine++;
1213
- } // End also from the end
1214
-
1043
+ }
1215
1044
 
1045
+ // End also from the end
1216
1046
  var lastChangedLine = -1;
1217
-
1218
1047
  while (-lastChangedLine < this.lines.length && -lastChangedLine < this.lineElements.length && this.lines[this.lines.length + lastChangedLine] == this.lineElements[this.lineElements.length + lastChangedLine].textContent) {
1219
1048
  lastChangedLine--;
1220
1049
  }
1221
-
1222
1050
  var linesToDelete = this.lines.length + lastChangedLine + 1 - firstChangedLine;
1223
1051
  if (linesToDelete < -lineDelta) linesToDelete = -lineDelta;
1224
1052
  if (linesToDelete < 0) linesToDelete = 0;
1225
1053
  var linesToAdd = [];
1226
-
1227
1054
  for (var l = 0; l < linesToDelete + lineDelta; l++) {
1228
1055
  linesToAdd.push(this.lineElements[firstChangedLine + l].textContent);
1229
1056
  }
1230
-
1231
1057
  this.spliceLines(firstChangedLine, linesToDelete, linesToAdd, false);
1232
1058
  } else {
1233
1059
  // No lines added or removed
1234
1060
  for (var line = 0; line < this.lineElements.length; line++) {
1235
1061
  var e = this.lineElements[line];
1236
1062
  var ct = e.textContent;
1237
-
1238
1063
  if (this.lines[line] !== ct) {
1239
1064
  // Line changed, update it
1240
1065
  this.lines[line] = ct;
@@ -1243,62 +1068,56 @@ var Editor = /*#__PURE__*/function () {
1243
1068
  }
1244
1069
  }
1245
1070
  }
1071
+
1246
1072
  /**
1247
1073
  * Processes a new paragraph.
1248
1074
  * @param sel The current selection
1249
1075
  */
1250
-
1251
1076
  }, {
1252
1077
  key: "processNewParagraph",
1253
1078
  value: function processNewParagraph(sel) {
1254
- if (!sel) return; // Update lines from content
1079
+ if (!sel) return;
1255
1080
 
1081
+ // Update lines from content
1256
1082
  this.updateLineContents();
1257
- var continuableType = false; // Let's see if we need to continue a list
1083
+ var continuableType = false;
1084
+ // Let's see if we need to continue a list
1258
1085
 
1259
1086
  var checkLine = sel.col > 0 ? sel.row : sel.row - 1;
1260
-
1261
1087
  switch (this.lineTypes[checkLine]) {
1262
1088
  case 'TMUL':
1263
1089
  continuableType = 'TMUL';
1264
1090
  break;
1265
-
1266
1091
  case 'TMOL':
1267
1092
  continuableType = 'TMOL';
1268
1093
  break;
1269
-
1270
1094
  case 'TMIndentedCode':
1271
1095
  continuableType = 'TMIndentedCode';
1272
1096
  break;
1273
1097
  }
1274
-
1275
1098
  var lines = this.lines[sel.row].replace(/\n\n$/, '\n').split(/(?:\r\n|\n|\r)/);
1276
-
1277
1099
  if (lines.length == 1) {
1278
1100
  // No new line
1279
1101
  this.updateFormatting();
1280
1102
  return;
1281
1103
  }
1282
-
1283
1104
  this.spliceLines(sel.row, 1, lines, true);
1284
1105
  sel.row++;
1285
1106
  sel.col = 0;
1286
-
1287
1107
  if (continuableType) {
1288
1108
  // Check if the previous line was non-empty
1289
1109
  var capture = _grammar.lineGrammar[continuableType].regexp.exec(this.lines[sel.row - 1]);
1290
-
1291
1110
  if (capture) {
1292
1111
  // Convention: capture[1] is the line type marker, capture[2] is the content
1293
1112
  if (capture[2]) {
1294
1113
  // Previous line has content, continue the continuable type
1114
+
1295
1115
  // Hack for OL: increment number
1296
1116
  if (continuableType == 'TMOL') {
1297
1117
  capture[1] = capture[1].replace(/\d{1,9}/, function (result) {
1298
1118
  return parseInt(result[0]) + 1;
1299
1119
  });
1300
1120
  }
1301
-
1302
1121
  this.lines[sel.row] = "".concat(capture[1]).concat(this.lines[sel.row]);
1303
1122
  this.lineDirty[sel.row] = true;
1304
1123
  sel.col = capture[1].length;
@@ -1309,9 +1128,10 @@ var Editor = /*#__PURE__*/function () {
1309
1128
  }
1310
1129
  }
1311
1130
  }
1312
-
1313
1131
  this.updateFormatting();
1314
- } // /**
1132
+ }
1133
+
1134
+ // /**
1315
1135
  // * Processes a "delete" input action.
1316
1136
  // * @param {object} focus The selection
1317
1137
  // * @param {boolean} forward If true, performs a forward delete, otherwise performs a backward delete
@@ -1334,6 +1154,7 @@ var Editor = /*#__PURE__*/function () {
1334
1154
  // // Otherwise, we're at the very beginning and can't delete backwards
1335
1155
  // }
1336
1156
  // }
1157
+
1337
1158
  // }
1338
1159
 
1339
1160
  /**
@@ -1342,7 +1163,6 @@ var Editor = /*#__PURE__*/function () {
1342
1163
  * @param {boolean} getAnchor if set to true, gets the selection anchor (start point of the selection), otherwise gets the focus (end point).
1343
1164
  * @return {object} An object representing the selection, with properties col and row.
1344
1165
  */
1345
-
1346
1166
  }, {
1347
1167
  key: "getSelection",
1348
1168
  value: function getSelection() {
@@ -1351,27 +1171,23 @@ var Editor = /*#__PURE__*/function () {
1351
1171
  var startNode = getAnchor ? selection.anchorNode : selection.focusNode;
1352
1172
  if (!startNode) return null;
1353
1173
  var offset = startNode.nodeType === Node.TEXT_NODE ? getAnchor ? selection.anchorOffset : selection.focusOffset : 0;
1354
-
1355
1174
  if (startNode == this.e) {
1356
1175
  return {
1357
1176
  row: 0,
1358
1177
  col: offset
1359
1178
  };
1360
1179
  }
1361
-
1362
1180
  var col = this.computeColumn(startNode, offset);
1363
1181
  if (col === null) return null; // We are outside of the editor
1364
- // Find the row node
1365
1182
 
1183
+ // Find the row node
1366
1184
  var node = startNode;
1367
-
1368
1185
  while (node.parentElement != this.e) {
1369
1186
  node = node.parentElement;
1370
1187
  }
1371
-
1372
- var row = 0; // Check if we can read a line number from the data-line-num attribute.
1188
+ var row = 0;
1189
+ // Check if we can read a line number from the data-line-num attribute.
1373
1190
  // The last condition is a security measure since inserting a new paragraph copies the previous rows' line number
1374
-
1375
1191
  if (node.dataset && node.dataset.lineNum && (!node.previousSibling || node.previousSibling.dataset.lineNum != node.dataset.lineNum)) {
1376
1192
  row = parseInt(node.dataset.lineNum);
1377
1193
  } else {
@@ -1380,33 +1196,30 @@ var Editor = /*#__PURE__*/function () {
1380
1196
  node = node.previousSibling;
1381
1197
  }
1382
1198
  }
1383
-
1384
1199
  return {
1385
1200
  row: row,
1386
1201
  col: col,
1387
1202
  node: startNode
1388
1203
  };
1389
1204
  }
1205
+
1390
1206
  /**
1391
1207
  * Computes a column within an editor line from a node and offset within that node.
1392
1208
  * @param {Node} startNode The node
1393
1209
  * @param {int} offset THe selection
1394
1210
  * @returns {int} the column, or null if the node is not inside the editor
1395
1211
  */
1396
-
1397
1212
  }, {
1398
1213
  key: "computeColumn",
1399
1214
  value: function computeColumn(startNode, offset) {
1400
1215
  var node = startNode;
1401
- var col = offset; // First, make sure we're actually in the editor.
1402
-
1216
+ var col = offset;
1217
+ // First, make sure we're actually in the editor.
1403
1218
  while (node && node.parentNode != this.e) {
1404
1219
  node = node.parentNode;
1405
1220
  }
1406
-
1407
1221
  if (node == null) return null;
1408
1222
  node = startNode;
1409
-
1410
1223
  while (node.parentNode != this.e) {
1411
1224
  if (node.previousSibling) {
1412
1225
  node = node.previousSibling;
@@ -1415,40 +1228,35 @@ var Editor = /*#__PURE__*/function () {
1415
1228
  node = node.parentNode;
1416
1229
  }
1417
1230
  }
1418
-
1419
1231
  return col;
1420
1232
  }
1233
+
1421
1234
  /**
1422
1235
  * Computes DOM node and offset within that node from a position expressed as row and column.
1423
1236
  * @param {int} row Row (line number)
1424
1237
  * @param {int} col Column
1425
1238
  * @returns An object with two properties: node and offset. offset may be null;
1426
1239
  */
1427
-
1428
1240
  }, {
1429
1241
  key: "computeNodeAndOffset",
1430
1242
  value: function computeNodeAndOffset(row, col) {
1431
1243
  var bindRight = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
1432
-
1433
1244
  if (row >= this.lineElements.length) {
1434
1245
  // Selection past the end of text, set selection to end of text
1435
1246
  row = this.lineElements.length - 1;
1436
1247
  col = this.lines[row].length;
1437
1248
  }
1438
-
1439
1249
  if (col > this.lines[row].length) {
1440
1250
  col = this.lines[row].length;
1441
1251
  }
1442
-
1443
1252
  var parentNode = this.lineElements[row];
1444
1253
  var node = parentNode.firstChild;
1445
- var childrenComplete = false; // default return value
1446
-
1254
+ var childrenComplete = false;
1255
+ // default return value
1447
1256
  var rv = {
1448
1257
  node: parentNode.firstChild ? parentNode.firstChild : parentNode,
1449
1258
  offset: 0
1450
1259
  };
1451
-
1452
1260
  while (node != parentNode) {
1453
1261
  if (!childrenComplete && node.nodeType === Node.TEXT_NODE) {
1454
1262
  if (node.nodeValue.length >= col) {
@@ -1470,7 +1278,6 @@ var Editor = /*#__PURE__*/function () {
1470
1278
  col -= node.nodeValue.length;
1471
1279
  }
1472
1280
  }
1473
-
1474
1281
  if (!childrenComplete && node.firstChild) {
1475
1282
  node = node.firstChild;
1476
1283
  } else if (node.nextSibling) {
@@ -1480,56 +1287,49 @@ var Editor = /*#__PURE__*/function () {
1480
1287
  childrenComplete = true;
1481
1288
  node = node.parentNode;
1482
1289
  }
1483
- } // Either, the position was invalid and we just return the default return value
1484
- // Or we are binding right and the selection is at the end of the line
1485
-
1290
+ }
1486
1291
 
1292
+ // Either, the position was invalid and we just return the default return value
1293
+ // Or we are binding right and the selection is at the end of the line
1487
1294
  return rv;
1488
1295
  }
1296
+
1489
1297
  /**
1490
1298
  * Sets the selection based on rows and columns within the editor Markdown content.
1491
1299
  * @param {object} focus Object representing the selection, needs to have properties row and col.
1492
1300
  */
1493
-
1494
1301
  }, {
1495
1302
  key: "setSelection",
1496
1303
  value: function setSelection(focus) {
1497
1304
  var anchor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
1498
1305
  if (!focus) return;
1499
1306
  var range = document.createRange();
1500
-
1501
1307
  var _this$computeNodeAndO = this.computeNodeAndOffset(focus.row, focus.col, anchor && anchor.row == focus.row && anchor.col > focus.col),
1502
- focusNode = _this$computeNodeAndO.node,
1503
- focusOffset = _this$computeNodeAndO.offset; // Bind selection right if anchor is in the same row and behind the focus
1504
-
1505
-
1308
+ focusNode = _this$computeNodeAndO.node,
1309
+ focusOffset = _this$computeNodeAndO.offset; // Bind selection right if anchor is in the same row and behind the focus
1506
1310
  var anchorNode = null,
1507
- anchorOffset = null;
1508
-
1311
+ anchorOffset = null;
1509
1312
  if (anchor && (anchor.row != focus.row || anchor.col != focus.col)) {
1510
1313
  var _this$computeNodeAndO2 = this.computeNodeAndOffset(anchor.row, anchor.col, focus.row == anchor.row && focus.col > anchor.col),
1511
- node = _this$computeNodeAndO2.node,
1512
- offset = _this$computeNodeAndO2.offset;
1513
-
1314
+ node = _this$computeNodeAndO2.node,
1315
+ offset = _this$computeNodeAndO2.offset;
1514
1316
  anchorNode = node;
1515
1317
  anchorOffset = offset;
1516
1318
  }
1517
-
1518
1319
  if (anchorNode) range.setStart(anchorNode, anchorOffset);else range.setStart(focusNode, focusOffset);
1519
1320
  range.setEnd(focusNode, focusOffset);
1520
1321
  var windowSelection = window.getSelection();
1521
1322
  windowSelection.removeAllRanges();
1522
1323
  windowSelection.addRange(range);
1523
1324
  }
1325
+
1524
1326
  /**
1525
1327
  * Event handler for input events
1526
1328
  */
1527
-
1528
1329
  }, {
1529
1330
  key: "handleInputEvent",
1530
1331
  value: function handleInputEvent(event) {
1531
1332
  var focus = this.getSelection();
1532
-
1533
1333
  if ((event.inputType == 'insertParagraph' || event.inputType == 'insertLineBreak') && focus) {
1534
1334
  this.clearDirtyFlag();
1535
1335
  this.processNewParagraph(focus);
@@ -1547,22 +1347,21 @@ var Editor = /*#__PURE__*/function () {
1547
1347
  }
1548
1348
  }
1549
1349
  }
1550
-
1551
1350
  this.updateLineContentsAndFormatting();
1552
1351
  }
1553
-
1554
1352
  if (focus) this.setSelection(focus);
1555
1353
  this.fireChange();
1556
1354
  }
1355
+
1557
1356
  /**
1558
1357
  * Event handler for "selectionchange" events.
1559
1358
  */
1560
-
1561
1359
  }, {
1562
1360
  key: "handleSelectionChangeEvent",
1563
1361
  value: function handleSelectionChangeEvent() {
1564
1362
  this.fireSelection();
1565
1363
  }
1364
+
1566
1365
  /**
1567
1366
  * Convenience function to "splice" new lines into the arrays this.lines, this.lineDirty, this.lineTypes, and the DOM elements
1568
1367
  * underneath the editor element.
@@ -1574,58 +1373,51 @@ var Editor = /*#__PURE__*/function () {
1574
1373
  * @param {array} linesToInsert Array of strings representing the lines to be inserted
1575
1374
  * @param {boolean} adjustLineElements If true, then <div> elements are also inserted in the DOM at the respective position
1576
1375
  */
1577
-
1578
1376
  }, {
1579
1377
  key: "spliceLines",
1580
1378
  value: function spliceLines(startLine) {
1581
1379
  var _this$lines, _this$lineTypes, _this$lineDirty;
1582
-
1583
1380
  var linesToDelete = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
1584
1381
  var linesToInsert = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
1585
1382
  var adjustLineElements = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
1586
-
1587
1383
  if (adjustLineElements) {
1588
1384
  for (var i = 0; i < linesToDelete; i++) {
1589
1385
  this.e.removeChild(this.e.childNodes[startLine]);
1590
1386
  }
1591
1387
  }
1592
-
1593
1388
  var insertedBlank = [];
1594
1389
  var insertedDirty = [];
1595
-
1596
1390
  for (var _i3 = 0; _i3 < linesToInsert.length; _i3++) {
1597
1391
  insertedBlank.push('');
1598
1392
  insertedDirty.push(true);
1599
-
1600
1393
  if (adjustLineElements) {
1601
1394
  if (this.e.childNodes[startLine]) this.e.insertBefore(document.createElement('div'), this.e.childNodes[startLine]);else this.e.appendChild(document.createElement('div'));
1602
1395
  }
1603
1396
  }
1604
-
1605
1397
  (_this$lines = this.lines).splice.apply(_this$lines, [startLine, linesToDelete].concat(_toConsumableArray(linesToInsert)));
1606
-
1607
1398
  (_this$lineTypes = this.lineTypes).splice.apply(_this$lineTypes, [startLine, linesToDelete].concat(insertedBlank));
1608
-
1609
1399
  (_this$lineDirty = this.lineDirty).splice.apply(_this$lineDirty, [startLine, linesToDelete].concat(insertedDirty));
1610
1400
  }
1401
+
1611
1402
  /**
1612
1403
  * Event handler for the "paste" event
1613
1404
  */
1614
-
1615
1405
  }, {
1616
1406
  key: "handlePaste",
1617
1407
  value: function handlePaste(event) {
1618
- event.preventDefault(); // get text representation of clipboard
1408
+ event.preventDefault();
1619
1409
 
1620
- var text = (event.originalEvent || event).clipboardData.getData('text/plain'); // insert text manually
1410
+ // get text representation of clipboard
1411
+ var text = (event.originalEvent || event).clipboardData.getData('text/plain');
1621
1412
 
1413
+ // insert text manually
1622
1414
  this.paste(text);
1623
1415
  }
1416
+
1624
1417
  /**
1625
1418
  * Pastes the text at the current selection (or at the end, if no current selection)
1626
1419
  * @param {string} text
1627
1420
  */
1628
-
1629
1421
  }, {
1630
1422
  key: "paste",
1631
1423
  value: function paste(text) {
@@ -1634,7 +1426,6 @@ var Editor = /*#__PURE__*/function () {
1634
1426
  if (!anchor) anchor = this.getSelection(true);
1635
1427
  if (!focus) focus = this.getSelection(false);
1636
1428
  var beginning, end;
1637
-
1638
1429
  if (!focus) {
1639
1430
  focus = {
1640
1431
  row: this.lines.length - 1,
@@ -1645,7 +1436,6 @@ var Editor = /*#__PURE__*/function () {
1645
1436
  if (!anchor) {
1646
1437
  anchor = focus;
1647
1438
  }
1648
-
1649
1439
  if (anchor.row < focus.row || anchor.row == focus.row && anchor.col <= focus.col) {
1650
1440
  beginning = anchor;
1651
1441
  end = focus;
@@ -1653,7 +1443,6 @@ var Editor = /*#__PURE__*/function () {
1653
1443
  beginning = focus;
1654
1444
  end = anchor;
1655
1445
  }
1656
-
1657
1446
  var insertedLines = text.split(/(?:\r\n|\r|\n)/);
1658
1447
  var lineBefore = this.lines[beginning.row].substr(0, beginning.col);
1659
1448
  var lineEnd = this.lines[end.row].substr(end.col);
@@ -1667,41 +1456,36 @@ var Editor = /*#__PURE__*/function () {
1667
1456
  this.setSelection(focus);
1668
1457
  this.fireChange();
1669
1458
  }
1459
+
1670
1460
  /**
1671
1461
  * Computes the (lowest in the DOM tree) common ancestor of two DOM nodes.
1672
1462
  * @param {Node} node1 the first node
1673
1463
  * @param {Node} node2 the second node
1674
1464
  * @returns {Node} The commen ancestor node, or null if there is no common ancestor
1675
1465
  */
1676
-
1677
1466
  }, {
1678
1467
  key: "computeCommonAncestor",
1679
1468
  value: function computeCommonAncestor(node1, node2) {
1680
1469
  if (!node1 || !node2) return null;
1681
1470
  if (node1 == node2) return node1;
1682
-
1683
1471
  var ancestry = function ancestry(node) {
1684
1472
  var ancestry = [];
1685
-
1686
1473
  while (node) {
1687
1474
  ancestry.unshift(node);
1688
1475
  node = node.parentNode;
1689
1476
  }
1690
-
1691
1477
  return ancestry;
1692
1478
  };
1693
-
1694
1479
  var ancestry1 = ancestry(node1);
1695
1480
  var ancestry2 = ancestry(node2);
1696
1481
  if (ancestry1[0] != ancestry2[0]) return null;
1697
1482
  var i;
1698
-
1699
1483
  for (i = 0; ancestry1[i] == ancestry2[i]; i++) {
1700
1484
  ;
1701
1485
  }
1702
-
1703
1486
  return ancestry1[i - 1];
1704
1487
  }
1488
+
1705
1489
  /**
1706
1490
  * Finds the (lowest in the DOM tree) enclosing DOM node with a given class.
1707
1491
  * @param {object} focus The focus selection object
@@ -1709,35 +1493,30 @@ var Editor = /*#__PURE__*/function () {
1709
1493
  * @param {string} className The class name to find
1710
1494
  * @returns {Node} The enclosing DOM node with the respective class (inside the editor), if there is one; null otherwise.
1711
1495
  */
1712
-
1713
1496
  }, {
1714
1497
  key: "computeEnclosingMarkupNode",
1715
1498
  value: function computeEnclosingMarkupNode(focus, anchor, className) {
1716
1499
  var node = null;
1717
1500
  if (!focus) return null;
1718
-
1719
1501
  if (!anchor) {
1720
1502
  node = focus.node;
1721
1503
  } else {
1722
1504
  if (focus.row != anchor.row) return null;
1723
1505
  node = this.computeCommonAncestor(focus.node, anchor.node);
1724
1506
  }
1725
-
1726
1507
  if (!node) return null;
1727
-
1728
1508
  while (node != this.e) {
1729
1509
  if (node.className && node.className.includes(className)) return node;
1730
1510
  node = node.parentNode;
1731
- } // Ascended all the way to the editor element
1732
-
1733
-
1511
+ }
1512
+ // Ascended all the way to the editor element
1734
1513
  return null;
1735
1514
  }
1515
+
1736
1516
  /**
1737
1517
  * Returns the state (true / false) of all commands.
1738
1518
  * @param focus Focus of the selection. If not given, assumes the current focus.
1739
1519
  */
1740
-
1741
1520
  }, {
1742
1521
  key: "getCommandState",
1743
1522
  value: function getCommandState() {
@@ -1746,18 +1525,14 @@ var Editor = /*#__PURE__*/function () {
1746
1525
  var commandState = {};
1747
1526
  if (!focus) focus = this.getSelection(false);
1748
1527
  if (!anchor) anchor = this.getSelection(true);
1749
-
1750
1528
  if (!focus) {
1751
1529
  for (var cmd in _grammar.commands) {
1752
1530
  commandState[cmd] = null;
1753
1531
  }
1754
-
1755
1532
  return commandState;
1756
1533
  }
1757
-
1758
1534
  if (!anchor) anchor = focus;
1759
1535
  var start, end;
1760
-
1761
1536
  if (anchor.row < focus.row || anchor.row == focus.row && anchor.col < focus.col) {
1762
1537
  start = anchor;
1763
1538
  end = focus;
@@ -1765,7 +1540,6 @@ var Editor = /*#__PURE__*/function () {
1765
1540
  start = focus;
1766
1541
  end = anchor;
1767
1542
  }
1768
-
1769
1543
  if (end.row > start.row && end.col == 0) {
1770
1544
  end.row--;
1771
1545
  end.col = this.lines[end.row].length; // Selection to beginning of next line is said to end at the beginning of the last line
@@ -1777,37 +1551,35 @@ var Editor = /*#__PURE__*/function () {
1777
1551
  commandState[_cmd] = null;
1778
1552
  } else {
1779
1553
  // The command state is true if there is a respective enclosing markup node (e.g., the selection is enclosed in a <b>..</b>) ...
1780
- commandState[_cmd] = !!this.computeEnclosingMarkupNode(focus, anchor, _grammar.commands[_cmd].className) || // ... or if it's an empty string preceded by and followed by formatting markers, e.g. **|** where | is the cursor
1554
+ commandState[_cmd] = !!this.computeEnclosingMarkupNode(focus, anchor, _grammar.commands[_cmd].className) ||
1555
+ // ... or if it's an empty string preceded by and followed by formatting markers, e.g. **|** where | is the cursor
1556
+
1781
1557
  focus.col == anchor.col && !!this.lines[focus.row].substr(0, focus.col).match(_grammar.commands[_cmd].unset.prePattern) && !!this.lines[focus.row].substr(focus.col).match(_grammar.commands[_cmd].unset.postPattern);
1782
1558
  }
1783
1559
  }
1784
-
1785
1560
  if (_grammar.commands[_cmd].type == 'line') {
1786
1561
  if (!focus) {
1787
1562
  commandState[_cmd] = null;
1788
1563
  } else {
1789
1564
  var state = this.lineTypes[start.row] == _grammar.commands[_cmd].className;
1790
-
1791
1565
  for (var line = start.row; line <= end.row; line++) {
1792
1566
  if (this.lineTypes[line] == _grammar.commands[_cmd].className != state) {
1793
1567
  state = null;
1794
1568
  break;
1795
1569
  }
1796
1570
  }
1797
-
1798
1571
  commandState[_cmd] = state;
1799
1572
  }
1800
1573
  }
1801
1574
  }
1802
-
1803
1575
  return commandState;
1804
1576
  }
1577
+
1805
1578
  /**
1806
1579
  * Sets a command state
1807
1580
  * @param {string} command
1808
1581
  * @param {boolean} state
1809
1582
  */
1810
-
1811
1583
  }, {
1812
1584
  key: "setCommandState",
1813
1585
  value: function setCommandState(command, state) {
@@ -1819,8 +1591,9 @@ var Editor = /*#__PURE__*/function () {
1819
1591
  if (anchor.row != focus.row) return;
1820
1592
  if (!this.isInlineFormattingAllowed(focus, anchor)) return;
1821
1593
  var markupNode = this.computeEnclosingMarkupNode(focus, anchor, _grammar.commands[command].className);
1822
- this.clearDirtyFlag(); // First case: There's an enclosing markup node, remove the markers around that markup node
1594
+ this.clearDirtyFlag();
1823
1595
 
1596
+ // First case: There's an enclosing markup node, remove the markers around that markup node
1824
1597
  if (markupNode) {
1825
1598
  this.lineDirty[focus.row] = true;
1826
1599
  var startCol = this.computeColumn(markupNode, 0);
@@ -1832,72 +1605,66 @@ var Editor = /*#__PURE__*/function () {
1832
1605
  anchor.col = left.length;
1833
1606
  focus.col = anchor.col + len;
1834
1607
  this.updateFormatting();
1835
- this.setSelection(focus, anchor); // Second case: Empty selection with surrounding formatting markers, remove those
1608
+ this.setSelection(focus, anchor);
1609
+
1610
+ // Second case: Empty selection with surrounding formatting markers, remove those
1836
1611
  } else if (focus.col == anchor.col && !!this.lines[focus.row].substr(0, focus.col).match(_grammar.commands[command].unset.prePattern) && !!this.lines[focus.row].substr(focus.col).match(_grammar.commands[command].unset.postPattern)) {
1837
1612
  this.lineDirty[focus.row] = true;
1838
-
1839
1613
  var _left = this.lines[focus.row].substr(0, focus.col).replace(_grammar.commands[command].unset.prePattern, '');
1840
-
1841
1614
  var _right = this.lines[focus.row].substr(focus.col).replace(_grammar.commands[command].unset.postPattern, '');
1842
-
1843
1615
  this.lines[focus.row] = _left.concat(_right);
1844
1616
  focus.col = anchor.col = _left.length;
1845
1617
  this.updateFormatting();
1846
- this.setSelection(focus, anchor); // Not currently formatted, insert formatting markers
1618
+ this.setSelection(focus, anchor);
1619
+
1620
+ // Not currently formatted, insert formatting markers
1847
1621
  } else {
1848
1622
  // Trim any spaces from the selection
1849
1623
  var _ref = focus.col < anchor.col ? {
1850
- startCol: focus.col,
1851
- endCol: anchor.col
1852
- } : {
1853
- startCol: anchor.col,
1854
- endCol: focus.col
1855
- },
1856
- _startCol = _ref.startCol,
1857
- endCol = _ref.endCol;
1858
-
1859
- var match = this.lines[focus.row].substr(_startCol, endCol - _startCol).match( /*#__PURE__*/_wrapRegExp(/^([\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*).*[\0-\x08\x0E-\x1F!-\x9F\xA1-\u167F\u1681-\u1FFF\u200B-\u2027\u202A-\u202E\u2030-\u205E\u2060-\u2FFF\u3001-\uFEFE\uFF00-\uFFFF]([\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*)$/, {
1624
+ startCol: focus.col,
1625
+ endCol: anchor.col
1626
+ } : {
1627
+ startCol: anchor.col,
1628
+ endCol: focus.col
1629
+ },
1630
+ _startCol = _ref.startCol,
1631
+ endCol = _ref.endCol;
1632
+ var match = this.lines[focus.row].substr(_startCol, endCol - _startCol).match( /*#__PURE__*/_wrapRegExp(/^(\s*).*\S(\s*)$/, {
1860
1633
  leading: 1,
1861
1634
  trailing: 2
1862
1635
  }));
1863
-
1864
1636
  if (match) {
1865
1637
  _startCol += match.groups.leading.length;
1866
1638
  endCol -= match.groups.trailing.length;
1867
1639
  }
1868
-
1869
1640
  focus.col = _startCol;
1870
- anchor.col = endCol; // Just insert markup before and after and hope for the best.
1641
+ anchor.col = endCol;
1871
1642
 
1872
- this.wrapSelection(_grammar.commands[command].set.pre, _grammar.commands[command].set.post, focus, anchor); // TODO clean this up so that markup remains properly nested
1643
+ // Just insert markup before and after and hope for the best.
1644
+ this.wrapSelection(_grammar.commands[command].set.pre, _grammar.commands[command].set.post, focus, anchor);
1645
+ // TODO clean this up so that markup remains properly nested
1873
1646
  }
1874
1647
  } else if (_grammar.commands[command].type == 'line') {
1875
1648
  var _anchor = this.getSelection(true);
1876
-
1877
1649
  var _focus = this.getSelection(false);
1878
-
1879
1650
  if (!_anchor) _anchor = _focus;
1880
1651
  if (!_focus) return;
1881
1652
  this.clearDirtyFlag();
1882
1653
  var start = _anchor.row > _focus.row ? _focus : _anchor;
1883
1654
  var end = _anchor.row > _focus.row ? _anchor : _focus;
1884
-
1885
1655
  if (end.row > start.row && end.col == 0) {
1886
1656
  end.row--;
1887
1657
  }
1888
-
1889
1658
  for (var line = start.row; line <= end.row; line++) {
1890
1659
  if (state && this.lineTypes[line] != _grammar.commands[command].className) {
1891
1660
  this.lines[line] = this.lines[line].replace(_grammar.commands[command].set.pattern, _grammar.commands[command].set.replacement.replace('$#', line - start.row + 1));
1892
1661
  this.lineDirty[line] = true;
1893
1662
  }
1894
-
1895
1663
  if (!state && this.lineTypes[line] == _grammar.commands[command].className) {
1896
1664
  this.lines[line] = this.lines[line].replace(_grammar.commands[command].unset.pattern, _grammar.commands[command].unset.replacement);
1897
1665
  this.lineDirty[line] = true;
1898
1666
  }
1899
1667
  }
1900
-
1901
1668
  this.updateFormatting();
1902
1669
  this.setSelection({
1903
1670
  row: end.row,
@@ -1908,40 +1675,41 @@ var Editor = /*#__PURE__*/function () {
1908
1675
  });
1909
1676
  }
1910
1677
  }
1678
+
1911
1679
  /**
1912
1680
  * Returns whether or not inline formatting is allowed at the current focus
1913
1681
  * @param {object} focus The current focus
1914
1682
  */
1915
-
1916
1683
  }, {
1917
1684
  key: "isInlineFormattingAllowed",
1918
1685
  value: function isInlineFormattingAllowed() {
1919
1686
  // TODO Remove parameters from all calls
1920
1687
  var sel = window.getSelection();
1921
- if (!sel) return false; // Check if we can find a common ancestor with the class `TMInlineFormatted`
1922
- // Special case: Empty selection right before `TMInlineFormatted`
1688
+ if (!sel) return false;
1689
+
1690
+ // Check if we can find a common ancestor with the class `TMInlineFormatted`
1923
1691
 
1692
+ // Special case: Empty selection right before `TMInlineFormatted`
1924
1693
  if (sel.isCollapsed && sel.focusNode.nodeType == 3 && sel.focusOffset == sel.focusNode.nodeValue.length) {
1925
1694
  var node;
1926
-
1927
1695
  for (node = sel.focusNode; node && node.nextSibling == null; node = node.parentNode) {
1928
1696
  ;
1929
1697
  }
1930
-
1931
1698
  if (node && node.nextSibling.className && node.nextSibling.className.includes('TMInlineFormatted')) return true;
1932
- } // Look for a common ancestor
1933
-
1699
+ }
1934
1700
 
1701
+ // Look for a common ancestor
1935
1702
  var ancestor = this.computeCommonAncestor(sel.focusNode, sel.anchorNode);
1936
- if (!ancestor) return false; // Check if there's an ancestor of class 'TMInlineFormatted' or 'TMBlankLine'
1703
+ if (!ancestor) return false;
1937
1704
 
1705
+ // Check if there's an ancestor of class 'TMInlineFormatted' or 'TMBlankLine'
1938
1706
  while (ancestor && ancestor != this.e) {
1939
1707
  if (ancestor.className && (ancestor.className.includes('TMInlineFormatted') || ancestor.className.includes('TMBlankLine'))) return true;
1940
1708
  ancestor = ancestor.parentNode;
1941
1709
  }
1942
-
1943
1710
  return false;
1944
1711
  }
1712
+
1945
1713
  /**
1946
1714
  * Wraps the current selection in the strings pre and post. If the selection is not on one line, returns.
1947
1715
  * @param {string} pre The string to insert before the selection.
@@ -1949,7 +1717,6 @@ var Editor = /*#__PURE__*/function () {
1949
1717
  * @param {object} focus The current selection focus. If null, selection will be computed.
1950
1718
  * @param {object} anchor The current selection focus. If null, selection will be computed.
1951
1719
  */
1952
-
1953
1720
  }, {
1954
1721
  key: "wrapSelection",
1955
1722
  value: function wrapSelection(pre, post) {
@@ -1970,31 +1737,29 @@ var Editor = /*#__PURE__*/function () {
1970
1737
  this.updateFormatting();
1971
1738
  this.setSelection(focus, anchor);
1972
1739
  }
1740
+
1973
1741
  /**
1974
1742
  * Toggles the command state for a command (true <-> false)
1975
1743
  * @param {string} command The editor command
1976
1744
  */
1977
-
1978
1745
  }, {
1979
1746
  key: "toggleCommandState",
1980
1747
  value: function toggleCommandState(command) {
1981
1748
  if (!this.lastCommandState) this.lastCommandState = this.getCommandState();
1982
1749
  this.setCommandState(command, !this.lastCommandState[command]);
1983
1750
  }
1751
+
1984
1752
  /**
1985
1753
  * Fires a change event. Updates the linked textarea and notifies any event listeners.
1986
1754
  */
1987
-
1988
1755
  }, {
1989
1756
  key: "fireChange",
1990
1757
  value: function fireChange() {
1991
1758
  if (!this.textarea && !this.listeners.change.length) return;
1992
1759
  var content = this.getContent();
1993
1760
  if (this.textarea) this.textarea.value = content;
1994
-
1995
1761
  var _iterator3 = _createForOfIteratorHelper(this.listeners.change),
1996
- _step3;
1997
-
1762
+ _step3;
1998
1763
  try {
1999
1764
  for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
2000
1765
  var listener = _step3.value;
@@ -2009,10 +1774,10 @@ var Editor = /*#__PURE__*/function () {
2009
1774
  _iterator3.f();
2010
1775
  }
2011
1776
  }
1777
+
2012
1778
  /**
2013
1779
  * Fires a "selection changed" event.
2014
1780
  */
2015
-
2016
1781
  }, {
2017
1782
  key: "fireSelection",
2018
1783
  value: function fireSelection() {
@@ -2020,16 +1785,13 @@ var Editor = /*#__PURE__*/function () {
2020
1785
  var focus = this.getSelection(false);
2021
1786
  var anchor = this.getSelection(true);
2022
1787
  var commandState = this.getCommandState(focus, anchor);
2023
-
2024
1788
  if (this.lastCommandState) {
2025
1789
  Object.assign(this.lastCommandState, commandState);
2026
1790
  } else {
2027
1791
  this.lastCommandState = Object.assign({}, commandState);
2028
1792
  }
2029
-
2030
1793
  var _iterator4 = _createForOfIteratorHelper(this.listeners.selection),
2031
- _step4;
2032
-
1794
+ _step4;
2033
1795
  try {
2034
1796
  for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
2035
1797
  var listener = _step4.value;
@@ -2046,27 +1808,24 @@ var Editor = /*#__PURE__*/function () {
2046
1808
  }
2047
1809
  }
2048
1810
  }
1811
+
2049
1812
  /**
2050
1813
  * Adds an event listener.
2051
1814
  * @param {string} type The type of event to listen to. Can be 'change' or 'selection'
2052
1815
  * @param {*} listener Function of the type (event) => {} to be called when the event occurs.
2053
1816
  */
2054
-
2055
1817
  }, {
2056
1818
  key: "addEventListener",
2057
1819
  value: function addEventListener(type, listener) {
2058
1820
  if (type.match(/^(?:change|input)$/i)) {
2059
1821
  this.listeners.change.push(listener);
2060
1822
  }
2061
-
2062
1823
  if (type.match(/^(?:selection|selectionchange)$/i)) {
2063
1824
  this.listeners.selection.push(listener);
2064
1825
  }
2065
1826
  }
2066
1827
  }]);
2067
-
2068
1828
  return Editor;
2069
1829
  }();
2070
-
2071
1830
  var _default = Editor;
2072
1831
  exports.default = _default;