@taufik-nurrohman/text-editor.source 3.0.0 → 3.0.1
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/index.js +184 -133
- package/index.min.js +1 -1
- package/index.mjs +135 -81
- package/package.json +2 -1
package/index.js
CHANGED
@@ -27,32 +27,30 @@
|
|
27
27
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = f() : typeof define === 'function' && define.amd ? define(f) : (g = typeof globalThis !== 'undefined' ? globalThis : g || self, (g.TextEditor = g.TextEditor || {}, g.TextEditor.Source = f()));
|
28
28
|
})(this, (function () {
|
29
29
|
'use strict';
|
30
|
-
var debounce = function debounce(then, time) {
|
31
|
-
var timer;
|
32
|
-
return function () {
|
33
|
-
var _arguments = arguments,
|
34
|
-
_this = this;
|
35
|
-
timer && clearTimeout(timer);
|
36
|
-
timer = setTimeout(function () {
|
37
|
-
return then.apply(_this, _arguments);
|
38
|
-
}, time);
|
39
|
-
};
|
40
|
-
};
|
41
30
|
var hasValue = function hasValue(x, data) {
|
42
31
|
return -1 !== data.indexOf(x);
|
43
32
|
};
|
44
33
|
var isArray = function isArray(x) {
|
45
34
|
return Array.isArray(x);
|
46
35
|
};
|
47
|
-
var isDefined
|
36
|
+
var isDefined = function isDefined(x) {
|
48
37
|
return 'undefined' !== typeof x;
|
49
38
|
};
|
50
|
-
var
|
51
|
-
return
|
39
|
+
var isFunction = function isFunction(x) {
|
40
|
+
return 'function' === typeof x;
|
41
|
+
};
|
42
|
+
var isInstance = function isInstance(x, of) {
|
43
|
+
return x && isSet(of) && x instanceof of ;
|
52
44
|
};
|
53
|
-
var
|
45
|
+
var isInteger = function isInteger(x) {
|
46
|
+
return isNumber(x) && 0 === x % 1;
|
47
|
+
};
|
48
|
+
var isNull = function isNull(x) {
|
54
49
|
return null === x;
|
55
50
|
};
|
51
|
+
var isNumber = function isNumber(x) {
|
52
|
+
return 'number' === typeof x;
|
53
|
+
};
|
56
54
|
var isObject = function isObject(x, isPlain) {
|
57
55
|
if (isPlain === void 0) {
|
58
56
|
isPlain = true;
|
@@ -60,13 +58,10 @@
|
|
60
58
|
if ('object' !== typeof x) {
|
61
59
|
return false;
|
62
60
|
}
|
63
|
-
return isPlain ? isInstance
|
64
|
-
};
|
65
|
-
var isSet$1 = function isSet(x) {
|
66
|
-
return isDefined$1(x) && !isNull$1(x);
|
61
|
+
return isPlain ? isInstance(x, Object) : true;
|
67
62
|
};
|
68
|
-
var
|
69
|
-
return
|
63
|
+
var isSet = function isSet(x) {
|
64
|
+
return isDefined(x) && !isNull(x);
|
70
65
|
};
|
71
66
|
var toCount = function toCount(x) {
|
72
67
|
return x.length;
|
@@ -82,7 +77,7 @@
|
|
82
77
|
for (var i = 0, j = toCount(lot); i < j; ++i) {
|
83
78
|
for (var k in lot[i]) {
|
84
79
|
// Assign value
|
85
|
-
if (!isSet
|
80
|
+
if (!isSet(out[k])) {
|
86
81
|
out[k] = lot[i][k];
|
87
82
|
continue;
|
88
83
|
}
|
@@ -106,30 +101,21 @@
|
|
106
101
|
}
|
107
102
|
return out;
|
108
103
|
};
|
109
|
-
var
|
110
|
-
|
104
|
+
var W = window;
|
105
|
+
var debounce = function debounce(then, time) {
|
106
|
+
var timer;
|
107
|
+
return function () {
|
108
|
+
var _arguments = arguments,
|
109
|
+
_this = this;
|
110
|
+
timer && clearTimeout(timer);
|
111
|
+
timer = setTimeout(function () {
|
112
|
+
return then.apply(_this, _arguments);
|
113
|
+
}, time);
|
114
|
+
};
|
111
115
|
};
|
112
116
|
var offEventDefault = function offEventDefault(e) {
|
113
117
|
return e && e.preventDefault();
|
114
118
|
};
|
115
|
-
var onEvent = function onEvent(name, node, then, options) {
|
116
|
-
if (options === void 0) {
|
117
|
-
options = false;
|
118
|
-
}
|
119
|
-
node.addEventListener(name, then, options);
|
120
|
-
};
|
121
|
-
var isDefined = function isDefined(x) {
|
122
|
-
return 'undefined' !== typeof x;
|
123
|
-
};
|
124
|
-
var isInstance = function isInstance(x, of) {
|
125
|
-
return x && isSet(of) && x instanceof of ;
|
126
|
-
};
|
127
|
-
var isNull = function isNull(x) {
|
128
|
-
return null === x;
|
129
|
-
};
|
130
|
-
var isSet = function isSet(x) {
|
131
|
-
return isDefined(x) && !isNull(x);
|
132
|
-
};
|
133
119
|
var isPattern = function isPattern(pattern) {
|
134
120
|
return isInstance(pattern, RegExp);
|
135
121
|
};
|
@@ -147,37 +133,38 @@
|
|
147
133
|
}, 10);
|
148
134
|
|
149
135
|
function onKeyDown(e) {
|
150
|
-
var
|
151
|
-
var
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
bounce(editor);
|
158
|
-
if (editor.keys[keys]) {
|
136
|
+
var _$$state$source, _$$state$source2;
|
137
|
+
var $ = this,
|
138
|
+
key = $.k(false).pop(),
|
139
|
+
// Capture the last key
|
140
|
+
keys = $.k();
|
141
|
+
bounce($);
|
142
|
+
if (e.defaultPrevented || $.keys[keys]) {
|
159
143
|
return;
|
160
144
|
}
|
161
145
|
var charAfter,
|
162
146
|
charBefore,
|
163
|
-
charIndent = ((
|
164
|
-
charPairs = ((
|
147
|
+
charIndent = ((_$$state$source = $.state.source) == null ? void 0 : _$$state$source.tab) || $.state.tab || '\t',
|
148
|
+
charPairs = ((_$$state$source2 = $.state.source) == null ? void 0 : _$$state$source2.pairs) || {},
|
165
149
|
charPairsValues = toObjectValues(charPairs);
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
150
|
+
if (isInteger(charIndent)) {
|
151
|
+
charIndent = ' '.repeat(charIndent);
|
152
|
+
}
|
153
|
+
var _$$$ = $.$(),
|
154
|
+
after = _$$$.after,
|
155
|
+
before = _$$$.before,
|
156
|
+
end = _$$$.end,
|
157
|
+
start = _$$$.start,
|
158
|
+
value = _$$$.value,
|
172
159
|
lineAfter = after.split('\n').shift(),
|
173
160
|
lineBefore = before.split('\n').pop(),
|
174
|
-
lineMatch = lineBefore
|
175
|
-
lineMatchIndent = lineMatch && lineMatch[
|
161
|
+
lineMatch = /^\s+/.exec(lineBefore),
|
162
|
+
lineMatchIndent = lineMatch && lineMatch[0] || "";
|
176
163
|
if (CTRL_PREFIX + SHIFT_PREFIX + 'Enter' === keys) {
|
177
164
|
if (before || after) {
|
178
165
|
// Insert line above with `⎈⇧↵`
|
179
166
|
offEventDefault(e);
|
180
|
-
return
|
167
|
+
return $.select(start - toCount(lineBefore)).wrap(lineMatchIndent, '\n').insert(value).record(), false;
|
181
168
|
}
|
182
169
|
return;
|
183
170
|
}
|
@@ -185,7 +172,7 @@
|
|
185
172
|
if (before || after) {
|
186
173
|
// Insert line below with `⎈↵`
|
187
174
|
offEventDefault(e);
|
188
|
-
return
|
175
|
+
return $.select(end + toCount(lineAfter)).wrap('\n' + lineMatchIndent, "").insert(value).record(), false;
|
189
176
|
}
|
190
177
|
}
|
191
178
|
// Do nothing
|
@@ -197,11 +184,11 @@
|
|
197
184
|
charAfter = charPairs[charBefore = before.slice(-1)];
|
198
185
|
if (!value && charAfter && charBefore && charAfter === after[0]) {
|
199
186
|
offEventDefault(e);
|
200
|
-
return
|
187
|
+
return $.wrap(' ', ' ');
|
201
188
|
}
|
202
189
|
return;
|
203
190
|
}
|
204
|
-
if ('Backspace' === keys) {
|
191
|
+
if ('Backspace' === keys || 'Delete' === keys) {
|
205
192
|
charAfter = charPairs[charBefore = before.slice(-1)];
|
206
193
|
// Do nothing on escape
|
207
194
|
if ('\\' === charBefore) {
|
@@ -210,7 +197,7 @@
|
|
210
197
|
if (value) {
|
211
198
|
if (after && before && charAfter && charAfter === after[0] && !before.endsWith('\\' + charBefore)) {
|
212
199
|
offEventDefault(e);
|
213
|
-
return
|
200
|
+
return $.record().peel(charBefore, charAfter).record();
|
214
201
|
}
|
215
202
|
return;
|
216
203
|
}
|
@@ -219,19 +206,19 @@
|
|
219
206
|
if (after.startsWith(' ' + charAfter) && before.endsWith(charBefore + ' ') || after.startsWith('\n' + lineMatchIndent + charAfter) && before.endsWith(charBefore + '\n' + lineMatchIndent)) {
|
220
207
|
// Collapse bracket(s)
|
221
208
|
offEventDefault(e);
|
222
|
-
return
|
209
|
+
return $.trim("", "").record();
|
223
210
|
}
|
224
211
|
}
|
225
212
|
// Outdent
|
226
|
-
if (lineBefore.endsWith(charIndent)) {
|
213
|
+
if ('Delete' !== keys && lineBefore.endsWith(charIndent)) {
|
227
214
|
offEventDefault(e);
|
228
|
-
return
|
215
|
+
return $.pull(charIndent).record();
|
229
216
|
}
|
230
217
|
if (after && before && !before.endsWith('\\' + charBefore)) {
|
231
218
|
if (charAfter === after[0] && charBefore === before.slice(-1)) {
|
232
219
|
// Peel pair
|
233
220
|
offEventDefault(e);
|
234
|
-
return
|
221
|
+
return $.peel(charBefore, charAfter).record();
|
235
222
|
}
|
236
223
|
}
|
237
224
|
return;
|
@@ -240,11 +227,11 @@
|
|
240
227
|
if (!value) {
|
241
228
|
if (after && before && (charAfter = charPairs[charBefore = before.slice(-1)]) && charAfter === after[0]) {
|
242
229
|
offEventDefault(e);
|
243
|
-
return
|
230
|
+
return $.wrap('\n' + lineMatchIndent + (charBefore !== charAfter ? charIndent : ""), '\n' + lineMatchIndent).record();
|
244
231
|
}
|
245
232
|
if (lineMatchIndent) {
|
246
233
|
offEventDefault(e);
|
247
|
-
return
|
234
|
+
return $.insert('\n' + lineMatchIndent, -1).record();
|
248
235
|
}
|
249
236
|
}
|
250
237
|
return;
|
@@ -254,30 +241,29 @@
|
|
254
241
|
return;
|
255
242
|
}
|
256
243
|
charAfter = hasValue(after[0], charPairsValues) ? after[0] : charPairs[charBefore];
|
257
|
-
keys = keys.replace(SHIFT_PREFIX, "");
|
258
244
|
// `|}`
|
259
|
-
if (!value && after && before && charAfter &&
|
245
|
+
if (!value && after && before && charAfter && key === charAfter) {
|
260
246
|
// Move to the next character
|
261
247
|
// `}|`
|
262
248
|
offEventDefault(e);
|
263
|
-
return
|
249
|
+
return $.select(start + 1).record();
|
264
250
|
}
|
265
251
|
for (charBefore in charPairs) {
|
266
252
|
charAfter = charPairs[charBefore];
|
267
253
|
// `{|`
|
268
|
-
if (
|
254
|
+
if (key === charBefore && charAfter) {
|
269
255
|
// Wrap pair or selection
|
270
256
|
// `{|}` `{|aaa|}`
|
271
257
|
offEventDefault(e);
|
272
|
-
return
|
258
|
+
return $.wrap(charBefore, charAfter).record();
|
273
259
|
}
|
274
260
|
// `|}`
|
275
|
-
if (
|
261
|
+
if (key === charAfter) {
|
276
262
|
if (value) {
|
277
263
|
// Wrap selection
|
278
264
|
// `{|aaa|}`
|
279
265
|
offEventDefault(e);
|
280
|
-
return
|
266
|
+
return $.record().wrap(charBefore, charAfter).record();
|
281
267
|
}
|
282
268
|
break;
|
283
269
|
}
|
@@ -298,17 +284,17 @@
|
|
298
284
|
tokens.push('[\\s\\S]'); // Last try!
|
299
285
|
if (CTRL_PREFIX + 'ArrowLeft' === keys) {
|
300
286
|
offEventDefault(e);
|
301
|
-
if (m =
|
302
|
-
return
|
287
|
+
if (m = toPattern('(' + tokens.join('|') + ')$', "").exec(before)) {
|
288
|
+
return $.insert("").select(start - toCount(m[0])).insert(value).record();
|
303
289
|
}
|
304
|
-
return
|
290
|
+
return $.select();
|
305
291
|
}
|
306
292
|
if (CTRL_PREFIX + 'ArrowRight' === keys) {
|
307
293
|
offEventDefault(e);
|
308
294
|
if (m = after.match(toPattern('^(' + tokens.join('|') + ')', ""))) {
|
309
|
-
return
|
295
|
+
return $.insert("").select(end + toCount(m[0]) - toCount(value)).insert(value).record();
|
310
296
|
}
|
311
|
-
return
|
297
|
+
return $.select();
|
312
298
|
}
|
313
299
|
}
|
314
300
|
// Force to select the current line if there is no selection
|
@@ -318,40 +304,40 @@
|
|
318
304
|
if (CTRL_PREFIX + 'ArrowUp' === keys) {
|
319
305
|
offEventDefault(e);
|
320
306
|
if (!hasValue('\n', before)) {
|
321
|
-
return
|
307
|
+
return $.select();
|
322
308
|
}
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
var
|
327
|
-
before =
|
328
|
-
start =
|
309
|
+
$.insert("");
|
310
|
+
$.replace(/^([^\n]*?)(\n|$)/, '$2', 1);
|
311
|
+
$.replace(/(^|\n)([^\n]*?)$/, "", -1);
|
312
|
+
var s = $.$();
|
313
|
+
before = s.before;
|
314
|
+
start = s.start;
|
329
315
|
lineBefore = before.split('\n').pop();
|
330
|
-
|
331
|
-
|
332
|
-
return
|
316
|
+
$.select(start = start - toCount(lineBefore)).wrap(value, '\n');
|
317
|
+
$.select(start, start + toCount(value));
|
318
|
+
return $.record();
|
333
319
|
}
|
334
320
|
if (CTRL_PREFIX + 'ArrowDown' === keys) {
|
335
321
|
offEventDefault(e);
|
336
322
|
if (!hasValue('\n', after)) {
|
337
|
-
return
|
323
|
+
return $.select();
|
338
324
|
}
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
var
|
343
|
-
after =
|
344
|
-
end =
|
325
|
+
$.insert("");
|
326
|
+
$.replace(/^([^\n]*?)(\n|$)/, "", 1);
|
327
|
+
$.replace(/(^|\n)([^\n]*?)$/, '$1', -1);
|
328
|
+
var _s = $.$();
|
329
|
+
after = _s.after;
|
330
|
+
end = _s.end;
|
345
331
|
lineAfter = after.split('\n').shift();
|
346
|
-
|
332
|
+
$.select(end = end + toCount(lineAfter)).wrap('\n', value);
|
347
333
|
end += 1;
|
348
|
-
|
349
|
-
return
|
334
|
+
$.select(end, end + toCount(value));
|
335
|
+
return $.record();
|
350
336
|
}
|
351
337
|
return;
|
352
338
|
}
|
353
339
|
|
354
|
-
function attach(
|
340
|
+
function attach() {
|
355
341
|
var $ = this;
|
356
342
|
$.state = fromStates({
|
357
343
|
source: {
|
@@ -363,47 +349,112 @@
|
|
363
349
|
'"': '"',
|
364
350
|
"'": "'",
|
365
351
|
'<': '>'
|
366
|
-
}
|
367
|
-
type: null
|
352
|
+
}
|
368
353
|
}
|
369
354
|
}, $.state);
|
370
|
-
$.
|
371
|
-
|
372
|
-
|
355
|
+
$.alert = function (hint, then) {
|
356
|
+
W.alert && W.alert(hint);
|
357
|
+
return isFunction(then) && then.call($, true);
|
358
|
+
};
|
359
|
+
$.confirm = function (hint, then) {
|
360
|
+
return isFunction(then) && then.call($, W.confirm && W.confirm(hint));
|
361
|
+
};
|
362
|
+
$.insertBlock = function (value, mode) {
|
363
|
+
var _$$$2 = $.$(),
|
364
|
+
after = _$$$2.after,
|
365
|
+
before = _$$$2.before,
|
366
|
+
end = _$$$2.end,
|
367
|
+
start = _$$$2.start,
|
368
|
+
lineAfter = after.split('\n').shift(),
|
369
|
+
lineAfterCount = toCount(lineAfter),
|
370
|
+
lineBefore = before.split('\n').pop(),
|
371
|
+
lineBeforeCount = toCount(lineBefore),
|
372
|
+
lineMatch = /^\s+/.exec(lineBefore),
|
373
|
+
lineMatchIndent = lineMatch && lineMatch[0] || "";
|
374
|
+
if (-1 === mode) {
|
375
|
+
return $.select(start - lineBeforeCount).insert('\n', 1).push(lineMatchIndent).insert(value, 1, false);
|
373
376
|
}
|
374
|
-
if (
|
375
|
-
|
377
|
+
if (1 === mode) {
|
378
|
+
return $.select(end + lineAfterCount).insert('\n', -1).push(lineMatchIndent).insert(value, 1, false);
|
376
379
|
}
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
380
|
+
return $.select(start - lineBeforeCount, end + lineAfterCount).insert(value, mode, true).wrap(lineMatchIndent, "");
|
381
|
+
};
|
382
|
+
$.peelBlock = function (open, close, wrap) {
|
383
|
+
var _$$$3 = $.$(),
|
384
|
+
after = _$$$3.after,
|
385
|
+
before = _$$$3.before,
|
386
|
+
end = _$$$3.end,
|
387
|
+
start = _$$$3.start,
|
388
|
+
value = _$$$3.value,
|
389
|
+
closeCount = toCount(close),
|
390
|
+
lineAfter = after.split('\n').shift(),
|
391
|
+
lineAfterCount = toCount(lineAfter),
|
392
|
+
lineBefore = before.split('\n').pop(),
|
393
|
+
lineBeforeCount = toCount(lineBefore),
|
394
|
+
openCount = toCount(open);
|
395
|
+
if (wrap && close === value.slice(-closeCount) && open === value.slice(0, openCount) || close === lineAfter.slice(-closeCount) && open === lineBefore.slice(0, openCount)) {
|
396
|
+
return $.select(start - lineBeforeCount + (wrap ? 0 : openCount), end + lineAfterCount - (wrap ? 0 : closeCount)).peel(open, close, wrap);
|
397
|
+
}
|
398
|
+
return $.select(start, end);
|
399
|
+
};
|
400
|
+
$.prompt = function (hint, value, then) {
|
401
|
+
return isFunction(then) && then.call($, W.prompt ? W.prompt(hint, value) : false);
|
402
|
+
};
|
403
|
+
$.selectBlock = function () {
|
404
|
+
var _$$$4 = $.$(),
|
405
|
+
after = _$$$4.after,
|
406
|
+
before = _$$$4.before,
|
407
|
+
end = _$$$4.end,
|
408
|
+
start = _$$$4.start,
|
409
|
+
lineAfter = after.split('\n').shift(),
|
410
|
+
lineAfterCount = toCount(lineAfter),
|
411
|
+
lineBefore = before.split('\n').pop(),
|
412
|
+
lineBeforeCount = toCount(lineBefore);
|
413
|
+
return $.select(start - lineBeforeCount, end + lineAfterCount);
|
414
|
+
};
|
415
|
+
$.toggle = function (open, close, wrap) {
|
416
|
+
var _$$$5 = $.$(),
|
417
|
+
after = _$$$5.after,
|
418
|
+
before = _$$$5.before,
|
419
|
+
value = _$$$5.value,
|
381
420
|
closeCount = toCount(close),
|
382
421
|
openCount = toCount(open);
|
383
422
|
if (wrap && close === value.slice(-closeCount) && open === value.slice(0, openCount) || close === after.slice(0, closeCount) && open === before.slice(-openCount)) {
|
384
423
|
return $.peel(open, close, wrap);
|
385
424
|
}
|
386
|
-
if (false !== tidy) {
|
387
|
-
if (isString(tidy)) {
|
388
|
-
tidy = [tidy, tidy];
|
389
|
-
} else if (!isArray(tidy)) {
|
390
|
-
tidy = ["", ""];
|
391
|
-
}
|
392
|
-
if (!isSet$1(tidy[1])) {
|
393
|
-
tidy[1] = tidy[0];
|
394
|
-
}
|
395
|
-
$.trim(tidy[0], tidy[1]);
|
396
|
-
}
|
397
425
|
return $.wrap(open, close, wrap);
|
398
426
|
};
|
399
|
-
|
400
|
-
|
427
|
+
$.toggleBlock = function (open, close, wrap) {
|
428
|
+
var _$$$6 = $.$(),
|
429
|
+
after = _$$$6.after,
|
430
|
+
before = _$$$6.before,
|
431
|
+
value = _$$$6.value,
|
432
|
+
closeCount = toCount(close),
|
433
|
+
lineAfter = after.split('\n').shift(),
|
434
|
+
lineBefore = before.split('\n').pop(),
|
435
|
+
openCount = toCount(open);
|
436
|
+
if (wrap && close === value.slice(-closeCount) && open === value.slice(0, openCount) || close === lineAfter.slice(-closeCount) && open === lineBefore.slice(0, openCount)) {
|
437
|
+
return $.peelBlock(open, close, wrap);
|
438
|
+
}
|
439
|
+
return $.wrapBlock(open, close, wrap);
|
440
|
+
};
|
441
|
+
$.wrapBlock = function (open, close, wrap) {
|
442
|
+
var _$$$7 = $.$(),
|
443
|
+
after = _$$$7.after,
|
444
|
+
before = _$$$7.before,
|
445
|
+
end = _$$$7.end,
|
446
|
+
start = _$$$7.start,
|
447
|
+
lineAfter = after.split('\n').shift(),
|
448
|
+
lineAfterCount = toCount(lineAfter),
|
449
|
+
lineBefore = before.split('\n').pop(),
|
450
|
+
lineBeforeCount = toCount(lineBefore);
|
451
|
+
return $.select(start - lineBeforeCount, end + lineAfterCount).wrap(open, close, wrap);
|
452
|
+
};
|
453
|
+
return $.on('key.down', onKeyDown).record();
|
401
454
|
}
|
402
455
|
|
403
|
-
function detach(
|
404
|
-
|
405
|
-
offEvent('keydown', self, onKeyDown);
|
406
|
-
return $;
|
456
|
+
function detach() {
|
457
|
+
return this.off('key.down', onKeyDown);
|
407
458
|
}
|
408
459
|
var index_js = {
|
409
460
|
attach: attach,
|
package/index.min.js
CHANGED
@@ -23,4 +23,4 @@
|
|
23
23
|
* SOFTWARE.
|
24
24
|
*
|
25
25
|
*/
|
26
|
-
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):((e="undefined"!=typeof globalThis?globalThis:e||self).TextEditor=e.TextEditor||{},e.TextEditor.Source=r())}(this,(function(){"use strict";var e,r,t,n=function(e,r){return-1!==r.indexOf(e)},i=function(e){return Array.isArray(e)},o=function(e,r){return
|
26
|
+
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):((e="undefined"!=typeof globalThis?globalThis:e||self).TextEditor=e.TextEditor||{},e.TextEditor.Source=r())}(this,(function(){"use strict";var e,r,t,n=function(e,r){return-1!==r.indexOf(e)},i=function(e){return Array.isArray(e)},o=function(e){return"function"==typeof e},s=function(e,r){return e&&u(r)&&e instanceof r},c=function(e){return l(e)&&0==e%1},l=function(e){return"number"==typeof e},f=function(e,r){return void 0===r&&(r=!0),"object"==typeof e&&(!r||s(e,Object))},u=function(e){return function(e){return void 0!==e}(e)&&!function(e){return null===e}(e)},a=function(e){return e.length},p=function(e){return Object.values(e)},d=function e(){for(var r=arguments.length,t=Array(r),o=0;o<r;o++)t[o]=arguments[o];for(var s=t.shift(),c=0,l=a(t);c<l;++c)for(var p in t[c])if(u(s[p]))if(i(s[p])&&i(t[c][p])){s[p]=[].concat(s[p]);for(var d=0,h=a(t[c][p]);d<h;++d)n(t[c][p][d],s[p])||s[p].push(t[c][p][d])}else f(s[p])&&f(t[c][p])?s[p]=e({},s[p],t[c][p]):s[p]=t[c][p];else s[p]=t[c][p];return s},h=window,v=function(e){return e&&e.preventDefault()},w=function(e,r){return function(e){return s(e,RegExp)}(e)?e:RegExp(e,u(r)?r:"g")},b="Alt-",$="Control-",m="Shift-",k=(e=function(e){return e.record()},r=10,function(){var n=arguments,i=this;t&&clearTimeout(t),t=setTimeout((function(){return e.apply(i,n)}),r)});function y(e){var r,t,i=this,o=i.k(!1).pop(),s=i.k();if(k(i),!e.defaultPrevented&&!i.keys[s]){var l,f,u=(null==(r=i.state.source)?void 0:r.tab)||i.state.tab||"\t",d=(null==(t=i.state.source)?void 0:t.pairs)||{},h=p(d);c(u)&&(u=" ".repeat(u));var y=i.$(),g=y.after,x=y.before,E=y.end,A=y.start,B=y.value,T=g.split("\n").shift(),W=x.split("\n").pop(),j=/^\s+/.exec(W),D=j&&j[0]||"";if($+m+"Enter"===s)return x||g?(v(e),i.select(A-a(W)).wrap(D,"\n").insert(B).record(),!1):void 0;if($+"Enter"===s&&(x||g))return v(e),i.select(E+a(T)).wrap("\n"+D,"").insert(B).record(),!1;if(b!==s+"-"&&$!==s+"-"){if(" "===s)return l=d[f=x.slice(-1)],!B&&l&&f&&l===g[0]?(v(e),i.wrap(" "," ")):void 0;if("Backspace"===s||"Delete"===s){if(l=d[f=x.slice(-1)],"\\"===f)return;return B?g&&x&&l&&l===g[0]&&!x.endsWith("\\"+f)?(v(e),i.record().peel(f,l).record()):void 0:(l=d[f=x.trim().slice(-1)])&&f&&(g.startsWith(" "+l)&&x.endsWith(f+" ")||g.startsWith("\n"+D+l)&&x.endsWith(f+"\n"+D))?(v(e),i.trim("","").record()):"Delete"!==s&&W.endsWith(u)?(v(e),i.pull(u).record()):g&&x&&!x.endsWith("\\"+f)&&l===g[0]&&f===x.slice(-1)?(v(e),i.peel(f,l).record()):void 0}if("Enter"!==s&&m+"Enter"!==s){if("\\"!==(f=x.slice(-1))){if(l=n(g[0],h)?g[0]:d[f],!B&&g&&x&&l&&o===l)return v(e),i.select(A+1).record();for(f in d){if(l=d[f],o===f&&l)return v(e),i.wrap(f,l).record();if(o===l){if(B)return v(e),i.record().wrap(f,l).record();break}}var O,R,S,C=[];if(B){for(O in d)(R=d[O])&&C.push("(?:\\"+O+"(?:\\\\.|[^\\"+O+(R!==O?"\\"+R:"")+"])*\\"+R+")");if(C.push("\\w+"),C.push("\\s+"),C.push("[\\s\\S]"),$+"ArrowLeft"===s)return v(e),(S=w("("+C.join("|")+")$","").exec(x))?i.insert("").select(A-a(S[0])).insert(B).record():i.select();if($+"ArrowRight"===s)return v(e),(S=g.match(w("^("+C.join("|")+")","")))?i.insert("").select(E+a(S[0])-a(B)).insert(B).record():i.select()}if(E+=a(T),A-=a(W),B=W+B+T,$+"ArrowUp"===s){if(v(e),!n("\n",x))return i.select();i.insert(""),i.replace(/^([^\n]*?)(\n|$)/,"$2",1),i.replace(/(^|\n)([^\n]*?)$/,"",-1);var L=i.$();return x=L.before,A=L.start,W=x.split("\n").pop(),i.select(A-=a(W)).wrap(B,"\n"),i.select(A,A+a(B)),i.record()}if($+"ArrowDown"===s){if(v(e),!n("\n",g))return i.select();i.insert(""),i.replace(/^([^\n]*?)(\n|$)/,"",1),i.replace(/(^|\n)([^\n]*?)$/,"$1",-1);var P=i.$();return g=P.after,E=P.end,T=g.split("\n").shift(),i.select(E+=a(T)).wrap("\n",B),E+=1,i.select(E,E+a(B)),i.record()}}}else if(!B){if(g&&x&&(l=d[f=x.slice(-1)])&&l===g[0])return v(e),i.wrap("\n"+D+(f!==l?u:""),"\n"+D).record();if(D)return v(e),i.insert("\n"+D,-1).record()}}else v(e)}}var g={attach:function(){var e=this;return e.state=d({source:{pairs:{"`":"`","(":")","{":"}","[":"]",'"':'"',"'":"'","<":">"}}},e.state),e.alert=function(r,t){return h.alert&&h.alert(r),o(t)&&t.call(e,!0)},e.confirm=function(r,t){return o(t)&&t.call(e,h.confirm&&h.confirm(r))},e.insertBlock=function(r,t){var n=e.$(),i=n.after,o=n.before,s=n.end,c=n.start,l=i.split("\n").shift(),f=a(l),u=o.split("\n").pop(),p=a(u),d=/^\s+/.exec(u),h=d&&d[0]||"";return-1===t?e.select(c-p).insert("\n",1).push(h).insert(r,1,!1):1===t?e.select(s+f).insert("\n",-1).push(h).insert(r,1,!1):e.select(c-p,s+f).insert(r,t,!0).wrap(h,"")},e.peelBlock=function(r,t,n){var i=e.$(),o=i.after,s=i.before,c=i.end,l=i.start,f=i.value,u=a(t),p=o.split("\n").shift(),d=a(p),h=s.split("\n").pop(),v=a(h),w=a(r);return n&&t===f.slice(-u)&&r===f.slice(0,w)||t===p.slice(-u)&&r===h.slice(0,w)?e.select(l-v+(n?0:w),c+d-(n?0:u)).peel(r,t,n):e.select(l,c)},e.prompt=function(r,t,n){return o(n)&&n.call(e,!!h.prompt&&h.prompt(r,t))},e.selectBlock=function(){var r=e.$(),t=r.after,n=r.before,i=r.end,o=r.start,s=t.split("\n").shift(),c=a(s),l=n.split("\n").pop(),f=a(l);return e.select(o-f,i+c)},e.toggle=function(r,t,n){var i=e.$(),o=i.after,s=i.before,c=i.value,l=a(t),f=a(r);return n&&t===c.slice(-l)&&r===c.slice(0,f)||t===o.slice(0,l)&&r===s.slice(-f)?e.peel(r,t,n):e.wrap(r,t,n)},e.toggleBlock=function(r,t,n){var i=e.$(),o=i.after,s=i.before,c=i.value,l=a(t),f=o.split("\n").shift(),u=s.split("\n").pop(),p=a(r);return n&&t===c.slice(-l)&&r===c.slice(0,p)||t===f.slice(-l)&&r===u.slice(0,p)?e.peelBlock(r,t,n):e.wrapBlock(r,t,n)},e.wrapBlock=function(r,t,n){var i=e.$(),o=i.after,s=i.before,c=i.end,l=i.start,f=o.split("\n").shift(),u=a(f),p=s.split("\n").pop(),d=a(p);return e.select(l-d,c+u).wrap(r,t,n)},e.on("key.down",y).record()},detach:function(){return this.off("key.down",y)}};return g}));
|
package/index.mjs
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
+
import {W} from '@taufik-nurrohman/document';
|
1
2
|
import {debounce} from '@taufik-nurrohman/tick';
|
2
3
|
import {fromStates} from '@taufik-nurrohman/from';
|
3
4
|
import {hasValue} from '@taufik-nurrohman/has';
|
4
|
-
import {isArray, isSet, isString} from '@taufik-nurrohman/is';
|
5
|
-
import {
|
5
|
+
import {isArray, isFunction, isInteger, isSet, isString} from '@taufik-nurrohman/is';
|
6
|
+
import {offEventDefault} from '@taufik-nurrohman/event';
|
6
7
|
import {toCount, toObjectValues} from '@taufik-nurrohman/to';
|
7
8
|
import {toPattern} from '@taufik-nurrohman/pattern';
|
8
9
|
|
@@ -13,31 +14,31 @@ const SHIFT_PREFIX = 'Shift-';
|
|
13
14
|
const bounce = debounce($ => $.record(), 10);
|
14
15
|
|
15
16
|
function onKeyDown(e) {
|
16
|
-
let
|
17
|
-
|
18
|
-
keys =
|
19
|
-
|
20
|
-
|
21
|
-
}
|
22
|
-
bounce(editor);
|
23
|
-
if (editor.keys[keys]) {
|
17
|
+
let $ = this,
|
18
|
+
key = $.k(false).pop(), // Capture the last key
|
19
|
+
keys = $.k();
|
20
|
+
bounce($);
|
21
|
+
if (e.defaultPrevented || $.keys[keys]) {
|
24
22
|
return;
|
25
23
|
}
|
26
24
|
let charAfter,
|
27
25
|
charBefore,
|
28
|
-
charIndent =
|
29
|
-
charPairs =
|
26
|
+
charIndent = $.state.source?.tab || $.state.tab || '\t',
|
27
|
+
charPairs = $.state.source?.pairs || {},
|
30
28
|
charPairsValues = toObjectValues(charPairs);
|
31
|
-
|
29
|
+
if (isInteger(charIndent)) {
|
30
|
+
charIndent = ' '.repeat(charIndent);
|
31
|
+
}
|
32
|
+
let {after, before, end, start, value} = $.$(),
|
32
33
|
lineAfter = after.split('\n').shift(),
|
33
34
|
lineBefore = before.split('\n').pop(),
|
34
|
-
lineMatch = lineBefore
|
35
|
-
lineMatchIndent = lineMatch && lineMatch[
|
35
|
+
lineMatch = /^\s+/.exec(lineBefore),
|
36
|
+
lineMatchIndent = lineMatch && lineMatch[0] || "";
|
36
37
|
if (CTRL_PREFIX + SHIFT_PREFIX + 'Enter' === keys) {
|
37
38
|
if (before || after) {
|
38
39
|
// Insert line above with `⎈⇧↵`
|
39
40
|
offEventDefault(e);
|
40
|
-
return
|
41
|
+
return $.select(start - toCount(lineBefore)).wrap(lineMatchIndent, '\n').insert(value).record(), false;
|
41
42
|
}
|
42
43
|
return;
|
43
44
|
}
|
@@ -45,7 +46,7 @@ function onKeyDown(e) {
|
|
45
46
|
if (before || after) {
|
46
47
|
// Insert line below with `⎈↵`
|
47
48
|
offEventDefault(e);
|
48
|
-
return
|
49
|
+
return $.select(end + toCount(lineAfter)).wrap('\n' + lineMatchIndent, "").insert(value).record(), false;
|
49
50
|
}
|
50
51
|
}
|
51
52
|
// Do nothing
|
@@ -57,11 +58,11 @@ function onKeyDown(e) {
|
|
57
58
|
charAfter = charPairs[charBefore = before.slice(-1)];
|
58
59
|
if (!value && charAfter && charBefore && charAfter === after[0]) {
|
59
60
|
offEventDefault(e);
|
60
|
-
return
|
61
|
+
return $.wrap(' ', ' ');
|
61
62
|
}
|
62
63
|
return;
|
63
64
|
}
|
64
|
-
if ('Backspace' === keys) {
|
65
|
+
if ('Backspace' === keys || 'Delete' === keys) {
|
65
66
|
charAfter = charPairs[charBefore = before.slice(-1)];
|
66
67
|
// Do nothing on escape
|
67
68
|
if ('\\' === charBefore) {
|
@@ -70,7 +71,7 @@ function onKeyDown(e) {
|
|
70
71
|
if (value) {
|
71
72
|
if (after && before && charAfter && charAfter === after[0] && !before.endsWith('\\' + charBefore)) {
|
72
73
|
offEventDefault(e);
|
73
|
-
return
|
74
|
+
return $.record().peel(charBefore, charAfter).record();
|
74
75
|
}
|
75
76
|
return;
|
76
77
|
}
|
@@ -82,19 +83,19 @@ function onKeyDown(e) {
|
|
82
83
|
) {
|
83
84
|
// Collapse bracket(s)
|
84
85
|
offEventDefault(e);
|
85
|
-
return
|
86
|
+
return $.trim("", "").record();
|
86
87
|
}
|
87
88
|
}
|
88
89
|
// Outdent
|
89
|
-
if (lineBefore.endsWith(charIndent)) {
|
90
|
+
if ('Delete' !== keys && lineBefore.endsWith(charIndent)) {
|
90
91
|
offEventDefault(e);
|
91
|
-
return
|
92
|
+
return $.pull(charIndent).record();
|
92
93
|
}
|
93
94
|
if (after && before && !before.endsWith('\\' + charBefore)) {
|
94
95
|
if (charAfter === after[0] && charBefore === before.slice(-1)) {
|
95
96
|
// Peel pair
|
96
97
|
offEventDefault(e);
|
97
|
-
return
|
98
|
+
return $.peel(charBefore, charAfter).record();
|
98
99
|
}
|
99
100
|
}
|
100
101
|
return;
|
@@ -103,11 +104,11 @@ function onKeyDown(e) {
|
|
103
104
|
if (!value) {
|
104
105
|
if (after && before && (charAfter = charPairs[charBefore = before.slice(-1)]) && charAfter === after[0]) {
|
105
106
|
offEventDefault(e);
|
106
|
-
return
|
107
|
+
return $.wrap('\n' + lineMatchIndent + (charBefore !== charAfter ? charIndent : ""), '\n' + lineMatchIndent).record();
|
107
108
|
}
|
108
109
|
if (lineMatchIndent) {
|
109
110
|
offEventDefault(e);
|
110
|
-
return
|
111
|
+
return $.insert('\n' + lineMatchIndent, -1).record();
|
111
112
|
}
|
112
113
|
}
|
113
114
|
return;
|
@@ -117,30 +118,29 @@ function onKeyDown(e) {
|
|
117
118
|
return;
|
118
119
|
}
|
119
120
|
charAfter = hasValue(after[0], charPairsValues) ? after[0] : charPairs[charBefore];
|
120
|
-
keys = keys.replace(SHIFT_PREFIX, "");
|
121
121
|
// `|}`
|
122
|
-
if (!value && after && before && charAfter &&
|
122
|
+
if (!value && after && before && charAfter && key === charAfter) {
|
123
123
|
// Move to the next character
|
124
124
|
// `}|`
|
125
125
|
offEventDefault(e);
|
126
|
-
return
|
126
|
+
return $.select(start + 1).record();
|
127
127
|
}
|
128
128
|
for (charBefore in charPairs) {
|
129
129
|
charAfter = charPairs[charBefore];
|
130
130
|
// `{|`
|
131
|
-
if (
|
131
|
+
if (key === charBefore && charAfter) {
|
132
132
|
// Wrap pair or selection
|
133
133
|
// `{|}` `{|aaa|}`
|
134
134
|
offEventDefault(e);
|
135
|
-
return
|
135
|
+
return $.wrap(charBefore, charAfter).record();
|
136
136
|
}
|
137
137
|
// `|}`
|
138
|
-
if (
|
138
|
+
if (key === charAfter) {
|
139
139
|
if (value) {
|
140
140
|
// Wrap selection
|
141
141
|
// `{|aaa|}`
|
142
142
|
offEventDefault(e);
|
143
|
-
return
|
143
|
+
return $.record().wrap(charBefore, charAfter).record();
|
144
144
|
}
|
145
145
|
break;
|
146
146
|
}
|
@@ -160,17 +160,17 @@ function onKeyDown(e) {
|
|
160
160
|
tokens.push('[\\s\\S]'); // Last try!
|
161
161
|
if (CTRL_PREFIX + 'ArrowLeft' === keys) {
|
162
162
|
offEventDefault(e);
|
163
|
-
if (m =
|
164
|
-
return
|
163
|
+
if (m = toPattern('(' + tokens.join('|') + ')$', "").exec(before)) {
|
164
|
+
return $.insert("").select(start - toCount(m[0])).insert(value).record();
|
165
165
|
}
|
166
|
-
return
|
166
|
+
return $.select();
|
167
167
|
}
|
168
168
|
if (CTRL_PREFIX + 'ArrowRight' === keys) {
|
169
169
|
offEventDefault(e);
|
170
170
|
if (m = after.match(toPattern('^(' + tokens.join('|') + ')', ""))) {
|
171
|
-
return
|
171
|
+
return $.insert("").select(end + toCount(m[0]) - toCount(value)).insert(value).record();
|
172
172
|
}
|
173
|
-
return
|
173
|
+
return $.select();
|
174
174
|
}
|
175
175
|
}
|
176
176
|
// Force to select the current line if there is no selection
|
@@ -180,40 +180,40 @@ function onKeyDown(e) {
|
|
180
180
|
if (CTRL_PREFIX + 'ArrowUp' === keys) {
|
181
181
|
offEventDefault(e);
|
182
182
|
if (!hasValue('\n', before)) {
|
183
|
-
return
|
183
|
+
return $.select();
|
184
184
|
}
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
let
|
189
|
-
before =
|
190
|
-
start =
|
185
|
+
$.insert("");
|
186
|
+
$.replace(/^([^\n]*?)(\n|$)/, '$2', 1);
|
187
|
+
$.replace(/(^|\n)([^\n]*?)$/, "", -1);
|
188
|
+
let s = $.$();
|
189
|
+
before = s.before;
|
190
|
+
start = s.start;
|
191
191
|
lineBefore = before.split('\n').pop();
|
192
|
-
|
193
|
-
|
194
|
-
return
|
192
|
+
$.select(start = start - toCount(lineBefore)).wrap(value, '\n');
|
193
|
+
$.select(start, start + toCount(value));
|
194
|
+
return $.record();
|
195
195
|
}
|
196
196
|
if (CTRL_PREFIX + 'ArrowDown' === keys) {
|
197
197
|
offEventDefault(e);
|
198
198
|
if (!hasValue('\n', after)) {
|
199
|
-
return
|
199
|
+
return $.select();
|
200
200
|
}
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
let
|
205
|
-
after =
|
206
|
-
end =
|
201
|
+
$.insert("");
|
202
|
+
$.replace(/^([^\n]*?)(\n|$)/, "", 1);
|
203
|
+
$.replace(/(^|\n)([^\n]*?)$/, '$1', -1);
|
204
|
+
let s = $.$();
|
205
|
+
after = s.after;
|
206
|
+
end = s.end;
|
207
207
|
lineAfter = after.split('\n').shift();
|
208
|
-
|
208
|
+
$.select(end = end + toCount(lineAfter)).wrap('\n', value);
|
209
209
|
end += 1;
|
210
|
-
|
211
|
-
return
|
210
|
+
$.select(end, end + toCount(value));
|
211
|
+
return $.record();
|
212
212
|
}
|
213
213
|
return;
|
214
214
|
}
|
215
215
|
|
216
|
-
function attach(
|
216
|
+
function attach() {
|
217
217
|
let $ = this;
|
218
218
|
$.state = fromStates({
|
219
219
|
source: {
|
@@ -225,14 +225,60 @@ function attach(self) {
|
|
225
225
|
'"': '"',
|
226
226
|
"'": "'",
|
227
227
|
'<': '>'
|
228
|
-
}
|
229
|
-
type: null
|
228
|
+
}
|
230
229
|
}
|
231
230
|
}, $.state);
|
232
|
-
$.
|
233
|
-
|
234
|
-
|
231
|
+
$.alert = (hint, then) => {
|
232
|
+
W.alert && W.alert(hint);
|
233
|
+
return isFunction(then) && then.call($, true);
|
234
|
+
};
|
235
|
+
$.confirm = (hint, then) => {
|
236
|
+
return isFunction(then) && then.call($, W.confirm && W.confirm(hint));
|
237
|
+
};
|
238
|
+
$.insertBlock = (value, mode) => {
|
239
|
+
let {after, before, end, start} = $.$(),
|
240
|
+
lineAfter = after.split('\n').shift(),
|
241
|
+
lineAfterCount = toCount(lineAfter),
|
242
|
+
lineBefore = before.split('\n').pop(),
|
243
|
+
lineBeforeCount = toCount(lineBefore),
|
244
|
+
lineMatch = /^\s+/.exec(lineBefore),
|
245
|
+
lineMatchIndent = lineMatch && lineMatch[0] || "";
|
246
|
+
if (-1 === mode) {
|
247
|
+
return $.select(start - lineBeforeCount).insert('\n', 1).push(lineMatchIndent).insert(value, 1, false);
|
235
248
|
}
|
249
|
+
if (1 === mode) {
|
250
|
+
return $.select(end + lineAfterCount).insert('\n', -1).push(lineMatchIndent).insert(value, 1, false);
|
251
|
+
}
|
252
|
+
return $.select(start - lineBeforeCount, end + lineAfterCount).insert(value, mode, true).wrap(lineMatchIndent, "");
|
253
|
+
};
|
254
|
+
$.peelBlock = (open, close, wrap) => {
|
255
|
+
let {after, before, end, start, value} = $.$(),
|
256
|
+
closeCount = toCount(close),
|
257
|
+
lineAfter = after.split('\n').shift(),
|
258
|
+
lineAfterCount = toCount(lineAfter),
|
259
|
+
lineBefore = before.split('\n').pop(),
|
260
|
+
lineBeforeCount = toCount(lineBefore),
|
261
|
+
openCount = toCount(open);
|
262
|
+
if (
|
263
|
+
(wrap && close === value.slice(-closeCount) && open === value.slice(0, openCount)) ||
|
264
|
+
(close === lineAfter.slice(-closeCount) && open === lineBefore.slice(0, openCount))
|
265
|
+
) {
|
266
|
+
return $.select(start - lineBeforeCount + (wrap ? 0 : openCount), end + lineAfterCount - (wrap ? 0 : closeCount)).peel(open, close, wrap);
|
267
|
+
}
|
268
|
+
return $.select(start, end);
|
269
|
+
};
|
270
|
+
$.prompt = (hint, value, then) => {
|
271
|
+
return isFunction(then) && then.call($, W.prompt ? W.prompt(hint, value) : false);
|
272
|
+
};
|
273
|
+
$.selectBlock = () => {
|
274
|
+
let {after, before, end, start} = $.$(),
|
275
|
+
lineAfter = after.split('\n').shift(),
|
276
|
+
lineAfterCount = toCount(lineAfter),
|
277
|
+
lineBefore = before.split('\n').pop(),
|
278
|
+
lineBeforeCount = toCount(lineBefore);
|
279
|
+
return $.select(start - lineBeforeCount, end + lineAfterCount);
|
280
|
+
};
|
281
|
+
$.toggle = (open, close, wrap) => {
|
236
282
|
let {after, before, value} = $.$(),
|
237
283
|
closeCount = toCount(close),
|
238
284
|
openCount = toCount(open);
|
@@ -242,27 +288,35 @@ function attach(self) {
|
|
242
288
|
) {
|
243
289
|
return $.peel(open, close, wrap);
|
244
290
|
}
|
245
|
-
if (false !== tidy) {
|
246
|
-
if (isString(tidy)) {
|
247
|
-
tidy = [tidy, tidy];
|
248
|
-
} else if (!isArray(tidy)) {
|
249
|
-
tidy = ["", ""];
|
250
|
-
}
|
251
|
-
if (!isSet(tidy[1])) {
|
252
|
-
tidy[1] = tidy[0];
|
253
|
-
}
|
254
|
-
$.trim(tidy[0], tidy[1]);
|
255
|
-
}
|
256
291
|
return $.wrap(open, close, wrap);
|
257
292
|
};
|
258
|
-
|
259
|
-
|
293
|
+
$.toggleBlock = (open, close, wrap) => {
|
294
|
+
let {after, before, value} = $.$(),
|
295
|
+
closeCount = toCount(close),
|
296
|
+
lineAfter = after.split('\n').shift(),
|
297
|
+
lineBefore = before.split('\n').pop(),
|
298
|
+
openCount = toCount(open);
|
299
|
+
if (
|
300
|
+
(wrap && close === value.slice(-closeCount) && open === value.slice(0, openCount)) ||
|
301
|
+
(close === lineAfter.slice(-closeCount) && open === lineBefore.slice(0, openCount))
|
302
|
+
) {
|
303
|
+
return $.peelBlock(open, close, wrap);
|
304
|
+
}
|
305
|
+
return $.wrapBlock(open, close, wrap);
|
306
|
+
};
|
307
|
+
$.wrapBlock = (open, close, wrap) => {
|
308
|
+
let {after, before, end, start} = $.$(),
|
309
|
+
lineAfter = after.split('\n').shift(),
|
310
|
+
lineAfterCount = toCount(lineAfter),
|
311
|
+
lineBefore = before.split('\n').pop(),
|
312
|
+
lineBeforeCount = toCount(lineBefore);
|
313
|
+
return $.select(start - lineBeforeCount, end + lineAfterCount).wrap(open, close, wrap);
|
314
|
+
};
|
315
|
+
return $.on('key.down', onKeyDown).record();
|
260
316
|
}
|
261
317
|
|
262
|
-
function detach(
|
263
|
-
|
264
|
-
offEvent('keydown', self, onKeyDown);
|
265
|
-
return $;
|
318
|
+
function detach() {
|
319
|
+
return this.off('key.down', onKeyDown);
|
266
320
|
}
|
267
321
|
|
268
322
|
export default {attach, detach};
|
package/package.json
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
"browser": "index.min.js",
|
4
4
|
"bugs": "https://github.com/taufik-nurrohman/text-editor.source/issues",
|
5
5
|
"dependencies": {
|
6
|
+
"@taufik-nurrohman/document": "*",
|
6
7
|
"@taufik-nurrohman/event": "*",
|
7
8
|
"@taufik-nurrohman/from": "*",
|
8
9
|
"@taufik-nurrohman/has": "*",
|
@@ -52,5 +53,5 @@
|
|
52
53
|
"scripts": {
|
53
54
|
"pack": "pack --clean=false --from=.factory --js-format=umd --js-name=TextEditor.Source --js-top='%(js.license)' --mjs=true --to=."
|
54
55
|
},
|
55
|
-
"version": "3.0.
|
56
|
+
"version": "3.0.1"
|
56
57
|
}
|