@uiw/react-codemirror 4.23.13 → 4.24.0
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 +1 -0
- package/cjs/timeoutLatch.d.ts +22 -0
- package/cjs/timeoutLatch.js +118 -0
- package/cjs/useCodeMirror.d.ts +1 -0
- package/cjs/useCodeMirror.js +51 -10
- package/dist/codemirror.js +255 -210
- package/dist/codemirror.min.js +1 -1
- package/esm/timeoutLatch.d.ts +22 -0
- package/esm/timeoutLatch.js +88 -0
- package/esm/useCodeMirror.d.ts +1 -0
- package/esm/useCodeMirror.js +46 -10
- package/package.json +2 -2
- package/src/timeoutLatch.ts +98 -0
- package/src/useCodeMirror.ts +40 -6
package/README.md
CHANGED
|
@@ -388,6 +388,7 @@ import { EditorView, ViewUpdate } from '@codemirror/view';
|
|
|
388
388
|
export * from '@codemirror/view';
|
|
389
389
|
export * from '@codemirror/basic-setup';
|
|
390
390
|
export * from '@codemirror/state';
|
|
391
|
+
export declare const ExternalChange: import('@codemirror/state').AnnotationType<boolean>;
|
|
391
392
|
export interface UseCodeMirror extends ReactCodeMirrorProps {
|
|
392
393
|
container?: HTMLDivElement | null;
|
|
393
394
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare class TimeoutLatch {
|
|
2
|
+
private timeLeftMS;
|
|
3
|
+
private timeoutMS;
|
|
4
|
+
private isCancelled;
|
|
5
|
+
private isTimeExhausted;
|
|
6
|
+
private callbacks;
|
|
7
|
+
constructor(callback: Function, timeoutMS: number);
|
|
8
|
+
tick(): void;
|
|
9
|
+
cancel(): void;
|
|
10
|
+
reset(): void;
|
|
11
|
+
get isDone(): boolean;
|
|
12
|
+
}
|
|
13
|
+
declare class Scheduler {
|
|
14
|
+
private interval;
|
|
15
|
+
private latches;
|
|
16
|
+
add(latch: TimeoutLatch): void;
|
|
17
|
+
remove(latch: TimeoutLatch): void;
|
|
18
|
+
private start;
|
|
19
|
+
private stop;
|
|
20
|
+
}
|
|
21
|
+
export declare const getScheduler: () => Scheduler;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.getScheduler = exports.TimeoutLatch = void 0;
|
|
8
|
+
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
9
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
10
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
11
|
+
// Setting / Unsetting timeouts for every keystroke was a significant overhead
|
|
12
|
+
// Inspired from https://github.com/iostreamer-X/timeout-latch
|
|
13
|
+
var TimeoutLatch = exports.TimeoutLatch = /*#__PURE__*/function () {
|
|
14
|
+
function TimeoutLatch(callback, timeoutMS) {
|
|
15
|
+
(0, _classCallCheck2["default"])(this, TimeoutLatch);
|
|
16
|
+
(0, _defineProperty2["default"])(this, "timeLeftMS", void 0);
|
|
17
|
+
(0, _defineProperty2["default"])(this, "timeoutMS", void 0);
|
|
18
|
+
(0, _defineProperty2["default"])(this, "isCancelled", false);
|
|
19
|
+
(0, _defineProperty2["default"])(this, "isTimeExhausted", false);
|
|
20
|
+
(0, _defineProperty2["default"])(this, "callbacks", []);
|
|
21
|
+
this.timeLeftMS = timeoutMS;
|
|
22
|
+
this.timeoutMS = timeoutMS;
|
|
23
|
+
this.callbacks.push(callback);
|
|
24
|
+
}
|
|
25
|
+
return (0, _createClass2["default"])(TimeoutLatch, [{
|
|
26
|
+
key: "tick",
|
|
27
|
+
value: function tick() {
|
|
28
|
+
if (!this.isCancelled && !this.isTimeExhausted) {
|
|
29
|
+
this.timeLeftMS--;
|
|
30
|
+
if (this.timeLeftMS <= 0) {
|
|
31
|
+
this.isTimeExhausted = true;
|
|
32
|
+
var callbacks = this.callbacks.slice();
|
|
33
|
+
this.callbacks.length = 0;
|
|
34
|
+
callbacks.forEach(function (callback) {
|
|
35
|
+
try {
|
|
36
|
+
callback();
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.error('TimeoutLatch callback error:', error);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}, {
|
|
45
|
+
key: "cancel",
|
|
46
|
+
value: function cancel() {
|
|
47
|
+
this.isCancelled = true;
|
|
48
|
+
this.callbacks.length = 0;
|
|
49
|
+
}
|
|
50
|
+
}, {
|
|
51
|
+
key: "reset",
|
|
52
|
+
value: function reset() {
|
|
53
|
+
this.timeLeftMS = this.timeoutMS;
|
|
54
|
+
this.isCancelled = false;
|
|
55
|
+
this.isTimeExhausted = false;
|
|
56
|
+
}
|
|
57
|
+
}, {
|
|
58
|
+
key: "isDone",
|
|
59
|
+
get: function get() {
|
|
60
|
+
return this.isCancelled || this.isTimeExhausted;
|
|
61
|
+
}
|
|
62
|
+
}]);
|
|
63
|
+
}();
|
|
64
|
+
var Scheduler = /*#__PURE__*/function () {
|
|
65
|
+
function Scheduler() {
|
|
66
|
+
(0, _classCallCheck2["default"])(this, Scheduler);
|
|
67
|
+
(0, _defineProperty2["default"])(this, "interval", null);
|
|
68
|
+
(0, _defineProperty2["default"])(this, "latches", new Set());
|
|
69
|
+
}
|
|
70
|
+
return (0, _createClass2["default"])(Scheduler, [{
|
|
71
|
+
key: "add",
|
|
72
|
+
value: function add(latch) {
|
|
73
|
+
this.latches.add(latch);
|
|
74
|
+
this.start();
|
|
75
|
+
}
|
|
76
|
+
}, {
|
|
77
|
+
key: "remove",
|
|
78
|
+
value: function remove(latch) {
|
|
79
|
+
this.latches["delete"](latch);
|
|
80
|
+
if (this.latches.size === 0) {
|
|
81
|
+
this.stop();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}, {
|
|
85
|
+
key: "start",
|
|
86
|
+
value: function start() {
|
|
87
|
+
var _this = this;
|
|
88
|
+
if (this.interval === null) {
|
|
89
|
+
this.interval = setInterval(function () {
|
|
90
|
+
_this.latches.forEach(function (latch) {
|
|
91
|
+
latch.tick();
|
|
92
|
+
if (latch.isDone) {
|
|
93
|
+
_this.remove(latch);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}, 1);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}, {
|
|
100
|
+
key: "stop",
|
|
101
|
+
value: function stop() {
|
|
102
|
+
if (this.interval !== null) {
|
|
103
|
+
clearInterval(this.interval);
|
|
104
|
+
this.interval = null;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}]);
|
|
108
|
+
}();
|
|
109
|
+
var globalScheduler = null;
|
|
110
|
+
var getScheduler = exports.getScheduler = function getScheduler() {
|
|
111
|
+
if (typeof window === 'undefined') {
|
|
112
|
+
return new Scheduler();
|
|
113
|
+
}
|
|
114
|
+
if (!globalScheduler) {
|
|
115
|
+
globalScheduler = new Scheduler();
|
|
116
|
+
}
|
|
117
|
+
return globalScheduler;
|
|
118
|
+
};
|
package/cjs/useCodeMirror.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EditorState } from '@codemirror/state';
|
|
2
2
|
import { EditorView } from '@codemirror/view';
|
|
3
3
|
import { type ReactCodeMirrorProps } from '.';
|
|
4
|
+
export declare const ExternalChange: import("@codemirror/state").AnnotationType<boolean>;
|
|
4
5
|
export interface UseCodeMirror extends ReactCodeMirrorProps {
|
|
5
6
|
container?: HTMLDivElement | null;
|
|
6
7
|
}
|
package/cjs/useCodeMirror.js
CHANGED
|
@@ -4,6 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
+
exports.ExternalChange = void 0;
|
|
7
8
|
exports.useCodeMirror = useCodeMirror;
|
|
8
9
|
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
9
10
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
@@ -12,7 +13,10 @@ var _state = require("@codemirror/state");
|
|
|
12
13
|
var _view = require("@codemirror/view");
|
|
13
14
|
var _getDefaultExtensions = require("./getDefaultExtensions");
|
|
14
15
|
var _utils = require("./utils");
|
|
15
|
-
var
|
|
16
|
+
var _timeoutLatch = require("./timeoutLatch");
|
|
17
|
+
var ExternalChange = exports.ExternalChange = _state.Annotation.define();
|
|
18
|
+
var TYPING_TIMOUT = 200; // ms
|
|
19
|
+
|
|
16
20
|
var emptyExtensions = [];
|
|
17
21
|
function useCodeMirror(props) {
|
|
18
22
|
var value = props.value,
|
|
@@ -62,6 +66,16 @@ function useCodeMirror(props) {
|
|
|
62
66
|
_useState6 = (0, _slicedToArray2["default"])(_useState5, 2),
|
|
63
67
|
state = _useState6[0],
|
|
64
68
|
setState = _useState6[1];
|
|
69
|
+
var typingLatch = (0, _react.useState)(function () {
|
|
70
|
+
return {
|
|
71
|
+
current: null
|
|
72
|
+
};
|
|
73
|
+
})[0];
|
|
74
|
+
var pendingUpdate = (0, _react.useState)(function () {
|
|
75
|
+
return {
|
|
76
|
+
current: null
|
|
77
|
+
};
|
|
78
|
+
})[0];
|
|
65
79
|
var defaultThemeOption = _view.EditorView.theme({
|
|
66
80
|
'&': {
|
|
67
81
|
height: height,
|
|
@@ -80,8 +94,21 @@ function useCodeMirror(props) {
|
|
|
80
94
|
// Fix echoing of the remote changes:
|
|
81
95
|
// If transaction is market as remote we don't have to call `onChange` handler again
|
|
82
96
|
!vu.transactions.some(function (tr) {
|
|
83
|
-
return tr.annotation(
|
|
97
|
+
return tr.annotation(ExternalChange);
|
|
84
98
|
})) {
|
|
99
|
+
if (typingLatch.current) {
|
|
100
|
+
typingLatch.current.reset();
|
|
101
|
+
} else {
|
|
102
|
+
typingLatch.current = new _timeoutLatch.TimeoutLatch(function () {
|
|
103
|
+
if (pendingUpdate.current) {
|
|
104
|
+
var forceUpdate = pendingUpdate.current;
|
|
105
|
+
pendingUpdate.current = null;
|
|
106
|
+
forceUpdate();
|
|
107
|
+
}
|
|
108
|
+
typingLatch.current = null;
|
|
109
|
+
}, TYPING_TIMOUT);
|
|
110
|
+
(0, _timeoutLatch.getScheduler)().add(typingLatch.current);
|
|
111
|
+
}
|
|
85
112
|
var doc = vu.state.doc;
|
|
86
113
|
var _value = doc.toString();
|
|
87
114
|
onChange(_value, vu);
|
|
@@ -138,6 +165,10 @@ function useCodeMirror(props) {
|
|
|
138
165
|
view.destroy();
|
|
139
166
|
setView(undefined);
|
|
140
167
|
}
|
|
168
|
+
if (typingLatch.current) {
|
|
169
|
+
typingLatch.current.cancel();
|
|
170
|
+
typingLatch.current = null;
|
|
171
|
+
}
|
|
141
172
|
};
|
|
142
173
|
}, [view]);
|
|
143
174
|
(0, _react.useEffect)(function () {
|
|
@@ -159,14 +190,24 @@ function useCodeMirror(props) {
|
|
|
159
190
|
}
|
|
160
191
|
var currentValue = view ? view.state.doc.toString() : '';
|
|
161
192
|
if (view && value !== currentValue) {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
193
|
+
var isTyping = typingLatch.current && !typingLatch.current.isDone;
|
|
194
|
+
var forceUpdate = function forceUpdate() {
|
|
195
|
+
if (view && value !== view.state.doc.toString()) {
|
|
196
|
+
view.dispatch({
|
|
197
|
+
changes: {
|
|
198
|
+
from: 0,
|
|
199
|
+
to: view.state.doc.toString().length,
|
|
200
|
+
insert: value || ''
|
|
201
|
+
},
|
|
202
|
+
annotations: [ExternalChange.of(true)]
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
if (!isTyping) {
|
|
207
|
+
forceUpdate();
|
|
208
|
+
} else {
|
|
209
|
+
pendingUpdate.current = forceUpdate;
|
|
210
|
+
}
|
|
170
211
|
}
|
|
171
212
|
}, [value, view]);
|
|
172
213
|
return {
|