easy-richtextarea 4.0.26 → 4.0.28

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.
@@ -4,6 +4,7 @@ import { Element, document } from "easy";
4
4
 
5
5
  import Selection from "./selection"
6
6
  import UndoBuffer from "./undoBuffer";
7
+ import eventMixins from "./mixins/event";
7
8
  import InsertOperation from "./operation/insert";
8
9
  import DeleteOperation from "./operation/delete";
9
10
  import transformContent from "./transform/content";
@@ -54,90 +55,86 @@ export default class RichTextarea extends Element {
54
55
  this.readOnly = readOnly;
55
56
  }
56
57
 
57
- intermediateHandler = (event, element, undoable = true, eventType = CHANGE_EVENT_TYPE, selectionChanged = this.hasSelectionChanged()) => {
58
- if (this.readOnly) {
59
- const previousContent = this.getPreviousContent(),
60
- content = previousContent; ///
58
+ cutHandler = (event, element) => {
59
+ const selection = this.getSelection(),
60
+ selectionEmpty = selection.isEmpty();
61
61
 
62
- this.setContent(content);
62
+ if (selectionEmpty) {
63
+ return;
63
64
  }
64
65
 
65
- const content = this.getContent(),
66
- selection = this.getSelection(),
67
- contentChanged = this.hasContentChanged(),
68
- changed = (contentChanged || selectionChanged);
69
-
70
- if (changed) {
71
- this.callHandlers(eventType, event, element);
72
- }
66
+ const selectedContent = this.getSelectedContent();
73
67
 
74
- if (undoable) {
75
- if (contentChanged) {
76
- const previousContent = this.getPreviousContent(),
77
- operations = generateOperations(previousContent, content);
68
+ navigator.clipboard.writeText(selectedContent);
78
69
 
79
- this.undoBuffer.addOperations(operations);
80
- }
81
- }
70
+ const content = this.getContent(),
71
+ deleteOperation = DeleteOperation.fromContentAndSelection(content, selection),
72
+ operation = deleteOperation; ///
82
73
 
83
- const previousContent = content, ///
84
- previousSelection = selection; ///
74
+ this.applyOperation(operation);
85
75
 
86
- this.setPreviousContent(previousContent);
76
+ this.intermediateHandler(event, element);
87
77
 
88
- this.setPreviousSelection(previousSelection);
78
+ event.preventDefault();
89
79
  }
90
80
 
91
- selectChangeHandler = (event, element) => {
92
- if (this.focused) {
93
- element = this; ///
81
+ copyHandler = (event, element) => {
82
+ const selection = this.getSelection(),
83
+ selectionEmpty = selection.isEmpty();
94
84
 
95
- this.intermediateHandler(event, element);
85
+ if (selectionEmpty) {
86
+ return;
96
87
  }
97
- }
98
88
 
99
- contextmenuHandler = (event, element) => {
89
+ const selectedContent = this.getSelectedContent();
90
+
91
+ navigator.clipboard.writeText(selectedContent);
92
+
100
93
  event.preventDefault();
101
94
  }
102
95
 
103
- keyDownHandler = (event, element) => {
104
- const { ctrlKey, metaKey } = event;
96
+ pasteHandler = (event, element) => {
97
+ const { clipboardData } = event,
98
+ textData = clipboardData.getData(TEXT);
105
99
 
106
- if (ctrlKey || metaKey) {
107
- const { keyCode } = event;
100
+ if (textData === EMPTY_STRING) {
101
+ return;
102
+ }
108
103
 
109
- switch (keyCode) {
110
- case F_KEY_CODE: {
111
- this.find(event, element);
104
+ const selection = this.getSelection(),
105
+ selectionEmpty = selection.isEmpty();
112
106
 
113
- event.preventDefault();
107
+ if (!selectionEmpty) {
108
+ const content = this.getContent(),
109
+ deleteOperation = DeleteOperation.fromContentAndSelection(content, selection),
110
+ operation = deleteOperation;
114
111
 
115
- return;
116
- }
112
+ this.applyOperation(operation);
113
+ }
117
114
 
118
- case Z_KEY_CODE: {
119
- const { shiftKey } = event;
115
+ const content = textData, ///
116
+ insertOperation = InsertOperation.fromContentAndSelection(content, selection),
117
+ operation = insertOperation; ///
120
118
 
121
- shiftKey ?
122
- this.redo(event, element) :
123
- this.undo(event, element);
119
+ this.applyOperation(operation);
124
120
 
125
- event.preventDefault();
121
+ this.intermediateHandler(event, element);
126
122
 
127
- return;
128
- }
129
- }
130
- }
123
+ event.preventDefault();
124
+ }
131
125
 
132
- defer(() => {
133
- this.intermediateHandler(event, element);
134
- });
126
+ inputHandler = (event, element) => {
127
+ this.intermediateHandler(event, element);
135
128
  }
136
129
 
137
- scrollHandler = (event, element) => {
138
- const eventType = SCROLL_EVENT_TYPE;
130
+ blurHandler = (event, element) => {
131
+ this.focused = false;
139
132
 
140
- this.callHandlers(eventType, event, element);
133
+ const undoable = true,
134
+ eventType = BLUR_EVENT_TYPE,
135
+ selectionChanged = true;
136
+
137
+ this.intermediateHandler(event, element, undoable, eventType, selectionChanged);
141
138
  }
142
139
 
143
140
  focusHandler = (event, element) => {
@@ -152,86 +149,111 @@ export default class RichTextarea extends Element {
152
149
  });
153
150
  }
154
151
 
155
- blurHandler = (event, element) => {
156
- this.focused = false;
157
-
158
- const undoable = true,
159
- eventType = BLUR_EVENT_TYPE,
160
- selectionChanged = true;
152
+ scrollHandler = (event, element) => {
153
+ const eventType = SCROLL_EVENT_TYPE;
161
154
 
162
- this.intermediateHandler(event, element, undoable, eventType, selectionChanged);
155
+ this.callHandlers(eventType, event, element);
163
156
  }
164
157
 
165
- inputHandler = (event, element) => {
166
- this.intermediateHandler(event, element);
167
- }
158
+ keyDownHandler = (event, element) => {
159
+ let preventDefault = false;
168
160
 
169
- pasteHandler = (event, element) => {
170
- const { clipboardData } = event,
171
- textData = clipboardData.getData(TEXT);
161
+ const { keyCode } = event;
172
162
 
173
- if (textData === EMPTY_STRING) {
174
- return;
175
- }
163
+ switch (keyCode) {
164
+ case Z_KEY_CODE:
165
+ preventDefault = this.zKeyDown(event, element);
176
166
 
177
- const selection = this.getSelection(),
178
- selectionEmpty = selection.isEmpty();
167
+ break;
179
168
 
180
- if (!selectionEmpty) {
181
- const content = this.getContent(),
182
- deleteOperation = DeleteOperation.fromContentAndSelection(content, selection),
183
- operation = deleteOperation;
169
+ case F_KEY_CODE:
170
+ preventDefault = this.fKeyDown(event, element);
184
171
 
185
- this.applyOperation(operation);
172
+ break;
186
173
  }
187
174
 
188
- const content = textData, ///
189
- insertOperation = InsertOperation.fromContentAndSelection(content, selection),
190
- operation = insertOperation; ///
175
+ if (preventDefault) {
176
+ event.preventDefault();
191
177
 
192
- this.applyOperation(operation);
178
+ return;
179
+ }
193
180
 
194
- this.intermediateHandler(event, element);
181
+ defer(() => {
182
+ this.intermediateHandler(event, element);
183
+ });
184
+ }
195
185
 
186
+ contextmenuHandler = (event, element) => {
196
187
  event.preventDefault();
197
188
  }
198
189
 
199
- copyHandler = (event, element) => {
200
- const selection = this.getSelection(),
201
- selectionEmpty = selection.isEmpty();
190
+ selectChangeHandler = (event, element) => {
191
+ if (this.focused) {
192
+ element = this; ///
202
193
 
203
- if (selectionEmpty) {
204
- return;
194
+ this.intermediateHandler(event, element);
205
195
  }
196
+ }
206
197
 
207
- const selectedContent = this.getSelectedContent();
198
+ intermediateHandler = (event, element, undoable = true, eventType = CHANGE_EVENT_TYPE, selectionChanged = this.hasSelectionChanged()) => {
199
+ if (this.readOnly) {
200
+ const previousContent = this.getPreviousContent(),
201
+ content = previousContent; ///
208
202
 
209
- navigator.clipboard.writeText(selectedContent);
203
+ this.setContent(content);
204
+ }
210
205
 
211
- event.preventDefault();
212
- }
206
+ const content = this.getContent(),
207
+ selection = this.getSelection(),
208
+ contentChanged = this.hasContentChanged(),
209
+ changed = (contentChanged || selectionChanged);
213
210
 
214
- cutHandler = (event, element) => {
215
- const selection = this.getSelection(),
216
- selectionEmpty = selection.isEmpty();
211
+ if (changed) {
212
+ this.callHandlers(eventType, event, element);
213
+ }
217
214
 
218
- if (selectionEmpty) {
219
- return;
215
+ if (undoable) {
216
+ if (contentChanged) {
217
+ const previousContent = this.getPreviousContent(),
218
+ operations = generateOperations(previousContent, content);
219
+
220
+ this.undoBuffer.addOperations(operations);
221
+ }
220
222
  }
221
223
 
222
- const selectedContent = this.getSelectedContent();
224
+ const previousContent = content, ///
225
+ previousSelection = selection; ///
223
226
 
224
- navigator.clipboard.writeText(selectedContent);
227
+ this.setPreviousContent(previousContent);
225
228
 
226
- const content = this.getContent(),
227
- deleteOperation = DeleteOperation.fromContentAndSelection(content, selection),
228
- operation = deleteOperation; ///
229
+ this.setPreviousSelection(previousSelection);
230
+ }
229
231
 
230
- this.applyOperation(operation);
232
+ callHandlers(eventType, ...remainingArguments) {
233
+ const eventListeners = this.findEventListeners(eventType);
231
234
 
232
- this.intermediateHandler(event, element);
235
+ eventListeners.forEach((eventListener) => {
236
+ let { element } = eventListener;
233
237
 
234
- event.preventDefault();
238
+ const { handler } = eventListener,
239
+ handlerElement = element; ///
240
+
241
+ element = this; ///
242
+
243
+ if ( (handler !== this.cutHandler)
244
+ && (handler !== this.copyHandler)
245
+ && (handler !== this.pasteHandler)
246
+ && (handler !== this.inputHandler)
247
+ && (handler !== this.blurHandler)
248
+ && (handler !== this.focusHandler)
249
+ && (handler !== this.scrollHandler)
250
+ && (handler !== this.keyDownHandler)
251
+ && (handler !== this.contextmenuHandler)
252
+ && (handler !== this.selectChangeHandler) ) {
253
+
254
+ handler.call(handlerElement, ...remainingArguments, element);
255
+ }
256
+ });
235
257
  }
236
258
 
237
259
  isActive() {
@@ -316,42 +338,49 @@ export default class RichTextarea extends Element {
316
338
  }
317
339
  }
318
340
 
319
- find(event, element) {
320
- const eventType = FIND_EVENT_TYPE;
341
+ fKeyDown(event, element) {
342
+ let preventDefault = false;
321
343
 
322
- this.callHandlers(eventType, event, element);
323
- }
344
+ const { ctrlKey, metaKey } = event;
324
345
 
325
- undo(event, element) {
326
- const undoOperation = this.undoBuffer.undo();
346
+ if (ctrlKey || metaKey) {
347
+ const eventType = FIND_EVENT_TYPE;
327
348
 
328
- if (undoOperation !== null) {
329
- const operation = undoOperation; ///
349
+ this.callHandlers(eventType, event, element);
330
350
 
331
- this.revert(event, element, operation);
351
+ preventDefault = true;
332
352
  }
353
+
354
+ return preventDefault;
333
355
  }
334
356
 
335
- redo(event, element) {
336
- const redoOperation = this.undoBuffer.redo();
357
+ zKeyDown(event, element) {
358
+ let preventDefault = false;
337
359
 
338
- if (redoOperation !== null) {
339
- const operation = redoOperation; ///
360
+ const { ctrlKey, metaKey, shiftKey } = event;
340
361
 
341
- this.revert(event, element, operation);
342
- }
343
- }
362
+ if (ctrlKey || metaKey) {
363
+ const operation = shiftKey ?
364
+ this.undoBuffer.redo() :
365
+ this.undoBuffer.undo();
344
366
 
345
- revert(event, element, operation) {
346
- const undoable = false,
347
- selection = Selection.fromOperation(operation),
348
- setPreviousSelection = false;
367
+ if (operation !== null) {
368
+ const undoable = false,
369
+ eventType = CHANGE_EVENT_TYPE,
370
+ selection = Selection.fromOperation(operation),
371
+ setPreviousSelection = false;
349
372
 
350
- this.applyOperation(operation);
373
+ this.applyOperation(operation);
351
374
 
352
- this.setSelection(selection, setPreviousSelection);
375
+ this.setSelection(selection, setPreviousSelection);
376
+
377
+ this.intermediateHandler(event, element, undoable, eventType);
378
+ }
379
+
380
+ preventDefault = true;
381
+ }
353
382
 
354
- this.intermediateHandler(event, element, undoable);
383
+ return preventDefault;
355
384
  }
356
385
 
357
386
  transform(operations) {
@@ -382,23 +411,6 @@ export default class RichTextarea extends Element {
382
411
  this.intermediateHandler(event, element, undoable, eventType);
383
412
  }
384
413
 
385
- callHandlers(eventType, ...remainingArguments) {
386
- const eventListeners = this.findEventListeners(eventType);
387
-
388
- eventListeners.forEach((eventListener) => {
389
- let { element } = eventListener;
390
-
391
- const { handler } = eventListener,
392
- handlerElement = element; ///
393
-
394
- element = this; ///
395
-
396
- if ((handler !== this.blurHandler) && (handler !== this.focusHandler) && (handler !== this.scrollHandler)) {
397
- handler.call(handlerElement, ...remainingArguments, element);
398
- }
399
- });
400
- }
401
-
402
414
  applyOperation(operation) {
403
415
  let content = this.getContent(),
404
416
  selection = this.getSelection();
@@ -419,101 +431,51 @@ export default class RichTextarea extends Element {
419
431
  }
420
432
 
421
433
  activate() {
422
- this.on(KEYDOWN_EVENT_TYPE, this.keyDownHandler, this);
423
-
424
- this.on(INPUT_EVENT_TYPE, this.inputHandler, this);
425
-
426
- this.on(SCROLL_EVENT_TYPE, this.scrollHandler, this);
427
-
428
- this.on(FOCUS_EVENT_TYPE, this.focusHandler, this);
429
-
430
- this.on(BLUR_EVENT_TYPE, this.blurHandler, this);
431
-
432
- this.addClass("active");
433
- }
434
-
435
- deactivate() {
436
- this.off(KEYDOWN_EVENT_TYPE, this.keyDownHandler, this);
437
-
438
- this.off(INPUT_EVENT_TYPE, this.inputHandler, this);
439
-
440
- this.off(SCROLL_EVENT_TYPE, this.scrollHandler, this);
441
-
442
- this.off(FOCUS_EVENT_TYPE, this.focusHandler, this);
434
+ this.on(CUT_EVENT_TYPE, this.cutHandler);
443
435
 
444
- this.off(BLUR_EVENT_TYPE, this.blurHandler, this);
436
+ this.on(COPY_EVENT_TYPE, this.copyHandler);
445
437
 
446
- this.removeClass("active");
447
- }
438
+ this.on(PASTE_EVENT_TYPE, this.pasteHandler);
448
439
 
449
- onFind(findHandler, element) {
450
- const eventType = FIND_EVENT_TYPE,
451
- handler = findHandler; ///
440
+ this.on(INPUT_EVENT_TYPE, this.inputHandler);
452
441
 
453
- this.addEventListener(eventType, handler, element);
454
- }
442
+ this.on(BLUR_EVENT_TYPE, this.blurHandler);
455
443
 
456
- offFind(findHandler, element) {
457
- const eventType = FIND_EVENT_TYPE,
458
- handler = findHandler; ///
444
+ this.on(FOCUS_EVENT_TYPE, this.focusHandler);
459
445
 
460
- this.removeEventListener(eventType, handler, element);
461
- }
446
+ this.on(SCROLL_EVENT_TYPE, this.scrollHandler);
462
447
 
463
- onBlur(blurHandler, element) {
464
- const eventType = BLUR_EVENT_TYPE,
465
- handler = blurHandler; ///
448
+ this.on(KEYDOWN_EVENT_TYPE, this.keyDownHandler);
466
449
 
467
- this.addEventListener(eventType, handler, element);
468
- }
450
+ this.on(CONTEXTMENU_EVENT_TYPE, this.contextmenuHandler);
469
451
 
470
- offBlur(blurHandler, element) {
471
- const eventType = BLUR_EVENT_TYPE,
472
- handler = blurHandler; ///
452
+ document.on(SELECTIONCHANGE_EVENT_TYPE, this.selectChangeHandler);
473
453
 
474
- this.removeEventListener(eventType, handler, element);
454
+ this.addClass("active");
475
455
  }
476
456
 
477
- onFocus(blurHandler, element) {
478
- const eventType = FOCUS_EVENT_TYPE,
479
- handler = blurHandler; ///
480
-
481
- this.addEventListener(eventType, handler, element);
482
- }
457
+ deactivate() {
458
+ this.off(CUT_EVENT_TYPE, this.cutHandler);
483
459
 
484
- offFocus(blurHandler, element) {
485
- const eventType = FOCUS_EVENT_TYPE,
486
- handler = blurHandler; ///
460
+ this.off(COPY_EVENT_TYPE, this.copyHandler);
487
461
 
488
- this.removeEventListener(eventType, handler, element);
489
- }
462
+ this.off(PASTE_EVENT_TYPE, this.pasteHandler);
490
463
 
491
- onScroll(scrollHandler, element) {
492
- const eventType = SCROLL_EVENT_TYPE,
493
- handler = scrollHandler; ///
464
+ this.off(INPUT_EVENT_TYPE, this.inputHandler);
494
465
 
495
- this.addEventListener(eventType, handler, element);
496
- }
466
+ this.off(BLUR_EVENT_TYPE, this.blurHandler);
497
467
 
498
- offScroll(scrollHandler, element) {
499
- const eventType = SCROLL_EVENT_TYPE,
500
- handler = scrollHandler; ///
468
+ this.off(FOCUS_EVENT_TYPE, this.focusHandler);
501
469
 
502
- this.removeEventListener(eventType, handler, element);
503
- }
470
+ this.off(SCROLL_EVENT_TYPE, this.scrollHandler);
504
471
 
505
- onChange(changeHandler, element) {
506
- const eventType = CHANGE_EVENT_TYPE,
507
- handler = changeHandler; ///
472
+ this.off(KEYDOWN_EVENT_TYPE, this.keyDownHandler);
508
473
 
509
- this.addEventListener(eventType, handler, element);
510
- }
474
+ this.off(CONTEXTMENU_EVENT_TYPE, this.contextmenuHandler);
511
475
 
512
- offChange(changeHandler, element) {
513
- const eventType = CHANGE_EVENT_TYPE,
514
- handler = changeHandler; ///
476
+ document.off(SELECTIONCHANGE_EVENT_TYPE, this.selectChangeHandler);
515
477
 
516
- this.removeEventListener(eventType, handler, element);
478
+ this.removeClass("active");
517
479
  }
518
480
 
519
481
  getPreviousContent() {
@@ -541,12 +503,12 @@ export default class RichTextarea extends Element {
541
503
  }
542
504
 
543
505
  didMount() {
544
- const { onFind, onBlur, onFocus, onChange, onScroll } = this.properties,
506
+ const { onFind, onBlur, onFocus, onScroll, onChange } = this.properties,
545
507
  findHandler = onFind, ///
546
508
  blurHandler = onBlur, ///
547
509
  focusHandler = onFocus, ///
548
- changeHandler = onChange, ///
549
- scrollHandler = onScroll; ///
510
+ scrollHandler = onScroll, ///
511
+ changeHandler = onChange; ///
550
512
 
551
513
  this.updateInitialState();
552
514
 
@@ -556,28 +518,18 @@ export default class RichTextarea extends Element {
556
518
 
557
519
  focusHandler && this.onFocus(focusHandler, this);
558
520
 
559
- changeHandler && this.onChange(changeHandler, this);
560
-
561
521
  scrollHandler && this.onScroll(scrollHandler, this);
562
522
 
563
- this.on(CUT_EVENT_TYPE, this.cutHandler);
564
-
565
- this.on(COPY_EVENT_TYPE, this.copyHandler);
566
-
567
- this.on(PASTE_EVENT_TYPE, this.pasteHandler);
568
-
569
- this.on(CONTEXTMENU_EVENT_TYPE, this.contextmenuHandler);
570
-
571
- document.on(SELECTIONCHANGE_EVENT_TYPE, this.selectChangeHandler);
523
+ changeHandler && this.onChange(changeHandler, this);
572
524
  }
573
525
 
574
526
  willUnmount() {
575
- const { onFind, onBlur, onFocus, onChange, onScroll } = this.properties,
527
+ const { onFind, onBlur, onFocus, onScroll, onChange } = this.properties,
576
528
  findHandler = onFind, ///
577
529
  blurHandler = onBlur, ///
578
530
  focusHandler = onFocus, ///
579
- changeHandler = onChange, ///
580
- scrollHandler = onScroll; ///
531
+ scrollHandler = onScroll, ///
532
+ changeHandler = onChange; ///
581
533
 
582
534
  findHandler && this.offFind(findHandler, this);
583
535
 
@@ -585,19 +537,9 @@ export default class RichTextarea extends Element {
585
537
 
586
538
  focusHandler && this.offFocus(focusHandler, this);
587
539
 
588
- changeHandler && this.offChange(changeHandler, this);
589
-
590
540
  scrollHandler && this.offScroll(scrollHandler, this);
591
541
 
592
- this.off(CUT_EVENT_TYPE, this.cutHandler);
593
-
594
- this.off(COPY_EVENT_TYPE, this.copyHandler);
595
-
596
- this.off(PASTE_EVENT_TYPE, this.pasteHandler);
597
-
598
- this.off(CONTEXTMENU_EVENT_TYPE, this.contextmenuHandler);
599
-
600
- document.off(SELECTIONCHANGE_EVENT_TYPE, this.selectChangeHandler);
542
+ changeHandler && this.offChange(changeHandler, this);
601
543
 
602
544
  const active = this.isActive();
603
545
 
@@ -637,8 +579,8 @@ export default class RichTextarea extends Element {
637
579
  "onFind",
638
580
  "onBlur",
639
581
  "onFocus",
640
- "onChange",
641
582
  "onScroll",
583
+ "onChange"
642
584
  ];
643
585
 
644
586
  static defaultProperties = {
@@ -655,6 +597,8 @@ export default class RichTextarea extends Element {
655
597
  }
656
598
  }
657
599
 
600
+ Object.assign(RichTextarea.prototype, eventMixins);
601
+
658
602
  function defer(func) {
659
603
  setTimeout(func, 0);
660
604
  }
package/src/selection.js CHANGED
@@ -67,6 +67,22 @@ export default class Selection {
67
67
  return selection;
68
68
  }
69
69
 
70
+ emptiedToStart() {
71
+ const startPosition = this.startPosition,
72
+ endPosition = startPosition, ///
73
+ selection = new Selection(startPosition, endPosition);
74
+
75
+ return selection;
76
+ }
77
+
78
+ emptiedToEnd() {
79
+ const endPosition = this.endPosition,
80
+ startPosition = endPosition, ///
81
+ selection = new Selection(startPosition, endPosition);
82
+
83
+ return selection;
84
+ }
85
+
70
86
  transformed(operations) {
71
87
  const selection = this, ///
72
88
  transformedSelection = transformSelection(selection, operations);
@@ -98,14 +114,6 @@ export default class Selection {
98
114
  return selection;
99
115
  }
100
116
 
101
- emptied() {
102
- const startPosition = this.startPosition,
103
- endPosition = startPosition, ///
104
- selection = new Selection(startPosition, endPosition);
105
-
106
- return selection;
107
- }
108
-
109
117
  clone() {
110
118
  const selection = new Selection(this.startPosition, this.endPosition);
111
119