easy-richtextarea 4.0.18 → 4.0.20
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/example.js +96 -96
- package/lib/example/richTextarea.js +2 -2
- package/lib/example/view.js +9 -18
- package/lib/richTextarea.js +31 -28
- package/lib/undoBuffer.js +56 -51
- package/package.json +1 -1
- package/src/example/richTextarea.js +3 -11
- package/src/example/view.js +9 -28
- package/src/richTextarea.js +27 -21
- package/src/undoBuffer.js +67 -53
package/src/example/view.js
CHANGED
|
@@ -3,26 +3,20 @@
|
|
|
3
3
|
import RichTextarea from "./richTextarea";
|
|
4
4
|
|
|
5
5
|
const content = "",
|
|
6
|
-
|
|
6
|
+
richTextarea =
|
|
7
7
|
|
|
8
8
|
<RichTextarea onChange={changeHandler} onScroll={scrollHandler} onFocus={focusHandler} onBlur={blurHandler} />
|
|
9
9
|
|
|
10
|
-
,
|
|
11
|
-
inactiveRichTextarea =
|
|
12
|
-
|
|
13
|
-
<RichTextarea />
|
|
14
|
-
|
|
15
10
|
;
|
|
16
11
|
|
|
17
|
-
|
|
12
|
+
richTextarea.setContent(content);
|
|
18
13
|
|
|
19
|
-
|
|
14
|
+
richTextarea.activate();
|
|
20
15
|
|
|
21
16
|
const View = (properties) =>
|
|
22
17
|
|
|
23
18
|
<div className="view">
|
|
24
|
-
{
|
|
25
|
-
{inactiveRichTextarea}
|
|
19
|
+
{richTextarea}
|
|
26
20
|
</div>
|
|
27
21
|
|
|
28
22
|
;
|
|
@@ -30,30 +24,17 @@ const View = (properties) =>
|
|
|
30
24
|
export default View;
|
|
31
25
|
|
|
32
26
|
function changeHandler(event, element) {
|
|
33
|
-
const contentChanged =
|
|
34
|
-
selectionChanged =
|
|
27
|
+
const contentChanged = richTextarea.hasContentChanged(),
|
|
28
|
+
selectionChanged = richTextarea.hasSelectionChanged();
|
|
35
29
|
|
|
36
30
|
console.log(contentChanged, selectionChanged)
|
|
37
|
-
|
|
38
|
-
if (contentChanged) {
|
|
39
|
-
const content = activeRichTextarea.getContent();
|
|
40
|
-
|
|
41
|
-
inactiveRichTextarea.setContent(content);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (selectionChanged) {
|
|
45
|
-
const selection = activeRichTextarea.getSelection();
|
|
46
|
-
|
|
47
|
-
inactiveRichTextarea.setSelection(selection);
|
|
48
|
-
}
|
|
49
31
|
}
|
|
50
32
|
|
|
51
33
|
function scrollHandler(event, element) {
|
|
52
|
-
const scrollTop =
|
|
53
|
-
scrollLeft =
|
|
34
|
+
const scrollTop = richTextarea.getScrollTop(),
|
|
35
|
+
scrollLeft = richTextarea.getScrollLeft();
|
|
54
36
|
|
|
55
|
-
|
|
56
|
-
inactiveRichTextarea.setScrollLeft(scrollLeft);
|
|
37
|
+
console.log(scrollTop, scrollLeft)
|
|
57
38
|
}
|
|
58
39
|
|
|
59
40
|
function focusHandler(event, element) {
|
package/src/richTextarea.js
CHANGED
|
@@ -103,6 +103,8 @@ export default class RichTextarea extends Element {
|
|
|
103
103
|
|
|
104
104
|
selectChangeHandler = (event, element) => {
|
|
105
105
|
if (this.focused) {
|
|
106
|
+
element = this; ///
|
|
107
|
+
|
|
106
108
|
this.intermediateHandler(event, element);
|
|
107
109
|
}
|
|
108
110
|
}
|
|
@@ -312,17 +314,21 @@ export default class RichTextarea extends Element {
|
|
|
312
314
|
}
|
|
313
315
|
|
|
314
316
|
undo(event, element) {
|
|
315
|
-
const
|
|
317
|
+
const undoOperation = this.undoBuffer.undo();
|
|
318
|
+
|
|
319
|
+
if (undoOperation !== null) {
|
|
320
|
+
const operation = undoOperation; ///
|
|
316
321
|
|
|
317
|
-
if (operation !== null) {
|
|
318
322
|
this.revert(event, element, operation);
|
|
319
323
|
}
|
|
320
324
|
}
|
|
321
325
|
|
|
322
326
|
redo(event, element) {
|
|
323
|
-
const
|
|
327
|
+
const redoOperation = this.undoBuffer.redo();
|
|
328
|
+
|
|
329
|
+
if (redoOperation !== null) {
|
|
330
|
+
const operation = redoOperation; ///
|
|
324
331
|
|
|
325
|
-
if (operation !== null) {
|
|
326
332
|
this.revert(event, element, operation);
|
|
327
333
|
}
|
|
328
334
|
}
|
|
@@ -367,6 +373,23 @@ export default class RichTextarea extends Element {
|
|
|
367
373
|
this.intermediateHandler(event, element, undoable, eventType);
|
|
368
374
|
}
|
|
369
375
|
|
|
376
|
+
callHandlers(eventType, ...remainingArguments) {
|
|
377
|
+
const eventListeners = this.findEventListeners(eventType);
|
|
378
|
+
|
|
379
|
+
eventListeners.forEach((eventListener) => {
|
|
380
|
+
let { element } = eventListener;
|
|
381
|
+
|
|
382
|
+
const { handler } = eventListener,
|
|
383
|
+
handlerElement = element; ///
|
|
384
|
+
|
|
385
|
+
element = this; ///
|
|
386
|
+
|
|
387
|
+
if ((handler !== this.blurHandler) && (handler !== this.focusHandler) && (handler !== this.scrollHandler)) {
|
|
388
|
+
handler.call(handlerElement, ...remainingArguments, element);
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
|
|
370
393
|
applyOperation(operation) {
|
|
371
394
|
let content = this.getContent(),
|
|
372
395
|
selection = this.getSelection();
|
|
@@ -470,23 +493,6 @@ export default class RichTextarea extends Element {
|
|
|
470
493
|
this.removeEventListener(eventType, handler, element);
|
|
471
494
|
}
|
|
472
495
|
|
|
473
|
-
callHandlers(eventType, ...remainingArguments) {
|
|
474
|
-
const eventListeners = this.findEventListeners(eventType);
|
|
475
|
-
|
|
476
|
-
eventListeners.forEach((eventListener) => {
|
|
477
|
-
let { element } = eventListener;
|
|
478
|
-
|
|
479
|
-
const { handler } = eventListener,
|
|
480
|
-
handlerElement = element; ///
|
|
481
|
-
|
|
482
|
-
element = this; ///
|
|
483
|
-
|
|
484
|
-
if ((handler !== this.blurHandler) && (handler !== this.focusHandler) && (handler !== this.scrollHandler)) {
|
|
485
|
-
handler.call(handlerElement, ...remainingArguments, element);
|
|
486
|
-
}
|
|
487
|
-
});
|
|
488
|
-
}
|
|
489
|
-
|
|
490
496
|
didMount() {
|
|
491
497
|
const { onChange, onScroll, onFocus, onBlur } = this.properties,
|
|
492
498
|
changeHandler = onChange, ///
|
package/src/undoBuffer.js
CHANGED
|
@@ -7,99 +7,113 @@ import InsertOperation from "./operation/insert";
|
|
|
7
7
|
import DeleteOperation from "./operation/delete";
|
|
8
8
|
import transformOperations from "./transform/operations";
|
|
9
9
|
|
|
10
|
-
const {
|
|
10
|
+
const { clear, filter, unshift } = arrayUtilities;
|
|
11
11
|
|
|
12
12
|
export default class UndoBuffer {
|
|
13
|
-
constructor(
|
|
14
|
-
this.
|
|
15
|
-
this.
|
|
13
|
+
constructor(undoOperations, redoOperations) {
|
|
14
|
+
this.undoOperations = undoOperations;
|
|
15
|
+
this.redoOperations = redoOperations;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
return this.
|
|
18
|
+
getUndoOperations() {
|
|
19
|
+
return this.undoOperations;
|
|
20
20
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return this.
|
|
21
|
+
|
|
22
|
+
getRedoOperations() {
|
|
23
|
+
return this.redoOperations;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
undo() {
|
|
27
|
-
let
|
|
27
|
+
let undoOperation = null;
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
this.position--;
|
|
29
|
+
const undoOperationsLength = this.undoOperations.length;
|
|
31
30
|
|
|
32
|
-
|
|
31
|
+
if (undoOperationsLength > 0) {
|
|
32
|
+
undoOperation = this.undoOperations.shift();
|
|
33
33
|
|
|
34
|
-
const
|
|
34
|
+
const invertedUndoOperation = undoOperation.invert(InsertOperation, DeleteOperation),
|
|
35
|
+
redoOperation = invertedUndoOperation; ///
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
this.redoOperations.unshift(redoOperation);
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
return
|
|
40
|
+
return undoOperation;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
redo() {
|
|
43
|
-
let
|
|
44
|
+
let redoOperation = null;
|
|
45
|
+
|
|
46
|
+
const redoOperationsLength = this.redoOperations.length;
|
|
44
47
|
|
|
45
|
-
|
|
48
|
+
if (redoOperationsLength > 0) {
|
|
49
|
+
redoOperation = this.redoOperations.shift();
|
|
46
50
|
|
|
47
|
-
|
|
48
|
-
|
|
51
|
+
const invertedRedoOperation = redoOperation.invert(InsertOperation, DeleteOperation),
|
|
52
|
+
undoOperation = invertedRedoOperation; ///
|
|
49
53
|
|
|
50
|
-
this.
|
|
54
|
+
this.undoOperations.unshift(undoOperation);
|
|
51
55
|
}
|
|
52
56
|
|
|
53
|
-
return
|
|
57
|
+
return redoOperation;
|
|
54
58
|
}
|
|
55
59
|
|
|
56
60
|
transform(operations) {
|
|
57
|
-
this.
|
|
61
|
+
this.undoOperations = transformOperations(this.undoOperations, operations);
|
|
58
62
|
|
|
59
|
-
this.
|
|
63
|
+
this.redoOperations = transformOperations(this.redoOperations, operations);
|
|
64
|
+
|
|
65
|
+
filterEmptyOperations(this.undoOperations);
|
|
66
|
+
|
|
67
|
+
filterEmptyOperations(this.redoOperations);
|
|
60
68
|
}
|
|
61
69
|
|
|
62
70
|
addOperations(operations) {
|
|
63
|
-
const
|
|
71
|
+
const invertedOperations = invertOperations(operations),
|
|
72
|
+
reversedInvertedOperations = reverseOperations(invertedOperations),
|
|
73
|
+
undoOperations = reversedInvertedOperations; ///
|
|
64
74
|
|
|
65
|
-
this.
|
|
75
|
+
unshift(this.undoOperations, undoOperations);
|
|
66
76
|
|
|
67
|
-
|
|
77
|
+
clear(this.redoOperations);
|
|
78
|
+
}
|
|
68
79
|
|
|
69
|
-
|
|
80
|
+
static fromNothing() {
|
|
81
|
+
const undoOperations = [],
|
|
82
|
+
redoOperations = [],
|
|
83
|
+
undoBuffer = new UndoBuffer(undoOperations, redoOperations);
|
|
70
84
|
|
|
71
|
-
|
|
85
|
+
return undoBuffer;
|
|
72
86
|
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function invertOperations(operations) {
|
|
90
|
+
const invertedOperations = operations.map((operation) => {
|
|
91
|
+
const invertedOperation = operation.invert(InsertOperation, DeleteOperation);
|
|
73
92
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
position = 0;
|
|
93
|
+
return invertedOperation;
|
|
94
|
+
});
|
|
77
95
|
|
|
78
|
-
|
|
79
|
-
|
|
96
|
+
return invertedOperations;
|
|
97
|
+
}
|
|
80
98
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
99
|
+
function reverseOperations(operations) {
|
|
100
|
+
const reversedOperations = operations.reduce((reversedOperations, operation) => {
|
|
101
|
+
const reversedOperation = operation; ///
|
|
84
102
|
|
|
85
|
-
|
|
103
|
+
reversedOperations.unshift(reversedOperation);
|
|
86
104
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
} else {
|
|
91
|
-
position++;
|
|
92
|
-
}
|
|
105
|
+
return reversedOperations;
|
|
106
|
+
}, []);
|
|
93
107
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
108
|
+
return reversedOperations;
|
|
109
|
+
}
|
|
97
110
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
undoBuffer = new UndoBuffer(position, operations);
|
|
111
|
+
function filterEmptyOperations(operations) {
|
|
112
|
+
filter(operations, (operation) => {
|
|
113
|
+
const operationEmptyOperation = (operation instanceof EmptyOperation);
|
|
102
114
|
|
|
103
|
-
|
|
104
|
-
|
|
115
|
+
if (!operationEmptyOperation) {
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
});
|
|
105
119
|
}
|