easy-richtextarea 4.0.3 → 4.0.4
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/README.md +0 -8
- package/example.js +1399 -982
- package/lib/constants.js +13 -4
- package/lib/contentCompare.js +34 -0
- package/lib/example/richTextarea.js +2 -2
- package/lib/example/view.js +18 -9
- package/lib/keyCodes.js +13 -0
- package/lib/operation/delete.js +101 -52
- package/lib/operation/empty.js +21 -6
- package/lib/operation/insert.js +78 -31
- package/lib/operations/fromJSON.js +4 -4
- package/lib/operations/generate.js +3 -3
- package/lib/operations/transform.js +3 -7
- package/lib/richTextarea.js +244 -156
- package/lib/selection.js +55 -13
- package/lib/types.js +13 -13
- package/lib/undoBuffer.js +105 -0
- package/package.json +3 -2
- package/src/constants.js +1 -0
- package/src/contentCompare.js +34 -0
- package/src/example/richTextarea.js +11 -9
- package/src/example/view.js +28 -10
- package/src/keyCodes.js +3 -0
- package/src/operation/delete.js +135 -58
- package/src/operation/empty.js +19 -14
- package/src/operation/insert.js +97 -39
- package/src/operations/fromJSON.js +4 -4
- package/src/operations/generate.js +8 -4
- package/src/operations/transform.js +3 -3
- package/src/richTextarea.js +316 -185
- package/src/selection.js +53 -9
- package/src/types.js +6 -6
- package/src/undoBuffer.js +73 -0
- package/test/content/transform.js +9 -11
- package/test/helpers.js +27 -21
- package/test/operation/delete.js +187 -147
- package/test/operation/empty.js +3 -5
- package/test/operation/insert.js +134 -118
- package/test/operations/generate.js +19 -22
- package/test/operations/transform.js +37 -98
- package/lib/stringCompare.js +0 -33
- package/src/stringCompare.js +0 -33
package/src/selection.js
CHANGED
|
@@ -14,12 +14,10 @@ export default class Selection {
|
|
|
14
14
|
return this.endPosition;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
this.startPosition
|
|
19
|
-
}
|
|
17
|
+
isEmpty() {
|
|
18
|
+
const empty = (this.startPosition === this.endPosition);
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
this.endPosition = endPosition;
|
|
20
|
+
return empty;
|
|
23
21
|
}
|
|
24
22
|
|
|
25
23
|
isEqualTo(selection) {
|
|
@@ -37,11 +35,50 @@ export default class Selection {
|
|
|
37
35
|
return equalTo;
|
|
38
36
|
}
|
|
39
37
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
setStartPosition(startPosition) {
|
|
39
|
+
this.startPosition = startPosition;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
setEndPosition(endPosition) {
|
|
43
|
+
this.endPosition = endPosition;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
startPositionShifted(startOffset) {
|
|
47
|
+
const startPosition = this.startPosition + startOffset,
|
|
48
|
+
endPosition = this.endPosition,
|
|
49
|
+
selection = new Selection(startPosition, endPosition);
|
|
50
|
+
|
|
51
|
+
return selection;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
endPositionShifted(endOffset) {
|
|
55
|
+
const startPosition = this.startPosition,
|
|
56
|
+
endPosition = this.endPosition + endOffset,
|
|
57
|
+
selection = new Selection(startPosition, endPosition);
|
|
43
58
|
|
|
44
|
-
return
|
|
59
|
+
return selection;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
shifted(offset) {
|
|
63
|
+
const startPosition = this.startPosition + offset,
|
|
64
|
+
endPosition = this.endPosition + offset,
|
|
65
|
+
selection = new Selection(startPosition, endPosition);
|
|
66
|
+
|
|
67
|
+
return selection;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
emptied() {
|
|
71
|
+
const startPosition = this.startPosition,
|
|
72
|
+
endPosition = startPosition, ///
|
|
73
|
+
selection = new Selection(startPosition, endPosition);
|
|
74
|
+
|
|
75
|
+
return selection;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
clone() {
|
|
79
|
+
const selection = new Selection(this.startPosition, this.endPosition);
|
|
80
|
+
|
|
81
|
+
return selection;
|
|
45
82
|
}
|
|
46
83
|
|
|
47
84
|
static fromNothing() {
|
|
@@ -62,6 +99,13 @@ export default class Selection {
|
|
|
62
99
|
|
|
63
100
|
}
|
|
64
101
|
|
|
102
|
+
static fromStartPosition(startPosition) {
|
|
103
|
+
const endPosition = startPosition, ///
|
|
104
|
+
selection = new Selection(startPosition, endPosition);
|
|
105
|
+
|
|
106
|
+
return selection;
|
|
107
|
+
}
|
|
108
|
+
|
|
65
109
|
static fromStartPositionAndEndPosition(startPosition, endPosition) {
|
|
66
110
|
const selection = new Selection(startPosition, endPosition);
|
|
67
111
|
|
package/src/types.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
export const
|
|
4
|
-
export const
|
|
5
|
-
export const
|
|
3
|
+
export const EMPTY_TYPE = "empty";
|
|
4
|
+
export const DELETE_TYPE = "delete";
|
|
5
|
+
export const INSERT_TYPE = "insert";
|
|
6
6
|
|
|
7
7
|
export default {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
EMPTY_TYPE,
|
|
9
|
+
DELETE_TYPE,
|
|
10
|
+
INSERT_TYPE
|
|
11
11
|
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { arrayUtilities } from "necessary";
|
|
4
|
+
|
|
5
|
+
import InsertOperation from "./operation/insert";
|
|
6
|
+
import DeleteOperation from "./operation/delete";
|
|
7
|
+
|
|
8
|
+
const { push } = arrayUtilities;
|
|
9
|
+
|
|
10
|
+
export default class UndoBuffer {
|
|
11
|
+
constructor(position, operations) {
|
|
12
|
+
this.position = position;
|
|
13
|
+
this.operations = operations;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
getPosition() {
|
|
17
|
+
return this.position;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
getOperations() {
|
|
21
|
+
return this.operations;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
undo() {
|
|
25
|
+
let operation = null;
|
|
26
|
+
|
|
27
|
+
if (this.position > 0) {
|
|
28
|
+
this.position--;
|
|
29
|
+
|
|
30
|
+
operation = this.operations[this.position];
|
|
31
|
+
|
|
32
|
+
const invertedOperation = operation.invert(InsertOperation, DeleteOperation);
|
|
33
|
+
|
|
34
|
+
operation = invertedOperation; ///
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return operation;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
redo() {
|
|
41
|
+
let operation = null;
|
|
42
|
+
|
|
43
|
+
const operationsLength = this.operations.length;
|
|
44
|
+
|
|
45
|
+
if (this.position < operationsLength) {
|
|
46
|
+
operation = this.operations[this.position];
|
|
47
|
+
|
|
48
|
+
this.position++;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return operation;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
addOperations(operations) {
|
|
55
|
+
const start = this.position; ///
|
|
56
|
+
|
|
57
|
+
this.operations.splice(start);
|
|
58
|
+
|
|
59
|
+
push(this.operations, operations);
|
|
60
|
+
|
|
61
|
+
const operationsLength = this.operations.length;
|
|
62
|
+
|
|
63
|
+
this.position = operationsLength; ///
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static fromNothing() {
|
|
67
|
+
const position = 0,
|
|
68
|
+
operations = [],
|
|
69
|
+
undoBuffer = new UndoBuffer(position, operations);
|
|
70
|
+
|
|
71
|
+
return undoBuffer;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -3,12 +3,10 @@
|
|
|
3
3
|
const { assert } = require("chai"),
|
|
4
4
|
{ DeleteOperation, InsertOperation, transformContent, generateOperations } = require("../../lib/main"); ///
|
|
5
5
|
|
|
6
|
-
const helpers = require("../helpers");
|
|
7
|
-
|
|
8
6
|
describe("transformContent", () => {
|
|
9
7
|
describe("the array of operations is of zero length", () => {
|
|
10
8
|
it("leaves the content unchanged", () => {
|
|
11
|
-
const content =
|
|
9
|
+
const content = "jik8h",
|
|
12
10
|
operations = [],
|
|
13
11
|
transformedContent = transformContent(content, operations),
|
|
14
12
|
expectedContent = content; ///
|
|
@@ -19,13 +17,13 @@ describe("transformContent", () => {
|
|
|
19
17
|
|
|
20
18
|
describe("the array of operations is contains a single delete operation", () => {
|
|
21
19
|
it("deletes the requisite characters", () => {
|
|
22
|
-
const content =
|
|
23
|
-
deleteOperation = DeleteOperation.
|
|
20
|
+
const content = "jhUngfrcD",
|
|
21
|
+
deleteOperation = DeleteOperation.fromContentAndPosition("ngfr", 3),
|
|
24
22
|
operations = [
|
|
25
23
|
deleteOperation
|
|
26
24
|
],
|
|
27
25
|
transformedContent = transformContent(content, operations),
|
|
28
|
-
expectedContent =
|
|
26
|
+
expectedContent = "jhUcD";
|
|
29
27
|
|
|
30
28
|
assert.equal(transformedContent, expectedContent);
|
|
31
29
|
});
|
|
@@ -33,13 +31,13 @@ describe("transformContent", () => {
|
|
|
33
31
|
|
|
34
32
|
describe("the array of operations is contains a single insert operation", () => {
|
|
35
33
|
it("inserts the requisite characters", () => {
|
|
36
|
-
const content =
|
|
37
|
-
insertOperation = InsertOperation.
|
|
34
|
+
const content = "jubfEDf",
|
|
35
|
+
insertOperation = InsertOperation.fromContentAndPosition("avTgd", 2),
|
|
38
36
|
operations = [
|
|
39
37
|
insertOperation
|
|
40
38
|
],
|
|
41
39
|
transformedContent = transformContent(content, operations),
|
|
42
|
-
expectedContent =
|
|
40
|
+
expectedContent = "juavTgdbfEDf";
|
|
43
41
|
|
|
44
42
|
assert.equal(transformedContent, expectedContent);
|
|
45
43
|
});
|
|
@@ -47,8 +45,8 @@ describe("transformContent", () => {
|
|
|
47
45
|
|
|
48
46
|
describe("the array of operations is generated", () => {
|
|
49
47
|
it("returns the result of applying those operations", () => {
|
|
50
|
-
const contentA =
|
|
51
|
-
contentB =
|
|
48
|
+
const contentA = "8hUjy",
|
|
49
|
+
contentB = "ABV8hUjykmj",
|
|
52
50
|
operations = generateOperations(contentA, contentB),
|
|
53
51
|
transformedContentA = transformContent(contentA, operations),
|
|
54
52
|
expectedContent = contentB; ///
|
package/test/helpers.js
CHANGED
|
@@ -11,8 +11,7 @@ const DEFAULT_CONTENT_LENGTH = 4,
|
|
|
11
11
|
const random = randomSeed.create(".");
|
|
12
12
|
|
|
13
13
|
function content(length = DEFAULT_CONTENT_LENGTH) {
|
|
14
|
-
const
|
|
15
|
-
content = string; ///
|
|
14
|
+
const content = generateContent(length);
|
|
16
15
|
|
|
17
16
|
return content;
|
|
18
17
|
}
|
|
@@ -36,50 +35,57 @@ module.exports = {
|
|
|
36
35
|
operations
|
|
37
36
|
};
|
|
38
37
|
|
|
39
|
-
function
|
|
40
|
-
let
|
|
38
|
+
function generateContent(length) {
|
|
39
|
+
let content = "";
|
|
41
40
|
|
|
42
41
|
const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
43
42
|
|
|
44
43
|
for (let index = 0; index < length; index++) {
|
|
45
|
-
|
|
44
|
+
content += characters.charAt(random(characters.length));
|
|
46
45
|
}
|
|
47
46
|
|
|
48
|
-
return
|
|
47
|
+
return content;
|
|
49
48
|
}
|
|
50
49
|
|
|
51
|
-
function generateOperation(
|
|
52
|
-
if (
|
|
50
|
+
function generateOperation(content) {
|
|
51
|
+
if (content === "") {
|
|
53
52
|
return [
|
|
54
53
|
generateEmptyOperation,
|
|
55
54
|
generateInsertOperation
|
|
56
|
-
][random(2)](
|
|
55
|
+
][random(2)](content);
|
|
57
56
|
} else {
|
|
58
57
|
return [
|
|
59
58
|
generateEmptyOperation,
|
|
60
59
|
generateInsertOperation,
|
|
61
60
|
generateDeleteOperation
|
|
62
|
-
][random(3)](
|
|
61
|
+
][random(3)](content);
|
|
63
62
|
}
|
|
64
63
|
}
|
|
65
64
|
|
|
66
|
-
function generateEmptyOperation(
|
|
65
|
+
function generateEmptyOperation(content) {
|
|
67
66
|
return EmptyOperation.fromNothing();
|
|
68
67
|
}
|
|
69
68
|
|
|
70
|
-
function generateInsertOperation(
|
|
71
|
-
const
|
|
72
|
-
position = random(
|
|
69
|
+
function generateInsertOperation(content) {
|
|
70
|
+
const contentLength = content.length,
|
|
71
|
+
position = random(contentLength + 1);
|
|
73
72
|
|
|
74
|
-
|
|
73
|
+
content = generateContent(MAXIMUM_INSERT_OPERATION_LENGTH); ///
|
|
75
74
|
|
|
76
|
-
return InsertOperation.
|
|
75
|
+
return InsertOperation.fromContentAndPosition(content, position);
|
|
77
76
|
}
|
|
78
77
|
|
|
79
|
-
function generateDeleteOperation(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
78
|
+
function generateDeleteOperation(content) {
|
|
79
|
+
let contentLength = content.length;
|
|
80
|
+
|
|
81
|
+
const position = random(contentLength);
|
|
82
|
+
|
|
83
|
+
contentLength = random(contentLength - position) + 1;
|
|
84
|
+
|
|
85
|
+
const start = position,
|
|
86
|
+
end = start + contentLength;
|
|
87
|
+
|
|
88
|
+
content = content.substring(start, end);
|
|
83
89
|
|
|
84
|
-
return DeleteOperation.
|
|
90
|
+
return DeleteOperation.fromContentAndPosition(content, position);
|
|
85
91
|
}
|