/
ImageToolsState.ts
134 lines (113 loc) · 3.02 KB
/
ImageToolsState.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*/
import { Cell, Option } from '@ephox/katamari';
import Tools from 'tinymce/core/api/util/Tools';
import UndoStack from '../UndoStack';
import { Blob, URL } from '@ephox/dom-globals';
interface BlobState {
blob: Blob;
url: string;
}
interface UndoRedoState {
undoEnabled: boolean;
redoEnabled: boolean;
}
const makeState = (initialState: BlobState) => {
const blobState = Cell(initialState);
const tempState = Cell(Option.none<BlobState>());
const undoStack = UndoStack();
undoStack.add(initialState);
const getBlobState = (): BlobState => {
return blobState.get();
};
const setBlobState = (state: BlobState): void => {
blobState.set(state);
};
const getTempState = (): BlobState => {
return tempState.get().fold(() => {
return blobState.get();
}, (temp) => {
return temp;
});
};
const updateTempState = (blob: Blob): string => {
const newTempState = createState(blob);
destroyTempState();
tempState.set(Option.some(newTempState));
return newTempState.url;
};
const createState = (blob: Blob): BlobState => {
return {
blob,
url: URL.createObjectURL(blob)
};
};
const destroyState = (state: BlobState): void => {
URL.revokeObjectURL(state.url);
};
const destroyStates = (states: BlobState[]): void => {
Tools.each(states, destroyState);
};
const destroyTempState = (): void => {
tempState.get().each(destroyState);
tempState.set(Option.none());
};
const addBlobState = (blob: Blob): string => {
const newState = createState(blob);
setBlobState(newState);
const removed = undoStack.add(newState).removed;
destroyStates(removed);
return newState.url;
};
const addTempState = (blob: Blob): string => {
const newState = createState(blob);
tempState.set(Option.some(newState));
return newState.url;
};
const applyTempState = (postApply: () => void): void => {
return tempState.get().fold(() => {
// TODO: Inform the user of failures somehow
}, (temp) => {
addBlobState(temp.blob);
postApply();
});
};
const undo = (): string => {
const currentState = undoStack.undo();
setBlobState(currentState);
return currentState.url;
};
const redo = (): string => {
const currentState = undoStack.redo();
setBlobState(currentState);
return currentState.url;
};
const getHistoryStates = (): UndoRedoState => {
const undoEnabled = undoStack.canUndo();
const redoEnabled = undoStack.canRedo();
return {
undoEnabled,
redoEnabled
};
};
return {
getBlobState,
setBlobState,
addBlobState,
getTempState,
updateTempState,
addTempState,
applyTempState,
destroyTempState,
undo,
redo,
getHistoryStates
};
};
export {
makeState
};